#ifndef lint
static char Sccsid[] = "@(#)printdb.c	3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
#endif

/*      PRINTDB.C       */
/*      This module format prints the data base in the order requested.
**      NOTE: If a record contains multiple values for the key selected,
**      it will be printed multiple times.
**      Alternativly it will format print an extracted file (see extract.c)
**      The formats allowed are:
**		%NN     - contents of field NN (1-maxfield)
**		%NN(form) - contents of field NN in printf '%form' format
**		%n      - new-line
**		%t      - tab
**		%f      - form feed
**		%t(NN)  - tab to column NN
**		%%      - %
**      NOTE: '.' ends a format specification %1.1 prints the contents of
**      field 1 concatenated with a '1'.
**/
#include "stdio.h"
#include "cardfile.h"
#include "ascii.h"
#include <signal.h>

char    out_format[512], ext_file[15];
char    out_file[15], out_width[4];
struct  Sdata   first_screen[] = {
		    {"Format", 127, out_format, 0, -1, -1, -1, -1, -1, ""},
		    {"Extracted File", 14, ext_file, 0, -1, -1, -1, -1, -1, ""},
		    {"Output File", 14, out_file, 0, -1, -1, -1, -1, -1, ""},
		    {"Output Width", 3, out_width, 0, -1, -1, -1, -1, -1, ""},
		    {0, 0, 0, 0, -1, -1, -1, -1, -1, ""}
		};

static	int	quit = 0;
static	SIGRTN	(*old_sig)();
static	FILE	*out;
static	SIGRTN	abort();


printdb(fields, dbname)
struct  Fdata *fields;
char    *dbname;
{
    char	*keys[MAXAK+1];
    char	keyv[MAXAK][TSIZE+1];
    int 	nkeys, i;
    struct      Fdata *fp;
    char	aknum[MAXAK];
    int 	keynum;
    char	title[SWIDTH];
    char	fname[FNSIZE];
    FILE	*akfile, *dbfile;
    char	akrec[AKSIZE+1], dbrec[DBSIZE+1];
    long	offset, atol();
    int 	width;
    char	*last;
    char	h_line[1024];

    sprintf(title, "Print %s data base", dbname);
    while (1) {
	last = "Enter ? for help.";
	    screen(title, first_screen, last, 0, FALSE);
	    if (strcmp(ext_file, "?") == 0) {
		strcpy(h_line, "Enter the name of the extract file generated");
		strcat(h_line, " from\nthe maintenance menu. If you leave it");
		strcat(h_line, " blank, the entire\ndata base will be dumped.");
		help(h_line);
		continue;
	    }
	    if (strcmp(out_width, "?") == 0) {
		help("Enter the width of the output device, defaults to 80.");
		continue;
	    }
	    if (*out_width == '\0') {
		width = PWIDTH;
	    } else {
		width = atoi(out_width);
	    }
	    if (strcmp(out_file, "?") == 0) {
		strcpy(h_line, "Enter the name of the output file,");
		strcat(h_line, " defaults to '|lp', the printer.");
		help(h_line);
		continue;
	    }
	    if (*out_file == '\0') {
		strcpy(out_file, "|lp");
	    }
	    if (strcmp(out_format, "?") == 0) {
		strcpy(h_line, "Enter the output format. All characters will");
		strcat(h_line, " be\nprinted as entered except for % sequences.");
		strcat(h_line, "\n\n\t%NN\t - contents of field NN (1-maxfield)");
		strcat(h_line, "\n\t%NN(form) - contents of field NN in");
		    strcat(h_line, " printf '%form' format\n");
		strcat(h_line, "\t%n\t- new-line\n");
		strcat(h_line, "\t%t\t- tab\n");
		strcat(h_line, "\t%t(NN)\t- tab to column NN\n");
		strcat(h_line, "\t%f\t- form-feed\n");
		strcat(h_line, "\t%%\t- %");
		help(h_line);
		continue;
	    }
	    if (*out_format == '\0') {  /* not specified, use default */
	    fp = fields;
	    i = 1;
	    while (fp->F_title[0]) {
		sprintf(&out_format[strlen(out_format)], "%s: %%%d%%n",
		    fp->F_title, i);
		++i;
		++fp;
	    }
	    strcat(out_format, "%n%n%n");
	}
	break;
    }
    if (ext_file[0] == '\0') {
	msg("No extract specified, entire database will be dumped");
    }
    fp = fields;
    nkeys = 0;
    if (ext_file[0] == '\0') {
	while (fp->F_title[0] != '\0') {
	    if (fp->F_key != 'N') {
		sprintf(keyv[nkeys], "%-20s", fp->F_title);
		keys[nkeys] = keyv[nkeys];
		aknum[nkeys] = fp->F_key;
		++nkeys;
	    }
	    ++fp;
	}
	keys[nkeys] = "Cancel              ";
	aknum[nkeys] = '\0';
	++nkeys;
	keys[nkeys] = 0;
	sprintf(title, "Print %s data base selected by", dbname);
	keynum = menu(title, keys);
	if (aknum[keynum] == '\0') {    /* cancel */
	    return(1);
	}
	if (*out_file == '|')
	    out = popen(out_file+1, "w");
	else
	    out = fopen(out_file, "w");
	if (out == NULL) {
	    msg("Unable to open output file");
	    return(1);
	}

	sprintf(fname, "%s%s.ak%c", datadir, dbname, aknum[keynum]);
	if ((akfile = fopen(fname, "r")) == NULL) {
	    msg("Unable to open alternate key file");
	    getout();
	}
	sprintf(fname, "%s%s.db", datadir, dbname);
	if ((dbfile = fopen(fname, "r")) == NULL) {
	    msg("Unable to open db file");
	    getout();
	}
	msg(NULL);	/* leave the cursor at the bottom */
	fputs("DEL to abort printing", stdout);
	old_sig = signal(SIGINT, abort);

	while(!quit && fgets(akrec, AKSIZE, akfile) != NULL) {
	    offset = atol(strchr(akrec, ':')+1);
	    if (offset < 0L)
		continue;
	    fseek(dbfile, offset, 0);
	    if (fgets(dbrec, DBSIZE, dbfile) == NULL) {
		msg("Bad offset found");
		continue;
	    }
	    if (*dbrec == 'D')  /* check for delete flag */
		continue;
	    if (putrcd(0, dbrec, out, out_format, width, 1) == -1)
		break;
	}
	fclose(akfile);
    } else {
	if ((dbfile = fopen(ext_file, "r")) == NULL) {
	    msg("Unable to read extract file");
	    return(1);
	}
	if (*out_file == '|')
	    out = popen(out_file+1, "w");
	else
	    out = fopen(out_file, "w");
	if (out == NULL) {
	    msg("Unable to open output file");
	    return(1);
	}
	msg(NULL);	/* leave the cursor at the bottom */
	fputs("DEL to abort printing", stdout);
	old_sig = signal(SIGINT, abort);
	while(!quit && fgets(dbrec, DBSIZE, dbfile) != NULL) {
	    if (putrcd(0, dbrec, out, out_format, width, 1) == -1)
		break;
	}
	fclose(dbfile);
    }
    fclose(dbfile);
    if (*out_file == '|')
	pclose(out);
    else
	fclose(out);
    signal(SIGINT, old_sig);
    if (quit)
	return(1);
    else
	return(0);
}


static SIGRTN
abort()
{

    fputs("\n\nOUTPUT ABORTED!\n", out);
    msg("Dump aborted");
    quit = 1;
}
