/* chat.c 鱈千屋 ver 0.1b Copyright (c) 1999- TaraChan */ /*#define DEBUG*/ #include #include #include #include #include #include "cgi.h" #include "jc.h" #include "stringxx.h" #include "logfile.h" #ifdef DEBUG #define DEBUG_PRINT_D(index,val) printf("(%s):(%d)
\n",(index),(val)) #define DEBUG_PRINT_S(index,val) printf("(%s):(%s)
\n",(index),(val)) #else #define DEBUG_PRINT_D(index,val) #define DEBUG_PRINT_S(index,val) #endif #define HAIRETSU_SIZE(a) sizeof(a)/sizeof(a[0]) /*mbr_chk()用スイッチ*/ #define OUT_CHK 0 /*退室処理*/ #define IN_CHK 1 /*入室時処理*/ #define HASH_SIZE 32 /*コンフィグの変数の個数*/ #define BUFFER_SIZE 1024 /*文字バッファの大きさ(文字数)*/ #define LINE_SIZE 1024 /*1行の最大文字数*/ #define FILE_NAME_SIZE 64 /*ファイル名の最大文字数*/ #define DATE_SIZE 128 /*日付の最大文字数*/ #define ITOS_SIZE 16 /*数字の最高桁数(文字変換時)*/ #define RND_SU 10000 /*乱数の個数*/ #define PAR_SIZE 64 /*back_parstのサイズ*/ #define CHAT_MIN_LINE 10 /*logの最小行数*/ #define CHAT_MAX_LINE 50 /*logの最大行数*/ #define MIN_RETIME 10 /*最小リロード時間*/ #define MAX_RETIME 180 /*最大リロード時間*/ #define MAX_MEMBER 30 /*最大人数*/ #define ROOM_SIZE 62 /*部屋数*/ #define FALL_TIME 90 /*いないと判断するまでの時間*/ #define P_CHAR '|' /*文字列の区切り文字として使用。*/ /*フォームから受け取る整数変数*/ #define F_RETIME "t" #define F_ROOM "r" #define F_LOGSU "l" /*ユーザ変数展開用*/ #define SYS_HANDLE "" /*システムメッセージ用*/ #define U_ROOM "[room]" #define U_HANDLE "[handle]" #define U_ROOMNAME "[room_name]" /*この三つ、重複*/ #define U_COMENT "[coment]" #define U_DATE "[date]" #define U_SEC "[sec]" #define U_MIN "[min]" #define U_HOUR "[hour]" #define U_MDAY "[mday]" #define U_MON "[mon]" #define U_YEAR "[year]" #define U_WDAY "[wday]" /*モード*/ #define SET_FRAME 's' #define OPERATE 'o' #define LOGS 'l' #define CHAT_EXIT 'e' typedef struct{ char **val; char *name; }hensu_table; /*置換用テーブル*/ typedef struct{ char *name; /*置換する文字列*/ char *(*rep)(void *); /*置換される文字を返す関数*/ void *val; /*処理関数に渡す変数*/ }rep_table; /*==============================関数プロトタイプ============================*/ void page_index (void); void page_setframe (void); void page_operate (void); void page_logs (void); void page_exits (void); void mbr_chk(int sw); /*out or in*/ void u_open_print(char *in); void print_log(void); void print_member(void); void config_init(void); void form_init(void); void room_init(void); void noroom_init(void); void set_hensu(char **hensu,char *key,hash hashs[],int hashs_index); void set_ihensu(int *hensu,char *key,int min,int max,hash hashs[],int hash_index); char *back_encode(char *in); char *back_sysmsg(char *template,char *handle); char *back_filename(char *file,int room); char *back_date(time_t in_time); char *back_parst(char *in,int n); char *back_str(int i); void end(char *msg); /*==============================グローバル変数==============================*/ char con_file[]="chat.ini"; char room_file[]="room.ini"; char chat_logfile[]="chat\0.log"; /*\0に部屋名が入る*/ char mbr_logfile[]="member\0.log"; /*\0に部屋名が入る*/ int s_flag=0; /*会話ログのが更新されたか(保存するか)*/ char *chat_log[CHAT_MAX_LINE+1]; /*会話のログ*/ char *mbr_log[MAX_MEMBER+1]; /*メンバーログ*/ /*フォームからのデータ*/ char *handle,*coment,*pwd,*mode; int log_index,room,re_time; hensu_table formhensu_table[]= { {&handle,"h"}, {&coment,"c"}, {&pwd,"p"}, {&mode,"m"}, }; /*コンフィグファイルからのデータ*/ char *header,*lines,*sys_lines,*footer,*form,*title,*reload,*loghead; char *index_head,*index_line1,*index_line2,*index_foot,*frame_set; char *mbr_lines,*no_member,*date_lines,*weeks,*in_msg,*out_msg,*dead_msg; char *logout,*btn_logout,*ope_index; hensu_table cfghensu_table[]= { {&title,"title"}, {&header,"header"}, {&form,"form"}, {&lines,"lines"}, {&sys_lines,"sys_lines"}, {&in_msg,"in_msg"}, {&out_msg,"out_msg"}, {&dead_msg,"dead_msg"}, {&mbr_lines,"member_lines"}, {&footer,"footer"}, {&reload,"reload"}, {&loghead,"loghead"}, {&index_head,"index_head"}, {&index_line1,"index_line1"}, {&index_line2,"index_line2"}, {&index_foot,"index_foot"}, {&loghead,"loghead"}, {&frame_set,"frame_set"}, {&no_member,"no_member"}, {&date_lines,"date_lines"}, {&weeks,"weeks"}, {&logout,"logout"}, {&ope_index,"ope_index"}, {&btn_logout,"btn_logout"}, }; time_t now; /*実行時の時間*/ /*部屋のデータ*/ char *room_name; /*置換処理用インタフェース関数*/ char *rep_for_char(void *in){return *((char **)in);} char *rep_for_int(void *in){return back_str(*((int *)in));} char *rep_for_encode(void *in){return back_encode(*((char **)in));} char *rep_for_rnd(void *in){return back_str(rand()%RND_SU);} rep_table rep_tables[]= { {"[handle]",rep_for_char,&handle}, {"[room_name]",rep_for_char,&room_name}, {"[mode]",rep_for_char,&mode}, {"[pwd]",rep_for_char,&pwd}, {"[title]",rep_for_char,&title}, {"[retime]",back_str,&re_time}, {"[room]",rep_for_int,&room}, {"[logsu]",rep_for_int,&log_index}, {"[e_handle]",rep_for_encode,&handle}, {"[rnd]",rep_for_rnd,&handle}, }; /*==========================================================================*/ /*メイン関数*/ int main(void){ time(&now); srand(now); printf("Content-type: text/html\n\n"); chat_log[0]=NULL; config_init(); form_init(); DEBUG_PRINT_D("hashs",hash_index); switch (mode[0]){ case SET_FRAME : room_init(); page_setframe(); break; case OPERATE : room_init(); page_operate(); break; case LOGS : room_init(); page_logs(); break; case CHAT_EXIT : room_init(); page_exits(); break; default : noroom_init(); page_index(); } if (s_flag) save_log(back_filename(chat_logfile,room),chat_log,CHAT_MAX_LINE); return(0); } /*==========================================================================*/ /*表紙ページの処理*/ void page_index (void){ char *roomlog[ROOM_SIZE+1]; char *l_room_name; char buf[BUFFER_SIZE],*temp; int i; u_open_print(header); u_open_print(index_head); for (i=0;i<=ROOM_SIZE;i++) roomlog[i]=NULL; /*初期化*/ load_log(room_file,roomlog,ROOM_SIZE); for(i=0;iHASH_SIZE) end("不正なフォーム値です。"); cut_string(str_buf,strlen(str_buf),hashs_buf,&hash_index); for (i=0;i",">",BUFFER_SIZE); replace_word(buf,"\n","
",BUFFER_SIZE); ALLOC_STR(hashs[i].value,strlen(buf)+1 ,end("MemoryError in init()")); strcpy(hashs[i].value,buf); ALLOC_STR(hashs[i].name,strlen(hashs_buf[i].name)+1 ,end("MemoryError in init()")); strcpy(hashs[i].name,hashs_buf[i].name); } free (str_buf); for(i=0;imax)*hensu=max; if(*hensu=2)break; } buffer[strlen(buffer)]=c_room; buffer[FILE_NAME_SIZE-1]='0'; return buffer; } /*==========================================================================*/ /*in_timeを、書式date_lines,weeksによって静的文字列にする*/ char *back_date(time_t in_time){ static char ret_tm[DATE_SIZE]; char buf[DATE_SIZE]; struct tm *ptr; ptr=localtime(&in_time); strncpy(ret_tm,date_lines,DATE_SIZE); ret_tm[DATE_SIZE-1]='\0'; sprintf(buf,"%2d",ptr->tm_sec); replace_word(ret_tm,U_SEC,buf,DATE_SIZE); sprintf(buf,"%2d",ptr->tm_min); replace_word(ret_tm,U_MIN,buf,DATE_SIZE); sprintf(buf,"%2d",ptr->tm_hour); replace_word(ret_tm,U_HOUR,buf,DATE_SIZE); sprintf(buf,"%d",ptr->tm_mday); replace_word(ret_tm,U_MDAY,buf,DATE_SIZE); sprintf(buf,"%d",ptr->tm_mon+1); replace_word(ret_tm,U_MON,buf,DATE_SIZE); sprintf(buf,"%d",ptr->tm_year); replace_word(ret_tm,U_YEAR,buf,DATE_SIZE); sprintf(buf,"%s",back_parst(weeks,ptr->tm_wday)); replace_word(ret_tm,U_WDAY,buf,DATE_SIZE); return (ret_tm); } /*==========================================================================*/ /*P_CHARで区切られた文字列を配列とみなし、静的文字列を返す*/ char *back_parst(char *in,int n){ static char buf[PAR_SIZE]; int count=0,i=0; while(in!='\0'){ if (*in==P_CHAR)count++; if (count>=n){ if(*in==P_CHAR)in++; while(*in!='\0' && *in!=P_CHAR){ buf[i++]=*in++; if (i>=PAR_SIZE-1) break; } break; } in++; } buf[i]='\0'; return (buf); } /*==========================================================================*/ /*数値を変換し静的文字列を返す*/ char *back_str(int i){ static char str[ITOS_SIZE]; sprintf (str,"%d",i); return str; } /*==========================================================================*/ /*エラー終了*/ void end(char *msg){ printf("%s\n",msg); exit(1); } /*==========================================================================*/ /* [ver 0.1b] 1999.08.23 ・多チャンネル対応。 ・conv_str()の使用を中止。 1999.08.24 ・roomファイルによる、部屋の管理。 ・日付の表示。 ・URLに乱数を追加(URL自動集計回避機能)。 1999.08.26 ・システムメッセージ追加。 ・退室機能搭載。 1999.08.27 ・初期設定ルーチンの整理。 ・その他、コード修正。 */