분류 전체보기 (199)
ººº::Development™:: (66)
ººº::Learning™:: (31)
ººº::Information™:: (37)
ººº::Note™:: (11)
ººº::Photo™:: (50)
ººº::zEtc™:: (3)
rss

믹시
tistory 티스토리 가입하기!
'ººº::Development™::'에 해당되는 글 66건
2009. 5. 18. 09:46
간단하지만 이저먹기 쉬운것부터 정리하기! ... 그 첫번째로 SSH의 Root접근 제한하기

SSH의 Root접근 제한은 보안상 문제로 슈퍼 User의 접근을 Local 계정의 접근 이후 su 명령어를 통해 접근하도록 한다. 이유는 어느 계정을 통해 슈퍼 User로 접근했는지를 알기 위해서라고 한다.!!( 어디서 주워들은 얘기 ) 그래야 누가 무엇을 건드렸는지 유추해 내가 편하기 때문에~~^^

$ vi /etc/ssh/sshd_config
# Authentication:

#LoginGraceTime 2m
PermitRootLogin no
#StrictModes yes
#MaxAuthTries 6

vi에디터를 통해 sshd_config 파일을 열고 PermitRootLogin 옵션을 no로 설정한다. 기본은 yes의 #으로 주석처리가 되어있을 것이다.!

위와같이 변경하고 ssh데몬을 restart해주면 이후부터 root의 접근이 제한된다.!

:: 그럼 오늘하루도 즐겁고 행복한 하루 되시길 !!! ::



2009. 4. 10. 11:42
Crash Dump파일을 분석할 일이 생겼는데. 이번에 해본 경험이 없다.
하지만 찾아서 해야지..!! 일단 WinDbg를 이용해 Dump파일을 분석해보자, 나중에 또다시 사용할 수 있게

1. http://www.microsoft.com/whdc/devtools/debugging/default.mspx 로 이동
2. Install Debugging tools 다운로드
   다운로드시 해당 시스템에 맞는 Version을 다운로드
3. http://www.microsoft.com/whdc/devtools/debugging/symbolpkg.mspx로 이동
   덤프 파일이 생성된 환경에 맞게 심볼 파일을 다운로드

자 기본적으로 다운로드 해야하는 파일은 다 다운 받았고, 설치까지 완료 그러면 분석해야 하는 부분을 확인해 보자

1. WinDbg실행 후 심볼파일의 경로를 지정한다.
   File->Symbol File Path를 실행 해당 Symbol의 Path를 잡아준다. 또한 Dump가 사용된 프로그램의 심볼도 작성한다.
  만약 프로그램 심볼만 사용하고 싶으시다면, Source File Path도 잡아준다.
2. File->Open Crash Dump를 실행해서 덤프 파일의 경로를 지정 해서 덤프 파일을 Open

위의 작업까지 완료되었다면, 덤프 파일 내용을 통해 문제되는 부분을 확인할 수 있다.

명령어는 아직 잘 모르겠지만 !analyze -v 명령어를 통해 심볼 파일과 덤프 파일을 비교해서 오류가 나오는 부분을 확인할 수 있는 명령어라고 한다.
fault명령어는 driver 로딩 중 error나 warning이 발생한 드라이버를 확인할 수 있다.


2008. 12. 4. 21:27
입력된 path를 바탕으로 폴더를 만들어 주는 코드.
어찌보면 상당히 간단하다고 생각할 수 있지만, 나같이 C/C++코드를 잘 모르는 사람들에게는 어찌 느껴질지 모르는 코드이다. 자랑두 아닌 챙피하지만, 주로 JAVA로 개발을 해오다 보니 C/C++은 전혀 꽝이었다는... 그러다보니 이런 간단한 코드조차 사람을 당황스럽게 만들 수 있다는 사실.ㅋㅋ 오랫동안 머릿속에 남기기 위해!..

std::string strDirPath;
std::string strTempDir;
int indexOf = 0;
while( true ) {
indexOf = strDirPath.find( "/" );
strTempDir += strDirPath.substr( 0, indexOf ) + "/";

mkdir( strTempDir.c_str(), 0777 );
strDirPath = strDirPath.substr( indexOf + 1, strDirPath.length() );

if( indexOf < 0 ) break;
}

위 코드는 아주 간단하다 생성하고자 하는 PATH에서 "/"문자를 찾아 한 단계씩 폴더를 생성하는 것이다. 위 코드에 보면 폴더가 있는지 유무를 Check하고 하는 디테일한 부분은 존재하지 않는다. 그냥 기본적인 생각만 가지고 있는 코드이다.

:: 그럼 이 글을 읽는 모든 분들에게 오늘 하루 즐겁고 행복한 하루 되시길 ::



2008. 12. 3. 09:13
프로그램을 작성하다 보면 간단한 로직이라도 생각이 안날경우가 있다. 내가 바로 그 경우로 아주 쉽게 너무 자주 이런 현상이 발생한다. 지금 내가 쓰고자 하는 포스트도 같은 맹락에서 작성하는 것이다.
C나 C++로 코드를 작성하는 가운데 오늘 날짜를 구해야 하는 경우가 있는데 이럴 경우 어떻게 할까? 순간적으로 코드가 생각이 안나서 이렇게라도 글로 남겨 놓는다.

struct tm*    datetime;
time_t    t;
t = time( NULL );
datetime    = localtime( &t );

printf( "%d/%02/%02d %02d:%02d:%02d", datetime->tm_year - 1900,
 datetime->tm_mon + 1,
datetime->tm_mday,
datetime->tm_hour,
datetime->tm_min,
datetime->tm_sec );

코드는 아주 간단하다. 위와 같은 형식으로 작성해 주면 되고, 년/월/일 시:분:초 형식으로 사용하면 된다.

:: 이 글을 읽는 모든 분들에게 오늘 하루 즐겁고 행복한 하루 되길 ::



2008. 11. 27. 22:21
추상 메소드를 구현하는 것은 하위 클래스이다. 하위 클래스 측에서 메소드를 구현하면 구체적인 처리가 결정된다. 서로 다른 하위 클래스가 서로 다른 구현을 실행하면 서로 다른 처리가 실행될 것입니다. 그러나 하위 클래스에서 어떤 구현을 하더라고 처리의 흐름은 상위 클래스에서 결정한대로 이루어진다.
위와 같이 상위 클래스에서 모든 처리의 흐름을 정의하고, 하위 클래스에서 그 구체적인 내용을 결정하는 패턴이 Template Method 패던이다.

1. AbstractDisplay.java
public abstract class AbstractDisplay {
    public    abstract    void    open();
    public    abstract    void    print();
    public    abstract    void    close();   
    public final void display() {
        open();
        for( int i = 0; i < 5; i++ ) {
            print();
        } close();
    }
}

2. CharDisplay.java
public class CharDisplay extends AbstractDisplay {
    private    char    ch;
    public CharDisplay( char ch ) { this.ch = ch; }   

    public void close() { System.out.println( ">>" ); }
    public void open() { System.out.print( "<<" ); }   
    public void print() { System.out.print( ch ); }   
}

3. StringDisplay.java
public class StringDisplay extends AbstractDisplay {
    private    String    string;
    private    int        width;   
    public StringDisplay( String string ) {
        this.string    = string;
        this.width = string.getBytes().length;
    }
    public void close() { printLine(); }
    public void open() { printLine(); }
    public void print() { System.out.println( "|" + string + "|" ); }
    private void printLine() {
        System.out.print( "+" );
        for( int i = 0; i < width; i++ ) {
            System.out.print( "-" );
        } System.out.println( "+" );
    }
}

4. Main.java
public class Main {
    public static void main(String[] args) {
        AbstractDisplay    d1    = new CharDisplay( 'H' );
        AbstractDisplay d2    = new StringDisplay( "Hello, world." );
        AbstractDisplay d3    = new StringDisplay( "안녕하세요" );
        d1.display();
        d2.display();
        d3.display();
    }
}

어떻게 위의 코드를 보고 금방 이해가 되나여? 저같은 경우에는 앞의 내용들과 크게 다를것은 몬 느끼겠지만 조금씩 다른게 있다는 느낌이 받고 있다.

Template Method패턴을 사용하면 구체적인 알고리즘은 상위 클래스에서 정의대어 있고, 하위 클래스에서는 해당하는 method를 실제로 구현하는 역할을 수행하는 패턴이라고 이해하면 될 것 같다.

:: 그럼 일 글을 읽는 모든 분들에게 오늘 하루 즐겁고 행복하기를 ^^* ::



2008. 11. 27. 21:47
우리가 일사 생활에서 10v를 사용하는 전자 제품에 220볼트의 전원을 연결할 때, 중간에 어뎁터라는 것을 사용해서 전류를 변화 시켜주는 거와 같이 Adapter패턴은 한 클래스의 인터페이스를 다른 인터페이스로 변환해 주는 패턴입니다. Adapter패턴을 사용하면 인터페이스 호환성 문제 때문에 같이 사용할 수 없는 클래스를 연결해 줍니다.

아래 예제는 java.util의 Properties 클래스를 사용해 peorperty를 스크림에서 읽고 해당 property내용을 업데이트 한 후 다시 스크림을 쓰는 Adapter Class인 FileProperties Class를 작성하는 것이다.

1. FileIO.java
import java.io.IOException;

public interface FileIO
{
    public    void    readFromFile( String fileName ) throws IOException;
    public    void    writeToFile( String fileName ) throws IOException;
    public    void    setValue( String key, String value );
    public    String    getValue( String key );
}

2. FileProperties.java
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

public class FileProperties extends Properties implements FileIO
{
    Properties properties = new Properties();

    @Override
    public String getValue( String key ) { return properties.getProperty( key ); }

    @Override
    public void readFromFile(String fileName) throws IOException {
        properties.load( new FileInputStream( fileName ) );
    }

    @Override
    public void setValue(String key, String value) { properties.setProperty( key, value ); }

    @Override
    public void writeToFile(String fileName) throws IOException {
        properties.store( new FileOutputStream( fileName ), "Written by FileProperties" );
    }
}


3. Main.java
import java.io.IOException;

public class Main {
    public static void main( String[] args ) {
        FileIO    f    = new FileProperties();
        try
        {
            f.readFromFile( "file.txt" );
            f.setValue( "year", "2004" );
            f.setValue( "month", "4" );
            f.setValue( "day", "21" );
            f.writeToFile( "newfile.txt" );
        } catch( IOException e ) { e.printStackTrace(); }
    }
}


아직 이 패턴이 어떻게 쓰이는지는 잘 모르겠지만 전혀 이질적인 인터페이스를 가지는 클래스를 연결할 때, 사용하면 유용할 꺼 같기는 하다. 위 예지를 보면 FileIO Class 만 알고 있다면, FileProperties클래스가 Properties클래스의 메소르에 대해서 몰라고 peroperty를 취급할 수 있다.

정말로 어럽다.. 언제 다 이해를 할 수 있을런지!ㅡㅡ;

:: 이 글을 읽는 모든 분들에게 오늘 하루 즐겁고 행복만이 가득 하기를..^^*; ::



2008. 11. 21. 00:17
지금까지 내가 코딩을 하면서 얼마나 무식하게 코딩을 했는지 요즘 처절하게 느끼고 있다. 팀장님의 코딩 실력과 이사님의 개발자적 시각.. 아주 많이 부족하다는걸 느끼는 가운데 안되겠다 싶어서 공부를 시작한다. 그 첫번째로 패턴...이전에 포스팅에서 얼랭을 공부한다고 했는데 얼랭은 아주 천천히 시간 날때마다 보는 것으로 미루고( 이러면 안되는걸 알면서도 ) 지금당장 공부하는게 급하다!ㅠㅠ;

그 첫번째로 패턴..앞으로 지금 보고 있는 책을 바탕으로 하나하나 패턴에 관해 정리를 해봐야겠다. 이곳에 포스팅 되는 내용은 개인적인 내용도 있고, 지금 보는 책의 내용도 함깨 있음을 미리 밝힌다.

1. Iterator 패턴
모든 언어에서 배열의 요소를 찾기 위해서 for구문과 같은 Loop문을 사용해 요소를 하나하나 찾는다. 이와 같이 첫번째 요소부터 마지막 요소까지 하나하나 찾아 나가는 방법을 일반화한 것이 Iterator 패턴이다. 다시 말해 어떠한 무언가가 모여있는 것들은 단순하게 검색하는 것을 의미한다.

Iterator패턴은 컬랙션 구현 방법을 노출시키지 않으면서도 그 집합체 안에 모요있는 모든 요소에 접근할 수 있게 해주는 방법을 제공한다.

public interface Aggregate { public abstract Iterator iterator(); }

public interface Iterator {
    public abstract boolean hasNext();
    public abstract Object next();
}

public class Book {
    private String    name;   
    public Book( String name ) { this.name = name; }
    public String getName() { return name; }
}

import java.util.ArrayList;

public class BookShelf implements Aggregate
{
    private    Book[]    books;
    private int        last    = 0;
    private    ArrayList<Book>    arrayList;
   
    public BookShelf() { arrayList    = new ArrayList<Book>(); }
    public BookShelf( int maxsize ) { this.books    = new Book[maxsize]; }
   
    public Book getBookIndex( int index ) {
        return ( arrayList != null ) ? (Book)arrayList.get( index ) : books[index];
    }
    public Book getBookAt( int index ) {
        return ( arrayList != null ) ? arrayList.get( index ) : books[index];
    }
   
    public void appendBook( Book book ) {
        if( arrayList != null )   
            arrayList.add( book );
        else if( arrayList == null && last >= 0 )
        {
            books[last]    = book;       
            last++;
        }
    }
   
    public int getLength() { return ( arrayList != null ) ? arrayList.size() : last; }   
    public Iterator iterator() { return new BookShelfIterator( this ); }
}

public class BookShelfIterator implements Iterator
{
    private    BookShelf    bookShelf;
    private    int            index;
   
    public BookShelfIterator( BookShelf bookShelf ) {
        this.bookShelf    = bookShelf;
        this.index        = 0;
    }
   
    public boolean hasNext() {
        if( index < bookShelf.getLength() ) return true;
        else return false;
    }

    public Object next() {
        Book    book = bookShelf.getBookAt( index );
        index++;       
        return book;
    }
}

위에 상당히 많은 코드들이 보이는데 위 코드들은 서가(BookShelf)안에 책(Book)을 넣고, 그 책의 이름을 차례대로 표시하는 프로그램으로 Size가 정해진 서가와 가변 Slze의 서가가 존재하는 프로그램이다.

public class Main
{
    public static void main(String[] args)
    {
        BookShelf    bookShelf    = new BookShelf( 4 );
        bookShelf.appendBook( new Book( "Around the World in 80 days" ) );
        bookShelf.appendBook( new Book( "Bible" ) );
        bookShelf.appendBook( new Book( "Cinderella" ) );
        bookShelf.appendBook( new Book( "Daddy-Long-Legs" ) );
       
        Iterator    it = bookShelf.iterator();
        while( it.hasNext() )
        {
            Book    book = (Book)it.next();
            System.out.println( book.getName() );
        }
       
        BookShelf    bookShelf2    = new BookShelf();
        bookShelf2.appendBook( new Book( "Around the World in 80 days--" ) );
        bookShelf2.appendBook( new Book( "Bible--" ) );
       
        it = bookShelf2.iterator();
        while( it.hasNext() )
        {
            Book    book = (Book)it.next();
            System.out.println( book.getName() );
        }
    }
}

위 프로그램을 실제 테스트 하는 코드로 첫번째서가는 책을 4권만 넣을 수 있는 서가이지만 아래쪽의 코드는 ArrayList를 사용하는 서가이기 때문에 책의 숫자에 상관없이 저장할 수 있다.

코드들을 보다보면 추상 클랙스, 혹은 인터페이스를 많이 사용한다. 나도 아직 잘 사용해 보지 않은 방식이지만 앞으로 하나씩 보면서 몸에 익혀 보도록 해야겠다.

:: 그럼 이글을 읽는 모든 분들에게 오늘 하루 즐겁고, 행복많이 가득하기를 ::



2008. 11. 6. 09:04
기존 솔루션을 Java에서 C++로 바꾸는 프로젝트가 진행중이다. 기존에는 Java를 사용하기 때문에 공개된 API를 가져다 사용하기 편했지만, C++로 넘어오면서는 내가 많이 사용해보지 않은 플랫폼으로 인해 라이브러리 하나 사용하기도 쉽지가 않다. 그러다가 XML을 사용하기 위해 apache xercex-c 사용이 정해진 이후 해당 라이브러리를 사용하기 위해 삽질한 흔적을 나겨본다.

xercex-c 사용을 위해 지금 현재 개발 환경을 간략하게 살펴보면, Fedora8에서 Eclipse에서 C++코딩을 하고 있다. 기본적인 Charset은 UTF-8을 사용하고 있다.

우선 xercex-c사용을 위해 해당 라이브러리르 설치하자, 설치는 간단하게 yum을 통한 install소스코드를 직접 build하는 방식이 있다. 두방식의 가장 큰 차이점은 yum을 통한 install은 내가 원하는 버전 선택이 안된다는것과, 소스코드 build는 귀찮다는 단점이 가장 큰 차이점으로 보이지만, 더 큰 차이점은 한글을 사용하는데 있어서 yum을 통해 install되는 2.7.* 버전은 한글사용에 문제점이 있기때문에 한글을 사용해야 하는 분들은 xercex-c홈페이지에서 3.* 버전을 다운받아서 build후 사용하시기 바랍니다.

1. build 방법
xercex-c 홈페이지에서 최신 버전의 xercex-c를 다운받은 후 특정 폴더에 압축을 해제한다.
$ ./configure
$ make

위와 같은 명령이후에 /usr/local/include 폴더와 /usr/local/lib 폴더에 보면 해당하는 라이브러리 파일과 헤더 파일이 존재한다. 위와 같이 존재하게 되면 빌드 자체는 성공적으로 완료된 것이다.

2. 사용방법
해당라이브러리를 사용하기 위해서는 컴파일 옵션과 실행시 해당 라이브러리를 링크해줘야 한다.
컴파일
-I(대문자 I) 옵션   : 해당 라이브러리 해더 파일이 존재하는 include 폴더를 선택해 줘야 야 함
-l(소문자 L) 옵션  : 해당 라이브러리 이름을 선택
-L                      : 해당 라이브러리가 존재하는 폴더 선택
gcc -I /usr/local/include -lxercex-c -L /home/workspace/lib

실행
실행시는 해당 라이브러리가 존재하는 PATH를 시스템에 설정해 줘야 한다. 해당 라이브러리 Path는
$ export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

더 자세한 내용은 해당 홈페이지를 살펴보면 편하게 사용하실 수 있을 것이다. 또한, xercex-c는 윈도우와 다른 OS에서도 사용 가능하기 때문에 해당 OS사용자들은 홈페이지를 통해 사용 방법과 설정 방법을 습득하면 될 것이다.
마지막으로 xercex-c는 dom, sax, sax2를 모두 지원한다고 나와있다. 그리고 직접 C++상에서 xml을 파싱하는 내용은 추후 다시한번 포스팅 하도록 하겠다.

:: 관련 링크 ::
apache xercex-c :: http://xerces.apache.org/xerces-c/





2008. 10. 30. 11:09
프로젝트 때문에 Linux에서 MS-SQL을 접속할 일이 생겼다. 윈도우 같은 경우는 OLEDB를 사용하거나 하면 쉽게 접속을 할 수 있지만, Linux같은 경우에는 OLEDB를 사용하기 힘들어 부득이하게 ODBC를 사용해야 했다. 혹시 저와 같이 Linux에서 MS-SQL을 ODBC를 사용해 연결해야 하는 분들과 내 머릿속에있는 지우개때문에 정리 차원에서 어떻게 사용하고 설정하는지 살펴보자.

우선 odbc를 설정하기 위해서는 unixODBCfreeTDS등의 패키지가 필요하다, 해당 패키지 설치는 구글링등을 통해 알아보면 쉽게 설치 하실 수 있을 것이다. 저같은 경우는 Fedora 8에서 yum을 통해서 설치했다.
모든 설치가 끝났으면, 아래와 같은 순서로 설정을 하고 연결 테스트를 진행하면 된다.


1. odbcinst.ini
/etc/odbcinst.ini 파일에 아래 내용을 추가하자 :: 추가 내용은 freeTDS Driver를 사용한다는 것이다.
# FreeTDS
[FreeTDS]
Description     = freeTDS Driver
Driver             = /usr/lib/libtdsodbc.so.0
위 내용에서 Drvier 부분은 자신이 설치한 패키지를 바탕으로 경로와 라이브러리 파일명을 설정해 주면 된다.

2. odbc.ini
/etc/odbc.ini 파일에 아래 내용을 추가하자 :: 추가 내용은 FreeTDS Drvier를 통해 mssql에 접속하기 위해 필요한 내용이다.
[MSSQL_VINK]
Driver           = FreeTDS
Description   = ....
Server          = host ip or server name
Port              = mssql port
Database      = database name
 첫번째 라인은 odbc DSN 이름이며, Drvier는 odbsinst.ini에 설정한 Drvier 이름이다. 이외의 아래 내용은 해당하는 내용으로 설정해 주면 된다.

위와 같이 모든 설정이 되었으며, 실재로 접속이 되는지 Test를 해보면 된다. 테스트는 isql을 통해 콘솔상에서 직접 접속을 시도해 보면 된다.
#isql [DSN name] [username] [password]

별 애러 없이 연결이 된다면, 성공적으로 ODBC를 설정한 것이다. 만약 에러가 발생한다면 구글을 통해 에러내용을 검색해 보면 될것이다. :: 저는 에러가 없어서 어떤 내용의 에러가 발생했는지를 모르기 때문에 ..ㅋㅋ


:: 그럼 이 글을 읽는 모든 분들깨 오늘 하루 즐겁고 행복만 가득하기를...^^* ::



2008. 10. 20. 11:41
회사 프로젝트때문에 공개 프로젝트를 다운받아서 실행해보고자 하는 가운데 몇가지 api가 필요해 이러지리 찾는 가운데 jnlp.jar 파일을 도통 찾을 수 가 없었다.

이러저리 구글링하고 찾은 결과 1.2 버전까지는 다운받을 수 있는곳이 있다고 하고, 1.5 버전부터는 jdk를 설치하면 함깨 설치된다고 나와있다. 헉, 이말은 머야?
알아봤더니 jdk설치 경로에 함께 설치가 되어있다.

:: 경로보기 ::
%JDK_PATH%\sample\jnlp\servlet


위 폴더에 보면 jnlp.jar 파일이 존재한다.! 이걸 모르고 이리저리 돌아댕겼따니!ㅠㅠ;
혹 저와같은 삽질을 방지하기위해서!!^_^;

:: 이 글을 읽는 모든 분들께 오늘하루 즐겁고 행복만이 가득하기를 ::