[alt.sources] feed.c - File splitter/submitter

mann@intacc.uucp (Jeff Mann) (04/06/91)

feed - a general-purpose file splitter/submitter, useful for news articles

I needed to post a large number of small news articles to a local
newsgroup announcing events, etc.  I hacked up this little program to
allow me to type them all into one file with Newsgroups and Subject
headers, and have the file split up and sent to inews.  As an
afterthought, I added the ability to specify a substitute search string
to split the file by, (instead of "Newsgroups: ") - feed will split the
file anywhere the initial part of a line matches the search string.  I
also added the ability to specify a substitute command to run on the
file (instead of inews), so it can be used as a general-purpose file
splitter/submitter.

Instead of running a command on all the subfiles, you can tell feed to
just deposit them somewhere.  The initial part of the input file up to
the first occurrence of the search string will always be discarded.
feed is not intelligent about mistakes in the input file, so don't
misspell Newsgroups!  Also, make sure you don't put "Newsgroups: " at
the beginning of a line in your news article.


usage: feed [-h (help)] [-d output directory] 
            [-c command] [-s search string] [input file(s)]
feed takes input files which have multiple news articles. It splits the
input file into separate news articles, and either places them into a
directory specified with the -d option, or injects them directly into the
news flow via inews. Each article in the input file must have at least the
Newsgroups: and Subject: headers. Other headers will be filled in by inews
when the article is injected.
A command may be substituted for inews with the -c option. The command is
run as 'command file' for each sub-file. To pipe each sub-file through a
command, use redirection, eg. 'feed -c "mail root <" file'.
A search string may be substituted for Newsgroups: with the -s option.
Note that the -c and -d options are mutually exclusive; -d will override.


------------------------cut here-------------------------------
#include <stdio.h>

#define TRUE (1)
#define FALSE (0)

char *artdir = "/usr/tmp/artsXXXXXX";

main(argc,argv)
int argc;
char *argv[];
{
	extern char *optarg;
	extern int optind, errno;
	void perror();
	int c;
	int errflg = FALSE;
	int do_inject = TRUE;
	char inject[128];
	static char *command = "inews";
	static char *searchstring = "Newsgroups: ";
	FILE *inputfile;

	mktemp(artdir); /* make a unique name for the temporary directory */
	while((c = getopt(argc, argv, "hc:s:d:")) != -1)
		switch(c) {
		case 'd':
			artdir = optarg;	/* just put articles in specified */
			do_inject = FALSE;	/* directory, don't call inews	*/
			break;
		case 'c':
			command = optarg;
			break;
		case 's':
			searchstring = optarg;
			break;
		case 'h':
printf("usage: feed [-h (help)] [-d output directory] \n");
printf("            [-c command] [-s search string] [input file(s)]\n");
printf("feed takes input files which have multiple news articles. It splits the\n");
printf("input file into separate news articles, and either places them into a\n");
printf("directory specified with the -d option, or injects them directly into the\n");
printf("news flow via inews. Each article in the input file must have at least the\n");
printf("Newsgroups: and Subject: headers. Other headers will be filled in by inews\n");
printf("when the article is injected.\n");
printf("A command may be substituted for inews with the -c option. The command is\n");
printf("run as 'command file' for each sub-file. To pipe each sub-file through a\n");
printf("command, use redirection, eg. 'feed -c \"mail root <\" file'.\n");
printf("A search string may be substituted for Newsgroups: with the -s option.\n");
printf("Note that the -c and -d options are mutually exclusive; -d will override.\n");
			exit();
		case '?':
			errflg = TRUE;
		}
	if(errflg) {
		fprintf(stderr, "usage: feed [-h (help)] [-d output directory] \n");
		fprintf(stderr, "                [-c command] [-s search string] [input file(s)]\n");
		exit(2);
	}
	if(do_inject)
		mkdir(artdir,0755);
		
	if(optind == argc)	/* no file args, so use stdin */
		splitup(stdin,searchstring);

	for( ;optind < argc; optind++) {
		if(strcmp(argv[optind],"-") == 0) /* file arg is -, so use stdin */
			splitup(stdin,searchstring);
		else if(( inputfile = fopen(argv[optind],"r") ) == NULL) {
			fprintf(stderr,"feed: could not open file %s.\n",argv[optind]);
			perror();
			exit(-1);
		} else {
			splitup(inputfile,searchstring);
			fclose(inputfile);
		}
	}
	if(do_inject) {
		strcpy(inject,"for f in ");
		strcat(inject,artdir);
		strcat(inject,"/* ; do ");
		strcat(inject,command);
		strcat(inject," $f ; done");
		system(inject);
		strcpy(inject,"/bin/rm -rf "); /* remove temp dir */
		strcat(inject,artdir);
		system(inject);
	}
	exit(0);
}


splitup(input,searchstring)
FILE *input;
char *searchstring;
{
	char *outputname;
	char line[BUFSIZ];
	FILE *output;
	int gotheader = FALSE;

	/* throw away lines up to the first header */
	while(fgets(line,BUFSIZ -1,input) != NULL) { 
		if(strncmp(line,searchstring,strlen(searchstring)) == 0) {
			gotheader = TRUE;
			break;
		}
	}

	while(gotheader) {
		/* open a file and write until next header. */
		outputname = tempnam(artdir,"art"); /* unique file for each art */
		output = fopen(outputname,"w");
		fputs(line,output); /* write initial header line */
		gotheader = FALSE;
		/* transfer text until next header or end-of-file */
		while(gotheader == FALSE && fgets(line,BUFSIZ -1,input) != NULL) {
			if(strncmp(line,searchstring,strlen(searchstring)) != 0)
				fputs(line,output);
			else 
				gotheader = TRUE;
		}
		fclose(output);
		free(outputname);
	}
}
------------------------------cut here-------------------------------


=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|  Jeff Mann  Inter/Access Artists' Computer Centre, Toronto  [416] 535-8601 |
|  intacc!mann@cs.toronto.edu   Matrix Artists' BBS: [416] 535-7598 2400 8N1 |
| ...uunet!mnetor!intacc!mann  mann@intacc.uucp   [416] 535-1443 Telebit 8N1 |
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-