/*-------------------------------------------------------------------- amnuser-net 掲示板Logger Ver2.1 Programmed by うにゅん [はじめに] このプログラムは、amuser-netの掲示板を自動ロギングするもの です。UNIX用です。 [使用方法] (1) cc amloger.c -o amloger でコンパイルしてください(gccでもOK). (2) amloger [SJIS Conversion] [-t,h] [URL] & で常駐させます。 [SJIS Conversion] UNIXによってことなります。 0 = sjistoeuc コマンドをサポートしているUNIX (例 : IRIX ) 1 = sjtoeuc コマンドをサポートしているUNIX (例 : SunOS4, Solaris2.x) sjistoeucおよびsjtoeucを実行させてみることで、どちらをサポート しているか確認できます。 [-t,h] -tか-hのどちらかのロギングタイプを指定します。 -t : EUC-テキスト形式で整形してロギングします。 -h : EUC-HTML形式でロギングします。 [URL] 掲示板のURLを記述してください。 (例) ShadowPenguinのPenguinBBSをSolaris2.5でHTML形式でloggingする場合 amloger 1 -h hyper2.amuser-net.ne.jp/~auto/b28/usr/551/brd1/bbs.cgi あとは、1時間おきに自動ロギングし、ファイル名"log"(-h指定時はlog.html)に 自動的に追加されます。 -h指定時(HTML形式)でロギングした場合は、"top.html"にカラータグなどが含ま れますので、 cat top.html log.html > aaa.html とし、aaa.htmlを開くことによりブラウザで見ることができます。 [注意事項] (1) ゲストブック型のみロギング可能です。タイトル一覧モードはサポート していません。 (2) 1行レスには対応していません。 (3) ログはEUCコードで保存されますので、Windows等で読む場合は、 漢字コードを変換してください。 (*このプログラムは転載OKです) [動作確認] Solaris2.6, SunOS4, IRIX6.3 -------------------------------------------------------------------- */ #include #include #include #include #include #include #include #define LOGFILE "log" /* ログファイル名 */ #define INTERVAL_TIME 3600 /* 更新時間(秒) */ #define SEPARATER '-' /* ログ・セパレータ文字 */ #define SEPARATER_NUM 80 /* セパレータ文字数 */ #define PORT_HTTP 80 /* Request Port */ #define RECVBUF_SIZE 5000 /* 受信バッファサイズ */ #define LINEBUF_SIZE 10000 /* テンポラリバッファサイズ */ #define GETFILE ".amlog" /* テンポラリログファイル名 */ #define FILE_HEADER "top.html" /* Header */ int SJISTOEUC=0; int HTML_FLAG=0; int main(argc,argv) int argc; char *argv[]; { int n; char logf[100],buf[100],host[100],request[100]; char *p; int save_log(); int separation(); int diff_file(); void addnewlog(); int copyfile(); if (argc<4){ printf("usage : %s [switch] [-t,h] [url]\n",argv[0]); printf("[SJIS Conversion]\n"); printf(" 0 : sjistoeuc (IRIX)\n"); printf(" 1 : sjtoeuc (SunOS4, Solaris2.x)\n"); printf("[Log Type]\n"); printf(" -t : EUC Text\n"); printf(" -h : EUC HTML\n"); exit(1); } SJISTOEUC=atoi(argv[1]); if (strcmp(argv[2],"-t")==0 || strcmp(argv[2],"-T")==0) HTML_FLAG=0; else if (strcmp(argv[2],"-h")==0 || strcmp(argv[2],"-H")==0) HTML_FLAG=1; strcpy(host,argv[3]); if ((p=strchr(host,'/'))!=NULL) *p=0; else{ printf("Invalid URL.\n"); exit(1); } strcpy(request,strchr(argv[3],'/')); if (strlen(host)==0 || strlen(request)==0){ printf("Invalid URL.\n"); exit(1); } if (HTML_FLAG==1) sprintf(logf,"%s.html",LOGFILE); else strcpy(logf,LOGFILE); for (;;){ printf("Checking...\n"); sprintf(buf,"tmp0"); copyfile(buf,"tmp0.old"); save_log(host,request,GETFILE); separation(GETFILE,"tmp"); if (diff_file("tmp0","tmp0.old")==0 && existfile(logf)==1) { printf("新しい書き込みはありません\n"); }else addnewlog(logf,"tmp"); remove("amlog"); sleep(INTERVAL_TIME); } } /*======================================================= ファイルの存在チェック [Input] 0 = なし 1 = あり ======================================================= */ int existfile(file) char *file; { FILE *fp; if ((fp=fopen(file,"rb"))==NULL) return(0); fclose(fp); return(1); } /*======================================================= 新たなカキコの分割ファイル番号の終端を求め、 ログに追加する [Input] logfile : ログファイル sepf : 分割ファイルindex ======================================================= */ void addnewlog(logfile,sepf) char *logfile,*sepf; { FILE *fps,*fpl,*fpt,*fpcol; static char buf[LINEBUF_SIZE]; int i,j,r,maxi,n; /* ログに追加すべき分割ファイルの終端を選択 */ if (existfile(logfile)==1){ for (i=0,maxi=0;;i++){ sprintf(buf,"%s%d",sepf,i); if ((r=diff_file(buf,logfile))==1) maxi=i; else break; } if (r!=-1) printf("%d件の書き込みがあります.\n",maxi+1); }else{ printf("新規Logging開始\n"); maxi=-1; } /* 新ログファイルtempを準備 */ if ((fpt=fopen(".temp","wb"))==NULL){ printf("Can not write temp file.\n"); return; } /* 分割ファイルをtempファイルに書き込む */ for (i=0;;i++){ if (maxi!=-1 && i==maxi+1) break; sprintf(buf,"%s%d",sepf,i); if ((fps=fopen(buf,"rb"))==NULL) break; for (;;){ if (feof(fps)) break; if ((n=fread(buf,1,LINEBUF_SIZE,fps))==0) break; fwrite(buf,1,n,fpt); } fclose(fps); if (HTML_FLAG==1) fprintf(fpt,"
\n"); else{ for (j=0;j"); else strcpy(br,""); fprintf(fpt,"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%s\n",br); fprintf(fpt,"さきほど最新の書き込みが削除されたため、書き込み数の%s\n",br); fprintf(fpt,"算出ができません。1ページ全てをロギングしました %s\n",br); fprintf(fpt,"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%s\n",br); if (HTML_FLAG==1) fprintf(fpt,"
\n"); else{ for (j=0;j\n"); fprintf(fpcol,"%s\n",buf); fclose(fpcol); } first_colortag=1; } } /* 1カキコの終端をセット */ if (strcmp(buf,"")==0){ if (HTML_FLAG==1) fprintf(fpo,"%s\n",buf); flag=msgflag=0; name_count=-1; fclose(fpo); kn++; sprintf(fn,"%s%d",sepf,kn); if ((fpo=fopen(fn,"w"))==NULL){ printf("File write error.\n"); return(-1); } continue; } /* 1カキコの開始をセット */ if (strcmp(buf,"")==0){ if (HTML_FLAG==1) fprintf(fpo,"%s\n",buf); flag=1; } if (HTML_FLAG==1 && flag==1) fprintf(fpo,"%s\n",buf); if (HTML_FLAG==0 && flag==1){ if (msgflag==1){ /* メッセージ */ fprintf(fpo,"\n"); for (i=0;i",4)==0){ buf[i+3]=10; buf[i]=buf[i+1]=buf[i+2]=' '; } fprintf(fpo,"%s\n",buf); } if (name_count==1){ /* 日付 */ buf[strlen(buf)-4]=0; for (i=0;i='0' && buf[i]<='9') break; p=buf+i; fprintf(fpo,"【日  付】%s\n",p); name_count=-1; } if (name_count==0){ /* タイトル */ buf[strlen(buf)-4]=0; fprintf(fpo,"%s\n",buf); name_count++; } /* メッセージ開始行のセット */ if (strncmp(buf,"
%s",sj[SJISTOEUC],logf); system(buf); remove(".temp"); return(0); } /*======================================================= 指定したIPとリクエストによるHTTPイメージを 指定ファイルポインタに対して保存 [Input] fp : 保存対象ファイルポインタ ip : 対象IP request : HTTPリクエスト [Output] -1 = Error 0 = 正常終了 ======================================================= */ void dump_http(fp,ip,command) FILE *fp; char *ip,*command; { int make_connection(); int s,i,r; char buf[1000]; static char recvbuf[RECVBUF_SIZE]; if ((s=make_connection(PORT_HTTP,ip))<0) return; sprintf(buf,"GET %s\n",command); send(s,buf,strlen(buf),0); for (;;){ memset(recvbuf,0,RECVBUF_SIZE); if ((r=recv(s,recvbuf,RECVBUF_SIZE-1,0))<=0) break; recvbuf[RECVBUF_SIZE-1]=0; fprintf(fp,"%s",recvbuf); } fprintf(fp,"\n\n"); close(s); } /*======================================================= TCPコネクションを張る [Input] port : 対象ポート ipaddr : 対象IP [Output] -1 = ソケット作成失敗 -2 = BIND失敗 -3 = CONNECT失敗 -4 = UnknowHost その他 = socket ======================================================= */ int make_connection(port,ipaddr) int port; char *ipaddr; { struct sockaddr_in addr, server; struct hostent *host; void timeoutfunc(); int sock; sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0){ printf("Socket creation error"); return(-1); } memset((char *) &server, 0, sizeof(server)); server.sin_family = AF_INET; server.sin_port = 0; server.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(sock, (struct sockaddr *) &server, sizeof(server)) < 0) { close(sock); printf("Bind error "); return (-2); } addr.sin_family = AF_INET; addr.sin_port = htons(port); if ((addr.sin_addr.s_addr=inet_addr(ipaddr))==-1){ if ((host=gethostbyname(ipaddr))==NULL){ printf( "Unknown host.\n"); return(-4); } addr.sin_family = host->h_addrtype; memcpy( ( caddr_t )&addr.sin_addr, host->h_addr, host->h_length ); } if (connect(sock,(struct sockaddr *)&addr,sizeof(addr))!=0){ close(sock); return (-3); } return(sock); }