금요일, 12월 30, 2005

perl 날짜구하기

use strict;
use POSIX;

print POSIX::strftime("%Y/%m/%d %H:%M:%S", localtime(time()));

수요일, 12월 28, 2005

수요일, 12월 21, 2005

아파치 트래픽 제한

아파치 1.x 에서는 트래픽 제한하는 프로그램이 mod_throttle

아피치 2.x
http://dembol.nasa.pl/mod_cband

Bandwidth Management Module for Apache 2.0
http://www.ivn.cl/apache

화요일, 12월 20, 2005

dll, so 지원 함수 보기

win32
dumpbin /exports dll파일명
VC가 설치되어있다면 DEPENDS.EXE dll파일명

UNIX 계열 (so파일)
nm 파일명

종속성
ldd 파일명

금요일, 12월 16, 2005

Java Forums - Useful Code of the Day: Multipart Form File Upload

http://forum.java.sun.com/thread.jspa?forumID=256&threadID=451245

Useful Code of the Day: Multipart Form File Upload
Author: bsampieri Posts: 13,389 Registered: 4/2/99

Oct 3, 2003 6:10 PM

So, you want to upload files to your web server, do ya? Well, I've seen this topic posted a few times in the last month or so and many of the response I've seen here haven't included definitive answers. Of course, the actual problems vary, but ultimately, a bunch of people want to do file upload from an applet or application to an existing file upload script (CGI, PHP, JSP, etc.) on a web server. And invariably, there are problems with formatting the HTTP request to get things working.

Well, I had a need to do the same thing. I realize there are other solutions out there, such as some sample code that comes with Jakarta Commons Upload. But since we all like reusable code, and we also all seem to like reinventing wheels, here's my go at it: MultiPartFormOutputStream!

MultiPartFormOutputStream is a specialized OutputStream-like class. You create your URLConnection to the server (a static method included can do this for a URL for you, as some of the settings, doInput and doOutput specifically, seem to confuse people). Then get the OutputStream from it and create a boundary string (a static method to create one is provided as well) and pass them to the constructor. Now you have a MultiPartFormOutputStream which you can use to write form fields like text fields, checkboxes, etc., as well as write file data (from Files, InputStreams or raw bytes).

There are some convenience methods for writing primative type values as well as strings, but any higher level objects (aside from Files or InputStreams) aren't supported. (You can always serialize and pass the raw bytes.)

Sample usage code is below. Also, any recommendations for improvement are requested. The code was tested with the Jakarta Struts.

import java.io.*;
import java.net.*;

/**
* MultiPartFormOutputStream is used to write
* "multipart/form-data" to a java.net.URLConnection for
* POSTing. This is primarily for file uploading to HTTP servers.
*
* @since JDK1.3
*/

public class MultiPartFormOutputStream {
/**
* The line end characters.
*/

private static final String NEWLINE = "\r\n";

/**
* The boundary prefix.
*/

private static final String PREFIX = "--";

/**
* The output stream to write to.
*/

private DataOutputStream out = null;

/**
* The multipart boundary string.
*/

private String boundary = null;

/**
* Creates a new MultiPartFormOutputStream object using
* the specified output stream and boundary. The boundary is required
* to be created before using this method, as described in the
* description for the getContentType(String) method.
* The boundary is only checked for null or empty string,
* but it is recommended to be at least 6 characters. (Or use the
* static createBoundary() method to create one.)
*
* @param os the output stream
* @param boundary the boundary
* @see #createBoundary()
* @see #getContentType(String)
*/

public MultiPartFormOutputStream(OutputStream os, String boundary) {
if(os == null) {
throw new IllegalArgumentException("Output stream is required.");
}
if(boundary == null || boundary.length() == 0) {
throw new IllegalArgumentException("Boundary stream is required.");
}
this.out = new DataOutputStream(os);
this.boundary = boundary;
}

/**
* Writes an boolean field value.
*
* @param name the field name (required)
* @param value the field value
* @throws java.io.IOException on input/output errors
*/

public void writeField(String name, boolean value)
throws java.io.IOException {
writeField(name, new Boolean(value).toString());
}

/**
* Writes an double field value.
*
* @param name the field name (required)
* @param value the field value
* @throws java.io.IOException on input/output errors
*/

public void writeField(String name, double value)
throws java.io.IOException {
writeField(name, Double.toString(value));
}

/**
* Writes an float field value.
*
* @param name the field name (required)
* @param value the field value
* @throws java.io.IOException on input/output errors
*/

public void writeField(String name, float value)
throws java.io.IOException {
writeField(name, Float.toString(value));
}

/**
* Writes an long field value.
*
* @param name the field name (required)
* @param value the field value
* @throws java.io.IOException on input/output errors
*/

public void writeField(String name, long value)
throws java.io.IOException {
writeField(name, Long.toString(value));
}

/**
* Writes an int field value.
*
* @param name the field name (required)
* @param value the field value
* @throws java.io.IOException on input/output errors
*/

public void writeField(String name, int value)
throws java.io.IOException {
writeField(name, Integer.toString(value));
}

/**
* Writes an short field value.
*
* @param name the field name (required)
* @param value the field value
* @throws java.io.IOException on input/output errors
*/

public void writeField(String name, short value)
throws java.io.IOException {
writeField(name, Short.toString(value));
}

/**
* Writes an char field value.
*
* @param name the field name (required)
* @param value the field value
* @throws java.io.IOException on input/output errors
*/

public void writeField(String name, char value)
throws java.io.IOException {
writeField(name, new Character(value).toString());
}

/**
* Writes an string field value. If the value is null, an empty string
* is sent ("").
*
* @param name the field name (required)
* @param value the field value
* @throws java.io.IOException on input/output errors
*/

public void writeField(String name, String value)
throws java.io.IOException {
if(name == null) {
throw new IllegalArgumentException("Name cannot be null or empty.");
}
if(value == null) {
value = "";
}
/*
--boundary\r\n
Content-Disposition: form-data; name=""\r\n
\r\n
\r\n
*/

// write boundary
out.writeBytes(PREFIX);
out.writeBytes(boundary);
out.writeBytes(NEWLINE);
// write content header
out.writeBytes("Content-Disposition: form-data; name=\"" + name + "\"");
out.writeBytes(NEWLINE);
out.writeBytes(NEWLINE);
// write content
out.writeBytes(value);
out.writeBytes(NEWLINE);
out.flush();
}

/**
* Writes a file's contents. If the file is null, does not exists, or
* is a directory, a java.lang.IllegalArgumentException
* will be thrown.
*
* @param name the field name
* @param mimeType the file content type (optional, recommended)
* @param file the file (the file must exist)
* @throws java.io.IOException on input/output errors
*/

public void writeFile(String name, String mimeType, File file)
throws java.io.IOException {
if(file == null) {
throw new IllegalArgumentException("File cannot be null.");
}
if(!file.exists()) {
throw new IllegalArgumentException("File does not exist.");
}
if(file.isDirectory()) {
throw new IllegalArgumentException("File cannot be a directory.");
}
writeFile(name, mimeType, file.getCanonicalPath(), new FileInputStream(file));
}

/**
* Writes a input stream's contents. If the input stream is null, a
* java.lang.IllegalArgumentException will be thrown.
*
* @param name the field name
* @param mimeType the file content type (optional, recommended)
* @param fileName the file name (required)
* @param is the input stream
* @throws java.io.IOException on input/output errors
*/

public void writeFile(String name, String mimeType,
String fileName, InputStream is)
throws java.io.IOException {
if(is == null) {
throw new IllegalArgumentException("Input stream cannot be null.");
}
if(fileName == null || fileName.length() == 0) {
throw new IllegalArgumentException("File name cannot be null or empty.");
}
/*
--boundary\r\n
Content-Disposition: form-data; name=""; filename=""\r\n
Content-Type: \r\n
\r\n
\r\n
*/

// write boundary
out.writeBytes(PREFIX);
out.writeBytes(boundary);
out.writeBytes(NEWLINE);
// write content header
out.writeBytes("Content-Disposition: form-data; name=\"" + name +
"\"; filename=\"" + fileName + "\"");
out.writeBytes(NEWLINE);
if(mimeType != null) {
out.writeBytes("Content-Type: " + mimeType);
out.writeBytes(NEWLINE);
}
out.writeBytes(NEWLINE);
// write content
byte[] data = new byte[1024];
int r = 0;
while((r = is.read(data, 0, data.length)) != -1) {
out.write(data, 0, r);
}
// close input stream, but ignore any possible exception for it
try {
is.close();
} catch(Exception e) {}
out.writeBytes(NEWLINE);
out.flush();
}

/**
* Writes the given bytes. The bytes are assumed to be the contents
* of a file, and will be sent as such. If the data is null, a
* java.lang.IllegalArgumentException will be thrown.
*
* @param name the field name
* @param mimeType the file content type (optional, recommended)
* @param fileName the file name (required)
* @param data the file data
* @throws java.io.IOException on input/output errors
*/

public void writeFile(String name, String mimeType,
String fileName, byte[] data)
throws java.io.IOException {
if(data == null) {
throw new IllegalArgumentException("Data cannot be null.");
}
if(fileName == null || fileName.length() == 0) {
throw new IllegalArgumentException("File name cannot be null or empty.");
}
/*
--boundary\r\n
Content-Disposition: form-data; name=""; filename=""\r\n
Content-Type: \r\n
\r\n
\r\n
*/

// write boundary
out.writeBytes(PREFIX);
out.writeBytes(boundary);
out.writeBytes(NEWLINE);
// write content header
out.writeBytes("Content-Disposition: form-data; name=\"" + name +
"\"; filename=\"" + fileName + "\"");
out.writeBytes(NEWLINE);
if(mimeType != null) {
out.writeBytes("Content-Type: " + mimeType);
out.writeBytes(NEWLINE);
}
out.writeBytes(NEWLINE);
// write content
out.write(data, 0, data.length);
out.writeBytes(NEWLINE);
out.flush();
}

/**
* Flushes the stream. Actually, this method does nothing, as the only
* write methods are highly specialized and automatically flush.
*
* @throws java.io.IOException on input/output errors
*/

public void flush() throws java.io.IOException {
// out.flush();
}

/**
* Closes the stream.

*

* NOTE: This method MUST be called to finalize the
* multipart stream.
*
* @throws java.io.IOException on input/output errors
*/

public void close() throws java.io.IOException {
// write final boundary
out.writeBytes(PREFIX);
out.writeBytes(boundary);
out.writeBytes(PREFIX);
out.writeBytes(NEWLINE);
out.flush();
out.close();
}

/**
* Gets the multipart boundary string being used by this stream.
*
* @return the boundary
*/

public String getBoundary() {
return this.boundary;
}

/**
* Creates a new java.net.URLConnection object from the
* specified java.net.URL. This is a convenience method
* which will set the doInput, doOutput,
* useCaches and defaultUseCaches fields to
* the appropriate settings in the correct order.
*
* @return a java.net.URLConnection object for the URL
* @throws java.io.IOException on input/output errors
*/

public static URLConnection createConnection(URL url)
throws java.io.IOException {
URLConnection urlConn = url.openConnection();
if(urlConn instanceof HttpURLConnection) {
HttpURLConnection httpConn = (HttpURLConnection)urlConn;
httpConn.setRequestMethod("POST");
}
urlConn.setDoInput(true);
urlConn.setDoOutput(true);
urlConn.setUseCaches(false);
urlConn.setDefaultUseCaches(false);
return urlConn;
}

/**
* Creates a multipart boundary string by concatenating 20 hyphens (-)
* and the hexadecimal (base-16) representation of the current time in
* milliseconds.
*
* @return a multipart boundary string
* @see #getContentType(String)
*/

public static String createBoundary() {
return "--------------------" +
Long.toString(System.currentTimeMillis(), 16);
}

/**
* Gets the content type string suitable for the
* java.net.URLConnection which includes the multipart
* boundary string.

*

* This method is static because, due to the nature of the
* java.net.URLConnection class, once the output stream
* for the connection is acquired, it's too late to set the content
* type (or any other request parameter). So one has to create a
* multipart boundary string first before using this class, such as
* with the createBoundary() method.
*
* @param boundary the boundary string
* @return the content type string
* @see #createBoundary()
*/

public static String getContentType(String boundary) {
return "multipart/form-data; boundary=" + boundary;
}
}


Usage: (try/catch left out to shorten the post a bit)
URL url = new URL("http://www.domain.com/webems/upload.do");
// create a boundary string
String boundary = MultiPartFormOutputStream.createBoundary();
URLConnection urlConn = MultiPartFormOutputStream.createConnection(url);
urlConn.setRequestProperty("Accept", "*/*");
urlConn.setRequestProperty("Content-Type",
MultiPartFormOutputStream.getContentType(boundary));
// set some other request headers...
urlConn.setRequestProperty("Connection", "Keep-Alive");
urlConn.setRequestProperty("Cache-Control", "no-cache");
// no need to connect cuz getOutputStream() does it
MultiPartFormOutputStream out =
new MultiPartFormOutputStream(urlConn.getOutputStream(), boundary);
// write a text field element
out.writeField("myText", "text field text");
// upload a file
out.writeFile("myFile", "text/plain", new File("C:\\test.txt"));
// can also write bytes directly
//out.writeFile("myFile", "text/plain", "C:\\test.txt",
// "This is some file text.".getBytes("ASCII"));
out.close();
// read response from server
BufferedReader in = new BufferedReader(
new InputStreamReader(urlConn.getInputStream()));
String line = "";
while((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();

금요일, 12월 09, 2005

리눅스에서 ACE 설치하기

1 리눅스에서 ACE 설치하기

리눅스에서 ACE 설치하는 것은 보통의 Unix 머신에서 ACE 설치하는 것과 정확히 동일한 방식을 따른다.

  1. ACE.tar.gz 파일을 우선 다운로드해서 tar.gz을 푼다.
    • 그러면 ACE_wrappers 디렉토리가 생긴다.
  2. 환경변수 두가지를 설정해야 한다. ACE_ROOT 와 LD_LIBRARY_PATH 인데,
    • ACE_ROOT = ~/ACE_wrappers 가 되도록 하고,
      • csh 에서는 % setenv ACE_ROOT ~myhome/ACE_wrappers
    • LD_LIBRARY_PATH 에 ~/ACE_wrappers/ace 가 추가되도록 한다.
      • csh 에서는 % setenv LD_LIBRARY_PATH ${ACE_ROOT}/ace:${LD_LIBRARY_PATH}
  3. 두개의 설정파일을 생성해 준다.
    • ACE_ROOT/ace 디렉토리에서
      • ln -s config-linux.h config.h 명령어를 수행하고,
      • 주의: config-linux-common.h 가 아님.
    • ACE_ROOT/include/makeinclude 디렉토리에서
      • ln -s platform_linux.GNU platform_macros.GNU 명령어를 수행한다.
  4. 그러고 나서, ~/ACE_wrapeprs/ace 디렉토리에 가서
    • make 라고 치면 만들어진다.
    • ~/ACE_wrappers 에서 make 치면 모든 테스트 루틴을 다 컴파일 하기 때문에, 총 컴파일 시간이 40 분 이상 걸린다.
      • 총 컴파일 결과가 압축해서 240 메가 바이트가 될 정도로 무시무시하게 크다.
    • 최적화 버젼으로 컴파일하면 결과가 10 메가 내외로 줄어든다.
      • make stdcpplib=1 debug=0 exceptions=1 optimize=1
  5. 문제없이 make 가 되었으면, 제대로 동작하는 지를 확인하기 위해서,
    • ACE_ROOT/examples/Threads 에 가서 make 하고, (5분 소요)
      • 만약 make 수행했는데,
        • Makefile: 43: /include/makeinclude/wrapper_macros.GNU: 그런 파일이나 디렉토리가 없음
        • Makefile: 44: /include/makeinclude/macros.GNU: 그런 파일이나 디렉토리가 없음
        • Makefile: 45: /include/makeinclude/rules.common.GNU: 그런 파일이나 디렉토리가 없음
        • Makefile: 46: /include/makeinclude/rules.nonested.GNU: 그런 파일이나 디렉토리가 없음
        • Makefile: 47: /include/makeinclude/rules.bin.GNU: 그런 파일이나 디렉토리가 없음
        • Makefile: 48: /include/makeinclude/rules.local.GNU: 그런 파일이나 디렉토리가 없음
      • 이렇게 나오면, ACE_ROOT 변수가 세팅되지 않은 것이다.
      • 만약 make 를 수행했는데, make: Nothing to be done for `all'. 이라고 나오면, 이미 다 만들어진 경우이다.
    • make가 다되었으면, ./task_one 이라는 명령어를 수행할 수 있다.
      • 만약 ./task_one을 수행할 때,
        • ./task_one: error while loading shared libraries: libACE.so.5.2.7: cannot open shared object file: No such file or directory
      • 이렇게 나오면, LD_LIBRARY_PATH 에 ACE_ROOT/ace 가 추가되어 있지 않은 것이다.
    • ./task_one 이 제대로 실행되면, ACE 가 정상적으로 설치된 것이다.

참고1: [WWW]Red Pixel의 리눅스설치 페이지 * 솔라리스에 설치하기전

vim에서 보이는 특수기호

ASCII 대응표
10진수설명기호
0NUL[^@]
1SOH[^A]
2STX[^B]
3ETX[^C]
4EOT[^D]
5ENQ[^E]
6ACK[^F]
7BEL[^G]
8BS[^H]
11VT[^K]
12NP[^L]
13CR[^M]
14SO[^N]
15SI[^O]
16DLE[^P]
17DC1[^Q]
18DC2[^R]
19DC3[^S]
20DC4[^T]
21NAK[^U]
22SYN[^V]
23ETB[^W]
24SP[^X]
25EM[^Y]
26SUB[^Z]
27ESC[^[]
28FS[^\]
29GS[^]]
30RS[]
31US[^_]
127DEL[^?]

특수기호 읽는법

특수기호 읽는법
기호이름
!Exclamation Point(익스클레메이션 포인트)
"Quotation Mark(쿼테이션 마크)
#Crosshatch (크로스해치)
$Dollar Sign (달러사인)
%Percent Sign (퍼센트사인)
@At Sign (엣 사인, 혹은 엣)
&Ampersand (앰퍼센드)
'Aposterophe (어퍼스트로피)
*Asterisk (아스테리스크)
-Hyphen (하이픈)
.Period (피리어드)
/Slash (슬래시)
\Back Slash (백슬래시)
:Colon (콜론)
;Semicolon (세미콜론)
^Circumflex (서큠플렉스)
`Grave (그레이브)
{Left Brace (레프트 브레이스)
}Right Brace (라이트 브레이스)
[Left Braket (레프트 브라켓)
]Right Braket (라이트 브라켓)
|Vertical Bar (버티컬바)
~Tilde (틸드)

브라우져버젼별js버젼

// *** JAVASCRIPT VERSION CHECK ***
var is_js;
if (is_nav2 || is_ie3) is_js = 1.0;
else if (is_nav3) is_js = 1.1;
else if (is_opera5up) is_js = 1.3;
else if (is_opera) is_js = 1.1;
else if ((is_nav4 && (is_minor <= 4.05)) || is_ie4) is_js = 1.2; else if ((is_nav4 && (is_minor > 4.05)) || is_ie5) is_js = 1.3;
else if (is_hotjava3up) is_js = 1.4;
else if (is_nav6 || is_gecko) is_js = 1.5;
// NOTE: In the future, update this code when newer versions of JS
// are released. For now, we try to provide some upward compatibility
// so that future versions of Nav and IE will show they are at
// *least* JS 1.x capable. Always check for JS version compatibility
// with > or >=.
else if (is_nav6up) is_js = 1.5;
// NOTE: ie5up on mac is 1.4
else if (is_ie5up) is_js = 1.3

thread safe function

Table 6-1 Reentrant Functions
alphabetical ordergethostbyaddr_r(3n)getrpcent_r(3n)
asctime_r(3c)gethostbyname_r(3n)getservbyname_r(3n)
ctermid_r(3s)gethostent_r(3n)getservbyport_r(3n)
ctime_r(3c)getlogin_r(3c)getservent_r(3n)
fgetgrent_r(3c)getnetbyaddr_r(3n)getspent_r(3c)
fgetpwent_r(3c)getnetbyname_r(3n)getspnam_r(3c)
fgetspent_r(3c)getnetent_r(3n)gmtime_r(3c)
gamma_r(3m)getnetgrent_r(3n)lgamma_r(3m)
getauclassent_r(3)getprotobyname_r(3n)localtime_r(3c)
getauclassnam_r(3)getprotobynumber_r(3n)nis_sperror_r(3n)
getauevent_r(3)getprotoent_r(3n)rand_r(3c)
getauevnam_r(3)getpwent_r(3c)readdir_r(3c)
getauevnum_r(3)getpwnam_r(3c)strtok_r(3c)
getgrent_r(3c)getpwuid_r(3c)tmpnam_r(3s)
getgrgid_r(3c)getrpcbyname_r(3n)ttyname_r(3c)
getgrnam_r(3c)getrpcbynumber_r(3n).

TortoiseCVS 사용법

TortoiseCVS 사용법

* 작성: 2005-04-04 eek@mobigen.com

1 환경설정

  • 내컴퓨터 > 속성 > 고급 > 환경변수 새로 만들기선택후 CVSROOT환경변수를 설정한다.
  • env.jpg
  • Diff tool설정
    • TortoiseCVS에서 diff Tools은 acroedit의 acrodiff.exe를 추천합니다.
    • acroedit 설치
    • CVS > Preferences > Tools

2 프로젝트 생성

  • 프로젝트 폴더를 선택하고 왼쪽마우스버튼 클릭 후
    • cvs > make new module... 선택
    • Module: 부분에 프로젝트명을 입력후 OK 클릭
    • make_new_module.gif
  • CVS > ADD > OK
    • cvs_add.gif
    • cvs_add_ok.gif
  • CVS > Commit... > OK
    • cvs_commit.gif
    • cvs_commit_ok.gif

3 충돌에 대한 해결

  • CVS > commit 선택
    • cvs_ci_err.gif
  • CVS > update 선택
    • cvs_up_err.gif

4 프로젝트 가지고 오기

  • CVS > Checkout...
    • cvs_checkout.gif
    • cvs_checkout2.gif

5 파일별 상태

  • 파일의 일반적인 상태 v
  • 파일 수정 또는 추가는 +
  • 파일를 CVS업데이트 무시 x
  • 파일이 충돌이 발생한 경우 !
  • 파일 삭제는 바로 삭제됨
    • ex)
    • cvs_ex.gif

6 질문&답변

  • 한글로 업데이트 한 파일의 내용이 깨지는 문제
    • cvs > preferences > Main > Language: 한국어로 설정함.
  • vc 리소스(resource.rc)파일 한글이 깨지는 현상
    • Dialog Properties > Font name을 한글 폰트로 수정 후 커밋함.

7 참조

cvs 사용법

CVS

  • 작성: eekplus
    1. CVS 설치방법
      1.1. Linux 설치
        1.1.1. 계정생성
        1.1.2. xinet.d등록
        1.1.3. xinet restart
      1.2. test
      1.3. 초기화
    2. CVS 명령어 사용법
      2.1. 계정생성
      2.2. 새 프로젝트는 어떻게 만드나요?
      2.3. Login
      2.4. Check out
        2.4.1. 메인버젼 꺼내 오기
        2.4.2. 특정버젼 꺼내 오기
      2.5. Update
      2.6. Commit(저장)
      2.7. Diff(비교)
      2.8. Remove(삭제)
      2.9. Add(파일 추가)
      2.10. 특정파일무시하기
      2.11. branch는 어떻게 만들죠?
      2.12. FAQ
    3. 참고 자료

1 CVS 설치방법

1.1 Linux 설치

1.1.1 계정생성

  • root 계정으로 cvs계정과 cvs 그룹을 생성한다.
    $ adduser cvs

1.1.2 xinet.d등록

  • /etc/xinet.d에 서비스로 등록한다.
  • vi /etc/xinet.d/cvspserver
    # default: on
    # description: cvs pserver
    service cvspserver
    {
    disable = no
    flags = REUSE
    socket_type = stream
    wait = no
    user = root
    server = /usr/bin/cvs
    server_args = -f --allow-root=/home/cvs pserver
    log_on_failure += USERID
    }

1.1.3 xinet restart

  • cd /etc/init.d/
  • ./xinetd restart
    xinetd 를 정지함: [ 확인 ]
    xinetd (을)를 시작합니다: [ 확인 ]

1.2 test

  • telnet localhost 4300
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.

    cvs [pserver aborted]: bad auth protocol start:

    Connection closed by foreign host.

1.3 초기화

  • su - cvs
  • cvs -d /home/cvs init
  • ls -a
    . .. CVSROOT

2 CVS 명령어 사용법

2.1 계정생성

  • cvs가 설치되어있는 위치 CVSROOT의 passwd파일에 사용자 ID와 PASSWORD를 입력한다.
    $ cd /home/cvs/CVSROOT/
    $ mkpasswd
    makepasswd - generates system password entry for cvsd

    usage: ./mkpasswd user password

    $ ./mkpasswd test test123
    makepasswd - generates system password entry for cvsd

    put this line into /CVSROOT/passwd
    test:xB0y/2RhqIHx6:cvs

    # passwd파일을 open후 "test:xB0y/2RhqIHx6:cvs"이 라인을 복사하여 추가한다.
    $ vi passwd

2.2 새 프로젝트는 어떻게 만드나요?

$ ls proj/
README a.c a.h
$ cd proj/
$ cvs import -m "this is the project" proj VENDOR INIT
$ ls /var/cvsroot/
CVSROOT/ proj/
$ ls /var/cvsroot/proj/
README,v a.c,v a.h,v

2.3 Login

  1. 최초 로그인 시
    touch ~/.cvslogin
  2. CVSROOT설정
    bash, ksh
    export CVSROOT=:pserver:xxx@test.mobigen.com:/home/cvs
    csh
    setenv CVSROOT :pserver:xxx@test.mobigen.com:/home/cvs

    xxx부분에 계정명을 입력한다.
    예)
    $ export CVSROOT=:pserver:eek@test.mobigen.com:/home/cvs
  3. cvs 를 사용하기 위해서 cvs에 접근하기 위한 권한을 얻는 방법으로 로그인을 합니다. 계정을 만드는 방법은 추후에 내용을 추가 하겠습니다.
    $ cvs login
    Logging in to :pserver:eek@test.mobigen.com:2401/home/cvs
    CVS password:

    비밀번호를 입력합니다.

2.4 Check out

2.4.1 메인버젼 꺼내 오기

  • 현재 개발하고 있는 프로젝트 이름을 입력합니다. 예) mobi
    cvs checkout mobi

2.4.2 특정버젼 꺼내 오기

  • 메인버젼을 개발 도중 특정 버젼으로 패키지한 버젼의 소소코드를 꺼내오기 싶은경우
    cvs checkout -r 버젼_번호 프로젝트명
    예)
    cvs checkout -r r2-8-0 mobi

2.5 Update

  1. checkout한경우 변경된 내용만 받아 올 수 있도록 하는 기능
    • check out한 디렉토리로 이동하여 명령을 실행한다.

    $ cvs update
    ? Makefile
    cvs server: Updating .
    ...
    U htable.C
    U htable.h
    ...
  2. U, P 표시는 cvs에서 수정이 된 파일 기존에 파일이 변경됨
  3. M 표시는 사용자가 파일을 수정한 경우 M flag가 표시됨
  4. C 표시는 사용자가 파일을 수정한 경우 CVS 메인 버젼과 충돌이 생긴 경우
    • 충돌 후 해결을 참조
  5. ? 표시는 CVS에 저장 되어 있지 않는 파일 또는 디렉토리
  6. A 표시는 CVS에 사용자기 추가하기 전 상태 삭제를 적용하기 위해서는 cvs commit명령을 수행한다.
  7. R 표시는 CVS에 있는 파일을 삭제하기 전 상태 삭제를 적용하기 위해서는 cvs commit 명령을 수행한다.

2.6 Commit(저장)

  1. repository로 보낼려면 commit을 수행하면 됩니다.
    수정한 파일 하나만 올린다
    $ cvs commit 파일명
    또는
    수정한 모든 파일을 올린다
    $ cvs commit

2.7 Diff(비교)

  1. 수정된 내용을 확인하고 싶은경우
    $ cvs diff 파일명
  2. 수정된 내용을 이전버젼과 비교하고 싶은경우
    $ cvs diff -r 1.2 파일명

2.8 Remove(삭제)

  1. 파일 지우기
    $ rm 파일명
    $ cvs remove 파일명
    $ cvs commit
    Removing 파일명;
    파일명,v <-- 파일명
    new revision: delete; previous revision: 1.1
    done

2.9 Add(파일 추가)

  1. 파일 추가
    $ cvs update
    ? add_file <-- 아직 추가 되어있진 않은 상태로 보인다.
    $ cvs add add_file1 [add_file2] [add_file3] [add_file4]
    $ cvs update
    A add_file <-- 추가되기 위한 전단계
    $ cvs commit add_file <-- 파일추가
  2. Dir 추가
    • Dir을 추가 하고 앞에 있는 파일은 파일 추가 절차에 따른다.

    $ mkdir a_dir
    $ cvs add a_dir
    $ cvs commit a_dir
    $ cd a_dir
    $ ls
    CVS/
    $

2.10 특정파일무시하기

  • .o 파일 이나 임시 파일을 cvs를 저장하면 컴파일할때마다 update되었다고 표시된다 이런경우 삭제하면 update하는 경우에 다시 내려받기 때문에 cvs에서 리스트 무시하도록 표시하는 기능을 제공한다.
  • ※ 주의: .cvsignore파일도 cvs에 add하지 않으면 다른 사용자와 같은 환경을 공유할 수 없다.
    $ vi .cvsignore
    #무시하고 싶은 파일을 기록한다.
    *.obj
    *.o
    *.tmp
    *.log
    $ cvs add
    $ cvs commit

2.11 branch는 어떻게 만들죠?

  1. 특정 버젼 쉽게 만드는 법
    브랜치를 쉽게 만드는 방법입니다.
    $ cvs tag -b BRANCHNAME
    이 명령을 실행한 작업소는 앞으로 이 브랜치로 작업을 하게 됩니다.
  2. ※ 특정 버젼을 가지고 오는 방법을 찾조하시면 됩니다. ;)

2.12 FAQ

  1. undelete
$ cvs checkout project; cd project
$ cvs update foo.c
$ cvs tag release-1 .
$ cd ..; cvs release -d project

$ cvs checkout -r release-1 project
$ cvs release -d project


$ cvs rtag -b -r release-1 release-1-patches project
$ cvs checkout -r release-1-patches project
$ cvs commit -m "Fixed printf bug" foo.c
$ cd ..; cvs release -d project



--------------------------------------------------------------------------------
cvs를 사용할 때 Branch를 해서 버젼을 만들고 메인 버젼이 올라가면 다시 메인버젼과 머지를 하고.. 등의 작업을 수행할 때, 먼저 브랜치를 할 파일들에 태그를 달아주고 태그를 기준으로 브랜치를 만드는 것이 편한 것 같습니다.


명령어는 다음과 같습니다.


cvs rtag -r arab -b arab_xxx ggg


이렇게 하면 ggg라는 프로젝트에서 arab 태그가 붙은 것을 arab_xxx 브랜치로 작성하겠다. 라는 의미가 됩니다. 태그는 먼저 달아주어야 하겠지요.


그리고 태그와 브랜치는 다르다는 점을 미리 아시면 좋겠고.. 만일 wincvs를 사용하신다면 graph를 보시게 되면 tag는 검정색 얇은 선 브랜치는 파란색 굵은 선으로 나뉘는 것을 알 수 있습니다. --최성우 / eatingstars.com


브랜치를 쉽게 만드는 방법입니다.
$ cvs tag -b BRANCHNAME
이 명령을 실행한 작업소는 앞으로 이 브랜치로 작업을 하게 됩니다.

3 참고 자료

메모리 리크 체크 유틸리티 (ccmalloc) 사용법

메모리 리크 체크 유틸리티 (ccmalloc) 사용법

저자 홈페이지: http://www.inf.ethz.ch/personal/biere
CCMALLOC 홈페이지: http://www.inf.ethz.ch/personal/biere/projects/ccmalloc/

1. ccmalloc이란... (works only with g++/gcc, partly with Solaris cc)

C/C++의 메모리 리크(leak)를 체크해 주는 오픈소스 유틸리티이다. 기존의 상업용으로 나오는 Purify 같은 제품에 비해서, 일부 기능이 부족한 점도 있지만, 공짜로 쓸 수 있는 메모리 리크(leak) 체크 프로그램으로는 단연 최우수라고 할 수 있다.

ccmalloc의 가장 큰 장점은 그 사용의 단순성에 있다. 소스코드를 "전혀 고치지" 않고 단지 ccmalloc 라이브러리를 링크만 해 주면 된다.

2. ccmalloc 다운로드

http://www.inf.ethz.ch/personal/biere/projects/ccmalloc/ccmalloc-0.3.9.tar.gz http://www.inf.ethz.ch/personal/biere/projects/ccmalloc/ccmalloc-0.4.0.tar.gz


3. ccmalloc 설치

tar.gz 을 풀고, ./ccmalloc-0.4.0/src 디렉토리에서,

#솔라리스 경우만 및에 config.h를 include 하는 코드를 추가한다.
$vi ccmalloc.cc
#include "ccmalloc.h"
#include

#include "config.h" <-- 추가


configure / make 명령어를 쓰면,

~/ccmalloc-0.4.0/lib 디렉토리에 libccmalloc.a 가 생긴다.
~/ccmalloc-0.4.0/obj 디렉토리에 ccmalloc-g++.o 가 생긴다.
~/ccmalloc-0.4.0/obj 디렉토리에 ccmalloc-gcc.o 가 생긴다.

주의:

최초에 생성된 libccmalloc.a 파일에는 ccmalloc-g++.o 가 추가되어 있지 않으므로, ~/ccmalloc-0.4.0 디렉토리에서 다음 명령어를 써서 ccmalloc-g++.o 가 추가되도록 한다.

% ar rc lib/libccmalloc.a obj/ccmalloc-g++.o
% ar rc lib/libccmalloc.a obj/ccmalloc-gcc.o

결과적으로 ~/ccmalloc-0.4.0/lib/libccmalloc.a 가 우리가 원하는 최종 라이브러리이다.

만약 여러 프로젝트에서 쓸 것 같으면, libccmalloc.a 파일만 원하는 라이브러리 디렉토리 (예: /usr/local/lib) 에 복사해 두고 그것을 쓰면 된다.

4. ccmalloc을 사용한 컴파일

만약 내 프로그램이 test.c++ 라고 가정하면 다음과 같이 링크 옵션을 준다.

% g++ -g test.c++ -o test.exe -L./ccmalloc-0.4.0/lib -lccmalloc -ldl

(여기서 -g 옵션은 test.c++ 의 디버깅 정보를 넣기 위함이다. -ldl 이 필요한 경우도 있음. )

또는 Makefile 속에

LIB_CCMALLOC = -L./ccmalloc-0.4.0/lib -lccmalloc -ldl

를 추가한다.

5. ccmalloc 이 링크된 프로그램의 실행

우선 ./ccmalloc-0.4.0/ccmalloc.cfg 파일을 실행프로그램이 있는 디렉토리에 .ccmalloc 파일로 복사해 둔다.

% cp ./ccmalloc-0.4.0/ccmalloc.cfg .ccmalloc

복사된 .ccmalloc 파일에 다양한 옵션을 바꿀 수 있다. (우선은 아무것도 고치지 않고 돌려도 무방하다.)

그냥 보통 프로그램 실행시키는 것과 동일한 방식으로 실행시키면 된다. 실행시키면, 로그파일을 생성하지 않도록 했으면, 화면에 STDERR로 현재 설정된 옵션이 보이고, 프로그램이 끝나면, free/delete/release 가 되지 않은 메모리가 정확히 어느 위치에서 malloc/new 되었는지를 스택 트레이스 형태로 보여 준다.

.ccmalloc 파일 중에, %log FILE 옵션을 log ccmalloc.log 라고 바꿔주면, 프로그램 실행이 끝난 후에 ccmalloc.log 파일 속에 결과가 쌓인다.

6. 데몬 형태의 프로그램에 대한 메모리 리크 디버깅

ccmalloc은 프로그램이 종료될 때 로그를 생성하므로, 데몬 프로그램 일정횟수 이상 동작한 후 자동으로 종료되도록 코드를 일부 수정해서 처리할 필요가 있다.

7. Enjoy you life. Ccmalloc frees you up out of terrible C/C++ memories.

Error Code

#define EPERM 1 /* Not super-user */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Arg list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No children */
#define EAGAIN 11 /* Resource temporarily unavailable */
#define ENOMEM 12 /* Not enough core */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Mount device busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Inappropriate ioctl for device */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math arg out of domain of func */
#define ERANGE 34 /* Math result not representable */
#define ENOMSG 35 /* No message of desired type */
#define EIDRM 36 /* Identifier removed */
#define ECHRNG 37 /* Channel number out of range */
#define EL2NSYNC 38 /* Level 2 not synchronized */
#define EL3HLT 39 /* Level 3 halted */
#define EL3RST 40 /* Level 3 reset */
#define ELNRNG 41 /* Link number out of range */
#define EUNATCH 42 /* Protocol driver not attached */
#define ENOCSI 43 /* No CSI structure available */
#define EL2HLT 44 /* Level 2 halted */
#define EDEADLK 45 /* Deadlock condition. */
#define ENOLCK 46 /* No record locks available. */
#define ECANCELED 47 /* Operation canceled */
#define ENOTSUP 48 /* Operation not supported */

/* Filesystem Quotas */
#define EDQUOT 49 /* Disc quota exceeded */

/* Convergent Error Returns */
#define EBADE 50 /* invalid exchange */
#define EBADR 51 /* invalid request descriptor */
#define EXFULL 52 /* exchange full */
#define ENOANO 53 /* no anode */
#define EBADRQC 54 /* invalid request code */
#define EBADSLT 55 /* invalid slot */
#define EDEADLOCK 56 /* file locking deadlock error */

#define EBFONT 57 /* bad font file fmt */

/* Interprocess Robust Locks */
#define EOWNERDEAD 58 /* process died with the lock */
#define ENOTRECOVERABLE 59 /* lock is not recoverable */

/* stream problems */
#define ENOSTR 60 /* Device not a stream */
#define ENODATA 61 /* no data (for no delay io) */
#define ETIME 62 /* timer expired */
#define ENOSR 63 /* out of streams resources */

#define ENONET 64 /* Machine is not on the network */
#define ENOPKG 65 /* Package not installed */
#define EREMOTE 66 /* The object is remote */
#define ENOLINK 67 /* the link has been severed */
#define EADV 68 /* advertise error */
#define ESRMNT 69 /* srmount error */

#define ECOMM 70 /* Communication error on send */
#define EPROTO 71 /* Protocol error */

/* Interprocess Robust Locks */
#define ELOCKUNMAPPED 72 /* locked lock was unmapped */

#define EMULTIHOP 74 /* multihop attempted */
#define EBADMSG 77 /* trying to read unreadable message */
#define ENAMETOOLONG 78 /* path name is too long */
#define EOVERFLOW 79 /* value too large to be stored in data type */
#define ENOTUNIQ 80 /* given log. name not unique */
#define EBADFD 81 /* f.d. invalid for this operation */
#define EREMCHG 82 /* Remote address changed */

/* shared library problems */
#define ELIBACC 83 /* Can't access a needed shared lib. */
#define ELIBBAD 84 /* Accessing a corrupted shared lib. */
#define ELIBSCN 85 /* .lib section in a.out corrupted. */
#define ELIBMAX 86 /* Attempting to link in too many libs. */
#define ELIBEXEC 87 /* Attempting to exec a shared library. */
#define EILSEQ 88 /* Illegal byte sequence. */
#define ENOSYS 89 /* Unsupported file system operation */
#define ELOOP 90 /* Symbolic link loop */
#define ERESTART 91 /* Restartable system call */
#define ESTRPIPE 92 /* if pipe/FIFO, don't sleep in stream head */
#define ENOTEMPTY 93 /* directory not empty */
#define EUSERS 94 /* Too many users (for UFS) */

/* BSD Networking Software */
/* argument errors */
#define ENOTSOCK 95 /* Socket operation on non-socket */
#define EDESTADDRREQ 96 /* Destination address required */
#define EMSGSIZE 97 /* Message too long */
#define EPROTOTYPE 98 /* Protocol wrong type for socket */
#define ENOPROTOOPT 99 /* Protocol not available */
#define EPROTONOSUPPORT 120 /* Protocol not supported */
#define ESOCKTNOSUPPORT 121 /* Socket type not supported */
#define EOPNOTSUPP 122 /* Operation not supported on socket */
#define EPFNOSUPPORT 123 /* Protocol family not supported */
#define EAFNOSUPPORT 124 /* Address family not supported by */
/* protocol family */
#define EADDRINUSE 125 /* Address already in use */
#define EADDRNOTAVAIL 126 /* Can't assign requested address */
/* operational errors */
#define ENETDOWN 127 /* Network is down */
#define ENETUNREACH 128 /* Network is unreachable */
#define ENETRESET 129 /* Network dropped connection because */
/* of reset */
#define ECONNABORTED 130 /* Software caused connection abort */
#define ECONNRESET 131 /* Connection reset by peer */
#define ENOBUFS 132 /* No buffer space available */
#define EISCONN 133 /* Socket is already connected */
#define ENOTCONN 134 /* Socket is not connected */
/* XENIX has 135 - 142 */
#define ESHUTDOWN 143 /* Can't send after socket shutdown */
#define ETOOMANYREFS 144 /* Too many references: can't splice */
#define ETIMEDOUT 145 /* Connection timed out */
#define ECONNREFUSED 146 /* Connection refused */
#define EHOSTDOWN 147 /* Host is down */
#define EHOSTUNREACH 148 /* No route to host */
#define EWOULDBLOCK EAGAIN
#define EALREADY 149 /* operation already in progress */
#define EINPROGRESS 150 /* operation now in progress */

/* SUN Network File System */
#define ESTALE 151 /* Stale NFS file handle */

수요일, 12월 07, 2005

Eclipse + Regular Expression Tester

Regular Expression Tester



java에서는 perl만큼 regex사용하기가 편하지는 않지만. regex test가 있으니 조금은 좋은 환경에서 작업할 수 있겠군요.

http://brosinski.com/regex/

월요일, 12월 05, 2005

UNIX정보

{{{
* ifstream
- Sun OS 2.6
- Sun OS 2.7 에서 256개
open만 됨.
* BUFSIZ
- Sun OS 2.6 인경우 1024 byte
- Sun OS 2.7~2.8 4096 byte
}}}

{{{
* 2039년 문제
32bit UNIX머신에서 2039년으로 표현이 않되는 문제가 발생함.
}}}


{{{

Unix Incompatibility Notes:
Password Checking
Jan Wolter
Suppose we have a login name and a plain-text password, and we want to know if they are valid on our system. How do we check this?
There are always three steps:

Use the user's login to look up the user's encrypted password in the appropriate database.
Encrypt the plain-text password.
Compare the two with strcmp(). If they match, the login is valid.
Both of the first two steps are done differently on different Unixes. We will outline those variations here.
We will not discuss authenticating through PAM here. See elsewhere.

1. Traditional
In traditional Unix systems, the user's encrypted password was stored in the /etc/passwd file. Because /etc/passwd is publicly readable, you don't need to be root to check authentication on such systems. Passwords are fetched with getpwnam() and encrypted with crypt(), as follows:
#include
:
struct passwd *user;
:
if ((user= getpwnam(login)) == NULL)
printf("No such user\n");
else if (!strcmp(user->pw_passwd, crypt(password, user->pw_passwd))
printf("Password correct\n");
else
printf("Password incorrect\n");
On some systems, you will need to link with -lcrypt to get the crypt() function.
2. BSD Shadow System
These days it is considered a really bad idea to have encrypted passwords in a publicly readable file so they are no longer stored in /etc/passwd on most modern Unix systems. Instead they are stored in a ``shadow'' database (often the file /etc/shadow) which is only readable by root.
Most BSD systems, including FreeBSD, NetBSD, OpenBSD, and BSDI implement this very transparently. You still call getpwnam(), but if you aren't root, it doesn't return the encrypted password. Thus the password checking code looks exactly like the traditional code, except you have to be root for it to work.

3. Sun Shadow System
Sun's Solaris operating system and all recent Linux versions use a separate call, getspnam() to get information from the shadow database. It works like this:
#include
:
struct spwd *user;
:
if ((user= getspnam(login)) == NULL)
printf("No such user\n");
else if (!strcmp(user->sp_pwdp, crypt(password, user->sp_pwdp))
printf("Password correct\n");
else
printf("Password incorrect\n");
On some systems, you will need to link with -lcrypt to get the crypt() function.
The open source Linux version of this was developed by Julianne F. Haugh. Some installations that use that may need to link with -lshadow to get the getspnam() function (and faster versions of getpwnam()).

Ancient versions of the Julianne F. Haugh shadow package replaced the crypt() function with one named pw_encrypt() which was supposed to do a better job encrypting long passwords. It didn't really, and has fallen into disfavor, and is rarely seen now. It's arguments were the same as those to crypt().

4. AIX Shadow System
I believe that if you are root on AIX, getpwnam() will return the encrypted password, just like the BSD systems. However their manual pages suggest that it is prefered to use the getuserpw() routine to fetch the password. If you use this, I think the code is something like this:
#include
:
struct userpw *user;
:
if ((user= getuserpw(login)) == NULL)
printf("No such user\n");
else if (!strcmp(user->upw_passwd, crypt(password, user->upw_passwd))
printf("Password correct\n");
else
printf("Password incorrect\n");
I haven't actually tried this.
5. HP-UX Shadow System
It appears that HP-UX's shadow system uses getprpwnam() to access the shadow database. The code is apparantly like this:
#include
#include
#include
:
struct pr_passwd *user;
:
if ((user= getspwnam(login)) == NULL)
printf("No such user\n");
else if (!strcmp(user->ufld.fd_encrypt,
crypt(password, user->ufld.fd_encrypt))
printf("Password correct\n");
else
printf("Password incorrect\n");
I haven't actually tried this. It's possible that you have to call bigcrypt() instead of crypt().
HP-UX also has a function called getspwnam() which returns the encrypted password with less other baggage than getprpwnam() does, but their documentation suggests it is depreciated.

}}}

토요일, 12월 03, 2005

EFFECTIVE STL 간단 요약

----------------------------------------------------------------------------------------------------
[EFFECTIVE STL]
----------------------------------------------------------------------------------------------------
[1 : Containers]

[ITEM 1 : Choose your containers with care]

standard STL sequence containers : vector string, dequeue, list
standard STL associative containers : set, multiset, map, and multimap



----------------------------------------------------------------------------------------------------
[2 : Vector and string]


vector , string 가지고 모든 array 관련 application 대체 가능

1. vector, string의 performance 향상 방법
2. string implemenation의 다양성
[ITEM 13 : Prefer vector and string to dynamically allocated arrays]

[ITEM 16 : Know how to pass vector and string data to legacy APIs]


vector v : &v[0] first element에 대한 포인터

void doSomething(const int * plnts, size_t numInts);

// EMPTY 체크 해야함
if(!v.empty()) doSomething(&v[0], v.size());

char * --> string 으로 대체
void doSomething(const char *p)

string s
// string 이 length 0 이어도 문제 없이 동작 --> null charactor 에 대한 포인터 리턴
// string 은 null character 또한 가질수 있다.
doSomething(s.c_str());


[주의]

시나리오 1 : C API 로 부터 array 사이즈 만큼 초기화 시킨다.

size_t fillArray(double *pArray, size_t arraySize)

vector vd(maxNumDoubles);
vd.resize(fillArray(&vd[0], vd.size());

vector 인 경우는 문제 없는 시나리오 (vector와 array memory layout 은 동일)


시나리오 2 : 시나리오 1인데 string을 초기화 시킨다.
--> vector를 가지고 구현해야만 가능


size_t fillString(char *pArray, size_t arraySize);

vector vc(maxNumChars);

// ------------> TERRABLE CODE
// string s;
//size_t charWritten = fillString(s.c_str(), maxNumChars);

size_t charWritten = fillString(&vc[0], vc.size());

string s(vc.begin(), vc.begin() + charWritten);

결론 : C API 사용시 vector에 data를 넣고 해당 STL container에 copy 하는 순서를 따라야함.




void doSomething(const int * plnts, size_t numInts); // C API

set intSet;
vector v(intSet.begin(), intSet.end());
...
vector v(intSet.begin(), intSet.end());

// EMPTY 체크 해야함
if(!v.empty()) doSomething(&v[0], v.size());











string s : s.c_str()

but, certain restriction








----------------------------------------------------------------------------------------------------
[3 : Associative Container]

[ITEM 19 : Understand the difference between equality and equivalence]


EQUQLITY : find algorithm (operator== 사용)

EQUIVALENCE : set::insert (operator< 사용) set ciss;
set::iterator iter;
bool inserted;

boost::tie(iter,inserted) = ciss.insert("aired");

BOOST_TEST(inserted == true);

boost::tie(iter,inserted) = ciss.insert("AIRED");
BOOST_TEST(inserted == false);


// EQUIVALCE 연산 : CIStringCompare comparation functor 에 의해 equivalent 하나 equal 은 아님
// ITEM44 참고
BOOST_TEST(ciss.find("aired") != ciss.end());

// find algorithm 은 equality 연산 : operator==
// ASSERT FAIL
BOOST_TEST(find(ciss.begin(), ciss.end(),"Aired") != ciss.end());


왜 standard associative container는 equivalence 기반인가? ( 답 ?)

TWO Comparison Function

1 : sorted order 유지 : default less comparison function
Equivalence를 only one comparision function 에서 정의함
2 : Equility 에 대한 default comparision function 존재(equal_to)
그러나 STL 에서는 사용하지 않고 operator== 정의해서 non-member find 알고리즘같은경우도 고려함


[ITEM 20 : Specify comparision types for associative containers of pointers]

* POINTER VALUE 로 sorting 되어있는 associative container 구현
1 : container 의 comparision type을 specify.
2 : deference 작업 필수 (Template으로 구현)

struct DereferenceLess {

template
bool operator()(PtrType pT1, PtrType pT2) const
{
return *pT1 < *pT2; } }; void print(const string *ps){ cout << *ps <<> ssp2;
ssp2.insert(new string("AIRED1"));
ssp2.insert(new string("AIRED2"));
for_each(ssp2.begin(), ssp2.end(), print);

[ITEM21 : Always have comparision functions return false for equal values]

// ITEM21
// WRONG USAGE
set > s;
set >::iterator iter2;

bool inserted2;
boost::tie(iter2,inserted2) = s.insert(10);
BOOST_TEST(inserted2 == true);

// equivalce 가 실패 해서 INSERT 된다.
// !(10A <= 10B) &&amp;amp;amp;amp;amp; !(10B <=10A) // !(true) && !(true) // false && false boost::tie(iter2,inserted2) = s.insert(10); [ITEM 22 : Avoid in-place key modification in set and multiset] [ITEM 23 : Consider replacing associative containers with sorted vectors] set, multiset, map, multimap is OK , 그러나 logrithmic-time lookup speed 능가 하는 constant-time lookup speed 필요 lookup speed 가 중요하다면 non standard hashed container 사용(ITEM25) standard associative container 는 balanced binary search tree로 구현 되어 있다. --> insertion, erase, lookup combination 에 대한 OPTIMIZATION

세가지 DataSturcture 에 대한 사용
1 . Setup :
2 .
3 .

Sorted Vector
- lookup algorithm : binary_search, lower_bound, equal_range

binary serarch tree 를 binary searching 하는것 보다 sorted vector내에서 binary_searching 이 빠른 이유?
1 : size
2 : locality of reference

associative container 의 각 element 당 left, right child node 에 대한 포인터 스페이스 OVERHEAD

vector space overhead 무시 : 3 pointer + 2 pointer + 1 int

vector 는 swap trick 통해 extra space 제거 가능 , 그러나 이자체도 의미가 없다. lookup 동안에는
mermory referencing 이 없슴

morory page 당 몇개 들어갈지 계산하면?

12byte 클래스 , pointer 4byte
4K page 내 : vector(341 entry) , associative container(170 entry)

associative container 사용시 small memory page set 을 클러스터링 할 수 있는 container allocator 구현해야함.
--> tree node 사이에서 locality fo reference 추가 시킴

Sorted Vector : insertion & erasures 에 대한 오버헤드가 큼 , 그렇다 하더라도 associative container
비하면 미비한 오버헤드
insert new element : one 씩 이동 , expensive , reallocate 발생시는 더 큰 오버헤드

map 은 sorting 을 위해서 element 의 key 부분만 필요
pair 부분만

--> pair : const 없다. vector 는 element 의 value 들이 move 되면서 assing 됨

[ITEM 24 : Choose carefully between map::operator[] and map::insert when efficiency is import]

element 존재시 ? operator[] : insert

[ITEM 25 : Familiarize yourself with the nonstandard hashed containers]



----------------------------------------------------------------------------------------------------
[4 : Iterators]


----------------------------------------------------------------------------------------------------
[5 : Algorithms]

[ITEM 30: Make sure destination ranges are big enough]

----------------------------------------------------------------------------------------------------
[6 : Functors, Functor Classes, Functions, etc]


functors : function and function-like object

find_if, for_each ,,, 등등 많은 알고리즘들이 functor를 이용해 control을 제어 한다.

[ITEM38: design functor classes for pass-by-value]
STL function objects are passed by value(i.e., copied) when passed to and from functions


template
Function for_each(InputIterator first, InputIterator last, Function f);

Function object 사용시 2가지 전제 조건
1: function object 자체가 small 해야함
--> pass by value 에 대한 overhead

2: monomorphic 해야함(not polymorphic) --> no virtual function
--> base class, derive class 간 pass-by-value 시 slicing problem 발생
--> Effect C++ ITEM22 , STL ITEM3


but polymorphic functor 자체를 사실상 피하기는 불가능
보통 function object 자체가 크고 polymorphic

bridge pattern으로 해결가능(handle-body)

[ITEM39 : Make predicates pure functions]

predicate : return boool 형태의 function( implicitly bool conversion 도 가능)

predicate 예 : standard associative containers 의 comparison functions , find_if 및 sort
알고리즘에 parameter 로서 패스 된다.

pure function : return value가 parameter 에 의해서만 변하는 function

predicate class : operator() function 이 predicate 인 functor 클래스

중요 : predicate function 들을 pure function 을 만족해야함.

functor 클래스는 1개의 operator() function 을 가짐

unary_function binary_function 을 상속받는 이유
--> adaptable function object를 만들기 위함
--> not1, bind2nd 자체도 adaptable function object와 같이 동작


---------------------------------------------------------------------------------------------------------
[7 : Programming with the STL]

ITEM 43 : Prefer algorithm calls to hand-written loops

vector<u> vector;
for(vector<u>::iterator i = vector.begin(); i!= vector.end(); ++i)
i->redraw();

for_each(vector.begin(), vector.end(), mem_fun(&U::redraw));

1. Efficiency
2. Correctness
3. Maintainablility


ITEM 44 : Prefer member functions to algorithms with the same names
1. FAST
2. container 에 맞게 integrating.


associative container : count, find, lower_bound, upper_bound, equal_range

list container : remove, remove_if, unique, sort, merge, reverse

ITEM 45 : Distinguish among cuont, find, binary_search, lower_bound, upper_bound, and equal_range

p 200 표 참고


-----------------------------------------------------------------------------------------------

개발자 업그레이드

개발자 업그레이드

펄 개발자 한단계 업그레이드 되기
Perl프로그래머를 위한 Python Cookbook
http://starship.python.net/~da/jak/cookbook.html

Python 튜토리얼
http://www.python.org/doc/current/tut/tut.html

Python 레퍼런스
http://www.python.org/doc/current/ref/ref.html

Perl을 이용한 서버 프로그래밍 - Advanced Issues
- Object Oriented Networking Modules
- Fork/Thread/Signal Handling, lightweight network connection
- IPC (Shared Memory, Message Queue, Semaphore개념)
- Memory Management (Garbage Collection), lightweight encoding/decoding
- Swig/XSub/Syscall을 이용한 C/C++와의 인터페이스
- Embedding Perl, Single Interpreter for Multiprograms

----
PHP/HTML 개발자 한단계 업그레이드 되기

PHP 클래스 라이브러리 활용
Template/Session 활용
Dynamic HTML 활용 (HTML version 4이상)
PHP/C Extention 인터페이스 활용

----
C++ 개발자 한단계 업그레이드 되기.

필수 사이트: Bjarne Stroustrup's Homepage
http://www.research.att.com/~bs/homepage.html

필수문서0: Learning Standard C++ as a New Language.
http://www.research.att.com/~bs/new_learning.pdf
(C스타일을 버리고, C++로 바로 시작하는 법, 필독!)
Standard Template Library에 대한 이해를 촉구하는 문서

문서: An Overview of the C++ Programming language
http://www.research.att.com/~bs/crc.pdf
(C++ 창조자가 얘기하는 C++의 진수)

문서: Why C++ isn't just an Object-Oriented Programming Language
http://www.research.att.com/~bs/oopsla.pdf
(약간의 철학적인 문제와, C++의 진면모를 볼 수 있는 글)

필수문서: Bjarne Stroustrup's FAQ
http://www.research.att.com/~bs/bs_faq.html

필수문서: SGI의 Standard Template Library 페이지
http://www.sgi.com/tech/stl/

필수문서: Light C++ FAQ (by Marshall Cline)
http://www.parashift.com/c++-faq-lite/

문서: C++에 대한 편견 -- 언어철학적인 문제
http://www.research.att.com/~bs/blast.html

문서: Wrapping C++ Member Function Calls
http://www.research.att.com/~bs/wrapper.pdf
http://www.research.att.com/~bs/wrap_code.cpp
(Wrapping을 이용한 인캡슐레이션 테크닉)

문서: C/C++에 쓸 수 있는 가비지 콜렉터
http://reality.sgi.com/boehm/gc.html

라이브러리 만드는법

== 정적 라이브러리(.a) ==

* 사용하기
{{{
ar rcs my_library.a [http://imfzs.crc-deff.com/183400.htm f]ile1.o [http://www.angelfire.com/bc3/annwhite1755/index.htm f]ile2.o
gcc -o test1 test.o -lmy_library -L./
}}}


== 공유 라이브러리(.so) ==

* 만들기
{{{
gcc -fPIC -c [http://www.angelfire.com/psy/ninawhite1342/index.htm a].c
gcc -fPIC -c [http://uk.geocities.com/steeve_tropez_282/index.htm b].c
gcc -shared -soname,libmystuff.so.1 -o libmystuff.so.1.0.1 a.o b.o -lc
}}}

* 사용방법
{{{
gcc -o [http://qvde.crc-deff.com/8.htm t]est1 test.o -lmy_library
}}}

*UNIX ( Linux, Solaris)
* LD_LIBRARY_PATH
*HU-UX
* SHLIB_PATH
*AIX
* LIBPATH

* so debug
{{{
$ export LD_DEBUG=files
$ test.exe
# 라이브러리를 다룰때 파일과 라이브러리의 동작을 보여주고,
# 어떤 의존성이 발견되었고, 어떤 SOs(sonames)가 어떤 순서로
# 로드되었는지 말해준다.
# LD_DEBUG를 bindings로 설정하는 것은 심볼제한에 대한 정보를
# 보여주고, libs에 설정하는은 것은 라이브러리 탐색경로에 대해서 보여주고,
# version으로 설정하는 것은 버전 의존성을 보여준다.
$ export LD_DEBUG=help <-- 도움말 출력
}}}

== 참조 ==
* 관련 링크
* http://kldp.org/HOWTO/html/Program-Library-HOWTO/index.html

이것저것

2004-02-25 오후 11:14:54 crypt() -- -lcrypt 리눅스 에서는 -l 옵션으로 컴파일 해야함.

2004-02-25 오후 9:50:04 gcc -dM -E - < /dev/null

2004-03-29 오후 8:32:25 lib만들때는 모든 코드에 -fPIC를 추가하도록 할것

2004-03-26 오후 2:47:11

2004-03-26 오후 4:07:24 Mult-Process로 동작하는 프로그램에서 로그를 남길때는 유닉하게 구분될 수 있는 정보와 함께 로그를 남기는것이 디버깅하기 편리하고원인 파악하기 쉽다. 예)

    [pid-thrID-fd] connect [pid-thrID-fd] HELO mobigen.com

cvs 사용자 추가

$ cd /usr/local/apache/bin
$ ./htpasswd -nb 아이디 비밀번호
test1:aw2nh6xA9rPFQ
$ cd /home/cvs/CVSROOT/
$ vi passwd
test1:aw2nh6xA9rPFQ:cvs <-- :cvs를 붙치고 추가함
$ cvs login 으로 등록되었는지 확인함

- 설치문서는 나중에^^;

금요일, 12월 02, 2005

aix man page link

http://publib16.boulder.ibm.com/cgi-bin/ds_form?lang=en_US&viewset=AIX

man page link
http://publib.boulder.ibm.com/infocenter/pseries/index.jsp?topic=/com.ibm.aix.doc/infocenter/base/programmingforaix.htm


// thread safe option

gcc또는 g++ 사용시 thread safe 함수를 사용하도록 하는 define
-D_REENTRANT -D_PTHREADS


_POSIX_REENTRANT_FUNCTIONS
_POSIX_THREADS

// errno가 thread환경에서 설정됨.
_THREAD_SAFE

// BSD socket을 사용하는 경우
_BSD
// 링크시
-lbsd

socket 사용하는 경우 BSD SOCKET을 사용하는 COMPAT_43 이라는 변수가 define이 정의해야함. !!!
#ifdef _AIX
#define _BSD 1
#endif // _AIX

libbsd.a를 링크해야함.

tomcat multi process(load balanced)

Listen 80
NameVirtualHost *

<virtualhost>
DocumentRoot /usr/local/mobigen/CrediMail/web
<ifmodule>
WebAppConnection conn1 warp localhost:8008
WebAppDeploy ROOT conn1 /
WebAppDeploy examples conn1 /examples
WebAppInfo /webapp-info
</ifmodule>
</virtualhost>

<virtualhost>
DocumentRoot /usr/local/mobigen/CrediMail/web
ServerName newmail.abc.com
<ifmodule>
WebAppConnection conn1 warp localhost:8008
WebAppDeploy examples conn1 /
</ifmodule>
</virtualhost>

<virtualhost>
DocumentRoot /usr/local/mobigen/CrediMail/web
ServerName pmailsa1.abc.com
<ifmodule>
WebAppConnection conn1 warp localhost:8008
WebAppDeploy examples conn1 /examples
</ifmodule>
</virtualhost>


<virtualhost>
ServerName smsmail.test.com
DocumentRoot /app/sms/webapp
JkMount /*.jsp tomcat_sms
JkMount /*.do tomcat_sms
JkMount /*.vw tomcat_sms
JkMount /servlet/* tomcat_sms
JkMount /examples/* tomcat_sms
JkMount /download tomcat_sms
<ifmodule>
WebAppConnection conn2 warp localhost:8008
WebAppDeploy examples conn2 /
</ifmodule>
</virtualhost>


------------ mod_jk.conf
LoadModule jk_module libexec/mod_jk.so

JkWorkersFile conf/workers.properties
JkLogFile logs/jk.log
JkLogLevel error

JkMount /*.jsp loadbalancer
JkMount /*.do loadbalancer
JkMount /*.vw tomcat_sms
JkMount /servlet/* loadbalancer
JkMount /examples/* loadbalancer
JkMount /download loadbalancer

------------ workers.properties
worker.list=tomcat1, tomcat2, tomcat3, loadbalancer,tomcat_sms

worker.tomcat1.port=8009
worker.tomcat1.host=localhost
worker.tomcat1.type=ajp13

worker.tomcat2.port=9009
worker.tomcat2.host=localhost
worker.tomcat2.type=ajp13

worker.tomcat3.port=10009
worker.tomcat3.host=localhost
worker.tomcat3.type=ajp13

worker.tomcat_sms.port=8109
worker.tomcat_sms.host=localhost
worker.tomcat_sms.type=ajp13

worker.tomcat1.lbfactor=1
worker.tomcat2.lbfactor=1
worker.tomcat3.lbfactor=1


worker.loadbalancer.balanced_workers=tomcat1, tomcat2, tomcat3


------------tomcat1/conf/server.xml
<server port="8005" shutdown="SHUTDOWN" debug="0">
<connector port="8009" enablelookups="false" debug="0" protocol="AJP/1.3">
<engine name="Standalone" defaulthost="localhost" debug="0" jvmroute="tomcat1">
------------tomcat2/conf/server.xml
<server port="9005" shutdown="SHUTDOWN" debug="0">
<connector port="9009" enablelookups="false" debug="0" protocol="AJP/1.3">
<engine name="Standalone" defaulthost="localhost" debug="0" jvmroute="tomcat2">
------------tomcat3/conf/server.xml
<server port="10005" shutdown="SHUTDOWN" debug="0">
<connector port="10009" enablelookups="false" debug="0" protocol="AJP/1.3">
<engine name="Standalone" defaulthost="localhost" debug="0" jvmroute="tomcat3">

  • 참고자료
    • http://tomcat.apache.org/tomcat-5.0-doc/balancer-howto.html
    • http://wiki.apache.org/tomcat/Tomcat/Jk2Connector
    • http://raibledesigns.com/tomcat/index.html

수요일, 11월 23, 2005

HTML cache-control

response.setHeader("Cache-Control","no-cache"); //HTTP 1.1
response.setHeader("Pragma","no-cache"); //HTTP 1.0
response.setDateHeader ("Expires", 0); //prevents caching at the proxy server

META

<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">

<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">

<META HTTP-EQUIV="EXPIRES" CONTENT="Mon, 22 Jul 2002 11:12:01 GMT">


화요일, 11월 22, 2005

ajax 간단 샘플

var xmlhttp = null;
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch(E) {
xmlhttp = false;
}
}

if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
xmlhttp = new XMLHttpRequest();
}

var url;
url = "http://192.1.5.252/adminmail/userinfo.jsp?path=" + path;

xmlhttp.open("GET", url, false); // synchronous call
xmlhttp.send(null);

userinfo.innerText = xmlhttp.responseText;

목요일, 11월 17, 2005

apache+tomcat virtualdomain 설정하기

########################################################
Apache + Tomcat (webapp module) 연동 가상호스트
########################################################

#----------------- httpd.conf 파일 ---------------------
NameVirtualHost *

<VirtualHost *>
ServerAdmin admin@okejb.com
DocumentRoot /server/tomcat4.12/webapps/ROOT
ServerName okjeb.com
ServerAlias www.okejb.com okejb.com
ErrorLog logs/phonia.okejb.com-error_log
CustomLog logs/phonia.okejb.com-access_log common
<IfModule mod_webapp.c>
WebAppConnection conn1 warp localhost:8008
WebAppDeploy ROOT conn1 /
WebAppDeploy examples conn1 /examples
WebAppInfo /webapp-info
</IfModule>
</VirtualHost>

<VirtualHost *>
ServerAdmin admin@jsp.okejb.com
DocumentRoot /server/tomcat4.12/webapps/jsp
ServerName jsp.okejb.com
ErrorLog logs/jsp.okejb.com-error_log
CustomLog logs/jsp.okejb.com-access_log common
<IfModule mod_webapp.c>
WebAppConnection conn2 warp localhost:8008
WebAppDeploy examples conn2 /
</IfModule>
</VirtualHost>

#----------------- httpd.conf 파일 ---------------------


#----------------- server.xml 파일 ---------------------
<Server port="8005" shutdown="SHUTDOWN" debug="0">
<Service name="Tomcat-Standalone">
<Host name="localhost" debug="0" appBase="webapps"
unpackWARs="true" autoDeploy="true">

<Context path="/examples" docBase="examples" debug="0"
reloadable="true" crossContext="true">
<Context path="" docBase="/server/tomcat4.12/webapps/ROOT" reloadable="true"/>

</Host>

<Host name="jsp.okejb.com" debug="0" appBase="webapps" unpackWARs="true">
<Context path="" docBase="/server/tomcat4.12/webapps/jsp" reloadable="true"/>
</Host>
</Service>
</Server>
#----------------- server.xml 파일 ---------------------

ROOT Content : http://okejb.com/test.jsp

examples Context : http://www.okejb.com/examples/jsp/

가상호스트 : http://jsp.okejb.com/






http.conf설정

Listen 80
NameVirtualHost *

<VirtualHost *>
DocumentRoot "/usr/local/test/web"
ServerName dpostwb1
# ServerAlias
<IfModule mod_webapp.c>
WebAppConnection conn1 warp localhost:8008
WebAppDeploy ROOT conn1 /
WebAppDeploy examples conn1 /examples
WebAppInfo /webapp-info
</IfModule>
</VirtualHost>

<VirtualHost *>
DocumentRoot /app/sms/webap
ServerName smsdev.test.com
<IfModule mod_webapp.c>
WebAppConnection conn2 warp localhost:8008
WebAppDeploy examples conn2 /
</IfModule>
</VirtualHost>


server.xml

<Host name="smsdev.test.com" debug="0" appBase="webapps" unpackWARs="true">
<Context path="" docBase="/app/sms/webapp" reloadable="true"/>
</Host>

awk 간단사용법 메모

cat 12 | awk '/\t/ {print $2}' | sort -u

awk <search pattern> {<program actions>}

ps -ef | awk '/httpd/ {if ($4 >= 1) print $1, $2, $4; sum += $4} END {print "sum = ", sum}'


hope Posted by Picasa