
/*
 *	Program 	postnews
 *	Programmer	N.d'Alterio
 *	Date		06/07/95
 *
 *  Synopsis:	This program spools an news article ready for posting at
 *              some later time. If currently online then sendnews is 
 *              called and the article will be sent off immediately.
 *		The online check is done by trying to open bsdsocket
 *              library.
 *
 *		This is a heavily modified version of postnews by 
 *              James Burton from his postnewsspool package. This fixes
 *              a number of bugs such as the leaving of locks, hanging
 *              for a long time while waiting to see if it is online.
 *		In addition the program has been very much streamlined
 *              there are no longer the command line options -X, -R as
 *              these seemd to have no use. Also gone are the arg### and
 *              ref### files it produced which seemed to be useless.
 *	
 *		For tin users the program has the command line option
 *              -f the add a From: user@somewhere to the header.
 *
 *		This program has the paths for my setup compiled into
 *              it as defaults to use different paths and files there
 *              is an env variable PNS_SPOOLDIR which is the full directory
 *              name for the spool dir with no trailing '/'.
 *
 *              The program expects to have the companion program sendnews
 *              in AmiTCP:bin/sendnews which in turn needs to have the 
 *              NNTP posting program as AmiTCP:bin/NNTPPost. 	
 *
 *  Command Line Arguments:	-a		Does not do online check
 *				-n		Does not send if online
 *				-R		Specifies header filename
 *				-x		File to delete if successful
 *				-f		Adds a From: someone@ line to header
 *                              -h              Prints some help info
 *				filename	The article file to post
 *                                              if omitted will take from STDIN
 *
 *  Inputs:		article			Should contain a full header
 *			or
 *			header			article header
 *			body			article body
 *
 *  Outputs:		spooldir/msg.### 	The spooled message
 *
 *  Variables:		int i			general loop var
 *			int exit_code		return code for prog
 *			BPTR lock		lock on spooldir
 *			char *Buffer 		string to build filenames
 *			FILE *msg_fptr		file to contain spooled  article
 *			FILE *body_fptr		file containing article body
 *			FILE *head_fptr		fiel containing article header
 *			int no_post		flag - don't try to send
 *			int amitcp		flag - dont check for online
 *			char *from		Pointer to from string
 *			char *body_fname	Pointer to body filename 
 *			char *head_fname	Pointer to header filename
 *			int status		delete status flag
 *			int num_del 		Number of files to be deleted
 *			char *Todelete[]	Buffer containing names of files to delete
 *
 *  Functions:		copyfile		copies article to spooldir
 *			NextArg			checks for existance of next argument
 *
 * $VER: postnews.c 2.1 (07.08.95) $		
 * $Log: postnews.c $
 * Revision 4.1  1995/12/19  17:47:57  nagd
 * addded options -R, -x, -a new online check
 *
 *
 * Revision 3.3  1995/09/30  21:25:18  daltern
 * new command line option -n
 *
 * Revision 3.2  1995/09/30  21:17:20  daltern
 * Added new env var PNS_OFFLINE
 * improved error handling
 *
 * Revision 3.1  1995/09/10  16:41:41  daltern
 * Removed need for seq file to comply with v3.1 of sendnews
 * spooled messages now have name of form msg.##########
 * where ###### is the long date returned by time()
 *
 *
 * Revision 1.2  1995/08/27  21:49:10  daltern
 * Added env vars for path options
 * fixed a bug where a file was left open
 *
 * Revision 1.1  1995/08/07  14:17:55  daltern
 * Initial revision
 *
 *
 */


#include <stdio.h>                   
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <dos/dos.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <exec/types.h>

#define SPOOLDIR	"AmiTCP:Usr/Spool/News"
#define MAX_DEL		16

void  copyfile( FILE *, FILE * );
int   NextArg( int, int, char ** );

extern char *version = "$VER: postnews 4.1 (18.12.95) Nick d'Alterio";
extern struct Library *DOSBase;
       struct Library *SocketBase;

int main( int argc,char **argv )

{

  FILE *msg_fptr;
  FILE *head_fptr;
  FILE *body_fptr;
    
  int i;          
  int exit_code = 0;
  int no_post   = FALSE;
  int num_del;
  int status;
  int amitcp;

  char *spooldir;
  char *from;
  char *body_fname;
  char *head_fname;

  char Buffer[200];
  
  char *Todelete[MAX_DEL];   

  BPTR lock;                     

/*
 *   Read spool dir from env variable.
 */

  if ( ( spooldir = getenv( "PNS_SPOOLDIR" ) ) == NULL ) {
	spooldir = SPOOLDIR;
  }   /* end if */

/*
 *   See if user wants to post or not if online.
 */

  if ( getenv( "PNS_OFFLINE" ) ) {
	no_post = TRUE;
  }   /* end if */


/*
 *=================================================================================================*/

/*
 *   Parse command line.
 */
  
  amitcp     = TRUE;
  i          = 1;
  num_del    = 0;
  from       = NULL;
  head_fname = NULL;
  body_fname = NULL;
    
  while ( i < argc ) {    

	if ( argv[i][0] == '-' ) {   

	switch ( argv[i][1] ) {

/*
 *  Not using amitcp so dont do online check
 */
       
		case 'a': 

			amitcp = FALSE;
			i++;
			break;

/*
 *  Add a From: line to article.
 */

                case 'f' : 

			if ( NextArg( i, argc, argv ) ) {
 
				from = argv[i+1];
								
			} else {

				exit(10);

			}  /* end if */
			i = i + 2;
			break;

/*
 *   Dont attempt to post if online.
 */

		case 'n' :

			no_post = TRUE;
			i++;
			break;

/*
 *   Specifies a header for the article.
 */

		case 'R' :

			if ( NextArg( i, argc, argv ) ) {
				head_fname = argv[i+1];						
			} else {
				exit(10);
			}  /* end if */
			i = i + 2;
			break;

/*
 *   Set up a buffer of filenames to delete if 
 *   successful in posting.
 */
							
		case 'x' :

			if ( NextArg( i, argc, argv ) ) {
				if ( num_del < MAX_DEL ) {
					Todelete[num_del] = argv[i+1];
					num_del++;
				} else {
					fprintf( stderr, " Option '-x' used to many times ignoring\n" );
				}   /* end if */
			} else {
				exit(10);
			}   /* end if */
			i = i + 2;
			break;

/*
 *   Print help.
 */
 
		case 'h' :

			fprintf( stderr, " Usage: %s article [options] or %s [options] < article\n", argv[0], argv[0] );
                   	fprintf( stderr, " Where options are :-\n" );
			fprintf( stderr, "\t-a        \tNot using AmiTCP\n" );
			fprintf( stderr, "\t-f address\tAdd a From: address line to article\n" );
			fprintf( stderr, "\t-n        \tDon't try to send article if online\n" );
			fprintf( stderr, "\t-R header \tPut header at top of message\n" );
			fprintf( stderr, "\t-x file   \tFile to delete if posting successful\n" );
			fprintf( stderr, "\t-h        \tFor this help\n\n" );
			exit(0);;
               		break;

		default :
 
			fprintf( stderr, " Unknown option use -h for help\n" );
			exit(5);
			break;

		}   /* end switch */


        } else {   

		body_fname = argv[i];
		i++;

	}   /* end if */

  }   /* end while */                    

/*
 *=================================================================================================*
 */

/*
 *   Open dos library > v37
 */

  if ( OpenLibrary( "dos.library", 37 ) ) {

/*
 *   Lock directory while using.
 */
      
	if ( lock = Lock( spooldir, ACCESS_READ ) ) {
 

/*
 *   Open file to spool articles to.
 */

  		sprintf( Buffer, "%s/msg.%ld", spooldir, time( NULL ) );
  		if ( msg_fptr = fopen( Buffer, "w" ) ) {

/*
 *   Add a from line if requested.
 */

			if ( from != NULL ) fprintf( msg_fptr, "From: %s\n", from );

/*
 *  Open header file and copy to destination if user
 *  has used -R option.
 */

			if ( head_fname != NULL ) {

				if ( head_fptr = fopen( head_fname, "r" ) ) {

					copyfile( head_fptr, msg_fptr );
					fclose( head_fptr );

				} else {

					fprintf( stderr, " Could not open header file - %s\n", head_fname );
					exit_code = 10;
	
				}   /* end if */

			}   /* end if */

			if ( !exit_code ) {

/*
 *   Open article/body file or set to stdin if no name
 *   has been specified.
 */

				if ( body_fname != NULL ) {
		
					if ( ( body_fptr = fopen( body_fname, "r" ) ) == NULL ) {

						fprintf( stderr, " Could not open body/article file - %s\n", body_fname );
						exit_code = 10;

					}   /* end if */

				} else {

					body_fptr = stdin;

				}   /* end if */

/*
 *   All files opened correctly so copy article to destination
 *   file.
 */

				if ( !exit_code ) {

					copyfile( body_fptr, msg_fptr );
					if ( body_fname != NULL ) fclose( body_fptr );


/*
 *   Successful posting so delete the specified
 *   files
 */

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

						status = remove( Todelete[i] );
						if ( status ) fprintf( stderr, " Failed to delete file - %s\n", Todelete[i] );

					}   /* end for */

				}   /* end if */

			}   /* end if */
                  
  			fclose( msg_fptr );
			if ( exit_code ) remove( Buffer );

		} else {

			fprintf( stderr, " Could not open message file - %s\n", Buffer );
			exit_code = 10;

		}   /* end if open msg file */

  		UnLock( lock );

	} else {

		fprintf( stderr, " Could not lock spooldir - %s\n", spooldir );
		exit_code = 20;

	}   /* end if lock */

  } else {

	fprintf( stderr, " Could not open dos.library > v37\n" );
	exit_code = 20;
 
  }   /* end if */         
  
    
/*
 *   Check if online. If yes then call sendnews to send off articles
 *   now.
 */

  if ( !exit_code && amitcp ) {

	if ( ( SocketBase = OpenLibrary( "bsdsocket.library", 0L ) ) || no_post ) {

		fprintf( stderr, " You are not online - message spooled\n" );

  	} else {

		CloseLibrary( SocketBase );
		fprintf( stderr, " Posting spooled news now....\n" );
		system("amitcp:bin/sendnews");
  
  	}   /* end if */

  }   /* end if !exit_code */

  exit(exit_code);

}   /* end program postnews */



/*========================================================================*
                          BEGIN FUNCTION NextArg
 *========================================================================*/

int NextArg( int i, int argc, char *argv[] )

{

  if ( (i+1) < argc ) {

	if ( argv[i+1][0] != '-' ) return TRUE;

  }   /* end if */

  fprintf( stderr, " Error - No parameter specified following %s\n", argv[i] );
  return FALSE;

}   /* end function NextArg */



/*========================================================================*
                          BEGIN FUNCTION copyfile
 *========================================================================*/

void copyfile( FILE *in_fptr, FILE *out_fptr )

{ 
               
  int ch;

  while ( ( ch = fgetc( in_fptr ) ) != EOF ) fputc( ch, out_fptr );

}   /* end function copyfile */

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