[net.sources] new batch program

gj@cbscc.UUCP (08/25/83)

		The New Batch Program

		Owner: Gary Jolly


	It became necessary to write a new batch program  
to be used on netnews in place of the old batch program.The
old batch program was unable to transfer a file, which con-
tain names of news articles, that exceeds one million bytes. 
The new batch program differs in that it will enable the 
transfer of news articles up  until their limit.  The limit
of the articles that can be transferred will be decided by 
how many blocks the user wishes to transfer.  This limit
will be the third argument in the program.  Once the limit
of how many articles that can be transferred is reached,the
remaining articles that were not transferred will be placed 
in a file by the same name.  The old file is then removed.
If the limit is greater than the size of the articles, each
article in the file is printed.  The file is then removed.




		Using the Batch Program



User types: batch list 88

	The first argument, which is batch, is the name of the 
program.

	The second argument is a file, which in this example is
called list.  For this example list will contain the articles below.
			
			/usr/spool/news/control/112
			/usr/spool/news/btl/general/82
			/usr/spool/news/btl/general/186
			/usr/spool/news/btl/movies/403

	The third argument is the number of blocks the user wishes
to transfer.  For this example the number of blocks will be 88.

			1 block = 512 characters




			
		How it works

	  

 	1. If articles 112 and 82 are less than 88 blocks, they 
will be transferred.  The rest of the articles will be placed
in a file by the same name.  The old file will be removed.
   

		list contains: /usr/spool/news/btl/general/186
			       /usr/spool/news/btl/movies/403


	2.  If all of the articles are less than 88 blocks,
each one will be transferred.  The file, which is called list, 
is then removed.

********************* batch.c **********************

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

#define ERROR  -1

char IBUF[513];
char *BUFP;
char *BUFE;
int LEN;
long n;


main( argc, argv )
int argc;
char **argv;
{
	FILE *fp;
	char filename[80];
	int getlin();
	int indev;
	int i,x;

	if( argc != 3)
	{
		printf("Usage: 3 argruments needed\n");
		exit(0);
	}
	if(( n = atoi(argv[2])) >= 0 )
		n *= 512;   
	else
	{
		printf("%s : not acceptable    MUST BE POSITIVE\n",argv[2]);
		exit(0);
	}
	if( (indev = open( argv[ 1 ], 0 )) == ERROR )
	{
		printf("batch: can't open %s\n",argv[ 1 ]);
		exit( 0 );
	}

	while( (getlin( indev )) > 0 )
	{
		x=0;
		for( i = 0 ; i < 80 ; i++ )
		{
			if( BUFP[i] == ' ' )
				continue;
			if( (filename[x++] = BUFP[i] ) == '\0' )
				break;
		}
                if(cat_file(filename) == -1)
		{
			fp = fopen("batchtmp", "w");
			fprintf(fp, "%s\n",&filename[0]);
			while( (getlin( indev )) > 0 ) {
				x=0;
				for( i = 0 ; i < 80 ; i++ )
				{
					if( BUFP[i] == ' ' )
						continue;
					if( (filename[x++] = BUFP[i] ) == '\0' )
						break;
				}
				fprintf(fp, "%s\n",&filename[0]);
			}
			unlink(argv[1]);
			link("batchtmp", argv[1]);
			unlink("batchtmp");
			fclose(fp);
			exit(0);
		}
	}
	unlink(argv[1]);
	exit( 0 );
}



cat_file( filename )		/* cat files */
char filename[];
{
	FILE *fp;
	int filesize();
	static long size = 0;
	int fsize;


	if((fp =fopen(filename,"r"))== NULL)
		printf("batch: cannot open  %s\n",filename);
	else
	{
		fsize = filesize( filename);
		size += fsize;
	}
	if(n > size )
	{
		printf("#! rnews %d\n",fsize);
		filecopy(fp);
		fclose(fp);
		return( 0 );
	}
	else
		return( -1 );
}

filecopy(fp)	/* copy file fp into std.output */
FILE *fp;
{
	int c;

	while((c =getc(fp)) != EOF )
		putc(c, stdout);

}


filesize( name )
char *name;
{

	int fstat();
	int fildes;
	struct stat buf;

	fildes = open( name , 0 );

	fstat( fildes , &buf );

	close(fildes);

	return( (int)buf.st_size );
}

********************** getlin.c **********************
#
/*

	FUNCTION: Get line of input data

	Owner: Jim McGuire

     This subroutine reads data from the file specified by the
file descriptor given as an argument and breaks it into individual
lines terminated by a new line character.

	CALL is made as follows:

	getlin(indev);

	where indev is the input file descriptor of an opened file.
	The number of characters read will be returned as the
	value of the function. Global variables BUFP and LEN will
	contain the address of the input line, and the LENgth
	of the line, respectively.  Global variables BUFE and IBUF
	are used by the routine, and should not be used by the users
	program.

*/

#define IBUFSZ 512

char IBUF[513];	/* internal data buffer		*/
char *BUFP = IBUF;	/* User's data ptr		*/
char *BUFE = IBUF;	/* Pointer to next loc in IBUF	*/
int LEN;		/* Count of characters read	*/

int getlin(indev) int indev;
{
int i,j;

	if (indev == -1)
		{BUFP = IBUF;
		  BUFE = IBUF;
		  LEN = 0;
		  return(-1);
		}
start:
			/* Check if end of file has occurred	*/
	if (BUFE < BUFP) goto reteof;
			/* Test if this is the first entry	*/
	if (BUFE == IBUF)
			/* Buffer is empty--reset buffer pointer*/
			/* and read an entire buffer of data	*/
		{BUFP = IBUF;
		 LEN = read(indev,BUFP,IBUFSZ);

			/* Test for error or end of file	*/
		 if (LEN < 1)
			{	
			reteof: LEN = 0;
				*BUFP = 0;
			/* Set BUFE ptr to indicate EOF 	*/
				BUFE = BUFP - 1;
				return(0);
			}

			/* Mark end of buffer with null byte	*/
		BUFP[LEN] = 0;
		}

			/* Buffer contains data. Search for 	*/
			/* another input line			*/
	  else BUFP = BUFE;

/****************************************************************

	SEARCH FOR END OF LINE --- OR END OF BUFFER

****************************************************************/
	LEN = -1;
			/* end of buffer is mark by null byte	*/
findnl:	while(BUFP[++LEN])
		if (BUFP[LEN] == '\n')
			/* End of line found, return if this	*/
			/* was not a blank line			*/
			{BUFP[LEN] = 0;
			 BUFE = &BUFP[LEN+1];
			 if (LEN) return(LEN);
			/* Blank line--ignore it		*/
			     else goto start;
			}

/***************************************************************

	BUFFER HAS BEEN SEARCHED FOR THE END OF LINE

**************************************************************/
			/* Test if the entire buffer is full	*/
			/* If so, then this input line is	*/
			/* longer than the buffer size IBUFSZ	*/
	if (BUFP == IBUF)
		{LEN = -1;
		 BUFE = IBUF;
		 *IBUF = 0;
			/* Return negative value to indicate error*/
		 return(-1);
		}

			/* Move current line to beginning of buffer*/
			/* and read rest of buffer input	*/
	   else {
		i = -1;
		j = -1;
		if (BUFP >= &IBUF[IBUFSZ]) 
			{BUFE = IBUF;  BUFP = IBUF; goto start;}
		while(IBUF[++i] = BUFP[++j]) ;
		BUFP = IBUF;
		j = IBUFSZ - i;
		LEN = read(indev,&BUFP[i],j);
			/* Test for EOF				*/
		if (LEN < 1)
			{LEN = i;
			 BUFE = IBUF - 1;
			 return(i);
			}

		BUFP[LEN+i] = 0;	/* Mark end */
		LEN = -1;
		goto findnl;
		}
}