허정수님의 홈페이지

	
		MySQL과 C로 만든 프로그램을 연동하는 예제를 짜 봤습니다.
		그다지 좋은 예는 아니지만,, 어떻게 돌아가는지 참고 정도는
		할 수 있습니다. 

소스
1. 
	예제로 짜볼 프로그램은 '친구 찾기'입니다. 
	telnet으로 서버에 접속하여, 검색 조건을 넣고, 
	찾기를 하면 원하는 친구를 찾아서 정보를 보여 줍니다.

	만들기 쉽게 하기 위하여, 네트웍 프로그래밍은 안 썼습니다.
	단순히 telnet으로 접속을 하고, login에서 아이디를 치면
	그 사용자의 SHELL이 뜰텐데 (일반적이라면 본쉘이나, C 쉘이 뜨겟져)
	이 SHELL을 우리가 만든 프로그램으로 바꾸어 버립니다. 
	가장 간단한 방법이라고 생각합니다. 
	보안상 논캐너니컬 모드로 바꿔줘야 하는데, 제가 이 부분은 제가
	잘 모르겠네여.

	단순히 예제로 쓰이기 위하여 최소 사항만 구현을 합니다.

2. 사용자 추가 하기.
	일단 친구 검색 프로그램을 쓸 User를 추가하기로 하져.

	#adduser inos 
	
	새로운 사용자가 생겼습니다. 암호는 없도록 합시다. (/etc/passwd 파일에서
	암호에 관한 부분을 지워버리면 됩니다.)
	
	MySQL에도 사용자를 추가해 보져.
	보안상 새로 추가할 사용자는 Select만 할 수 있는 권한을 
	주기로 합니다. 
	위의 강좌에서 mysql DB의 user Table에 사용자에 관한 
	설정이 있다는 것을 기억하시져? 

	# mysql mysql
	mysql> select * from user ;
	+-----------+---------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+
	| Host      | User    | Password         | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Reload_priv | Shutdown_priv | Process_priv | File_priv |
	+-----------+---------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+
	| localhost | root    |                  | Y           | Y           | Y           | Y           | Y           | Y         | Y           | Y             | Y            | Y         |
	| localhost |         |                  | N           | N           | N           | N           | N           | N         | N           | N             | N            | N         |
	| localhost | pds     | 77fca4775957e5d4 | Y           | Y           | Y           | Y           | Y           | Y         | Y           | Y             | Y            | Y         |
	| localhost | newuser | 7b17bc5522ac2590 | Y           | Y           | Y           | Y           | Y           | Y         | Y           | Y             | Y            | Y         |
	+-----------+---------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+
	4 rows in set (0.00 sec)

	다음과 같이 사용자를 추가합니다.

	mysql> insert into user values ('localhost', 'inos',password('hjshjs'), 'Y','N','N','N','N','N','N','N','N','N') ;
	Query OK, 1 row affected (0.12 sec)

	확인을 해볼까요?

	mysql> select * from user ;
	+-----------+---------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+
	| Host      | User    | Password         | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Reload_priv | Shutdown_priv | Process_priv | File_priv |
	+-----------+---------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+
	| localhost | root    |                  | Y           | Y           | Y           | Y           | Y           | Y         | Y           | Y             | Y            | Y         |
	| localhost |         |                  | N           | N           | N           | N           | N           | N         | N           | N             | N            | N         |
	| localhost | pds     | 77fca4775957e5d4 | Y           | Y           | Y           | Y           | Y           | Y         | Y           | Y             | Y            | Y         |
	| localhost | newuser | 7b17bc5522ac2590 | Y           | Y           | Y           | Y           | Y           | Y         | Y           | Y             | Y            | Y         |
	| localhost | inos    | 4e2eb14c2c15d95e | Y           | N           | N           | N           | N           | N         | N           | N             | N            | N         |
	+-----------+---------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+
	5 rows in set (0.00 sec)

	추가된 것을 확인하셨져?

	사용자를 추가할 때 password('hjshjs')부분을 보셨나요? 
	패스워드를 암호화 하여 테이블에 삽입합니다. Select_priv만 Y이므로 
	inos라는 User는 select 문만을 사용할 수 있습니다.

3. DB.
	
	meeting이라는 DB를 만들고, meeting에 profile이라는 Table을 
	만들도록 하져.

	#mysqladmin create meeting
	Database "meeting" created.

	#mysql meeting
	mysql> create table profile(name char(10), sex char(3), age int, hobby tinyint
	    -> , job tinyint);

	각각의 필드는 다음과 같습니다.

	name  : 이름
	sex   : 성별
	age   : 나이
	hobby : 취미 
			hobby = 1 : 낚시, 등산, 여행 등
			        2 : 컴퓨터, 인터넷, 채팅, 게임
					3 : TV, 라디오, 신문 읽기, 음악 듣기
					4 : 당구, 술, 춤 
	job   : 직업
			job   = 1 : 학생
					2 : 주부
					3 : 공무원
					4 : 자영업
					5 : 회사원
					6 : 연예인

	취미와 job을 직접 DB에 집어 넣지 않은 이유는
	용량을 줄이고 수정을 쉽게 하기 위해서져. 
	tinyint는 1 byte 입니다. 

	각자 데이타를 입력해 봅시다.
	
	예)
	mysql> insert into profile values ('오모양', '여', 25,1,1);

	이런 식으로 계속해서 데이타를 입력하져.

	그럼 각자 입력한 데이터를 봅시다.

	mysql> select * from profile ;
	+--------+------+------+-------+------+
	| name   | sex  | age  | hobby | job  |
	+--------+------+------+-------+------+
	| 오모양 | 여   |   25 |     1 |    1 |
	| 허정수 | 남   |   22 |     1 |    2 |
	| 박미달 | 여   |   22 |     2 |    3 |
	| 조규태 | 남   |   22 |     1 |    3 |
	| 김봉길 | 남   |   30 |     2 |    4 |
	| 이민규 | 남   |   20 |     4 |    6 |
	| 이애경 | 여   |   19 |     3 |    2 |
	+--------+------+------+-------+------+
	7 rows in set (0.00 sec)

	음. 이 정도면 준비는 다 됐으니, 이제 소스 코드를 보면서
	설명을 하져...

	혹시, 위의 'MySQL C API'에 대한 강좌를 읽지 않으셨다면
	꼭 읽어 보셔야 합니다.

4. 헤더 파일

	char *query[] = { "select * from %s where name = '%s'",
				  	  "select * from %s where age >= %d && age <= %d && sex = '%s' "
	};

	/* query[LN]은 이름 만으로 찾기
	   query[LT]은 성별과 나이로 찾기 입니다.
	   그냥, 쓰기 편하게....
	*/

	#define LN 0  
	#define LT 1


	/* DB에서 읽어온 취미에 관한 값이 2였으면
	   hobby[2] = "낚시, 등산, 여행 등" 이니깐
	   hobby[2] 를 출력해주면 되겠네여.
	*/

	char *hobby[] = { NULL, 
					  "낚시, 등산, 여행 등",
					  "컴퓨터, 인터넷, 채팅, 게임",
					  "TV, 라디오, 신문 읽기, 음악 듣기",
					  "당구, 술, 춤"
	};

	char *job[] = { NULL,
					"학생",
					"주부",
					"공무원",
					"자영업",
					"회사원",
					"연예인"
	};

5. main.c

#include 
#include 
#include 
#include "query.h"

MYSQL meeting ;
MYSQL_RES *result ;
MYSQL_ROW row ;

void exiterr( void );
void connect2db( void ) ;
void close2db( void ) ;
void ln( void ) ;
void lt( void ) ;
void divide(int , int *, int *) ;

void main(void)
{
	int select ;
	connect2db() ;

	printf("1. 이름으로 검색\n2. 성별과 나이로 검색\n") ;
	printf("선택하세요 : ") ;

	scanf("%d", &select) ;

	if( select == 1 )
		ln() ; /* 이름으로 검색 */
	else if( select == 2)
		lt() ; /* 성별과 나이로 검색 */
	else
		printf("잘못 입력하셨습니다.\n") ;

	close2db() ;
}

void ln( void )
{
	char ln_name[10] ;
	char query_buffer[200] ;
	int i ;

	printf("검색하실 이름을 입력하십시오\n") ;
	printf("검색할 이름 : ") ;

	scanf("%s", ln_name) ;
	sprintf(query_buffer, query[LN], "profile", ln_name) ;

	if(mysql_query(&meeting, query_buffer) )
		exiterr() ;

	if( ! (result = mysql_store_result( &meeting ) ))
		exiterr() ;

	while( row = mysql_fetch_row( result ) )
	{
		printf("이름 : %s\n", row[0] ) ;
		printf("성별 : %s\n", row[1] ) ;
		printf("나이 : %s\n", row[2] ) ;
		printf("취미 : %s\n", hobby[ atoi( row[3] )]) ;
		printf("직업 : %s\n", job[ atoi( row[4] )]) ;
	}

}

void lt( void ) 
{
	int cnt ;
	char query_buffer[300] ;
	char sex[3] ;
	int low , high , select;
	
	printf("검색할 성별은[남/여] : ") ;
	scanf("%s", sex) ;

	printf("검색할 나이는?\n") ;
	printf("1. 13세 이하\n2. 14~18세\n3. 19~25세\n4. 25세 이상\n") ;
	printf("선택 : ") ;

	scanf("%d", &select ) ;
	getchar() ;
	divide(select, &low, &high) ;
	sprintf(query_buffer, query[LT], "profile", low, high, sex) ;

	if(mysql_query(&meeting, query_buffer) )
		exiterr() ;

	if( ! (result = mysql_store_result( &meeting ) ))
		exiterr() ;

	cnt = 0 ;

	while( row = mysql_fetch_row( result ) )
	{
		printf("검색 결과 %d : \n", cnt++) ;
		printf("이름 : %s\n", row[0] ) ;
		printf("성별 : %s\n", row[1] ) ;
		printf("나이 : %s\n", row[2] ) ;
		printf("취미 : %s\n", hobby[ atoi( row[3] )]) ;
		printf("직업 : %s\n", job[ atoi( row[4] )]) ;
		
		printf("더 보시려면 enter 키를 누르세요") ;
		getchar() ;

		/* row[i]는 char * 형입니다.  숫자로 바꿔주기 위해서 
		   atoi()를 썼습니다.
		   query.h를 보면 쉽게 이해될 수 있을 듯
		*/

	}
}

void divide(int select , int *low, int *high) 
{
	switch( select )
	{
		case 1: 
			*low = 0 ;
			*high = 13 ;
			break ;
		case 2:
			*low = 14 ;
			*high = 18 ;
			break ;
		case 3:
			*low = 19 ;
			*high = 25 ;
			break ;
		case 4 :
			*low = 26 ;
			*high = 99 ;
			break ;
		default:
			*low = 0 ;
			*high = 100 ;
			break ;
	}
}
void connect2db( void )
{
	/* host 부분이 NULL이면 localhost입니다. */
	if( !mysql_connect(&meeting, NULL, "inos", "hjshjs"))
		exiterr() ;

	/* meeting이라는 db를 선택 */
	if( mysql_select_db(&meeting, "meeting")) 
		exiterr() ;
}

void close2db( void )
{
	mysql_free_result( result ) ;
	mysql_close( &meeting ) ;
}

void exiterr( void )
{
	printf("ERROR : %s\n", mysql_error(&meeting)) ;
	exit(1) ;
}

6. 컴파일 방법

	컴파일을 하기 위해선 gcc의 옵션 정도는 아셔야 합니다. 
	위에 있는 강좌의 처음을 참고하세요.

7. 실행 결과

	만들어진 실행 파일을 그냥 실행 시켜도 되지만,,,,
	그럼 외부에서 접속해서 사용할 수는 없잖아여....
	그래서 telnet으로 접속해서 사용하는 방법을 생각해 봤네여.

	네트웍 프로그래밍 하기 지겨워서리....
	일단 암호없는 계정을 만들고( 1번을 보세여)
	계정의 쉘을 우리가 만든 프로그램으로 했습니다.
	/etc/passwd 파일에서 쉘 부분을 이 프로그램으로 바꿔주세여....

	실행을 해보면 다음과 같습니다.

	InoS Linux release 5.1 (AddOn)
	Kernel 2.0.35 on an i686
	login: inos
	Last login: Mon Mar 22 20:10:05 from 192.168.1.2
	1. 이름으로 검색
	2. 성별과 나이로 검색
	선택하세요 : 1
	검색하실 이름을 입력하십시오
	검색할 이름 : 허정수
	이름 : 허정수
	성별 : 남
	나이 : 22
	취미 : 남
	직업 : 22

	단순히 예제 프로그램이라 많은 일을 하진 않습니다.

8. 마침
	
	많은 도움이 되었으면 하는데.....
	MySQL에 있는 예제만큼 밖에 안되나 보네여...
	근데 조금만 응용하면, 좋은 프로그램 만들 수 
	있을 거예여....

	질문이 있으시다면
	InoS에게 
	메일을 보내주세여.
	감사합니다.