<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);
}
|