
/*
 *	Program 	sendnews
 *	Programmer	N.d'Alterio
 *	Date		06/08/95
 *
 *  Synopsis:	This program sends news which has been spooled by
 *		postnews using NNTPpost from INETUtils. If not 
 *              online then the program will exit and do nothing.
 *              'Onlineness' is checked by trying to open the
 *              TCP daytime port.
 *
 *              This program was adapted from the postnewsspool
 *              package by James Burton which although useful
 *		was bugged. It could often hang, it gave little
 *              info as what it was doing, it left locks on the
 *              spool dir and was over complicated.
 * 
 *              It is specifically compiled for my INET set up
 *              i.e. spool dir AmiTCP:Usr/Spool/News
 *                   seq file  AmiTCP:Usr/Spool/News/Seq
 *                   NNTPPost  AmiTCP:bin/NNTPPost
 *
 *		These may be changed using the ENV variables
 *              PNS_SPOOLDIR and PNS_SEQFILE
 *
 *		These can be easily changed by anyone with 
 *		a C compiler.
 *
 *		If NNTPpost fails the article is appended to
 *              the file AmiTCP:Usr/Spool/sendnews.failed or
 *              the ENV variable PNS_FAILED_ARC
 *
 *  Command Line Arguments: None
 *
 *  Inputs:	Needs enviroment variables NNTPSERVER
 *                                         PNS_SPOOLDIR   (opt)
 *                                         PNS_SEQ        (opt)
 *                                         PNS_FAILED_ARC (opt)
 *              
 *
 *  Outputs:	None
 *
 *  Variables:	BPTR	lock 		-	lock on spool dir
 *		char    *Buffer		-	string to build command in
 *		int	seq		- 	number of spooled articles
 *		int	i		-	general loop var
 *
 *  Functions:	getseq			-	reads the Seq file to get seq #
 *		setseq			-	sets seq to 0 after posting
 *		cleanup			-	removeds posted messages
 * 		save_failed		-	saves failed messages to failed archive
 *
 * $VER: sendnews.c 2.1 (07.08.95) $		
 * $Log: sendnews.c $
 * Revision 2.2  1995/08/27  21:32:56  daltern
 * fixed a couple of typos
 *
 * Revision 2.1  1995/08/27  21:29:18  daltern
 * Added some ENV var checking for paths and files
 * Fixed a bug that left a file open
 *
 * Revision 1.3  1995/08/07  13:07:23  daltern
 * added saving of failed messages
 *
 * Revision 1.2  1995/08/07  12:48:19  daltern
 * Added version string
 *
 * Revision 1.1  1995/08/07  12:45:05  daltern
 * Initial revision
 *
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <clib/dos_protos.h>

#define SPOOLDIR    "AmiTCP:Usr/Spool/News"
#define SEQFILE     "AmiTCP:Usr/Spool/News/Seq"
#define FAILED_ARC  "AmiTCP:Usr/Spool/sendnews.failed"
#define NNTPSERVER  NNTPServer

int  getseq( char * );
void setseq( int, char * );
void cleanup( int, char * );
void save_failed( int, char *, char * );

extern char *version = "$VER: sendnews 2.2 (07.08.95) Nick d'Alterio";

int main( void )

{

  int seq;
  int i;

  char *spooldir;
  char *seqfile;
  char *failed_arc;

  char Buffer[256];

  unsigned long  lock;

  FILE *fptr;

/*
 *   Check if online.
 */

  if ( ( fptr = fopen( "TCP:localhost/daytime", "r" ) )  == NULL ) {

	fprintf( stderr, " You cant send news if you are not online !\n" );
	exit(0);

  }   /* end if */

  fclose( fptr );

/*
 *   Read env variable to get NNTP server.
 */
        
  if ( getenv("NNTPSERVER") == NULL ) {

	fprintf( stderr, " You must specify a NNTP news server\n" );
	exit(10);

  }   /* end if */

/*
 *   Read spool dir env variable.
 */

  if ( ( spooldir = getenv( "PNS_SPOOLDIR" ) ) == NULL ) {

	spooldir = SPOOLDIR;

  }   /* end if */

/*
 *   Read seqfile name from env variable.
 */

  if ( ( seqfile = getenv( "PNS_SEQ" ) ) == NULL ) {

	seqfile = SEQFILE;

  }   /* end if */

/*
 *    Read failed archive name from env variable.
 */

  if ( ( failed_arc = getenv( "PNS_FAILED_ARC" ) ) == NULL ) {

	failed_arc = FAILED_ARC;

  }   /* end if */

/*
 *   Lock the spool directory whilst posting.
 */

  lock = Lock( spooldir, ACCESS_WRITE );
  if ( lock == NULL ) {
            
	fprintf( stderr, " Could not lock spool directory\n" );
	exit(20);

  }   /* end if */

/*
 *   Find out how many messages to be posted.
 */

  seq = getseq( seqfile );
  
  if ( seq <= 0 ) {

	UnLock( lock );
	fprintf( stderr, " No articles to send\n" );
	exit(0);

  }   /* end if */
	  
/*
 *   Loop for each article.
 */

  for ( i = 0; i < seq; i++ ) {

/*
 *   Build up command string to execute.
 */

	sprintf( Buffer, "AmiTCP:bin/NNTPPost >NIL: %s/msg%03d", spooldir, i );

/*
 *   Execute system command.
 */

	if ( system( Buffer ) == 0 ) {

        	fprintf( stderr, " Posted article %d\n", i );

	} else { 

		fprintf( stderr, " Failed to post article %d - saving\n", i );
		save_failed( i, failed_arc, spooldir );

	}   /* end if */

/*
 *   Delete old message.
 */

	cleanup( i, spooldir );
                      
  }   /* end for i */                  

/*
 *   Reset seq to 0 after spool dir cleared.
 */
    
  setseq( 0, seqfile );
    
  UnLock( lock );
                
  return(0);

}   /* end program sendnews */

/*========================================================================*
                                  END
 *========================================================================*/


/*========================================================================*
                          BEGIN FUNCTION getseq
 *========================================================================*/

int getseq( char *seqfilename )

{

  FILE *seqfile;       
  int   seq;
                     
  seqfile = fopen( seqfilename, "r" );
  if ( seqfile == NULL ) {   
            
	seq = 0;
     
  } else {

	fscanf( seqfile, "%d", &seq);
	fclose( seqfile );
        
  }   /* end if */                   

  return seq;

}   /* end function getseq */
                 
/*========================================================================*
                               END getseq
 *========================================================================*/


/*========================================================================*
                          BEGIN FUNCTION cleanup
 *========================================================================*/

void cleanup( int article, char *spooldir ) 

{

  char Buffer[100];
   
  sprintf( Buffer, "%s/msg%03d", spooldir, article );
  remove( Buffer );

}   /* end function cleanup */

/*========================================================================*
                               END cleanup
 *========================================================================*/


/*========================================================================*
                          BEGIN FUNCTION setseq
 *========================================================================*/

void setseq( int seq, char *seqfilename )

{

  FILE *seqfile;
    
  seqfile = fopen( seqfilename, "w" );
  if ( seqfile != NULL ) {
                   
	fprintf( seqfile, "%d", seq);
	fclose( seqfile );

  }   /* end if */

}   /* end function setseq */

/*========================================================================*
                                 END setseq
 *========================================================================*/


/*========================================================================*
                          BEGIN FUNCTION save_failed
 *========================================================================*/

void save_failed( int article, char *arc_file, char *spooldir )

{

  FILE *arc_fp;
  FILE *msg_fp;

  char Buffer[100];

  int ch;

  sprintf( Buffer, "%s/msg%03d", spooldir, article );

  arc_fp = fopen( arc_file, "a" );
  if ( arc_fp == NULL ) {

	fprintf( stderr, " Could not open failed archive\n" );
	return;

  }   /* end if */

  msg_fp = fopen( Buffer, "r" );
  if ( msg_fp == NULL ) {

	fprintf( stderr, " Could not open message file to backup\n" );
	fclose( arc_fp );
	return;

  }   /* end if */

  while ( ( ch = fgetc( msg_fp ) ) != EOF ) fputc( ch, arc_fp );

  fclose( arc_fp );
  fclose( msg_fp );
  return;

}   /* end function save_failed */

/*========================================================================*
                                 END save_failed
 *========================================================================*/
