재만, 영호, 정희, 덕일, 선주 이렇게 해서 총 6인이 명동 밀리오레에서 만났다.
뭐, 술 한잔 하자고 생각은 했지만, 만나고 보니, 술보다도 밥이 더 궁했다고나 할까?
정희 결혼식 후에 만나는거니 2달만인가?
뭐 어쨌던 간만에 만난 얼굴은 크게 달라져 보이지는 않았다.
늘 한결 같은 모습들이여서 좋기만 했다.
(하지만, 덕일의 모습은 너무도 첫인상이 강해 여전히 낯설지만 ^^)
아, 그리고 선주. 너무도 간만에 나와, (2년 만?) 너무도 반가웠다.
중국집에서 탕수육과 깐풍기를 먹고 난 볶음밥, 다른 애들은 사천짜장과 짬뽕을 먹었다.
정희의 결혼 이야기와 그 밖에 지금까지 걸어온 이야기 보고 정도...
99년 이래에 계속 만나온거니 역사상으로는 벌써 5년째가 되는거 아닌지 모르겠다.

아.. 이렇게 아저씨 아줌마들이 되었으니(아... 선주는 아직도 미혼이니까 아가씨가 되나?)
이제 결혼들 마저 하고 애들 하나씩 끼고 오는건 아닌지 모르것다.
하하하~
728x90
WM_ 으로 시작하는 윈도우 메시지를 만들었을때, MFC에서 제공하는 On_ 으로 처리되는 함수들이
자동으로 생성되는 것 보면 편해보이기 까지한다.
이를 수동적으로 생성하는 방법을 알아보자.

WM_USERDEFINE 이라는 메시지가 있다고 하자.
사용자가 만든 메시지여서, 실제 MFC Wizard로 만들수 없다.
게다가, MessageMap 매크로 안에 넣으려해도, afxmsg OnUserDefine 을 만들려고 하면
그 함수와 Message와 연결 할 방법이 없다.
이를 처리하려면, MessageMap 안에서 함수와 Message를 연결해주는 무언가를 만들어 줘야 한다.
그리고, 각 함수를 살펴보면, 윈도우 메시지를 그냥 받는 것이 아니고 각 유형 별로 파라미터로 받는 경우가 있다.
예를 들자면 OnLButtonDown(UINT nFlags, CPoint point) 같은 것은 nFlags 나 point를 받는다.
하지만, 현재는 파라미터가 없는 버젼만을 생각하여 만들도록 하자.

WM_USERDEFINE을 가지고 한번 만들어 보자.

.H 을 열어 보면,
   //{{AFX_MSG(CUserDefine)
   //}}AFX_MSG
   DECLARE_MESSAGE_MAP()
이라는 부분이 있다.
실제로 "//{{AFX_MSG(CUserDefine)",  "//}}AFX_MSG" 이 두 문장은 단순히 클래스 위자드에서 사용하기 위해
만들어진 내용이므로 삭제해도 무방하다. 단 클래스 위자드에 의존하는 분들은 이 부분을 지우게 되면 새로운 메시지
처리를 추가/삭제/수정이 절대 불가능하니, 조심한다.
일단, "//}}AFX_MSG" 아래에다 자신이 만든 메시지 핸들러 함수를 선언한다.
afx_msg 를 맨 앞에 붙이고 그 뒤에 함수 선언을 한다. On 이라는 이름이 붙은 형태의 함수를 만든다.
   afx_msg OnUserDefine()
그러면 .H에서 다 기록한 것이다.

.CPP를 열어보면,
   BEGIN_MESSAGE_MAP(CUserDefine,CWnd )
           //{{AFX_MSG_MAP(CUserDefine)
           ON_WM_PAINT()        
           //}}AFX_MSG_MAP
   END_MESSAGE_MAP()
가 보일 것이다. 이 안이 바로 Message와 함수를 연결해주는 부분이다. 그러나 그 안에 보면 단순히
ON_WM_PAINT()와 같은 단순 무식한 한줄의 함수만 보인다. 그렇다면 이를 어떻게 해야 하는 것인가?
간단하다. ON_WM..  시리즈를 직접 만드는 것이다.
   #define ON_WM_USERDEFINE()
   { WM_USERDEFINE, 0, 0, 0, AfxSig_vv,
   (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(void))&OnUserDefine },
위의 세줄을 넣어준다.  이 부분이 바로 ON_WM 시리즈의 실체가 된다.
실제 사용되는 WM_ 메시지를 넣고 맨 뒤의 On.. 시리즈 함수를 대체해서 만들어 주면 된다.
위의 예제는 WM_USERDEFINE을 기준으로 넣었다. 그러면 BEGIN_... 안에다 자신이 만든것을 넣어 주면 된다.
   BEGIN_MESSAGE_MAP(CUserDefine,CWnd )
           //{{AFX_MSG_MAP(CUserDefine)
           ON_WM_PAINT()        
           //}}AFX_MSG_MAP
                ON_WM_USERDEFINE()
   END_MESSAGE_MAP()
이렇게 하면 모든것이 해결!

파라미터가 있다면 그 뒤에 다시 생각해보도록한다.
참고로 AfxSig_xxx 라는 값을 이용하면 다양한 형태로 구성할 수 있는 데, 이는 정해진 내용만 적용가능하다.
        AfxSig_bD,      // BOOL (CDC*)
        AfxSig_bb,      // BOOL (BOOL)
        AfxSig_bWww,    // BOOL (CWnd*, UINT, UINT)
        AfxSig_hDWw,    // HBRUSH (CDC*, CWnd*, UINT)
        AfxSig_hDw,     // HBRUSH (CDC*, UINT)
        AfxSig_iwWw,    // int (UINT, CWnd*, UINT)
        AfxSig_iww,     // int (UINT, UINT)
        AfxSig_iWww,    // int (CWnd*, UINT, UINT)
        AfxSig_is,      // int (LPTSTR)
        AfxSig_lwl,     // LRESULT (WPARAM, LPARAM)
        AfxSig_lwwM,    // LRESULT (UINT, UINT, CMenu*)
        AfxSig_vv,      // void (void)

        AfxSig_vw,      // void (UINT)
        AfxSig_vww,     // void (UINT, UINT)
        AfxSig_vvii,    // void (int, int) // wParam is ignored
        AfxSig_vwww,    // void (UINT, UINT, UINT)
        AfxSig_vwii,    // void (UINT, int, int)
        AfxSig_vwl,     // void (UINT, LPARAM)
        AfxSig_vbWW,    // void (BOOL, CWnd*, CWnd*)
        AfxSig_vD,      // void (CDC*)
        AfxSig_vM,      // void (CMenu*)
        AfxSig_vMwb,    // void (CMenu*, UINT, BOOL)

        AfxSig_vW,      // void (CWnd*)
        AfxSig_vWww,    // void (CWnd*, UINT, UINT)
        AfxSig_vWp,     // void (CWnd*, CPoint)
        AfxSig_vWh,     // void (CWnd*, HANDLE)
        AfxSig_vwW,     // void (UINT, CWnd*)
        AfxSig_vwWb,    // void (UINT, CWnd*, BOOL)
        AfxSig_vwwW,    // void (UINT, UINT, CWnd*)
        AfxSig_vwwx,    // void (UINT, UINT)
        AfxSig_vs,      // void (LPTSTR)
        AfxSig_vOWNER,  // void (int, LPTSTR), force return TRUE
        AfxSig_iis,     // int (int, LPTSTR)
        AfxSig_wp,      // UINT (CPoint)
        AfxSig_wv,      // UINT (void)
        AfxSig_vPOS,    // void (WINDOWPOS*)
        AfxSig_vCALC,   // void (BOOL, NCCALCSIZE_PARAMS*)
        AfxSig_vNMHDRpl,    // void (NMHDR*, LRESULT*)
        AfxSig_bNMHDRpl,    // BOOL (NMHDR*, LRESULT*)
        AfxSig_vwNMHDRpl,   // void (UINT, NMHDR*, LRESULT*)
        AfxSig_bwNMHDRpl,   // BOOL (UINT, NMHDR*, LRESULT*)
        AfxSig_bHELPINFO,   // BOOL (HELPINFO*)
        AfxSig_vwSIZING,    // void (UINT, LPRECT) -- return TRUE

        // signatures specific to CCmdTarget
        AfxSig_cmdui,   // void (CCmdUI*)
        AfxSig_cmduiw,  // void (CCmdUI*, UINT)
        AfxSig_vpv,     // void (void*)
        AfxSig_bpv,     // BOOL (void*)

        // Other aliases (based on implementation)
        AfxSig_vwwh,                // void (UINT, UINT, HANDLE)
        AfxSig_vwp,                 // void (UINT, CPoint)
        AfxSig_bw = AfxSig_bb,      // BOOL (UINT)
        AfxSig_bh = AfxSig_bb,      // BOOL (HANDLE)
        AfxSig_iw = AfxSig_bb,      // int (UINT)
        AfxSig_ww = AfxSig_bb,      // UINT (UINT)
        AfxSig_bv = AfxSig_wv,      // BOOL (void)
        AfxSig_hv = AfxSig_wv,      // HANDLE (void)
        AfxSig_vb = AfxSig_vw,      // void (BOOL)
        AfxSig_vbh = AfxSig_vww,    // void (BOOL, HANDLE)
        AfxSig_vbw = AfxSig_vww,    // void (BOOL, UINT)
        AfxSig_vhh = AfxSig_vww,    // void (HANDLE, HANDLE)
        AfxSig_vh = AfxSig_vw,      // void (HANDLE)
        AfxSig_viSS = AfxSig_vwl,   // void (int, STYLESTRUCT*)
        AfxSig_bwl = AfxSig_lwl,
        AfxSig_vwMOVING = AfxSig_vwSIZING,  // void (UINT, LPRECT) -- return TRUE

        AfxSig_vW2,                 // void (CWnd*) (CWnd* comes from lParam)
        AfxSig_bWCDS,               // BOOL (CWnd*, COPYDATASTRUCT*)
        AfxSig_bwsp,                // BOOL (UINT, short, CPoint)
위에서 보듯이 딱 정해진 기능만 하므로... 그 외의 것이라면 다시 생각해보도록 한다.

PS. 혹여 AfxSig_lwl 를 사용하면 WPARAM, LPARAM 이니까... 다양하게 이용할 수 있을지도 모르겠다.

728x90
Linux에서 rdate라는 명령이 있다.
시간 서버에 접속해서 현재 Linux 의 시간을 설정하는 것이다.

이 명령을 보면, rdate -s 가 있는 time host에 접속해 서버 시간을 로컬 시간과 동일하게 만들어 준다.
Time 서버는 일반적으로 time.nist.gov를 사용하면 된다.

728x90
분 시 일 월 요일 권한자 실행내용
ex) 0 0 * * 0 root rdate -s time.nist.gov
   0시 0분 그것도 일요일만 실행을하면 실행권한은 root 이고, rdate 이하를 실행한다.  

/etc/crontab 안의 Text로 해당하는 처리를 하면 된다.
728x90
Winsock의 형태는 다양하게 변모되어 우리에게 다가왔다
sock 라이브러리를 Windows에 맞게 처음 도입한 Winsock 1.x에서 2.x로 발전하고,
MFC로 재 제작하여 배포하고 있다.

여기서 winsock 1.x 때와 2,x 때 include하는 내용이 틀리다.

1. 일반적으로 winsock1.x 라이브러리를 사용하려면,
winsock.h만 include하면 된다. (lib는 일반적으로 섞여 처리된다.)

2. winsock 2.x대에서는 다음의 추가적인 처리가 필요하다.
Winsock2.h 와 ws2tcpip.h 를 include 처리하고
ws2_32.lib를 link시 연결해 주면 된다.

3. MFC 인경우에는 MFC 4.x 대 library안에 lib는 내장되어 있고 단지, 해당 클래스만 include 처리하면 된다.
afxsock.h 가 바로 그 include해야 될 내용이다.
728x90
문득 달력을 보고 있다가, 갑자기 내가 휑하니 여기 까지 왔다는 생각이 든다.
내가 서 있는 위치에서 내가 서있는 길까지의 이 기묘한 기분.
어느새 첫눈도 내렸고, 날씨는 날씨대로 차가워져 있다.
하지만, 뭐 특별히 하는 것 없이 시간을 보내고 있다.
이 진한 커피향 같은 생활속에서 기묘한 여유로움을 가져본다.
가끔 낮에도 잠도 자고 한다.
기묘한 여유로움이 내 몸을 감싸안고 가만히 뒤적거린다.

아아... 지금 난 왜 여기 있지?
728x90
mysql 4.x를 RPM으로..
libiconv 도 prefix = "/usr" 로 설정하고 설치하고...
apache 1.3. x도 RPM으로 되었다면..
/usr/local/freetds 에 MSSQL 라이브러리를 설치하고 난뒤 사용한다.
Gd 라이브러리 포함(단 zlib를 RPM으로 설치되어 있어야함 )

./configure --with-apxs=/usr/sbin/apxs --with-imap=/usr --with-mysql=/usr --with-iconv=/usr --with-language=korean --with-charset=euc_kr --enable-track-vars --enable-module=so  --disable-cgi --with-config-file-path=/etc/httpd/conf --enable-versioning --with-kerberos --with-imap-ssl=/usr   --with-mssql=/usr/local/freetds --enable-msdblib --with-gd  --with-zlib-dir=/usr
728x90
Kernel Compile

  배경지식

기본적으로 커널 소스의 디렉토리는 /usr/src/linux 이다.
커널 컴파일 방법에는 3가지가 있다
make config -> 옵션을 잘못 선택하면 처음부터 다시해야하는 단점이 있다.
make menuconfig -> 가장 추천하는 방법(단, ncurses가 있어야 한다.)
make xconfig -> X에서 볼수 있다.( 화려하다. 그냥 구경한번 해보길...)
시스템 사양을 잘 알아야 한다.(이더넷 카드, 사운드 카드, CPU가 몇개(?)인지등...)
어떠한 환경에서 사용할건지 결정하여야 한다.(커널의 최적화를 위해...)
Kernel Compile Option
꼭 주의깊게 살펴볼것!!(나에게 어떤 옵션이 필요한지 볼것)
제 2회 리눅스 공동체 세미나 자료에서 추출(이규호님께 감사)
커널 2.4 Intro중 커널옵션설정
일반적인 데스크탑 PC사양에서 필요로하는 커널옵션들을 설명하고있다.
  따라하기

커널 소스를 받는다.( http://www.kr.kernel.org/pub/linux/kernel/)
소스를 /usr/src 방으로 옮긴다.(예: mv linux-2.2.12.tar.gz /usr/src )
전에 있던 커널소스 /usr/src/linux 디렉은 다른이름으로 바꾸던지 지워라.(예: mv linux linux-2.2.11)
만약 linux라는 이름으로 심벌릭 링크되어있다면 링크만 해제하라.(예: rm linux)
커널 소스를 푼다.(예: tar xvvzf 커널버전.tar.gz 또는 tar xvvIf 커널버전.tar.bz2)
linux라는 디렉토리가 생겼을 것이다. 그 디렉으로 들어간다.( cd linux )
# make menuconfig ( 현재 위치 /usr/src/linux )
커널 컴파일 옵션을 보고 시스템에 맞는걸 선택한다.(중요하다!)
# make clean (예전 오브젝트 파일 제거)
# make dep (의존성을 검사)
# make bzImage (커널 이미지를 압축생성한다.)
# mv arch/i386/boot/bzImage /boot/vmlinuz-커널버전 (예: mv arch/i386/boot/bzImage /boot/vmlinuz-2.2.12)
# mv System.map /boot/System.map-커널버전 (예: mv System.map /boot/System.map-2.2.12)
# vi /etc/lilo.conf ( 리로를 편집한다 )
     boot=/dev/hda
     map=/boot/map
     install=/boot/boot.b
     prompt
     timeout=50
     image=/boot/vmlinuz-2.2.12 -> 새로운 커널이미지를 linux라는
     label=linux              ?   레이블로 한다.
     root=/dev/hda1
     read-only

     image=/boot/vmlinuz-2.2.11 -> 혹시나 모를 커널 패닉에 대비하여          
     label=old                     예전 커널을 old란 레이블로 해놓는다.
     root=/dev/hda1                (예전 버전이 2.2.11일때)
     read-only
# /sbin/lilo ( lilo.conf의 내용을 인식시켜 주기위해 )
여기까지 커널 컴파일은 과정은 끝.
  모듈 인스톨 하기

커널 옵션에서 모듈(M)으로 선택한것을 컴파일 하기위해
# cd /usr/src/linux
# make modules
# make modules_install
위와같이 하면 '/lib/modules/커널버전' 디렉에 모듈들이 위치한다.


Kernel Patch


패치란 매번 커널이 바뀔때 마다 13MB가 넘는 커널 소스를 다시 받을 필요없이 바뀐 차이점만 담고있는 작은 용량의 파일로 커널을 업하는걸 말한다.
장점 : 적은용량으로 패치파일로 커널을 금방 업 할 수 있다.
단점 : 중간의 한 단계를 건너 뛸 수 없다. 예를들어 현재 커널 버전이 2.2.10 인데 바로 2.2.12로 패치 할 순없다.(꼭 2.2.11을 패치하고 나야 된다)
  따라하기

패치 파일을 다운받아 bzip2이든 gzip으로 압축되어있던지 간에 압축을 푼다.
압축을 푼후 /usr/src/linux 방으로 옮긴다.
# patch -p1 < 패치파일?
에러 없이 넘어가면 다음은 커널 컴파일 과정과 같다.
만약 압축을 풀지않고 패치하려면 gzip 또는 bzip2에 따라 다음과 같이한다.
# gzip -cd 패치파일.gz | patch -p1(물론 패치파일의 위치는 /usr/src/linux)
# bzip2 -cd 패치파일.bz2 | patch -p1
728x90

+ Recent posts

728x90