Linux/Mac TTS script

Posted at 2011/04/08 19:54// Posted in 장난하기
구글 번역기의 읽기 버튼을 조금 활용하여, 간단한 TTS를 해주는 스크립트 입니다. 구글 번역기는 번역된 글을 mp3로 만들어주는 훌륭한 기능을 제공하지요. 따라서, 리눅스에 mpg321 패키지가 제공하는 mpg123 유틸이나, Mac의 afplay를 이용하여 명령행으로 전달되는 문자열을 읽어주게 됩니다.
./play_tts.sh "안녕하세요? 쿨엔!"
만약 영어로 하려면,
TTSLANG=en ./play_tts.sh "How are you? Coolen?"
이런식으로 사용하면 되지요.
이 기능은 소스 커밋하면 목소리로 알려주기 기능의 연장선상에서 진행되었습니다.
크리에이티브 커먼즈 라이센스
Creative Commons License
2011/04/08 19:54 2011/04/08 19:54

LDAP 과 씨름 중

Posted at 2010/11/21 00:35// Posted in 장난하기
LDAP이 Lightweight Directory Access Protocol 이라는게 한 10년은 맘에 안들어 왔다. X.500의 존재를 알기에 그것보다는 Lightweight 라는 것도 알지만, 정말 lightweight라면 속성과 계층구조를 지원하는 xml 수준으로도 설정이 가능하면 좋겠다는 생각이다.

맘에 안들지만, 상당히 많은 웹 어플리케이션이 LDAP을 지원하고 있어서, 그 어플리케이션에 통합 인증을 지원하려면, LDAP Server라도 돌려야할 처지에 놓여있다. subversion, redmine, reviewboard를 모두 ldap으로 묶으려는 시도를 하고 있는 판이다. subversion은 sasl을 지원하므로, sasl에 얹어서 ldap에 접근하면 될것 같고, redmine, reviewboard 모두 직접적으로 ldap을 지원하니 쉬울것 같다.

OpenLDAP이 실험적인 재밌는 요소들을 지원한다. LDAP 자료구조의 backend를 굉장히 다양하게 지원하고 있다는 것이다. shell, perl, odbc-sql 등을 지원하는 것이 눈에 들어오고 있다.

어쨋거나, 사용자들이 자신의 인증 메커니즘을 서로다른 어플리케이션에서 같은 비밀번호를 쓰도록하는 것이 목표인데, 관리적인 면에서도, redmine을 중심에 두고, redmine의 DB를 다른 어플리케이션에서 인증하도록 openldap을 잘 구성하면 되지 않을까 고민한다. 그러면, 비번 바꾸기 등도 관리자가 따로 개발하지 않아도 되는 것 아닌가.

이번 주말에 끝장을 보자스라.

크리에이티브 커먼즈 라이센스
Creative Commons License
2010/11/21 00:35 2010/11/21 00:35
openssh 의 클라이언트는 외부에 접속할 때 HTTP 프록시를 통하여 접속하는 것을 지원하지 않습니다. 하지만, 다른 유틸의 도움을 받아 접속할 수가 있지요. openssh에는 ProxyCommand 라는 옵션이 있습니다. 이것은 ssh 명령을 내릴때 서버에 직접 접속하지 않고, 다른 명령을 실행시켜 접속을 위임하고, 그 표준 입출력을 접속으로 여기겠다는 것입니다. 그 다른 명령에 HTTP 프록시를 지원하는 'nc' 를 이용하면 됩니다.

예를 들어, squid가 돌고 있는 proxyhost

nc -X connect -x proxyhost:3128 coolengineer.com 80

이런 명령을 내리면 proxyhost:3128에 접속하여 http 프로토콜을 이용하여 coolengineer.com 의 웹서비스에 접속합니다. 이후 "GET / HTTP/1.0" 와 같은 명령을 내리면 제 홈의 HTML 소스가 전송되는 것입니다.

nc -X connect -x proxyhost:3128 coolengineer.com 22

이렇게 하면 coolengineer.com의 SSH 서비스에 접속을 하겠죠. 그럼 openssh 클라이언트의 ProxyCommand 규격에 맞게 다음과 같이 하면..!

ssh -o "ProxyCommand nc -X connect -x proxyhost:3128 %h %p" coolengineer.com


짜잔! openssh 클라이언트인 ssh는 proxyhost를 거쳐서 coolengineer.com 22 번포트에 접속한 nc 의 표준 입출력을 이용하여 로그인을 진행하게 됩니다.

크리에이티브 커먼즈 라이센스
Creative Commons License
2010/05/13 14:00 2010/05/13 14:00

RPM-Wand, 쉽게 RPM 만드는 유틸리티

Posted at 2010/04/19 22:15// Posted in 장난하기
소스 컴파일이 되지 않는 바이너리 혹은 스크립트 수준의 패키지를 위한 rpm build utility 입니다. 만들어 쓰던것을 공유해보고자
 http://code.google.com/p/rpmwand/
위에 둥지를 하나 틀어, rpmwand 라는 이름으로 올렸습니다.
사용방법은 간단합니다.

초기화

$ rpmwand init sample
* Created skeleton directory: 'sample-skel'
* Created file list: sample-files.txt
  Please edit sample-files.txt
* Created spec input file: sample.spec.in
  Please edit sample.spec.in
  Fix TODO values
rpmwand 는 크게 두가지 명령으로 구성되어 있습니다. 'init' 명령과 패키지 이름을 주면 두 개의 파일과 한 개의 디렉토리가 생성됩니다. rpm 빌드용 spec file과 간단한 skeleton root 디렉토리, 그리고, skeleton에 들어간 file list가 들어 있는 파일하나가 생성됩니다.

빌드

$ rpmwand build sample
 * Package name : sample
 * Version      : 1.0.0
 * Release      : 1
--------------------------------------------------------------------------
* Making tarball(sample-1.0.0.tar.gz) for rpm build...
* Tarball(sample-1.0.0.tar.gz) is assumed containing 'sample-1.0.0' directory as the first child item
* Cloning 'sample-skel' directory to 'sample-1.0.0'
* Check if there is custom packaging script (sample-setup.sh)
  skip running: bash sample-setup.sh /home/pynoos/rpmwand/sample-1.0.0
* Tarring 'sample-1.0.0.tar.gz' from 'sample-1.0.0'
--------------------------------------------------------------------------
* Now, building rpm....
Building target platforms: noarch
Building for target noarch
Executing(%prep): /bin/sh -e /home/pynoos/rpmwand/faked-root.19231/tmp/rpm-tmp.83533
+ umask 022
+ cd /home/pynoos/rpmwand/faked-root.19231/
+ true ==================================================================================
+ true 'BEG Build preprocess'
+ true 'END Build preprocess'
+ cd /home/pynoos/rpmwand/faked-root.19231
+ rm -rf sample-1.0.0
+ /bin/gzip -dc /home/pynoos/rpmwand/sample-1.0.0.tar.gz
+ tar -xf -
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd sample-1.0.0
++ /usr/bin/id -u
+ '[' 503 = 0 ']'
++ /usr/bin/id -u
+ '[' 503 = 0 ']'
+ /bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ true ==================================================================================
+ true 'BEG Setup'
+ true 'END Setup'
+ exit 0
Executing(%build): /bin/sh -e /home/pynoos/rpmwand/faked-root.19231/tmp/rpm-tmp.83533
+ umask 022
+ cd /home/pynoos/rpmwand/faked-root.19231/
+ cd sample-1.0.0
+ true ==================================================================================
+ true 'BEG Build'
+ echo 'BUILDROOT: /home/pynoos/rpmwand/faked-root.19231'
BUILDROOT: /home/pynoos/rpmwand/faked-root.19231
+ echo 'PACKAGE-NAME: sample'
PACKAGE-NAME: sample
+ echo 'PACKAGE-VERSION: 1.0.0'
PACKAGE-VERSION: 1.0.0
+ echo 'PACKAGE-RELEASE: 1'
PACKAGE-RELEASE: 1
+ true 'END Build'
+ exit 0
Executing(%install): /bin/sh -e /home/pynoos/rpmwand/faked-root.19231/tmp/rpm-tmp.83533
+ umask 022
+ cd /home/pynoos/rpmwand/faked-root.19231/
+ cd sample-1.0.0
+ true ==================================================================================
+ true 'BEG Installation'
+ /bin/cat
+ true 'END Installation'
+ make prefix=/home/pynoos/rpmwand/faked-root.19231/usr exec_prefix=/home/pynoos/rpmwand/faked-root.19231/usr bindir=/home/pynoos/rpmwand/faked-root.19231/usr/bin sbindir=/home/pynoos/rpmwand/faked-root.19231/usr/sbin sysconfdir=/home/pynoos/rpmwand/faked-root.19231/etc datadir=/home/pynoos/rpmwand/faked-root.19231/usr/share includedir=/home/pynoos/rpmwand/faked-root.19231/usr/include libdir=/home/pynoos/rpmwand/faked-root.19231/usr/lib libexecdir=/home/pynoos/rpmwand/faked-root.19231/usr/libexec localstatedir=/home/pynoos/rpmwand/faked-root.19231/var sharedstatedir=/home/pynoos/rpmwand/faked-root.19231/usr/com mandir=/home/pynoos/rpmwand/faked-root.19231/usr/share/man infodir=/home/pynoos/rpmwand/faked-root.19231/usr/share/info install
I am FAKE Makefile install target. Do you see me?
+ true ==================================================================================
+ true 'BEG make install'
+ true BUILDROOT:/home/pynoos/rpmwand/faked-root.19231
+ /bin/rm -rf /home/pynoos/rpmwand/faked-root.19231/sample-1.0.0/Makefile
+ mv /home/pynoos/rpmwand/faked-root.19231/sample-1.0.0/etc /home/pynoos/rpmwand/faked-root.19231/sample-1.0.0/usr /home/pynoos/rpmwand/faked-root.19231
+ true 'END make install'
+ /usr/lib/rpm/brp-compress
+ /usr/lib/rpm/brp-strip
+ /usr/lib/rpm/brp-strip-static-archive
+ /usr/lib/rpm/brp-strip-comment-note
Processing files: sample-1.0.0-1
Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/pynoos/rpmwand/faked-root.19231
Wrote: /home/pynoos/rpmwand/RPMS/noarch/sample-1.0.0-1.noarch.rpm
Executing(%clean): /bin/sh -e /home/pynoos/rpmwand/faked-root.19231/tmp/rpm-tmp.27064
+ umask 022
+ cd /home/pynoos/rpmwand/faked-root.19231/
+ cd sample-1.0.0
+ true ==================================================================================
+ exit 0
--------------------------------------------------------------------------
 * RPM build done...
 * Check..
/home/pynoos/rpmwand/RPMS/noarch/sample-1.0.0-1.noarch.rpm
위 명령은 'build' 인데 인자를 추가로 version, release, architecture를 갖습니다. 이 명령으로 spec.in을 spec으로 만들고, file-list를 읽어서 rpm을 만드는데 사용합니다.

이렇게 간단한 두 명령으로 일단 sample-1.0.0-1.noarch.rpm 파일이 만들어집니다.

실제 사용을 위해서는 init 명령에 의해 생성된 skeleton root에 원하는 파일을 추가하고, 설치 목록 파일(file-list.txt)을 수정하여 build 명령을 주면 됩니다. 만들어지는 spec.in 파일들을 직접 열어서 수정할 수 있고, 수정하면 전문적으로 사용할 수도 있는 구조로 되어 있으므로, 처음 배우시는 분들에게 도움이 될 것입니다.

참고로, 저희 팀 내부에서는 이 유틸리티의 전신이 되는 툴을 사용하여 php 배포용 rpm을 만들어 사용합니다.
크리에이티브 커먼즈 라이센스
Creative Commons License
2010/04/19 22:15 2010/04/19 22:15

Subversion Commit Log Template for VIM

Posted at 2010/04/11 23:34// Posted in 장난하기
VIM 사용자를 위해서, 서브버전 커밋로그 템플릿 빔플러그인을 만들어 보았습니다.

원래.
  1 
  2 --This line, and those below, will be ignored--
  3
  4 M    src/cmdcenter.py

이렇게 나오던 것을

  1 [Hojin Choi][BT:n/a][RV:n/a][2010-04-11]
  2
  3 M    src/cmdcenter.py
  4
  5 --This line, and those below, will be ignored--
  6 * Log template from /home/pynoos/.subversion/commit-template.txt


이런식으로 맨 윗줄에 임의의 양식을 넣어 주고, 그 아래에 수정된 내용을 바로 붙여주는 기능입니다.

$ more ~/.subversion/commit-template.txt
@DATE:%Y-%m-%d
[Hojin Choi][BT:n/a][RV:n/a][{DATE}]

템플릿의 예로 사용된것은 위와 같습니다.

여기서 다운로드하시면됩니다.

크리에이티브 커먼즈 라이센스
Creative Commons License
2010/04/11 23:34 2010/04/11 23:34

SVN log edit script

Posted at 2010/02/16 17:38// Posted in 장난하기
가지고 다니는것이 귀찮아서요. 블로그를 임시 저장소로 쓸 겸해서 올립니다.
#!/bin/sh
TMPFILE=/tmp/svnlog-$$.txt
TMPFILE2=/tmp/svnlog-$$.orig.txt
svn pg --revprop -r$1 svn:log > $TMPFILE || exit 1
ex $TMPFILE <<'EOT'
:$d
:wq!
EOT
cp -p $TMPFILE $TMPFILE2
vi $TMPFILE || exit 1
if cmp $TMPFILE $TMPFILE2 2>/dev/null; then
        echo "Skip editting..."
else
        svn ps --revprop -r$1 svn:log -F $TMPFILE
fi
rm -f $TMPFILE $TMPFILE2
크리에이티브 커먼즈 라이센스
Creative Commons License
2010/02/16 17:38 2010/02/16 17:38

I have no name!

Posted at 2009/11/25 12:02// Posted in 장난하기
bash의 prompt(PS1)에서 "I have no name!"이 나오면,

/etc/passwd 가 world readable한지,
/etc/nsswitch.conf 가 있는지,
/lib/libnss_files.so.2 파일이 있는지 확인해야한다.

쩝...
크리에이티브 커먼즈 라이센스
Creative Commons License
2009/11/25 12:02 2009/11/25 12:02
Tag ,

VirtualBox 오류 복원

Posted at 2009/10/20 11:08// Posted in 장난하기
VM의 상태를 끄지 않고 저장해둔 다음, VirtualBox의 버전이 바뀌거나 OS가 달라져서, 복원이 되지 않을때, 다음과 같이 수동으로 VM 상태를 끄면 됩니다.
VBoxManage discardstate {Virtual Machine Name}
그리고, 다시 부팅 시도 해봅니다. -- 미투데이 수준의 블로깅.
크리에이티브 커먼즈 라이센스
Creative Commons License
2009/10/20 11:08 2009/10/20 11:08
지금 소개할 방법은 FTP가 control 채널과 data 채널로 나뉘며, data 채널은 양방향으로 접속이 되도록 구현되어 있는데, 이것을 잘 이용하여 방화벽을 우회할 수 있는 기술입니다. 그러나, 여러가지 제약으로 인해 시도하다 좌절할 수 있습니다.

FTP의 Active Mode는 FTP 클라이언트가 포트를 열고 있으면, 서버가 데이터(디렉토리 목록나 파일 내용)를 쏴주는 방법입니다.  예를 들어 "ls" 명령이 어떻게 되는지 알아 보기로 합시다.

ftp> open 200.200.200.200
Connected to200.200.200.200.
220 FTP Server Ready ..
Name (200.200.200.200:pynoos):
Password:
230 User pynoos logged in
ftp> debug
Debugging on (debug=1).
ftp> ls
---> PORT 172,20,114,164,208,31
200 PORT command successful
---> LIST
150 Opening ASCII mode data connection for file list
-rw-rw-r--   1 pynoos   pynoos       1202 Jul  2 16:43 a
-rwxr-xr-x   1 pynoos   pynoos         62 Dec 16  2008 ac.sh
-rw-rw-r--   1 pynoos   pynoos      69386 Dec 16  2008 a.tar.gz
-rwxr-xr-x   1 pynoos   pynoos     589463 Aug 10 19:31 s
-rw-r--r--   1 pynoos   pynoos       1630 Aug 10 19:30 s.c
-rw-r--r--   1 pynoos   pynoos       2672 Dec 17  2008 sendmail.c
226 Transfer complete
debug 라는 명령으로 프로토콜을 중간에 보이도록 하면, 'ls' 명령을 내렸을 때, PORT, LIST 두 개의 조합으로 이루어지는 것을 볼 수 있습니다. (passive 도 한번 해보세요.) 이 때, PORT 명령을 잘 살펴보면, 앞의 네 개의 숫자는 IP고 뒤의 두 개의 숫자는 port를 256으로 나눈 값과 그 나머지 입니다. 53279번 포트(208*256+31=53279)를 열어 두고 PORT 명령을 전송하면, 서버에서 그 포트에 접속하여 LIST를 쏘아주는 것입니다.

자, 여기에서 만약 FTP Client가 NAT가 되는 방화벽 안에 있다면, 방화벽은 조금 스마트하게 동작하여 connection tracking 정보를 만듭니다. 21번 포트에서 왔다갔다하는 것들 중에, PORT 명령 같은 것을 감시하고 있다가, 외부로 전송될때, 실제 주소로 바꿔서 나가는 것이죠. 위의 경우 172.20 이라는 내부 IP를 사용했습니다만, 실제 외부에 있는 저 FTP(200.200.200.200) 서버는 다른 IP를 받게 됩니다. 심지어, PORT도 다르게 할당하는 NAT도 있습니다.

제가 사용한 NAT 장비는 다행히도 PORT는 바뀌지 않아서, 다음을 계속 진행할 수가 있었습니다.
$ more /etc/ssh/sshd_config

# Package generated configuration file

# What ports, IPs and protocols we listen for
Port 2560
Port 22
# Use these options to restrict which interfaces/protocols sshd will bind to
#ListenAddress ::
#ListenAddress 0.0.0.0
Protocol 2
...
이런식으로 SSHD의 서비스를 2560번에 하나 더 띄우고 재시작을 시킵니다. 이렇게 하는 이유는 FTP의 데이터 채널은 1024번 이상의 포트에서 접속이 일어나기 때문에 그렇습니다. 자, 2560번 포트에는 SSH 서비스가 대기하고 있는데, FTP 클라이언트로 PORT, LIST 조합에서 PORT만 전송하고 LIST 명령을 내리지 않으면, 누군가 해당 포트로 접속할 수 있는 것 아니겠습니까?

이때, 사용할 명령이 FTP 클라이언트의 quote 명령입니다.

ftp> quote PORT 172,20,114,164,10,0
---> PORT 172,20,114,164,10,0
200 PORT command successful

quote 명령은 뒤에 따라오는 것들을 그대로 전송하라는 얘기입니다. 위의 예는 "10*256+0번 포트로 나는 대기중이야, 다음 접속은 그쪽으로 해"라는 뜻입니다. 이때, 이 명령을 감시하고 있는 방화벽의 NAT 모듈은 2560 번으로 누군가 들어오면, 내부 IP 172.20.114.164 번으로 바로 접속할 수 있도록 임시로 개방이 되는 것입니다. 단, 조건은 control 채널에 해당하는 IP에서만 들어올 수 있습니다. 지금까지 하면, 현재 ftp 서버인 200.200.200.200 장비에서 2560 번 포트로 접속이 가능한 것이지요.

FTP 서버에 ssh로 들어가서
$ w
  5:58pm  up 187 days, 10:45,  2 users,  load average: 0.35, 0.39, 0.44
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU  WHAT
pynoos   pts/1    200.111.111.100   5:58pm  0.00s  0.05s  0.00s  w
자신의 FTP Client가 돌고 있는 외부 IP를 얻습니다. 그리고, 그 서버에서
$ ssh 200.111.111.100 -p 2560
으로 접속해 들어오면, 프롬프트가 나오는 것을 보실 수 있을 겁니다. 짜잔! 외부에서 바로 들어 올 수 있다니요...

크리에이티브 커먼즈 라이센스
Creative Commons License
2009/08/21 18:03 2009/08/21 18:03
$ sudo debian/rules binary
혹은
$ fakeroot debian/rules binary
간단하고나...
그나저나, 이게 얼마만에 쓰는 글이야...
크리에이티브 커먼즈 라이센스
Creative Commons License
2009/08/20 16:14 2009/08/20 16:14
1 2 3 4 5 ... 22