
	/* this program tries to fill in each header in a multi-header
	   request file with information from the previous header.  
	   Headers which are missing keywords will have the keywords,
	   and values, from the previous header inserted into them.  The first
	   header is, of course, not changed.  Usage is:

	                replicate file.rqs
	       or
	                replicate help 

	   A request file with only one header is not changed, either.

	   The program exits with a code of 0 if all is OK, or non-zero
	   if something went wrong.  In the latter case, an error is
	   printed to stderr. */

#include <stdio.h>
#include <ctype.h>
#include "pf.h"

	/* a file with this name will exist while the program is running... */
#define TEMPNAME     "/tmp/replicate.temp"

static int do_repl( /* char *filename, int n */ );
static void parse( /* char *line, *keyword, *value */ );
static void make_copy( /* char *filename */ );


main(argc, argv)
int argc;
char *argv[];
{
	int i, num_hdr;
	char filename[80];

	if (argc != 2) {
		fprintf(stderr, "usage: replicate filename\n");
		exit(1);
	}
		
	if (strcmp(argv[1], "help") == 0) {
		printf("replicate filename  -  copies info into all headers of a request file\n");
		exit(0);
	}
	strcpy(filename, argv[1]);

	if ((num_hdr = pf_headers(filename)) < 1) {
		fprintf(stderr, "file '%s' does not have a valid request-file format\n",
				filename);
		exit(1);
	}

	for (i = 2; i <= num_hdr; i++) {
		do_repl(filename, i);
	}

	exit(0);
}

	/* actually replicate all the information in the n'th-minus-1 header
	   to fill up the n'th header; however, do not overwrite things
	   that are already there, and do not copy comments */

static int
do_repl(filename, n)
char *filename;
int n;
{
	FILE *fp;
	pf_handle pf_cur;
	int i;
	char line[PF_LEN + 1], keyword[PF_LEN + 1], value[PF_LEN + 1];	
	char v[PF_LEN + 1];
	
	/* make a copy of the file for readonly */
	make_copy(filename);

	if ((fp = fopen(TEMPNAME, "r")) == NULL) {
		fprintf(stderr, "error opening temporary file %s\n", TEMPNAME);
		exit(1);
	}
	if ((pf_cur = pf_open(filename, n, PF_EXIST)) == PF_ERROR) {
		fprintf(stderr, "error opening header %d in file %s\n", 
					n, filename);
		exit(1);
	}

	/* skip forward to the beginning of the (n-1)'th header */
	rewind(fp);
	for (i = 1; i < n - 1; ) {
		if (fgets(line, PF_LEN, fp) == NULL) {
			fprintf(stderr, "error skipping to start of %d'th header\n", n - 1);
			exit(1);
		}
		if (strncmp(line, "END", 3) == 0)
			i++;
	}

	/* now read through the (n-1)'th header (up to the first "END" line),
	   and check to see if the n'th header has a line that begins the
	   same way (same keyword).  If not, then insert the line into
	   the n'th header. */

	while (fgets(line, PF_LEN, fp) != NULL) {
		if (strncmp(line, "END", 3) == 0)
			break;
		parse(line, keyword, value);
		if (*keyword != '\0') {
			if (pf_getval(pf_cur, keyword, v) == NULL) {
				if (pf_putval(pf_cur, keyword, value) == NULL) {
					fprintf(stderr, "error putting line for ..%s.. into file\n",
							keyword);
					exit(1);
				}
			}
		}
	}

	/* okay, all done */
	close(fp);
	pf_close(pf_cur);

	/* and don't forget to delete the temporary file ... */
	unlink(TEMPNAME);
	
	return(0);
}
	

	/* parse the given line to find the keyword and value; if the line
	   is blank, or a comment, or has been commented out, set the
	   'keyword' to point to an empty string ('\0');
	   otherwise, put a pointer to the string
	   for the keyword into 'keyword' and its value into 'value'. */

static void
parse(line, keyword, value)
char *line, *keyword, *value;
{
	int i;

	*keyword = '\0';
	*value = '\0';

	if (isspace(line[0]) || (line[0] == '\n')) {
		return;
	}	
	for (i = 0; i < PF_LEN; i++) {
		if ((line[i] == DELIM_CHAR) || (line[i] == '\n') || (line[i] == '\0'))
			break;
	}
	if (line[i] != DELIM_CHAR) {
		return;
	}
	while (line[i - 1] == ' ')
		i--;
	strncpy(keyword, line, i);
	keyword[i] = '\0';
	pf_copyvalue(line, value);
}


	/* make a copy of the given file, using TEMPNAME as the new name */

#define BUFLEN 256

static void
make_copy(filename)
char *filename;
{
	FILE *fp1, *fp2;
	char line[BUFLEN];

	if ((fp1 = fopen(filename, "r")) == NULL) {
		fprintf(stderr, "can't open file '%s' for reading copy\n", filename);
		exit(1);
	}
	if ((fp2 = fopen(TEMPNAME, "w")) == NULL) {
		fprintf(stderr, "can't open file '%s' to create copy\n", TEMPNAME);
		exit(1);
	}
	rewind(fp1);
	while (fgets(line, BUFLEN, fp1) != NULL) {
		fprintf(fp2, "%s", line);
	}
	fclose(fp1);
	fclose(fp2);
}

