#ifndef lint
static char rcsid[] = "$Id: dbase.update.c,v 1.16 1994/07/17 01:44:44 gkim Exp $";
#endif

/*
 * dbase.update.c
 *
 *	build the preen.database file with the list of files that
 *	was generated by config.parse.c
 *
 * Gene Kim
 * Purdue University
 */

#include "../include/config.h"
#include <stdio.h>
#include <fcntl.h>
#ifdef STDLIBH
# include <stdlib.h>
#endif
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef STRINGH
#include <string.h>
#else
#include <strings.h>
#endif
#include <errno.h>
#include "../include/list.h"
#include "../include/tripwire.h"
#include <assert.h>

/*
 * dbase_entry_flag ()
 *
 *	mark all entries with the given entrynumber (flagentry) with (orflag).
 *	if (ignorevec) is non-NULL, then splice it in as the new ignore
 *	vector.
 */

void
dbase_entry_flag (pp_list, flagentry, orflag, ignorevec)
    struct list **pp_list;
    int flagentry;
    int orflag;
    char *ignorevec;
{
    struct list_elem *p_fileentry;
    char trash[1024];
    int entry;
    int err;

    /* use pp_list as key */
    if (list_open(pp_list) < 0) {
	fputs("database_update: list_open() failed!\n", stderr);
	exit(1);
    }

    /* foreach file entry */
    while ((p_fileentry = list_get(pp_list)) != NULL) {
	if ((err = sscanf(p_fileentry->varvalue, "%d %s", &entry, trash)) < 2) {
	    fprintf(stderr, "dbase_entry_flag: sscanf() parse error, returned %d!\n", err);
	    exit(1);
	}

	/* flag if entry number match */
	if (entry == flagentry) {
	    int flags, newflag;
	    char pcname[MAXPATHLEN+1];

	    strcpy(pcname, p_fileentry->varname);

	    /* exception list */
	    flags = list_getflag(pcname, pp_list);
	    list_setflag(pcname, (orflag)|flags, pp_list);
	    newflag = list_getflag(pcname, pp_list);

	    SPDEBUG(3) 
		fprintf(stderr, "dbase_entry_flag: found %s (entry=%d), oldflag=%d, newflag=%d\n", pcname, flagentry, flags, newflag);

	    /* do we replace the ignorevector? */
	    if (ignorevec) {
		int entrynum;
		char oldignore[512], oldrest[2048];
		char newvalue[2048];

		/* parse the old dbase entry */
		if ((err = sscanf(p_fileentry->varvalue, 
			    "%d %s %[^\n]", &entrynum, oldignore, 
			    oldrest)) != 3) {
		    /* was it just added? */
		    if (list_getflag(pcname, pp_list) & 
					FLAG_UPDATE) {
			SPDEBUG(3) printf("\t(it's already a newly file...)\n");
			continue;
		    }
		    fprintf(stderr, "dbase_entry_flag: list parse error (nfields=%d)!\n", err);
		    fprintf(stderr, "%s>> %s\n", pcname,
			    p_fileentry->varvalue);
		    exit(1);
		}

		/* splice the new ignore flag */
		sprintf(newvalue, "%d %s %s\n", entrynum, ignorevec, oldrest);

		/* they should be the same, since ignorevecs are the only
		 * things that changed 
		 */
		assert(strlen(p_fileentry->varvalue) == strlen(newvalue));

		list_set(pcname, newvalue, MAXPATHLEN+1, pp_list);
	    }

	    list_setflag(pcname, (orflag)|flags, pp_list);

	    /* printf("%s: %d\n", pcname, flags); */
	    if (flags & FLAG_NOOPEN) {
	        if (verbosity)
		    fprintf(stderr, "%s is a special file!  Skipping...\n",
		    	pcname);
	        continue;
	    }
	}
    }

    /* close up the list */
    if (list_close(pp_list) < 0) {
	fputs("database_update: list_close() failed!\n", stderr);
	exit(1);
    }
}

