#include <stdio.h>
#include <pwd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#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);
}
syntax highlighted by Code2HTML, v. 0.9.1