djl@PacBell.COM (Dave Lampe) (10/15/90)
Posting-number: Volume 15, Issue 50 Submitted-by: Dave Lampe <dplace!djl@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