/*
 * batcher - send a bunch of news articles as an unbatch script
 *
 * Usage: batcher [-d dir] listfile
 *
 *	where listfile is a file containing a list, one per line, of
 *	full pathnames of files containing articles.  Only the first
 *	field of each line is looked at, so there can be more if needed
 *	for other things.
 *
 *	The -d option specifies a directory where most articles are
 *	likely to be; the program chdirs there to speed things up.
 */

#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "fgetmfs.h"

#ifndef READSIZE
#define READSIZE 8192	/* allows for even 4.2 worst case file systems */
#endif
char buffer[READSIZE];

char *progname;

char *dir = NULL;		/* NULL means don't bother chdiring. */
int dirlen;			/* strlen(dir) */
int debug = 0;			/* Debugging? */

main(argc, argv)
int argc;
char *argv[];
{
	int c;
	int errflg = 0;
	extern int optind;
	extern char *optarg;
	register FILE *list;
	char *article;
	int ret;

	progname = argv[0];
	while ((c = getopt(argc, argv, "d:x")) != EOF)
		switch (c) {
		case 'd':	/* Directory containing many articles. */
			dir = optarg;
			dirlen = strlen(dir);
			break;
		case 'x':	/* Debugging. */
			debug++;
			break;
		case '?':
		default:
			errflg++;
			break;
		}
	if (errflg || optind != argc-1) {
		(void) fprintf(stderr,
			"Usage: batcher [-d dir] listfile\n");
		exit(2);
	}

	list = fopen(argv[optind], "r");
	if (list == NULL)
		error("unable to open `%s'", argv[optind]);

	if (dir != NULL)
		if (chdir(dir) < 0)
			error("can't chdir to `%s'", dir);

	while ((article = fgetms(list)) != NULL) {
		process(article);
		free(article);
	}
	if (!feof(list))
		error("fgetmfs failure", "");

	exit(0);
}

/*
 - process - process an article
 */
process(article)
char *article;
{
	char *p;
	register int artfile;
	register int count;
	struct stat sbuf;

	*(article + strcspn(article, "\n\t ")) = '\0';
	if (dir != NULL && strncmp(article, dir, dirlen) == 0 &&
			article[dirlen] == '/')
		p = article+dirlen+1;
	else
		p = article;

	artfile = open(p, 0);
	if (artfile < 0) {
		/*
		 * Can't read the article.  This isn't necessarily a
		 * disaster, since things like cancellations will do
		 * this.  Mumble and carry on.
		 */
		if (debug)
			warning("can't find `%s'", p);
		return;
	}

	if (fstat(artfile, &sbuf) < 0)
		error("internal disaster, can't fstat", "");
	if ((sbuf.st_mode&S_IFMT) != S_IFREG) {
		close(artfile);
		return;		/* Don't try to batch directories etc. */
	}

	(void) printf("#! rnews %ld\n", sbuf.st_size);
	fflush(stdout);

	while ((count = read(artfile, buffer, sizeof buffer)) > 0)
		if (write(1, buffer, count) != count)
			error("write failure in `%s'", article);
	if (count < 0)
		error("read failure in `%s'", article);

	(void) close(artfile);
}
