home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume15 / cardfile / part01 next >
Encoding:
Text File  |  1990-10-14  |  61.0 KB  |  2,397 lines

  1. Newsgroups: comp.sources.misc
  2. X-UNIX-From: dplace!pacbell!djl@PacBell.COM
  3. from: Dave Lampe <dplace!djl@PacBell.COM>
  4. subject: v15i049: cardfile - part 1 of 3
  5. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  6.  
  7. Posting-number: Volume 15, Issue 49
  8. Submitted-by: Dave Lampe <dplace!djl@PacBell.COM>
  9. Archive-name: cardfile/part01
  10.  
  11. ---- Cut Here and feed the following to sh ----
  12. #!/bin/sh
  13. # This is cardfile, a shell archive (produced by shar 3.49)
  14. # To extract the files from this archive, save it to a file, remove
  15. # everything above the "!/bin/sh" line above, and type "sh file_name".
  16. #
  17. # made 10/06/1990 19:30 UTC by djl@dplace
  18. # Source directory /usr/src/cmd/cardfile.d
  19. #
  20. # existing files WILL be overwritten
  21. # This format requires very little intelligence at unshar time.
  22. # "echo", "true", and "sed" may be needed.
  23. #
  24. # This shar contains:
  25. # length  mode       name
  26. # ------ ---------- ------------------------------------------
  27. #   1485 -rw-r--r-- README
  28. #   8576 -r--r--r-- cardfile.man
  29. #   4564 -r--r--r-- Makefile
  30. #   5422 -r--r--r-- cardfile.c
  31. #   2555 -r--r--r-- add.c
  32. #   4552 -r--r--r-- change.c
  33. #   1842 -r--r--r-- common.c
  34. #   1145 -r--r--r-- compress.c
  35. #   8363 -r--r--r-- define.c
  36. #   2755 -r--r--r-- delete.c
  37. #   2934 -r--r--r-- dumpdb.c
  38. #   1445 -r--r--r-- extract.c
  39. #   2549 -r--r--r-- find.c
  40. #   5897 -r--r--r-- findrcds.c
  41. #   1467 -r--r--r-- fmt_chk.c
  42. #    902 -r--r--r-- getkey.c
  43. #   3043 -r--r--r-- keymatch.c
  44. #   1387 -r--r--r-- maint.c
  45. #    930 -r--r--r-- menu.c
  46. #   5999 -r--r--r-- printdb.c
  47. #   5962 -r--r--r-- putrcd.c
  48. #    522 -r--r--r-- rawio.c
  49. #   1397 -r--r--r-- rbuildak.c
  50. #  16416 -r--r--r-- screen.c
  51. #  11302 -r--r--r-- setupkeys.c
  52. #   2834 -r--r--r-- updak.c
  53. #    975 -rw-r--r-- ascii.h
  54. #   2160 -rw-r--r-- cardfile.h
  55. #    252 -rw-r--r-- library.def
  56. #  29494 -rw-r--r-- library.db
  57. #   6271 -rw-r--r-- library.ak0
  58. #   3351 -rw-r--r-- library.ak1
  59. #   5248 -rw-r--r-- library.ak2
  60. #   7266 -rw-r--r-- library.ak3
  61. #
  62. # ============= README ==============
  63. echo 'x - extracting README (Text)'
  64. sed 's/^X//' << 'SHAR_EOF' > 'README' &&
  65. XThis program is a simple screen oriented database manager. It does have
  66. Xsome rudimentary file formatting and printing capabilities. I use it as a
  67. Xlibrary catalog. The metaphor is a stack of index cards with fields and
  68. Xsubfields on them. To explain subfields, think of a book with multiple
  69. Xauthors. Each author must be treated equally and there may be many authors.
  70. XIf you search for any book written by "John Smith" you want to find it
  71. Xwhether he is the only author or the fifteenth author.
  72. X
  73. XThere are parameters in the Makefile to configure it for System V, Sun OS,
  74. Xor BSD. I do not have access to a BSD system so the ioctl calls are from
  75. Xthe book. If you have problems and make changes to screen.c, please send 
  76. Xthe patches to me.
  77. X
  78. XSome of the source may look a little strange because I wrote it originally
  79. Xto run under CPM. I still have the CPM version if anyone wants it.
  80. X
  81. XOne thing that needs to be done yet.  The indexing needs to be converted
  82. Xfrom a sequential search to something faster such as a B tree. Even with
  83. Xa sequential search, the speed is acceptable on a database of about 500K.
  84. X
  85. XIncluded in the package is a piece of the catalog file for my library so
  86. Xthat you can get the feeling for what it does. After you make it,
  87. Xexecute "cardfile library" and then play.
  88. X
  89. XIf anyone finds any bugs (What? Bugs in MY code? :-) ), or makes any
  90. Ximprovements, please let me know.
  91. X
  92. XDave Lampe
  93. X{ames | lll-tis | sun | pyramid}!pacbell!dplace!djl
  94. X(415) 455-1571 (H)
  95. X(408) 986-9770 (W)
  96. SHAR_EOF
  97. true || echo 'restore of README failed'
  98. # ============= cardfile.man ==============
  99. echo 'x - extracting cardfile.man (Text)'
  100. sed 's/^X//' << 'SHAR_EOF' > 'cardfile.man' &&
  101. X.\ "@(#)cardfile.man    3.1 Delta Date 8/3/90  ExtrDate 10/6/90 ";
  102. X.if t .po 1i
  103. X.TH CARDFILE 1 djl
  104. X.SH NAME
  105. Xcardfile \- simple index card database
  106. X.SH SYNOPSIS
  107. X\fBcardfile [-r] file\fP
  108. X.SH DESCRIPTION
  109. X.I Cardfile
  110. Xis a simple screen oriented index card database program.
  111. XIf
  112. X.I file
  113. Xdoes not exist,
  114. X.I cardfile
  115. Xwill prompt for a definition of the fields to appear in each record.
  116. XEach field has:
  117. X.IP \(bu
  118. Xa name
  119. X.IP \(bu
  120. Xthe maximum length of the field
  121. X.IP \(bu
  122. Xa flag to determine if it is required or not
  123. X.IP \(bu
  124. Xa flag to determine if the field is indexed
  125. X(whether or not it can be searched for)
  126. X.IP \(bu
  127. Xif multiple values may appear in the field,
  128. Xwhat character will separate the values,
  129. Xfor example a book may have multiple authors separated by semicolons
  130. X.IP \(bu
  131. Xwhat screen page this field will appear on
  132. X.IP \(bu
  133. Xwhat position on the screen (line and column) the field title will appear in
  134. X.IP \(bu
  135. Xwhat position the field data will start in
  136. X#ifndef NO_RE
  137. X.IP \(bu
  138. Xa regular expression defining the
  139. Xrequired format of the data in the field.
  140. X#endif
  141. X.PP
  142. XThe position fields are not required and \fIcardfile\fP does
  143. Xnot check for overlap.
  144. XWhen all fields have been defined,
  145. Xreturn a blank screen and
  146. X.I cardfile
  147. Xwill create all necessary files and exit.
  148. XReenter
  149. X.I cardfile
  150. Xwith the same filename and you will be able to start adding the data.
  151. X.P
  152. XThe \fB-r\fP flag tells \fIcardfile\fP to open the database readonly.
  153. XYou must use this flag to retrieve data from a database on which
  154. Xyou do not have write permission.
  155. XWhen \fIcardfile\fP starts, the main menu is the first screen presented.
  156. XYou may use the cursor keys or the tab keys to move.
  157. XWhen the cursor is next to the option desired the return key
  158. Xwill select it.
  159. XThe options on the main menu are:
  160. X.SS Find
  161. XThe \fIFIND\fP option is used to retrieve data from the file.
  162. XYou will be presented with a screen containing all the fields flagged
  163. Xas index fields.
  164. XEnter the value for which you wish to search.
  165. X#ifdef NO_RE
  166. XIf the value is enclosed in quotes (\fB"\fP) it must match exactly.
  167. XOtherwise, case is ignored and asterisk (\fB*\fP) can be used at the
  168. Xend of a string to match anything,
  169. Xi.e. \fIFarmer*\fP will match "Farmer,P.J." or "farmer,philip",
  170. Xor "FARMER9999".
  171. X#else
  172. XIf the value is enclosed in quotes, case is significant,
  173. Xotherwise it is ignored.
  174. XIt is a real regular expression match, \fIlog\fP will match
  175. X"Archaeology", "Logistics" and "analog circuits" for example.
  176. XThe full regular expression syntax of ed is supported.
  177. X#endif
  178. XSearch values within a field may be connected by "\fB&\fP" for
  179. X\fBand\fP or "\fB|\fP" for \fBor\fP,
  180. Xi.e. if you enter "1986|1987" any record with a value of 1986
  181. Xor 1987 will be selected
  182. X("and" only makes sense if multiple values are allowed in the field).
  183. XIf values are entered in multiple fields, a record must satisfy
  184. Xboth criteria to be selected.
  185. X.P
  186. XWhen all values have been input,
  187. Xhit return and the database will be searched.
  188. XThe selected records will be displayed on the screen one at a time.
  189. XReturn will display the next record,
  190. XCtrl-B will move backwards through the list,
  191. Xand Esc will abort the display.
  192. X.if t .bp
  193. X.SS Add
  194. XThe \fIADD\fP option is used to add a new record to the database.
  195. XYou will be presented with a screen with all the fields defined
  196. Xon the record.
  197. XThe maximum size of each field will appear after the field name.
  198. XWhen all the data has been entered for a record,
  199. Xreturn will save the data and blank the fields.
  200. XThe data is not actually written to the file until
  201. Xyou leave the \fIadd\fP screen.
  202. XTo leave the \fIADD\fP screen simply return a blank screen.
  203. X.SS Change
  204. XThe \fICHANGE\fP option starts out like \fIFIND\fP but
  205. Xwhen the selected records are displayed,
  206. XCtrl-C will display an \fIADD\fP screen with the data from
  207. Xthe selected record as the initial value of each field.
  208. XChange the data as desired and then hit return to write the data
  209. Xand display the next selected record.
  210. X.SS Delete
  211. XThe \fIDELETE\fP option starts out like \fIFIND\fP but
  212. Xwhen the selected records are displayed,
  213. XCtrl-D will delete the record from the database.
  214. XThe record is not physically deleted from the file until
  215. X\fICOMPRESS\fP is run, the record is only marked and ignored.
  216. X.SS Print
  217. XThe \fIPRINT\fP option is used to format and print the database
  218. Xor a subset of the database.
  219. XThe first screen asks for the output format, the extracted file
  220. Xif any (see \fIExtract\fP on the \fIMaintenance\fP menu),
  221. Xthe output file, and the output width.
  222. X.if n .P
  223. XAny character in the output format will be printed as entered
  224. Xexcept for \fB%\fP sequences.
  225. XThe recognized sequences are:
  226. X.nf
  227. X.ta 0.5i,1.5i
  228. X    %N    The contents of field N
  229. X    %N(form)    The contents of field N in \fIprintf\fP(3) 
  230. X        "%form" format, i.e. "%1(%-20s)" will print
  231. X        field 1 left justified in a 20 character field.
  232. X    %n    Print a new-line.
  233. X    %t    Output a tab character.
  234. X    %f    Output a form feed.
  235. X    %t(NN)    Advance to column NN.
  236. X    %%    Print a %.
  237. X.fi
  238. XIf the extract name field is left blank, the entire database will be dumped.
  239. XThe output file may be an ordinary file,
  240. Xor it may be specified as "| \fIcommand\fP" in which case
  241. X\fIcommand\fP will be started and the print piped to it.
  242. XIf the output width is missing, it defaults to 80.
  243. X.SS Exit
  244. XThe \fIEXIT\fP option will return to UNIX.
  245. X.SS Maintenance
  246. XThe \fIMAINTENANCE\fP option will generate a submenu of infrequently used actions.
  247. XThe actions available from the maintenance menu are:
  248. X.br
  249. X.RS 0.25i
  250. X.B Dump
  251. X.br
  252. X.RS 0.25i
  253. XThe \fIDUMP\fP option of the maintenance menu
  254. Xis used to dump all records in the database and in the index files
  255. Xto the printer.
  256. XThe records are not formated, they are printed exactly as in the database.
  257. X.RE
  258. X.B Compress
  259. X.br
  260. X.RS 0.25i
  261. XThe \fICOMPRESS\fP option of the maintenance menu
  262. Xwill reclaim the space taken by records marked as deleted
  263. Xand then will rebuild the index files.
  264. XAfter \fICOMPRESS\fP has been run a record can no longer be recovered.
  265. X.RE
  266. X.B "Rebuild AK's"
  267. X.br
  268. X.RS 0.25i
  269. XThe \fIREBUILD AK's\fP option of the maintenance menu
  270. Xwill recreate the index files from the main database file.
  271. XThis is necessary if the main database has been changed by any means
  272. Xother than this program.
  273. X.RE
  274. X.B Extract
  275. X.br
  276. X.RS 0.25i
  277. XThe \fIEXTRACT\fP option of the maintenance menu
  278. Xis used to write selected records from the
  279. Xdatabase to another file.
  280. XYou are first asked for the name of the output file and then
  281. Xpresented with a screen like \fIFIND\fP to select the records to
  282. Xbe extracted.
  283. X.RE
  284. X.B Exit
  285. X.br
  286. X.RS 0.25i
  287. XThe \fIEXIT\fP option of the maintenance menu will return to the main menu.
  288. X.RE
  289. X.br
  290. X.SH "CONTROL KEYS"
  291. XThe keys used to control the screens are defined in \fItermcap\fP(4).
  292. X.sp
  293. X.nf
  294. X.ta 0.5i,1.5i,3i
  295. X    TERMCAP    UNIX-PC    ACTION
  296. X    CAP-NAME    KEY
  297. X.sp
  298. X    kcuf1    \(->    move right or to next field if at
  299. X            end of field
  300. X.if t .sp 0.5
  301. X    kcub1    \(<-    move left or to previous field if
  302. X            at start of field
  303. X.if t .sp 0.5
  304. X    kbs    Back    same as kcub1
  305. X        Space
  306. X.if t .sp 0.5
  307. X    ht    Tab    move to start of next field
  308. X.if t .sp 0.5
  309. X    kcud1    Down    same as ht
  310. X        Arrow
  311. X.if t .sp 0.5
  312. X    kcbt    shift-    move to start of this field or previous
  313. X        Tab    field if at start
  314. X.if t .sp 0.5
  315. X    kcuu1    Up    same as kcbt
  316. X        Arrow
  317. X.if t .sp 0.5
  318. X    kel    Clear    clear to end of field
  319. X        Line
  320. X.if t .sp 0.5
  321. X    kf4    Funct    same as kel
  322. X        Key 4
  323. X.if t .sp 0.5
  324. X    kdch1    Dlete    delete character under cursor
  325. X        Char
  326. X.if t .sp 0.5
  327. X    kf3    Funct    same as kdch1
  328. X        Key 3
  329. X.if t .sp 0.5
  330. X    kich1    Input    insert a blank under the cursor
  331. X        Mode
  332. X.if t .sp 0.5
  333. X    kf2    Funct    same as kich1
  334. X        Key 2
  335. X.if t .sp 0.5
  336. X    kf5    Funct    go to the next page of a multi-page form
  337. X        Key 5
  338. X.if t .sp 0.5
  339. X    kf6    Funct    go to the previous page of a multi-page form
  340. X        Key 6
  341. X.fi
  342. X.SH FILES
  343. X.ta 1.5i
  344. X\fIfile\fP.def    The file of field and file definitions
  345. X.br
  346. X\fIfile\fP.db    The database records
  347. X.br
  348. X\fIfile\fP.ak\fBN\fP    The index files for searches
  349. X.SH NOTE
  350. XNo field may contain a colon "\fB:\fP" as it is used as a field
  351. Xseparator in the database.
  352. X.if t .sp 0.5v
  353. X.if n .br
  354. XThe maximum size of a field is 255 characters
  355. Xand of the total record is 1024 characters.
  356. XThe maximum number of fields in a record is 15.
  357. XThese are arbitrary numbers and are easy to change at compile time.
  358. X.if t .sp 0.5v
  359. X.if n .br
  360. XAt least one field must be defined as an index field.
  361. X.if t .sp 0.5v
  362. X.if n .br
  363. XThe regular expressions used as formats and search fields are those supported
  364. Xby the library functions.
  365. XRemember that if a field is supposed to be numeric,
  366. X\&'[0-9]*' will not work, '^[0-9]*$' is necessary.
  367. X.if t .sp 0.5v
  368. X.if n .br
  369. XThe termcap name
  370. X.I kcbt
  371. Xmay not be defined in some versions of UNIX.
  372. XJust use the up arrow instead.
  373. X.if t .sp 0.5v
  374. X.if n .br
  375. XThere is no concurrency control in \fIcardfile\fP.
  376. SHAR_EOF
  377. true || echo 'restore of cardfile.man failed'
  378. # ============= Makefile ==============
  379. echo 'x - extracting Makefile (Text)'
  380. sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
  381. X# @(#)Makefile    3.2  DeltaDate 8/11/90   ExtrDate 10/6/90
  382. X
  383. X# Variables to define your environment:
  384. X#   Define what kind of regular expression routines you have
  385. X#    BSD_RE        use re_comp()/re_exec()
  386. X#    SYSV_RE        use recmp()/regex()
  387. X#    PD_RE        use Henry Spencer's public domain routines
  388. X#            regcomp()/regexec()
  389. X#    NO_RE        no regular expressions
  390. X#
  391. X#   Define what flavor of curses you have
  392. X#    TERMCAP        use the original (BSD) curses
  393. X#    TERMINFO    use the SYSV rewrite of curses
  394. X#
  395. X#   Define what tty driver you have
  396. X#    SYSV_TTY
  397. X#    BSD_TTY
  398. X#
  399. X#   Define which string library you have
  400. X#    BSD_STRING    unprotected tolower(), index()
  401. X#    SYSV_STRING    safe tolower(), strchr()
  402. X#
  403. X#   Define which signal library you have
  404. X#    BSD_SIG        system calls are continued after interrupt
  405. X#    SYSV_SIG    system call returns error if interrupted
  406. X#
  407. X# Pick one from each of the five lists above.
  408. X#
  409. X# SIGRTN defines the return type of the signal functions, normally
  410. X#    an integer prior to SysV.3, void in SysV.3 and after
  411. X# DEBUG defines the level of debug output, normally not defined
  412. X
  413. X# These are for compiling on the Sun 4.0
  414. X#CC    =    cc
  415. X#CCP    =    ccp
  416. X#LINT    =    lint
  417. X#DEFINES =    -DTERMCAP -DBSD_RE -DBSD_STRING -DSYSV_TTY -DSIGRTN=void -DBSD_SIG
  418. X#CC    =    /usr/5bin/cc
  419. X#CCP    =    /usr/5bin/ccp
  420. X#LINT    =    /usr/5bin/lint
  421. X#DEFINES =    -DTERMINFO -DBSD_RE -DBSD_STRING -DSYSV_TTY -DSIGRTN=void -DSYSV_SIG
  422. X
  423. X# These are for System V
  424. XCC    =    cc
  425. XCPP    =    /lib/cpp
  426. XLINT    =    lint
  427. XDEFINES    =    -DTERMINFO -DSYSV_RE -DSYSV_STRING -DSYSV_TTY -DSIGRTN=int -DSYSV_SIG
  428. X
  429. X
  430. X# The PW library is where the regular expression subroutines regcmp, and
  431. X#    regex are kept. If you use -DNO_RE or if your libraries are
  432. X#    different change it.
  433. XLIBS    =    -lPW -lcurses
  434. X#LIBS    =    -lcurses -ltermcap
  435. X
  436. XBINDIR    =    /usr/local/bin/
  437. XMANDIR    =    /usr/man/man1/
  438. X
  439. X#CFLAGS    =    -g -DDEBUG $(DEFINES)
  440. XCFLAGS    =    -g $(DEFINES)
  441. X
  442. X#
  443. X# Nothing past here should need changing
  444. X#
  445. X
  446. X.SUFFIXES:    .1 .1~ .man .man~
  447. X.c~.c:
  448. X        $(GET) $(GFLAGS) $<
  449. X
  450. X.man~.man:
  451. X        $(GET) $(GFLAGS) $<
  452. X
  453. X
  454. XSHAR    =    shar
  455. XSHARFLAGS =    -c -V -l62 -n cardfile -a -x -o cardfile
  456. X
  457. XDOC    =    cardfile.1
  458. XDOCS    =    cardfile.man
  459. X
  460. XHDRS    =    ascii.h cardfile.h
  461. X
  462. XSRC    =    \
  463. X        cardfile.c \
  464. X        add.c \
  465. X        change.c \
  466. X        common.c \
  467. X        compress.c \
  468. X        define.c \
  469. X        delete.c \
  470. X        dumpdb.c \
  471. X        extract.c \
  472. X        find.c \
  473. X        findrcds.c \
  474. X        fmt_chk.c \
  475. X        getkey.c \
  476. X        keymatch.c \
  477. X        maint.c \
  478. X        menu.c \
  479. X        printdb.c \
  480. X        putrcd.c \
  481. X        rawio.c \
  482. X        rbuildak.c \
  483. X        screen.c \
  484. X        setupkeys.c \
  485. X        updak.c \
  486. X        $(NULL)
  487. X
  488. XOBJ    =    \
  489. X        cardfile.o \
  490. X        add.o \
  491. X        change.o \
  492. X        common.o \
  493. X        compress.o \
  494. X        define.o \
  495. X        delete.o \
  496. X        dumpdb.o \
  497. X        extract.o \
  498. X        find.o \
  499. X        findrcds.o \
  500. X        fmt_chk.o \
  501. X        getkey.o \
  502. X        keymatch.o \
  503. X        maint.o \
  504. X        menu.o \
  505. X        printdb.o \
  506. X        putrcd.o \
  507. X        rawio.o \
  508. X        rbuildak.o \
  509. X        screen.o \
  510. X        setupkeys.o \
  511. X        updak.o \
  512. X        $(NULL)
  513. X
  514. XTESTDB    =    \
  515. X        library.def \
  516. X        library.db \
  517. X        library.ak0 \
  518. X        library.ak1 \
  519. X        library.ak2 \
  520. X        library.ak3 \
  521. X        $(NULL)
  522. X
  523. X###############################################################################
  524. X#
  525. X#    Make targets
  526. X#
  527. X###############################################################################
  528. X
  529. Xall:        cardfile cardfile.1
  530. X
  531. Xcardfile:    $(OBJ)
  532. X        $(CC) -o cardfile $(OBJ) $(LIBS)
  533. X
  534. Xinstall:    all
  535. X        cp cardfile $(BINDIR)cardfile
  536. X        strip $(BINDIR)cardfile
  537. X        cp cardfile.1 $(MANDIR)cardfile.1
  538. X
  539. Xclean:
  540. X        rm -f *.o cardfile cardfile.1
  541. X        for f in $(DOCS) $(SRC) $(HDRS) Makefile ; \
  542. X        do \
  543. X            if [ -f $$f -a -f s.$$f -a ! -f p.$$f ] ; \
  544. X            then \
  545. X                rm -f $$f ; \
  546. X            fi ; \
  547. X        done
  548. X
  549. X
  550. Xprint:        prt_src prt_docs
  551. X
  552. Xprt_src:    $(HDRS) $(SRC) Makefile
  553. X        cpr -w96 -l88 $(HDRS) $(SRC) Makefile |  \
  554. X        lp -o-v8 -o-t -o-h12
  555. X
  556. Xprt_docs:    $(DOC)
  557. X        nroff -man cardfile.1 | lp -o-qc
  558. X
  559. Xcardfile.1:    cardfile.man
  560. X        $(CPP) -C -P cardfile.man | sed -e '/^$$/d' >cardfile.1
  561. X
  562. Xshar:        $(HDRS) $(SRC) $(DOCS) Makefile $(TESTDB)
  563. X        $(SHAR) $(SHARFLAGS) README $(DOCS) Makefile \
  564. X            $(SRC) $(HDRS) $(TESTDB)
  565. X
  566. Xlint:        $(HDRS) $(SRC)
  567. X        $(LINT) $(DEFINES) $(SRC)
  568. X
  569. X###############################################################################
  570. X#
  571. X#    Object dependencies
  572. X#
  573. X###############################################################################
  574. X
  575. Xadd.o:        cardfile.h ascii.h
  576. Xcardfile.o:    cardfile.h ascii.h
  577. Xchange.o:    cardfile.h ascii.h
  578. Xcommon.o:    cardfile.h ascii.h
  579. Xcompress.o:    cardfile.h
  580. Xdefine.o:    cardfile.h ascii.h
  581. Xdelete.o:    cardfile.h ascii.h
  582. Xdumpdb.o:    cardfile.h ascii.h
  583. Xextract.o:    cardfile.h ascii.h
  584. Xfind.o:        cardfile.h ascii.h
  585. Xfindrcds.o:    cardfile.h ascii.h
  586. Xgetkey.o:    cardfile.h
  587. Xkeymatch.o:    cardfile.h
  588. Xmaint.o:    cardfile.h
  589. Xmenu.o:        cardfile.h
  590. Xprintdb.o:    cardfile.h ascii.h
  591. Xputrcd.o:    cardfile.h
  592. Xrbuildak.o:    cardfile.h
  593. Xscreen.o:    cardfile.h ascii.h
  594. Xsetupkeys.o:    cardfile.h ascii.h
  595. Xupdak.o:    cardfile.h ascii.h
  596. SHAR_EOF
  597. true || echo 'restore of Makefile failed'
  598. # ============= cardfile.c ==============
  599. echo 'x - extracting cardfile.c (Text)'
  600. sed 's/^X//' << 'SHAR_EOF' > 'cardfile.c' &&
  601. X#ifndef lint
  602. Xstatic char Sccsid[] = "@(#)cardfile.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  603. X#endif
  604. X
  605. X/*      CARDFILE.C      */
  606. X/*      This is the main routine for cardfile
  607. X*/
  608. X#include    "ascii.h"
  609. X#include    "stdio.h"
  610. X#include    "cardfile.h"
  611. X#include    <signal.h>
  612. X
  613. X#define FIND    0
  614. X#define ADD     1
  615. X#define CHANGE  2
  616. X#define DELETE  3
  617. X#define PRINT   4
  618. X#define MAINT   5
  619. X#define EXIT    6
  620. X
  621. XFILE    *def_fp;
  622. Xint    readonly;
  623. Xchar    fname[FNSIZE];
  624. Xextern  char *getfield();
  625. Xchar    *functs[]    = {"FIND       ",
  626. X            "ADD        ",
  627. X            "CHANGE     ",
  628. X            "DELETE     ",
  629. X            "PRINT      ",
  630. X            "MAINTENANCE",
  631. X            "EXIT       ",
  632. X            0
  633. X            };
  634. X
  635. Xchar    datadir[FNSIZE];
  636. Xchar    *dbname;
  637. Xvoid    setupscr();
  638. Xvoid    exit();
  639. Xunsigned sleep();
  640. Xstatic    usage();
  641. X
  642. Xmain(argc, argv)
  643. Xint     argc;
  644. Xchar    **argv;
  645. X{
  646. X    int     num_flds, i;
  647. X    char    line_buf[133];
  648. X    struct      Fdata fields[MAXFLDS+1], *fp;
  649. X    int     num_ak;
  650. X    struct      AKdata ak_data[MAXAK+1];
  651. X    int        fn;
  652. X    int     func;
  653. X    char    *cp;
  654. X    extern char *optarg;
  655. X    extern int optind, opterr;
  656. X    
  657. X    opterr = 0;
  658. X    while ((i = getopt(argc, argv, "r")) != EOF) {
  659. X    switch (i) {
  660. X    case 'r':
  661. X        ++readonly;
  662. X        break;
  663. X    case '?':
  664. X        usage(argv[0]);
  665. X        exit(1);
  666. X    }
  667. X    }
  668. X    if (optind != argc-1) {
  669. X    usage(argv[0]);
  670. X    exit(1);
  671. X    }
  672. X    signal(SIGINT, getout);
  673. X    signal(SIGQUIT, getout);
  674. X    signal(SIGTERM, getout);
  675. X    setupscr();        /* from here on use getout, not exit to reset screen */
  676. X    if ((cp = strrchr(argv[optind], '/')) != NULL) {
  677. X    *cp = '\0';
  678. X    sprintf(datadir, "%s/", argv[optind]);
  679. X    dbname = cp + 1;
  680. X    } else {
  681. X    *datadir = '\0';
  682. X    dbname = argv[optind];
  683. X    }
  684. X    if (strlen(dbname) > 10) {
  685. X    printf("Database name cannot be longer than 10 characters.\n");
  686. X    sleep(5);
  687. X    getout();
  688. X    }
  689. X    /* build definition file name */
  690. X    sprintf(fname, "%s%s.def", datadir, dbname);
  691. X    if ((def_fp = fopen(fname,"r")) == NULL) {
  692. X    db_define(dbname);
  693. X    getout();
  694. X    }
  695. X    /* The format of the definition file is:
  696. X     * Num_of_fields
  697. X     * Field1_Name:Key:Sub_Seps:Req:Data_Len
  698. X     * ...
  699. X     * Num_of_Alt_Keys
  700. X     * Field_Num:AK1_File_Name
  701. X     * ...
  702. X     * %%
  703. X     * Field_Num:Label_Row:Label_Col:Data_Row:Data_Col:Data_Fmt
  704. X     * ...
  705. X     */
  706. X    if (fgets(line_buf, 132, def_fp) == NULL) {
  707. X    printf("Unable to read DEF file\n");
  708. X    sleep(5);
  709. X    getout();
  710. X    }
  711. X    if (! readonly && access(fname, 06) != 0) {
  712. X    printf("You can not write to the database, try\n%s -r %s%s\n",
  713. X        argv[0], datadir, dbname);
  714. X    sleep(5);
  715. X    getout();
  716. X    }
  717. X    strcpy(fname, getfield(line_buf, ":"));
  718. X    num_flds = atoi(getfield(0, ":"));
  719. X
  720. X    for (i=0, fp=&fields[0]; i<num_flds; i++, fp++) {    /* get definition of each field */
  721. X    if (fgets(line_buf, 132, def_fp) == NULL) {
  722. X        printf("DEF file syntax error, field defs\n");
  723. X        sleep(5);
  724. X        getout();
  725. X    }
  726. X    strcpy(fp->F_title, getfield(line_buf, ":"));
  727. X    fp->F_key = *getfield(0, ":");
  728. X    strcpy(fp->F_seps, getfield(0, ":"));
  729. X    fp->F_required = *getfield(0, ":");
  730. X    fp->F_length = atoi(getfield(0, ":"));
  731. X    /* set defaults */
  732. X    fp->F_page = -1;
  733. X    fp->F_Lrow = -1;
  734. X    fp->F_Lcol = -1;
  735. X    fp->F_Drow = -1;
  736. X    fp->F_Dcol = -1;
  737. X    fp->F_Dfmt[0] = '\0';
  738. X    }
  739. X    fp->F_title[0] = '\0';
  740. X
  741. X    fgets(line_buf, 10, def_fp);
  742. X    num_ak = atoi(line_buf);
  743. X    for (i=0; i<num_ak; i++) {          /* get definition of each AK file */
  744. X    if (fgets(line_buf, 132, def_fp) == NULL) {
  745. X        printf("DEF file syntax error, AK files\n");
  746. X        sleep(5);
  747. X        getout();
  748. X    }
  749. X    line_buf[strlen(line_buf)-1] = '\0';    /* truncate newline */
  750. X    ak_data[i].A_fldnum = atoi(getfield(line_buf, ":"));
  751. X    strcpy(ak_data[i].A_akname, getfield(0, ":"));
  752. X    }
  753. X    ak_data[i].A_fldnum = -1;
  754. X
  755. X    fgets(line_buf, 10, def_fp);
  756. X    if (strcmp(line_buf, "%%\n") == 0) {
  757. X    for (i=0; i<num_flds; i++) {    /* Get screen layout for each field */
  758. X        if (fgets(line_buf, 132, def_fp) == NULL) {
  759. X        break;
  760. X        }
  761. X        line_buf[strlen(line_buf)-1] = '\0';    /* truncate newline */
  762. X        fn = atoi(getfield(line_buf, ":"));
  763. X        if (fn < 0 || fn >= num_flds) {
  764. X        printf("DEF file syntax error, screen layout\n");
  765. X        sleep(5);
  766. X        getout();
  767. X        }
  768. X        if ((cp = getfield(0, ":")) != NULL && *cp != '\0')
  769. X        fields[fn].F_page = atoi(cp);
  770. X        if ((cp = getfield(0, ":")) != NULL && *cp != '\0')
  771. X        fields[fn].F_Lrow = atoi(cp);
  772. X        if ((cp = getfield(0, ":")) != NULL && *cp != '\0')
  773. X        fields[fn].F_Lcol = atoi(cp);
  774. X        if ((cp = getfield(0, ":")) != NULL && *cp != '\0')
  775. X        fields[fn].F_Drow = atoi(cp);
  776. X        if ((cp = getfield(0, ":")) != NULL && *cp != '\0')
  777. X        fields[fn].F_Dcol = atoi(cp);
  778. X        if ((cp = getfield(0, ":")) != NULL) {
  779. X        strcpy(fields[fn].F_Dfmt, cp);
  780. X        }
  781. X    }
  782. X    }
  783. X    fclose(def_fp);
  784. X#ifdef DEBUG
  785. X    fprintf(stderr, "%d fields in the %s database\n", num_flds, dbname);
  786. X    for (i=0; i<num_flds; ++i) {
  787. X    fprintf(stderr, "%8d  %s\n", i, fields[i].F_title);
  788. X    }
  789. X#endif
  790. X    
  791. X    /* get function to be performed */
  792. X    while ((func = menu(dbname, functs)) != EXIT) {
  793. X    switch (func) {
  794. X    case FIND:
  795. X        find(fields, dbname);
  796. X        continue;
  797. X    case ADD:
  798. X        add(fields, dbname);
  799. X        continue;
  800. X    case CHANGE:
  801. X        change(fields, dbname);
  802. X        continue;
  803. X    case DELETE:
  804. X        delete(fields, dbname);
  805. X        continue;
  806. X    case PRINT:
  807. X        printdb(fields, dbname);
  808. X        continue;
  809. X    case MAINT:
  810. X        maint(fields, dbname, ak_data);
  811. X        continue;
  812. X    default:
  813. X        msg("Illegal function chosen");
  814. X        getout();
  815. X    }
  816. X    }
  817. X    getout();
  818. X/*NOTREACHED*/
  819. X}
  820. X
  821. X
  822. Xstatic
  823. Xusage(prog)
  824. Xchar    *prog;
  825. X{
  826. X    printf("Usage: %s [-r] file\n", prog);
  827. X}
  828. SHAR_EOF
  829. true || echo 'restore of cardfile.c failed'
  830. # ============= add.c ==============
  831. echo 'x - extracting add.c (Text)'
  832. sed 's/^X//' << 'SHAR_EOF' > 'add.c' &&
  833. X#ifndef lint
  834. Xstatic char Sccsid[] = "@(#)add.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  835. X#endif
  836. X
  837. X/*      ADD.C   */
  838. X/*      This subroutine is used to add a new record to the
  839. X**    data base. It also requests the updating of the
  840. X**    alternate key files.
  841. X*/
  842. X
  843. X#include <stdio.h>
  844. X#include <errno.h>
  845. X#include "ascii.h"
  846. X#include "cardfile.h"
  847. X
  848. Xlong    ftell();
  849. Xchar    *malloc();
  850. Xextern  int     errno;
  851. Xextern    int    readonly;
  852. X
  853. Xadd(fields, dbname)
  854. Xstruct  Fdata   fields[];
  855. Xchar    *dbname;
  856. X{
  857. X    struct      Fdata   *fp;
  858. X    struct      Sdata   add_screen[MAXFLDS+1], *sp;
  859. X    int     err;
  860. X    char    first[SWIDTH+1];
  861. X    char    out_line[DBSIZE+1];
  862. X    FILE    *filep;
  863. X    char    filename[FNSIZE];
  864. X    long    offset;
  865. X    char    *buffer;
  866. X    
  867. X    if (readonly) {
  868. X    msg("Database is readonly");
  869. X    return(1);
  870. X    }
  871. X    sprintf(first, "Add Records to %s Data Base", dbname);
  872. X    buffer = malloc(BUFSIZE+1);
  873. X    buffer[0] = '\0';
  874. X    sprintf(filename, "%s%s.db", datadir, dbname);
  875. X    if((filep = fopen(filename, "a")) == NULL) {
  876. X    if (errno == EACCES) {
  877. X        strcpy(out_line, "You do not have permission to modify this database");
  878. X    } else {
  879. X        sprintf(out_line, "Unable to open %s, errno=%d\n", filename, errno);
  880. X    }
  881. X    msg(out_line);
  882. X    return(1);
  883. X    }
  884. X    for (fp = fields, sp = add_screen ; fp->F_title[0] != 0; ++fp, ++sp) {
  885. X    sp->S_title = fp->F_title;
  886. X    sp->S_length = fp->F_length;
  887. X    sp->S_result = malloc((unsigned)fp->F_length+1);
  888. X    sp->S_dfault = 0;
  889. X    sp->S_page = fp->F_page;
  890. X    sp->S_Lrow = fp->F_Lrow;
  891. X    sp->S_Lcol = fp->F_Lcol;
  892. X    sp->S_Drow = fp->F_Drow;
  893. X    sp->S_Dcol = fp->F_Dcol;
  894. X    sp->S_Dfmt = fp->F_Dfmt;
  895. X    }
  896. X    sp->S_title = 0;
  897. X    while (screen(first, add_screen, 0, 0, FALSE) != 0) {
  898. X    out_line[0] = '\0';
  899. X    err = 0;
  900. X    fp = fields;
  901. X    sp = add_screen;
  902. X    while (sp->S_title) {
  903. X        if (sp->S_result[0] == '\0' && fp->F_required == 'Y') {
  904. X        sprintf(out_line, "Required field %s missing", fp->F_title);
  905. X        msg(out_line);
  906. X        ++err;
  907. X        }
  908. X        if (strchr(sp->S_result, ':')) {
  909. X        msg("A ':' is not allowed in any field");
  910. X        ++err;
  911. X        }
  912. X        if (strlen(out_line) + strlen(sp->S_result) >= DBSIZE) {
  913. X        msg("Record too long");
  914. X        ++err;
  915. X        break;
  916. X        }
  917. X        strcat(out_line, sp->S_result);
  918. X        strcat(out_line, ":");
  919. X        ++fp;
  920. X        ++sp;
  921. X    }
  922. X    if (err)
  923. X        continue;
  924. X    out_line[strlen(out_line)-1] = '\0';
  925. X    offset = ftell(filep);
  926. X    fprintf(filep, " :%s\n", out_line);
  927. X    buildak(dbname, out_line, offset, fields, buffer);
  928. X    }
  929. X    sp = add_screen;
  930. X    while (sp->S_title) {
  931. X    free(sp->S_result);
  932. X    ++sp;
  933. X    }
  934. X    fclose(filep);
  935. X    writeak(dbname, buffer);
  936. X    free(buffer); 
  937. X    return(0);
  938. X}
  939. SHAR_EOF
  940. true || echo 'restore of add.c failed'
  941. # ============= change.c ==============
  942. echo 'x - extracting change.c (Text)'
  943. sed 's/^X//' << 'SHAR_EOF' > 'change.c' &&
  944. X#ifndef lint
  945. Xstatic char Sccsid[] = "@(#)change.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  946. X#endif
  947. X
  948. X/*      CHANGE.C        */
  949. X/*      This module is used to find and change records
  950. X**    in the data base matching the selection criteria.
  951. X**    The user may select multiple values of one field
  952. X**    which will be or'd and/or multiple fields which will
  953. X**    be and'd. In other words, if field 1 is specified
  954. X**    as value1:value2 and field3 is specified as value3.
  955. X**    Records with field1==(value1 || value2) && field3==value3
  956. X**    will be selected for changing.
  957. X**    It calls findrcds.c to do all the work of finding them.
  958. X**    It does not actually change records, the flag(first)
  959. X**    field is set to 'D' in the current record and a new
  960. X**    record is added. To physically delete the old record,
  961. X**    the data base must be compressed.
  962. X*/
  963. X
  964. X#include <stdio.h>
  965. X#include <errno.h>
  966. X#include "ascii.h"
  967. X#include "cardfile.h"
  968. X
  969. Xchar    *malloc(), *getfield();
  970. Xextern    int    readonly;
  971. X
  972. X
  973. Xstatic struct Sdata disp_screen[MAXFLDS+1];
  974. X
  975. Xchange(fields, dbname)
  976. Xstruct  Fdata   fields[];
  977. Xchar    *dbname;
  978. X{
  979. X    char    first[SWIDTH];
  980. X    struct Fdata *fp;
  981. X    struct Sdata *sp;
  982. X    int     processc();
  983. X
  984. X    if (readonly) {
  985. X    msg("Database is readonly");
  986. X    return(1);
  987. X    }
  988. X    sprintf(first, "Select Records from the %s Data Base to be Changed",
  989. X    dbname);
  990. X    for (fp = fields, sp = disp_screen ; fp->F_title[0] != 0; ++fp, ++sp) {
  991. X    sp->S_title = fp->F_title;
  992. X    sp->S_length = fp->F_length;
  993. X    sp->S_result = (char*)malloc((unsigned)fp->F_length+1);
  994. X    sp->S_page = fp->F_page;
  995. X    sp->S_Lrow = fp->F_Lrow;
  996. X    sp->S_Lcol = fp->F_Lcol;
  997. X    sp->S_Drow = fp->F_Drow;
  998. X    sp->S_Dcol = fp->F_Dcol;
  999. X    sp->S_Dfmt = fp->F_Dfmt;
  1000. X    }
  1001. X    sp->S_title = 0;
  1002. X
  1003. X    findrcds(fields, dbname, processc, first);
  1004. X    for (sp = disp_screen ; sp->S_title != 0; ++sp) {
  1005. X    free(sp->S_result);
  1006. X    }
  1007. X    return(0);
  1008. X}
  1009. X
  1010. X
  1011. Xprocessc(fields, rcd, dbfile, dbname)
  1012. Xstruct  Fdata   *fields;
  1013. Xchar    *rcd;
  1014. XFILE    *dbfile;
  1015. Xchar    *dbname;
  1016. X{
  1017. X    char    c, save[DBSIZE+1];
  1018. X    long    offset, ftell();
  1019. X    char    *strchr();
  1020. X    int     fn;
  1021. X    struct      Fdata   *fp;
  1022. X    struct      Sdata   *sp;
  1023. X    char    *first = "Record to be CHANGED";
  1024. X    char    *last = "RETURN for next, ESC to abort, Ctrl-C to Change, Ctrl-B to reverse";
  1025. X    extern char    lastchar;
  1026. X    
  1027. X    strcpy(save, rcd);
  1028. X    *strchr(save, '\n') = '\0';          /* truncate \n */
  1029. X    getfield(save, ":");
  1030. X    for (sp = disp_screen; sp->S_title != 0; ++sp) {
  1031. X    sp->S_dfault = getfield(NULL, ":");
  1032. X    }
  1033. X    screen(first, disp_screen, last, NULL, TRUE);
  1034. X    noecho();
  1035. X    c = lastchar;
  1036. X    do {
  1037. X    if (c == LF || c == CR)
  1038. X        break;
  1039. X    if (c == ETX) {         /* CTL-C entered */
  1040. X        offset = ftell(dbfile) - strlen(rcd);
  1041. X        *strchr(rcd, '\n') = '\0';          /* truncate \n */
  1042. X        if (doadd(dbname, fields, rcd, dbfile) == 0) {
  1043. X        fseek(dbfile, offset, 0);
  1044. X        putc('D', dbfile);
  1045. X        }
  1046. X        break;
  1047. X    }
  1048. X    if (c == ESC) {
  1049. X        echo();
  1050. X        return(1);
  1051. X    }
  1052. X    if (c == STX) {            /* CTRL-B */
  1053. X        echo();
  1054. X        return(-1);
  1055. X    }
  1056. X    rawputchar(BEL);
  1057. X    } while (c=rawgetchar());
  1058. X    echo();
  1059. X    return(0);
  1060. X}
  1061. X
  1062. Xdoadd(dbname, fields, rcd, filep)
  1063. Xchar    *dbname;
  1064. Xstruct  Fdata   *fields;
  1065. Xchar    *rcd;
  1066. XFILE    *filep;
  1067. X{
  1068. X    struct      Sdata   *sp;
  1069. X    struct      Fdata   *fp;
  1070. X    int     err;
  1071. X    char    buffer[BUFSIZE+1];
  1072. X    char    outline[DBSIZE+1];
  1073. X    long    offset, ftell();
  1074. X
  1075. X    fseek(filep, 0L, 2);     /* end of file */
  1076. X    fp = fields;
  1077. X    getfield(rcd, ":");         /* step past flag */
  1078. X    sp = disp_screen;
  1079. X    while(fp->F_title[0]) {
  1080. X    sp->S_dfault = getfield(0, ":");
  1081. X    ++fp;
  1082. X    ++sp;
  1083. X    }
  1084. X    outline[0] = '\0';
  1085. X    while (screen("Enter changes", disp_screen, 0, 0, FALSE) > 0) {
  1086. X    err = 0;
  1087. X    fp = fields;
  1088. X    sp = disp_screen;
  1089. X    while(fp->F_title[0]) {
  1090. X        if (sp->S_result[0] == '\0' && fp->F_required == 'Y') {
  1091. X        sprintf(outline, "Required field %s missing", fp->F_title);
  1092. X        msg(outline);
  1093. X        err++;
  1094. X        }
  1095. X        if (strchr(sp->S_result, ':')) {
  1096. X        msg("A : is not allowed in any field");
  1097. X        ++err;
  1098. X        }
  1099. X        if (strlen(outline) + strlen(sp->S_result) >= DBSIZE) {
  1100. X        msg("Record too long");
  1101. X        ++err;
  1102. X        break;
  1103. X        }
  1104. X        strcat(outline, sp->S_result);
  1105. X        strcat(outline, ":");
  1106. X        ++fp;
  1107. X        ++sp;
  1108. X    }
  1109. X    if (err == 0)
  1110. X        break;
  1111. X    outline[0] = '\0';
  1112. X    }
  1113. X    if (err > 0 || outline[0] == '\0') {
  1114. X    return(1);
  1115. X    }
  1116. X    outline[strlen(outline)-1] = '\0';  /* truncate trailing : */
  1117. X    offset = ftell(filep);
  1118. X    if (fprintf(filep, " :%s\n", outline) == EOF) {
  1119. X    msg("Error writing DB file");
  1120. X    getout();
  1121. X    }
  1122. X    buffer[0] = '\0';
  1123. X    buildak(dbname, outline, offset, fields, buffer);
  1124. X    writeak(dbname, buffer);
  1125. X    return(0);
  1126. X}
  1127. SHAR_EOF
  1128. true || echo 'restore of change.c failed'
  1129. # ============= common.c ==============
  1130. echo 'x - extracting common.c (Text)'
  1131. sed 's/^X//' << 'SHAR_EOF' > 'common.c' &&
  1132. X#ifndef lint
  1133. Xstatic char Sccsid[] = "@(#)common.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  1134. X#endif
  1135. X
  1136. X/*      COMMON.C        */
  1137. X#include "stdio.h"
  1138. X#include "ascii.h"
  1139. X#include "cardfile.h"
  1140. X#ifdef TERMCAP
  1141. X#define tparm(a, line, col)    tgoto(a, col, line)
  1142. X#define    putp(a)        tputs(a, 12, mputc)
  1143. X#else    /* TERMINFO */
  1144. X#include <curses.h>
  1145. X#include <term.h>
  1146. X#endif
  1147. X
  1148. X#ifdef TERMCAP
  1149. Xextern char
  1150. X    *clear_screen,
  1151. X    *clr_eol,
  1152. X    *enter_dim_mode,
  1153. X    *enter_blink_mode,
  1154. X    *exit_attribute_mode,
  1155. X    *keypad_xmit,
  1156. X    *keypad_local,
  1157. X    *cursor_address,
  1158. X    *cursor_left,
  1159. X    *cursor_right;
  1160. Xint    mputc();
  1161. X#endif
  1162. X
  1163. Xmsg(str)        /* put a blinking message on the 23'th line of the crt */
  1164. Xchar    *str;
  1165. X{
  1166. X    putp(tparm(cursor_address, MSGLINE, 9));
  1167. X    putp(clr_eol);            /* erase line */
  1168. X    if (str != NULL && *str != '\0') {
  1169. X    putp(enter_blink_mode);        /* blink */
  1170. X    fputs(str, stdout);
  1171. X    putp(exit_attribute_mode);        /* back to normal */
  1172. X    sleep(4);
  1173. X    }
  1174. X}
  1175. X
  1176. X
  1177. Xchar *
  1178. Xgetfield(string, sepset)        /* like strtok except contiguous seps */
  1179. Xchar    *string, *sepset;       /* result in a null field */
  1180. X{
  1181. X    register char *p, *r;
  1182. X    static char *savept;
  1183. X    char    *strpbrk();
  1184. X    
  1185. X    p = (string == NULL)? savept : string;
  1186. X    if (p == 0)
  1187. X        return(NULL);
  1188. X    if (*p == '\0')
  1189. X        return(NULL);
  1190. X    if ((r = strpbrk(p, sepset)) == NULL)       /* move past token */
  1191. X        savept = 0;     /* indicate this is the last token */
  1192. X    else {
  1193. X        *r = '\0';
  1194. X        savept = ++r;
  1195. X    }
  1196. X    return(p);
  1197. X}
  1198. X
  1199. X
  1200. Xhelp(help_msg)
  1201. Xchar    *help_msg;
  1202. X{
  1203. X    putp(clear_screen);              /* clear screen */
  1204. X    puts("\n");
  1205. X    fputs(help_msg, stdout);
  1206. X    putp(tparm(cursor_address, MSGLINE, 9));
  1207. X    fputs("Enter any character to continue.", stdout);
  1208. X    rawgetchar();
  1209. X    putp(clear_screen);              /* clear screen */
  1210. X}
  1211. X
  1212. X
  1213. X#ifdef TERMCAP
  1214. Xmputc(c)
  1215. Xchar    c;
  1216. X{
  1217. X    putchar(c);
  1218. X}
  1219. X#endif
  1220. SHAR_EOF
  1221. true || echo 'restore of common.c failed'
  1222. # ============= compress.c ==============
  1223. echo 'x - extracting compress.c (Text)'
  1224. sed 's/^X//' << 'SHAR_EOF' > 'compress.c' &&
  1225. X#ifndef lint
  1226. Xstatic char Sccsid[] = "@(#)compress.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  1227. X#endif
  1228. X
  1229. X/*      COMPRESS.C      */
  1230. X/*    This function will remove all records with a flag
  1231. X**    byte of 'D' from the data base.  The alternate key
  1232. X**    files MUST be rebuilt after it finishes.
  1233. X*/
  1234. X
  1235. X#include "stdio.h"
  1236. X#include "cardfile.h"
  1237. X
  1238. Xcompress(dbname)
  1239. Xchar    *dbname;
  1240. X{
  1241. X    FILE    *in, *out;
  1242. X    char    fname[FNSIZE];
  1243. X    char    tempname[FNSIZE];
  1244. X    char    rcd[DBSIZE+1];
  1245. X    
  1246. X    sprintf(tempname, "%snewdb.$$$", datadir);
  1247. X    if ((out = fopen(tempname, "w")) == NULL) {
  1248. X    msg("Unable to create temporary file");
  1249. X    getout();
  1250. X    }
  1251. X    sprintf(fname, "%s%s.db", datadir, dbname);
  1252. X    if ((in = fopen(fname, "r")) == NULL) {
  1253. X    unlink(tempname);
  1254. X    msg("Unable to read DB file");
  1255. X    getout();
  1256. X    }
  1257. X    while (fgets(rcd, DBSIZE, in) != NULL) {
  1258. X    if (feof(in))
  1259. X        break;
  1260. X    if (*rcd == 'D')        /* record to be deleted */
  1261. X        continue;
  1262. X    if(fputs(rcd, out) == EOF) {
  1263. X        unlink(tempname);
  1264. X        msg("Unable to write to temporary file");
  1265. X        getout();
  1266. X    }
  1267. X    }
  1268. X    fclose(in);
  1269. X    fclose(out);
  1270. X    unlink(fname);
  1271. X    link(tempname, fname);
  1272. X    unlink(tempname);
  1273. X}
  1274. SHAR_EOF
  1275. true || echo 'restore of compress.c failed'
  1276. # ============= define.c ==============
  1277. echo 'x - extracting define.c (Text)'
  1278. sed 's/^X//' << 'SHAR_EOF' > 'define.c' &&
  1279. X#ifndef lint
  1280. Xstatic char Sccsid[] = "@(#)define.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  1281. X#endif
  1282. X
  1283. X/*      DEFINE.C    */
  1284. X/*      This subroutine is used to define a new data-base.
  1285. X**    It expects as input the base name (10 characters or less)
  1286. X**    of all files.
  1287. X**
  1288. X**    It will create the definition file  -  name.def
  1289. X**    the primary file            -  name.db
  1290. X**    and the alternate key files         -  name.akN
  1291. X*/
  1292. X
  1293. X#include "cardfile.h"
  1294. X#include "stdio.h"
  1295. X#include "ascii.h"
  1296. X#include <ctype.h>
  1297. X
  1298. X#define    FNAME    0
  1299. X#define    MAXL    1
  1300. X#define    REQD    2
  1301. X#define    SRCH    3
  1302. X#define    SUBF    4
  1303. X#define    PAGE    5
  1304. X#define    LLINE    6
  1305. X#define    LCOL    7
  1306. X#define    DLINE    8
  1307. X#define    DCOL    9
  1308. X#define    FMT    10
  1309. X
  1310. Xstatic int    page_def = 1;
  1311. Xstatic int    lline_def = 2;
  1312. Xstatic int    col_def = 4;
  1313. X
  1314. Xstatic char    name_res[TSIZE+1];
  1315. Xstatic char    mlen_res[3+1];
  1316. Xstatic char    req_res[1+1];
  1317. Xstatic char    skey_res[1+1];
  1318. Xstatic char    sep_res[5+1];
  1319. Xstatic char    page_res[1+1];
  1320. Xstatic char    lline_res[2+1];
  1321. Xstatic char    lcol_res[2+1];
  1322. Xstatic char    dline_res[2+1];
  1323. Xstatic char    dcol_res[2+1];
  1324. X#ifndef NO_RE
  1325. Xstatic char    fmt_res[MAXFMT+1];
  1326. X#endif
  1327. X
  1328. Xstatic struct    Sdata    def_screen[] = {
  1329. X            {"FIELD NAME", TSIZE, name_res, 0,
  1330. X                -1, -1, -1, -1, -1, "^[^:]*$"},
  1331. X            {"MAXIMUM LENGTH", 3, mlen_res, 0,
  1332. X                -1, -1, -1, -1, -1, "^[0-9]*$"},
  1333. X            {"REQUIRED?", 1, req_res, "N",
  1334. X                -1, -1, -1, -1, -1, "[nyNY]"},
  1335. X            {"SEARCH KEY", 1, skey_res, "Y",
  1336. X                -1, 6, 35, -1, -1, "[nyNY]"},
  1337. X            {"SUBFIELD SEPARATORS", 5, sep_res, 0,
  1338. X                -1, -1, -1, -1, -1, "^[^:]$"},
  1339. X            {"FIELD PAGE", 1, page_res, " ",
  1340. X                -1, -1, -1, -1, -1, "^[-0-9]$"},
  1341. X            {"LABEL LINE", 2, lline_res, "  ",
  1342. X                -1, -1, -1, -1, -1, "^[-0-9]$"},
  1343. X            {"LABEL COLUMN", 2, lcol_res, "  ",
  1344. X                -1, 12, 35, -1, -1, "^[-0-9]$"},
  1345. X            {"DATA FIELD LINE", 2, dline_res, "  ",
  1346. X                -1, -1, -1, -1, -1, "^[-0-9]$"},
  1347. X            {"DATA FIELD COLUMN", 2, dcol_res, 0,
  1348. X                -1, 14, 35, -1, -1, "^[-0-9]$"},
  1349. X#ifdef RE
  1350. X            {"FORMAT", MAXFMT, fmt_res, 0,
  1351. X                -1, -1, -1, -1, -1, ""},
  1352. X#endif
  1353. X            {0, 0, 0, 0, -1, -1, -1, -1, -1, ""}
  1354. X        };
  1355. X
  1356. Xstatic struct  Fdata   fields[MAXFLDS];
  1357. X
  1358. Xdb_define(basename)
  1359. Xchar    *basename;
  1360. X{
  1361. X    int     i;
  1362. X    char    first[SWIDTH];
  1363. X    char    *last = "RETURN to exit";
  1364. X    struct      Fdata   *fp;
  1365. X    int     num_fields, num_ak;
  1366. X    char    fname[FNSIZE];
  1367. X    FILE    *filep, *filep2;
  1368. X    int     err;
  1369. X    int     tsize;
  1370. X    int        opt_out;
  1371. X
  1372. X    sprintf(first,"DEFINING %s DATA BASE", basename);
  1373. X    if (access((*datadir ? datadir : "."), 06) != 0) {
  1374. X    printf("Cannot write into %s\n", (*datadir ? datadir : "."));
  1375. X    sleep(5);
  1376. X    return(1);
  1377. X    }
  1378. X    
  1379. X    /*
  1380. X     *    Read each field entered
  1381. X     */
  1382. X    num_fields = 0;
  1383. X    fp = &fields[0];
  1384. X    tsize = 0;
  1385. X    sprintf(def_screen[PAGE].S_dfault, "%d", page_def);
  1386. X    sprintf(def_screen[LLINE].S_dfault, "%d", lline_def);
  1387. X    sprintf(def_screen[LCOL].S_dfault, "%d", col_def);
  1388. X    sprintf(def_screen[DLINE].S_dfault, "%d", lline_def);
  1389. X    while (screen(first, def_screen, last, 0, FALSE)) {
  1390. X    err = 0;
  1391. X    strcpy(fp->F_title, def_screen[FNAME].S_result);
  1392. X    if (fp->F_title[0] == '\0') {
  1393. X        msg("TITLE field must be specified");
  1394. X        ++err;
  1395. X    }
  1396. X    if (strchr(fp->F_title, ':') != NULL) {
  1397. X        msg("TITLE field must not include :");
  1398. X        ++err;
  1399. X    }
  1400. X
  1401. X    fp->F_length = atoi(def_screen[MAXL].S_result);
  1402. X    if (fp->F_length <= 0 || fp->F_length >= FLDLEN) {
  1403. X        msg("LENGTH field must be less than 256");
  1404. X        ++err;
  1405. X    }
  1406. X    if ((tsize += fp->F_length) > DBSIZE) {
  1407. X        msg("Total record length too large");
  1408. X        ++err;
  1409. X    }
  1410. X
  1411. X#ifdef BSD_STRING
  1412. X    if (islower(def_screen[REQD].S_result[0]))
  1413. X        fp->F_required = toupper(def_screen[REQD].S_result[0]);
  1414. X#else
  1415. X    fp->F_required = toupper(def_screen[REQD].S_result[0]);
  1416. X#endif
  1417. X    if (fp->F_required != 'Y' && fp->F_required != 'N') {
  1418. X        msg("REQUIRED must be Y or N");
  1419. X        ++err;
  1420. X    }
  1421. X
  1422. X#ifdef BSD_STRING
  1423. X    if (islower(def_screen[SRCH].S_result[0]))
  1424. X        fp->F_key = toupper(def_screen[SRCH].S_result[0]);
  1425. X#else
  1426. X    fp->F_key = toupper(def_screen[SRCH].S_result[0]);
  1427. X#endif
  1428. X    if (fp->F_key != 'Y' && fp->F_key != 'N') {
  1429. X        msg("KEY must be Y or N");
  1430. X        ++err;
  1431. X    }
  1432. X
  1433. X    strcpy(fp->F_seps, def_screen[SUBF].S_result);
  1434. X    if (strchr(fp->F_seps, ':') != NULL) {
  1435. X        msg("SEPARATORS must not include :");
  1436. X        ++err;
  1437. X    }
  1438. X
  1439. X#ifndef NO_RE
  1440. X    strcpy(fp->F_Dfmt, def_screen[FMT].S_result);
  1441. X#else
  1442. X    fp->F_Dfmt[0] = '\0';
  1443. X#endif
  1444. X
  1445. X    fp->F_page = atoi(def_screen[PAGE].S_result);
  1446. X    if (fp->F_page == 0) {
  1447. X        fp->F_page = -1;
  1448. X    }
  1449. X
  1450. X    if (def_screen[LLINE].S_result[0] == '\0') {
  1451. X        fp->F_Lrow = -1;
  1452. X    } else {
  1453. X        fp->F_Lrow = atoi(def_screen[LLINE].S_result);
  1454. X        if (fp->F_Lrow < 2 || fp->F_Lrow >= MSGLINE) {
  1455. X        msg("LABEL ROW field must be less than 22");
  1456. X        ++err;
  1457. X        }
  1458. X    }
  1459. X
  1460. X    if (def_screen[LCOL].S_result[0] == '\0') {
  1461. X        fp->F_Lcol = -1;
  1462. X    } else {
  1463. X        fp->F_Lcol = atoi(def_screen[LCOL].S_result);
  1464. X        if (fp->F_Lcol < 0 || fp->F_Lcol >= SWIDTH) {
  1465. X        msg("LABEL COLUMN field must be less than 80");
  1466. X        ++err;
  1467. X        }
  1468. X    }
  1469. X
  1470. X    if (def_screen[DLINE].S_result[0] == '\0') {
  1471. X        fp->F_Drow = -1;
  1472. X    } else {
  1473. X        fp->F_Drow = atoi(def_screen[DLINE].S_result);
  1474. X        if (fp->F_Drow < 2 || fp->F_Drow >= MSGLINE) {
  1475. X        msg("DATA ROW field must be less than 22");
  1476. X        ++err;
  1477. X        }
  1478. X    }
  1479. X
  1480. X    if (def_screen[DCOL].S_result[0] == '\0') {
  1481. X        fp->F_Dcol = -1;
  1482. X    } else {
  1483. X        fp->F_Dcol = atoi(def_screen[DCOL].S_result);
  1484. X        if (fp->F_Dcol < 0 || fp->F_Dcol >= SWIDTH) {
  1485. X        msg("DATA COLUMN field must be less than 80");
  1486. X        ++err;
  1487. X        }
  1488. X    }
  1489. X
  1490. X    for (i=0; i<num_fields; i++) {
  1491. X        if (strcmp(fields[i].F_title, fp->F_title) == 0) {
  1492. X        msg("Field already defined");
  1493. X        err++;
  1494. X        break;
  1495. X        }
  1496. X    }
  1497. X    if (err)
  1498. X        continue;
  1499. X    /*
  1500. X     * Valid field, update defaults
  1501. X     */
  1502. X    lline_def = (fp->F_Lrow > fp->F_Drow ? fp->F_Lrow : fp->F_Drow) + 2;
  1503. X    if (fp->F_Dcol == -1) {
  1504. X        lline_def += ((fp->F_Lcol == -1 ? 4 : fp->F_Lcol) +
  1505. X                strlen(fp->F_title) + (fp->F_length > 99 ? 7 : 6) +
  1506. X                fp->F_length) / SWIDTH;
  1507. X    } else {
  1508. X        lline_def += (fp->F_Dcol + fp->F_length) / SWIDTH;
  1509. X    }
  1510. X    if (lline_def > SLENGTH - 4) {
  1511. X        page_def++;
  1512. X        lline_def = 2;
  1513. X    }
  1514. X    sprintf(def_screen[PAGE].S_dfault, "%d", page_def);
  1515. X    sprintf(def_screen[LLINE].S_dfault, "%d", lline_def);
  1516. X    sprintf(def_screen[LCOL].S_dfault, "%d", col_def);
  1517. X    sprintf(def_screen[DLINE].S_dfault, "%d", lline_def);
  1518. X    ++fp;
  1519. X    if (++num_fields > MAXFLDS) {
  1520. X        msg("Too many fields defined, aborting");
  1521. X        return(1);
  1522. X    }
  1523. X    }
  1524. X#ifdef DEBUG
  1525. X    fprintf(stderr, "%d fields in the %s database\n", num_fields, basename);
  1526. X    for (i=0; i<num_fields; ++i) {
  1527. X    fprintf(stderr, "%8d  %s\n", i, fields[i].F_title);
  1528. X    }
  1529. X#endif
  1530. X
  1531. X    if (num_fields == 0) {
  1532. X    msg("No fields defined, aborting");
  1533. X    return(1);
  1534. X    }
  1535. X    sprintf(fname,"%s%s.def", datadir, basename);
  1536. X    if ((filep = fopen(fname,"w")) == NULL) {
  1537. X    msg("Unable to create DEF file");
  1538. X    return(1);
  1539. X    }
  1540. X    sprintf(fname,"%s%s.db", datadir, basename);
  1541. X    if ((filep2 = fopen(fname,"w")) == NULL) {
  1542. X    msg("Unable to create DB file");
  1543. X    sprintf(fname, "%s.def", basename);
  1544. X    unlink(fname);
  1545. X    return(1);
  1546. X    }
  1547. X    fclose(filep2);
  1548. X    fprintf(filep, "%s:%d\n", fname, num_fields);
  1549. X    num_ak = 0;
  1550. X    for (i=0; i<num_fields; i++) {
  1551. X    fp = &fields[i];
  1552. X    if (fp->F_key == 'Y')
  1553. X        fp->F_key = '0' + num_ak++;
  1554. X    fprintf(filep, "%s:%c:%s:%c:%d\n", fp->F_title, fp->F_key,
  1555. X        fp->F_seps, fp->F_required, fp->F_length);
  1556. X    }
  1557. X    if (num_ak == 0) {
  1558. X    msg("At least 1 key field must be defined");
  1559. X    unlink(fname);          /* DB file */
  1560. X    sprintf(fname, "%s.def", basename);
  1561. X    unlink(fname);
  1562. X    return(1);
  1563. X    }
  1564. X    fprintf(filep, "%d\n", num_ak);
  1565. X    num_ak = 0;
  1566. X    for (i=0; i<num_fields; i++) {
  1567. X    fp = &fields[i];
  1568. X    if (fp->F_key != 'N') {         /* Alternate key file required */
  1569. X        sprintf(fname,"%s%s.ak%d", datadir, basename, num_ak++);
  1570. X        if ((filep2 = fopen(fname,"w")) == NULL) {
  1571. X        msg("Unable to create AK file\n");
  1572. X        sprintf(fname, "%s.def", basename);
  1573. X        unlink(fname);
  1574. X        return(1);
  1575. X        }
  1576. X        fclose(filep2);
  1577. X        fprintf(filep, "%d:%s\n", i, fname);
  1578. X    }
  1579. X    }
  1580. X
  1581. X    /*
  1582. X     * Output optional fields if necessary (position and format)
  1583. X     */
  1584. X    for (i=0, opt_out=1, fp = &fields[0]; i<num_fields; i++, fp++) {
  1585. X    if (fp->F_page == -1 && fp->F_Lrow == -1 && fp->F_Lcol == -1 &&
  1586. X        fp->F_Drow == -1 && fp->F_Dcol == -1 && fp->F_Dfmt[0] == '\0') {
  1587. X        continue;
  1588. X    }
  1589. X    if (opt_out) {
  1590. X        fprintf(filep, "%%%%\n");
  1591. X        opt_out = 0;
  1592. X    }
  1593. X    fprintf(filep, "%d:%d:%d:%d:%d:%d:%s\n", i, fp->F_page, fp->F_Lrow,
  1594. X        fp->F_Lcol, fp->F_Drow, fp->F_Dcol, fp->F_Dfmt);
  1595. X    }
  1596. X    fclose(filep);
  1597. X    return(0);
  1598. X}
  1599. SHAR_EOF
  1600. true || echo 'restore of define.c failed'
  1601. # ============= delete.c ==============
  1602. echo 'x - extracting delete.c (Text)'
  1603. sed 's/^X//' << 'SHAR_EOF' > 'delete.c' &&
  1604. X#ifndef lint
  1605. Xstatic char Sccsid[] = "@(#)delete.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  1606. X#endif
  1607. X
  1608. X/*    DELETE.C        */
  1609. X/*    This module is used to find and delete records
  1610. X**    in the data base matching the selection criteria.
  1611. X**    The user may select multiple values of one field
  1612. X**    which will be or'd and/or multiple fields which will
  1613. X**    be and'd. In other words, if field 1 is specified
  1614. X**    as value1:value2 and field3 is specified as value3.
  1615. X**    Records with field1==(value1 || value2) && field3==value3
  1616. X**    will be selected for deletion.
  1617. X**    It calls findrcds.c to do all the work.
  1618. X**    It does not actually delete records, the flag(first)
  1619. X**    field is set to 'D'. To physically delete them, the data
  1620. X**    base must be compressed.
  1621. X*/
  1622. X
  1623. X#include "stdio.h"
  1624. X#include "ascii.h"
  1625. X#include "cardfile.h"
  1626. X
  1627. X
  1628. Xstatic struct Sdata disp_screen[MAXFLDS+1];
  1629. X
  1630. Xextern    int    readonly;
  1631. Xchar    *malloc(), *getfield();
  1632. X
  1633. Xdelete(fields, dbname)
  1634. Xstruct  Fdata   fields[];
  1635. Xchar    *dbname;
  1636. X{
  1637. X    char    first[SWIDTH];
  1638. X    struct Fdata *fp;
  1639. X    struct Sdata *sp;
  1640. X    int     processd();
  1641. X    
  1642. X    if (readonly) {
  1643. X    msg("Database is readonly");
  1644. X    return(1);
  1645. X    }
  1646. X    sprintf(first, "Select Records from the %s Data Base to be DELETED",
  1647. X    dbname);
  1648. X    for (fp = fields, sp = disp_screen ; fp->F_title[0] != 0; ++fp, ++sp) {
  1649. X    sp->S_title = fp->F_title;
  1650. X    sp->S_length = fp->F_length;
  1651. X    sp->S_result = (char*)malloc((unsigned)fp->F_length+1);
  1652. X    sp->S_page = fp->F_page;
  1653. X    sp->S_Lrow = fp->F_Lrow;
  1654. X    sp->S_Lcol = fp->F_Lcol;
  1655. X    sp->S_Drow = fp->F_Drow;
  1656. X    sp->S_Dcol = fp->F_Dcol;
  1657. X    sp->S_Dfmt = fp->F_Dfmt;
  1658. X    }
  1659. X    sp->S_title = 0;
  1660. X
  1661. X    findrcds(fields, dbname, processd, first);
  1662. X    for (sp = disp_screen ; sp->S_title != 0; ++sp) {
  1663. X    free(sp->S_result);
  1664. X    }
  1665. X    return(0);
  1666. X}
  1667. X
  1668. X
  1669. X/*ARGSUSED*/
  1670. Xprocessd(fields, rcd, dbfile, dummy)
  1671. Xstruct  Fdata   *fields;
  1672. Xchar    *rcd;
  1673. XFILE    *dbfile;
  1674. Xchar    *dummy;
  1675. X{
  1676. X    char    c, save[DBSIZE+1];
  1677. X    static      char    fmt[256];
  1678. X    int     fn;
  1679. X    struct      Fdata   *fp;
  1680. X    struct      Sdata   *sp;
  1681. X    char    *first = "Record to be DELETED";
  1682. X    char    *last = "RETURN for next, ESC to abort, CTL-D to DELETE, CTL-B to reverse";
  1683. X    extern char    lastchar;
  1684. X
  1685. X    strcpy(save, rcd);
  1686. X    *strchr(save, '\n') = '\0';          /* truncate \n */
  1687. X    getfield(save, ":");
  1688. X    for (sp = disp_screen; sp->S_title != 0; ++sp) {
  1689. X    sp->S_dfault = getfield(NULL, ":");
  1690. X    }
  1691. X    screen(first, disp_screen, last, NULL, TRUE);
  1692. X    noecho();
  1693. X    c = lastchar;
  1694. X    do {
  1695. X    if (c == LF || c == CR)
  1696. X        break;
  1697. X    if (c == EOT) {        /* CTL-D entered */
  1698. X        fseek(dbfile, (long)(-strlen(rcd)), 1);
  1699. X        putc('D', dbfile);
  1700. X        break;
  1701. X    }
  1702. X    if (c == ESC) {
  1703. X        echo();
  1704. X        return(1);
  1705. X    }
  1706. X    if (c == STX) {
  1707. X        echo();
  1708. X        return(-1);
  1709. X    }
  1710. X    rawputchar(BEL);
  1711. X    } while (c=rawgetchar());
  1712. X    echo();
  1713. X    return(0);
  1714. X}
  1715. SHAR_EOF
  1716. true || echo 'restore of delete.c failed'
  1717. # ============= dumpdb.c ==============
  1718. echo 'x - extracting dumpdb.c (Text)'
  1719. sed 's/^X//' << 'SHAR_EOF' > 'dumpdb.c' &&
  1720. X#ifndef lint
  1721. Xstatic char Sccsid[] = "@(#)dumpdb.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  1722. X#endif
  1723. X
  1724. X/*      DUMPDB.C        */
  1725. X/*      This subroutine is used to dump all records from
  1726. X        the data base and the alternate key files, including
  1727. X        deleted records.
  1728. X*/
  1729. X
  1730. X#include "stdio.h"
  1731. X#include "ascii.h"
  1732. X#include "cardfile.h"
  1733. X#include <signal.h>
  1734. X
  1735. Xstatic    FILE    *in, *out;
  1736. Xstatic    int    quit = 0;
  1737. Xstatic    SIGRTN    abort();
  1738. Xstatic    SIGRTN    (*old_sig)();
  1739. X
  1740. Xdumpdb(dbname, ak_data, fields)
  1741. Xchar    *dbname;
  1742. Xstruct  AKdata  *ak_data;
  1743. Xstruct  Fdata   *fields;
  1744. X{
  1745. X    char        ptitle[PWIDTH+1];
  1746. X    int         pnum, lnum;
  1747. X    char        fname[FNSIZE];
  1748. X    char        rcd[DBSIZE+1];
  1749. X    
  1750. X    if ((out = popen("lp", "w")) == NULL) {
  1751. X        msg("Unable to open printer");
  1752. X        return(1);
  1753. X    }
  1754. X    sprintf(fname, "%s%s.db", datadir, dbname);
  1755. X    if ((in = fopen(fname, "r")) == NULL) {
  1756. X    pclose(out);
  1757. X        msg("Unable to open DB file");
  1758. X        return(1);
  1759. X    }
  1760. X    /* msg() will leave the cursor at the bottom */
  1761. X    msg("");
  1762. X    fputs("DEL to abort dump", stdout);
  1763. X    old_sig = signal(SIGINT, abort);
  1764. X    lnum = PLENGTH + 1;                 /* force top-of-page */
  1765. X    pnum = 1;
  1766. X    sprintf(ptitle, "Records in %s.db", dbname);
  1767. X    while( !quit && (fgets(rcd, DBSIZE, in)) != NULL) {   /* print DB file */
  1768. X        rcd[strlen(rcd)-1] = '\0';      /* truncate \n */
  1769. X        if (lnum + 3 + (strlen(rcd)+PWIDTH-1)/PWIDTH >= PLENGTH) {
  1770. X            newpage(&pnum, ptitle);
  1771. X            lnum = 3;
  1772. X        }
  1773. X        fputs(rcd, out);
  1774. X        putc('\n', out);
  1775. X        lnum += (strlen(rcd)+PWIDTH-1)/PWIDTH;
  1776. X    }
  1777. X    if (quit)
  1778. X    return(1);
  1779. X    fclose(in);
  1780. X    while (ak_data->A_fldnum >= 0) {
  1781. X    strcpy(fname, datadir);
  1782. X        strcat(fname, ak_data->A_akname);
  1783. X        if ((in = fopen(fname, "r")) == NULL) {
  1784. X            sprintf(ptitle, "Unable to open %s", fname);
  1785. X            msg(ptitle);
  1786. X            return(1);
  1787. X        }
  1788. X        lnum = PLENGTH + 1;
  1789. X        pnum = 1;
  1790. X        sprintf(ptitle, "Records in %s sorted on %s",
  1791. X            fname, fields[ak_data->A_fldnum].F_title);
  1792. X    /* print AK file */
  1793. X        while( !quit && (fgets(rcd, DBSIZE, in)) != NULL) {
  1794. X            rcd[strlen(rcd)-1] = '\0';  /* truncate \n */
  1795. X            if (lnum + 3 + (strlen(rcd)+PWIDTH-1)/PWIDTH >= PLENGTH) {
  1796. X                newpage(&pnum, ptitle);
  1797. X                lnum = 3;
  1798. X            }
  1799. X            fputs(rcd, out);
  1800. X            putc('\n', out);
  1801. X            lnum += (strlen(rcd)+PWIDTH-1)/PWIDTH;
  1802. X        }
  1803. X    if (quit)
  1804. X        return(1);
  1805. X        fclose(in);
  1806. X        ++ak_data;
  1807. X    }
  1808. X    pclose(out);
  1809. X    signal(SIGINT, old_sig);
  1810. X    return(0);
  1811. X}
  1812. X
  1813. Xnewpage(pnum, title)
  1814. Xint     *pnum;
  1815. Xchar    *title;
  1816. X{
  1817. X
  1818. X    putc(FF, out);
  1819. X    fprintf(out, "%-69sPAGE %4d\n\n\n", title, *pnum);
  1820. X    *pnum += 1;
  1821. X}
  1822. X
  1823. X
  1824. Xstatic SIGRTN
  1825. Xabort()
  1826. X{
  1827. X
  1828. X    signal(SIGINT, old_sig);
  1829. X    fputs("\n\nOUTPUT ABORTED!\n", out);
  1830. X    pclose(out);
  1831. X    fclose(in);
  1832. X    msg("Dump aborted");
  1833. X    quit = 1;
  1834. X}
  1835. SHAR_EOF
  1836. true || echo 'restore of dumpdb.c failed'
  1837. # ============= extract.c ==============
  1838. echo 'x - extracting extract.c (Text)'
  1839. sed 's/^X//' << 'SHAR_EOF' > 'extract.c' &&
  1840. X#ifndef lint
  1841. Xstatic char Sccsid[] = "@(#)extract.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  1842. X#endif
  1843. X
  1844. X/*      EXTRACT.C       */
  1845. X/*      This subroutine is used to write selected records from the
  1846. X *      database on to another disk file.
  1847. X */
  1848. X
  1849. X#include "stdio.h"
  1850. X#include "cardfile.h"
  1851. X#include "ascii.h"
  1852. X
  1853. XFILE    *ext_fp;
  1854. Xchar    ext_fname[FNSIZE];
  1855. Xint     rec_cnt;
  1856. Xstruct Sdata    fn_screen[] = {
  1857. X            {"File Name", FNSIZE, ext_fname, NULL},
  1858. X            {0, 0, 0, 0}
  1859. X        };
  1860. X
  1861. Xextract(fields, dbname)
  1862. Xstruct  Fdata   *fields;
  1863. Xchar    *dbname;
  1864. X{
  1865. X    char    first[SWIDTH+1];
  1866. X    int     write_rcd();
  1867. X
  1868. X    sprintf(first, "Select records from the %s Data Base to be extracted",
  1869. X    dbname);
  1870. X    screen(first, fn_screen, "Enter File Name of Extract File", NULL, FALSE);
  1871. X    if (ext_fname[0] == '\0') {
  1872. X    msg("No file name entered, using temp.ext");
  1873. X    strcpy(ext_fname, "temp.ext");
  1874. X    }
  1875. X    if ((ext_fp = fopen(ext_fname, "w")) == NULL) {
  1876. X    sprintf(first, "Unable to open file %s for output", ext_fname);
  1877. X    msg(first);
  1878. X    return(1);
  1879. X    }
  1880. X    rec_cnt = 0;
  1881. X    findrcds(fields, dbname, write_rcd, first);
  1882. X    fclose(ext_fp);
  1883. X    sprintf(first, "%d records written to %s", rec_cnt, ext_fname);
  1884. X    msg("");
  1885. X    fputs(first, stdout);    /* this works because msg() leaves the cursor */
  1886. X    sleep(5);
  1887. X    return(0);
  1888. X}
  1889. X
  1890. X
  1891. X/*ARGSUSED*/
  1892. Xint
  1893. Xwrite_rcd(dummy1, rcd, dummy2, dummy3)
  1894. Xchar    *rcd;
  1895. Xchar    *dummy1, *dummy2, *dummy3;
  1896. X{
  1897. X    ++rec_cnt;
  1898. X    return(fputs(rcd, ext_fp));
  1899. X}
  1900. SHAR_EOF
  1901. true || echo 'restore of extract.c failed'
  1902. # ============= find.c ==============
  1903. echo 'x - extracting find.c (Text)'
  1904. sed 's/^X//' << 'SHAR_EOF' > 'find.c' &&
  1905. X#ifndef lint
  1906. Xstatic char Sccsid[] = "@(#)find.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  1907. X#endif
  1908. X
  1909. X/*      FIND.C      */
  1910. X/*      This module is used to find and display records
  1911. X**    in the data base matching the selection criteria.
  1912. X**    The user may select multiple values of one field
  1913. X**    which will be or'd and/or multiple fields which will
  1914. X**    be and'd. In other words, if field 1 is specified
  1915. X**    as value1:value2 and field3 is specified as value3.
  1916. X**    Records with field1==(value1 || value2) && field3==value3
  1917. X**    will be displayed.
  1918. X**    It calls findrcds.c to do all the work.
  1919. X*/
  1920. X
  1921. X#include "stdio.h"
  1922. X#include "ascii.h"
  1923. X#include "cardfile.h"
  1924. X
  1925. Xstatic struct Sdata disp_screen[MAXFLDS+1];
  1926. X
  1927. Xfind(fields, dbname)
  1928. Xstruct  Fdata   *fields;
  1929. Xchar    *dbname;
  1930. X{
  1931. X    struct Fdata *fp;
  1932. X    struct Sdata *sp;
  1933. X    char    first[SWIDTH];
  1934. X    int     display();
  1935. X    
  1936. X    sprintf(first, "Display Records from the %s Data Base", dbname);
  1937. X    for (fp = fields, sp = disp_screen ; fp->F_title[0] != 0; ++fp, ++sp) {
  1938. X    sp->S_title = fp->F_title;
  1939. X    sp->S_length = fp->F_length;
  1940. X    sp->S_result = (char*)malloc((unsigned)fp->F_length+1);
  1941. X    sp->S_page = fp->F_page;
  1942. X    sp->S_Lrow = fp->F_Lrow;
  1943. X    sp->S_Lcol = fp->F_Lcol;
  1944. X    sp->S_Drow = fp->F_Drow;
  1945. X    sp->S_Dcol = fp->F_Dcol;
  1946. X    sp->S_Dfmt = fp->F_Dfmt;
  1947. X    }
  1948. X    sp->S_title = 0;
  1949. X
  1950. X    findrcds(fields, dbname, display, first);
  1951. X    for (sp = disp_screen ; sp->S_title != 0; ++sp) {
  1952. X    free(sp->S_result);
  1953. X    }
  1954. X    return(0);
  1955. X}
  1956. X
  1957. X
  1958. X/*ARGSUSED*/
  1959. Xdisplay(fields, rcd, dummy1, dummy2)
  1960. Xstruct  Fdata   *fields;
  1961. Xchar    *rcd;
  1962. XFILE    *dummy1;
  1963. Xchar    *dummy2;
  1964. X{
  1965. X    char    c, save[DBSIZE+1];
  1966. X    FILE    *filep;
  1967. X    char    *first = "Selected Records";
  1968. X    char    *last = "RETURN for next, ESC to abort, CTL-P to print, CTL-B to reverse";
  1969. X    static      char    fmt[256];
  1970. X    struct      Sdata   *sp;
  1971. X    char    *getfield();
  1972. X    extern char    lastchar;
  1973. X    
  1974. X    strcpy(save, rcd);
  1975. X    getfield(rcd, ":");
  1976. X    for (sp = disp_screen; sp->S_title != 0; ++sp) {
  1977. X    sp->S_dfault = getfield(NULL, ":");
  1978. X    }
  1979. X    screen(first, disp_screen, last, NULL, TRUE);
  1980. X    noecho();
  1981. X    c = lastchar;
  1982. X    do {
  1983. X    if (c == LF || c == CR)
  1984. X        break;
  1985. X    if (c == DLE) {        /* CTL-P entered */
  1986. X        if ((filep=popen("lp", "w")) == NULL) {
  1987. X        msg("Unable to open printer");
  1988. X        continue;
  1989. X        }
  1990. X        strcpy(rcd, save);
  1991. X        putrcd(first, rcd, filep, fmt, PWIDTH, 1);
  1992. X        pclose(filep);
  1993. X        continue;
  1994. X    }
  1995. X    if (c == ESC) {
  1996. X        echo();
  1997. X        return(1);
  1998. X    }
  1999. X    if (c == STX) {        /* CTL-B entered */
  2000. X        echo();
  2001. X        return(-1);
  2002. X    }
  2003. X    rawputchar(BEL);
  2004. X    } while (c=rawgetchar());
  2005. X    echo();
  2006. X    return(0);
  2007. X}
  2008. SHAR_EOF
  2009. true || echo 'restore of find.c failed'
  2010. # ============= findrcds.c ==============
  2011. echo 'x - extracting findrcds.c (Text)'
  2012. sed 's/^X//' << 'SHAR_EOF' > 'findrcds.c' &&
  2013. X#ifndef lint
  2014. Xstatic char Sccsid[] = "@(#)findrcds.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  2015. X#endif
  2016. X
  2017. X/*    FINDRCDS.C    */
  2018. X/*    This module is used to find records in the data base
  2019. X**    matching the selection criteria.
  2020. X**    The user may select multiple values of one field
  2021. X**    connected by '&' or '|' which will be or'd and/or
  2022. X**    multiple fields which will be and'd.
  2023. X**    In other words, if field 1 is specified
  2024. X**    as value1|value2 and field3 is specified as value3.
  2025. X**    Records with field1==(value1 || value2) && field3==value3
  2026. X**    will be selected. An external routine 'display', passed
  2027. X**    as a parameter will be called to process the selected records.
  2028. X*/
  2029. X
  2030. X#include <stdio.h>
  2031. X#include <errno.h>
  2032. X#include "ascii.h"
  2033. X#include "cardfile.h"
  2034. X
  2035. Xextern    int    readonly;
  2036. X
  2037. Xstruct Keys {
  2038. X    char    K_flag;
  2039. X    long    K_offset;
  2040. X};
  2041. X/*
  2042. X * Possible values of the K_flag field
  2043. X */
  2044. X#define    GOOD    0    /* good record */
  2045. X#define    MATCH    1    /* found on this search argument */
  2046. X#define    END    32    /* physical end of key array */
  2047. X#define    FREE    64    /* first free key block */
  2048. X
  2049. X
  2050. Xfindrcds(fields, dbname, display, first)
  2051. Xstruct  Fdata    *fields;
  2052. Xchar    *dbname;
  2053. Xint    (*display)();
  2054. Xchar    *first;
  2055. X{
  2056. X    struct    Fdata    *fp;
  2057. X    struct    Sdata    find_screen[MAXFLDS+1], *sp;
  2058. X    int     found;
  2059. X    FILE    *filep;
  2060. X    char    filename[FNSIZE];
  2061. X    diskptr    offset;
  2062. X    char    *last =
  2063. X        "Separate alternate values with a | for 'or' or a & for 'and'";
  2064. X    int        knum, firstflag;
  2065. X    long    getkey();
  2066. X    char    *keyval, *cp;
  2067. X    char    *rcd;
  2068. X    char    operator, nextop;
  2069. X    char    out_line[SWIDTH+1];
  2070. X    struct    Keys    keys[MAXKEYS+1], *kp;
  2071. X    int        i;
  2072. X    int     rc;
  2073. X    char    *getslct(), *malloc();
  2074. X    
  2075. X    fp = fields;
  2076. X    sp = find_screen;
  2077. X    while (fp->F_title[0] != '\0') {
  2078. X    if (fp->F_key == 'N') {
  2079. X        ++fp;
  2080. X        continue;
  2081. X    }
  2082. X    sp->S_title = fp->F_title;
  2083. X    sp->S_length = 2 * fp->F_length;
  2084. X    sp->S_page = -1;
  2085. X    sp->S_Lrow = -1;
  2086. X    sp->S_Lcol = -1;
  2087. X    sp->S_Drow = -1;
  2088. X    sp->S_Dcol = -1;
  2089. X    sp->S_Dfmt = "";
  2090. X    sp->S_result = malloc((unsigned)sp->S_length+1);
  2091. X    sp->S_dfault = 0;
  2092. X    ++fp;
  2093. X    ++sp;
  2094. X    }
  2095. X    sp->S_title = 0;
  2096. X    while (screen(first, find_screen, last, 0, FALSE) != 0) {
  2097. X    firstflag = 1;
  2098. X    knum = -1;
  2099. X    keys[0].K_flag = FREE;
  2100. X    for (i=1; i<MAXKEYS; ++i)
  2101. X        keys[i].K_flag = GOOD;
  2102. X    keys[MAXKEYS].K_flag = END;
  2103. X    sp = find_screen;
  2104. X    while (sp->S_title) {        /* loop on key field */
  2105. X        ++knum;
  2106. X        if (*(sp->S_result) == '\0') {    /* was key entered */
  2107. X        ++sp;
  2108. X        continue;
  2109. X        }
  2110. X        sprintf(filename, "%s%s.ak%d", datadir, dbname, knum);
  2111. X        if ((filep = fopen(filename, "r")) == NULL) {
  2112. X        msg("Unable to open alternate key file");
  2113. X        getout();
  2114. X        }
  2115. X        operator = '&';
  2116. X        if (firstflag) {
  2117. X        firstflag = 0;
  2118. X        operator = '|';
  2119. X        }
  2120. X        cp = sp->S_result;
  2121. X        /* loop for each key for this field */
  2122. X        while ((keyval = getslct(cp, "&|", &nextop)) != NULL) {
  2123. X        cp = NULL;
  2124. X        /* loop getting offsets for this value */
  2125. X        while ((offset = getkey(filep, keyval)) >= 0L) {
  2126. X            keyval = 0;
  2127. X            if (operator == '|') {
  2128. X            if (orkey(offset, keys) == -1)
  2129. X                break;
  2130. X            }
  2131. X            if (operator == '&') {
  2132. X            andkey(offset, keys);
  2133. X            }
  2134. X        }
  2135. X        if (operator == '&') {
  2136. X            purgekey(keys);
  2137. X        }
  2138. X        operator = nextop;
  2139. X        }
  2140. X        fclose(filep);
  2141. X        ++sp;
  2142. X    }
  2143. X    sprintf(filename, "%s%s.db", datadir, dbname);
  2144. X    if (readonly) {
  2145. X        if ((filep = fopen(filename, "r")) == NULL) {
  2146. X        sprintf(out_line, "Unable to open %s, errno=%d\n", filename, errno);
  2147. X        msg(out_line);
  2148. X        return(1);
  2149. X        }
  2150. X    } else {
  2151. X        if ((filep = fopen(filename, "r+")) == NULL) {
  2152. X        if (errno == EACCES) {
  2153. X            strcpy(out_line, "You do not have permission to modify this database");
  2154. X        } else {
  2155. X            sprintf(out_line, "Unable to open %s, errno=%d\n", filename, errno);
  2156. X        }
  2157. X        msg(out_line);
  2158. X        return(1);
  2159. X        }
  2160. X    }
  2161. X    found = 0;
  2162. X    rcd = malloc(DBSIZE);
  2163. X    kp = keys;
  2164. X    while (kp->K_flag == GOOD) {
  2165. X        if (kp->K_offset <0L) {
  2166. X        ++kp;
  2167. X        continue;
  2168. X        }
  2169. X        fseek(filep, kp->K_offset, 0);
  2170. X        if (fgets(rcd, DBSIZE, filep) == NULL) {
  2171. X        msg("Error reading DB file");
  2172. X        getout();
  2173. X        }
  2174. X        if (*rcd == 'D') {
  2175. X        kp->K_offset = -1L;
  2176. X        ++kp;
  2177. X        continue;
  2178. X        }
  2179. X        ++found;
  2180. X        if ((rc = (*display)(fields, rcd, filep, dbname)) == 1)
  2181. X        break;
  2182. X        if (rc == -1) {    /* reverse */
  2183. X        while (kp > &keys[0]) {
  2184. X            --kp;
  2185. X            if (kp->K_offset >= 0L)
  2186. X            break;
  2187. X        }
  2188. X        } else {
  2189. X        ++kp;
  2190. X        }
  2191. X    }
  2192. X    fclose(filep);
  2193. X    free(rcd);
  2194. X    if (found == 0) {
  2195. X        msg("No records found");
  2196. X    }
  2197. X    }
  2198. X    sp = find_screen;
  2199. X    while (sp->S_title) {
  2200. X    free(sp->S_result);
  2201. X    ++sp;
  2202. X    }
  2203. X    return(0);
  2204. X}
  2205. X
  2206. X
  2207. Xchar *
  2208. Xgetslct(string, seps, sepval)   /* identical to getfld except separator is */
  2209. Xchar    *string, *seps, *sepval;    /* returned thru sepval */
  2210. X{
  2211. X    register char    *p, *r;
  2212. X    static   char    *savept;
  2213. X    
  2214. X    p = (string == NULL)? savept : string;
  2215. X    if (p == 0)
  2216. X    return(NULL);
  2217. X    if (*p == '\0')
  2218. X    return(NULL);
  2219. X    if ((r = strpbrk(p, seps)) == NULL) {    /* move past token */
  2220. X    *sepval = '\0';
  2221. X    savept = 0;        /* indicate this is the last token */
  2222. X    } else {
  2223. X    *sepval = *r;
  2224. X    *r = '\0';
  2225. X    savept = ++r;
  2226. X    }
  2227. X    return(p);
  2228. X}
  2229. X
  2230. X
  2231. Xorkey(offset, keys)
  2232. Xdiskptr    offset;
  2233. Xstruct    Keys    *keys;
  2234. X{
  2235. X    struct Keys    *save;
  2236. X
  2237. X    save = NULL;
  2238. X    while (keys->K_flag == GOOD) {
  2239. X    if (offset == keys->K_offset) {
  2240. X        return(0);
  2241. X    }
  2242. X    if (keys->K_offset < 0L && save == NULL) {
  2243. X        save = keys;    /* found free point for insertion */
  2244. X    }
  2245. X    ++keys;
  2246. X    }
  2247. X    if (save == NULL) {
  2248. X    if (keys->K_flag == END) {
  2249. X        msg("Too many records selected");
  2250. X        return(-1);
  2251. X    }
  2252. X    save = keys;
  2253. X    if ((++keys)->K_flag != END)
  2254. X        keys->K_flag = FREE;
  2255. X    }
  2256. X    save->K_flag = GOOD;
  2257. X    save->K_offset = offset;
  2258. X    return(0);
  2259. X}
  2260. X
  2261. Xandkey(offset, keys)
  2262. Xdiskptr    offset;
  2263. Xstruct Keys    *keys;
  2264. X{
  2265. X
  2266. X    while(keys->K_flag < END) {
  2267. X    if (offset == keys->K_offset) {
  2268. X        keys->K_flag = MATCH;
  2269. X        break;
  2270. X    }
  2271. X    ++keys;
  2272. X    }
  2273. X}
  2274. X
  2275. X
  2276. Xpurgekey(keys)
  2277. Xstruct Keys    *keys;
  2278. X{
  2279. X
  2280. X    while(keys->K_flag < END) {
  2281. X    if (keys->K_flag != MATCH) {
  2282. X        keys->K_offset = -1L;
  2283. X    } else {
  2284. X        keys->K_flag = GOOD;
  2285. X    }
  2286. X    ++keys;
  2287. X    }
  2288. X}
  2289. SHAR_EOF
  2290. true || echo 'restore of findrcds.c failed'
  2291. # ============= fmt_chk.c ==============
  2292. echo 'x - extracting fmt_chk.c (Text)'
  2293. sed 's/^X//' << 'SHAR_EOF' > 'fmt_chk.c' &&
  2294. X#ifndef lint
  2295. Xstatic char Sccsid[] = "@(#)fmt_chk.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  2296. X#endif
  2297. X
  2298. X/*
  2299. X**    FMT_CHK.C
  2300. X**
  2301. X** Return 0 if field matches fmt, 1 otherwise
  2302. X**
  2303. X**/
  2304. X
  2305. X#include    <stdio.h>
  2306. X#include    "cardfile.h"
  2307. X#ifdef BSD_RE
  2308. Xextern    char    *re_comp();
  2309. Xextern    int    re_exec();
  2310. X#endif
  2311. X#ifdef SYSV_RE
  2312. Xextern    char    *regcmp();
  2313. Xextern    char    *regex();
  2314. X#endif
  2315. X#ifdef PD_RE
  2316. X#include    <regexp.h>
  2317. Xextern    regexp    *regcomp();
  2318. Xextern    int    regexec();
  2319. X#endif
  2320. X
  2321. X
  2322. Xint
  2323. Xfmt_chk(field, fmt)
  2324. Xchar    *field, *fmt;
  2325. X{
  2326. X    static char    lastval[MAXFMT];
  2327. X#ifdef BSD_RE
  2328. X    int        rc;
  2329. X#endif
  2330. X#ifdef SYSV_RE
  2331. X    char    *rc;
  2332. X    static char    *cval;
  2333. X#endif
  2334. X#ifdef PD_RE
  2335. X    int        rc;
  2336. X    static regexp *cval;
  2337. X#endif
  2338. X#ifdef NO_RE
  2339. X    return(0);
  2340. X#endif
  2341. X
  2342. X    if (fmt == NULL || *fmt == '\0')
  2343. X    return(0);
  2344. X    
  2345. X    if (strcmp(fmt, lastval) != 0) {
  2346. X    strcpy(lastval, fmt);
  2347. X#ifdef BSD_RE
  2348. X    if (re_comp(fmt) != 0) {
  2349. X#else
  2350. X    if (cval)
  2351. X        free(cval);
  2352. X# ifdef SYSV_RE
  2353. X    if ((cval = regcmp(fmt, 0)) == 0) {
  2354. X# else    /* PD_RE */
  2355. X    if ((cval = regcomp(fmt, 0)) == 0) {
  2356. X# endif
  2357. X#endif    /* BSD_RE */
  2358. X        msg("Invalid format specification");
  2359. X        return(-1);
  2360. X    }
  2361. X    }
  2362. X
  2363. X#ifdef BSD_RE
  2364. X    if ((rc = re_exec(field)) != 1) {
  2365. X    return(1);
  2366. X    }
  2367. X#endif
  2368. X#ifdef SYSV_RE
  2369. X    if ((rc = regex(cval, field)) == NULL) {
  2370. X    return(1);
  2371. X    }
  2372. X#endif
  2373. X#ifdef PD_RE
  2374. X    if ((rc = regexec(cval, field)) == NULL) {
  2375. X    return(1);
  2376. X    }
  2377. X#endif
  2378. X    return(0);
  2379. X}
  2380. X
  2381. X#ifdef PD_RE
  2382. X/* Let cardfile handle errors */
  2383. Xvoid
  2384. Xregerror(msg)
  2385. Xchar    *msg;
  2386. X{
  2387. X    return;
  2388. X}
  2389. X#endif
  2390. SHAR_EOF
  2391. true || echo 'restore of fmt_chk.c failed'
  2392. true || echo 'restore of getkey.c failed'
  2393. echo End of part 1, continue with part 2
  2394. exit 0
  2395.  
  2396.  
  2397.