/***************************************************************************
* 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