#include #include #include #include #include #include #include #include #include #include #include #include "newsfetch.h" extern int terminate, wait_after_articles, wait_for_time, articles_fetched; extern int last_than_current, first_article, max_article, news_target; extern int timeout, article_fetching; extern char dirname[100], group[100], pipe_command[100]; extern FILE *rcfp, *rctmpfp, *socket_fp[2]; char *header; #define MAXBUFSIZE 500 #define GROUP_FMT "%99s" char command_buf[MAXBUFSIZE+1]; readNNTPdata() { alarm(timeout); fgets(command_buf,MAXBUFSIZE,socket_fp[1]); alarm(0); } setReaderMode() { /* dummy read to flush input */ readNNTPdata(); fprintf(socket_fp[0],"MODE READER\r\n"); readNNTPdata(); return(get_error(command_buf)); } get_error(char *buf) { int result; sscanf(buf,"%d",&result); if(result >= 200 && result < 300) return(1); /* Print error message */ fprintf(stderr,"%s",buf); return(0); } get_error1(char *buf) { int result; sscanf(buf,"%d",&result); if(result >= 200 && result < 300) return(1); return(0); } get_error2(char *buf) { int result, space=0x20; char *errMsg; sscanf(buf,"%d",&result); if(result >= 200 && result < 300) return(1); errMsg=strchr(buf, space); /* Print error message with a leading space*/ fprintf(stderr,"%s",errMsg); return(0); } set_article_number(char *buf) { int result; sscanf(buf,"%d %d",&result, &first_article); return(1); } FILE * getNewsFileFd() { char news_filename[200]; FILE *newsfp; if(news_target == 2 || news_target == 3) return(stdout); if(news_target == 4 ) { newsfp = popen(pipe_command, "w"); if(newsfp == NULL) perror(pipe_command); return(newsfp); } strcpy(news_filename,dirname); if(strlen(dirname)) strcat(news_filename,"/"); strcat(news_filename,group); #ifdef DEBUG fprintf(stderr, "maildir %s\n",news_filename); #endif if((newsfp=fopen(news_filename,"a+"))==NULL) fprintf(stderr,"Can not create news file...aborting\n"); return(newsfp); } getNextGroup() { char *tmp; int items_read,comment=1; max_article = -1; while(comment) { tmp=fgets(command_buf, MAXBUFSIZE, rcfp); if(tmp == NULL) return(0); #ifdef DEBUG fprintf(stderr, "get_next_group: %s\n",command_buf); #endif for(items_read =0; command_buf[items_read] == 0x20 ; items_read++) ; if(command_buf[items_read] != '#' && command_buf[items_read] != '\n') comment = 0; else fprintf(rctmpfp,"%s",command_buf); } items_read=sscanf(command_buf,GROUP_FMT "%d %d", group, &first_article, &max_article); group[sizeof(group)-1] = '\0'; if(items_read < 2) return(0); return(items_read); } checkGroup() { int first_art, last_art, total_art, tmp ; fprintf(stderr,"%s: ",group); fprintf(socket_fp[0],"GROUP %s\r\n",group); readNNTPdata(); #ifdef DEBUG fprintf(stderr,"fetch group: %s\n",command_buf); #endif if(!get_error2(command_buf)) { first_article--; return(0); } sscanf(command_buf,"%d %d %d %d",&tmp,&total_art,&first_art,&last_art); if(first_article > last_art) { fprintf(stderr,"No new articles\n"); first_article = last_art; return(0); } if(first_article < first_art) first_article = first_art; if(max_article != -1) { if((last_art - first_article) + 1 > max_article) first_article = last_art - max_article + 1; } fprintf(socket_fp[0],"STAT %d\r\n",first_article); readNNTPdata(); while(!get_error1(command_buf)) { first_article++; /* Some news server appear to give the article number of expired articles, check for the last_art */ if(first_article > last_art) { fprintf(stderr,"No new articles: Should not happen\n"); first_article = last_art; return(0); } fprintf(socket_fp[0],"STAT %d\r\n",first_article); readNNTPdata(); } fprintf(stderr,"articles %d to %d\n",first_article,last_art); return(1); } fetchGroup() { FILE *newsfp; int tmp=1; if((newsfp = getNewsFileFd()) == NULL) { /* This is perfect even if article number became invalid since in next run ++ operation will make it valid article and save STAT time */ first_article--; return(-1); } for(; tmp=fetchArticle(newsfp) && terminate ;); first_article = last_than_current; if(news_target < 3) fclose(newsfp); if(news_target == 4 ) pclose(newsfp); #ifndef NO_STATUS_METER if(isatty(2)) fprintf(stderr," %c",0xd); #endif if(terminate) return(1); return(-1); } fetchArticle(FILE *fp1) { int check_header = 1; /* Limit is article_fetched and wait_for articles are interger In rare case, article fetched can be wrap around */ if( wait_after_articles && articles_fetched == wait_after_articles ) { if(isatty(2)) fprintf(stderr,"Waiting for %d seconds%c",wait_for_time,0xd); articles_fetched = 0; sleep(wait_for_time); if(isatty(2)) fprintf(stderr," %c",0xd); } fprintf(socket_fp[0],"ARTICLE\r\n"); readNNTPdata(); if(!get_error(command_buf)) return(0); articles_fetched++; if(news_target == 3 ) { /* forget about old fp1, make it more simple */ fp1 = popen(pipe_command, "w"); if(fp1 == NULL) { perror(pipe_command); return(-1); } } /* Make it little fast */ fprintf(socket_fp[0],"NEXT\r\n"); article_fetching=1; #ifndef NO_STATUS_METER if(isatty(2)) { fprintf(stderr," %c",0xd); fprintf(stderr,"%d%c",first_article, 0xd); } #endif readNNTPdata(); /* Put any date, require by many mail reader */ fprintf(fp1,"From localhost Sat Apr 26 18:57:03 WAT 1997\n"); while(command_buf[0] != '.' || command_buf[1] != 13 )/*|| command_buf[1] != 10)*/ { if(command_buf[0] == '.' && command_buf[1] =='.') command_buf[1]=0x20; if(command_buf[strlen(command_buf)-2] == 0xd || command_buf[strlen(command_buf)-2] == 0x0a) command_buf[strlen(command_buf)-2] = '\0'; if(command_buf[strlen(command_buf)-1] == 0xd || command_buf[strlen(command_buf)-1] == 0x0a) command_buf[strlen(command_buf)-1] = '\0'; fprintf(fp1,"%s\n",command_buf); if(check_header && (strncasecmp(command_buf,"Newsgroups:",10)) == 0) { fprintf(fp1,"%s: %s\n",NEWSFETCH_HEADER_INCL, group); check_header = 0; } readNNTPdata(); } fprintf(fp1,"\n"); if(news_target == 3 ) pclose(fp1); last_than_current = first_article; article_fetching=0; if(terminate) { readNNTPdata(); if(!get_error1(command_buf)) return(0); set_article_number(command_buf); } return(1); } getGroupList() { char groupname[100]; fprintf(stderr, "\nList of NewsGroups:\n"); fprintf(socket_fp[0],"LIST\r\n"); readNNTPdata(); if(!get_error2(command_buf)) exit(1); readNNTPdata(); sscanf(command_buf,GROUP_FMT,groupname); groupname[sizeof(groupname)-1] = '\0'; while(command_buf[0] != '.' || command_buf[1] != 13 )/*|| command_buf[1] != 10)*/ { fprintf(stderr,"%s\n",groupname); readNNTPdata(); sscanf(command_buf,GROUP_FMT,groupname); groupname[sizeof(groupname)-1] = '\0'; } exit(1); } sendQuit() { fprintf(socket_fp[0],"QUIT\r\n"); readNNTPdata(); } fill_tmpfile() { char *tmp; while((tmp=fgets(command_buf, MAXBUFSIZE, rcfp)) != NULL) fprintf(rctmpfp,"%s",command_buf); }