#include <awlib.h>
char TGTFILE[260];
#define BUFSIZEUNIT 8192
typedef struct _STRBUF {
char *text;
int bsize;
int esize;
int tsize;
} STRBUF;
typedef struct _MSGBUF {
struct _MSGBUF *next;
char *msgtext;
} MSGBUF;
MSGBUF *MSGSTACK = NULL;
static char daynames_j[] = "日月火水木金土";
static char daynames_e[] = "SunMonTueWedThuFriSat";
static int istripod = 0;
int getmessagedate(struct tm *trec,char *datestr) {
time_t t;
char tmp[32];
char week1[16];
char week2[16];
int count;
time(&t);
memcpy(trec,localtime(&t),sizeof(struct tm));
/* 012345678901234567890123 */
/* 07月14日(金)18時06分09秒 */
strncpy(tmp,datestr,24);
tmp[2]='\0';
trec->tm_mon=atoi(tmp);
tmp[6]='\0';
trec->tm_mday=atoi(tmp+4);
tmp[11]='\0';
tmp[14]='\0';
trec->tm_hour=atoi(tmp+12);
tmp[18]='\0';
trec->tm_min=atoi(tmp+16);
tmp[22]='\0';
for(trec->tm_wday = 0; trec->tm_wday < 7; trec->tm_wday++) {
if(!strncmp(daynames_j+trec->tm_wday*2,tmp+9,2)) {
strncpy(week1,daynames_e+trec->tm_wday*3,3);
break;
}
}
trec->tm_sec=atoi(tmp+20);
for(count=0;count<10;count++) {
strftime(week2,sizeof(week2),"%a",trec);
if(!strncmp(week1,week2,3)) break;
trec->tm_year--;
}
return 0;
}
int storemessage(QDATA *qd,char *subject,char *sender,char *mail,char *date,char *text) {
MSGBUF *tmpmsg;
char idstr[128];
struct tm tmp;
char timestamp[128];
int result;
str tmptext;
getmessagedate(&tmp,date);
strftime(timestamp,sizeof(timestamp),"%c",&tmp);
strftime(idstr,sizeof(idstr),"<%Y%m%d%H%M%S>",&tmp);
if(qfind(qd,QFIND_MESSAGEID,(int)idstr)==-1) {
// debug("store %s",idstr);
//setstatustext(subject);
tmpmsg = (MSGBUF *)malloc(sizeof(MSGBUF));
tmptext = "From foo@bar " + timestamp + "\r\n";
if(mail) {
tmptext = tmptext + "From: " + sender + " <" + mail + ">\r\n";
} else {
tmptext = tmptext + "From: " + sender + "\r\n";
}
tmptext = tmptext + "Message-ID: " + idstr + "\r\n";
tmptext = tmptext + "Date: " + timestamp + "\r\n";
tmptext = tmptext + "Subject: " + subject + "\r\n";
tmptext = tmptext + "\r\n";
tmptext = tmptext + text;
tmptext = tmptext + "\r\n";
tmptext = tmptext + "\r\n";
tmpmsg->msgtext = strcpy(malloc(strlen(tmptext)+1),tmptext);
tmpmsg->next = MSGSTACK;
MSGSTACK = tmpmsg;
result=1;
} else {
debug("cache hit %s",idstr);
result=0;
}
return result;
}
int checkmessages(STRBUF *buf) {
QDATA *qd;
PAGE *page;
ELEMENTS *el;
ELEMENTS *ea;
int scan;
int index;
int result,count;
char *mail;
result=0;
qd=qopen(TGTFILE);
page=page_create(buf->text,buf->esize);
ea=page_elements(page);
el=page_find_elements(page,NULL,"HR");
for(scan=0;scan<el->count;scan++) {
index=el->items[scan].number+1;
if((ea->items[index].tag=="FONT") &&
(ea->items[index+1].tag=="B") &&
(ea->items[index+2].tag=="") &&
(page_element_text(page,&ea->items[index+3])==" 投稿者:")) {
if(ea->items[index+5].tag=="A") mail=page_element_att(page,&ea->items[index+5],"href")+7;
else mail=NULL;
count=storemessage(
qd,
page_element_text(page,&ea->items[index]),
page_element_text(page,&ea->items[index+4]),
mail,
page_element_text(page,&ea->items[index+7])+10,
page_element_text(page,&ea->items[index+11])
);
if(!count) break;
result += count;
}
}
page_free(page);
qclose(qd);
return result;
}
int getmessages(STRBUF *buf,INET *inet,char *ownerid,int offset) {
HTTP *http;
int tmplen;
char tmp[80];
int result,count;
// REGEX *re;
// char *spanstr;
if(offset) http=http_open(inet,"POST",(istripod ? "/cgi-bin/" : "/cgi-localbin/")+ownerid+".cgi",NULL,0);
else http=http_open(inet,"GET","/"+ownerid+".html",NULL,0);
if (http) {
buf->bsize += BUFSIZEUNIT;
buf->text = realloc(buf->text,buf->bsize+1);
sprintf(tmp,"ダウンロード中... %d メッセージ (%d bytes)",offset,buf->tsize);
setstatustext(tmp);
if(offset) {
sprintf(tmp,"page=%d&m=",offset);
tmplen = http_request(http,tmp,strlen(tmp),buf->text+buf->esize,BUFSIZEUNIT+1);
} else {
tmplen = http_request(http,NULL,0,buf->text+buf->esize,BUFSIZEUNIT+1);
}
buf->esize += tmplen;
buf->tsize += buf->esize;
while(tmplen==BUFSIZEUNIT) {
buf->bsize+=BUFSIZEUNIT;
buf->text=realloc(buf->text,buf->bsize+1);
tmplen=http_read(http,buf->text+buf->esize,BUFSIZEUNIT+1);
buf->esize += tmplen;
buf->tsize += buf->esize;
sprintf(tmp,"ダウンロード中... %d メッセージ (%d bytes)",offset,buf->tsize);
setstatustext(tmp);
}
buf->text[buf->esize]='\0';
sprintf(tmp,"ダウンロード中... %d メッセージ (%d bytes)",offset,buf->tsize);
setstatustext(tmp);
http_close(http);
}
result = 0;
if(count = checkmessages(buf)) {
/* //このメッセージがない場合があるので無視
re=re_compile("1回の表示で([0-9]+)件を越える場合は、.*</i></font>");
if(re_search(re,buf->text)>=0 && (spanstr=re_get_group(re,1))) result=atoi(spanstr);
re_free(re);
*/
if(strstr(buf->text,"<input type=submit value=\"次のページ\">")) result = offset + count;
else result = 0;
}
if(buf->text) {
free(buf->text);
buf->esize = 0;
buf->bsize = 0;
buf->text = NULL;
}
return result;
}
int main(int argc,char **argv) {
FILE *out;
char filename[260];
QDATA *qd;
MSGBUF *tmp;
INET *inet;
STRBUF buffer;
LOCATION loc;
char stat[80];
int ofs;
char *scan;
char* p;
if(argc<2) return -1;
for(ofs=1;ofs<argc-1;ofs++) {
if(!strcmp(argv[ofs],"-o")) {
ofs++;
if(ofs<argc-1) {
if(p = strrchr(argv[ofs], '\\')) // ディレクトリを無視!
++p;
else
p = argv[ofs];
sprintf(TGTFILE,"%s\\tcup\\%s", getenv("DATA_DIR"), p);
}
else return -1;
}
}
memset(&loc,0,sizeof(LOCATION));
loc.size=sizeof(LOCATION);
decodeurl(&loc,argv[argc-1]);
scan=strend(loc.path);
ofs=0;
while(scan>=loc.path) {
if(*scan=='.') *scan='\0';
else if(*scan=='/') {
ofs++;
if(ofs==2) {
memcpy((void *)loc.path,scan+1,strlen(scan+1)+1);
break;
}
}
scan--;
}
istripod = (strstr(loc.host, "tripod.co.jp") != NULL);
inet=inet_open(NULL,loc.host,loc.port,INET_SERVICE_HTTP,NULL,NULL,0);
if(inet) {
memset(&buffer,0,sizeof(STRBUF));
ofs=0;
setstatustext("ダウンロード開始");
do {
ofs = getmessages(&buffer,inet,loc.path,ofs);
} while(ofs && !terminated);
ofs = 0;
if(MSGSTACK) {
strcpy(filename,TGTFILE);
scan=strrchr(filename,'.');
if(!scan) scan=strend(filename);
strcpy(scan,".g00");
out=fopen(filename,"a+");
while(MSGSTACK) {
ofs++;
fwrite(MSGSTACK->msgtext,1,strlen(MSGSTACK->msgtext),out);
tmp = MSGSTACK->next;
free(MSGSTACK->msgtext);
free(MSGSTACK);
MSGSTACK = tmp;
}
fclose(out);
qd=qopen(TGTFILE);
qupdate(qd);
qclose(qd);
}
if(ofs > 0)
sprintf(stat,"巡回完了 (%d件取得)",ofs);
else
strcpy(stat,"巡回完了");
setstatustext(stat);
inet_close(inet);
}
return 0;
}
|