[alt.sources] cardfile part 2 of 2

djl@dplace.UUCP (Dave Lampe) (04/17/89)

---- Cut Here and unpack ----
#!/bin/sh
# this is part 2 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file printdb.c continued
#
CurArch=2
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
     exit 1; fi
( read Scheck
  if test "$Scheck" != $CurArch
  then echo "Please unpack part $Scheck next!"
       exit 1;
  else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file printdb.c"
sed 's/^X//' << 'SHAR_EOF' >> printdb.c
X	    msg("Unable to read extract file");
X	    return(1);
X	}
X	if (*out_file == '|')
X	    out = popen(out_file+1, "w");
X	else
X	    out = fopen(out_file, "w");
X	if (out == NULL) {
X	    msg("Unable to open output file");
X	    return(1);
X	}
X	putp(tparm(cursor_address, MSGLINE, 9));
X	putp(clr_eol);                /* clear line */
X	fputs("DEL to abort printing", stdout);
X	old_sig = signal(SIGINT, abort);
X	while(!quit && fgets(dbrec, DBSIZE, dbfile) != NULL) {
X	    putrcd(0, dbrec, out, out_format, width, 1);
X	}
X	fclose(dbfile);
X    }
X    fclose(dbfile);
X    if (*out_file == '|')
X	pclose(out);
X    else
X	fclose(out);
X    signal(SIGINT, old_sig);
X    if (quit)
X	return(1);
X    else
X	return(0);
X}
X
X
Xstatic
Xabort()
X{
X
X    fputs("\n\nOUTPUT ABORTED!\n", out);
X    msg("Dump aborted");
X    quit = 1;
X}
SHAR_EOF
echo "File printdb.c is complete"
chmod 0644 printdb.c || echo "restore of printdb.c fails"
echo "x - extracting putrcd.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > putrcd.c &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)putrcd.c	2.1    DeltaDate 2/13/89    ExtrDate 2/13/89";
X#endif
X
X/*      PUTRCD.C        */
X/*      This subroutine is used to format print a record
X *      Input is :
X *          1) An optional pointer to the header to be printed
X *          2) A pointer to the field structures defining the record
X *          3) A pointer to the record
X *          4) The output file
X *          5) The format of the output
X *          6) The width of a line on the output device
X *          7) The line spacing
X *      It returns the number of lines printed.
X *      The format is specified in "printdb.c"
X */
X#include "stdio.h"
X#include "cardfile.h"
X#include <curses.h>
X#include <term.h>
X
Xputrcd(first, rcd, file, fmt, width, space)
Xchar    *first, *rcd;
XFILE    *file;
Xchar    *fmt;
Xint     width, space;
X{
X    char        *fmt_ptr;
X    char        *fld_ptr[MAXFLDS+2];
X    char        fmtspec[25];
X    int         i, field;
X    int         atcol, tocol;
X    int         state;
X    char	*getfield();
X#define COPY    0
X#define ESC     1
X#define FIELD   2
X    
X    if (first != 0) {
X        fprintf(file, "          %s", first);
X        for (i=0; i<space; i++)
X            putc('\n', file);
X    }
X    rcd[strlen(rcd)-1] = '\0';  /* throw away \n */
X    getfield(rcd, ":"); /* throw away flag */
X    i = 1;
X    /* get position of all fields */
X    while ((fld_ptr[i++]=getfield(0, ":")) != NULL) ;
X    /* analyze format string */
X    state = COPY;
X    atcol = 1;
X    fmt_ptr = fmt;
X    while (*fmt != '\0') {
X        switch (state) {
X        case COPY:
X            if (*fmt == '%') {
X                state = ESC;
X            } else {
X                putc(*fmt, file);
X                ++atcol;
X            }
X            ++fmt;
X            break;
X        case ESC:
X            if (*fmt == 'n') {                          /* %n */
X                for (i=0; i<space; i++)
X                    putc('\n', file);
X                atcol = 1;
X                state = COPY;
X            } else if (*fmt == 'f') {                   /* %f */
X                putc('\f', file);
X                atcol = 1;
X                state = COPY;
X            } else if (*fmt == 't') {                   /* %t */
X                if (*(fmt+1) == '(') {          /* %t(NN) */
X                    fmt += 2;   /* point past '(' */
X                    tocol = atoi(fmt);
X                    if (tocol < atcol) {
X                        fmt_error(fmt_ptr, fmt-fmt_ptr);
X                        return(-1);
X                    }
X                    while (atcol++ < tocol) {   /* space to correct column */
X                        putc(' ', file);
X                    }
X                    /* move past column specifier in format */
X                    while (*fmt >'0' && *fmt <= '9') {
X                        ++fmt;
X                    }
X                } else {                        /* %t */
X                    putc('\t', file);
X                    atcol += 8 - (atcol-1)%8;
X                }
X                state = COPY;
X            } else if (*fmt == '%') {                   /* %% */
X                state = COPY;
X                ++atcol;
X                putc('%', file);
X            } else if (*fmt >= '0' && *fmt <= '9') {    /* %NN */
X                state = FIELD;
X                field = atoi(fmt);
X                while (*(fmt+1) >= '0' && *(fmt+1) <= '9')
X                    ++fmt;
X            } else {
X                fmt_error(fmt_ptr, fmt-fmt_ptr);
X                return(-1);
X            }
X            ++fmt;
X            break;
X        case FIELD:
X            strcpy(fmtspec, "%s");
X            if (*fmt == '(') {  /* special format */
X                ++fmt;
X                strncpy(fmtspec, fmt, (i = strchr(fmt, ')') - fmt));
X                fmtspec[i] = '\0';
X                fmt += i + 1;
X                if(putfield(file, fld_ptr[field], fmtspec, &atcol, width) == -1)
X                    return(-1);
X            } else {            /* default string format */
X                if(putfield(file, fld_ptr[field], fmtspec, &atcol, width) == -1)
X                    return(-1);
X                if (*fmt == '.') {
X                    ++fmt;
X                }
X            }
X            state = COPY;
X            break;
X        }
X    }
X    return(0);
X}
X
X    
X/*
X * Print a field in default format
X */
Xputfield(outfile, fld, outfmt, colptr, width)
XFILE    *outfile;
Xchar    *fld;
Xchar    *outfmt;
Xint     *colptr;
Xint     width;
X{
X    int         cleft;          /* number of characters left on line */
X    char        format[64];
X    char        outstr[512];
X    double      atof();
X    long        atol();
X
X    if (fld == NULL)
X        return(0);
X    cleft = width - *colptr;
X    while (strlen(fld) > cleft) {       /*break field if too long for 1 line */
X        if (*(fld+cleft) == ' ' || *(fld+cleft) == ',' || cleft <= 10) {
X            if (cleft <= 10)
X                cleft = width - *colptr;        /* reset to use full line */
X            sprintf(format, "%%.%ds\n", cleft);
X            fprintf(outfile, format, fld);
X            fld += cleft;
X            cleft = width;
X            *colptr = 1;
X            continue;
X        }
X        --cleft;
X    }
X    switch (outfmt[strlen(outfmt)-1]) {
X    case 's':
X        sprintf(outstr, outfmt, fld);
X        break;
X    case 'f':
X    case 'e':
X    case 'E':
X    case 'g':
X    case 'G':
X        sprintf(outstr, outfmt, atof(fld));
X        break;
X    case 'd':
X    case 'u':
X    case 'o':
X    case 'x':
X    case 'X':
X        sprintf(outstr, outfmt, atoi(fld));
X        break;
X    default:
X        printf("unknown format '%s'\n", outfmt);
X        return(-1);
X    }
X    *colptr += strlen(outstr);
X    fprintf(outfile, "%s", outstr);
X    return(0);
X}
X
X
Xfmt_error(fmt, col)
Xchar    *fmt;
Xint     col;
X{
X
X    putp(clear_screen);              /* clear screen */
X    printf("format='%s'\nError near column %d\n", fmt, col);
X}
SHAR_EOF
chmod 0644 putrcd.c || echo "restore of putrcd.c fails"
echo "x - extracting rawio.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > rawio.c &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)rawio.c	2.1    DeltaDate 2/13/89    ExtrDate 2/13/89";
X#endif
X
X/*      RAWIO.C         */
X
X#include "ascii.h"
X
Xstatic int     echo_f =1;
X
Xint
Xrawgetchar()
X{
X    int	        ch;
X    
X    ch = getchar();
X    if (ch == DEL) {
X	msg("Again to quit");
X	if ((ch = getchar()) == DEL)
X	    getout();
X	msg("");
X	resetcursor();
X    }
X    if (echo_f)
X        rawputchar(ch);
X    return (ch);
X}
X
Xrawputchar(ch)
Xchar    ch;
X{
X    putchar(ch);
X}
X
Xecho()
X{
X    echo_f = 1;
X}
X
Xnoecho()
X{
X    echo_f = 0;
X}
SHAR_EOF
chmod 0644 rawio.c || echo "restore of rawio.c fails"
echo "x - extracting rbuildak.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > rbuildak.c &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)rbuildak.c	2.2    DeltaDate 4/16/89    ExtrDate 4/16/89";
X#endif
X
X/*	RBUILDAK.C      */
X/*	This module will rebuild the alternate key files.
X**	It requires only the DEF and DB files. It must be
X**	used after a compress, if the DB file has been edited,
X**	or if the DEF file is changed affecting the key fields.
X*/
X#include "stdio.h"
X#include "cardfile.h"
X
Xrbuildak(dbname, ak_data, fields)
Xchar    *dbname;
Xstruct  AKdata  *ak_data;
Xstruct  Fdata   *fields;
X{
X    FILE	*dbfile, *akfile;
X    char	fname[FNSIZE], rec[DBSIZE];
X    long	offset, ftell();
X    char	*buffer, *malloc();
X    
X    while (ak_data->A_fldnum >= 0) {
X	sprintf(fname, "%s%s", datadir, ak_data->A_akname);
X	if ((akfile=fopen(fname, "w")) == NULL) {;   /* truncate file */
X	    msg("Unable to write the database");
X	    getout();
X	}
X	fclose(akfile);
X	++ak_data;
X    }
X    sprintf(fname, "%s%s.db", datadir, dbname);
X    dbfile = fopen(fname, "r");
X    buffer = malloc(BUFSIZE);
X    if (buffer == NULL) {
X	msg("Unable to allocate buffer space");
X	getout();
X    }
X    *buffer = '\0';
X    while ((offset = ftell(dbfile)) >= 0L &&
X	fgets(rec, DBSIZE, dbfile) != NULL) {
X	if (feof(dbfile))
X	    break;
X	rec[strlen(rec)-1] = '\0';      /* truncate new-line */
X	buildak(dbname, strchr(rec,':')+1, offset, fields, buffer);
X    }
X    fclose(dbfile);
X    writeak(dbname, buffer);
X    free(buffer);
X}
SHAR_EOF
chmod 0644 rbuildak.c || echo "restore of rbuildak.c fails"
echo "x - extracting screen.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > screen.c &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)screen.c	2.2    DeltaDate 4/16/89    ExtrDate 4/16/89";
X#endif
X
X/*	SCREEN.C	*/
X/*	This subroutine is used to format a screen and handle
X**	input to it. It expects as input:
X**		1. A pointer to the title of the screen
X**		2. A pointer to an array of structures describing
X**		   each field.
X**		3. An (optional) pointer to a footer line.
X**		4. An (optional) pointer to an integer to contain
X**		   the field number in which the pointer was left.
X**	It returns the number of fields modified.
X**
X**	The field definition structures contain:
X**		1. A character pointer to the title of the field
X**		2. The maximum length of the field
X**		3. A pointer to the variable to hold the result
X**		4. An (optional) pointer to the default value
X**
X**	It allows the user to enter:
X**		1. CR   End of Input
X**		2. ->   Move right
X**		3. <-   Move left
X**		4. TAB  Move to next field, wrap around to top
X**		5. BACK-TAB Move to previous field, no wrap
X**		6. LINE-ERASE Erase to end of field
X**		7. CHAR-INSERT Insert a blank and move everything right
X**		8. CHAR-DELETE Delete a character and move everything left
X**		9. DOWN-ARROW Same as TAB
X**	       10. UP-ARROW Same as BACK-TAB
X**	       11. F2	Same as CHAR-INSERT
X**	       12. F3	Same as CHAR-DELETE
X**	       13. F4	Same as LINE-ERASE
X**	       14. F5	Go to the first field on the next page of a
X**			multi-page form
X**	       15. F6	Go to the previous page
X*/
X
X#include "cardfile.h"
X#include "stdio.h"
X#include "ascii.h"
X#include <ctype.h>
X#include <curses.h>
X#include <term.h>
X
X
Xextern  struct  Cstring C1[];
Xextern	char	func_label[];
X
Xstatic  int     flen;
Xstatic  char    *cp;
Xstatic  int     changes;
Xstatic  struct	SFdata {
X		int	f_page;
X		int     f_line;
X		char	*f_title;
X		int     f_start;
X		int	f_length;
X		char	*f_result;
X		char	*f_dfault;
X	} scr_fields[MAXFLDS+1];
Xstatic	struct	SFdata	*fp, *first_field;
Xstatic	int	page_num;
X
Xint
Xscreen (first, vardata, last, left)
Xchar    *first, *last;
Xstruct  Sdata   *vardata;
Xint     *left;
X{
X    int		inp;
X    char	t_last[81];
X    register	struct	Cstring *sp;
X    struct	SFdata	*last_field;
X
X#if DEBUG > 0
X    fprintf(stderr,"screen: called first=%s\n",first);
X#endif
X    /*
X     * Build the scr_fields table
X     */
X    scr_fields[0].f_page = 1;
X    scr_fields[0].f_line = 2;
X    for (fp = scr_fields ; vardata->S_title != NULL ; ++vardata , ++fp) {
X	if (vardata->S_length > 1) {
X	    fp->f_start = strlen(vardata->S_title) + 10;
X	    if (vardata->S_length > 99)
X		fp->f_start += 2;
X	    else if (vardata->S_length > 9)
X		fp->f_start += 1;
X	} else {
X	    fp->f_start = strlen(vardata->S_title) + 7;
X	}
X	fp->f_title = vardata->S_title;
X	fp->f_length = vardata->S_length;
X	fp->f_result = vardata->S_result;
X	fp->f_dfault = vardata->S_dfault;
X	/* check if too much for this screen */
X	if ( (fp->f_line + (fp->f_start + fp->f_length + SWIDTH-1)/SWIDTH)
X	   > SLENGTH - 3) {
X	    (fp+1)->f_page = fp->f_page + 1;
X	    (fp+1)->f_line = 2;
X	} else {
X	    (fp+1)->f_page = fp->f_page;
X	    (fp+1)->f_line = fp->f_line + 1
X		+ (fp->f_start + fp->f_length + SWIDTH-1)/SWIDTH;
X	}
X    }
X    fp->f_page = fp->f_line = 0;
X#if DEBUG > 0
X    fprintf(stderr, "%-4s  %-4s  %-10.10s %-5s  %-4s\n",
X	"", "", "", "data", "data");
X    fprintf(stderr, "%-4s  %-4s  %-10.10s %-5s  %-4s\n",
X	"page", "line", "title", "start", "size");
X    for (fp = scr_fields ; fp->f_page != 0 ; ++fp) {
X	fprintf(stderr, "%4d  %4d  %-10.10s %5d %4d\n",
X	    fp->f_page, fp->f_line, fp->f_title, fp->f_start, fp->f_length);
X    }
X#endif
X    /*
X     *	Format the screen
X     */
X    changes = 0;
X    noecho();
X    /* Loop for all pages */
X    for (page_num = 1 , first_field = scr_fields
X	 ; first_field->f_page != 0 ; ) {
X#if DEBUG > 1
X    fprintf(stderr,"screen: outer loop, page_num=%d\n",page_num);
X#endif
X	putp(clear_screen);			/* clear screen */
X	putp(tparm(cursor_address, 0, 9));
X	fputs(first, stdout);			/* display title */
X	/* Loop for each field on 1 page */
X	for (fp = first_field ; fp->f_page == page_num ; ++fp) {
X#if DEBUG > 1
X	    fprintf(stderr,"screen: inner loop, page_num=%d, line=%d\n",
X		page_num, fp->f_line);
X#endif
X	    putp(tparm(cursor_address, fp->f_line, 4));
X	    putp(enter_dim_mode);
X	    if (fp->f_length > 1) {
X		putp(tparm(cursor_address, fp->f_line, 5));
X		printf("%s(%d):", fp->f_title, fp->f_length);
X	    } else {
X		putp(tparm(cursor_address, fp->f_line, 5));
X		printf("%s:", fp->f_title);
X	    }
X	    putp(exit_attribute_mode);
X	    if (fp->f_dfault != 0) {
X		strcpy(fp->f_result, fp->f_dfault);
X		putp(tparm(cursor_address, fp->f_line, fp->f_start));
X		fputs(fp->f_dfault, stdout);
X		flen = strlen(fp->f_dfault);
X	    } else {
X		flen = 0;
X		fp->f_result[0] = '\0';
X	    }
X	    putchar('\n');
X	    for (flen=strlen(fp->f_result); flen <= fp->f_length; flen++)
X		fp->f_result[flen] = '\0';
X	}
X	/* check if too much for this screen */
X	if (fp->f_page != 0) {
X	    sprintf(t_last, "%-64s[CONT]", last?last:"");
X	} else {
X	    strcpy(t_last, last?last:"");
X	}
X	/* Write instructions if any */
X	if (*t_last != '\0') {
X	    putp(tparm(cursor_address, MSGLINE, 9));
X	    fputs(t_last, stdout);
X	}
X	putp(tparm(cursor_address, SLENGTH-1, 0));
X	fputs(func_label, stdout);
X	fp = first_field;
X	cp = fp->f_result;
X	resetcursor();
X	flen = fp->f_length;
X	
X	/*
X	 *	Process the user input
X	 */
X	while ((inp = rawgetchar()) != '\n' && inp != '\r') {
X	    sp = C1;
X	    while (sp->C_c) {
X		if (inp == sp->C_c) {
X		    inp = (*sp->C_func)(scr_fields, sp->next_table);
X		    break;
X		}
X		++sp;
X	    }
X	    if (sp->C_c != 0) {		/* control character match found */
X		if (inp == -1)	/* page switch */
X		    break;
X		continue;
X	    }
X	    /* Control characters are illegal */
X	    if (! isascii(inp) || iscntrl(inp)) {
X		rawputchar(BEL);
X		continue;
X	    }
X	    rawputchar(inp);		/* echo character */
X	    *cp++ = inp;
X	    ++changes;
X	    if (--flen <= 0)		/* reached end of field */
X		nextfield(scr_fields, (char*)0);
X	}   /* End of INPut Loop */
X#if DEBUG > 0
X	fprintf(stderr,"screen: end of outer loop, inp=%d\n",inp);
X#endif
X	last_field = fp;
X	if (inp == '\n' || inp == '\r')
X	    break;
X    }
X
X    echo();
X    if (left != NULL)
X	*left = last_field - scr_fields;
X#ifdef DEBUG
X    fprintf(stderr,"screen exit, left=%d, changes=%d\n",
X	    (left ? *left : -1), changes);
X#endif
X    return changes;
X}
X
X/*
X *	These are the action routines to manage the fields on the screen.
X * Each routine is called from the getchar loop above when an action key
X * is read. The routine is passed 2 parameters, the screen data structure
X * and the next action table. The normal routines ignore the second
X * parameter. The switch routine, used for multi character keys, ignores
X * the first parameter and just passes it on when the key has been recognized.
X *
X * Globally they use
X * fp		pointer to the current entry in the fields table (SFtable)
X * cp		character position, i.e., character in which next input
X *		is to be placed
X * flen		length of input field
X * changes	flag if screen has been modified
X * page_num	the page of fields displayed
X * first_field	the first field displayed on the screen
X */
X
X/*ARGSUSED*/
Xnextpage(field_tbl, dummy)
Xstruct	SFdata	field_tbl[];
Xchar	*dummy;
X{
X    page_num++;
X    for (first_field = field_tbl ;
X	 first_field->f_page != page_num && first_field->f_page != 0 ;
X	 ++first_field)
X	;
X    if (first_field->f_page == 0) {	/* wrap around */
X	page_num = 1;
X	first_field = field_tbl;
X    }
X#if DEBUG > 0
X    fprintf(stderr, "nextpage: page=%d, first_field=%d\n",
X	page_num, first_field-field_tbl);
X#endif
X    return(-1);		/* force termination of input loop */
X}
X
X
X/*ARGSUSED*/
Xprevpage(field_tbl, dummy)
Xstruct	SFdata	field_tbl[];
Xchar	*dummy;
X{
X    register struct	SFdata	*t_fp;
X
X    if (--page_num < 1) {	/* wrap around */
X	for (t_fp = field_tbl ; (t_fp+1)->f_page != 0 ; ++t_fp)
X	    ;
X	page_num = t_fp->f_page;
X    }
X    for (first_field = field_tbl ;
X	 first_field->f_page != page_num && first_field->f_page != 0 ;
X	 ++first_field)
X	;
X#if DEBUG > 0
X    fprintf(stderr, "prevpage: page=%d, first_field=%d\n",
X	page_num, first_field-field_tbl);
X#endif
X    return(-1);		/* force termination of input loop */
X}
X
X
X/*ARGSUSED*/
Xnextfield(dummy1, dummy2)
Xstruct	SFdata	dummy1[];
Xchar	*dummy2;
X{
X    register int page;
X
X    page  = fp->f_page;
X    ++fp;
X    if (fp->f_page != page) {		/* wrap-around */
X	fp = first_field;
X    }
X    cp = fp->f_result;
X    flen = fp->f_length;
X    resetcursor();
X    return(0);
X}
X
X
X/*ARGSUSED*/
Xprevfield(dummy1, dummy2)
Xstruct	SFdata	dummy1[];
Xchar	*dummy2;
X{
X    register int page;
X
X    if (cp == fp->f_result) {   /* at beginning of field */
X	if (fp == first_field) {	/* wrap around */
X	    page = fp->f_page;
X	    while ((++fp)->f_page == page)
X		;
X	}
X	--fp;
X    }
X    cp = fp->f_result;
X    flen = fp->f_length;
X    resetcursor();
X    return(0);
X}
X
Xsfunct(field_tbl, next_table)
Xstruct	SFdata	field_tbl[];
Xstruct	Cstring	*next_table;
X{
X    register	int	inp;
X    register	struct	Cstring *sp;
X    
X    inp = rawgetchar();
X    sp = next_table;
X    while (sp->C_c) {
X	if (inp == sp->C_c) {
X	    return((*sp->C_func)(field_tbl, sp->next_table));
X	}
X	++sp;
X    }
X    rawputchar(BEL);
X    return(0);
X}
X
X
Xgoright(field_tbl, dummy)
Xstruct	SFdata	field_tbl[];
Xchar	*dummy;
X{
X    register int	pos;
X
X    if (--flen <= 0)
X	nextfield(field_tbl, dummy);
X    if (*cp == '\0')
X	*cp = ' ';
X    cp++;
X    pos = cp - fp->f_result + fp->f_start;
X    if (pos % SWIDTH == 0) {
X	resetcursor();
X    } else {
X	putp(cursor_right);
X    }
X    return(0);
X}
X
X
Xgoleft(field_tbl, dummy)
Xstruct	SFdata	field_tbl[];
Xchar	*dummy;
X{
X    register int	pos;
X
X    if (++flen > fp->f_length) {
X	prevfield(field_tbl, dummy);
X    } else {
X	--cp;
X	pos = cp - fp->f_result + fp->f_start;
X	if (pos % SWIDTH == SWIDTH - 1) {
X	    resetcursor();
X	} else {
X	    putp(cursor_left);
X	}
X    }
X    return(0);
X}
X
X
X/*ARGSUSED*/
Xferase(dummy1, dummy2)
Xstruct  Sdata   *dummy1;
Xchar	*dummy2;
X{
X    register char	*cpt;
X    register int	flent;
X    
X    cpt = cp;
X    flent = flen;
X    while (flent-- > 0) {
X	*(cpt++) = '\0';
X	rawputchar(' ');
X    }
X    resetcursor();
X    ++changes;
X    return(0);
X}
X
X
X/*ARGSUSED*/
Xdelchar(dummy1, dummy2)
Xstruct  Sdata   *dummy1;
Xchar	*dummy2;
X{
X    strcpy(cp, cp+1);
X    fputs(cp, stdout);
X    rawputchar(' ');
X    resetcursor();
X    ++changes;
X    return(0);
X}
X
X
X/*ARGSUSED*/
Xinschar(dummy1, dummy2)
Xstruct  Sdata   *dummy1;
Xchar	*dummy2;
X{
X    mvright(cp+1, cp);
X    *cp = ' ';
X    fputs(cp, stdout);
X    resetcursor();
X    ++changes;
X    return(0);
X}
X
X
Xmvright(d, s)
Xchar    *d, *s;
X{
X    register int	slen;
X    
X    slen = strlen(s);
X    while (slen-- >= 0)
X	*(d+slen) = *(s+slen);
X    return(0);
X}
X
X
Xresetcursor()
X{
X    register int	flent;
X
X    flent = cp - fp->f_result + fp->f_start;
X    putp(tparm(cursor_address, fp->f_line + flent/SWIDTH, flent%SWIDTH));
X}
SHAR_EOF
chmod 0444 screen.c || echo "restore of screen.c fails"
echo "x - extracting setupkeys.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > setupkeys.c &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)setupkeys.c	2.1    DeltaDate 2/13/89    ExtrDate 2/13/89";
X#endif
X
X/*	SETUPKEYS.C	     */
X/*	This module sets up all	terminal specific key sequences.
X**	It sets	up the tables that translate function keys to actions
X**	and sets up the label for the function keys.
X**
X**  It requires	definitions of
X**	key_right	move cursor right
X**	key_left	move cursor left
X**	key_backspace   "
X**	key_tab		move forward thru fields
X**	key_down	"
X**	key_btab	move backward thru fields
X**	key_up		"
X**	key_eol		clear to end of	field
X**	key_dc		delete character under cursor
X**	key_ic		move characters	from the cursor	on one space right
X**	key_f2		same as key_ic
X**	key_f3		same as key_dc
X**	key_f4		same as key_eol
X**	key_f5		next page
X**	key_f6		previous page
X**/
X
X#include "ascii.h"
X#include "cardfile.h"
X#include <curses.h>
X#include <term.h>
X
X#define	CNULL	((struct Cstring*)0)
X/*
X** Indices into "keys" structure
X**/
X#define	k_BS	0
X#define	k_LEFT	1
X#define	k_RIGHT	2
X#define	k_EOL	3
X#define	k_DC	4
X#define	k_IC	5
X#define	k_TAB	6
X#define	k_UP	7
X#define	k_DOWN	8
X#define	k_F2	9
X#define	k_F3	10
X#define	k_F4	11
X#define	k_F5	12
X#define	k_F6	13
X#define	k_BTAB	14
X
Xint	sfunct(), goright(), goleft(), nextfield(), prevfield(), ferase();
Xint	delchar(), inschar(), nextpage(), prevpage();
Xunsigned sleep();
X
X/* translation of terminfo names to action routines */
Xstruct	keys	{
X    char    *terminfo_name;
X    char    *string;
X    int	(*func)();
X};
Xstatic struct keys keys[20] = {
X    {"key_backspace", 0, goleft},
X    {"key_left",      0, goleft},
X    {"key_right",     0, goright},
X    {"key_eol",	      0, ferase},
X    {"key_dc",	      0, delchar},
X    {"key_ic",	      0, inschar},
X    {"tab",	      0, nextfield},
X    {"key_up",	      0, prevfield},
X    {"key_down",      0, nextfield},
X    {"key_f2",	      0, inschar},
X    {"key_f3",	      0, delchar},
X    {"key_f4",	      0, ferase},
X    {"key_f5",	      0, nextpage},
X    {"key_f6",	      0, prevpage},
X#ifdef key_btab
X    {"key_btab",      0, prevfield},
X#endif
X    { 0, 0, 0}
X};
X
X/* strings received from terminal */
X
X/*	Single character control sequences or the first
X *	character of a multi character sequence */
Xstruct Cstring C1[20];
X
X/*	Legal characters after an escape */
Xstruct Cstring C2[20];
X
X/*	Third character of a multi character escape sequence */
Xstruct	Cstring	C3_1[20];
Xstruct	Cstring	C3_2[20];
Xstruct	Cstring	C3_3[20];
Xstruct	Cstring	C3_4[20];
X
X/*	Fourth character */
Xstruct	Cstring	C4_1[20];
Xstruct	Cstring	C4_2[20];
Xstruct	Cstring	C4_3[20];
Xstruct	Cstring	C4_4[20];
Xstruct	Cstring	C4_5[20];
X
X/*	Fifth character */
Xstruct	Cstring	C5_1[15];
Xstruct	Cstring	C5_2[15];
Xstruct	Cstring	C5_3[15];
Xstruct	Cstring	C5_4[15];
Xstruct	Cstring	C5_5[15];
X
X/*	Sixth character */
Xstruct	Cstring	C6_1[15];
Xstruct	Cstring	C6_2[15];
Xstruct	Cstring	C6_3[15];
Xstruct	Cstring	C6_4[15];
Xstruct	Cstring	C6_5[15];
X
Xstruct	st {
X    char    s_char;
X    struct  Cstring *table;
X};
Xstatic struct st s2_tab[] = {	/* switch table for the second	*/
X	'\0', C3_1,		/* of an escape sequence	*/
X	'\0', C3_2,
X	'\0', C3_3,
X	'\0', C3_4,
X	'\0', 0
X};
X
Xstatic struct st s3_tab[] = {	/* switch table for the third	*/
X	'\0', C4_1,		/* of an escape sequence	*/
X	'\0', C4_2,
X	'\0', C4_3,
X	'\0', C4_4,
X	'\0', C4_5,
X	'\0', 0
X};
X
Xstatic struct st s4_tab[] = {	/* switch table for the fourth	*/
X	'\0', C5_1,		/* of an escape sequence	*/
X	'\0', C5_2,
X	'\0', C5_3,
X	'\0', C5_4,
X	'\0', C5_5,
X	'\0', 0
X};
X
Xstatic struct st s5_tab[] = {	/* switch table for the fifth 	*/
X	'\0', C6_1,		/* of an escape sequence	*/
X	'\0', C6_2,
X	'\0', C6_3,
X	'\0', C6_4,
X	'\0', C6_5,
X	'\0', 0
X};
X
Xchar	func_label[256];
X
Xsetupkeys()
X{
X    register struct keys    *kp;
X    int		lead2 = 0;
X    int		lead3 = 0;
X    int		lead4 = 0;
X    int		lead5 = 0;
X    register int    slen;
X    register char   *on, *off;
X#ifdef DEBUG
X    register char   *cp;
X#endif
X
X    /* this is because I can't make cc accept the initialization */
X    keys[k_BS].string = key_backspace;
X    keys[k_LEFT].string = key_left;
X    keys[k_RIGHT].string = key_right;
X    keys[k_EOL].string = key_eol;
X    keys[k_DC].string = key_dc;
X    keys[k_IC].string = key_ic;
X    keys[k_TAB].string = tab;
X    keys[k_UP].string = key_up;
X    keys[k_DOWN].string = key_down;
X    keys[k_F2].string = key_f2;
X    keys[k_F3].string = key_f3;
X    keys[k_F4].string = key_f4;
X    keys[k_F5].string = key_f5;
X    keys[k_F6].string = key_f6;
X#ifdef key_btab
X    keys[k_BTAB].string = key_btab;
X#endif
X
X/*
X * Set up function key label string
X */
X    on = enter_reverse_mode;
X    off = exit_attribute_mode;
X    if (on == 0 || strlen(on) == 0) {
X	on = enter_standout_mode;
X	off = exit_standout_mode;
X    }
X    sprintf(func_label, "%s%8s%s %s%8s%s %s%8s%s %s%8s%s         ",
X	on, "", off,
X	on, key_f2?"insert ":"", off,
X	on, key_f3?"delete ":"", off,
X	on, key_f4?"clr fld ":"", off);
X    sprintf(func_label+strlen(func_label), "%s%8s%s %s%8s%s %s%8s%s %s%8s%s",
X	on, key_f5?"next pg":"", off,
X	on, key_f6?"prev pg":"", off,
X	on, "", off,
X	on, "", off);
X
X/*
X** Set defaults for some keys
X**/
X    if (keys[k_BS].string == 0 || strlen(keys[k_BS].string) == 0)
X	keys[k_BS].string = "\b";
X    if (keys[k_TAB].string == 0 || strlen(keys[k_TAB].string) == 0)
X	keys[k_TAB].string = "\t";
X
X    for (kp = keys; kp->terminfo_name; ++kp) {
X#ifdef DEBUG
X	fprintf(stderr, "Capname=%s,address=%X,string='",
X		kp->terminfo_name, kp->string);
X	for (cp=kp->string ;  cp != 0 && *cp ; cp++)
X	    fputs(unctrl(*cp), stderr);
X	fprintf(stderr,"'\n");
X#endif
X	if (kp->string == 0 || (slen = strlen(kp->string)) == 0 || slen > 6) {
X#ifdef DEBUG
X	    fprintf(stderr, "Control sequence for \"%s\" doesn't exist %s\n",
X		kp->terminfo_name,
X		"or is too long on this terminal.");
X#endif
X	    continue;
X	}	
X	if (slen == 1) {
X	    insert(C1, *(kp->string), kp->func,	CNULL);
X	} else {
X	    insert(C1, *(kp->string), sfunct, C2);
X	    if (slen ==	2) {
X		insert(C2, *(kp->string+1), kp->func, CNULL);
X	    } else {
X		/* see if this 2 char leadin sequence has already been found */
X		for (lead2 = 0;
X		     s2_tab[lead2].table != 0 && s2_tab[lead2].s_char != '\0';
X		     ++lead2) {
X		    if (s2_tab[lead2].s_char == *(kp->string+1))
X			break;
X		}
X		if (s2_tab[lead2].table == 0) {
X		    puts("Too many command leadin sequences.");
X		    continue;
X		}
X		if (s2_tab[lead2].s_char == '\0') {
X		    s2_tab[lead2].s_char = *(kp->string+1);
X		    insert(C2, *(kp->string+1),	sfunct,
X			s2_tab[lead2].table);
X		}
X		if (slen == 3) {
X		    insert(s2_tab[lead2].table, *(kp->string+2), kp->func, CNULL);
X		} else {
X		    /* see if this 3 char sequence has already been found */
X		    for (lead3 = 0;
X			 s3_tab[lead3].table != 0 && s3_tab[lead3].s_char != '\0';
X			 ++lead3) {
X			if (s3_tab[lead3].s_char == *(kp->string+2))
X			    break;
X		    }
X		    if (s3_tab[lead3].table == 0) {
X			puts("Too many command leadin sequences.");
X			continue;
X		    }
X		    if (s3_tab[lead3].s_char == '\0')	{
X			s3_tab[lead3].s_char = *(kp->string+2);
X			insert(s2_tab[lead2].table, *(kp->string+2), sfunct,
X			    s3_tab[lead3].table);
X		    }
X		    if (slen == 4) {
X		        insert(s3_tab[lead3].table, *(kp->string+3),
X			       kp->func, CNULL);
X		    } else {
X			/* see if this 4 char sequence already found */
X			for (lead4 = 0;
X			     s4_tab[lead4].table != 0
X				 && s4_tab[lead4].s_char != '\0';
X			     ++lead4) {
X			    if (s4_tab[lead4].s_char == *(kp->string+3))
X				break;
X			}
X			if (s4_tab[lead4].table == 0) {
X			    puts("Too many command leadin sequences.");
X			    continue;
X			}
X			if (s4_tab[lead4].s_char == '\0') {
X			    s4_tab[lead4].s_char = *(kp->string+3);
X			    insert(s3_tab[lead3].table, *(kp->string+3), sfunct,
X				   s4_tab[lead4].table);
X			}
X			if (slen == 5) {
X			    insert(s4_tab[lead4].table, *(kp->string+4),
X				   kp->func, CNULL);
X			} else {
X			    /* see if 5 char sequence already found */
X			    for (lead5 = 0;
X				 s5_tab[lead5].table != 0
X				     && s5_tab[lead5].s_char != '\0';
X				 ++lead5) {
X				if (s5_tab[lead5].s_char == *(kp->string+4))
X				    break;
X			    }
X			    if (s5_tab[lead5].table == 0) {
X				puts("Too many command leadin sequences.");
X				continue;
X			    }
X			    if (s5_tab[lead5].s_char == '\0') {
X				s5_tab[lead5].s_char = *(kp->string+4);
X				insert(s4_tab[lead4].table, *(kp->string+4),
X					sfunct, s5_tab[lead5].table);
X			    }
X			    insert(s5_tab[lead5].table, *(kp->string+5),
X				   kp->func, CNULL);
X			}
X		    }
X		}
X	    }
X	}
X#if DEBUG > 0
X	dumptables(0);
X#endif
X    }
X#ifdef DEBUG
X    dumptables(1);
X#endif
X}
X
Xstatic
Xinsert(cstrings, ch, func, next)
Xstruct	Cstring	*cstrings, *next;
Xregister char	ch;
Xint (*func)();
X{
X    register struct Cstring *csp;
X
X    for	(csp = cstrings; csp->C_c; ++csp) {
X	if (csp->C_c ==	ch) {
X	    if (csp->C_func == func) {
X		return(0);
X	    } else {
X		puts("Control string leadin character conflict");
X#ifdef DEBUG
X		dumptables(1);
X#endif
X		getout();
X	    }
X	}
X    }
X    csp->C_c = ch;
X    csp->C_func	= func;
X    csp->next_table = next;
X    return(0);
X}
X
X#ifdef DEBUG
Xstatic
Xdumptables(s_flag)
Xint	s_flag;
X{
X
X    fprintf(stderr, "C1\n");
X    dtable(C1);
X    fprintf(stderr, "C2\n");
X    dtable(C2);
X    fprintf(stderr, "C3_1\n");
X    dtable(C3_1);
X    fprintf(stderr, "C3_2\n");
X    dtable(C3_2);
X    fprintf(stderr, "C3_3\n");
X    dtable(C3_3);
X    fprintf(stderr, "C3_4\n");
X    dtable(C3_4);
X    if (s_flag)
X    	sleep(5);
X    fprintf(stderr, "C4_1\n");
X    dtable(C4_1);
X    fprintf(stderr, "C4_2\n");
X    dtable(C4_2);
X    fprintf(stderr, "C4_3\n");
X    dtable(C4_3);
X    fprintf(stderr, "C4_4\n");
X    dtable(C4_4);
X    fprintf(stderr, "C4_5\n");
X    dtable(C4_5);
X    if (s_flag)
X    	sleep(5);
X    fprintf(stderr, "C5_1\n");
X    dtable(C5_1);
X    fprintf(stderr, "C5_2\n");
X    dtable(C5_2);
X    fprintf(stderr, "C5_3\n");
X    dtable(C5_3);
X    fprintf(stderr, "C6_1\n");
X    dtable(C6_1);
X    fprintf(stderr, "C6_2\n");
X    dtable(C6_2);
X    fprintf(stderr, "C6_3\n");
X    dtable(C6_3);
X    if (s_flag)
X    	sleep(5);
X#if DEBUG > 0
X    fprintf(stderr, "s2_tab\n");
X    dumpstab(s2_tab);
X    fprintf(stderr, "s3_tab\n");
X    dumpstab(s3_tab);
X    fprintf(stderr, "s4_tab\n");
X    dumpstab(s4_tab);
X    fprintf(stderr, "s5_tab\n");
X    dumpstab(s5_tab);
X#endif
X}
X
X
Xstatic
Xdtable(csp)
Xregister struct	Cstring	*csp;
X{
X
X    for	( ; csp->C_c ; ++csp) {
X	fprintf(stderr,	"\t%s",	unctrl(csp->C_c));
X	if (csp->C_func	== sfunct) {
X	    fprintf(stderr, "\tsfunct");
X	} else if (csp->C_func == goright) {
X	    fprintf(stderr, "\tgoright");
X	} else if (csp->C_func == goleft) {
X	    fprintf(stderr, "\tgoleft");
X	} else if (csp->C_func == nextfield) {
X	    fprintf(stderr, "\tnfield");
X	} else if (csp->C_func == prevfield) {
X	    fprintf(stderr, "\tpfield");
X	} else if (csp->C_func == ferase) {
X	    fprintf(stderr, "\tferase");
X	} else if (csp->C_func == delchar) {
X	    fprintf(stderr, "\tdelchar");
X	} else if (csp->C_func == inschar) {
X	    fprintf(stderr, "\tinschar");
X	} else if (csp->C_func == nextpage) {
X	    fprintf(stderr, "\tnextpage");
X	} else if (csp->C_func == prevpage) {
X	    fprintf(stderr, "\tprevpage");
X	}
X	if (csp->next_table == NULL) {
X	    fprintf(stderr, "\tNULL\n");
X	} else if (csp->next_table == C2) {
X	    fprintf(stderr, "\tC2\n");
X	} else if (csp->next_table == C3_1) {
X	    fprintf(stderr, "\tC3_1\n");
X	} else if (csp->next_table == C3_2) {
X	    fprintf(stderr, "\tC3_2\n");
X	} else if (csp->next_table == C3_3) {
X	    fprintf(stderr, "\tC3_3\n");
X	} else if (csp->next_table == C3_4) {
X	    fprintf(stderr, "\tC3_4\n");
X	} else if (csp->next_table == C4_1) {
X	    fprintf(stderr, "\tC4_1\n");
X	} else if (csp->next_table == C4_2) {
X	    fprintf(stderr, "\tC4_2\n");
X	} else if (csp->next_table == C4_3) {
X	    fprintf(stderr, "\tC4_3\n");
X	} else if (csp->next_table == C4_4) {
X	    fprintf(stderr, "\tC4_4\n");
X	} else if (csp->next_table == C4_5) {
X	    fprintf(stderr, "\tC4_5\n");
X	} else if (csp->next_table == C5_1) {
X	    fprintf(stderr, "\tC5_1\n");
X	} else if (csp->next_table == C5_2) {
X	    fprintf(stderr, "\tC5_2\n");
X	} else if (csp->next_table == C5_3) {
X	    fprintf(stderr, "\tC5_3\n");
X	} else if (csp->next_table == C6_1) {
X	    fprintf(stderr, "\tC6_1\n");
X	} else if (csp->next_table == C6_2) {
X	    fprintf(stderr, "\tC6_2\n");
X	} else if (csp->next_table == C6_3) {
X	    fprintf(stderr, "\tC6_3\n");
X	}
X    }
X}
X
X
X#if DEBUG > 0
Xstatic
Xdumpstab(stp)
Xregister struct st *stp;
X{
X    for ( ; stp->s_char ; stp++) {
X	fprintf(stderr, "\t%s\n", unctrl(stp->s_char));
X    }
X}
X#endif
X#endif
SHAR_EOF
chmod 0644 setupkeys.c || echo "restore of setupkeys.c fails"
echo "x - extracting updak.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > updak.c &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)updak.c	2.1    DeltaDate 2/13/89    ExtrDate 2/13/89";
X#endif
X
X/*      UPDAK.C         */
X/*      These subroutines are used to update the alternate key files
X        after the DB file has been changed.
X*/
X
X#include "stdio.h"
X#include "ascii.h"
X#include "cardfile.h"
X
Xchar    *bufend;
X
Xbuildak(dbname, recd, addr, fp, buffer)
Xchar    *dbname, *recd;
Xlong    addr;
Xstruct  Fdata *fp;
Xchar    *buffer;
X{
X    char        *fld, *fld2;
X    char        temp[AKSIZE];
X    char	*getfield();
X
X    if (*buffer == '\0')        /* first time */
X        bufend = buffer;
X    for ( ; fp->F_title[0] != '\0' ; ++fp) {
X        if ((fld = getfield(recd, ":")) == 0)
X	    continue;
X        recd += strlen(fld) + 1;
X        if (fp->F_key != 'N' && *fld != '\0') { /* AK record required */
X            while((fld2 = getfield(fld, fp->F_seps)) != NULL) {
X                fld = 0;
X                sprintf(temp, "%c:%s:%ld\n", fp->F_key, fld2, addr);
X                /* check if buffer full */
X                if (bufend+strlen(temp)+1 >= buffer+BUFSIZE) {
X                    writeak(dbname, buffer);
X                }
X                strcpy(bufend, temp);
X                bufend += strlen(temp);
X            }
X        }
X    }
X}
X
X
Xwriteak(dbname, buffer)		/* sort the lines in buffer then merge */
Xchar    *dbname;		/* them in with the appropriate AK file*/
Xchar    *buffer;
X{
X    char        *line[400];
X    int         nlines, i;
X    char        fnum, akname[FNSIZE];
X    FILE        *akfile;
X    char        *strchr();
X    int		compar();
X    void	qsort();
X
X    nlines = 0;
X    bufend = buffer;            /* reset end of buffer pointer */
X    while(*buffer != '\0') {    /* Build file to be sorted */
X        line[nlines++] = buffer;
X        buffer = strchr(buffer, '\n') + 1;
X        if (buffer == (char*)1)        /* test for missing '\n' */
X            break;
X    }
X    if (nlines == 0)    /* no records to add */
X        return;
X    qsort((char*)line, (unsigned)nlines, sizeof(int), compar);
X    fnum = ' ';
X    for (i=0; i<nlines; ++i) {
X        if (*(line[i]) != fnum) {       /* check for same file */
X            if (fnum != ' ') {  /* not first time */
X                fclose(akfile);
X            }
X            fnum = *line[i];
X            sprintf(akname, "%s%s.ak%c", datadir, dbname, fnum);
X            if((akfile = fopen(akname, "a+")) == NULL) {
X                msg(strcat("Unable to open file ", akname));
X                getout();
X            }
X        }
X        fwrite(line[i]+2, strchr(line[i], '\n')-line[i]-2, 1, akfile);
X        putc('\n', akfile);
X    }
X    fclose(akfile);
X}
X
X
Xcompar(str1, str2)
Xchar	**str1, **str2;
X{
X    return(keycmp(*str1, *str2, AKSIZE));
X}
X
Xkeycmp(s1, s2, len)
Xregister char	*s1, *s2;
Xregister int	len;
X{
X
X    while (tolower(*s1) == tolower(*s2) && len--) {
X	if (*s1 == '\0')
X	    return(0);
X	++s1;
X	++s2;
X    }
X    return(tolower(*s1) - tolower(*s2));
X}
SHAR_EOF
chmod 0644 updak.c || echo "restore of updak.c fails"
echo "x - extracting ascii.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > ascii.h &&
X#ifndef lint
Xstatic char ID_ascii[] = "@(#)ascii.h	2.1   DeltaDate 2/13/89    ExtrDate 2/13/89";
X#endif
X
X/*      ASCII.H         */
X/* This defines ASCII control characters as octal numbers */
X
X#define NUL     '\000'
X#define SOH     '\001'
X#define STX     '\002'
X#define ETX     '\003'
X#define EOT     '\004'
X#define ENQ     '\005'
X#define ACK     '\006'
X#define BEL     '\007'
X#define BS      '\010'
X#define HT      '\011'
X#define LF      '\012'
X#define VT      '\013'
X#define FF      '\014'
X#define CR      '\015'
X#define SO      '\016'
X#define SI      '\017'
X#define DLE     '\020'
X#define DC1     '\021'
X#define DC2     '\022'
X#define DC3     '\023'
X#define DC4     '\024'
X#define NAK     '\025'
X#define SYN     '\026'
X#define ETB     '\027'
X#define CAN     '\030'
X#define EM      '\031'
X#define SUB     '\032'
X#define ESC     '\033'
X#define FS      '\034'
X#define GS      '\035'
X#define RS      '\036'
X#define NL      '\037'
X#define SP      '\040'
X#define DEL     '\177'
SHAR_EOF
chmod 0444 ascii.h || echo "restore of ascii.h fails"
echo "x - extracting cardfile.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > cardfile.h &&
X#ifndef lint
Xstatic char ID_cardfile[] = "@(#)cardfile.h	2.1   DeltaDate 2/13/89    ExtrDate 2/13/89";
X#endif
X
X/*      CARDFILE.h      */
X#include	"string.h"
X
X#define SWIDTH	80	/* width of screen line */
X#define	SLENGTH	24	/* length of screen */
X#define PWIDTH	80	/* width of printer line */
X#define	MSGLINE	(SLENGTH-2) /* screen message line */
X#define DBSIZE	1024	/* max size of record in DB file */
X#define AKSIZE	270	/* max size of record in AK file */
X#define MAXFLDS	11	/* max number of fields in record */
X#define FNSIZE	128	/* max size of a file name */
X#define PLENGTH	66	/* number of lines per page on printer */
X#define MAXAK	10	/* max number of AK files */
X#define FLDLEN	256	/* max length of one field */
X#define TSIZE	20	/* max length of field title */
X#define BUFSIZE	(2*1024) /* size of buffer used to build AK files */
X#define MAXKEYS	500	/* maximium keys on one find screen */
X#define	BSIZE	128
X
Xtypedef long	diskptr;
X
Xstruct Sdata	{	/* structure to describe a screen field */
X    char	*S_title;
X    int		S_length;
X    char	*S_result;
X    char	*S_dfault;
X};
X
Xstruct Fdata	{	/* structure to define a data-base field */
X    char	F_title[TSIZE+1];
X    char	F_required;
X    int		F_length;
X    char	F_key;
X    char	F_seps[6];
X};
X
Xstruct AKdata	{	/* structure to hold Alternate Key file info */
X    int		A_fldnum;
X    char	A_akname[FNSIZE];
X};
X
Xstruct  Cstring {
X    char	C_c;
X    int		(*C_func)();
X    struct Cstring *next_table;
X};
X
X
Xextern char	datadir[];
Xint		getout();
Xvoid		exit(), free();
Xunsigned	sleep();
Xchar		*tparm();
SHAR_EOF
chmod 0444 cardfile.h || echo "restore of cardfile.h fails"
echo "x - extracting library.def (Text)"
sed 's/^X//' << 'SHAR_EOF' > library.def &&
Xlibrary.db:8
XTitle:0:;:Y:65
XType:1::N:35
XAuthor:2:;:Y:37
XKeywords:3:,:N:130
XPublisher:N::N:20
XDate:N::N:10
XCost:N::N:6
XComments:N::N:250
X4
X0:library.ak0
X1:library.ak1
X2:library.ak2
X3:library.ak3
SHAR_EOF
chmod 0644 library.def || echo "restore of library.def fails"
echo "x - extracting library.db (Text)"
sed 's/^X//' << 'SHAR_EOF' > library.db &&
X :Devil to Pay,The:Adv(pb):Adams,Hunter::Pinnacle:1977:1.25:Man From Planet X #3.
X :She-Beast,The:Adv(pb):Adams,Hunter::Pinnacle:1975:1.50:Man from Planet X #1.
X :Tiger by the Tail:Adv(pb):Adams,Hunter::Pinnacle:1975:1.50:Man from Planet X #2.
X :Not a Penny More, Not a Penny Less:Adv(pb):Archer,Jeffrey::Fawcett:1976:2.95:
X :Golden Keel,The:Adv(pb):Bagley,Desmond::Pocket Books:1963:0.50:
X :Mackintosh Man,The;Freedom Trap,The:Adv(pb):Bagley,Desmond::Fawcett:1971:0.95:
X :Running Blind:Adv(pb):Bagley,Desmond::Fawcett:1970:0.95:
X :Snow Tiger,The:Adv(pb):Bagley,Desmond::Fawcett:1975:1.75:
X :Spoilers,The:Adv(pb):Bagley,Desmond::Pyramid:1969:1.25:
X :Tightrope Men,The:Adv(pb):Bagley,Desmond::Fawcett:1973:1.25:
X :Cold Jungle,The:Adv(pb):Black,Gavin:Paul Harris:Popular Library:1969:0.60:
X :Dragon for Christmas,A:Adv(pb):Black,Gavin:Paul Harris:Perennial:1963:1.95:
X :Eyes Around Me,The:Adv(pb):Black,Gavin:Paul Harris:Perennial:1964:1.95:
X :Wind of Death,A:Adv(pb):Black,Gavin:Paul Harris:Popular Library:1967:0.75:
X :Canceled Czech,The:Adv(pb):Block,Lawrence:Tanner:Fawcett:1966:0.50:Tanner #2
X :Here Comes a Hero:Adv(pb):Block,Lawrence:Tanner:Fawcett:1968:0.60:Tanner #6
X :Specialists,The:Adv(pb):Block,Lawrence::Fawcett:1969:0.60:
X :Thief Who Couldn't Sleep,The:Adv(pb):Block,Lawrence:Tanner:Fawcett:1966:0.50:Tanner #1
X :Two for Tanner:Adv(pb):Block,Lawrence:Tanner:Fawcett:1968:0.50:Tanner #4
X :Wear the Butchers' Medal:Adv(pb):Brunner,John::Pocket Books:1965:0.50:A hitchhiker in Germany agrees to carry a watch to a man's brother in England. The car is bombed which starts him on the track of the reason which includes the Neo-Nazis and guns smuggled from East-Germany.
X :Golden Virgin,The:Adv(pb):Dipper,Alan::Pinnacle:1972:1.25:
X :Paradise Formula,The:Adv(pb):Dipper,Alan::Pyramid:1970:0.95:
X :Imperial 109:Adv(pb):Doyle,Richard::Bantam:1977:2.50:
X :Odessa File,The:Adv(pb):Forsyth,Frederick::Bantam:1972:1.75:
X :Zoo Gang,The:Adv(pb):Gallico,Paul::Dell:1962:1.50:Ex French resistance fighters go in for crime on the Riviera.
X :Fate is the Hunter:Adv(pb):Gann,Ernest::Fawcett:1961:0.60:
X :Island in the Sky:Adv(pb):Gann,Ernest::Popular Library:1944:0.75:Army bomber down in Canada and the search for the pilot.
X :Trouble with Lazy Ethel:Adv(pb):Gann,Ernest::Ballantine:1958:0.95:Hurricane on a South Pacific island that is the base for the testing of the H bomb.
X :Temptation to Steal:Adv(pb):Gerson,Noel::Popular Library:1972:0.95:
X :Fathom:Adv(pb):Hammond,Marc::Jove:1979:2.25:
X :In the Hour Before Midnight:Adv(pb):Higgins,Jack::Fawcett:1969:1.25:
X :Iron Tiger,The:Adv(pb):Higgins,Jack::Fawcett:1966:0.95:
X :Savage Day,The:Adv(pb):Higgins,Jack::Fawcett:1972:0.95:
X :Prisoner of Zenda,The:Adv(pb):Hope,Anthony::Lancer:1968:0.60:
X :Angry Mountain,The:Adv(pb):Innes,Hammond::Ballantine:1950:0.50:
X :Atlantic Fury:Adv(pb):Innes,Hammond::Avon:1962:0.75:
X :Blue Ice,The:Adv(pb):Innes,Hammond::Avon:1948:0.60:
X :Campbell's Kingdom:Adv(pb):Innes,Hammond::Avon:1952:0.75:
X :Golden Soak,The:Adv(pb):Innes,Hammond::Avon:1973:1.50:
X :Killer Mine,The:Adv(pb):Innes,Hammond::Avon:1947:0.60:
X :North Star:Adv(pb):Innes,Hammond::Ballantine:1974:1.95:
X :Trojan Horse,The:Adv(pb):Innes,Hammond::Fontana:1940:2.50:
X :Grue of Ice,A:Adv(pb):Jenkins,Geoffrey::Avon:1962:0.60:
X :Terror's Cradle:Adv(pb):Kyle,Duncan::Fontana:1974::
X :But We Didn't Get the Fox:Adv(pb):Llewellyn,Richard::Pyramid:1969:0.95:
X :Blame the Dead:Adv(pb):Lyall,Gavin::Ballentine:1973:1.25:
X :Midnight Plus One:Adv(pb):Lyall,Gavin::Dell:1965:0.75:
X :Most Dangerous Game,The:Adv(pb):Lyall,Gavin::Avon:1963:0.75:
X :Shooting Script:Adv(pb):Lyall,Gavin::Avon:1966:0.60:
X :Wrong Side of the Sky,The:Adv(pb):Lyall,Gavin::Avon:1961:0.75:
X :Bear Island:Adv(pb):MacLean,Alistair::Fawcett:1971:1.25:
X :Black Shrike,The:Adv(pb):MacLean,Alistair::Fawcett:1961:0.95:
X :Fear is the Key:Adv(pb):MacLean,Alistair::Fawcett:1961:0.95:
X :Goodbye California:Adv(pb):MacLean,Alistair::Fawcett:1977:2.50:Terrorists threaten California with a nuclear triggered earthquake.
X :Night Without End:Adv(pb):MacLean,Alistair::Fawcett:1960:0.95:Plane crash in the Arctic
X :River of Death:Adv(pb):MacLean,Alistair::Fawcett:1981:3.50:
X :Satan Bug,The:Adv(pb):MacLean,Alistair::Fawcett:1962:0.95:Toxin is stolen from a germ warfare lab. 
X :Seawitch:Adv(pb):MacLean,Alistair::Fawcett:1977:2.25:
X :Secret Ways,The:Adv(pb):MacLean,Alistair::Fawcett:1959:0.75:
X :South by Java Head:Adv(pb):MacLean,Alistair::Fawcett:1958:0.95:Escape from Singapore after its fall to the Japanese.
X :Way to Dusty Death,The:Adv(pb):MacLean,Alistair::Fawcett:1973:1.50:
X :When Eight Bells Toll:Adv(pb):MacLean,Alistair::Fawcett:1966:0.95:
X :Cairo Intrigue:Adv(pb):Manchester,William::Pocket Books:1958:0.25:
X :Bearknife Gold:Adv(pb):Marks,Alan::Belmont:1980:1.75:
X :Gentleman,The:Adv(pb):Marshall,Edison::Pyramid:1956:0.60:
X :Yankee Pasha:Adv(pb):Marshall,Edison::Avon:1947:0.95:
X :Captain Judas:Adv(pb):Mason,F. van Wyck::Pocket Books:1955:0.25:
X :Captain Nemesis:Adv(pb):Mason,F. van Wyck::Pocket Books:1957:1.75:
X :Rivers of Glory:Adv(pb):Mason,F. van Wyck::Pocket Books:1942:0.75:
X :Nightrunners of Bengal:Adv(pb):Masters,John::Bantam:1951:0.60:
X :Operation World War III:Adv(pb):Milton,Joseph::Lancer:1966:0.50:Bart Gould
X :President's Agent:Adv(pb):Milton,Joseph::Lancer:1963:0.60:Bart Gould
X :Worldbreaker:Adv(pb):Milton,Joseph::Lancer:1964:0.50:Bart Gould
X :Terrible Game,The:Adv(pb):Moore,Dan Tyler::Signet:1957:0.60:
X :Operation Cuttlefish:Adv(pb):Mounce,David::Pyramid:1972:0.95:Paul Fox #2.
X :Shield Project,The:Adv(pb):Mounce,David::Pyramid:1971:0.75:Paul Fox #1.
X :Innocent Bystanders,The:Adv(pb):Munro,James::Bantam:1969:0.75:John Craig
X :Man Who Sold Death,The:Adv(pb):Munro,James::Bantam:1964:0.95:John Craig #1.
X :Money That Money Can't Buy,The:Adv(pb):Munro,James::Bantam:1967:0.75:John Craig
X :Prince Commands,The:Adv(pb):Norton,Andre::Tor:1934:2.95:
X :Pieces of Modesty:Adv(pb):O'Donnell::Pan:1972:1.95:Short stories
X :I, Lucifer:Adv(pb):O'Donnell,Peter::Fawcett:1967:0.75:Modesty Blaise
X :Taste For Death,A:Adv(pb):O'Donnell,Peter::Fawcett:1969:0.75:Modesty Blaise
X :Flameout:Adv(pb):Peel,Colin::Playboy:1976:2.25:
X :Nightdive:Adv(pb):Peel,Colin::Playboy:1977:1.95:
X :Bishop's Pawn:Adv(pb):Perry,Ritchie::Ballantine:1979:2.25:Philis #4.
X :Dead End:Adv(pb):Perry,Ritchie::Ballantine:1977:2.25:Philis #10.
X :Dutch Courage:Adv(pb):Perry,Ritchie::Ballantine:1978:2.25:Philis #7.
X :Fall Guy,The:Adv(pb):Perry,Ritchie::Ballantine:1972:2.25:Philis #1.
X :One Good Death Deserves Another:Adv(pb):Perry,Ritchie::Ballantine:1976:2.25:Philis #8.
X :Ticket to Ride:Adv(pb):Perry,Ritchie::Ballantine:1973:2.25:Philis #3.
X :Your Money and Your Wife:Adv(pb):Perry,Ritchie::Ballantine:1975:2.25:Philis #6.
X :Cry of the Halidon,The:Adv(pb):Ryder,Jonathan::Dell:1974:1.75:
X :African Queen,The:Adv(pb):Forester,C.S.:Africa:Bantam:1935:0.35:
X :Count of Monte Cristo,The:Adv(pb):Dumas,Alexandre::Bantam:1956:0.75:The classic revenge novel.
X :Wyatt's Hurricane:Adv(pb):Bagley,Desmond:Caribbean:Pocket Books:1966:0.75:
X :Mandarin Gold:Adv(pb):Leasor,James::Dell:1973:1.50:
X :Naked Land,The:Adv(pb):Innes,Hammond:Iceland:Ballantine:1954:0.50:
X :Puppet on a Chain:Adv(pb):MacLean,Alistair:Holland:Fawcett:1969:0.95:Drug smuggling in Holland
X :Assignment Find Cherry:Adv(pb):Seward,Jack:Japan:Belmont:1973:0.95:Curt Stone #5
SHAR_EOF
chmod 0644 library.db || echo "restore of library.db fails"
echo "x - extracting library.ak0 (Text)"
sed 's/^X//' << 'SHAR_EOF' > library.ak0 &&
XCanceled Czech,The:1017
XCold Jungle,The:711
XDevil to Pay,The:0
XDragon for Christmas,A:788
XEyes Around Me,The:866
XFate is the Hunter:2035
XFathom:2442
XFreedom Trap,The:390
XGolden Keel,The:324
XGolden Virgin,The:1678
XHere Comes a Hero:1096
XImperial 109:1802
XIn the Hour Before Midnight:2489
XIron Tiger,The:2560
XIsland in the Sky:2096
XMackintosh Man,The:390
XNot a Penny More, Not a Penny Less:244
XOdessa File,The:1858
XParadise Formula,The:1739
XRunning Blind:471
XShe-Beast,The:82
XSnow Tiger,The:530
XSpecialists,The:1174
XSpoilers,The:590
XTemptation to Steal:2372
XThief Who Couldn't Sleep,The:1235
XTiger by the Tail:161
XTightrope Men,The:648
XTrouble with Lazy Ethel:2220
XTwo for Tanner:1324
XWear the Butchers' Medal:1399
XWind of Death,A:940
XZoo Gang,The:1921
XAngry Mountain,The:2740
XAtlantic Fury:2806
XBear Island:3694
XBearknife Gold:4713
XBlack Shrike,The:3753
XBlame the Dead:3394
XBlue Ice,The:2861
XBut We Didn't Get the Fox:3320
XCairo Intrigue:4644
XCampbell's Kingdom:2915
XFear is the Key:3817
XGentleman,The:4769
XGolden Soak,The:2975
XGoodbye California:3880
XGrue of Ice,A:3208
XKiller Mine,The:3032
XMidnight Plus One:3454
XMost Dangerous Game,The:3511
XNight Without End:4013
XNorth Star:3089
XPrisoner of Zenda,The:2676
XRiver of Death:4103
XSatan Bug,The:4165
XSavage Day,The:2618
XSeawitch:4267
XSecret Ways,The:4323
XShooting Script:3574
XSouth by Java Head:4386
XTerror's Cradle:3266
XTrojan Horse,The:3147
XWay to Dusty Death,The:4505
XWhen Eight Bells Toll:4575
XWrong Side of the Sky,The:3629
XAfrican Queen,The:6780
XBishop's Pawn:6193
XCaptain Judas:4885
XCaptain Nemesis:4952
XCount of Monte Cristo,The:6847
XCry of the Halidon,The:6715
XDead End:6264
XDutch Courage:6331
XFall Guy,The:6402
XFlameout:6092
XI, Lucifer:5943
XInnocent Bystanders,The:5582
XMan Who Sold Death,The:5657
XMandarin Gold:7021
XMoney That Money Can't Buy,The:5735
XNaked Land,The:7075
XNightdive:6142
XNightrunners of Bengal:5090
XOne Good Death Deserves Another:6472
XOperation Cuttlefish:5432
XOperation World War III:5155
XPieces of Modesty:5876
XPresident's Agent:5232
XPrince Commands,The:5817
XRivers of Glory:5021
XShield Project,The:5508
XTaste For Death,A:6014
XTerrible Game,The:5369
XTicket to Ride:6561
XWorldbreaker:5303
XWyatt's Hurricane:6944
XYankee Pasha:4829
XYour Money and Your Wife:6633
XAssignment Find Cherry:7241
XPuppet on a Chain:7144
SHAR_EOF
chmod 0644 library.ak0 || echo "restore of library.ak0 fails"
echo "x - extracting library.ak1 (Text)"
sed 's/^X//' << 'SHAR_EOF' > library.ak1 &&
XAdv(pb):0
XAdv(pb):1017
XAdv(pb):1096
XAdv(pb):1174
XAdv(pb):1235
XAdv(pb):1324
XAdv(pb):1399
XAdv(pb):161
XAdv(pb):1678
XAdv(pb):1739
XAdv(pb):1802
XAdv(pb):1858
XAdv(pb):1921
XAdv(pb):2035
XAdv(pb):2096
XAdv(pb):2220
XAdv(pb):2372
XAdv(pb):244
XAdv(pb):2442
XAdv(pb):2489
XAdv(pb):2560
XAdv(pb):324
XAdv(pb):390
XAdv(pb):471
XAdv(pb):530
XAdv(pb):590
XAdv(pb):648
XAdv(pb):711
XAdv(pb):788
XAdv(pb):82
XAdv(pb):866
XAdv(pb):940
XAdv(pb):2618
XAdv(pb):2676
XAdv(pb):2740
XAdv(pb):2806
XAdv(pb):2861
XAdv(pb):2915
XAdv(pb):2975
XAdv(pb):3032
XAdv(pb):3089
XAdv(pb):3147
XAdv(pb):3208
XAdv(pb):3266
XAdv(pb):3320
XAdv(pb):3394
XAdv(pb):3454
XAdv(pb):3511
XAdv(pb):3574
XAdv(pb):3629
XAdv(pb):3694
XAdv(pb):3753
XAdv(pb):3817
XAdv(pb):3880
XAdv(pb):4013
XAdv(pb):4103
XAdv(pb):4165
XAdv(pb):4267
XAdv(pb):4323
XAdv(pb):4386
XAdv(pb):4505
XAdv(pb):4575
XAdv(pb):4644
XAdv(pb):4713
XAdv(pb):4769
XAdv(pb):4829
XAdv(pb):4885
XAdv(pb):4952
XAdv(pb):5021
XAdv(pb):5090
XAdv(pb):5155
XAdv(pb):5232
XAdv(pb):5303
XAdv(pb):5369
XAdv(pb):5432
XAdv(pb):5508
XAdv(pb):5582
XAdv(pb):5657
XAdv(pb):5735
XAdv(pb):5817
XAdv(pb):5876
XAdv(pb):5943
XAdv(pb):6014
XAdv(pb):6092
XAdv(pb):6142
XAdv(pb):6193
XAdv(pb):6264
XAdv(pb):6331
XAdv(pb):6402
XAdv(pb):6472
XAdv(pb):6561
XAdv(pb):6633
XAdv(pb):6715
XAdv(pb):6780
XAdv(pb):6847
XAdv(pb):6944
XAdv(pb):7021
XAdv(pb):7075
XAdv(pb):7144
XAdv(pb):7241
SHAR_EOF
chmod 0644 library.ak1 || echo "restore of library.ak1 fails"
echo "x - extracting library.ak2 (Text)"
sed 's/^X//' << 'SHAR_EOF' > library.ak2 &&
XAdams,Hunter:0
XAdams,Hunter:161
XAdams,Hunter:82
XArcher,Jeffrey:244
XBagley,Desmond:324
XBagley,Desmond:390
XBagley,Desmond:471
XBagley,Desmond:530
XBagley,Desmond:590
XBagley,Desmond:648
XBlack,Gavin:711
XBlack,Gavin:788
XBlack,Gavin:866
XBlack,Gavin:940
XBlock,Lawrence:1017
XBlock,Lawrence:1096
XBlock,Lawrence:1174
XBlock,Lawrence:1235
XBlock,Lawrence:1324
XBrunner,John:1399
XDipper,Alan:1678
XDipper,Alan:1739
XDoyle,Richard:1802
XForsyth,Frederick:1858
XGallico,Paul:1921
XGann,Ernest:2035
XGann,Ernest:2096
XGann,Ernest:2220
XGerson,Noel:2372
XHammond,Marc:2442
XHiggins,Jack:2489
XHiggins,Jack:2560
XHiggins,Jack:2618
XHope,Anthony:2676
XInnes,Hammond:2740
XInnes,Hammond:2806
XInnes,Hammond:2861
XInnes,Hammond:2915
XInnes,Hammond:2975
XInnes,Hammond:3032
XInnes,Hammond:3089
XInnes,Hammond:3147
XJenkins,Geoffrey:3208
XKyle,Duncan:3266
XLlewellyn,Richard:3320
XLyall,Gavin:3394
XLyall,Gavin:3454
XLyall,Gavin:3511
XLyall,Gavin:3574
XLyall,Gavin:3629
XMacLean,Alistair:3694
XMacLean,Alistair:3753
XMacLean,Alistair:3817
XMacLean,Alistair:3880
XMacLean,Alistair:4013
XMacLean,Alistair:4103
XMacLean,Alistair:4165
XMacLean,Alistair:4267
XMacLean,Alistair:4323
XMacLean,Alistair:4386
XMacLean,Alistair:4505
XMacLean,Alistair:4575
XManchester,William:4644
XMarks,Alan:4713
XMarshall,Edison:4769
XBagley,Desmond:6944
XDumas,Alexandre:6847
XForester,C.S.:6780
XLeasor,James:7021
XMarshall,Edison:4829
XMason,F. van Wyck:4885
XMason,F. van Wyck:4952
XMason,F. van Wyck:5021
XMasters,John:5090
XMilton,Joseph:5155
XMilton,Joseph:5232
XMilton,Joseph:5303
XMoore,Dan Tyler:5369
XMounce,David:5432
XMounce,David:5508
XMunro,James:5582
XMunro,James:5657
XMunro,James:5735
XNorton,Andre:5817
XO'Donnell,Peter:5943
XO'Donnell,Peter:6014
XO'Donnell:5876
XPeel,Colin:6092
XPeel,Colin:6142
XPerry,Ritchie:6193
XPerry,Ritchie:6264
XPerry,Ritchie:6331
XPerry,Ritchie:6402
XPerry,Ritchie:6472
XPerry,Ritchie:6561
XPerry,Ritchie:6633
XRyder,Jonathan:6715
XInnes,Hammond:7075
XMacLean,Alistair:7144
XSeward,Jack:7241
SHAR_EOF
chmod 0644 library.ak2 || echo "restore of library.ak2 fails"
echo "x - extracting library.ak3 (Text)"
sed 's/^X//' << 'SHAR_EOF' > library.ak3 &&
XPaul Harris:711
XPaul Harris:788
XPaul Harris:866
XPaul Harris:940
XTanner:1017
XTanner:1096
XTanner:1235
XTanner:1324
XAfrica:6780
XCaribbean:6944
XHolland:7144
XIceland:7075
XJapan:7241
SHAR_EOF
chmod 0644 library.ak3 || echo "restore of library.ak3 fails"
rm -f s2_seq_.tmp
echo "You have unpacked the last part"
exit 0