PHS経由でネットに接続できるEthernetアダプタのファームウェアをハック・中編 ―― LANにつないでメールの送受信と自動実行を実現
// Get number sub | |
int GetNumber(char *ptr){int res=0;char ch;while(ch=*ptr++) | // 10進数文字列を数値へ変換 |
{if(ch<'0'||ch>'9')break;res=res*10+ch-'0';}return res;} | // 数字なら10倍して加算 |
// Send sub | |
char SendStr(char s,char *b){if(Write(s,b,StrLen(b))<0)return -2; | // TCP/IP送出 |
WaitWriteComplete(s);return 0;} | // 相手先のACKパケット到着確認 |
// POP handler | |
char PopHandler(char soc){ | // POPステート・マシン |
char *PopName="userid"; | // POPログイン用のユーザID |
char *PopPass="password"; | // POPログイン用のパスワード |
char ch,*sendbuf,*frombuf;int len,i; | // 各種バッファの確保 |
if(PopState){ | // アイドル・ステート以外なら |
if(GetNetLine(soc,recbuf,64,10)<0)return -4; | // POPサーバより1行入力 |
PrStr(recbuf);PrStr("¥r¥n"); | // デバッグ用に画面表示 |
if(PopState!=5&&PopState!=6&&*recbuf!='+')return -4; | // POPステータス・チェック |
} | // POPサーバより1行入力終了 |
switch(PopState){ | // それぞれのステートで分岐 |
case 1: | // POPへ接続済み |
sendbuf=MemoryAlloc(StrLen(PopName)+8);StrCpy(sendbuf,"USER "); | // USERコマンド生成開始 |
StrCat(sendbuf,PopName);StrCat(sendbuf,"¥r¥n"); | // USERコマンド生成の続き |
if(SendStr(soc,sendbuf)<0){MemoryFree(sendbuf);return -2;} | // USERコマンド送出 |
MemoryFree(sendbuf);PopState++;break; | // バッファの開放とステート進行 |
case 2: | // USERコマンド送出済み |
sendbuf=MemoryAlloc(StrLen(PopPass)+8);StrCpy(sendbuf, "PASS "); | // PASSコマンド生成開始 |
StrCat(sendbuf, PopPass);StrCat(sendbuf, "¥r¥n"); | // PASSコマンド生成の続き |
if(SendStr(soc,sendbuf)<0){MemoryFree(sendbuf);return -2;} | // PASSコマンド送出 |
MemoryFree(sendbuf);PopState++;break; | // バッファの開放とステート進行 |
case 3: | // PASSコマンド送出済み |
if(SendStr(soc,"STAT¥r¥n")<0)return -2;PopState++;break; | // STATコマンド送出 |
case 4: | // STATコマンド送出済み |
len=GetNumber(recbuf+4);if(!len)goto Finish; | // メールの総数を取得,なければセッション終了へ |
if(SendStr(soc,"TOP 1 0¥r¥n")<0)return -2;PopState++;break; | // TOPコマンド送出 |
case 5: | // TOPコマンド送出済み |
if(frombuf=StrStr(recbuf,"From: ")){ | // From:ヘッダ以外ならスキップ |
frombuf+=5;sendbuf=StrChr(frombuf,'<');if(sendbuf)frombuf=sendbuf; | // <メール・アドレス>形式かチェック |
while(*frombuf=='<'||*frombuf==' '||*frombuf=='"')frombuf++; | // <メール・アドレス>の中身だけ取り出す処理 |
sendbuf=frombuf; | // メール・アドレスの先頭ポインタを保存 |
while(*frombuf&&*frombuf!='¥r'&&*frombuf!='>'&&*frombuf!=' ' | // メール・アドレスの終端をサーチ |
&& *frombuf!='"'&&*frombuf!=0x28&&*frombuf!='¥n')frombuf++; | // メール・アドレスの終端のサーチの続き |
len=frombuf-sendbuf;MailTo=MemoryAlloc(len+1); | // メール・アドレスの文字列長を求めバッファを確保 |
BufCopy(MailTo, sendbuf, len);MailTo[len]=0;PopState++;}break; | // 確保したバッファにアドレスをコピー |
case 6: | // すでにFrom:ヘッダが出現済み |
if(*recbuf=='.') | // 行頭にピリオドだとヘッダの終了 |
{if(SendStr(soc,"DELE 1¥r¥n")<0)return -2;PopState++;}break; | // DELEコマンド送出 |
case 7: | // DELEコマンド送出済み |
Finish: | // POPサーバのセッション終了 |
if(SendStr(soc,"QUIT¥r¥n") < 0)return -2;PopState++;break; | // QUITコマンド送出 |
case 8: | // QUITコマンド送出済み |
PopState=0;return 1; | // アイドル・ステートへ復帰して1でリターン |
} | |
return 0; | // ステート・マシン実行中は0でリターン |
} |
リスト4 メール自動返信のPOPファイル