CGI ÇÁ·Î±×·¡¹Ö

±è½Â¿µ (nobreak@cgiserver.net)

 

 

 

 

 

1ȸ : Äõ¸® ½ºÆ®¸µ µðÄÚ´õÀÇ Á¦ÀÛ

2ȸ : CGI Å×Å©´Ð

3ȸ : ÀÎÆ®¶ó³ÝÀ» À§ÇÑ À¥ º¸µå Á¦ÀÛ

 

  Áö³­È£¿¡¼­´Â ÄíŰ, SSIµîÀÇ CGI ±â¹ýµéÀ» ¾Ë¾Æº¸¾Ò´Ù. CGIÀÇ µ¶Æ¯ÇÑ µ¿ÀÛ ¹æ½Ä ¶§¹®¿¡ ´Þ¶ó Á®¾ßÇÏ´Â ÀÔ¡¤Ãâ·Â ±â¹ýÀ» ¤¾î º¸¾ÒÀ¸¹Ç·Î, ¾î´À Á¤µµ °³³äÀÌ Á¤¸³µÆÀ¸¸®¶ó ÆÇ´ÜµÈ´Ù. »óÅÂÁ¤º¸¸¦ À¯ÁöÇÏÁö ¸øÇÏ´Â Á¡°ú ÀÔ¡¤Ãâ·Â ¹æ½ÄÀÇ Â÷À̸¦ Á¦¿ÜÇϸé ÀϹÝÀûÀÎ ±×°Í°ú º° Â÷À̰¡ ¾øÀ¸¹Ç·Î  À̹ø È£¿¡¼­´Â À¥º¸µå¶ó´Â CGI¸¦ ¼³°èÇϸç, ¸î¸î ±â±³¸¦ Àû¿ëÇÏ¿© º¸¸ç, ÀÌ·¯ÇÑ ·ùÀÇ ÇÁ·Î±×·¥À» Á¦ÀÛÇÏ¸ç °Þ´Â ¹®Á¦Á¡À» »ìÆìº¸ÀÚ.

  ÀüüÀûÀ¸·Î À¥º¸µåÀÇ ¿Ü°üÀº ¸ñ·Ï(list), Ãß°¡, »èÁ¦, °ü¸® ¸ðµâÀ» °®Ãß°í ÀÖ¾î¾ß ÇϰڴÙ. ÅëÇÕÀÎÅÍÆäÀ̽º·Î ±¸¼ºÇϸç, °¢ ¸ðµâÀº 'mode'¶ó´Â Äõ¸®·Î ºÐ¸®Çϰí, ÇϳªÀÇ CGI·Î½á ´Ù¼öÀÇ DB¸¦ °ü¸®ÇÒ ¼ö ÀÖµµ·Ï ÇÏ¸ç ¸ðµâ°£ÀÇ ÀÎÀÚ Àü´ÞÀº °ú¿ùÈ£¿¡¼­ ¼³¸íÇÑ ISINDEX ¹æ½ÄÀ» ÃëÇϵµ·Ï ÇÏÀÚ.

 

µ¥ÀÌÅͺ£À̽º

  ÀÌ·¯ÇÑ ·ùÀÇ ÇÁ·Î±×·¥ Á¦ÀÛ¿¡ ÀÖ¾î ÇÙ½ÉÀº µ¥ÀÌÅͺ£À̽º(ÀÌÇÏ DB)ÀÇ ¼±Åà ¶Ç´Â ±¸ÇöÀ̶ó »ý°¢µÇ´Âµ¥, ´ÙÀ½°ú °°ÀÌ Å©°Ô 3°¡Áö ¹æ½ÄÀ¸·Î ³ª´­ ¼ö ÀÖ°Ú´Ù.

ù° : Postgres, mSQLµîÀÇ DBMS

µÑ° : DB Library

¼Â° : ÀÚü Á¦ÀÛ

  ÀϹÝÀûÀ¸·Î ¼ÒÇÁÆ®¿þ¾î°¡ ¾ÈÁ¤È­ ´Ü°è¿¡ Á¢¾îµå´Âµ¥´Â ¸î ¹øÀÇ ¹öÀü¾÷ ÀÛ¾÷ÀÌ µ¿¹ÝµÇ´Âµ¥, ÀÚü ¼³°èµÈ DBÀÇ ±¸¼º¿¡ ¹®Á¦°¡ ÁöÀûµÈ´Ù¸é, ±âÁ¸ ÀÚ·áÀÇ ¾ÈÁ¤¼ºÀ» º¸Àå¹Þ±â°¡ Èûµé´Ù. µû¶ó¼­ °³¹ßÀÚµéÀº ù°¿Í µÑ°ÀÇ ¹æ¹ýó·³ ¾ÈÁ¤¼ºÀÌ ¾î´ÀÁ¤µµ º¸ÀåµÈ DB¸¦ µµÀÔÇÏ°Ô µÈ´Ù. ÀÌ´Â ÀÚ·áÀÇ È£È¯¼º, ½Å·Ú¼º, µ¶¸³¼ºÀÌ Á¦°øµÇ¹Ç·Î ¼ÒÇÁÆ®¿þ¾îÀÇ ¹öÀü¾÷À̳ª ±¸¼ºÀÇ º¯È¯ µî¿¡µµ ½±°Ô ´ëó°¡ °¡´ÉÇÏ¿© ¼±È£µÇ´Â ¹æ½ÄÀÌ´Ù. ±×·¯³ª ÀڷᱸÁ¶°¡ µ¶Æ¯Çϰųª, °Ë»ö¼Óµµ Çâ»ó µîÀÇ ÀÌÀ¯·Î DB ¿£Áø ÀÚü¸¦ ¿ªÆÄÀϵîÀÇ ¾Ë°í¸®ÁòÀ» µµÀÔÇÏ¿© ¼³°èÇÏ´Â °æ¿ìµµ ÈçÈ÷ º¼ ¼ö Àִµ¥, ÆÄÀÏ Àá±Ý¿¡¼­ºÎÅÍ ÀúÀ塤ÃßÃâÀÇ ÃÖÀûÈ­±îÁö °³¹ßÀÚ°¡ ÀÏÀÏÀÌ ±¸ÇöÇØ¾ßÇÏ´Â ÁüÀ» Á®¾ß ÇÑ´Ù.

  ¸ðµÎ Àå´ÜÁ¡ÀÌ ÀÖÀ» ÅÙµ¥, ¿ì¸®°¡ ±¸ÇöÇÒ À¥º¸µåÀÇ °æ¿ì´Â ¾î¶°ÇÑ ÆÇ´ÜÀ» ³»·Á¾ß ÇÒ±î? ´ë±Ô¸ðÀÇ DB¸¦ ±¸ÃàÇÑ´Ù¸é, DBMS(DataBase Management System)¸¦ µµÀÔÇÏ´Â °ÍÀÌ È¿À²ÀûÀ̰ÚÁö¸¸, À¥º¸µåÀÇ °æ¿ì´Â ÀÚ·á°¡ ¸¸°ÇÀ» ³Ñ±â Èûµé¸ç, ÀÚ·áÀÇ ¾ç ¶ÇÇÑ Àû±â¿¡ DBMSÀÇ Àû¿ëÀº ¿À¸®»ç³É¿¡ ´ëÆ÷µé°í °¡´Â °ÝÀ̶ó ÆÇ´ÜµÈ´Ù. ¶ÇÇÑ °ø°³ ¹èÆ÷¸¦ ¸ñÀûÀ¸·Î ÇÑ´Ù¸é DBMS ¹è°æÁö½ÄÀÌ ¿ä±¸µÇ¹Ç·Î »ç¿ëÀÚ°¡ Èû°Ü¿ö ÇÒ ¼ö ÀÖ°Ú´Ù. ÀÚü ¿£ÁøÀ» ±¸ÇöÇÏ´Â °Í ¶ÇÇÑ ±â´ÉÀû Çâ»óÀ» ±â´ë Çϱä Èûµå¹Ç·Î Á¦ÃÄ µÎ°í ¹èÆ÷µÇ´Â DB ¶óÀ̺귯¸®¸¦ Àû¿ëÇϵµ·Ï ÇÏÀÚ.

 

GNU 'gdbm' Library

  ¿©·¯ °¡Áö Á¾·ùÀÇ DB ¶óÀ̺귯¸®°¡ Á¸ÀçÇÏÁö¸¸, ¿©±â¼± GNU ProjectÀÇ ÀÏȯÀ¸·Î °³¹ßµÈ 'gdbm' ¶óÀ̺귯¸®¸¦ ¼±ÅÃÇÏ¿´´Ù. 'gdbm'´Â ±âº»ÀûÀ¸·Î À¯ÀÏÇÑ 'key'°ª¿¡ ÇϳªÀÇ 'data'°¡ Á¸ÀçÇÑ´Ù. ¿äÁò ÈçÈ÷ ¸»ÇÏ´Â RDBMS¶ó´Â '°ü°³Çü µ¥ÀÌÅͺ£À̽º ½Ã½ºÅÛ'¿¡¼­´Â Table Á¤ÀÇ, ÆÐÅϰ˻öµîÀÌ DB ¿£Áø ÀÚü¿¡ Æ÷ÇÔÇϹǷΠ°³¹ßÀÚ´Â ´Ü¼øÈ÷ SQLµîÀ» Àû¿ëÇÏ¿© À̸¦ Á¦¾îÇÒ ¼ö ÀÖÁö¸¸, 'gdbm'Àº ´Ü¼øÈ÷ ÀÚ·áÀÇ ÀúÀå, ÃßÃ⸸À» Áö¿øÇϹǷÎ, ÀÌ·¯ÇÑ ºÎºÐÀº °³¹ßÀÚ°¡ ¼Õ¼ö ÇÁ·Î±×·¡¹Ö ÇÏ¿©¾ß Çϳª, ±× ±¸Á¶°¡ °£´ÜÇϹǷÎ, ¼Ò±Ô¸ð DB¸¦ Àû¿ëÇÒ ¶§ Æí¸®ÇÏ´Ù. ´ÜÁ¡À¸·Î´Â °ÅÄ£Àá±Ý±â¹ýÀ» »ç¿ëÇϹǷÎ, Àб⠸ðµå·Î´Â ¿©·¯ »ç¿ëÀÚ°¡ Á¢±ÙÇÒ ¼ö ÀÖÁö¸¸, ¾²±â ¸ðµå·ÎÀÇ Á¢±ÙÀº ÇϳªÀÇ ÇÁ·Î¼¼½º¸¸ÀÌ Çã¿ëµÈ´Ù.

  [Ç¥ 1]ÀÇ ÄÚµå´Â 'gdbm'À» »ç¿ëÇÏ¿© DB¸¦ »ý¼ºÇϰí, ÀڷḦ Ãß°¡, ÃßÃâÇÏ´Â ÇÔ¼ö¸¦ ¿¹·Î º¸¿©ÁØ´Ù.

[Ç¥ 1] 'gdbm'ÀÇ »ç¿ë¿¹

#include "gdbm.h"

#include "qDecoder.h"

 

static GDBM_FILE _dbf = NULL;

 

void DBOpen(char *filename, int flag){    // DB¸¦ ¿©´Â ÇÔ¼ö

  int i;

  

  if(_dbf != NULL)DBClose();              // DB°¡ ¿­·Á ÀÖ´Ù¸é ¸ÕÀú ´Ý´Â´Ù.

 

  for(i=0; i < 10; i++){

    _dbf = gdbm_open(filename, 512, flag, 0644, NULL);  // DB¸¦ ¿¬´Ù.

    if(_dbf != NULL)break;        // ¿­±â¿¡ ¼º°øÇÏ¸é ·çÇÁ¸¦ ºüÁ®³ª°¨.

    if(gdbm_errno == GDBM_FILE_OPEN_ERROR)DBError();   // DB°¡ Á¸ÀçÇÏÁö ¾ÊÀ¸¸é ¿¡·¯

    sleep(1);     // DB°¡ ´Ù¸¥ ÇÁ·Î¼¼¼­¿¡ ÀÇÇØ Àá°Ü ÀÖÀ¸¸é 1ÃÊÈÄ Àç½Ãµµ ÇÑ´Ù.

  }

  if(_dbf == NULL) qError("Time Out!!! ´Ù½Ã ½ÃµµÇϽʽÿÀ");  // ¿­±â ½ÇÆÐ

}

 

char *DBFetch(char *key){    // 'key'°ª¿¡ ÇØ´çÇÏ´Â 'data'¸¦ ¾ò´Â´Ù.

  datum buf, ret;

 

  if(_dbf == NULL) qError("DBFetch() : DB°¡ ¿­·ÁÀÖÁö ¾ÊÀ½");

  buf.dptr = key;

  buf.dsize = strlen(key) + 1;

  ret = gdbm_fetch(_dbf, buf);

  return ret.dptr;

}

 

void DBStore(char *key, char *str, int flag){  // DB¿¡ ÀÚ·á ÀúÀå

  datum key_data, data_data;

 

  if(key == NULL || str == NULL) qError("DBStore() : NULL Pointer´Â »ç¿ëµÉ ¼ö ¾øÀ½");

  if(_dbf == NULL) qError("DBFetch() : DB°¡ ¿­·ÁÀÖÁö ¾ÊÀ½");

 

  key_data.dptr = key, key_data.dsize = strlen(key) + 1;

  data_data.dptr = str, data_data.dsize = strlen(str) + 1;

 

  if(gdbm_store(_dbf, key_data, data_data, flag) != 0)DBError();  

}

  'gdbm' ¹èÆ÷ÆÇ°ú ÀÚ¼¼ÇÑ ¼³¸íÀº ¾Æ·¡ÀÇ ÁÖ¼Ò¿¡¼­ ¾òÀ» ¼ö ÀÖ´Ù.

  - ftp://cair-archive.kaist.ac.kr/pub/gnu/gnu.mit/gdbm-1.7.3.tar.gz

  - http://funnelweb.utcc.utk.edu/~harp/gnu/gdbm/gdbm_toc.html

 

Å×À̺í(Table) ¼³°è

  ¸ÕÀú À¥º¸µå¿¡¼­ »ç¿ëµÉ Å×À̺íÀ» [Ç¥ 2], [Ç¥ 3]°ú °°ÀÌ ±¸¼ºÇÏÀÚ. [Ç¥ 2]´Â À¥º¸µåÀÇ ±¸¼º¿¡ ´ëÇÑ °ÍÀ̸ç, [Ç¥ 3]Àº °Ô½Ã¹°¿¡ ´ëÇÑ Å×À̺íÀÌ´Ù.

  ¾Ë¾Æº» ¹Ù¿Í °°ÀÌ 'gdbm'Àº Àú¼öÁØÀÇ Á¦¾î¸¸À» Á¦°øÇϹǷÎ, ¿øÇÏ´Â Çü½ÄÀÇ Å×À̺íÀ» SQLÀÇ 'create table' ¸í·É°ú °°ÀÌ °£´ÜÈ÷ ±¸Çö ÇÒ ¼ö´Â ¾ø°Ú´Ù. ¿ì¸®´Â DBMS°¡ À¥º¸µå¿¡ ºÒÇÕ¸®ÇÏ´Ù°í ÆÇ´ÜÇÏ¿´À¸¹Ç·Î, Á» ¼ö°í½º·´Áö¸¸ ÀÌ·¯ÇÑ ±â´ÉÀ» ¼ÒÇÁÆ®¿þ¾î ÀÚü¿¡ ½É¾î ÁÖ¾î¾ß ÇÑ´Ù. Á¦ÀÛÇÒ À¥º¸µå´Â '±Û¾²±â' ¸ðµå ¶ÇÇÑ º°µµÀÇ HTML¹®¼­·Î Á¦ÀÛÇÏÁö ¾Ê°í ÅëÇÕÈ­ÇÏ·Á ÇϹǷΠ'conf.language'¶ó´Â Ç׸ñÀ» µÎ¾î ¸î°¡Áö ÇüÅÂÀÇ ÆûÀ» ¼±ÅÃÇÒ ¼ö ÀÖµµ·Ï ÇÏ¿´´Ù. ÀÌ´Â µÚ¿¡ ³ª¿Ã '°ü¸®' ¸ðµâ¿¡¼­ Á¦¾îµÈ´Ù.

 

[Ç¥ 2] À¥º¸µå ±¸¼º Å×À̺í

DB °Ë»ö Key

»ç ¿ë ¼³ ¸í

 conf.password

 ¾ÏȣȭµÈ ºñ¹Ð¹øÈ£

 conf.message

 À¥º¸µåÀÇ »ó´Ü¿¡ À§Ä¡ÇÏ´Â ±Û

 conf.homeurl

 È¨ÆäÀÌÁö ¾ÆÀÌÄÜÀÌ ¸µÅ©µÇ´Â URL

 conf.hometarget

 È¨ÆäÀÌÁö°¡ Ãâ·ÂµÇ´Â ÇÁ·¹ÀÓ¸í

 conf.backurl

 ÀÌÀüÆäÀÌÁö ¾ÆÀÌÄÜÀÌ ¸µÅ©µÇ´Â URL

 conf.backtarget

 ÀÌÀüÆäÀÌÁö°¡ Ãâ·ÂµÇ´Â ÇÁ·¹ÀÓ¸í

 conf.linktarget

 °Ô½Ã¹° ³»¿ëÁß ¸µÅ©µÈ ¹®¼­°¡ Ãâ·ÂµÉ ÇÁ·¹ÀÓ¸í

 conf.language

 Ç¥½ÃÇÒ ¾ð¾î¼±ÅÃ

 conf.htmlaccept

 °Ô½Ã¹° ³»¿ëÁß HTML¹®ÀÇ Àνġ¤°ÅºÎ(ÀÚµ¿¸µÅ©) ¼±ÅÃ

 conf.lines

 ÆäÀÌÁö´ç Ç¥½ÃµÉ °Ô½Ã¹°¼ö

 conf.lastnum

 ¸¶Áö¸· °Ô½Ã¹° ¹øÈ£

 conf.total

 Àüü °Ô½Ã¹° °³¼ö

[Ç¥ 3] °Ô½Ã¹° Å×À̺í

DB °Ë»ö Key (%d = °Ô½Ã¹° ¹øÈ£)

»ç ¿ë ¼³ ¸í

 %d.year, %d.mon, %d.day

 °Ô½Ã¹°ÀÇ ÀÛ¼º ³â, ¿ù, ÀÏ

 %d,hour, %d.min

 °Ô½Ã¹°ÀÇ ÀÛ¼º ½Ã°£, ºÐ

 %d.ip, %d.domain

 ÀÛ¼ºÀÚÀÇ IP, È£½ºÆ®¸í

 %d.name

 ÀÛ¼ºÀÚ À̸§

 %d.email

 ÀÛ¼ºÀÚ ÀüÀÚ¿ìÆí ÁÖ¼Ò

 %d.title

 °Ô½Ã¹°ÀÇ Á¦¸ñ

 %d.text

 °Ô½Ã¹°ÀÇ ³»¿ë

 %d.access

 ÀÐÀº Ƚ¼ö

 

¸ñ·Ï º¸±â ¸ðµâ°ú Å¥(queue)

  ±¸Ã¼ÀûÀÎ ÀÚ·á ÇüűîÁö ±¸»óÇÏ¿´À¸´Ï, ¸ñ·Ï º¸±â ¸ðµâºÎÅÍ ¼³°èÇØ º¸ÀÚ.

  'wwwboard.cgi?db=test&mode=list'¿Í °°ÀÌ È£ÃâµÇ¾úÀ» ¶§ Àû¿ëµÇµµ·Ï Çϰí, 'Á¦¸ñ, À̸§, ³¯Â¥, ¹øÈ£, ³»¿ë'À» ÆÐÅϰ˻ö ÇÒ ¼ö ÀÖµµ·Ï ÇÏÀÚ. °Ë»öÆÐÅÏ ¾øÀÌ È£ÃâµÉ °æ¿ì ¸¶Áö¸· Æ÷½ºÆÃµÈ °Ô½Ã¹°ºÎÅÍ º¸¿©ÁÖ¸ç, ÇöÀçÀÇ º¯¼ö´Â ISINDEX ¹æ½ÄÀ¸·Î »óÅ À¯Áö¸¦ Çϵµ·Ï ÇÏÀÚ.

  ±âº»ÀûÀ¸·Î 'conf.lastnum'¿¡¼­ ¸¶Áö¸· °Ô½Ã¹° ¹øÈ£¸¦ ã¾Æ 'conf.lines'ÀÇ °³¼ö¸¸Å­ Ãâ·ÂÇÏ¿© ÁÙ ¼ö ÀÖ°Ú´Ù. Ãâ·ÂµÈ ÆäÀÌÁöÁß ÃÖ»ó´Ü°ú ÃÖÇÏ´ÜÀÇ °Ô½Ã¹° ¹øÈ£°¡ 30°ú 15 ¶ó¸é, '´ÙÀ½ÆäÀÌÁö' ¾ÆÀÌÄÜ ¸µÅ©¿£ 'wwwboard.cgi?db=test&num=14'¸¦ 'ÀÌÀü ÆäÀÌÁö' ¸µÅ©¿£ 'wwwboard.cgi?db=test&num=45'¿Í °°ÀÌ ±¸Çö ÇÒ ¼ö ÀÖ°Ú´Ù.

  ±×·¯³ª ÀÌ·¸µí °Ô½Ã¹° ¹øÈ£¸¦ »ç¿ëÇÑ ¹æ¹ü¿£ ¾à°£ÀÇ ¹®Á¦Á¡ÀÌ º¸ÀδÙ. '´ÙÀ½ÆäÀÌÁö' ¸µÅ©ÀÏ °æ¿ì¿£ º° ¹®Á¦½ÃµÇÁö ¾ÊÀ¸³ª, 'ÀÌÀüÆäÀÌÁö' ¸µÅ©ÀÇ °æ¿ì 45¹ø°ú 31¹ø »çÀÌ¿¡ »èÁ¦µÈ °Ô½Ã¹°ÀÌ ÀÖ´Ù¸é, Ãâ·ÂµÇ´Â °Ô½Ã¹°ÀÇ °³¼ö´Â 'conf.lines'¿¡ Á¤ÀÇµÈ °³¼ö 15(°¡Á¤ÇÏÀÚ)º¸´Ù ÀûÀº Ãâ·ÂÀ» º¸¿©ÁÙ °ÍÀÌ´Ù. ÆÐÅϰ˻öÀÇ °æ¿ì¸¦ »ý°¢ÇØ º¸¸é, 45¹ø°ú 31¹ø »çÀÌ¿¡ ¸ÅĪµÇ´Â °Ô½Ã¹°ÀÌ ¾øÀ» ¼öµµ ÀÖ´Ù. HTTP ÇÁ·ÎÅäÄÝÀÇ Æ¯¼º»ó ÀϹÝÀû ÇÁ·Î±×·¥°ú °°ÀÌ »óÅÂÀ¯Áö°¡ µÇÁö ¾Ê±â ¶§¹®¿¡ °í·ÁµÇ´Â ºÎºÐÀÏÅÙµ¥, Å¥¸¦ Àû¿ëÇϸé È¿°úÀûÀ¸·Î ÇØ°áÇÒ ¼ö ÀÖ´Ù.

  'wwwboard.cgi?db=test&num=31&dir=up'°ú °°ÀÌ È£ÃâÇϸé, ³»ºÎÀûÀ¸·Î 31¹ø °Ô½Ã¹°ºÎÅÍ ¸¶Áö¸· °Ô½Ã¹°±îÁö(Å« ¹øÈ£) °Ë»öµÈ °á°ú¸¦ Å¥¿¡ ÀúÀåÈÄ Àιö½º Ãâ·ÂÇÏ¿© ÆäÀÌÁö´ç °Ë»ö°³¼ö¸¦

[±×¸² 1] ¸ñ·Ï º¸±â ¼ø¼­µµ

ÀÏÁ¤·® À¯ÁöÇÒ ¼ö ÀÖ´Ù. À̸¦ µµÇ¥È­ÇÏ¿© [±×¸² 1]¿¡ ³ªÅ¸³»¾ú°í,

 

 

[±×¸² 2]´Â È­¸é Ãâ·Â ÇüÅÂÀÌ´Ù.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

[±×¸² 2] À¥º¸µåÀÇ ¸ñ·Ïº¸±â

°ü¸® ¸ðµâ °ú ºñ¹Ð¹øÈ£ È®ÀÎ

  Á¦ÀÛÇÒ À¥º¸µå´Â ¿©·¯°³ÀÇ °Ô½ÃÆÇÀ» »ç¿ëÇÒ ¼ö Àִµ¥, °¢ °Ô½ÃÆÇÀÇ ±¸¼º(configuration)À» °ü¸® ÇÒ ¼ö ÀÖ´Â ¸ðµâÀ» žÀçÇÏ¿© [±×¸² 3]°ú °°ÀÌ À¥»ó¿¡¼­ °ü¸®¸¦ ÇàÇÏ¸é Æí¸®ÇÏ´Ù. °ü¸® ¸ðµâ¿¡¼­´Â [Ç¥ 3]ÀÇ Å×ÀÌºí °ªÀ» Á¤Á¤ÇÒ ¼ö Àִµ¥, DB¸¦ »ç¿ëÇÏ¿© ÀúÀ塤ÂüÁ¶Çϱ⵵ ÇÏÁö¸¸, ¸ðµâÈ­µîÀÇ ÀÌÀ¯·Î 'db.conf'¿Í °°ÀÌ º°µµÀÇ ÆÄÀÏÀ» ´ÙÀ½°ú °°Àº Çü½ÄÀ¸·Î °ü¸®Çϱ⵵ ÇÑ´Ù.

Password = SYi30NGbHBYMs

Message = ¾È³çÇϼ¼¿ä. È«±æµ¿ÀÇ °Ô½ÃÆÇÀÔ´Ï´Ù.

HomeURL = http://cgi.hongik.ac.kr

  °Ô½Ã¹°ÀÇ »èÁ¦³ª, °ü¸® ¸ðµâ ÁøÀÔÀ» À§Çؼ­´Â ½Å¿ø È®ÀÎ ¹æ¹ýÀ¸·Î ºñ¹Ð¹øÈ£¸¦ ´ëÁ¶ Çϴµ¥, ºñ¹Ð¹øÈ£ÀÇ À¯ÃâÀ» ÃÖ´ëÇÑ ¸·±âÀ§ÇØ ÀÔ·ÂµÈ ºñ¹Ð¹øÈ£´Â ¾Ïȣȭ(Encrypt)ÇÏ¿© ÀúÀåÇϸç, °¢ ¸ðµâ°£ÀÇ Àü´Þ½Ã¿¡µµ ¾ÏȣȭµÈ ±×°ÍÀ» »ç¿ëÅä·Ï ÇÑ´Ù. ÀÔ·ÂµÈ ºñ¹Ð¹øÈ£°¡ ¾ÏȣȭµÇÁö ¾Ê°í °ü¸® ¸ðµâ·Î Àü´Þ(ISINDEX ¶Ç´Â HIDDEN TAG)µÉ °æ¿ì '¹®¼­ ¼Ò½º º¸±â'µîÀÇ ¹æ¹ýÀ¸·Î À¯ÃâµÉ ¼ö Àֱ⠶§¹®ÀÌ´Ù. Ȥ, ±âÁ¸¿¡ Á¦ÀÛµÈ CGI°¡ º¸¾Èº¸´Ù´Â °ü¸®ÀÇ Æí¸®¼º ¶§¹®¿¡ À̸¦ °£°úÇÏ¿´´Ù¸é, ¾Æ·¡¿Í °°Àº HTMLÀ» Ãâ·Â ¹®¼­¿¡ »ðÀÔÇÔÀ¸·Î½á [±×¸² 4]¿Í °°ÀÌ '¹®¼­ ¼Ò½º º¸±â'¸¦ ¹«·ÂÈ­ ½Ãų ¼ö ÀÖÀ¸³ª, ¸ðµç ºê¶ó¿ìÀú¿¡ Àû¿ëµÇ´Â °ÍÀº ¾Æ´Ï´Ï ÁÖÀÇ ¹Ù¶õ´Ù.

<head>

  <meta http-equiv='pragma' content='no-cache'>

</head>

  ¶ÇÇÑ ¾Æ·¡¿Í °°ÀÌ »õ·Î¿î ºê¶ó¿ìÀú¸¦ ¿­¾î Ãâ·ÂÇϰí, ÀÏ·ÃÀÇ ÀýÂ÷¸¦ ¸¶Ä£ ÈÄ ºê¶ó¿ìÀú¸¦ ´Ý´Â ¹æ¹ýµµ °í·ÁµÉ ¼ö ÀÖ´Ù.

<!-- »õ·Î¿î ºê¶ó¿ìÀú·Î Ãâ·Â -->

<a href='wwwboard.cgi?db=test&mode=admin' target='admin'>°ü¸®</a>

<!-- ÇöÀçÀÇ ºê¶ó¿ìÀú¸¦ Á¾·á -->

<form>

  <input type=button value='Á¾·á' onClick='window.close()'>

</form>

  ´ëºÎºÐÀÇ À¯´Ð½º ½Ã½ºÅÛ¿¡¼­´Â ´Ü ¹æÇâ ¾Ïȣȭ ÇÔ¼ö¸¦ Á¦°øÇϴµ¥ ´ÙÀ½ÀÇ Äڵ带 »ìÆìº¸ÀÚ.

char *crypt(const char *key, const char *salt);

 

char *EncPasswd(char *string){

  return crypt(string, "SY");

}

 °°Àº ¹®ÀÚ¿­À» ¾ÏÈ£È­ÇØµµ 'salt'°ª¿¡ ÇØ´çÇÏ´Â 2¹ÙÀÌÆ®ÀÇ ¹®ÀÚ¿­¿¡ µû¶ó ÀüÇô ´Ù¸¥ °á°ú¸¦ ¾òÀ» ¼ö Àִµ¥, º¹±ÍµÇ´Â ¹®ÀÚ¿­ÀÇ Ã³À½ 2¹ÙÀÌÆ®´Â salt°ªÀ» Ç¥½ÃÇÑ´Ù. ÇÊÀÚÀÇ ½Ã½ºÅÛ¿¡¼­ ¹®ÀÚ¿­ "0000"À» ÀÎÀڷΠȣÃâÇÏ¿´À» ¶§ º¹±ÍµÇ´Â °ªÀº "SYi30NGbHBYMs"¿´´Ù.

  [±×¸² 5]´Â À̸¦ ÀÌ¿ëÇÑ ºñ¹Ð¹øÈ£ È®ÀÎ È­¸éÀÌ´Ù.

[±×¸² 3] °ü¸® ¸ðµâ

[±×¸² 4] 'no-cache' Àû¿ë

[±×¸² 5] ºñ¹Ð¹øÈ£ È®ÀÎ

 

¾²±â ¸ðµâ°ú ÄíŰ(Cookie)

  »ç¿ëÀÇ Æí¸®¼ºÀ» À§ÇØ, ¾²±â È­¸éµµ ³»ÀåÀ» ½ÃŰÀÚ. ¾²±â ¸ðµâ·ÎÀÇ ÁøÀÔÀº 'wwwboard?db=test&mode=write'·Î Çϸç, ¹®¼­È­ÀÏÀÇ ¾÷·Îµåµµ Áö¿øÇϵµ·Ï ÇÏÀÚ.

  ¾÷·Îµå´Â Áö³­È£¿¡ ¾Ë¾Æº»¹Ù¿Í°°ÀÌ enctype='multipart/form-data'·Î ÀÎÄÚµùÇÏ¿© boundary°ªÀ¸·Î ºÐ¸®, ÀúÀåÅä·Ï ÇÒ¼öÀÖ´Ù.

  [±×¸² 6]°ú °°Àº ¾²±â È­¸éÀÇ ÀÎÀÚ´Â À̸§, E-mail, Á¦¸ñ, ³»¿ë, ÆÄÀÏÀÇ ¼øÀ¸·Î Àü´ÞµÇ´Âµ¥, stdin¿¡¼­ '--boundary'¿Í '--boundary' »çÀÌÀÇ °ªµéÀ» ¼ø¼­´ë·Î ÃëÇÏ¿© ó¸® ÇÒ ¼ö ÀÖ´Ù.

[±×¸² 6] À¥º¸µåÀÇ ¾²±â ¸Þ´º

  ±ÛÀ» ¾µ ¶§¸¶´Ù À̸§, E-mailÀ» ¾²´Â °ÍÀº ¼º°¡½Å ÀÏ Àϼö ÀÖÀ¸´Ï, Äí۸¦ Àû¿ëÇÏ¿© ÇÊ¿äÇÑ Á¤º¸¸¦ Ŭ¶óÀÌ¾ðÆ®¿¡ ÀúÀå½Ã۰í, Äí۰¡ Á¸ÀçÇÏ¸é ±× °ªÀ» À̸§°ú E-mail¶õ¿¡ Ç¥½ÃÇÏ¿© ÁÖµµ·Ï ÇÏÀÚ. ¶ÇÇÑ, E-mail°ú °°ÀÌ °Ë»ç°¡ °¡´ÉÇÑ ºÎºÐÀº Ÿ´ç¼º ¿©ºÎ¸¦ ÆÇº°ÇÏ¿© »ç¿ëÀÚÀÇ ½Ç¼ö¸¦ ¾Ë·ÁÁÙ¼ö ÀÖ°Ú´Ù. ¾Æ·¡ÀÇ ÄÚµå¿Í °°ÀÌ E-mailÁÖ¼ÒÀÇ ¿À·ù¸¦ °£´ÜÈ÷ ÆÇº°ÇÒ¼ö ÀÖ´Ù.

int qCheckEmail(char *email){

  char *ptr, *token, retstop, buf[60+1];

  int i, flag;

 

  if(email == NULL) return 0;

 

  if(strlen(email) > 60) return 0;

  strcpy(buf, email);

 

  token = "@.";                            // E-mail ºÐ¸®ÀÚ ¼³Á¤

  ptr = _strtok2(buf, token, &retstop);    // E-mailÀ» ºÐ¸®ÀÚ·Î ³ª´®

  for(flag = i = 1; ptr != NULL; i++){

    if(qStr09AZaz(ptr) == 0) flag = 0;     // ¹®ÀÚ¿­ °Ë»ç

    if((i == 1) && (retstop != '@'))flag = 0;

    if((i >= 2) && !(retstop == '.' || retstop == '\0'))flag = 0;

    ptr = _strtok2(NULL, token, &retstop);

  }

  if((i >=4) && (i <= 7)) return flag;

  return 0;

}

 

±Û º¸±â ¸ðµâ

  ±Û º¸±â ¸ðµâÀº ¼±ÅÃµÈ ±ÛÀ» [±×¸² 7]°ú °°ÀÌ º¸¿©ÁÙ ¶§ »ç¿ëµÇ´Âµ¥, ³»¿ëÁß¿¡ 'http://abc.com'°ú °°Àº Ç׸ñÀ» ÀÚµ¿À¸·Î ¸µÅ©ÇØ ÁÖ´Â ¹æ¹ý¿¡ ´ëÇØ »ìÆìº¸ÀÚ. ³»¿ë Ãâ·ÂÀº °ø¹éµµ Á¤È®È÷ Ãâ·ÂÇÏ¿© ÁÖ¾î¾ß ÇϹǷÎ, <pre> TAG³ª <xmp> TAG¸¦ Ȱ¿ëÇÒ¼ö Àִµ¥, ÀÚµ¿ ¸µÅ©¸¦ ¼öÇàÇϱâ À§Çؼ­´Â <pre> TAG¿Í [Ç¥ 4]¿Í °°Àº Ãâ·Â ÇÔ¼ö¸¦ Ȱ¿ëÇÏ¿© ±¸ÇöÇÒ¼ö ÀÖ°Ú´Ù.

  [Ç¥ 5]´Â [Ç¥ 4]ÀÇ ÇÔ¼ö¸¦ »ç¿ëÇÑ Ãâ·Â ÇüŸ¦ º¸¿©ÁØ´Ù.

 

[Ç¥ 4] ÀÚµ¿ ¸µÅ©¸¦ ¼öÇàÇÏ´Â ÇÔ¼ö

void qPuts(int mode, char *buf){

 

  if(mode == 0) printf("%s", buf);

  else {

    char *ptr, retstop, *target, *token;

    int printhtml, autolink, linkflag, ignoreflag;

 

    switch(mode){  // Mode¿¡ µû¸¥ »óÅ Ç÷¹±× ¼³Á¤

      case 1 : {printhtml = 1, autolink = 0, target = ""; break;}

      case 2 : {printhtml = 1, autolink = 1, target = ""; break;}

      case 3 : {printhtml = 1, autolink = 1, target = "_top"; break;}

      case 4 : {printhtml = 0, autolink = 0, target = ""; break;}

      case 5 : {printhtml = 0, autolink = 1, target = ""; break;}

      case 6 : {printhtml = 0, autolink = 1, target = "_top"; break;}

      default: {qError("_autolink() : Invalid Mode (%d)", mode); break;}

    }

 

    if(autolink == 1) token = " `(){}[]<>\"',\r\n";  // ºÐ¸®ÀÚ ¼³Á¤

    else token = "<>\r\n";

 

    ptr = _strtok2(buf, token, &retstop);  // ¹®ÀÚ¿­À» ÅäÅ«À¸·Î ºÐ¸®

    for(linkflag = ignoreflag = 0; ptr != NULL;){

      if(autolink == 1){  // ºÐ¸®µÈ ¹®ÀÚ¿­ÀÇ ¸µÅ©¿©ºÎ ÆÇº°

        if(!strncmp(ptr, "http://", 7))linkflag = 1;

        else if(!strncmp(ptr, "ftp://", 6))linkflag = 1;     

        else if(!strncmp(ptr, "telnet://", 9))linkflag = 1;

        else if(!strncmp(ptr, "mailto:", 7))linkflag = 1;

        else if(!strncmp(ptr, "news:", 5))linkflag = 1;

        else linkflag = 0;

      }

      if(linkflag == 1 && ignoreflag == 0)

        printf("<a href='%s' target='%s'>%s</a>", ptr, target, ptr);

      else if(linkflag == 0 && ignoreflag == 0)

        printf("%s", ptr);

 

      if(printhtml == 1){   // TAG È­¸é Ãâ·Â

        if(retstop == '<') printf("&lt");

        else if(retstop == '>') printf("&gt");

        else printf("%c", retstop);

      }

      else {                // TAG ¹ö¸²

        if(retstop == '<') ignoreflag = 1;

        else if(retstop == '>') ignoreflag = 0;

        else if(ignoreflag  == 0) printf("%c", retstop);

      }

 

      ptr = _strtok2(NULL, token, &retstop);  // ´ÙÀ½ ¹®ÀÚ¿­ ºÐ¸®

    }

  }

}

[Ç¥ 5] ÀÚµ¿ ¸µÅ© Ãâ·Â ÇüÅÂ

Mode

±â ´É

°á °ú

0

printf()¿Í µ¿ÀÏ

<font><b>"http://shinan.hongik.ac.kr"</b></font>

1

TAG¸¦ Ãâ·Â

&ltfont&gt&ltb&gt"http://shinan.hongik.ac.kr"&lt/b&gt&lt/font&gt

2

Mode 1 + ÀÚµ¿ ¸µÅ©

&ltfont&gt&ltb&gt"<a href="http://shinan.hongik.ac.kr" target="">http://shinan.hongik.ac.kr</a>"&lt/b&gt&lt/font&gt

3

Mode 2 + ¸µÅ© Àüüȭ¸é Ãâ·Â

&ltfont&gt&ltb&gt"<a href="http://shinan.hongik.ac.kr" target="_top">http://shinan.hongik.ac.kr</a>"&lt/b&gt&lt/font&gt

4

TAG¸¦ ¹ö¸²

"http://shinan.hongik.ac.kr"

5

Mode 4 + ÀÚµ¿ ¸µÅ©

"<a href="http://shinan.hongik.ac.kr" target="">http://shinan.hongik.ac.kr</a>"

6

Mode 5 + ¸µÅ© Àüüȭ¸é Ãâ·Â

"<a href="http://shinan.hongik.ac.kr" target="_top">http://shinan.hongik.ac.kr</a>"

[±×¸² 7] ÀÚµ¿ ¸µÅ© Àû¿ë È­¸é

 

·Î±×(Log) ÀÛ¼º

  À¥¼­¹ö¿¡¼­ Á¦°øÇÏ´Â ·Î±× À̿ܿ¡ ÀÚüÀûÀÎ ·Î±×¸¦ ÀÛ¼ºÇØ¾ß ÇÒ ¶§°¡ Àִµ¥, ¾Æ·¡¿Í °°Àº °ü·Ê¸¦ ÁöŲ´Ù¸é, °ø°³µÈ ·Î±× ºÐ¼®Åøµµ ±×´ë·Î Àû¿ëÇÒ ¼ö°¡ ÀÖ´Ù.

¿ø°Ý È£½ºÆ® ¸í - - [³¯Â¥¿Í ½Ã°£] "¹æ½Ä ³»¿ë ÇÁ·ÎÅäÄÝ" - -

hongik.ac.kr - - [06/Jun/1997:09:43:39 +0900] "GET /index.html HTTP/1.0" - -

 

Time Out°ú °­Á¦ ½Ã±×³Î (signal)

  Ãâ·ÂÀÌ ¿Ï·áµÇÁö ¾ÊÀº »óÅ¿¡¼­ »ç¿ëÀÚ°¡ ºê¶ó¿ìÀúÀÇ 'STOP'¹öưÀ» ´©¸£¸é ¾î¶»°Ô µÉ±î? CGI´Â °­Á¦ Á¾·áµÉ±î? ±×·¸Áö ¾Ê´Ù. ¼­¹ö¿Í Ŭ¶óÀÌ¾ðÆ®°£ÀÇ ¿¬°á¸¸ÀÌ ²÷¾îÁö°í CGI´Â °è¼Ó ½ÇÇàµÈ´Ù. µû¶ó¼­, CGI´Â ¾î¶°ÇÑ ±ÔÁ¦ ¾øÀÌ Ã³¸®¸¦ ¿Ï·áÇϰí Á¤»ó Á¾·á¸¦ ÇÒ ¼ö ÀÖ´Ù.

  ±×·¯³ª ¼­¹ö¿¡ ±ÔÁ¤µÈ Time Out ½Ã°£ ¾È¿¡ Á¾·áÇÏÁö ¾ÊÀ¸¸é, ¼­¹ö´Â ÇØ´ç ÇÁ·Î¼¼¼­¸¦ °­Á¦ÀûÀ¸·Î Á¾·áÇÏ·Á ½ÃµµÇÑ´Ù. ´ëºÎºÐÀÇ °æ¿ì ÀÌ·¯ÇÑ °æ¿ì±îÁö ´ëóÇÒ ÇÊ¿ä´Â ¾øÁö¸¸, ÇÁ·Î±×·¥ÀÇ ±¸¼º»ó DBÀÇ µ¿±âÈ­(Sync)³ª ÆÄÀÏ ½Ã½ºÅÛ ÃÖÀûÈ­¿Í °°Àº ÀÛ¾÷ Áß¿¡´Â Á¾·áÀü ¸¶¹«¸® ÀÛ¾÷ÀÌ ÇÊÈ÷ ¼±ÇàµÇ¾î¾ß ÇÏ´Â °æ¿ì°¡ ÀÖ´Ù.

  ¾ÆÆÄÄ¡ ¼­¹öÀÇ °æ¿ì ÀÚ½ÄÇÁ·Î¼¼¼­(¼­¹ö´Â ÀÚ½ÅÀ» º¹Á¦[fork()]ÇÑÈÄ º¹Á¦µÈ ÇÁ·Î¼¼¼­¸¦ ÇØ´ç CGI·Î º¯È¯ ½ÇÇà[execl()]ÇÑ´Ù. Áï, CGI°¡ ÀÚ½ÄÇÁ·Î¼¼¼­ÀÓÀ» ¶æÇÑ´Ù.)°¡ °­Á¦ Á¾·áµÇÁö ¾ÊÀ» °æ¿ì SIGHUP, SIGTERM, SIGKILL ½Ã±×³ÎÀ» ¾à°£ÀÇ ½Ã°£Â÷¸¦ µÎ°í ÇÁ·Î¼¼¼­¿¡ º¸³½´Ù. SIGKILL ½Ã±×³ÎÀº ¹«½ÃÇÒ ¼ö ¾ø±â ¶§¹®¿¡, ½Ã±×³ÎÀ» Æ÷ÂøÇÑ ½ÃÁ¡ºÎÅÍ SIGKILL µµ´Þ Àü¿¡ (¾à 2, 3ÃÊ) ÇÊ¿äÇÑ ÀÛ¾÷À» ¸¶¹«¸®ÇØ¾ß ÇÑ´Ù.

  ´ÙÀ½ Äڵ带 ¹é±×¶ó¿îµå·Î ½ÇÇà½Ã۰í, 'kill -SIGHUP ÇÁ·Î¼¼¼­¹øÈ£' ¸í·ÉÀ» ³»·Áº¸ÀÚ.

#include <signal.h>

 

static void sig_detect(int signo){    // ½Ã±×³ÎÀ» ¹Þ¾ÒÀ» ¶§ ½ÇÇàµÉ ÇÔ¼ö

  printf("Signal(%d) received\n", signo);

  exit(-1);

}

 

void main(void){

  signal(SIGHUP, sig_detect);      // SIGHUP¿Í SIGTERM ½Ã±×³Î¿¡ ´ëÇØ

  signal(SIGTERM, sig_detect);     // sig_detect()¸¦ È£ÃâÇÔ

  pause();

}

 

¸¶Ä¡¸ç...

  3ȸ¿¡ °ÉÃÄ CGIÀÇ Àü¹ÝÀûÀÎ ¸ð½ÀÀ» ÈȾ¾Ò´Âµ¥, ÇÊÀÚ ³ª¸§´ë·Î ºÎÁ·ÇÑ Á¡ÀÌ ¸¹¾Æ ¿å½É¸¸Å­ ÁÁÀº ³»¿ëÀ» ±Û·Î½á Ç¥ÇöÇÏÁö ¸øÇÑ µí ½Í´Ù. ¹Ì¼÷ÇÑ ±Û¼Ø¾¾·Î µÎ¼­¾øÀÌ ¾´ ±ÛÀÌÁö¸¸ µ¶ÀÚµéÀÌ ÀÌ ±ÛÀ» Àаí Á¶±ÝÀ̳ª¸¶ µµ¿òÀÌ µÇ¾úÀ¸¸é ÇÑ´Ù.

  ÄÚµù¿¡ °üÇÑ ±Ã±ÝÁõÀº ¾Æ·¡ ÁÖ¼Ò¿¡¼­ ¼Ò½º¸¦ ´Ù¿î ¹Þ¾Æ »ìÆìº¸±â ¹Ù¶õ´Ù.

http://cgi.hongik.ac.kr/wwwboard/CrazyWWWBoard2.0.tar.Z