<html> <head> <title>ゲストブック</title> </head> <body> <center> <h2>ゲストブック</h2> みんなのスペースです<br> たくさん書き込んでくださいね!<br> <br> <!--APPEND HERE--> <hr> </body> </html> | まず、左のようなゲストブックのデータファイルの初期ファイルを 作成します。これの<!--APPEND HERE-->の部分へ次々に 新しいメッセージを追加します。<!--APPEND HERE--> はブラウザにとってはコメントですので、 ユーザーはわざわざ見ようとしなければ見えないわけです。 このファイルには、nobodyが 書き込みアクセスしますので、666などnobodyが書き込める パーミッションを設定します。 |
<html> <head> <title>書き込んでね </title> </head> <body> <center> <h2>書き込んでね!!</h2> </center> <form method="POST" action="gbkakiko.cgi"> <p>ご意見<br> <textarea cols="40" rows="10" name="comment"> ここになんかかいてね!</textarea> <p>名前<br> <input type="text" name="name"> <p> <input type="submit" value="send"> </form> </body> </html> | 次に、このような入力用のフォームを作ります。 データを単にgbkakiko.cgiに渡すだけのものです。 説明は要りませんね。 |
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXLEN 4096 main() { char *inputstring,*cLength,*name[20],*value[20]; int nfield,retcode; long i,length; char buf[MAXLEN]; FILE *old,*new; char *oldname="gbdata.html",*newname="gbdata.temp", *mark="<!--APPEND HERE-->"; int decode_form(),parse_form(),nkfsub(); cLength=(char*)getenv("CONTENT_LENGTH"); length=atol(cLength); if(length>MAXLEN) {printf("CONTENT_LENGTH>MAXLEN\n");exit(0);} inputstring=(char*)malloc(length+1); scanf("%s",inputstring); parse_form(inputstring,MAXLEN,name,value,&nfield); for(i=0;i<2;i++) decode_form(value[i],strlen(value[i])); old=fopen(oldname,"r"); new=fopen(newname,"w"); while(fgets(buf,MAXLEN,old)){ if(strstr(buf,mark)){ fprintf(new,"%s\n",mark); fputs("<hr>\n",new); nkfsub("s",value[0],buf); fputs(buf,new); fputs("<div align=right>",new); nkfsub("s",value[1],buf); fputs(buf,new); fputs("</div>",new); } else { fputs(buf,new); } } fclose(old); fclose(new); rename(newname,oldname); printf("Content-type: text/html\n\n"); printf("<HTML><HEAD></HEAD><BODY>\n"); printf("<center><h2>Thank YOU!!</h2></center>\n"); printf("\n</BODY></HTML>\n"); free(inputstring); exit(0); } |
これが、書き込みのためのCGIプログラムのソースです。
前述しましたが、同時アクセス問題と、SSIタグの問題には
説明の便のため対処してませんので、実際に使う時にはそれぞれ、
アクセスカウンタの章と、このページの始めの方を参考に
して下さいな。 まず、定法によって、フォームからのデータを 受け取ります。ここで用いている parse_form()とdecode_form()関数については、 「基本的な入出力」の章で説明してありますが、 この説明の後で再掲しておきます。 次に、ゲストブックのデータファイルと 作業ファイルをオープンします。 同時アクセスに対処するためには、ここのとこの前に ロックを掛けて下さい。 次のループで新しいデータファイルを作ります。 前に決めたマーク"<!--APPEND HERE-->" 以外の行は、左から右へと、作業ファイルにコピーします。 一方このマークに当ったら、フォームのデータを 作業ファイルに書き込みます。 この時に、nkfsub()でデータをシフトJISに変換します。 このサブルーチンはオリジナルのnkfを改変したものです。 「基本的な入出力」の章で使い方を書いておきましたので 参考にして下さい。 ダウンロードは ここからして下さい。Windowsの ために改行コードをCR/LFにしたものは ここにあります。 後は、後始末をして、作業ファイルをデータファイルに コピーするだけです。 |
#include <stdio.h> #include <stdlib.h> #include <string.h> int parse_form(char* s_in,long maxl,char* name[],char* value[],int *p_nfld) { int i,cur_field; *p_nfld=0; i=0; cur_field=0; if(s_in[0]==NULL) return(-1); name[0]=s_in; while((s_in[++i]!=NULL)&&(i<maxl)){ if(s_in[i]=='='){ s_in[i]=NULL; value[cur_field]=s_in+i+1; } else if(s_in[i]=='&'){ s_in[i]=NULL; cur_field++; name[cur_field]=s_in+i+1; } } *p_nfld=cur_field+1; return(0); } int decode_form(char* s,long len) { int i,j; char buf,*s1; if(len==0)return(-1); s1=(char*)malloc(len); for(i=0,j=0;i<len;i++,j++) { if(s[i]=='+'){s1[j]=' ';continue;} if(s[i]!='%') {s1[j]=s[i];continue;} buf=((s[++i]>='A') ? s[i]-'A'+10 : s[i]-'0'); buf*=16; buf+=((s[++i]>='A') ? s[i]-'A'+10 : s[i]-'0'); s1[j]=buf; } for(i=0;i<j;i++) s[i]=s1[i]; s[i]='\0'; free(s1); return(0); } |