Apr 172012
 

SVN을 사용하여 기존에 개발된 소스 디렉토리를 추가하는 경우가 많습니다.
하지만 기존의 디렉토리 구조가 SVN에 적합하지 않거나, 일부분만 SVN과 연동을 하고자 하는 경우가 있습니다.

이런 경우에 처리하기가 좀 곤란해서 여러가지 꼼수를 사용했는데요. 아래와 같이 “svn add -N” 명령어로 간단하게 해결이 가능합니다.


[root@localhost~]# svn help add
add: 파일과 디렉토리를 버전관리 대상에 넣습니다. 저장소에
추가하도록 스케쥴링 되며, 다음 커밋할 때, 추가됩니다.
사용법: add PATH...

옵션:
  --targets ARG            : ARG로 주어진 파일 내용을 옵션으로 추가합니다
  -N [--non-recursive]     : obsolete; try --depth=files or --depth=immediates
  --depth ARG              : 적용할 단계를 제한합니다. 가능한 인자 ('empty', 'files',
                            'immediates', or 'infinity')
  -q [--quiet]             : 아무것도 출력하지 않거나, 요약 정보만 출력합니다
  --force                  : 강제로 실행합니다
  --no-ignore              : svn:ignore로 지정한 것과 디폴트로 무시하는 파일들을 무시하지 않습니다
  --auto-props             : 자동 속성기능을 활성화합니다
  --no-auto-props          : 자동 속성기능을 비활성화합니다
  --parents                : 임시 상위개체 삽입

글로벌 옵션:
  --username ARG           : arg를 접속에 필요한 사용자 ID로 사용합니다
  --password ARG           : arg를 접속에 필요한 패스워드로 사용합니다
  --no-auth-cache          : 인증 정보를 캐시에 저장하지 않습니다
  --non-interactive        : 대화식 사용자 입력을 기다리지 않습니다
  --trust-server-cert      : accept unknown SSL server certificates without
                             prompting (but only with '--non-interactive')
  --config-dir ARG         : arg로 지정된 디렉토리에서 사용자 구성화일을 읽습니다
  --config-option ARG      : set user configuration option in the format:
                                 FILE:SECTION:OPTION=[VALUE]
                             For example:
                                 servers:global:http-library=serf

Apr 172012
 

HTTP/1.1 에서 Cache와 관련된 헤더중에 If-Modified-Since와 ETag를 사용하는 방법이 있습니다.

ETag에 대한 설명은 아래에서 확인이 가능합니다.

http://en.wikipedia.org/wiki/HTTP_ETag

여기서 궁금한 것은 국내에서 많이 사용하고 있는 Apache 웹서버에서는 ETag 값을 어떻게 생성하는지가 궁금해서 소스를 다운받아서 확인을 해봤다.

아래 주석에서와 같이 inode-size-mtime 으로 구성이 하되, hex 값으로 변환을 해서 사용하도록 되어 있습니다. 물론 filetype이 0인 경우에는 mtime값만을 사용하는 것을 149라인에서 확인을 할수 있다.

    113     if (r->finfo.filetype != 0) {
    114         /*
    115          * ETag gets set to [W/]"inode-size-mtime", modulo any
    116          * FileETag keywords.
    117          */
    118         etag = apr_palloc(r->pool, weak_len + sizeof("\"--\"") +
    119                           3 * CHARS_PER_UINT64 + 1);
    120         next = etag;
    121         if (weak) {
    122             while (*weak) {
    123                 *next++ = *weak++;
    124             }
    125         }
    126         *next++ = '"';
    127         bits_added = 0;
    128         if (etag_bits & ETAG_INODE) {
    129             next = etag_uint64_to_hex(next, r->finfo.inode);
    130             bits_added |= ETAG_INODE;
    131         }
    132         if (etag_bits & ETAG_SIZE) {
    133             if (bits_added != 0) {
    134                 *next++ = '-';
    135             }
    136             next = etag_uint64_to_hex(next, r->finfo.size);
    137             bits_added |= ETAG_SIZE;
    138         }
    139         if (etag_bits & ETAG_MTIME) {
    140             if (bits_added != 0) {
    141                 *next++ = '-';
    142             }
    143             next = etag_uint64_to_hex(next, r->mtime);
    144         }
    145         *next++ = '"';
    146         *next = '\0';
    147     }
    148     else {
    149         /*
    150          * Not a file document, so just use the mtime: [W/]"mtime"
    151          */
    152         etag = apr_palloc(r->pool, weak_len + sizeof("\"\"") +
    153                           CHARS_PER_UINT64 + 1);
    154         next = etag;
    155         if (weak) {
    156             while (*weak) {
    157                 *next++ = *weak++;
    158             }
    159         }
    160         *next++ = '"';
    161         next = etag_uint64_to_hex(next, r->mtime);
    162         *next++ = '"';
    163         *next = '\0';
    164     }

아래는 실제 Apache 서버에서 받은 HTTP 헤더에 들어 있는 ETag 값입니다.

위의 ETag 값을 검증해보기 위해서 마지막에 있는 0467ddaad 값을 10진수로 변환을 하고, 해당 값을 Unix Timestamp로 변환을 해보면 다음과 같이 확인이 가능합니다.

Apr 122012
 

SVN을 RPM으로 설치하면 시스템 재시작시 실행해주는 스크립트가 들어가 있지 않다.
이런 경우 대부분 /etc/rc.d/rc.local 에 넣어서 처리를 하는 경우가 대부분인데. 이번에 설치한 CentOS 서버에서는 /etc/rc.d/rc.local 이 제대로 작동하지 않아서 스크립트를 찾아보니 없어서 하나 만들었다.

#!/bin/bash
#
# svnserve        Startup SVN Server
#
# chkconfig: - 85 15
# processname: svnserve
# config: none
# pidfile: /var/run/svnserve.pid
 
# Source function library.
. /etc/rc.d/init.d/functions
 
# Path to the apachectl script, server binary, and short-form for messages.
svnserve=/usr/bin/svnserve
prog=svnserve
pidfile=/var/run/svnserve.pid
logfile=/var/log/svnserve
repository=/home/svn
OPTIONS="-d -r $repository --pid-file $pidfile --log-file $logfile"
RETVAL=0
 
start() {
        echo -n $"Starting $prog: "
        daemon --pidfile=${pidfile} $svnserve $OPTIONS
        RETVAL=$?
        echo
        return $RETVAL
}
 
stop() {
        echo -n $"Stopping $prog: "
        killproc -p ${pidfile}
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && rm -f ${pidfile}
}
 
# See how we were called.
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart)
        stop
        start
        ;;
  *)
        echo $"Usage: $prog {start|stop|restart}"
        RETVAL=2
esac
 
exit $RETVAL

위와 같은 파일을 /etc/init.d/svnserve 로 생성을 하고, 아래와 같이 서비스 등록을 해주면 된다.

[root@localhost ~]# chmod 755 /etc/init.d/svnserve
[root@localhost ~]# chkconfig --add svnserve 
[root@localhost ~]# /sbin/runlevel
N 3
[root@localhost ~]# chkconfig --level 3 svnserve on

참고로 데스크탑으로 설정한 경우에는 Run Level에 5이므로 level을 5로 설정해야 한다.

아래와 같이 사용을 하면 된다.

[root@localhost log]# /etc/init.d/svnserve stop
svnserve 를 정지 중:                                       [  OK  ]
[root@localhost log]# /etc/init.d/svnserve start
svnserve (을)를 시작 중:                                   [  OK  ]
[root@localhost log]# /etc/init.d/svnserve restart
svnserve 를 정지 중:                                       [  OK  ]
svnserve (을)를 시작 중:                                   [  OK  ]
[root@localhost log]#
Apr 092012
 

svn을 linux/unix 환경에서 사용하는 경우에 checkout을 처음 할때 서버의 계정과 클라이언트의 접속 계정이 다른 경우가 있습니다. 이런 경우에는 패스워드를 저장해두면 편리합니다. 다만 해당 계정이 다른 사람이 접근을 하게 된다면 문제가 되겠지만요.

일단 svn을 사용하게 되면 ~/.subversion 이라는 디렉토리가 생성이 됩니다.
해당 디렉토리에서 plaintext 형태로 패스워드를 저장할지를 선택해두면 편리하게 이용이 가능하다.

[root@localhost public_html]# diff ~/.subversion/servers.org ~/.subversion/servers
156c156
< # store-plaintext-passwords = no
---
> store-plaintext-passwords = yes
Apr 092012
 

PHP에서는 PHPMailer라는 프로그램을 이용해서 메일을 쉽게 다양한 서버 메일서버로 보낼수가 있었습니다.

Java로 프로그램을 작성하다가 로그는 log4j를 이용해서 파일로 저장을 하면 되겠지만, 특정 이벤트가 일어날 경우에는 운영자에게 메일로 통보하는 기능을 만들려고 하다가 검색한 것이 JavaMail API 입니다.

정말 다양한 기능을 제공하고 있으며, 샘플 프로그램으로 메일클라이언트, 웹메일등등 다양하게 공개가 되어 있습니다.

http://www.oracle.com/technetwork/java/index-138643.html

샘플 프로그램을 구해서 보면 쉽게 되겠지만, 아래와 같이 Properties 클래스에 메일 서버의 설정값을 넣어서 Session 클래스를 만들어서 사용을 하면 됩니다. gmail 과 같은 공개 메일서버들은 TLS/SSL, 아이디, 패스워드 인증을 사용합니다. 직접구현을 할려면 신경을 좀 써야 하겠지만, 아래와 같이 쉽게 설정으로 해결이 가능합니다.

                        Properties props = System.getProperties();
			props.put("mail.smtp.host", dnsagent.MailHost);
			props.put("mail.smtp.auth", "true");
 
			Session session = Session.getInstance(props, 
					new javax.mail.Authenticator() {
						protected PasswordAuthentication getPasswordAuthentication() {
							return new PasswordAuthentication(dnsagent.AuthId, dnsagent.AuthPw);
						}
					}
			);
			if (dnsagent.debug==true) {	session.setDebug(true); }

그리고 나면 아래와 같이 Message를 만들어서 SMTP서버로 전송을 하면 메일이 발송이 됩니다.

Message msg = new MimeMessage(session);
.......
Transport.send(msg);

쉽게 개발이 가능하며, 다만 500k 정도의 mail.jar 파일만 첨부하여 사용하면 됩니다.

Plugin from the creators of Brindes :: More at Plulz Wordpress Plugins