v15i050: cardfile - part 2 of 3
Dave Lampe
dplace!djl at PacBell.COM
Mon Oct 15 11:33:18 AEST 1990
Posting-number: Volume 15, Issue 50
Submitted-by: Dave Lampe <dplace!djl at PacBell.COM>
Archive-name: cardfile/part02
---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is part 02 of cardfile
# ============= getkey.c ==============
echo 'x - extracting getkey.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'getkey.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)getkey.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
X#endif
X
X/* GETKEY.C */
X/* This subroutine is used to search an alternate key file
X to find records matching the input value. It returns the
X offset of the record in the DB file if found, or -1 if
X no match was found.
X*/
X#include "stdio.h"
X#include "cardfile.h"
X#include "ascii.h"
X
Xdiskptr
Xgetkey(file, val)
XFILE *file;
Xchar *val;
X{
X static char *match;
X char rcd[AKSIZE];
X long atol();
X char *fgets();
X int rc;
X
X if (val != 0) { /* first time */
X match = val;
X fseek(file, 0L, 0);
X }
X while (fgets(rcd, AKSIZE, file) != NULL) {
X if ((rc = keymatch(rcd, match)) == -1) {
X break;
X } else if (rc == 1) {
X return (atol(strchr(rcd, ':')+1));
X }
X }
X return (-1L);
X}
SHAR_EOF
true || echo 'restore of getkey.c failed'
# ============= keymatch.c ==============
echo 'x - extracting keymatch.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'keymatch.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)keymatch.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
X#endif
X
X/* KEYMATCH.C */
X/* This subroutine is used to test if the key in the AK file
X** record matches the input value. Two options are supported,
X** UNIX style regular expressions or simple matches. If 'BSD_RE',
X** 'SYSV_RE', or 'PD_RE' is defined regular expressions are allowed.
X** If the input value is enclosed in quotes an exact match is
X** required, otherwise upper/lower case is ignored. If simple
X** matching is being done, 'NO_RE', an '*' at the end of an unquoted
X** string matches everything.
X**/
X#include "cardfile.h"
X
X#ifdef BSD_RE
Xextern char *re_comp();
Xextern int re_exec();
X#endif
X#ifdef SYSV_RE
Xextern char *regcmp();
Xextern char *regex();
X#endif
X#ifdef PD_RE
X#include <regexp.h>
Xextern regexp *regcomp();
Xextern int regexec();
X#endif
X
Xstatic strlower();
X
Xkeymatch(akrcd, val)
Xchar *akrcd, *val;
X{
X register int vlen;
X char convert[256];
X char key[256];
X static int lower;
X#ifdef SYSV_RE
X static char lastval[256];
X static char *cval;
X#endif
X#ifdef PD_RE
X static char lastval[256];
X static regexp *cval;
X#endif
X#ifdef BSD_RE
X static char lastval[256];
X# endif
X#ifdef NO_RE
X register char *cp = convert,
X *kp = key;
X#endif
X
X#ifdef NO_RE
X vlen = strlen(val);
X strcpy(convert, val);
X if ((*convert == '"' && convert[vlen-1] == '"')
X || (*convert == '\'' && convert[vlen-1] == '\'')) {
X strcpy(convert, convert+1);
X convert[vlen-2] = '\0';
X lower = 0;
X } else {
X strlower(convert);
X lower = 1;
X }
X strcpy(key, akrcd);
X *strchr(key, ':') = '\0';
X if (lower) {
X strlower(key);
X }
X while (*cp != '\0' && (lower == 0 || *cp != '*')) {
X if (*cp != *kp)
X return(0);
X ++cp;
X ++kp;
X }
X if (*cp == '\0' && *kp != '\0')
X return(0);
X return(1);
X#else /* BSD_RE | SYSV_RE | PD_RE */
X if (strcmp(val, lastval) != 0) { /* new pattern */
X vlen = strlen(val);
X# ifndef BSD_RE /* SYSV_RE | PD_RE */
X if (cval) /* free last pattern if any */
X free (cval);
X# endif
X strcpy(lastval, val);
X strcpy(convert, val);
X if ((*convert == '"' && convert[vlen-1] == '"')
X || (*convert == '\'' && convert[vlen-1] == '\'')) {
X strcpy(convert, convert+1);
X convert[vlen-2] = '\0';
X lower = 0;
X } else {
X strlower(convert);
X lower = 1;
X }
X# ifdef BSD_RE
X if (re_comp(convert) != 0) {
X# endif
X# ifdef SYSV_RE
X if ((cval = regcmp(convert, 0)) == 0) {
X# endif
X# ifdef PD_RE
X if ((cval = regcomp(convert)) == 0) {
X# endif
X msg("Invalid search pattern");
X return(-1);
X }
X }
X strcpy(key, akrcd);
X *strchr(key, ':') = '\0';
X if (lower) {
X strlower(key);
X }
X# ifdef BSD_RE
X if (re_exec(key) != 0) {
X# endif
X# ifdef SYSV_RE
X if (regex(cval, key) != 0) {
X# endif
X# ifdef PD_RE
X if (regexec(cval, key) != 0) {
X# endif
X return(1);
X }
X return(0);
X#endif /* RE */
X}
X
X
Xstatic
Xstrlower(str)
Xregister char *str;
X{
X
X while (*str) {
X if (*str >= 'A' && *str <= 'Z')
X *str = *str - 'A' + 'a';
X ++str;
X }
X}
SHAR_EOF
true || echo 'restore of keymatch.c failed'
# ============= maint.c ==============
echo 'x - extracting maint.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'maint.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)maint.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
X#endif
X
X/* MAINT.C */
X/* This module is displays the maintenance menu and
X controls the execution of the associated routines
X*/
X#include "stdio.h"
X#include "cardfile.h"
X
Xchar *mfuncts[] = {"EXIT ",
X "DUMP ",
X "COMPRESS ",
X "REBUILD AK's",
X "EXTRACT ",
X 0
X };
X#define DUMP 1
X#define COMPRES 2
X#define RBUILD 3
X#define EXTRACT 4
X#define EXIT 0
X
X
Xmaint(fields, dbname, ak_data)
Xstruct Fdata *fields;
Xchar *dbname;
Xstruct AKdata *ak_data;
X{
X char first[SWIDTH];
X int func;
X
X sprintf(first, "Maintenance functions for %s", dbname);
X while ((func = menu(first, mfuncts)) != EXIT) {
X switch (func) {
X case DUMP:
X dumpdb(dbname, ak_data, fields);
X continue;
X case COMPRES:
X compress(dbname);
X rbuildak(dbname, ak_data, fields);
X continue;
X case RBUILD:
X rbuildak(dbname, ak_data, fields);
X continue;
X case EXTRACT:
X extract(fields, dbname);
X continue;
X default:
X msg("Illegal function chosen");
X }
X }
X}
SHAR_EOF
true || echo 'restore of maint.c failed'
# ============= menu.c ==============
echo 'x - extracting menu.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'menu.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)menu.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
X#endif
X
X/* MENU.C */
X/* This subroutine is used to display a menu of commands
X** and wait for the user to select one.
X** It returns the number of the command selected.
X**/
X#include "cardfile.h"
X
Xmenu(dbname, functs)
Xchar *dbname;
Xchar **functs;
X{
X int func;
X char dummy[2];
X struct Sdata *sp, *mscreen;
X char *malloc();
X
X mscreen = (struct Sdata*)malloc((MAXFLDS+1) * sizeof(struct Sdata));
X sp = mscreen;
X do {
X sp->S_title = *functs;
X sp->S_length = 1;
X sp->S_result = dummy;
X sp->S_dfault = 0;
X sp->S_page = -1;
X sp->S_Lrow = -1;
X sp->S_Lcol = -1;
X sp->S_Drow = -1;
X sp->S_Dcol = -1;
X sp->S_Dfmt = "";
X ++sp;
X } while (*++functs);
X sp->S_title = 0;
X screen(dbname, mscreen, 0, &func, FALSE);
X free((char*)mscreen);
X return (func);
X}
SHAR_EOF
true || echo 'restore of menu.c failed'
# ============= printdb.c ==============
echo 'x - extracting printdb.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'printdb.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)printdb.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
X#endif
X
X/* PRINTDB.C */
X/* This module format prints the data base in the order requested.
X** NOTE: If a record contains multiple values for the key selected,
X** it will be printed multiple times.
X** Alternativly it will format print an extracted file (see extract.c)
X** The formats allowed are:
X** %NN - contents of field NN (1-maxfield)
X** %NN(form) - contents of field NN in printf '%form' format
X** %n - new-line
X** %t - tab
X** %f - form feed
X** %t(NN) - tab to column NN
X** %% - %
X** NOTE: '.' ends a format specification %1.1 prints the contents of
X** field 1 concatenated with a '1'.
X**/
X#include "stdio.h"
X#include "cardfile.h"
X#include "ascii.h"
X#include <signal.h>
X
Xchar out_format[512], ext_file[15];
Xchar out_file[15], out_width[4];
Xstruct Sdata first_screen[] = {
X {"Format", 127, out_format, 0, -1, -1, -1, -1, -1, ""},
X {"Extracted File", 14, ext_file, 0, -1, -1, -1, -1, -1, ""},
X {"Output File", 14, out_file, 0, -1, -1, -1, -1, -1, ""},
X {"Output Width", 3, out_width, 0, -1, -1, -1, -1, -1, ""},
X {0, 0, 0, 0, -1, -1, -1, -1, -1, ""}
X };
X
Xstatic int quit = 0;
Xstatic SIGRTN (*old_sig)();
Xstatic FILE *out;
Xstatic SIGRTN abort();
X
X
Xprintdb(fields, dbname)
Xstruct Fdata *fields;
Xchar *dbname;
X{
X char *keys[MAXAK+1];
X char keyv[MAXAK][TSIZE+1];
X int nkeys, i;
X struct Fdata *fp;
X char aknum[MAXAK];
X int keynum;
X char title[SWIDTH];
X char fname[FNSIZE];
X FILE *akfile, *dbfile;
X char akrec[AKSIZE+1], dbrec[DBSIZE+1];
X long offset, atol();
X int width;
X char *last;
X char h_line[1024];
X
X sprintf(title, "Print %s data base", dbname);
X while (1) {
X last = "Enter ? for help.";
X screen(title, first_screen, last, 0, FALSE);
X if (strcmp(ext_file, "?") == 0) {
X strcpy(h_line, "Enter the name of the extract file generated");
X strcat(h_line, " from\nthe maintenance menu. If you leave it");
X strcat(h_line, " blank, the entire\ndata base will be dumped.");
X help(h_line);
X continue;
X }
X if (strcmp(out_width, "?") == 0) {
X help("Enter the width of the output device, defaults to 80.");
X continue;
X }
X if (*out_width == '\0') {
X width = PWIDTH;
X } else {
X width = atoi(out_width);
X }
X if (strcmp(out_file, "?") == 0) {
X strcpy(h_line, "Enter the name of the output file,");
X strcat(h_line, " defaults to '|lp', the printer.");
X help(h_line);
X continue;
X }
X if (*out_file == '\0') {
X strcpy(out_file, "|lp");
X }
X if (strcmp(out_format, "?") == 0) {
X strcpy(h_line, "Enter the output format. All characters will");
X strcat(h_line, " be\nprinted as entered except for % sequences.");
X strcat(h_line, "\n\n\t%NN\t - contents of field NN (1-maxfield)");
X strcat(h_line, "\n\t%NN(form) - contents of field NN in");
X strcat(h_line, " printf '%form' format\n");
X strcat(h_line, "\t%n\t- new-line\n");
X strcat(h_line, "\t%t\t- tab\n");
X strcat(h_line, "\t%t(NN)\t- tab to column NN\n");
X strcat(h_line, "\t%f\t- form-feed\n");
X strcat(h_line, "\t%%\t- %");
X help(h_line);
X continue;
X }
X if (*out_format == '\0') { /* not specified, use default */
X fp = fields;
X i = 1;
X while (fp->F_title[0]) {
X sprintf(&out_format[strlen(out_format)], "%s: %%%d%%n",
X fp->F_title, i);
X ++i;
X ++fp;
X }
X strcat(out_format, "%n%n%n");
X }
X break;
X }
X if (ext_file[0] == '\0') {
X msg("No extract specified, entire database will be dumped");
X }
X fp = fields;
X nkeys = 0;
X if (ext_file[0] == '\0') {
X while (fp->F_title[0] != '\0') {
X if (fp->F_key != 'N') {
X sprintf(keyv[nkeys], "%-20s", fp->F_title);
X keys[nkeys] = keyv[nkeys];
X aknum[nkeys] = fp->F_key;
X ++nkeys;
X }
X ++fp;
X }
X keys[nkeys] = "Cancel ";
X aknum[nkeys] = '\0';
X ++nkeys;
X keys[nkeys] = 0;
X sprintf(title, "Print %s data base selected by", dbname);
X keynum = menu(title, keys);
X if (aknum[keynum] == '\0') { /* cancel */
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
X sprintf(fname, "%s%s.ak%c", datadir, dbname, aknum[keynum]);
X if ((akfile = fopen(fname, "r")) == NULL) {
X msg("Unable to open alternate key file");
X getout();
X }
X sprintf(fname, "%s%s.db", datadir, dbname);
X if ((dbfile = fopen(fname, "r")) == NULL) {
X msg("Unable to open db file");
X getout();
X }
X msg(NULL); /* leave the cursor at the bottom */
X fputs("DEL to abort printing", stdout);
X old_sig = signal(SIGINT, abort);
X
X while(!quit && fgets(akrec, AKSIZE, akfile) != NULL) {
X offset = atol(strchr(akrec, ':')+1);
X if (offset < 0L)
X continue;
X fseek(dbfile, offset, 0);
X if (fgets(dbrec, DBSIZE, dbfile) == NULL) {
X msg("Bad offset found");
X continue;
X }
X if (*dbrec == 'D') /* check for delete flag */
X continue;
X if (putrcd(0, dbrec, out, out_format, width, 1) == -1)
X break;
X }
X fclose(akfile);
X } else {
X if ((dbfile = fopen(ext_file, "r")) == NULL) {
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 msg(NULL); /* leave the cursor at the bottom */
X fputs("DEL to abort printing", stdout);
X old_sig = signal(SIGINT, abort);
X while(!quit && fgets(dbrec, DBSIZE, dbfile) != NULL) {
X if (putrcd(0, dbrec, out, out_format, width, 1) == -1)
X break;
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 SIGRTN
Xabort()
X{
X
X fputs("\n\nOUTPUT ABORTED!\n", out);
X msg("Dump aborted");
X quit = 1;
X}
SHAR_EOF
true || echo 'restore of printdb.c failed'
# ============= putrcd.c ==============
echo 'x - extracting putrcd.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'putrcd.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)putrcd.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
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
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 max_flds;
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 max_flds = --i;
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 if (field > max_flds) {
X fmt_error(fmt_ptr, fmt-fmt_ptr);
X return(-1);
X }
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 char str[200];
X
X sprintf(str, "format='%s' Error near column %d", fmt, col);
X msg(str);
X sleep(4);
X}
SHAR_EOF
true || echo 'restore of putrcd.c failed'
# ============= rawio.c ==============
echo 'x - extracting rawio.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'rawio.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)rawio.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
X#endif
X
X/* RAWIO.C */
X
X#include "ascii.h"
X#include "cardfile.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
true || echo 'restore of rawio.c failed'
# ============= rbuildak.c ==============
echo 'x - extracting rbuildak.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'rbuildak.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)rbuildak.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
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
true || echo 'restore of rbuildak.c failed'
# ============= screen.c ==============
echo 'x - extracting screen.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'screen.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)screen.c 3.2 DeltaDate 8/11/90 ExtrDate 10/6/90";
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** 5. A flag which if TRUE makes the screen display only.
X** It returns the number of fields modified.
X** The external character lastchar will return the last charater input.
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** 5. An (optional) row for the title
X** 6. An (optional) column for the title
X** 7. An (optional) row for the data
X** 8. An (optional) column for the data
X** 9. An (optional) format for the data
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, wrap to the bottom field
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 <signal.h>
X#ifdef TERMCAP
X#include <termio.h>
X#define tparm(a, line, col) tgoto(a, col, line)
X#define putp(a) tputs(a, 12, mputc)
X#else
X#include <curses.h>
X#include <term.h>
X#endif
X#ifdef BSD_TTY
X#include <sgtty.h>
X#endif
X#ifdef BSD_SIG
X#include <setjmp.h>
Xjmp_buf jbuf;
X#endif
X
X#ifdef TERMCAP
Xextern char *tgoto(), *getenv();
Xextern char
X *clear_screen,
X *clr_eol,
X *enter_dim_mode,
X *enter_blink_mode,
X *exit_attribute_mode,
X *keypad_xmit,
X *keypad_local,
X *cursor_address,
X *cursor_left,
X *cursor_right;
Xint mputc();
X#endif
X
X
Xextern struct cchar *cc_head;
Xextern char func_label[];
X
Xchar lastchar;
X
Xstatic int flen;
Xstatic char *cp;
Xstatic int changes;
Xstatic int fmt_msg = FALSE;
Xstatic struct SFdata {
X int f_page;
X int f_tline;
X int f_tcol;
X char *f_title;
X int f_dline;
X int f_dcol;
X char *f_dfmt;
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;
Xstatic int read_only; /* true if not to be modified */
X
XSIGRTN ctl_timeout();
Xstatic int timedout;
X
Xint
Xscreen(first, vardata, last, left, ro)
Xchar *first, *last;
Xstruct Sdata *vardata;
Xint *left;
Xint ro;
X{
X int inp;
X char t_last[81];
X char mbuf[81];
X register struct cchar *sp;
X struct SFdata *last_field;
X
X read_only = ro;
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_tline = 2;
X for (fp = scr_fields ; vardata->S_title != NULL ; ++vardata , ++fp) {
X if (vardata->S_Lrow != -1) {
X fp->f_tline = vardata->S_Lrow;
X }
X if (vardata->S_Lcol != -1) {
X fp->f_tcol = vardata->S_Lcol;
X } else {
X fp->f_tcol = 4;
X }
X if (vardata->S_Drow != -1) {
X fp->f_dline = vardata->S_Drow;
X } else {
X fp->f_dline = fp->f_tline;
X }
X if (vardata->S_Dcol != -1) {
X fp->f_dcol = vardata->S_Dcol;
X } else {
X if (vardata->S_length > 1) {
X fp->f_dcol = fp->f_tcol + strlen(vardata->S_title) + 6;
X if (vardata->S_length > 99)
X fp->f_dcol += 2;
X else if (vardata->S_length > 9)
X fp->f_dcol += 1;
X } else {
X fp->f_dcol = fp->f_tcol + strlen(vardata->S_title) + 3;
X }
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 fp->f_dfmt = vardata->S_Dfmt;
X /* check if too much for this screen */
X if ( (fp->f_tline + (fp->f_dcol + fp->f_length + SWIDTH-1)/SWIDTH)
X > SLENGTH - 4) {
X (fp+1)->f_page = fp->f_page + 1;
X (fp+1)->f_tline = 2;
X } else {
X (fp+1)->f_page = fp->f_page;
X (fp+1)->f_tline = fp->f_tline + 1
X + (fp->f_dcol + fp->f_length + SWIDTH-1)/SWIDTH;
X }
X }
X fp->f_page = fp->f_tline = 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_tline, fp->f_title, fp->f_dcol, 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_tline);
X#endif
X putp(tparm(cursor_address, fp->f_tline, fp->f_tcol-1));
X putp(enter_dim_mode);
X if (fp->f_length > 1) {
X putp(tparm(cursor_address, fp->f_tline, fp->f_tcol));
X printf("%s(%d):", fp->f_title, fp->f_length);
X } else {
X putp(tparm(cursor_address, fp->f_tline, fp->f_tcol));
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_dline, fp->f_dcol));
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())) {
X lastchar = inp;
X if (inp == '\n' || inp == '\r') {
X /* check format first */
X if (! read_only && fp->f_dfmt[0] && fp->f_result[0]) {
X if (fmt_chk(fp->f_result, fp->f_dfmt) != 0) {
X fmt_msg = TRUE;
X sprintf(mbuf, "Invalid format, should be %.40s", fp->f_dfmt);
X msg(mbuf);
X rawputchar(BEL);
X cp = fp->f_result;
X flen = fp->f_length;
X resetcursor();
X continue;
X } else {
X if (fmt_msg) {
X msg("");
X fmt_msg = FALSE;
X }
X }
X
X }
X if (fmt_msg) {
X msg("");
X fmt_msg = FALSE;
X }
X break;
X }
X /*
X * Check for control key sequence
X */
X timedout = FALSE;
X signal(SIGALRM, ctl_timeout);
X alarm(1);
X sp = cc_head;
X while (sp) {
X if (inp == sp->ch) {
X inp = process_ctl(sp);
X break;
X }
X sp = sp->alt;
X }
X alarm(0);
X signal(SIGALRM, SIG_DFL);
X if (sp != NULL) { /* control character match found */
X if (inp == -1) /* page switch */
X break;
X if (read_only && timedout)
X return(0);
X continue;
X }
X if (read_only) {
X return(0);
X }
X /*
X * Process a normal character
X */
X /* Control characters are illegal (also catches illegal controls) */
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);
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
Xint
Xprocess_ctl(ccp)
Xstruct cchar *ccp;
X{
X int ch;
X
X /* check for end of control sequence */
X if (ccp->action) {
X return((*ccp->action)(scr_fields));
X }
X#ifdef BSD_SIG
X if (setjmp(jbuf) != 0) {
X /* return from interupt */
X return(0);
X }
X#endif
X if ((ch = rawgetchar()) == EOF) {
X if (! read_only)
X rawputchar(BEL);
X return(0);
X }
X lastchar = ch;
X ccp = ccp->next;
X while (ccp) {
X if (ch == ccp->ch)
X return(process_ctl(ccp));
X ccp = ccp->alt;
X }
X rawputchar(BEL);
X return(0); /* illegal sequence */
X}
X
XSIGRTN
Xctl_timeout()
X{
X timedout = TRUE;
X#ifdef BSD_SIG
X longjmp(jbuf, 1);
X#endif
X return;
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 the screen data structure.
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)
Xstruct SFdata field_tbl[];
X{
X char mbuf[81];
X
X /* see if format needs to be checked */
X if (fp->f_dfmt[0] && fp->f_result[0]) {
X if (fmt_chk(fp->f_result, fp->f_dfmt) != 0) {
X fmt_msg = TRUE;
X sprintf(mbuf, "Invalid format, should be %.40s", fp->f_dfmt);
X msg(mbuf);
X rawputchar(BEL);
X cp = fp->f_result;
X flen = fp->f_length;
X resetcursor();
X return(0);
X } else {
X if (fmt_msg) {
X msg("");
X fmt_msg = FALSE;
X }
X }
X }
X if (fmt_msg) {
X msg("");
X fmt_msg = FALSE;
X }
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
Xprevpage(field_tbl)
Xstruct SFdata field_tbl[];
X{
X register struct SFdata *t_fp;
X char mbuf[81];
X
X /* see if format needs to be checked */
X if (fp->f_dfmt[0] && fp->f_result[0]) {
X if (fmt_chk(fp->f_result, fp->f_dfmt) != 0) {
X fmt_msg = TRUE;
X sprintf(mbuf, "Invalid format, should be %.40s", fp->f_dfmt);
X msg(mbuf);
X rawputchar(BEL);
X cp = fp->f_result;
X flen = fp->f_length;
X resetcursor();
X return(0);
X } else {
X if (fmt_msg) {
X msg("");
X fmt_msg = FALSE;
X }
X }
X }
X if (fmt_msg) {
X msg("");
X fmt_msg = FALSE;
X }
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(dummy)
Xstruct SFdata dummy[];
X{
X register int page;
X char mbuf[81];
X
X /* see if format needs to be checked */
X if (fp->f_dfmt[0] && fp->f_result[0]) {
X if (fmt_chk(fp->f_result, fp->f_dfmt) != 0) {
X fmt_msg = TRUE;
X sprintf(mbuf, "Invalid format, should be %.40s", fp->f_dfmt);
X msg(mbuf);
X rawputchar(BEL);
X cp = fp->f_result;
X flen = fp->f_length;
X resetcursor();
X return(0);
X } else {
X if (fmt_msg) {
X msg("");
X fmt_msg = FALSE;
X }
X }
X }
X if (fmt_msg) {
X msg("");
X fmt_msg = FALSE;
X }
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(dummy)
Xstruct SFdata dummy[];
X{
X register int page;
X char mbuf[81];
X
X /* see if format needs to be checked */
X if (fp->f_dfmt[0] && fp->f_result[0]) {
X if (fmt_chk(fp->f_result, fp->f_dfmt) != 0) {
X fmt_msg = TRUE;
X sprintf(mbuf, "Invalid format, should be %.40s", fp->f_dfmt);
X msg(mbuf);
X rawputchar(BEL);
X cp = fp->f_result;
X flen = fp->f_length;
X resetcursor();
X return(0);
X } else {
X if (fmt_msg) {
X msg("");
X fmt_msg = FALSE;
X }
X }
X }
X if (fmt_msg) {
X msg("");
X fmt_msg = FALSE;
X }
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
X
Xgoright(field_tbl)
Xstruct SFdata field_tbl[];
X{
X register int pos;
X
X if (--flen <= 0)
X nextfield(field_tbl);
X if (*cp == '\0')
X *cp = ' ';
X cp++;
X pos = cp - fp->f_result + fp->f_dcol;
X if (pos % SWIDTH == 0) {
X resetcursor();
X } else {
X putp(cursor_right);
X }
X return(0);
X}
X
X
Xgoleft(field_tbl)
Xstruct SFdata field_tbl[];
X{
X register int pos;
X
X if (++flen > fp->f_length) {
X prevfield(field_tbl);
X } else {
X --cp;
X pos = cp - fp->f_result + fp->f_dcol;
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(dummy)
Xstruct Sdata *dummy;
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(dummy)
Xstruct Sdata *dummy;
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(dummy)
Xstruct Sdata *dummy;
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_dcol;
X putp(tparm(cursor_address, fp->f_dline + flent/SWIDTH, flent%SWIDTH));
X}
X
X#ifdef BSD_TTY
Xstatic struct sgttyb instty, outstty;
X#else /* SYSV_TTY */
Xstatic struct termio instty, outstty;
X#endif
X
X
Xvoid
Xsetupscr()
X{
X
X setbuf(stdout, NULL);
X setbuf(stdin, NULL);
X#ifdef BSD_TTY
X ioctl(0, TIOCGETP, &outstty);
X instty.sg_ispeed = outstty.sg_ispeed;
X instty.sg_ospeed = outstty.sg_ospeed;
X instty.sg_erase = outstty.sg_erase;
X instty.sg_kill = outstty.sg_kill;
X instty.sg_flags = RAW;
X ioctl(0, TIOCSETP, &instty);
X#else /* SYSV_TTY */
X ioctl(0, TCGETA, &outstty);
X instty.c_iflag = outstty.c_iflag;
X instty.c_oflag = outstty.c_oflag;
X instty.c_cflag = outstty.c_cflag;
X instty.c_lflag = 0; /* turn off icanon, echo */
X instty.c_line = outstty.c_line;
X instty.c_cc[VINTR] = outstty.c_cc[VINTR];
X instty.c_cc[VQUIT] = outstty.c_cc[VQUIT];
X instty.c_cc[VERASE] = outstty.c_cc[VERASE];
X instty.c_cc[VKILL] = outstty.c_cc[VKILL];
X instty.c_cc[VMIN] = 1;
X instty.c_cc[VTIME] = 0;
X instty.c_cc[6] = outstty.c_cc[6];
X instty.c_cc[7] = outstty.c_cc[7];
X ioctl(0, TCSETAW, &instty);
X#endif
X#ifdef TERMINFO
X setupterm((char*)0, 1, (int*)0);
X#else
X setterm(getenv("TERM"));
X#endif
X setupkeys();
X putp(keypad_xmit);
X}
X
XSIGRTN
Xgetout()
X{
X
X putp(keypad_local);
X putp(clear_screen);
X#ifdef BSD_TTY
X ioctl(0, TIOCSETP, &outstty);
X#else /* SYSV_TTY */
X ioctl(0, TCSETAW, &outstty);
X#endif
X exit(0);
X}
X
SHAR_EOF
true || echo 'restore of screen.c failed'
# ============= setupkeys.c ==============
echo 'x - extracting setupkeys.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'setupkeys.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)setupkeys.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
X#endif
X
X/* SETUPKEYS.C */
X/* This module sets up all terminal specific key sequences.
X** It sets up the a linked list that translates function keys to
X** actions 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 <curses.h>
X#ifndef TERMCAP
X# include <term.h>
X#endif
X#ifdef DEBUG
X#include <stdio.h>
X#endif
X#include "cardfile.h"
X
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();
Xchar *malloc();
Xchar *memset();
Xchar *strstr();
X
X/* translation of terminfo/termcap 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#ifdef TERMCAP
Xchar *clear_screen,
X *clr_eol,
X *enter_dim_mode,
X *enter_blink_mode,
X *exit_attribute_mode,
X *keypad_xmit,
X *keypad_local,
X *cursor_address,
X *cursor_left,
X *cursor_right;
X#endif
X
Xstruct cchar *cc_head;
X
Xchar func_label[256];
X
Xsetupkeys()
X{
X register struct keys *kp;
X register char *so_on, *so_off;
X register char *cp;
X register struct cchar *ccp;
X int slen;
X#ifdef TERMCAP
X static char tc_buf[1024];
X static char *tc_ptr = tc_buf;
X static char tc_out[256];
X static char *out_ptr = tc_out;
X extern char *tgetstr(), *tgoto();
X extern char *getenv();
X#endif
X
X#ifdef TERMCAP
X if (tgetent(tc_buf, (cp = getenv("TERM"))) != 1) {
X printf(stderr, "Unable to get terminal settings for %s\n",
X (cp ? cp : "<NULL>"));
X exit(1);
X }
X if ((keys[k_BS].string = tgetstr("kb", &out_ptr)) == 0) {
X keys[k_BS].string = "\b";
X }
X if ((keys[k_LEFT].string = tgetstr("kl", &out_ptr)) == 0) {
X keys[k_LEFT].string = "";
X }
X if ((keys[k_RIGHT].string = tgetstr("kr", &out_ptr)) == 0) {
X keys[k_RIGHT].string = "";
X }
X if ((keys[k_EOL].string = tgetstr("kE", &out_ptr)) == 0) {
X keys[k_EOL].string = "";
X }
X if ((keys[k_DC].string = tgetstr("kD", &out_ptr)) == 0) {
X keys[k_DC].string = "";
X }
X if ((keys[k_IC].string = tgetstr("kI", &out_ptr)) == 0) {
X keys[k_IC].string = "";
X }
X if ((keys[k_TAB].string = tgetstr("ta", &out_ptr)) == 0) {
X keys[k_TAB].string = "\t";
X }
X if ((keys[k_UP].string = tgetstr("ku", &out_ptr)) == 0) {
X keys[k_UP].string = "";
X }
X if ((keys[k_DOWN].string = tgetstr("kd", &out_ptr)) == 0) {
X keys[k_DOWN].string = "";
X }
X if ((keys[k_F2].string = tgetstr("k2", &out_ptr)) == 0) {
X keys[k_F2].string = "";
X }
X if ((keys[k_F3].string = tgetstr("k3", &out_ptr)) == 0) {
X keys[k_F3].string = "";
X }
X if ((keys[k_F4].string = tgetstr("k4", &out_ptr)) == 0) {
X keys[k_F4].string = "";
X }
X if ((keys[k_F5].string = tgetstr("k5", &out_ptr)) == 0) {
X keys[k_F5].string = "";
X }
X if ((keys[k_F6].string = tgetstr("k6", &out_ptr)) == 0) {
X keys[k_F6].string = "";
X }
X if ((keys[k_BTAB].string = tgetstr("kB", &out_ptr)) == 0) {
X keys[k_BTAB].string = "";
X }
X
X if ((clear_screen = tgetstr("cl", &out_ptr)) == 0) {
X clear_screen = "";
X }
X if ((cursor_address = tgetstr("cm", &out_ptr)) == 0) {
X cursor_address = "";
X }
X if ((enter_dim_mode = tgetstr("mh", &out_ptr)) == 0) {
X enter_dim_mode = "";
X }
X if ((exit_attribute_mode = tgetstr("me", &out_ptr)) == 0) {
X exit_attribute_mode = "";
X }
X if ((cursor_right = tgetstr("nd", &out_ptr)) == 0) {
X cursor_right = "";
X }
X if ((cursor_left = tgetstr("le", &out_ptr)) == 0) {
X cursor_left = "\b";
X }
X if ((keypad_xmit = tgetstr("ks", &out_ptr)) == 0) {
X keypad_xmit = "";
X }
X if ((keypad_local = tgetstr("ke", &out_ptr)) == 0) {
X keypad_local = "";
X }
X if ((clr_eol = tgetstr("ce", &out_ptr)) == 0) {
X clr_eol = "";
X }
X if ((enter_blink_mode = tgetstr("mb", &out_ptr)) == 0) {
X if ((enter_blink_mode = tgetstr("so", &out_ptr)) == 0)
X enter_blink_mode = "";
X }
X#else /* TERMCAP */
X setupterm((char*)0, 1, (int*)0);
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#endif /* TERMCAP */
X
X/*
X * Set up function key label string
X */
X#ifdef TERMCAP
X so_on = tgetstr("mr", &out_ptr);
X so_off = tgetstr("me", &out_ptr);
X if (so_on == 0 || strlen(so_on) == 0) {
X so_on = tgetstr("se", &out_ptr);
X so_off = tgetstr("so", &out_ptr);
X }
X#else /* TERMCAP */
X so_on = enter_reverse_mode;
X so_off = exit_attribute_mode;
X if (so_on == 0 || strlen(so_on) == 0) {
X so_on = enter_standout_mode;
X so_off = exit_standout_mode;
X }
X#endif /* TERMCAP */
X sprintf(func_label, "%s%8s%s %s%8s%s %s%8s%s %s%8s%s ",
X so_on, "", so_off,
X so_on, (keys[k_F2].string[0]?"insert ":""), so_off,
X so_on, (keys[k_F3].string[0]?"delete ":""), so_off,
X so_on, (keys[k_F4].string[0]?"clr fld ":""), so_off);
X sprintf(func_label+strlen(func_label), "%s%8s%s %s%8s%s %s%8s%s %s%8s%s",
X so_on, (keys[k_F5].string[0]?"next pg":""), so_off,
X so_on, (keys[k_F6].string[0]?"prev pg":""), so_off,
X so_on, "", so_off,
X so_on, "", so_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 cc_head = (struct cchar*)malloc(sizeof(struct cchar));
X memset(cc_head, '\0', sizeof(struct cchar));
X
X for (kp = keys; kp->terminfo_name; ++kp) {
X#ifdef DEBUG
X fprintf(stderr, "Capname=%s,string='", kp->terminfo_name);
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 || strlen(kp->string) == 0) {
X#ifdef DEBUG
X fprintf(stderr, "Control sequence for \"%s\" doesn't exist\n",
X kp->terminfo_name);
X#endif
X continue;
X }
X /*
X * Throw away pad string '$<nn>'
X */
X if ((cp = strstr(kp->string, "$<")) != NULL) {
X /* num of chars to delete */
X slen = strchr(cp, '>') - cp + 1;
X if (slen > 0) {
X strcpy(cp, cp+slen);
X }
X }
X
X for (cp = kp->string, ccp = cc_head; *cp; ) {
X if (ccp->ch == '\0')
X ccp->ch = *cp;
X if (ccp->ch == *cp) {
X if (*(cp+1) == '\0') { /* end of string, add action */
X if (ccp->action != NULL) {
X fprintf(stderr, "Control string conflict\n");
X break;
X } else { /* add it */
X ccp->action = kp->func;
X break;
X }
X }
X /* not end of string */
X if (ccp->next == NULL) {
X ccp->next = (struct cchar*)malloc(sizeof(struct cchar));
X memset(ccp->next, '\0', sizeof(struct cchar));
X }
X ccp = ccp->next;
X ++cp;
X continue;
X }
X if (ccp->alt != NULL) {
X ccp = ccp->alt;
X continue;
X }
X /* allocate new alternate */
X ccp->alt = (struct cchar*)malloc(sizeof(struct cchar));
X memset(ccp->alt, '\0', sizeof(struct cchar));
X ccp = ccp->alt;
X }
X
X#if DEBUG > 1
X dumptables(cc_head);
X#endif
X }
X#if DEBUG == 1
X dumptables(cc_head);
X dumpcmd();
X#endif
X}
X
X
X/* strstr String version of strchr */
X/* Return pointer to 1st occurance of s2 in s1 */
X/* Return NULL if not found */
Xchar
X*strstr(s1, s2)
Xregister char *s1, *s2;
X{
X register int len;
X
X len = strlen(s2);
X while (*s1)
X {
X if (strncmp(s1, s2, len) == 0)
X return(s1);
X else
X ++s1;
X }
X return(NULL);
X}
X
X
X#ifdef DEBUG
Xstatic
Xdumptables(head)
Xstruct cchar *head;
X{
X dtable(head);
X if (head->alt)
X dumptables(head->alt);
X if (head->next)
X dumptables(head->next);
X}
X
X
Xstatic
Xdtable(ccp)
Xregister struct cchar *ccp;
X{
X
X fprintf(stderr, "%d:\tch='%s'\n", ccp-cc_head+1, unctrl(ccp->ch));
X fprintf(stderr, "\tnext=%d", ccp->next?ccp->next-cc_head+1:0);
X fprintf(stderr, "\talt=%d", ccp->alt?ccp->alt-cc_head+1:0);
X if (ccp->action == goright) {
X fprintf(stderr, "\taction=goright\n");
X } else if (ccp->action == goleft) {
X fprintf(stderr, "\taction=goleft\n");
X } else if (ccp->action == nextfield) {
X fprintf(stderr, "\taction=nfield\n");
X } else if (ccp->action == prevfield) {
X fprintf(stderr, "\taction=pfield\n");
X } else if (ccp->action == ferase) {
X fprintf(stderr, "\taction=ferase\n");
X } else if (ccp->action == delchar) {
X fprintf(stderr, "\taction=delchar\n");
X } else if (ccp->action == inschar) {
X fprintf(stderr, "\taction=inschar\n");
X } else if (ccp->action == nextpage) {
X fprintf(stderr, "\taction=nextpage\n");
X } else if (ccp->action == prevpage) {
X fprintf(stderr, "\taction=prevpage\n");
X } else {
X fprintf(stderr, "\n");
X }
X}
X
Xstatic
Xdumpcmd()
X{
X
X fprintf(stderr, "clear_screen='");
X putctlstr(clear_screen);
X fprintf(stderr,"'\n");
X fprintf(stderr, "cursor_address='");
X putctlstr(cursor_address);
X fprintf(stderr,"'\n");
X fprintf(stderr, "enter_dim_mode='");
X putctlstr(enter_dim_mode);
X fprintf(stderr,"'\n");
X fprintf(stderr, "exit_attribute_mode='");
X putctlstr(exit_attribute_mode);
X fprintf(stderr,"'\n");
X fprintf(stderr, "cursor_right='");
X putctlstr(cursor_right);
X fprintf(stderr,"'\n");
X fprintf(stderr, "cursor_left='");
X putctlstr(cursor_left);
X fprintf(stderr,"'\n");
X fprintf(stderr, "keypad_xmit='");
X putctlstr(keypad_xmit);
X fprintf(stderr,"'\n");
X fprintf(stderr, "keypad_local='");
X putctlstr(keypad_local);
X fprintf(stderr,"'\n");
X fprintf(stderr, "clr_eol='");
X putctlstr(clr_eol);
X fprintf(stderr,"'\n");
X fprintf(stderr, "enter_blink_mode='");
X putctlstr(enter_blink_mode);
X fprintf(stderr,"'\n");
X}
X
X
Xstatic
Xputctlstr(str)
Xregister char *str;
X{
X
X for ( ; str != 0 && *str ; str++)
X fputs(unctrl(*str), stderr);
X}
X#endif
SHAR_EOF
true || echo 'restore of setupkeys.c failed'
# ============= updak.c ==============
echo 'x - extracting updak.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'updak.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)updak.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
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#include <ctype.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#ifdef BSD_STRING
Xregister char c1, c2;
X while (1) {
X if (isupper(*s1))
X c1 = tolower(*s1);
X else
X c1 = *s1;
X if (isupper(*s2))
X c2 = tolower(*s2);
X else
X c2 = *s2;
X if (c1 != c2 || len-- == 0)
X break;
X if (c1 == '\0')
X return(0);
X ++s1;
X ++s2;
X }
X return(c1 - c2);
X#else
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#endif
X}
SHAR_EOF
true || echo 'restore of updak.c failed'
# ============= ascii.h ==============
echo 'x - extracting ascii.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ascii.h' &&
X#ifndef lint
Xstatic char ID_ascii[] = "@(#)ascii.h 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
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
true || echo 'restore of ascii.h failed'
# ============= cardfile.h ==============
echo 'x - extracting cardfile.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'cardfile.h' &&
X#ifndef lint
Xstatic char ID_cardfile[] = "@(#)cardfile.h 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
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 15 /* 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 15 /* 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 MAXFMT 128 /* maximum length of a format string */
X#ifndef TRUE
X# define TRUE 1
X# define FALSE 0
X#endif
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 int S_page;
X int S_Lrow;
X int S_Lcol;
X int S_Drow;
X int S_Dcol;
X char *S_Dfmt;
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 char F_page; /* What screen page this field will appear on */
X int F_Lrow; /* The screen field label row address */
X int F_Lcol; /* The screen field label column address */
X int F_Drow; /* The screen field data row address */
X int F_Dcol; /* The screen field data column address */
X char F_Dfmt[MAXFMT+1]; /* The screen field data format (fmt_chk) */
X};
X
Xstruct AKdata { /* structure to hold Alternate Key file info */
X int A_fldnum;
X char A_akname[FNSIZE+1];
X};
X
Xstruct cchar { /* strings received from terminal */
X char ch;
X int (*action)();
X struct cchar *next;
X struct cchar *alt;
X};
X
Xextern char datadir[];
XSIGRTN getout();
Xvoid exit(), free();
Xunsigned sleep();
Xchar *tparm();
SHAR_EOF
true || echo 'restore of cardfile.h failed'
# ============= library.def ==============
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
X%%
X5:1:::::^1[89][0-9][0-9]$
X6:1:::::^[0-9]*.[0-9][0-9]$
SHAR_EOF
true || echo 'restore of library.def failed'
true || echo 'restore of library.db failed'
echo End of part 2, continue with part 3
exit 0
More information about the Comp.sources.misc
mailing list