/***************************************************************************
* AUTHOR: Yusuf Motiwala (yusuf@scientist.com)
* FILENAME: newsfetch
* DESCRIPTION: Fetch news from news server and store in the mailbox format
* URL : http://ulf.wep.net/newsfetch.html
**************************************************************************/
#include <stdio.h>
#include <string.h>
#include <signal.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 "newsfetch.h"
extern char **environ;
/****************** GLOBAL DECLARATIONS ********************************/
char copy_cmd[200], dirname[100];
int terminate = 1;
int wait_after_articles = 0, articles_fetched=0, last_than_current;
int wait_for_time = 0, timeout=READ_TIMEOUT, article_fetching=0;
int cleanup=1, max_article, news_target=0, first_article, only_list=0;
int port = 119;
char group[100], pipe_command[100];
FILE *rcfp, *rctmpfp, *socket_fp[2];
char lockfile[100];
/****************** GLOBAL DECLARATIONS END *****************************/
main(argc,argv)
int argc;
char *argv[];
{
int socket_id,tmp, one=1;
char rcfile[100], execute_command[100], homedir[100];
char hostname[100];
int command_flag=0, pipe_flag=0, procmailrc=0;
char *version = "Newsfetch V1.21 Yusuf Motiwala (yusuf@scientist.com)";
fprintf(stderr,"%s\n\n",version);
if(argc < 2)
{
opt_help(argv[0]);
exit(1);
}
getcwd(dirname,99);
rcfile[0]='\0';
lockfile[0]='\0';
group[0]='\0';
getHomedir(homedir);
strcpy(hostname,argv[1]);
{
char *p;
int n;
if (NULL != (p = strchr(hostname, ':')) && 0 < (n = atoi(p + 1))) {
port = n;
*p = '\0';
}
}
get_commandline(argc, argv, dirname, rcfile,
&cleanup, &wait_after_articles, &wait_for_time,
&command_flag, execute_command,
&pipe_flag, pipe_command, &only_list,
&procmailrc, &timeout);
if(!only_list)
{
/* We do not need to do all this things for list only*/
signal(SIGUSR1, SIG_IGN);
checkLockFile(homedir);
defaultRcFiles(homedir, rcfile, copy_cmd);
if(procmailrc)
generateProcmailrc(homedir, rcfile, dirname, pipe_command);
}
socket_id=ConnectServer(hostname, port, 0);
/* two file descriptor are for portability among diff systems */
createFd(socket_id, socket_fp);
setvbuf(socket_fp[0], (char *)NULL, _IOLBF, 0);
setvbuf(socket_fp[1], (char *)NULL, _IOLBF, 0);
/* Set signal handler for termination */
if(!only_list)
{
signal(SIGPIPE, pipe_handler);
signal(SIGALRM, pipe_handler);
signal(SIGINT, exit_handler);
signal(SIGHUP, exit_handler);
signal(SIGTERM, exit_handler);
}
setReaderMode();
if(only_list)
getGroupList();
article_fetching = 1;
while( (tmp=getNextGroup()) > 0 )
{
if(!terminate)
{
/* If we have received signal in getNextGroup */
fprintf(rctmpfp,"%s %d %d\n",group, first_article, max_article);
break;
}
/* Increase first_article to point to next new message */
last_than_current = first_article;
first_article++;
article_fetching = 0;
tmp=checkGroup();
if(tmp > 0)
tmp=fetchGroup();
article_fetching = 1;
fprintf(rctmpfp,"%s %d %d\n",group, first_article, max_article);
article_fetching = 0;
if(command_flag)
executeGroupCommand(execute_command, group);
if(tmp < 0)
break;
article_fetching = 1;
}
quitNow(0);
}
executeGroupCommand(char *command, char *group)
{
char command1[100];
pid_t pid;
makeCommand(command, COMMAND_GROUP_REPLACE, group, command1);
pid = fork();
if(pid < 0 )
{
perror("fork Error");
return(-1);
}
if(pid == 0)
{
char *argv[4];
argv[0] = "sh";
argv[1] = "-c";
argv[2] = command1;
argv[3] = 0;
if((execve("/bin/sh", argv, environ))< 0)
perror("Error Executing Command");
exit(0);
}
}
quitNow(int exit_status)
{
fill_tmpfile();
sendQuit();
fclose(socket_fp[0]);
fclose(socket_fp[1]);
fclose(rcfp);
fclose(rctmpfp);
if(cleanup)
system(copy_cmd);
else
fprintf(stderr, "Not cleaning\n");
exitNow(exit_status);
}
void exit_handler(int sig)
{
if(article_fetching)
{
fprintf(stderr, "Terminating signal recieved, informed process\n");
terminate = 0;
}
else
pipe_handler(SIGINT);
signal(sig, SIG_DFL);
}
void pipe_handler(int sig)
{
if(sig == SIGALRM)
fprintf(stderr,"Timeout waiting for data\n");
if(sig == SIGPIPE)
fprintf(stderr, "Broken Connection\n");
if(sig == SIGINT)
fprintf(stderr, "Terminating\n");
if(group[0] != '\0')
{
fprintf(rctmpfp,"%s %d %d\n",group,last_than_current,max_article);
fill_tmpfile();
}
fclose(rcfp);
fclose(rctmpfp);
if(group[0] != '\0' && cleanup )
system(copy_cmd);
else
fprintf(stderr,"Not Updating\n");
fclose(socket_fp[0]);
fclose(socket_fp[1]);
exitNow(1);
}
exitNow(int exit_status)
{
if(lockfile[0] != '\0')
unlink(lockfile);
exit(exit_status);
}
checkLockFile(char *homedir)
{
FILE *lockfp;
int lockpid;
strcpy(lockfile,homedir);
strcat(lockfile,"/");
strcat(lockfile,NEWSFETCHLOCK);
/* preliminary lockfile, but okay for this app */
lockfp = fopen(lockfile, "r");
if(lockfp == NULL)
{
if((lockfp = fopen(lockfile, "w+")) == NULL)
{
fprintf(stderr,"lockfile creation error\n");
exit(1);
}
fprintf(lockfp,"%d\n",(int)getpid());
fclose(lockfp);
}
else
{
fscanf(lockfp,"%d",&lockpid);
fclose(lockfp);
if(kill(lockpid, SIGUSR1) < 0 )
{
fprintf(stderr,"removing old lock file\n");
if((lockfp = fopen(lockfile, "w+")) == NULL)
{
fprintf(stderr,"lockfile creation error\n");
exit(1);
}
fprintf(lockfp,"%d\n",(int)getpid());
fclose(lockfp);
}
else
{
fprintf(stderr,"Other newsfetch is running at %d\n",lockpid);
exit(1);
}
}
}
syntax highlighted by Code2HTML, v. 0.9.1