長くなりますがお力をお貸しください。
Cのコンソールアプリ@VC6.0です。
172.20.1.46,2090,61.121.100.107,80,20060202115041
..GET /aaa/bbb/ccc.cgi HTTP/1.1..Accept: */*..Accept-Language: ja..Accept-Encoding: gzip, deflate..User-Agent: Mozilla/4.0 (ddd; eee; fff)..Host: ggg.hhh.com..Connection: Keep-Alive..Cookie: opqrstuvwxyz.....
172.20.1.46,2091,61.121.100.107,80,20060202115044
..GET /sss/ttt/uuu.cgi HTTP/1.1..User-Agent: Mozilla/4.0 (ddd; eee; fff)..Host: ggg.hhh.com..Cookie: abcdefghijk.....
奇数行に「自IP、ポート、相手IP、ポート、日時」が「,」という文字区切りで
偶数行にリファラーやUAなどのパケット情報が「..」という文字列区切りで
以下繰り返し表示されている。
上記のような内容のテキストファイルが
実行ファイル直下のtxtフォルダに多くありまして、
[IP、ポート]
172.20.1.46, 2090 − 61.121.100.107 ,80
[Get]
/aaa/bbb/ccc.cgi HTTP/1.1
[Referer]
[User-Agent]
Mozila/4.00 (ddd; eee; fff)
[Host]
ggg.hhh.com
のように必要な部分だけを画面に表示したいのです。
奇数行はstrtok()で「,」で分割
複数行については
http://sometime.minidns.net/~ccgi/ref/strsplit.html
上記URLのstrsplit()関数を利用して「,,」で分割後
strstr()関数でGETやRefererといった文字列を探して表示させようと
考えていますがうまくいきません。
最初のファイルを読み込み必要な情報のみ表示し、
矢印キーなどで切り替え表示、ファイルエンドであれば
同じ日付の次のファイルを表示といったループにしたいのです。
int a,i = 0;
cDel[] = {0};
char str[8][512] = {0};
FILE *fp;
char* e_head = str[a]; // 最初は文字列の先頭を代入
char *token;
char elem[10][512];
char* next;
int iHeadCnt = 0;
char *p1, *p2, *p3, *p4;
char x[][16] = {"GET ","Referer:","User-Agent:","Host:"};
for (a=0;(fgets(str[a], 512, fp) != NULL);a++) {
// 1行目(IP、ポート)取得
fgets(str[a], 512, fp);
printf(" [自IP, 自ポート − 相手IP, 相手ポート]\n");
// トークンを取得 1行目IP、ポート表示
token = strtok( str[a], cDel );
printf(" %s", token);
token = strtok( NULL, cDel );
printf(", %s", token);
token = strtok( NULL, cDel );
printf(" − %s", token);
token = strtok( NULL, cDel );
printf(", %s\n\n", token);
a++;
// 2行目各情報取得
fgets(str[a], 1024, fp);
// 2行目を".."で分割
for(i=0 ; (next=StrSplit(e_head,"..")) != NULL ; i++) {
sprintf(elem[i],"%s",e_head);
e_head = next;
iHeadCnt++;
}
sprintf(elem[i],"%s",e_head);
// [Get]
puts(" [Get]");
for(i=0; i<iHeadCnt; i++) {
p1 = strstr(elem[i], x[0]);
if (p1 != NULL) {
printf(" %s\n\n",p1+4);
break;
}
}
// [Referer]
puts(" [Referer]");
for(i=0; i<=iHeadCnt; i++) {
p2 = strstr(elem[i], x[1]);
if (p2 != NULL) {
printf(" %s\n\n",p2+8);
break;
}
}
// 省略
}
> strstr()関数でGETやRefererといった文字列を探して表示させようと
> 考えていますがうまくいきません。
どこで、どのように上手くいきませんか?
あまり詳しくは見ていませんが、とりあえず気づいた点をいくつか。
> for (a=0;(fgets(str[a], 512, fp) != NULL);a++) {
> // 1行目(IP、ポート)取得
> fgets(str[a], 512, fp);
これって、1行目を読み飛ばしませんか?
> char elem[10][512];
> (中略)
> // 2行目を".."で分割
> for(i=0 ; (next=StrSplit(e_head,"..")) != NULL ; i++) {
> sprintf(elem[i],"%s",e_head);
2行目の中に".."が11個以上出てきた場合、メモリ破壊しませんか?
(".."が11個以上存在する可能性が皆無なら、問題ありませんが。)
> // 1行目(IP、ポート)取得
> fgets(str[a], 512, fp);
> (中略)
> // 2行目各情報取得
> fgets(str[a], 1024, fp);
fgets()が成功したかのエラーチェックがありませんが、問題ありませんか?
ぱっと見、こんなところで。
まずデバッガで、ステップ実行しながら、どこまでが、Jack06さんの考えているとおりに動いており、
どの時点でおかしくなるかを確認しましょう。
関数にして何とか思い通り動くようになりました。
// アクセス履歴を解析
int aspParseAccess(char* sBuf1, char* sBuf2, AccessData* adata)
{
int i, iHeadCnt;
char sMethod[100][1024] = {0};
char* e_head = sBuf2; /* 最初は文字列の先頭を代入しておく */
char* pNext;
char* cDel = ",";
const char* token = 0;
char *pGet, *pReferer, *pUserAgent, *pHost;
// 奇数行を","で分割
strcpy(adata->ports.sIp1, strtok(sBuf1, cDel));
strcpy(adata->ports.sPort1, strtok(NULL, cDel));
strcpy(adata->ports.sIp2, strtok(NULL, cDel));
strcpy(adata->ports.sPort2, strtok(NULL, cDel));
// 偶数行を".."で分割
i = 0;
iHeadCnt = 0;
while ((pNext=aspStrSplit(e_head,"..")) != NULL) {
sprintf(sMethod[i],"%s",e_head);
e_head = pNext;
iHeadCnt++;
i++;
}
sprintf(sMethod[i],"%s",e_head);
// [Get]
for(i=0; i<=iHeadCnt; i++) {
pGet = strstr(sMethod[i], "GET ");
if (pGet != NULL) {
strcpy(adata->sGet, pGet+4);
break;}
if(i == iHeadCnt){
strcpy(adata->sGet, " ");
}
}
// [Referer]
for(i=0; i<=iHeadCnt; i++) {
pReferer = strstr(sMethod[i], "Referer: ");
if (pReferer != NULL) {
strcpy(adata->sReferer, pReferer+9);
break;}
if(i == iHeadCnt){
strcpy(adata->sReferer, " ");
}
}
// [User-Agent]
for(i=0; i<=iHeadCnt; i++) {
pUserAgent = strstr(sMethod[i], "User-Agent: ");
if (pUserAgent != NULL) {
strcpy(adata->sUserAgent ,pUserAgent+12);
break;}
if(i == iHeadCnt){
strcpy(adata->sUserAgent, " ");
}
}
// [Host]
for(i=0; i<=iHeadCnt; i++) {
pHost = strstr(sMethod[i], "Host: ");
if (pHost != NULL) {
strcpy(adata->sHost ,pHost+6);
break;}
if(i == iHeadCnt){
strcpy(adata->sHost, " ");
}
}
return 0;
}
ツイート | ![]() |