v15i049: cardfile - part 1 of 3
Dave Lampe
dplace!djl at PacBell.COM
Mon Oct 15 11:32:56 AEST 1990
Posting-number: Volume 15, Issue 49
Submitted-by: Dave Lampe <dplace!djl at PacBell.COM>
Archive-name: cardfile/part01
---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is cardfile, a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 10/06/1990 19:30 UTC by djl at dplace
# Source directory /usr/src/cmd/cardfile.d
#
# existing files WILL be overwritten
# This format requires very little intelligence at unshar time.
# "echo", "true", and "sed" may be needed.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 1485 -rw-r--r-- README
# 8576 -r--r--r-- cardfile.man
# 4564 -r--r--r-- Makefile
# 5422 -r--r--r-- cardfile.c
# 2555 -r--r--r-- add.c
# 4552 -r--r--r-- change.c
# 1842 -r--r--r-- common.c
# 1145 -r--r--r-- compress.c
# 8363 -r--r--r-- define.c
# 2755 -r--r--r-- delete.c
# 2934 -r--r--r-- dumpdb.c
# 1445 -r--r--r-- extract.c
# 2549 -r--r--r-- find.c
# 5897 -r--r--r-- findrcds.c
# 1467 -r--r--r-- fmt_chk.c
# 902 -r--r--r-- getkey.c
# 3043 -r--r--r-- keymatch.c
# 1387 -r--r--r-- maint.c
# 930 -r--r--r-- menu.c
# 5999 -r--r--r-- printdb.c
# 5962 -r--r--r-- putrcd.c
# 522 -r--r--r-- rawio.c
# 1397 -r--r--r-- rbuildak.c
# 16416 -r--r--r-- screen.c
# 11302 -r--r--r-- setupkeys.c
# 2834 -r--r--r-- updak.c
# 975 -rw-r--r-- ascii.h
# 2160 -rw-r--r-- cardfile.h
# 252 -rw-r--r-- library.def
# 29494 -rw-r--r-- library.db
# 6271 -rw-r--r-- library.ak0
# 3351 -rw-r--r-- library.ak1
# 5248 -rw-r--r-- library.ak2
# 7266 -rw-r--r-- library.ak3
#
# ============= README ==============
echo 'x - extracting README (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'README' &&
XThis program is a simple screen oriented database manager. It does have
Xsome rudimentary file formatting and printing capabilities. I use it as a
Xlibrary catalog. The metaphor is a stack of index cards with fields and
Xsubfields on them. To explain subfields, think of a book with multiple
Xauthors. Each author must be treated equally and there may be many authors.
XIf you search for any book written by "John Smith" you want to find it
Xwhether he is the only author or the fifteenth author.
X
XThere are parameters in the Makefile to configure it for System V, Sun OS,
Xor BSD. I do not have access to a BSD system so the ioctl calls are from
Xthe book. If you have problems and make changes to screen.c, please send
Xthe patches to me.
X
XSome of the source may look a little strange because I wrote it originally
Xto run under CPM. I still have the CPM version if anyone wants it.
X
XOne thing that needs to be done yet. The indexing needs to be converted
Xfrom a sequential search to something faster such as a B tree. Even with
Xa sequential search, the speed is acceptable on a database of about 500K.
X
XIncluded in the package is a piece of the catalog file for my library so
Xthat you can get the feeling for what it does. After you make it,
Xexecute "cardfile library" and then play.
X
XIf anyone finds any bugs (What? Bugs in MY code? :-) ), or makes any
Ximprovements, please let me know.
X
XDave Lampe
X{ames | lll-tis | sun | pyramid}!pacbell!dplace!djl
X(415) 455-1571 (H)
X(408) 986-9770 (W)
SHAR_EOF
true || echo 'restore of README failed'
# ============= cardfile.man ==============
echo 'x - extracting cardfile.man (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'cardfile.man' &&
X.\ "@(#)cardfile.man 3.1 Delta Date 8/3/90 ExtrDate 10/6/90 ";
X.if t .po 1i
X.TH CARDFILE 1 djl
X.SH NAME
Xcardfile \- simple index card database
X.SH SYNOPSIS
X\fBcardfile [-r] file\fP
X.SH DESCRIPTION
X.I Cardfile
Xis a simple screen oriented index card database program.
XIf
X.I file
Xdoes not exist,
X.I cardfile
Xwill prompt for a definition of the fields to appear in each record.
XEach field has:
X.IP \(bu
Xa name
X.IP \(bu
Xthe maximum length of the field
X.IP \(bu
Xa flag to determine if it is required or not
X.IP \(bu
Xa flag to determine if the field is indexed
X(whether or not it can be searched for)
X.IP \(bu
Xif multiple values may appear in the field,
Xwhat character will separate the values,
Xfor example a book may have multiple authors separated by semicolons
X.IP \(bu
Xwhat screen page this field will appear on
X.IP \(bu
Xwhat position on the screen (line and column) the field title will appear in
X.IP \(bu
Xwhat position the field data will start in
X#ifndef NO_RE
X.IP \(bu
Xa regular expression defining the
Xrequired format of the data in the field.
X#endif
X.PP
XThe position fields are not required and \fIcardfile\fP does
Xnot check for overlap.
XWhen all fields have been defined,
Xreturn a blank screen and
X.I cardfile
Xwill create all necessary files and exit.
XReenter
X.I cardfile
Xwith the same filename and you will be able to start adding the data.
X.P
XThe \fB-r\fP flag tells \fIcardfile\fP to open the database readonly.
XYou must use this flag to retrieve data from a database on which
Xyou do not have write permission.
XWhen \fIcardfile\fP starts, the main menu is the first screen presented.
XYou may use the cursor keys or the tab keys to move.
XWhen the cursor is next to the option desired the return key
Xwill select it.
XThe options on the main menu are:
X.SS Find
XThe \fIFIND\fP option is used to retrieve data from the file.
XYou will be presented with a screen containing all the fields flagged
Xas index fields.
XEnter the value for which you wish to search.
X#ifdef NO_RE
XIf the value is enclosed in quotes (\fB"\fP) it must match exactly.
XOtherwise, case is ignored and asterisk (\fB*\fP) can be used at the
Xend of a string to match anything,
Xi.e. \fIFarmer*\fP will match "Farmer,P.J." or "farmer,philip",
Xor "FARMER9999".
X#else
XIf the value is enclosed in quotes, case is significant,
Xotherwise it is ignored.
XIt is a real regular expression match, \fIlog\fP will match
X"Archaeology", "Logistics" and "analog circuits" for example.
XThe full regular expression syntax of ed is supported.
X#endif
XSearch values within a field may be connected by "\fB&\fP" for
X\fBand\fP or "\fB|\fP" for \fBor\fP,
Xi.e. if you enter "1986|1987" any record with a value of 1986
Xor 1987 will be selected
X("and" only makes sense if multiple values are allowed in the field).
XIf values are entered in multiple fields, a record must satisfy
Xboth criteria to be selected.
X.P
XWhen all values have been input,
Xhit return and the database will be searched.
XThe selected records will be displayed on the screen one at a time.
XReturn will display the next record,
XCtrl-B will move backwards through the list,
Xand Esc will abort the display.
X.if t .bp
X.SS Add
XThe \fIADD\fP option is used to add a new record to the database.
XYou will be presented with a screen with all the fields defined
Xon the record.
XThe maximum size of each field will appear after the field name.
XWhen all the data has been entered for a record,
Xreturn will save the data and blank the fields.
XThe data is not actually written to the file until
Xyou leave the \fIadd\fP screen.
XTo leave the \fIADD\fP screen simply return a blank screen.
X.SS Change
XThe \fICHANGE\fP option starts out like \fIFIND\fP but
Xwhen the selected records are displayed,
XCtrl-C will display an \fIADD\fP screen with the data from
Xthe selected record as the initial value of each field.
XChange the data as desired and then hit return to write the data
Xand display the next selected record.
X.SS Delete
XThe \fIDELETE\fP option starts out like \fIFIND\fP but
Xwhen the selected records are displayed,
XCtrl-D will delete the record from the database.
XThe record is not physically deleted from the file until
X\fICOMPRESS\fP is run, the record is only marked and ignored.
X.SS Print
XThe \fIPRINT\fP option is used to format and print the database
Xor a subset of the database.
XThe first screen asks for the output format, the extracted file
Xif any (see \fIExtract\fP on the \fIMaintenance\fP menu),
Xthe output file, and the output width.
X.if n .P
XAny character in the output format will be printed as entered
Xexcept for \fB%\fP sequences.
XThe recognized sequences are:
X.nf
X.ta 0.5i,1.5i
X %N The contents of field N
X %N(form) The contents of field N in \fIprintf\fP(3)
X "%form" format, i.e. "%1(%-20s)" will print
X field 1 left justified in a 20 character field.
X %n Print a new-line.
X %t Output a tab character.
X %f Output a form feed.
X %t(NN) Advance to column NN.
X %% Print a %.
X.fi
XIf the extract name field is left blank, the entire database will be dumped.
XThe output file may be an ordinary file,
Xor it may be specified as "| \fIcommand\fP" in which case
X\fIcommand\fP will be started and the print piped to it.
XIf the output width is missing, it defaults to 80.
X.SS Exit
XThe \fIEXIT\fP option will return to UNIX.
X.SS Maintenance
XThe \fIMAINTENANCE\fP option will generate a submenu of infrequently used actions.
XThe actions available from the maintenance menu are:
X.br
X.RS 0.25i
X.B Dump
X.br
X.RS 0.25i
XThe \fIDUMP\fP option of the maintenance menu
Xis used to dump all records in the database and in the index files
Xto the printer.
XThe records are not formated, they are printed exactly as in the database.
X.RE
X.B Compress
X.br
X.RS 0.25i
XThe \fICOMPRESS\fP option of the maintenance menu
Xwill reclaim the space taken by records marked as deleted
Xand then will rebuild the index files.
XAfter \fICOMPRESS\fP has been run a record can no longer be recovered.
X.RE
X.B "Rebuild AK's"
X.br
X.RS 0.25i
XThe \fIREBUILD AK's\fP option of the maintenance menu
Xwill recreate the index files from the main database file.
XThis is necessary if the main database has been changed by any means
Xother than this program.
X.RE
X.B Extract
X.br
X.RS 0.25i
XThe \fIEXTRACT\fP option of the maintenance menu
Xis used to write selected records from the
Xdatabase to another file.
XYou are first asked for the name of the output file and then
Xpresented with a screen like \fIFIND\fP to select the records to
Xbe extracted.
X.RE
X.B Exit
X.br
X.RS 0.25i
XThe \fIEXIT\fP option of the maintenance menu will return to the main menu.
X.RE
X.br
X.SH "CONTROL KEYS"
XThe keys used to control the screens are defined in \fItermcap\fP(4).
X.sp
X.nf
X.ta 0.5i,1.5i,3i
X TERMCAP UNIX-PC ACTION
X CAP-NAME KEY
X.sp
X kcuf1 \(-> move right or to next field if at
X end of field
X.if t .sp 0.5
X kcub1 \(<- move left or to previous field if
X at start of field
X.if t .sp 0.5
X kbs Back same as kcub1
X Space
X.if t .sp 0.5
X ht Tab move to start of next field
X.if t .sp 0.5
X kcud1 Down same as ht
X Arrow
X.if t .sp 0.5
X kcbt shift- move to start of this field or previous
X Tab field if at start
X.if t .sp 0.5
X kcuu1 Up same as kcbt
X Arrow
X.if t .sp 0.5
X kel Clear clear to end of field
X Line
X.if t .sp 0.5
X kf4 Funct same as kel
X Key 4
X.if t .sp 0.5
X kdch1 Dlete delete character under cursor
X Char
X.if t .sp 0.5
X kf3 Funct same as kdch1
X Key 3
X.if t .sp 0.5
X kich1 Input insert a blank under the cursor
X Mode
X.if t .sp 0.5
X kf2 Funct same as kich1
X Key 2
X.if t .sp 0.5
X kf5 Funct go to the next page of a multi-page form
X Key 5
X.if t .sp 0.5
X kf6 Funct go to the previous page of a multi-page form
X Key 6
X.fi
X.SH FILES
X.ta 1.5i
X\fIfile\fP.def The file of field and file definitions
X.br
X\fIfile\fP.db The database records
X.br
X\fIfile\fP.ak\fBN\fP The index files for searches
X.SH NOTE
XNo field may contain a colon "\fB:\fP" as it is used as a field
Xseparator in the database.
X.if t .sp 0.5v
X.if n .br
XThe maximum size of a field is 255 characters
Xand of the total record is 1024 characters.
XThe maximum number of fields in a record is 15.
XThese are arbitrary numbers and are easy to change at compile time.
X.if t .sp 0.5v
X.if n .br
XAt least one field must be defined as an index field.
X.if t .sp 0.5v
X.if n .br
XThe regular expressions used as formats and search fields are those supported
Xby the library functions.
XRemember that if a field is supposed to be numeric,
X\&'[0-9]*' will not work, '^[0-9]*$' is necessary.
X.if t .sp 0.5v
X.if n .br
XThe termcap name
X.I kcbt
Xmay not be defined in some versions of UNIX.
XJust use the up arrow instead.
X.if t .sp 0.5v
X.if n .br
XThere is no concurrency control in \fIcardfile\fP.
SHAR_EOF
true || echo 'restore of cardfile.man failed'
# ============= Makefile ==============
echo 'x - extracting Makefile (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
X# @(#)Makefile 3.2 DeltaDate 8/11/90 ExtrDate 10/6/90
X
X# Variables to define your environment:
X# Define what kind of regular expression routines you have
X# BSD_RE use re_comp()/re_exec()
X# SYSV_RE use recmp()/regex()
X# PD_RE use Henry Spencer's public domain routines
X# regcomp()/regexec()
X# NO_RE no regular expressions
X#
X# Define what flavor of curses you have
X# TERMCAP use the original (BSD) curses
X# TERMINFO use the SYSV rewrite of curses
X#
X# Define what tty driver you have
X# SYSV_TTY
X# BSD_TTY
X#
X# Define which string library you have
X# BSD_STRING unprotected tolower(), index()
X# SYSV_STRING safe tolower(), strchr()
X#
X# Define which signal library you have
X# BSD_SIG system calls are continued after interrupt
X# SYSV_SIG system call returns error if interrupted
X#
X# Pick one from each of the five lists above.
X#
X# SIGRTN defines the return type of the signal functions, normally
X# an integer prior to SysV.3, void in SysV.3 and after
X# DEBUG defines the level of debug output, normally not defined
X
X# These are for compiling on the Sun 4.0
X#CC = cc
X#CCP = ccp
X#LINT = lint
X#DEFINES = -DTERMCAP -DBSD_RE -DBSD_STRING -DSYSV_TTY -DSIGRTN=void -DBSD_SIG
X#CC = /usr/5bin/cc
X#CCP = /usr/5bin/ccp
X#LINT = /usr/5bin/lint
X#DEFINES = -DTERMINFO -DBSD_RE -DBSD_STRING -DSYSV_TTY -DSIGRTN=void -DSYSV_SIG
X
X# These are for System V
XCC = cc
XCPP = /lib/cpp
XLINT = lint
XDEFINES = -DTERMINFO -DSYSV_RE -DSYSV_STRING -DSYSV_TTY -DSIGRTN=int -DSYSV_SIG
X
X
X# The PW library is where the regular expression subroutines regcmp, and
X# regex are kept. If you use -DNO_RE or if your libraries are
X# different change it.
XLIBS = -lPW -lcurses
X#LIBS = -lcurses -ltermcap
X
XBINDIR = /usr/local/bin/
XMANDIR = /usr/man/man1/
X
X#CFLAGS = -g -DDEBUG $(DEFINES)
XCFLAGS = -g $(DEFINES)
X
X#
X# Nothing past here should need changing
X#
X
X.SUFFIXES: .1 .1~ .man .man~
X.c~.c:
X $(GET) $(GFLAGS) $<
X
X.man~.man:
X $(GET) $(GFLAGS) $<
X
X
XSHAR = shar
XSHARFLAGS = -c -V -l62 -n cardfile -a -x -o cardfile
X
XDOC = cardfile.1
XDOCS = cardfile.man
X
XHDRS = ascii.h cardfile.h
X
XSRC = \
X cardfile.c \
X add.c \
X change.c \
X common.c \
X compress.c \
X define.c \
X delete.c \
X dumpdb.c \
X extract.c \
X find.c \
X findrcds.c \
X fmt_chk.c \
X getkey.c \
X keymatch.c \
X maint.c \
X menu.c \
X printdb.c \
X putrcd.c \
X rawio.c \
X rbuildak.c \
X screen.c \
X setupkeys.c \
X updak.c \
X $(NULL)
X
XOBJ = \
X cardfile.o \
X add.o \
X change.o \
X common.o \
X compress.o \
X define.o \
X delete.o \
X dumpdb.o \
X extract.o \
X find.o \
X findrcds.o \
X fmt_chk.o \
X getkey.o \
X keymatch.o \
X maint.o \
X menu.o \
X printdb.o \
X putrcd.o \
X rawio.o \
X rbuildak.o \
X screen.o \
X setupkeys.o \
X updak.o \
X $(NULL)
X
XTESTDB = \
X library.def \
X library.db \
X library.ak0 \
X library.ak1 \
X library.ak2 \
X library.ak3 \
X $(NULL)
X
X###############################################################################
X#
X# Make targets
X#
X###############################################################################
X
Xall: cardfile cardfile.1
X
Xcardfile: $(OBJ)
X $(CC) -o cardfile $(OBJ) $(LIBS)
X
Xinstall: all
X cp cardfile $(BINDIR)cardfile
X strip $(BINDIR)cardfile
X cp cardfile.1 $(MANDIR)cardfile.1
X
Xclean:
X rm -f *.o cardfile cardfile.1
X for f in $(DOCS) $(SRC) $(HDRS) Makefile ; \
X do \
X if [ -f $$f -a -f s.$$f -a ! -f p.$$f ] ; \
X then \
X rm -f $$f ; \
X fi ; \
X done
X
X
Xprint: prt_src prt_docs
X
Xprt_src: $(HDRS) $(SRC) Makefile
X cpr -w96 -l88 $(HDRS) $(SRC) Makefile | \
X lp -o-v8 -o-t -o-h12
X
Xprt_docs: $(DOC)
X nroff -man cardfile.1 | lp -o-qc
X
Xcardfile.1: cardfile.man
X $(CPP) -C -P cardfile.man | sed -e '/^$$/d' >cardfile.1
X
Xshar: $(HDRS) $(SRC) $(DOCS) Makefile $(TESTDB)
X $(SHAR) $(SHARFLAGS) README $(DOCS) Makefile \
X $(SRC) $(HDRS) $(TESTDB)
X
Xlint: $(HDRS) $(SRC)
X $(LINT) $(DEFINES) $(SRC)
X
X###############################################################################
X#
X# Object dependencies
X#
X###############################################################################
X
Xadd.o: cardfile.h ascii.h
Xcardfile.o: cardfile.h ascii.h
Xchange.o: cardfile.h ascii.h
Xcommon.o: cardfile.h ascii.h
Xcompress.o: cardfile.h
Xdefine.o: cardfile.h ascii.h
Xdelete.o: cardfile.h ascii.h
Xdumpdb.o: cardfile.h ascii.h
Xextract.o: cardfile.h ascii.h
Xfind.o: cardfile.h ascii.h
Xfindrcds.o: cardfile.h ascii.h
Xgetkey.o: cardfile.h
Xkeymatch.o: cardfile.h
Xmaint.o: cardfile.h
Xmenu.o: cardfile.h
Xprintdb.o: cardfile.h ascii.h
Xputrcd.o: cardfile.h
Xrbuildak.o: cardfile.h
Xscreen.o: cardfile.h ascii.h
Xsetupkeys.o: cardfile.h ascii.h
Xupdak.o: cardfile.h ascii.h
SHAR_EOF
true || echo 'restore of Makefile failed'
# ============= cardfile.c ==============
echo 'x - extracting cardfile.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'cardfile.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)cardfile.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
X#endif
X
X/* CARDFILE.C */
X/* This is the main routine for cardfile
X*/
X#include "ascii.h"
X#include "stdio.h"
X#include "cardfile.h"
X#include <signal.h>
X
X#define FIND 0
X#define ADD 1
X#define CHANGE 2
X#define DELETE 3
X#define PRINT 4
X#define MAINT 5
X#define EXIT 6
X
XFILE *def_fp;
Xint readonly;
Xchar fname[FNSIZE];
Xextern char *getfield();
Xchar *functs[] = {"FIND ",
X "ADD ",
X "CHANGE ",
X "DELETE ",
X "PRINT ",
X "MAINTENANCE",
X "EXIT ",
X 0
X };
X
Xchar datadir[FNSIZE];
Xchar *dbname;
Xvoid setupscr();
Xvoid exit();
Xunsigned sleep();
Xstatic usage();
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X int num_flds, i;
X char line_buf[133];
X struct Fdata fields[MAXFLDS+1], *fp;
X int num_ak;
X struct AKdata ak_data[MAXAK+1];
X int fn;
X int func;
X char *cp;
X extern char *optarg;
X extern int optind, opterr;
X
X opterr = 0;
X while ((i = getopt(argc, argv, "r")) != EOF) {
X switch (i) {
X case 'r':
X ++readonly;
X break;
X case '?':
X usage(argv[0]);
X exit(1);
X }
X }
X if (optind != argc-1) {
X usage(argv[0]);
X exit(1);
X }
X signal(SIGINT, getout);
X signal(SIGQUIT, getout);
X signal(SIGTERM, getout);
X setupscr(); /* from here on use getout, not exit to reset screen */
X if ((cp = strrchr(argv[optind], '/')) != NULL) {
X *cp = '\0';
X sprintf(datadir, "%s/", argv[optind]);
X dbname = cp + 1;
X } else {
X *datadir = '\0';
X dbname = argv[optind];
X }
X if (strlen(dbname) > 10) {
X printf("Database name cannot be longer than 10 characters.\n");
X sleep(5);
X getout();
X }
X /* build definition file name */
X sprintf(fname, "%s%s.def", datadir, dbname);
X if ((def_fp = fopen(fname,"r")) == NULL) {
X db_define(dbname);
X getout();
X }
X /* The format of the definition file is:
X * Num_of_fields
X * Field1_Name:Key:Sub_Seps:Req:Data_Len
X * ...
X * Num_of_Alt_Keys
X * Field_Num:AK1_File_Name
X * ...
X * %%
X * Field_Num:Label_Row:Label_Col:Data_Row:Data_Col:Data_Fmt
X * ...
X */
X if (fgets(line_buf, 132, def_fp) == NULL) {
X printf("Unable to read DEF file\n");
X sleep(5);
X getout();
X }
X if (! readonly && access(fname, 06) != 0) {
X printf("You can not write to the database, try\n%s -r %s%s\n",
X argv[0], datadir, dbname);
X sleep(5);
X getout();
X }
X strcpy(fname, getfield(line_buf, ":"));
X num_flds = atoi(getfield(0, ":"));
X
X for (i=0, fp=&fields[0]; i<num_flds; i++, fp++) { /* get definition of each field */
X if (fgets(line_buf, 132, def_fp) == NULL) {
X printf("DEF file syntax error, field defs\n");
X sleep(5);
X getout();
X }
X strcpy(fp->F_title, getfield(line_buf, ":"));
X fp->F_key = *getfield(0, ":");
X strcpy(fp->F_seps, getfield(0, ":"));
X fp->F_required = *getfield(0, ":");
X fp->F_length = atoi(getfield(0, ":"));
X /* set defaults */
X fp->F_page = -1;
X fp->F_Lrow = -1;
X fp->F_Lcol = -1;
X fp->F_Drow = -1;
X fp->F_Dcol = -1;
X fp->F_Dfmt[0] = '\0';
X }
X fp->F_title[0] = '\0';
X
X fgets(line_buf, 10, def_fp);
X num_ak = atoi(line_buf);
X for (i=0; i<num_ak; i++) { /* get definition of each AK file */
X if (fgets(line_buf, 132, def_fp) == NULL) {
X printf("DEF file syntax error, AK files\n");
X sleep(5);
X getout();
X }
X line_buf[strlen(line_buf)-1] = '\0'; /* truncate newline */
X ak_data[i].A_fldnum = atoi(getfield(line_buf, ":"));
X strcpy(ak_data[i].A_akname, getfield(0, ":"));
X }
X ak_data[i].A_fldnum = -1;
X
X fgets(line_buf, 10, def_fp);
X if (strcmp(line_buf, "%%\n") == 0) {
X for (i=0; i<num_flds; i++) { /* Get screen layout for each field */
X if (fgets(line_buf, 132, def_fp) == NULL) {
X break;
X }
X line_buf[strlen(line_buf)-1] = '\0'; /* truncate newline */
X fn = atoi(getfield(line_buf, ":"));
X if (fn < 0 || fn >= num_flds) {
X printf("DEF file syntax error, screen layout\n");
X sleep(5);
X getout();
X }
X if ((cp = getfield(0, ":")) != NULL && *cp != '\0')
X fields[fn].F_page = atoi(cp);
X if ((cp = getfield(0, ":")) != NULL && *cp != '\0')
X fields[fn].F_Lrow = atoi(cp);
X if ((cp = getfield(0, ":")) != NULL && *cp != '\0')
X fields[fn].F_Lcol = atoi(cp);
X if ((cp = getfield(0, ":")) != NULL && *cp != '\0')
X fields[fn].F_Drow = atoi(cp);
X if ((cp = getfield(0, ":")) != NULL && *cp != '\0')
X fields[fn].F_Dcol = atoi(cp);
X if ((cp = getfield(0, ":")) != NULL) {
X strcpy(fields[fn].F_Dfmt, cp);
X }
X }
X }
X fclose(def_fp);
X#ifdef DEBUG
X fprintf(stderr, "%d fields in the %s database\n", num_flds, dbname);
X for (i=0; i<num_flds; ++i) {
X fprintf(stderr, "%8d %s\n", i, fields[i].F_title);
X }
X#endif
X
X /* get function to be performed */
X while ((func = menu(dbname, functs)) != EXIT) {
X switch (func) {
X case FIND:
X find(fields, dbname);
X continue;
X case ADD:
X add(fields, dbname);
X continue;
X case CHANGE:
X change(fields, dbname);
X continue;
X case DELETE:
X delete(fields, dbname);
X continue;
X case PRINT:
X printdb(fields, dbname);
X continue;
X case MAINT:
X maint(fields, dbname, ak_data);
X continue;
X default:
X msg("Illegal function chosen");
X getout();
X }
X }
X getout();
X/*NOTREACHED*/
X}
X
X
Xstatic
Xusage(prog)
Xchar *prog;
X{
X printf("Usage: %s [-r] file\n", prog);
X}
SHAR_EOF
true || echo 'restore of cardfile.c failed'
# ============= add.c ==============
echo 'x - extracting add.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'add.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)add.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
X#endif
X
X/* ADD.C */
X/* This subroutine is used to add a new record to the
X** data base. It also requests the updating of the
X** alternate key files.
X*/
X
X#include <stdio.h>
X#include <errno.h>
X#include "ascii.h"
X#include "cardfile.h"
X
Xlong ftell();
Xchar *malloc();
Xextern int errno;
Xextern int readonly;
X
Xadd(fields, dbname)
Xstruct Fdata fields[];
Xchar *dbname;
X{
X struct Fdata *fp;
X struct Sdata add_screen[MAXFLDS+1], *sp;
X int err;
X char first[SWIDTH+1];
X char out_line[DBSIZE+1];
X FILE *filep;
X char filename[FNSIZE];
X long offset;
X char *buffer;
X
X if (readonly) {
X msg("Database is readonly");
X return(1);
X }
X sprintf(first, "Add Records to %s Data Base", dbname);
X buffer = malloc(BUFSIZE+1);
X buffer[0] = '\0';
X sprintf(filename, "%s%s.db", datadir, dbname);
X if((filep = fopen(filename, "a")) == NULL) {
X if (errno == EACCES) {
X strcpy(out_line, "You do not have permission to modify this database");
X } else {
X sprintf(out_line, "Unable to open %s, errno=%d\n", filename, errno);
X }
X msg(out_line);
X return(1);
X }
X for (fp = fields, sp = add_screen ; fp->F_title[0] != 0; ++fp, ++sp) {
X sp->S_title = fp->F_title;
X sp->S_length = fp->F_length;
X sp->S_result = malloc((unsigned)fp->F_length+1);
X sp->S_dfault = 0;
X sp->S_page = fp->F_page;
X sp->S_Lrow = fp->F_Lrow;
X sp->S_Lcol = fp->F_Lcol;
X sp->S_Drow = fp->F_Drow;
X sp->S_Dcol = fp->F_Dcol;
X sp->S_Dfmt = fp->F_Dfmt;
X }
X sp->S_title = 0;
X while (screen(first, add_screen, 0, 0, FALSE) != 0) {
X out_line[0] = '\0';
X err = 0;
X fp = fields;
X sp = add_screen;
X while (sp->S_title) {
X if (sp->S_result[0] == '\0' && fp->F_required == 'Y') {
X sprintf(out_line, "Required field %s missing", fp->F_title);
X msg(out_line);
X ++err;
X }
X if (strchr(sp->S_result, ':')) {
X msg("A ':' is not allowed in any field");
X ++err;
X }
X if (strlen(out_line) + strlen(sp->S_result) >= DBSIZE) {
X msg("Record too long");
X ++err;
X break;
X }
X strcat(out_line, sp->S_result);
X strcat(out_line, ":");
X ++fp;
X ++sp;
X }
X if (err)
X continue;
X out_line[strlen(out_line)-1] = '\0';
X offset = ftell(filep);
X fprintf(filep, " :%s\n", out_line);
X buildak(dbname, out_line, offset, fields, buffer);
X }
X sp = add_screen;
X while (sp->S_title) {
X free(sp->S_result);
X ++sp;
X }
X fclose(filep);
X writeak(dbname, buffer);
X free(buffer);
X return(0);
X}
SHAR_EOF
true || echo 'restore of add.c failed'
# ============= change.c ==============
echo 'x - extracting change.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'change.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)change.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
X#endif
X
X/* CHANGE.C */
X/* This module is used to find and change records
X** in the data base matching the selection criteria.
X** The user may select multiple values of one field
X** which will be or'd and/or multiple fields which will
X** be and'd. In other words, if field 1 is specified
X** as value1:value2 and field3 is specified as value3.
X** Records with field1==(value1 || value2) && field3==value3
X** will be selected for changing.
X** It calls findrcds.c to do all the work of finding them.
X** It does not actually change records, the flag(first)
X** field is set to 'D' in the current record and a new
X** record is added. To physically delete the old record,
X** the data base must be compressed.
X*/
X
X#include <stdio.h>
X#include <errno.h>
X#include "ascii.h"
X#include "cardfile.h"
X
Xchar *malloc(), *getfield();
Xextern int readonly;
X
X
Xstatic struct Sdata disp_screen[MAXFLDS+1];
X
Xchange(fields, dbname)
Xstruct Fdata fields[];
Xchar *dbname;
X{
X char first[SWIDTH];
X struct Fdata *fp;
X struct Sdata *sp;
X int processc();
X
X if (readonly) {
X msg("Database is readonly");
X return(1);
X }
X sprintf(first, "Select Records from the %s Data Base to be Changed",
X dbname);
X for (fp = fields, sp = disp_screen ; fp->F_title[0] != 0; ++fp, ++sp) {
X sp->S_title = fp->F_title;
X sp->S_length = fp->F_length;
X sp->S_result = (char*)malloc((unsigned)fp->F_length+1);
X sp->S_page = fp->F_page;
X sp->S_Lrow = fp->F_Lrow;
X sp->S_Lcol = fp->F_Lcol;
X sp->S_Drow = fp->F_Drow;
X sp->S_Dcol = fp->F_Dcol;
X sp->S_Dfmt = fp->F_Dfmt;
X }
X sp->S_title = 0;
X
X findrcds(fields, dbname, processc, first);
X for (sp = disp_screen ; sp->S_title != 0; ++sp) {
X free(sp->S_result);
X }
X return(0);
X}
X
X
Xprocessc(fields, rcd, dbfile, dbname)
Xstruct Fdata *fields;
Xchar *rcd;
XFILE *dbfile;
Xchar *dbname;
X{
X char c, save[DBSIZE+1];
X long offset, ftell();
X char *strchr();
X int fn;
X struct Fdata *fp;
X struct Sdata *sp;
X char *first = "Record to be CHANGED";
X char *last = "RETURN for next, ESC to abort, Ctrl-C to Change, Ctrl-B to reverse";
X extern char lastchar;
X
X strcpy(save, rcd);
X *strchr(save, '\n') = '\0'; /* truncate \n */
X getfield(save, ":");
X for (sp = disp_screen; sp->S_title != 0; ++sp) {
X sp->S_dfault = getfield(NULL, ":");
X }
X screen(first, disp_screen, last, NULL, TRUE);
X noecho();
X c = lastchar;
X do {
X if (c == LF || c == CR)
X break;
X if (c == ETX) { /* CTL-C entered */
X offset = ftell(dbfile) - strlen(rcd);
X *strchr(rcd, '\n') = '\0'; /* truncate \n */
X if (doadd(dbname, fields, rcd, dbfile) == 0) {
X fseek(dbfile, offset, 0);
X putc('D', dbfile);
X }
X break;
X }
X if (c == ESC) {
X echo();
X return(1);
X }
X if (c == STX) { /* CTRL-B */
X echo();
X return(-1);
X }
X rawputchar(BEL);
X } while (c=rawgetchar());
X echo();
X return(0);
X}
X
Xdoadd(dbname, fields, rcd, filep)
Xchar *dbname;
Xstruct Fdata *fields;
Xchar *rcd;
XFILE *filep;
X{
X struct Sdata *sp;
X struct Fdata *fp;
X int err;
X char buffer[BUFSIZE+1];
X char outline[DBSIZE+1];
X long offset, ftell();
X
X fseek(filep, 0L, 2); /* end of file */
X fp = fields;
X getfield(rcd, ":"); /* step past flag */
X sp = disp_screen;
X while(fp->F_title[0]) {
X sp->S_dfault = getfield(0, ":");
X ++fp;
X ++sp;
X }
X outline[0] = '\0';
X while (screen("Enter changes", disp_screen, 0, 0, FALSE) > 0) {
X err = 0;
X fp = fields;
X sp = disp_screen;
X while(fp->F_title[0]) {
X if (sp->S_result[0] == '\0' && fp->F_required == 'Y') {
X sprintf(outline, "Required field %s missing", fp->F_title);
X msg(outline);
X err++;
X }
X if (strchr(sp->S_result, ':')) {
X msg("A : is not allowed in any field");
X ++err;
X }
X if (strlen(outline) + strlen(sp->S_result) >= DBSIZE) {
X msg("Record too long");
X ++err;
X break;
X }
X strcat(outline, sp->S_result);
X strcat(outline, ":");
X ++fp;
X ++sp;
X }
X if (err == 0)
X break;
X outline[0] = '\0';
X }
X if (err > 0 || outline[0] == '\0') {
X return(1);
X }
X outline[strlen(outline)-1] = '\0'; /* truncate trailing : */
X offset = ftell(filep);
X if (fprintf(filep, " :%s\n", outline) == EOF) {
X msg("Error writing DB file");
X getout();
X }
X buffer[0] = '\0';
X buildak(dbname, outline, offset, fields, buffer);
X writeak(dbname, buffer);
X return(0);
X}
SHAR_EOF
true || echo 'restore of change.c failed'
# ============= common.c ==============
echo 'x - extracting common.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'common.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)common.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
X#endif
X
X/* COMMON.C */
X#include "stdio.h"
X#include "ascii.h"
X#include "cardfile.h"
X#ifdef TERMCAP
X#define tparm(a, line, col) tgoto(a, col, line)
X#define putp(a) tputs(a, 12, mputc)
X#else /* TERMINFO */
X#include <curses.h>
X#include <term.h>
X#endif
X
X#ifdef TERMCAP
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
Xmsg(str) /* put a blinking message on the 23'th line of the crt */
Xchar *str;
X{
X putp(tparm(cursor_address, MSGLINE, 9));
X putp(clr_eol); /* erase line */
X if (str != NULL && *str != '\0') {
X putp(enter_blink_mode); /* blink */
X fputs(str, stdout);
X putp(exit_attribute_mode); /* back to normal */
X sleep(4);
X }
X}
X
X
Xchar *
Xgetfield(string, sepset) /* like strtok except contiguous seps */
Xchar *string, *sepset; /* result in a null field */
X{
X register char *p, *r;
X static char *savept;
X char *strpbrk();
X
X p = (string == NULL)? savept : string;
X if (p == 0)
X return(NULL);
X if (*p == '\0')
X return(NULL);
X if ((r = strpbrk(p, sepset)) == NULL) /* move past token */
X savept = 0; /* indicate this is the last token */
X else {
X *r = '\0';
X savept = ++r;
X }
X return(p);
X}
X
X
Xhelp(help_msg)
Xchar *help_msg;
X{
X putp(clear_screen); /* clear screen */
X puts("\n");
X fputs(help_msg, stdout);
X putp(tparm(cursor_address, MSGLINE, 9));
X fputs("Enter any character to continue.", stdout);
X rawgetchar();
X putp(clear_screen); /* clear screen */
X}
X
X
X#ifdef TERMCAP
Xmputc(c)
Xchar c;
X{
X putchar(c);
X}
X#endif
SHAR_EOF
true || echo 'restore of common.c failed'
# ============= compress.c ==============
echo 'x - extracting compress.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'compress.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)compress.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
X#endif
X
X/* COMPRESS.C */
X/* This function will remove all records with a flag
X** byte of 'D' from the data base. The alternate key
X** files MUST be rebuilt after it finishes.
X*/
X
X#include "stdio.h"
X#include "cardfile.h"
X
Xcompress(dbname)
Xchar *dbname;
X{
X FILE *in, *out;
X char fname[FNSIZE];
X char tempname[FNSIZE];
X char rcd[DBSIZE+1];
X
X sprintf(tempname, "%snewdb.$$$", datadir);
X if ((out = fopen(tempname, "w")) == NULL) {
X msg("Unable to create temporary file");
X getout();
X }
X sprintf(fname, "%s%s.db", datadir, dbname);
X if ((in = fopen(fname, "r")) == NULL) {
X unlink(tempname);
X msg("Unable to read DB file");
X getout();
X }
X while (fgets(rcd, DBSIZE, in) != NULL) {
X if (feof(in))
X break;
X if (*rcd == 'D') /* record to be deleted */
X continue;
X if(fputs(rcd, out) == EOF) {
X unlink(tempname);
X msg("Unable to write to temporary file");
X getout();
X }
X }
X fclose(in);
X fclose(out);
X unlink(fname);
X link(tempname, fname);
X unlink(tempname);
X}
SHAR_EOF
true || echo 'restore of compress.c failed'
# ============= define.c ==============
echo 'x - extracting define.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'define.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)define.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
X#endif
X
X/* DEFINE.C */
X/* This subroutine is used to define a new data-base.
X** It expects as input the base name (10 characters or less)
X** of all files.
X**
X** It will create the definition file - name.def
X** the primary file - name.db
X** and the alternate key files - name.akN
X*/
X
X#include "cardfile.h"
X#include "stdio.h"
X#include "ascii.h"
X#include <ctype.h>
X
X#define FNAME 0
X#define MAXL 1
X#define REQD 2
X#define SRCH 3
X#define SUBF 4
X#define PAGE 5
X#define LLINE 6
X#define LCOL 7
X#define DLINE 8
X#define DCOL 9
X#define FMT 10
X
Xstatic int page_def = 1;
Xstatic int lline_def = 2;
Xstatic int col_def = 4;
X
Xstatic char name_res[TSIZE+1];
Xstatic char mlen_res[3+1];
Xstatic char req_res[1+1];
Xstatic char skey_res[1+1];
Xstatic char sep_res[5+1];
Xstatic char page_res[1+1];
Xstatic char lline_res[2+1];
Xstatic char lcol_res[2+1];
Xstatic char dline_res[2+1];
Xstatic char dcol_res[2+1];
X#ifndef NO_RE
Xstatic char fmt_res[MAXFMT+1];
X#endif
X
Xstatic struct Sdata def_screen[] = {
X {"FIELD NAME", TSIZE, name_res, 0,
X -1, -1, -1, -1, -1, "^[^:]*$"},
X {"MAXIMUM LENGTH", 3, mlen_res, 0,
X -1, -1, -1, -1, -1, "^[0-9]*$"},
X {"REQUIRED?", 1, req_res, "N",
X -1, -1, -1, -1, -1, "[nyNY]"},
X {"SEARCH KEY", 1, skey_res, "Y",
X -1, 6, 35, -1, -1, "[nyNY]"},
X {"SUBFIELD SEPARATORS", 5, sep_res, 0,
X -1, -1, -1, -1, -1, "^[^:]$"},
X {"FIELD PAGE", 1, page_res, " ",
X -1, -1, -1, -1, -1, "^[-0-9]$"},
X {"LABEL LINE", 2, lline_res, " ",
X -1, -1, -1, -1, -1, "^[-0-9]$"},
X {"LABEL COLUMN", 2, lcol_res, " ",
X -1, 12, 35, -1, -1, "^[-0-9]$"},
X {"DATA FIELD LINE", 2, dline_res, " ",
X -1, -1, -1, -1, -1, "^[-0-9]$"},
X {"DATA FIELD COLUMN", 2, dcol_res, 0,
X -1, 14, 35, -1, -1, "^[-0-9]$"},
X#ifdef RE
X {"FORMAT", MAXFMT, fmt_res, 0,
X -1, -1, -1, -1, -1, ""},
X#endif
X {0, 0, 0, 0, -1, -1, -1, -1, -1, ""}
X };
X
Xstatic struct Fdata fields[MAXFLDS];
X
Xdb_define(basename)
Xchar *basename;
X{
X int i;
X char first[SWIDTH];
X char *last = "RETURN to exit";
X struct Fdata *fp;
X int num_fields, num_ak;
X char fname[FNSIZE];
X FILE *filep, *filep2;
X int err;
X int tsize;
X int opt_out;
X
X sprintf(first,"DEFINING %s DATA BASE", basename);
X if (access((*datadir ? datadir : "."), 06) != 0) {
X printf("Cannot write into %s\n", (*datadir ? datadir : "."));
X sleep(5);
X return(1);
X }
X
X /*
X * Read each field entered
X */
X num_fields = 0;
X fp = &fields[0];
X tsize = 0;
X sprintf(def_screen[PAGE].S_dfault, "%d", page_def);
X sprintf(def_screen[LLINE].S_dfault, "%d", lline_def);
X sprintf(def_screen[LCOL].S_dfault, "%d", col_def);
X sprintf(def_screen[DLINE].S_dfault, "%d", lline_def);
X while (screen(first, def_screen, last, 0, FALSE)) {
X err = 0;
X strcpy(fp->F_title, def_screen[FNAME].S_result);
X if (fp->F_title[0] == '\0') {
X msg("TITLE field must be specified");
X ++err;
X }
X if (strchr(fp->F_title, ':') != NULL) {
X msg("TITLE field must not include :");
X ++err;
X }
X
X fp->F_length = atoi(def_screen[MAXL].S_result);
X if (fp->F_length <= 0 || fp->F_length >= FLDLEN) {
X msg("LENGTH field must be less than 256");
X ++err;
X }
X if ((tsize += fp->F_length) > DBSIZE) {
X msg("Total record length too large");
X ++err;
X }
X
X#ifdef BSD_STRING
X if (islower(def_screen[REQD].S_result[0]))
X fp->F_required = toupper(def_screen[REQD].S_result[0]);
X#else
X fp->F_required = toupper(def_screen[REQD].S_result[0]);
X#endif
X if (fp->F_required != 'Y' && fp->F_required != 'N') {
X msg("REQUIRED must be Y or N");
X ++err;
X }
X
X#ifdef BSD_STRING
X if (islower(def_screen[SRCH].S_result[0]))
X fp->F_key = toupper(def_screen[SRCH].S_result[0]);
X#else
X fp->F_key = toupper(def_screen[SRCH].S_result[0]);
X#endif
X if (fp->F_key != 'Y' && fp->F_key != 'N') {
X msg("KEY must be Y or N");
X ++err;
X }
X
X strcpy(fp->F_seps, def_screen[SUBF].S_result);
X if (strchr(fp->F_seps, ':') != NULL) {
X msg("SEPARATORS must not include :");
X ++err;
X }
X
X#ifndef NO_RE
X strcpy(fp->F_Dfmt, def_screen[FMT].S_result);
X#else
X fp->F_Dfmt[0] = '\0';
X#endif
X
X fp->F_page = atoi(def_screen[PAGE].S_result);
X if (fp->F_page == 0) {
X fp->F_page = -1;
X }
X
X if (def_screen[LLINE].S_result[0] == '\0') {
X fp->F_Lrow = -1;
X } else {
X fp->F_Lrow = atoi(def_screen[LLINE].S_result);
X if (fp->F_Lrow < 2 || fp->F_Lrow >= MSGLINE) {
X msg("LABEL ROW field must be less than 22");
X ++err;
X }
X }
X
X if (def_screen[LCOL].S_result[0] == '\0') {
X fp->F_Lcol = -1;
X } else {
X fp->F_Lcol = atoi(def_screen[LCOL].S_result);
X if (fp->F_Lcol < 0 || fp->F_Lcol >= SWIDTH) {
X msg("LABEL COLUMN field must be less than 80");
X ++err;
X }
X }
X
X if (def_screen[DLINE].S_result[0] == '\0') {
X fp->F_Drow = -1;
X } else {
X fp->F_Drow = atoi(def_screen[DLINE].S_result);
X if (fp->F_Drow < 2 || fp->F_Drow >= MSGLINE) {
X msg("DATA ROW field must be less than 22");
X ++err;
X }
X }
X
X if (def_screen[DCOL].S_result[0] == '\0') {
X fp->F_Dcol = -1;
X } else {
X fp->F_Dcol = atoi(def_screen[DCOL].S_result);
X if (fp->F_Dcol < 0 || fp->F_Dcol >= SWIDTH) {
X msg("DATA COLUMN field must be less than 80");
X ++err;
X }
X }
X
X for (i=0; i<num_fields; i++) {
X if (strcmp(fields[i].F_title, fp->F_title) == 0) {
X msg("Field already defined");
X err++;
X break;
X }
X }
X if (err)
X continue;
X /*
X * Valid field, update defaults
X */
X lline_def = (fp->F_Lrow > fp->F_Drow ? fp->F_Lrow : fp->F_Drow) + 2;
X if (fp->F_Dcol == -1) {
X lline_def += ((fp->F_Lcol == -1 ? 4 : fp->F_Lcol) +
X strlen(fp->F_title) + (fp->F_length > 99 ? 7 : 6) +
X fp->F_length) / SWIDTH;
X } else {
X lline_def += (fp->F_Dcol + fp->F_length) / SWIDTH;
X }
X if (lline_def > SLENGTH - 4) {
X page_def++;
X lline_def = 2;
X }
X sprintf(def_screen[PAGE].S_dfault, "%d", page_def);
X sprintf(def_screen[LLINE].S_dfault, "%d", lline_def);
X sprintf(def_screen[LCOL].S_dfault, "%d", col_def);
X sprintf(def_screen[DLINE].S_dfault, "%d", lline_def);
X ++fp;
X if (++num_fields > MAXFLDS) {
X msg("Too many fields defined, aborting");
X return(1);
X }
X }
X#ifdef DEBUG
X fprintf(stderr, "%d fields in the %s database\n", num_fields, basename);
X for (i=0; i<num_fields; ++i) {
X fprintf(stderr, "%8d %s\n", i, fields[i].F_title);
X }
X#endif
X
X if (num_fields == 0) {
X msg("No fields defined, aborting");
X return(1);
X }
X sprintf(fname,"%s%s.def", datadir, basename);
X if ((filep = fopen(fname,"w")) == NULL) {
X msg("Unable to create DEF file");
X return(1);
X }
X sprintf(fname,"%s%s.db", datadir, basename);
X if ((filep2 = fopen(fname,"w")) == NULL) {
X msg("Unable to create DB file");
X sprintf(fname, "%s.def", basename);
X unlink(fname);
X return(1);
X }
X fclose(filep2);
X fprintf(filep, "%s:%d\n", fname, num_fields);
X num_ak = 0;
X for (i=0; i<num_fields; i++) {
X fp = &fields[i];
X if (fp->F_key == 'Y')
X fp->F_key = '0' + num_ak++;
X fprintf(filep, "%s:%c:%s:%c:%d\n", fp->F_title, fp->F_key,
X fp->F_seps, fp->F_required, fp->F_length);
X }
X if (num_ak == 0) {
X msg("At least 1 key field must be defined");
X unlink(fname); /* DB file */
X sprintf(fname, "%s.def", basename);
X unlink(fname);
X return(1);
X }
X fprintf(filep, "%d\n", num_ak);
X num_ak = 0;
X for (i=0; i<num_fields; i++) {
X fp = &fields[i];
X if (fp->F_key != 'N') { /* Alternate key file required */
X sprintf(fname,"%s%s.ak%d", datadir, basename, num_ak++);
X if ((filep2 = fopen(fname,"w")) == NULL) {
X msg("Unable to create AK file\n");
X sprintf(fname, "%s.def", basename);
X unlink(fname);
X return(1);
X }
X fclose(filep2);
X fprintf(filep, "%d:%s\n", i, fname);
X }
X }
X
X /*
X * Output optional fields if necessary (position and format)
X */
X for (i=0, opt_out=1, fp = &fields[0]; i<num_fields; i++, fp++) {
X if (fp->F_page == -1 && fp->F_Lrow == -1 && fp->F_Lcol == -1 &&
X fp->F_Drow == -1 && fp->F_Dcol == -1 && fp->F_Dfmt[0] == '\0') {
X continue;
X }
X if (opt_out) {
X fprintf(filep, "%%%%\n");
X opt_out = 0;
X }
X fprintf(filep, "%d:%d:%d:%d:%d:%d:%s\n", i, fp->F_page, fp->F_Lrow,
X fp->F_Lcol, fp->F_Drow, fp->F_Dcol, fp->F_Dfmt);
X }
X fclose(filep);
X return(0);
X}
SHAR_EOF
true || echo 'restore of define.c failed'
# ============= delete.c ==============
echo 'x - extracting delete.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'delete.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)delete.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
X#endif
X
X/* DELETE.C */
X/* This module is used to find and delete records
X** in the data base matching the selection criteria.
X** The user may select multiple values of one field
X** which will be or'd and/or multiple fields which will
X** be and'd. In other words, if field 1 is specified
X** as value1:value2 and field3 is specified as value3.
X** Records with field1==(value1 || value2) && field3==value3
X** will be selected for deletion.
X** It calls findrcds.c to do all the work.
X** It does not actually delete records, the flag(first)
X** field is set to 'D'. To physically delete them, the data
X** base must be compressed.
X*/
X
X#include "stdio.h"
X#include "ascii.h"
X#include "cardfile.h"
X
X
Xstatic struct Sdata disp_screen[MAXFLDS+1];
X
Xextern int readonly;
Xchar *malloc(), *getfield();
X
Xdelete(fields, dbname)
Xstruct Fdata fields[];
Xchar *dbname;
X{
X char first[SWIDTH];
X struct Fdata *fp;
X struct Sdata *sp;
X int processd();
X
X if (readonly) {
X msg("Database is readonly");
X return(1);
X }
X sprintf(first, "Select Records from the %s Data Base to be DELETED",
X dbname);
X for (fp = fields, sp = disp_screen ; fp->F_title[0] != 0; ++fp, ++sp) {
X sp->S_title = fp->F_title;
X sp->S_length = fp->F_length;
X sp->S_result = (char*)malloc((unsigned)fp->F_length+1);
X sp->S_page = fp->F_page;
X sp->S_Lrow = fp->F_Lrow;
X sp->S_Lcol = fp->F_Lcol;
X sp->S_Drow = fp->F_Drow;
X sp->S_Dcol = fp->F_Dcol;
X sp->S_Dfmt = fp->F_Dfmt;
X }
X sp->S_title = 0;
X
X findrcds(fields, dbname, processd, first);
X for (sp = disp_screen ; sp->S_title != 0; ++sp) {
X free(sp->S_result);
X }
X return(0);
X}
X
X
X/*ARGSUSED*/
Xprocessd(fields, rcd, dbfile, dummy)
Xstruct Fdata *fields;
Xchar *rcd;
XFILE *dbfile;
Xchar *dummy;
X{
X char c, save[DBSIZE+1];
X static char fmt[256];
X int fn;
X struct Fdata *fp;
X struct Sdata *sp;
X char *first = "Record to be DELETED";
X char *last = "RETURN for next, ESC to abort, CTL-D to DELETE, CTL-B to reverse";
X extern char lastchar;
X
X strcpy(save, rcd);
X *strchr(save, '\n') = '\0'; /* truncate \n */
X getfield(save, ":");
X for (sp = disp_screen; sp->S_title != 0; ++sp) {
X sp->S_dfault = getfield(NULL, ":");
X }
X screen(first, disp_screen, last, NULL, TRUE);
X noecho();
X c = lastchar;
X do {
X if (c == LF || c == CR)
X break;
X if (c == EOT) { /* CTL-D entered */
X fseek(dbfile, (long)(-strlen(rcd)), 1);
X putc('D', dbfile);
X break;
X }
X if (c == ESC) {
X echo();
X return(1);
X }
X if (c == STX) {
X echo();
X return(-1);
X }
X rawputchar(BEL);
X } while (c=rawgetchar());
X echo();
X return(0);
X}
SHAR_EOF
true || echo 'restore of delete.c failed'
# ============= dumpdb.c ==============
echo 'x - extracting dumpdb.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'dumpdb.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)dumpdb.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
X#endif
X
X/* DUMPDB.C */
X/* This subroutine is used to dump all records from
X the data base and the alternate key files, including
X deleted records.
X*/
X
X#include "stdio.h"
X#include "ascii.h"
X#include "cardfile.h"
X#include <signal.h>
X
Xstatic FILE *in, *out;
Xstatic int quit = 0;
Xstatic SIGRTN abort();
Xstatic SIGRTN (*old_sig)();
X
Xdumpdb(dbname, ak_data, fields)
Xchar *dbname;
Xstruct AKdata *ak_data;
Xstruct Fdata *fields;
X{
X char ptitle[PWIDTH+1];
X int pnum, lnum;
X char fname[FNSIZE];
X char rcd[DBSIZE+1];
X
X if ((out = popen("lp", "w")) == NULL) {
X msg("Unable to open printer");
X return(1);
X }
X sprintf(fname, "%s%s.db", datadir, dbname);
X if ((in = fopen(fname, "r")) == NULL) {
X pclose(out);
X msg("Unable to open DB file");
X return(1);
X }
X /* msg() will leave the cursor at the bottom */
X msg("");
X fputs("DEL to abort dump", stdout);
X old_sig = signal(SIGINT, abort);
X lnum = PLENGTH + 1; /* force top-of-page */
X pnum = 1;
X sprintf(ptitle, "Records in %s.db", dbname);
X while( !quit && (fgets(rcd, DBSIZE, in)) != NULL) { /* print DB file */
X rcd[strlen(rcd)-1] = '\0'; /* truncate \n */
X if (lnum + 3 + (strlen(rcd)+PWIDTH-1)/PWIDTH >= PLENGTH) {
X newpage(&pnum, ptitle);
X lnum = 3;
X }
X fputs(rcd, out);
X putc('\n', out);
X lnum += (strlen(rcd)+PWIDTH-1)/PWIDTH;
X }
X if (quit)
X return(1);
X fclose(in);
X while (ak_data->A_fldnum >= 0) {
X strcpy(fname, datadir);
X strcat(fname, ak_data->A_akname);
X if ((in = fopen(fname, "r")) == NULL) {
X sprintf(ptitle, "Unable to open %s", fname);
X msg(ptitle);
X return(1);
X }
X lnum = PLENGTH + 1;
X pnum = 1;
X sprintf(ptitle, "Records in %s sorted on %s",
X fname, fields[ak_data->A_fldnum].F_title);
X /* print AK file */
X while( !quit && (fgets(rcd, DBSIZE, in)) != NULL) {
X rcd[strlen(rcd)-1] = '\0'; /* truncate \n */
X if (lnum + 3 + (strlen(rcd)+PWIDTH-1)/PWIDTH >= PLENGTH) {
X newpage(&pnum, ptitle);
X lnum = 3;
X }
X fputs(rcd, out);
X putc('\n', out);
X lnum += (strlen(rcd)+PWIDTH-1)/PWIDTH;
X }
X if (quit)
X return(1);
X fclose(in);
X ++ak_data;
X }
X pclose(out);
X signal(SIGINT, old_sig);
X return(0);
X}
X
Xnewpage(pnum, title)
Xint *pnum;
Xchar *title;
X{
X
X putc(FF, out);
X fprintf(out, "%-69sPAGE %4d\n\n\n", title, *pnum);
X *pnum += 1;
X}
X
X
Xstatic SIGRTN
Xabort()
X{
X
X signal(SIGINT, old_sig);
X fputs("\n\nOUTPUT ABORTED!\n", out);
X pclose(out);
X fclose(in);
X msg("Dump aborted");
X quit = 1;
X}
SHAR_EOF
true || echo 'restore of dumpdb.c failed'
# ============= extract.c ==============
echo 'x - extracting extract.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'extract.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)extract.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
X#endif
X
X/* EXTRACT.C */
X/* This subroutine is used to write selected records from the
X * database on to another disk file.
X */
X
X#include "stdio.h"
X#include "cardfile.h"
X#include "ascii.h"
X
XFILE *ext_fp;
Xchar ext_fname[FNSIZE];
Xint rec_cnt;
Xstruct Sdata fn_screen[] = {
X {"File Name", FNSIZE, ext_fname, NULL},
X {0, 0, 0, 0}
X };
X
Xextract(fields, dbname)
Xstruct Fdata *fields;
Xchar *dbname;
X{
X char first[SWIDTH+1];
X int write_rcd();
X
X sprintf(first, "Select records from the %s Data Base to be extracted",
X dbname);
X screen(first, fn_screen, "Enter File Name of Extract File", NULL, FALSE);
X if (ext_fname[0] == '\0') {
X msg("No file name entered, using temp.ext");
X strcpy(ext_fname, "temp.ext");
X }
X if ((ext_fp = fopen(ext_fname, "w")) == NULL) {
X sprintf(first, "Unable to open file %s for output", ext_fname);
X msg(first);
X return(1);
X }
X rec_cnt = 0;
X findrcds(fields, dbname, write_rcd, first);
X fclose(ext_fp);
X sprintf(first, "%d records written to %s", rec_cnt, ext_fname);
X msg("");
X fputs(first, stdout); /* this works because msg() leaves the cursor */
X sleep(5);
X return(0);
X}
X
X
X/*ARGSUSED*/
Xint
Xwrite_rcd(dummy1, rcd, dummy2, dummy3)
Xchar *rcd;
Xchar *dummy1, *dummy2, *dummy3;
X{
X ++rec_cnt;
X return(fputs(rcd, ext_fp));
X}
SHAR_EOF
true || echo 'restore of extract.c failed'
# ============= find.c ==============
echo 'x - extracting find.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'find.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)find.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
X#endif
X
X/* FIND.C */
X/* This module is used to find and display records
X** in the data base matching the selection criteria.
X** The user may select multiple values of one field
X** which will be or'd and/or multiple fields which will
X** be and'd. In other words, if field 1 is specified
X** as value1:value2 and field3 is specified as value3.
X** Records with field1==(value1 || value2) && field3==value3
X** will be displayed.
X** It calls findrcds.c to do all the work.
X*/
X
X#include "stdio.h"
X#include "ascii.h"
X#include "cardfile.h"
X
Xstatic struct Sdata disp_screen[MAXFLDS+1];
X
Xfind(fields, dbname)
Xstruct Fdata *fields;
Xchar *dbname;
X{
X struct Fdata *fp;
X struct Sdata *sp;
X char first[SWIDTH];
X int display();
X
X sprintf(first, "Display Records from the %s Data Base", dbname);
X for (fp = fields, sp = disp_screen ; fp->F_title[0] != 0; ++fp, ++sp) {
X sp->S_title = fp->F_title;
X sp->S_length = fp->F_length;
X sp->S_result = (char*)malloc((unsigned)fp->F_length+1);
X sp->S_page = fp->F_page;
X sp->S_Lrow = fp->F_Lrow;
X sp->S_Lcol = fp->F_Lcol;
X sp->S_Drow = fp->F_Drow;
X sp->S_Dcol = fp->F_Dcol;
X sp->S_Dfmt = fp->F_Dfmt;
X }
X sp->S_title = 0;
X
X findrcds(fields, dbname, display, first);
X for (sp = disp_screen ; sp->S_title != 0; ++sp) {
X free(sp->S_result);
X }
X return(0);
X}
X
X
X/*ARGSUSED*/
Xdisplay(fields, rcd, dummy1, dummy2)
Xstruct Fdata *fields;
Xchar *rcd;
XFILE *dummy1;
Xchar *dummy2;
X{
X char c, save[DBSIZE+1];
X FILE *filep;
X char *first = "Selected Records";
X char *last = "RETURN for next, ESC to abort, CTL-P to print, CTL-B to reverse";
X static char fmt[256];
X struct Sdata *sp;
X char *getfield();
X extern char lastchar;
X
X strcpy(save, rcd);
X getfield(rcd, ":");
X for (sp = disp_screen; sp->S_title != 0; ++sp) {
X sp->S_dfault = getfield(NULL, ":");
X }
X screen(first, disp_screen, last, NULL, TRUE);
X noecho();
X c = lastchar;
X do {
X if (c == LF || c == CR)
X break;
X if (c == DLE) { /* CTL-P entered */
X if ((filep=popen("lp", "w")) == NULL) {
X msg("Unable to open printer");
X continue;
X }
X strcpy(rcd, save);
X putrcd(first, rcd, filep, fmt, PWIDTH, 1);
X pclose(filep);
X continue;
X }
X if (c == ESC) {
X echo();
X return(1);
X }
X if (c == STX) { /* CTL-B entered */
X echo();
X return(-1);
X }
X rawputchar(BEL);
X } while (c=rawgetchar());
X echo();
X return(0);
X}
SHAR_EOF
true || echo 'restore of find.c failed'
# ============= findrcds.c ==============
echo 'x - extracting findrcds.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'findrcds.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)findrcds.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
X#endif
X
X/* FINDRCDS.C */
X/* This module is used to find records in the data base
X** matching the selection criteria.
X** The user may select multiple values of one field
X** connected by '&' or '|' which will be or'd and/or
X** multiple fields which will be and'd.
X** In other words, if field 1 is specified
X** as value1|value2 and field3 is specified as value3.
X** Records with field1==(value1 || value2) && field3==value3
X** will be selected. An external routine 'display', passed
X** as a parameter will be called to process the selected records.
X*/
X
X#include <stdio.h>
X#include <errno.h>
X#include "ascii.h"
X#include "cardfile.h"
X
Xextern int readonly;
X
Xstruct Keys {
X char K_flag;
X long K_offset;
X};
X/*
X * Possible values of the K_flag field
X */
X#define GOOD 0 /* good record */
X#define MATCH 1 /* found on this search argument */
X#define END 32 /* physical end of key array */
X#define FREE 64 /* first free key block */
X
X
Xfindrcds(fields, dbname, display, first)
Xstruct Fdata *fields;
Xchar *dbname;
Xint (*display)();
Xchar *first;
X{
X struct Fdata *fp;
X struct Sdata find_screen[MAXFLDS+1], *sp;
X int found;
X FILE *filep;
X char filename[FNSIZE];
X diskptr offset;
X char *last =
X "Separate alternate values with a | for 'or' or a & for 'and'";
X int knum, firstflag;
X long getkey();
X char *keyval, *cp;
X char *rcd;
X char operator, nextop;
X char out_line[SWIDTH+1];
X struct Keys keys[MAXKEYS+1], *kp;
X int i;
X int rc;
X char *getslct(), *malloc();
X
X fp = fields;
X sp = find_screen;
X while (fp->F_title[0] != '\0') {
X if (fp->F_key == 'N') {
X ++fp;
X continue;
X }
X sp->S_title = fp->F_title;
X sp->S_length = 2 * fp->F_length;
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->S_result = malloc((unsigned)sp->S_length+1);
X sp->S_dfault = 0;
X ++fp;
X ++sp;
X }
X sp->S_title = 0;
X while (screen(first, find_screen, last, 0, FALSE) != 0) {
X firstflag = 1;
X knum = -1;
X keys[0].K_flag = FREE;
X for (i=1; i<MAXKEYS; ++i)
X keys[i].K_flag = GOOD;
X keys[MAXKEYS].K_flag = END;
X sp = find_screen;
X while (sp->S_title) { /* loop on key field */
X ++knum;
X if (*(sp->S_result) == '\0') { /* was key entered */
X ++sp;
X continue;
X }
X sprintf(filename, "%s%s.ak%d", datadir, dbname, knum);
X if ((filep = fopen(filename, "r")) == NULL) {
X msg("Unable to open alternate key file");
X getout();
X }
X operator = '&';
X if (firstflag) {
X firstflag = 0;
X operator = '|';
X }
X cp = sp->S_result;
X /* loop for each key for this field */
X while ((keyval = getslct(cp, "&|", &nextop)) != NULL) {
X cp = NULL;
X /* loop getting offsets for this value */
X while ((offset = getkey(filep, keyval)) >= 0L) {
X keyval = 0;
X if (operator == '|') {
X if (orkey(offset, keys) == -1)
X break;
X }
X if (operator == '&') {
X andkey(offset, keys);
X }
X }
X if (operator == '&') {
X purgekey(keys);
X }
X operator = nextop;
X }
X fclose(filep);
X ++sp;
X }
X sprintf(filename, "%s%s.db", datadir, dbname);
X if (readonly) {
X if ((filep = fopen(filename, "r")) == NULL) {
X sprintf(out_line, "Unable to open %s, errno=%d\n", filename, errno);
X msg(out_line);
X return(1);
X }
X } else {
X if ((filep = fopen(filename, "r+")) == NULL) {
X if (errno == EACCES) {
X strcpy(out_line, "You do not have permission to modify this database");
X } else {
X sprintf(out_line, "Unable to open %s, errno=%d\n", filename, errno);
X }
X msg(out_line);
X return(1);
X }
X }
X found = 0;
X rcd = malloc(DBSIZE);
X kp = keys;
X while (kp->K_flag == GOOD) {
X if (kp->K_offset <0L) {
X ++kp;
X continue;
X }
X fseek(filep, kp->K_offset, 0);
X if (fgets(rcd, DBSIZE, filep) == NULL) {
X msg("Error reading DB file");
X getout();
X }
X if (*rcd == 'D') {
X kp->K_offset = -1L;
X ++kp;
X continue;
X }
X ++found;
X if ((rc = (*display)(fields, rcd, filep, dbname)) == 1)
X break;
X if (rc == -1) { /* reverse */
X while (kp > &keys[0]) {
X --kp;
X if (kp->K_offset >= 0L)
X break;
X }
X } else {
X ++kp;
X }
X }
X fclose(filep);
X free(rcd);
X if (found == 0) {
X msg("No records found");
X }
X }
X sp = find_screen;
X while (sp->S_title) {
X free(sp->S_result);
X ++sp;
X }
X return(0);
X}
X
X
Xchar *
Xgetslct(string, seps, sepval) /* identical to getfld except separator is */
Xchar *string, *seps, *sepval; /* returned thru sepval */
X{
X register char *p, *r;
X static char *savept;
X
X p = (string == NULL)? savept : string;
X if (p == 0)
X return(NULL);
X if (*p == '\0')
X return(NULL);
X if ((r = strpbrk(p, seps)) == NULL) { /* move past token */
X *sepval = '\0';
X savept = 0; /* indicate this is the last token */
X } else {
X *sepval = *r;
X *r = '\0';
X savept = ++r;
X }
X return(p);
X}
X
X
Xorkey(offset, keys)
Xdiskptr offset;
Xstruct Keys *keys;
X{
X struct Keys *save;
X
X save = NULL;
X while (keys->K_flag == GOOD) {
X if (offset == keys->K_offset) {
X return(0);
X }
X if (keys->K_offset < 0L && save == NULL) {
X save = keys; /* found free point for insertion */
X }
X ++keys;
X }
X if (save == NULL) {
X if (keys->K_flag == END) {
X msg("Too many records selected");
X return(-1);
X }
X save = keys;
X if ((++keys)->K_flag != END)
X keys->K_flag = FREE;
X }
X save->K_flag = GOOD;
X save->K_offset = offset;
X return(0);
X}
X
Xandkey(offset, keys)
Xdiskptr offset;
Xstruct Keys *keys;
X{
X
X while(keys->K_flag < END) {
X if (offset == keys->K_offset) {
X keys->K_flag = MATCH;
X break;
X }
X ++keys;
X }
X}
X
X
Xpurgekey(keys)
Xstruct Keys *keys;
X{
X
X while(keys->K_flag < END) {
X if (keys->K_flag != MATCH) {
X keys->K_offset = -1L;
X } else {
X keys->K_flag = GOOD;
X }
X ++keys;
X }
X}
SHAR_EOF
true || echo 'restore of findrcds.c failed'
# ============= fmt_chk.c ==============
echo 'x - extracting fmt_chk.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'fmt_chk.c' &&
X#ifndef lint
Xstatic char Sccsid[] = "@(#)fmt_chk.c 3.1 DeltaDate 8/3/90 ExtrDate 10/6/90";
X#endif
X
X/*
X** FMT_CHK.C
X**
X** Return 0 if field matches fmt, 1 otherwise
X**
X**/
X
X#include <stdio.h>
X#include "cardfile.h"
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
X
Xint
Xfmt_chk(field, fmt)
Xchar *field, *fmt;
X{
X static char lastval[MAXFMT];
X#ifdef BSD_RE
X int rc;
X#endif
X#ifdef SYSV_RE
X char *rc;
X static char *cval;
X#endif
X#ifdef PD_RE
X int rc;
X static regexp *cval;
X#endif
X#ifdef NO_RE
X return(0);
X#endif
X
X if (fmt == NULL || *fmt == '\0')
X return(0);
X
X if (strcmp(fmt, lastval) != 0) {
X strcpy(lastval, fmt);
X#ifdef BSD_RE
X if (re_comp(fmt) != 0) {
X#else
X if (cval)
X free(cval);
X# ifdef SYSV_RE
X if ((cval = regcmp(fmt, 0)) == 0) {
X# else /* PD_RE */
X if ((cval = regcomp(fmt, 0)) == 0) {
X# endif
X#endif /* BSD_RE */
X msg("Invalid format specification");
X return(-1);
X }
X }
X
X#ifdef BSD_RE
X if ((rc = re_exec(field)) != 1) {
X return(1);
X }
X#endif
X#ifdef SYSV_RE
X if ((rc = regex(cval, field)) == NULL) {
X return(1);
X }
X#endif
X#ifdef PD_RE
X if ((rc = regexec(cval, field)) == NULL) {
X return(1);
X }
X#endif
X return(0);
X}
X
X#ifdef PD_RE
X/* Let cardfile handle errors */
Xvoid
Xregerror(msg)
Xchar *msg;
X{
X return;
X}
X#endif
SHAR_EOF
true || echo 'restore of fmt_chk.c failed'
true || echo 'restore of getkey.c failed'
echo End of part 1, continue with part 2
exit 0
More information about the Comp.sources.misc
mailing list