home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume33 / mbase / part06 < prev    next >
Encoding:
Text File  |  1992-11-23  |  55.6 KB  |  1,683 lines

  1. Newsgroups: comp.sources.misc
  2. From: richid@owlnet.rice.edu (Richard Parvin Jernigan)
  3. Subject:  v33i124:  mbase - MetalBase 5.0, Portable database engine, Part06/08
  4. Message-ID: <1992Nov23.233014.9478@sparky.imd.sterling.com>
  5. X-Md4-Signature: ca7fc6bacc305b01846356db402f7863
  6. Date: Mon, 23 Nov 1992 23:30:14 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: richid@owlnet.rice.edu (Richard Parvin Jernigan)
  10. Posting-number: Volume 33, Issue 124
  11. Archive-name: mbase/part06
  12. Environment: AMIGA, MS-DOS, HP-UX, XENIX, UNIX, ULTRIX, SGI, SU, Curses
  13. Supersedes: mbase: Volume 28, Issue 40-44
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then feed it
  17. # into a shell via "sh file" or similar.  To overwrite existing files,
  18. # type "sh file -c".
  19. # Contents:  dox/report.dox dox/trouble.dox readme readme.too
  20. #   src/internal.h src/mbconv.c src/stdinc.h src/timedate.c
  21. # Wrapped by kent@sparky on Mon Nov 23 16:33:14 1992
  22. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  23. echo If this archive is complete, you will see the following message:
  24. echo '          "shar: End of archive 6 (of 8)."'
  25. if test -f 'dox/report.dox' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'dox/report.dox'\"
  27. else
  28.   echo shar: Extracting \"'dox/report.dox'\" \(3716 characters\)
  29.   sed "s/^X//" >'dox/report.dox' <<'END_OF_FILE'
  30. XReport Documentation                                              MetalBase 5.0
  31. X-------------------------------------------------------------------------------
  32. X
  33. XSpecial thanks to Bruce Momjian (root%candle.uucp@ls.com) for his input, and
  34. Xfor the inspiration for this utility.  This whole this is basically a
  35. Xglorified spin-off of report.c as he sent it to me when he got MB 4.0.
  36. X
  37. X                                  Function
  38. X
  39. XReport does just that; it produces reports on data found in relations, based
  40. Xon a format decided by the user in a report template.  These templates are
  41. Xexpected to have .rpt extensions and are accessed in their native form,
  42. Xwithout any pre-compilation.
  43. X
  44. XCurrently, report does not allow joins; thus, each report may only access
  45. Xone relation's data.  However, note that in the templates, fields may be
  46. Xrefered to either by "fieldname" or "relation.fieldname"; when further
  47. Xfunctionality is added, the latter will become necessary if a fieldname is
  48. Xused twice in different relations.
  49. X
  50. X                              Template Format
  51. X
  52. XThe templates are processed "on the fly", and output is produced on the
  53. Xstandard output, for redirection to a file, viewer, or printer as
  54. Xappropriate.  Output is performed in 3 stages (repeating as necessary), and
  55. Xthe template makes use of this; an example (note that spacing is rather
  56. Xirrelevant--"data test.rel;" is equivalent to what you see below):
  57. X
  58. X   Data
  59. X      test.rel;
  60. X   Size
  61. X      Columns      80; # 80-column page, regardless of margins
  62. X      Rows         66; # 66-row page (standard pagesize)
  63. X      Top Margin    4; # 4 lines for a top margin        [you don't have to
  64. X      Left Margin   8; # 8 spaces for a left margin       include any of this
  65. X      Bottom Margin 2; # 2 lines for a bottom margin      you don't want--they
  66. X      Right Margin  3; # 3 spaces for a bottom margin     all have defaults]
  67. X
  68. X   Page 5;  # Make the first page, page number 5.  Why?  Have no idea.  :)
  69. X
  70. X   Header
  71. X      print centered  : "test -- ages under 30";
  72. X      print centered  : system        # This just gives me some credits. :)
  73. X      skip 1 line
  74. X      print continued : system!date format 1, system!time format 1;
  75. X      print right     : "Page: ", system!page;
  76. X   Continue
  77. X      print centered  : "-Continued-";
  78. X   On ix_age < 30
  79. X      print           : name to 40, age, hobby;
  80. X
  81. X   Header
  82. X      print centered  : "test -- ages over 30";
  83. X      print centered  : system
  84. X      skip 1 line
  85. X      print continued : system!date format 1, system!time format 1;
  86. X      print right     : "Page: ", system!page;
  87. X   On ix_age >= 30
  88. X      print           : name to 40, age, hobby;
  89. X   Last
  90. X      print centered  : "---";
  91. X      print centered  : "Average age of all : ", age!rpt_avg;
  92. X
  93. XNote that Last and Footer sections should have the same number of lines; else,
  94. Xthe Last section will be assumed to have the same # as the Footer section, and
  95. Xyou may end up with slightly skewed paper-alignment.  Hey--it's shareware.
  96. X
  97. XThe "On" line indicates that the following instructions (between "On" and
  98. Xthe next keyword; in this case, "Last") should be executed for each record
  99. Xwhere the first field referenced by ix_age (age, in this case) is greater than
  100. Xor equal to thirty; thus, the following operation like the following is
  101. Xperformed:
  102. X
  103. X   for ( mb_sel (rel, idxnum(rel,"ix_age"), &rec, GTEQ, &[30]) ;
  104. X         mb_errno == MB_OKAY;
  105. X         mb_sel (rel, idxnum(rel,"ix_age"), &rec, NEXT, NULL) )
  106. X      {
  107. X        print  : name to 40, age, hobby;
  108. X      }
  109. X
  110. XWell, that's basically it.  Right now, the "age!rpt_avg" won't work--I
  111. Xhaven't written it.  But, if there's enough demand...
  112. X
  113. XGood luck.
  114. X
  115. XPS--If your relation is encrypted, say with the key "test", try:
  116. X   report -k test sample
  117. X
  118. END_OF_FILE
  119.   if test 3716 -ne `wc -c <'dox/report.dox'`; then
  120.     echo shar: \"'dox/report.dox'\" unpacked with wrong size!
  121.   fi
  122.   # end of 'dox/report.dox'
  123. fi
  124. if test -f 'dox/trouble.dox' -a "${1}" != "-c" ; then 
  125.   echo shar: Will not clobber existing file \"'dox/trouble.dox'\"
  126. else
  127.   echo shar: Extracting \"'dox/trouble.dox'\" \(7704 characters\)
  128.   sed "s/^X//" >'dox/trouble.dox' <<'END_OF_FILE'
  129. XTroubleshooting Hints                                             MetalBase 5.0
  130. X-------------------------------------------------------------------------------
  131. X
  132. XCan't compile
  133. X - There are several options you can add to or remove from CFLAGS= in your
  134. X   makefile.  stdinc.h will look at several compiler-generated settings to
  135. X   determine your system type and choose defaults, but they may need to be
  136. X   modified... standard machine definitions are:
  137. X         -DAMIGA      - Amiga
  138. X         -DNeXT       - NeXT
  139. X         -DCOHERENT   - COHERENT
  140. X         -DMSDOS      - Any MS-DOS compiler
  141. X         -Dapplec     - Mac Programmer's Workshop
  142. X         -Dsgi        - SGI
  143. X         -DM_SYS3     - Xenix
  144. X         -DM_SYS5     - Xenix
  145. X         -DM_7        - Xenix
  146. X   If you have a machine on the right, try adding the thing on the left to
  147. X   CFLAGS and recompiling.  If that doesn't help, read on:
  148. X
  149. X   There are several definitions which define how the code will be set up...
  150. X   of them, -DSTRUCT_# isn't necessary unless you're compiling the library
  151. X   itself:
  152. X
  153. X      -STRUCT_#........MetalBase uses this to determine which structure-packing
  154. X                       algorithm you're using; run STRUCT or STRUCT.EXE to find
  155. X                       out.  It'll tell you what to do with this.
  156. X
  157. X      -DLONGARGS.......If your machine screams about your prototypes, this may
  158. X                       be the problem.  If you don't define this, odds are the
  159. X                       prototypes MBASE will define will look like
  160. X                             void main ();
  161. X                       Define it, and you'll get
  162. X                             void main (int, char **);
  163. X
  164. X      -DSYS_FCNTL......If <fcntl.h> can't be found, try defining this--it'll
  165. X                       move the search to <sys/fcntl.h>
  166. X
  167. X      -DCHAR_IS_UNS....Most compilers define this if the default character type
  168. X                       is unsigned; some may not.  Try this if you suspect a
  169. X                       problem.
  170. X
  171. X      -DNEED_ULONG.....Most machines don't have the type "ulong"; some do.  Try
  172. X                       adding this if your compile freaks because of ulongs.
  173. X
  174. X      -DNEED_USHORT....Parallel to "ulong"; this makes a typedef for ushort.
  175. X
  176. X      -DNOVOIDPTR......Many older compilers still don't recognize "void *x;" as
  177. X                       a valid instruction--define this to change those kind of
  178. X                       declaration to "char *x;".
  179. X
  180. X      -DNON_ANSI.......If you're not using VT emulation (ANSI.SYS counts as VT
  181. X                       emulation; Amiga users have it built in to AmigaDOS),
  182. X                       define this.  Just makes Build a little prettier.
  183. X
  184. X      -DNOSYNC.........A few machines don't have fsync() or sync()--if you get
  185. X                       either as an unresolved external, add this.  MS-DOS
  186. X                       users: By default, stdinc.h tries some inline assembly.
  187. X                       If you're not running MB programs under windows, just
  188. X                       define this and it won't... otherwise, you may want to
  189. X                       try to get that translated to whatever works for you.
  190. X
  191. XMB_BUSY (Relation is too busy--if returned by a call other than mb_inc())
  192. X - Only thirty operations may be processed simultaneously--and this was
  193. X   number thirty one.  Try again in a second or two.
  194. X
  195. XMB_BUSY (Relation is too busy--if returned by mb_inc()) or
  196. XMB_LOCKED (Relation is locked by another user)
  197. X - If you're stuck by one of these, try the utility blast -- it erases the
  198. X   record of the number of users on a relation.  But the cause is still there:
  199. X   you may want to check your programs to make sure each terminates with
  200. X   mb_die() [ MBCloseAllRelations() ] or mb_exit(), or just mb_rmv()'ing all
  201. X   the relations you've used... if a relation isn't closed properly, its count
  202. X   will increase each time you use the thing, until it's got 255 users and won't
  203. X   let you add any more.  Then, you've gotta blast it.
  204. X
  205. XMB_NO_OPEN (Cannot open given filename) or
  206. XMB_NO_READ (Cannot read given filename)
  207. X - MetalBase does not use any evironment variables to check for possible
  208. X   directories for relations; it expects a full pathname if one is required.
  209. X   MB_NO_OPEN usually means the file can't be found; while MB_NO_READ means
  210. X   mb_inc() can't read the initial signature at all from the relation--possibly
  211. X   permissions, or a 0-length file.
  212. X
  213. XMB_FORMAT (Relation is not in MetalBase 4.0+ format)
  214. X - Gods.  Good luck.  This is caused if
  215. X    a) the initial signature (see format.dox) isn't (char)40 or (char)41, or
  216. X    b) the fields in the relation don't make sense, or
  217. X    c) the indices....
  218. X   basically, this is your generic "THIS SHOULDN'T HAVE HAPPENED!!!" error.
  219. X   If you get it, make _sure_ you're opening the right file, for starters:
  220. X   always pass mb_inc() the name of the file WITHOUT the extension.  I don't
  221. X   trust the extension bit...
  222. X
  223. XMB_TIMEOUT (Temporary lock has not been removed)
  224. X - MetalBase sets temporary locks on relations during add/delete/update/search
  225. X   operations--when a temporary lock has been placed on a relation, other
  226. X   commands wait for a set amount of time for the relation to be unlocked--
  227. X   this process is normally transparent to the user.  Though these waiting
  228. X   periods are kept as small as possible (obviously), under very peculiar
  229. X   situations, a program may be interrupted while a lock is still in place.
  230. X   On other occasions, two commands may have been issued nearly simultaneously,
  231. X   and the lock will be almost ready to remove when the second command gives
  232. X   up.  If you receive this error, you should try your command again--failing
  233. X   that, execute mb_rst(1) or use blast to remove the temporary lock.
  234. X
  235. XMB_DISKFULL (Not enough disk space left)
  236. X - mbconv requires again as much free space as the size of the relatation being
  237. X   converted; if you don't have that much, it'll stop the conversion.  Note
  238. X   that no check is made for enough free space before conversion so make sure
  239. X   yourself before you start, or 10 minutes into its work it may stop with this
  240. X   error.
  241. X
  242. XMB_TMPDIR (You must define a TMP directory)
  243. X - On some systems, MetalBase requires that you have the environment variable
  244. X   TMP set to an appropriate directory for temporary files; for example,
  245. X      TMP=/tmp; export TMP
  246. X   or
  247. X      set TMP=C:\TMP
  248. X   If you prefer, you can use the variable "TEMP" instead.
  249. X
  250. XMB_TMPERR (Cannot work with TMP directory)
  251. X - In order to control concurrency problems, MetalBase 5.0 uses a rather
  252. X   complex system of locking, which involves many busy loops of ReadByte,
  253. X   CheckByte, ReadByte and so on.  That kind of work really, really slows
  254. X   down access to a relation, so the locking mechanism has been moved off
  255. X   to a separate file.  This file is named after the relation, with the
  256. X   extension replaced with ".LCK", and is placed in the temporary directory
  257. X   given as per MB_TMPDIR (explained right above this).  This file is
  258. X   created every time mb_inc() is called, if it does not already exist...
  259. X   if it cannot be created, or opened for read/write access, this error
  260. X   is returned.  Try moving the temporary directory to another location.
  261. X
  262. XToo many relations--see trouble.dox
  263. XToo many fields--see trouble.dox
  264. X - Form has two manifest constants, MAXnREL and MAXnFLD.  These are defined
  265. X   for 5.0 to be 20 and 40 respectively; if you have more than 20 relations
  266. X   in a given data-entry template, add -DMAXnREL=30, etc, to CFLAGS in the
  267. X   Makefile and recompile.
  268. X
  269. XReport doesn't quite look like the template
  270. X - Check your semicolons.  Every print statement, every skip statement;
  271. X   hell, most statements, will freak if they don't end in a semicolon, and
  272. X   different systems freak in different ways.  :)
  273. X
  274. END_OF_FILE
  275.   if test 7704 -ne `wc -c <'dox/trouble.dox'`; then
  276.     echo shar: \"'dox/trouble.dox'\" unpacked with wrong size!
  277.   fi
  278.   # end of 'dox/trouble.dox'
  279. fi
  280. if test -f 'readme' -a "${1}" != "-c" ; then 
  281.   echo shar: Will not clobber existing file \"'readme'\"
  282. else
  283.   echo shar: Extracting \"'readme'\" \(7107 characters\)
  284.   sed "s/^X//" >'readme' <<'END_OF_FILE'
  285. X                              ___                     _____      _____
  286. X        |  |     |        |  |   )                   /          /    /
  287. X        |`'|  _ -|-  _   ||  |  '_   _   .-.  _     /          /    /
  288. X        |  | ( ) |  ( \  `|  |    ) ( \  `-. ( )   `---.      /    /
  289. X           | -'--`-- - `-' \/ ---' - - `-`- --'--      /  <> /    /
  290. X___________________________/\_____________________`.__/_____/____/_____________
  291. X
  292. X                              Please read the dox  /
  293. X                                                  '
  294. X
  295. X
  296. XWHAT'S NEW IN THIS RELEASE:
  297. X
  298. X    o SPEED
  299. X         MetalBase 5.0 destroys even 4.1a speed-wise; queries are the same
  300. X         speed, but adds/updates/deletes are always at least twice as fast, and
  301. X         often over three times as fast!  Internal caching of index pointers
  302. X         just makes the whole world turn 'round better...
  303. X
  304. X    o CONVERSION
  305. X         The utility MBCONV will convert 4.0 and 4.1a relations to 5.0 format.
  306. X         It is absolutely perfectly safe, but requires that you have enough
  307. X         free space to essentially make a copy of the relation.
  308. X
  309. X    o LOCKING
  310. X         Previously, unless you compiled with -DUNIX_LOCKS (and had a *nix
  311. X         machine), bad things would happen if a program shut down while
  312. X         something was being changed.  Now, since all indices are written at
  313. X         once (caching is so nice), chances of corruption are much smaller; and
  314. X         if a process does shut down with a system-placed lock in place, the
  315. X         next process will detect the condition and remove the lock, and
  316. X         decrement the number of users.  A request queue has also been built
  317. X         in, so that processes will always get equal timeshares.
  318. X
  319. X    o CREATE ON-THE-FLY
  320. X         You can now design and create a relation at run-time:
  321. X            rel = mb_new();
  322. X            mb_addfield (rel, "Customer's last name",  T_CHAR,   15);
  323. X            mb_addfield (rel, "Customer's first name", T_CHAR,   10);
  324. X            mb_addfield (rel, "Customer's number",     T_SERIAL, 40);
  325. X            mb_addindex (rel, "ix_name",   1, "0,1");
  326. X            mb_addindex (rel, "ix_number", 1, "2");
  327. X            mb_create (rel, "/usr/joe/simple.rel", 0);
  328. X         Check out the code for BUILD and MBCONV; they both use it.
  329. X
  330. X    o SIMPLE PHONE NUMBERS
  331. X         The schema type "phone" (C typedef == "mb_phone") has been added to
  332. X         5.0 to make handling of phone numbers easier; phone types accept area
  333. X         codes (of course), and extensions up to x99999.  The routines
  334. X         scn_phone() and fmt_phone() are included for quick handling of phone
  335. X         numbers, just as scn_ and fmt_ are provided for date and time!
  336. X
  337. X    o ENCRYPTION
  338. X         Encryption is now working for everyone, even MS-DOS users.  Be
  339. X         careful, though--I'm haphazard enough with encryption that, for
  340. X         example, a bad encryption key passed to VR under DOS will usually
  341. X         make you reboot your machine; under *nix it'll usually cause a seg
  342. X         violation.  Now THAT's encryption.  :)
  343. X
  344. X    o DOCUMENTATION
  345. X         The documentation, though still not perfect, is much more up to date
  346. X         than it was for the 4.0 release.  Included here are:
  347. X
  348. X            dox/mbase.dox   -- General documentation (the important stuff)
  349. X
  350. X            dox/author.dox  -- Information on where the hell I can be reached
  351. X            dox/build.dox   -- Information on schema and their compiler, build
  352. X            dox/crypt.dox   -- Information on MetalBase's encryption technique
  353. X            dox/flow.dox    -- Pseudocode for MetalBase's AVL-tree algorithms
  354. X            dox/format.dox  -- Character-by-character format for relations
  355. X            dox/lock.dox    -- Information on MetalBase's locking algorithms
  356. X            dox/struct.dox  -- Information on C structure interface
  357. X            dox/report.dox  -- Incomplete documentation on the report writer
  358. X            dox/trouble.dox -- Troubleshooting ideas (not too many--sorry)
  359. X
  360. X    o NO DAMNED DEBUGGING TRAILS
  361. X         If you got this release hoping I'd leave some debugging trails in the
  362. X         code again, BZZZZZT!  Sorry, but I'm only allowed to fuck up like that
  363. X         once a year.  I really, really feel stupid about that...
  364. X
  365. X
  366. X
  367. X
  368. XHOW TO BUILD THE STUPID THING:
  369. X
  370. X    o Go to the SRC directory.
  371. X
  372. X    o If you're using *nix.............type "MAKE"
  373. X      If you're using Microsoft C......type "NMAKE -f makefile.dos"
  374. X      If you're using something else...pick either makefile and modify it.
  375. X
  376. X    o It'll compile and run STRUCT (or STRUCT.EXE), which will tell you that
  377. X      you're either screwed, or what to change in the makefile to make the
  378. X      library appropriately for your compiler.  If you're screwed, send me
  379. X      mail (see dox/author.dox).  If you're not, do as it says.
  380. X
  381. X    o Check the makefile to make sure it's going to put the headers, library
  382. X      and executables wherever you want it to.
  383. X
  384. X    o Type "MAKE INSTALL" (or "NMAKE -f makefile.dos INSTALL" for Microsoft C).
  385. X
  386. X    o It'll compile the library and executables, and put them where you said
  387. X      to.
  388. X
  389. X    o If you have any relations from MetalBase 4.0 or MetalBase 4.1a, go to
  390. X      where they are and type "MBCONV relationname".  It'll convert them to
  391. X      5.0 (and hopefully the final) format and tell you it's done (it's really
  392. X      quick, but IRREVERSABLE).
  393. X
  394. X
  395. X
  396. X
  397. XWHAT TOYS YOU GET:
  398. X
  399. X    o BLAST.EXE - Removes locks accidentally left around on a relation; sets
  400. X      the internal number-of-users-on-this-relation to zero.
  401. X
  402. X    o BUILD.EXE - Compiles relations from schema files; erases all records
  403. X      in a relation.
  404. X
  405. X    o FORM.EXE - Builds header files from data-entry templates; the DE
  406. X      interface is really, really easy to program.  It's not perfect, but
  407. X      it's nice.
  408. X
  409. X    o MBCONV.EXE - Converts pre-5.0 relations to 5.0 format.  Works great!
  410. X
  411. X    o REPORT.EXE - Generates reports from template files, interpereted at
  412. X      run-time.
  413. X
  414. X    o VR.EXE - View Relation--one of my favorite toys.  4.0 users, NON-VI
  415. X      emulation is now the default; it's much, MUCH easier to add and change
  416. X      records.  The basics of the new DE keys are:
  417. X            CTRL-A, CTRL-return - Accept a transaction
  418. X            CTRL-Q, CTRL-C      - Abort a transaction
  419. X            CTRL-U,             - Undo a change within a field
  420. X            Arrows, End, Home   - As expected
  421. X
  422. X
  423. X
  424. X
  425. XHOW TO PLAY WITH THE STUPID THING:
  426. X
  427. X   I've included two programs with this; SAMPLE and BENCH.  BENCH is just a
  428. X   benchmark utility (see sample/readme), but SAMPLE is meant to be example
  429. X   code, for hooking up the (suggested) data-entry interface, for adding/
  430. X   deleting/changing records, etc.
  431. X
  432. X   Go to the directory SAMPLE and pick-n-edit a makefile.  Note that you
  433. X   don't need -DSTRUCT_ in these; that's just for building the library.  But
  434. X   you WILL need -DNEED_USHORT if your compiler doesn't contain ushort, etc.
  435. X
  436. X
  437. X
  438. X
  439. X-------------------------------------------------------------------------------
  440. X                                                               Richid
  441. X-------------------------------------------------------------------------------
  442. X
  443. END_OF_FILE
  444.   if test 7107 -ne `wc -c <'readme'`; then
  445.     echo shar: \"'readme'\" unpacked with wrong size!
  446.   fi
  447.   # end of 'readme'
  448. fi
  449. if test -f 'readme.too' -a "${1}" != "-c" ; then 
  450.   echo shar: Will not clobber existing file \"'readme.too'\"
  451. else
  452.   echo shar: Extracting \"'readme.too'\" \(4877 characters\)
  453.   sed "s/^X//" >'readme.too' <<'END_OF_FILE'
  454. XDonateware                                                        MetalBase 5.0
  455. X-------------------------------------------------------------------------------
  456. X
  457. X    Hiya.  This is the part where I whine about how our country's going down
  458. Xthe tubes and it's probably because no one ever pays for shareware anymore.
  459. X
  460. X    I have designed and written all the versions of MetalBase.  The database
  461. Xengine itself is of my own design and implementation, though there are several
  462. Xpeople to whom I am indebted for input and testing of the engine, and
  463. Xsuggestions for development of supporting utilites:
  464. X
  465. XJohn Steele       -- jsteele@netcom.netcom.com        -- Beta Testing / Input
  466. XLarry A Keber     -- lak@world.std.com                -- Beta Testing / Input
  467. XMarlin Sheffield  -- marlin@thelink.rn.com            -- Beta Testing / Input
  468. XWarlock           -- warlock@coco.ca.rop.edu          -- Beta Testing / Input
  469. XMike Cuddy        -- mcuddy@fensende.Rational.COM     -- Miscellaneous ideas
  470. XBruce Momjian     -- jabber!candle!root@dsinc.dsi.com -- Reporting
  471. XAdrian Corston    -- adrian@internode.com.au          -- Data-entry
  472. XRobert S          -- roseg@taurus.bitnet              -- 4.1a *nix file locking
  473. X
  474. X    I learned most of what I know of programming (such as it is) through
  475. Xexamples from various people, which were distributed freely.  As such, I feel
  476. Xit's only right for me to try to contribute this, the only thing I can think
  477. Xof which anyone might want, to the public.  I would therefore like to
  478. Xdistribute this freely and without restriction.
  479. X    HOWEVER, I'm also dead broke... so, I'm releasing this as shareware.  The
  480. Xconditions are a little unusual, though... hummm.  Not really shareware.  Let's
  481. Xcall it donateware:
  482. X
  483. X  * Don't send any money at all -unless- you truly feel it's worth it.  I think
  484. X    this is a useful enough package that it should be made more freely
  485. X    available, and don't wanna limit propogation by putting "send money to
  486. X    me!" labels on everything.  If you like it, though, and wanna send $$ to
  487. X    me, I'm certainly not going to complain.  I've made a few hundred off of
  488. X    all my releases of MetalBase total, over several years... and 4.0 alone is
  489. X    installed at hundreds of sites literally around the globe (just how many
  490. X    internet users ARE there in Australia?).  So don't feel compelled at all.
  491. X
  492. X  * Give it to as many people as possible.  I mean it--if you like the
  493. X    distribution, put it up on a local board or ftp site, or post it to a
  494. X    group.  It's so hard to get good distribution these days...
  495. X
  496. X  * Tell me about any bugs you find (God forbid -- you wouldn't _believe_ how
  497. X    many tests this thing has been through).  This works really well; I still
  498. X    do support for all MB stuff, and often end up debugging other code.  It's
  499. X    fine by me, so if you can track me down, lemme know what you've run up
  500. X    against.
  501. X
  502. X  * Leave the existing documentation intact.  Add more if you'd like, but leave
  503. X    what's already there.  Feel free to add sample programs and relations if
  504. X    you like--they always help.
  505. X
  506. X  * Leave the credits.  I'm vain and I'm poor, and the publicity for me might
  507. X    do me good; if not for my wallet, at least for my ego.
  508. X
  509. X  * Send any modifications to the enclosed code to me.  More importantly, SEND
  510. X    IDEAS!  If you'd like an improvement, tell me about it!  Whether or not you
  511. X    modify the code yourself, I'd like to know what's being done to it.  Most
  512. X    of the additions to MetalBase have come about from things like this (the
  513. X    report writer, the data-entry interface, etc), so it really works.  Keep
  514. X    'em coming...
  515. X
  516. X  * If you feel an urge to reach into your wallet and send me money, as I
  517. X    said, I'm going to be the last to complain.  My address is:
  518. X                   Richid Jernigan IV
  519. X                   PO Box 827
  520. X                   Norris, TN  37828   <- Yes, folks, he's from TN! <Speee-it!>
  521. X    Gimme a name and a mailing address (internet or bitnet account names are
  522. X    fine -- just so I can distribute code / information), and you'll receive
  523. X    the following (no guarantees, but I'll try):
  524. X       - Any new versions of MetalBase, whenever they pop up (provided I don't
  525. X         lose my stupid registration list like I did after 4.1a--sorry
  526. X         everyone!)
  527. X       - The privilege of being able to request modifications or development
  528. X         of any of the previously-mentioned utilities (which will be sent to
  529. X         everyone on the list when available)
  530. X       - The privilege of being able to demand fixes to any bugs you find (now
  531. X         wouldn't _that_ be fun?)
  532. X       - A big smiley from me (worth it, isn't it?  Wreeetch!)
  533. X
  534. X-------------------------------------------------------------------------------
  535. X                                                               Richid
  536. X-------------------------------------------------------------------------------
  537. X
  538. END_OF_FILE
  539.   if test 4877 -ne `wc -c <'readme.too'`; then
  540.     echo shar: \"'readme.too'\" unpacked with wrong size!
  541.   fi
  542.   # end of 'readme.too'
  543. fi
  544. if test -f 'src/internal.h' -a "${1}" != "-c" ; then 
  545.   echo shar: Will not clobber existing file \"'src/internal.h'\"
  546. else
  547.   echo shar: Extracting \"'src/internal.h'\" \(7196 characters\)
  548.   sed "s/^X//" >'src/internal.h' <<'END_OF_FILE'
  549. X/*
  550. X * METALBASE 5.0
  551. X *
  552. X * Released October 1st, 1992 by Huan-Ti [ richid@owlnet.rice.edu ]
  553. X *                                       [ t-richj@microsoft.com ]
  554. X */
  555. X
  556. X#ifndef INTERNAL_H
  557. X#define INTERNAL_H
  558. X
  559. X/*
  560. X * RELATION FORMAT ----------------------------------------------------------
  561. X *
  562. X */
  563. X
  564. X#define POS_SIGNATURE  0L   /* This information is described in */
  565. X#define POS_UNUSED1    1L   /* more detail in the file          */
  566. X#define POS_UNUSED2    2L   /*    ../dox/format.dox             */
  567. X#define POS_UNUSED3    4L
  568. X#define POS_FIELDPTR(x) (x == 40 ? 2L : 6L)  /* For 4.0 compatibility */
  569. X#define POS_INDEXPTR  10L
  570. X#define POS_RECZERO   14L
  571. X#define POS_NUMREC    18L
  572. X#define POS_NEXTSER   22L
  573. X#define POS_NUMFIELD  26L
  574. X#define POS_NUMINDEX  28L
  575. X#define POS_INDICES   30L
  576. X
  577. X#define lckPOS_USERS    0L   /* more detail in the file          */
  578. X#define lckPOS_ELOCK    2L   /*    ../dox/format.dox             */
  579. X#define lckPOS_HLOCK    4L
  580. X#define lckPOS_QUEUE   10L
  581. X#define lckPOS_STROBE  70L
  582. X
  583. X/*
  584. X * INTERNAL STRUCTURE DEFINITIONS AND UTILITIES -----------------------------
  585. X *
  586. X */
  587. X
  588. Xtypedef struct
  589. X   {
  590. X   long    num;
  591. X   long    left, right, parent;
  592. X   char    parbal;
  593. X   int     changed;
  594. X   } cache;
  595. X
  596. X#define _change_cache(p,f,v)   { p->changed = 1; _changeqcache(p,f,v); }
  597. X#define _changeqcache(p,f,v)     p->f = v
  598. X#define _cache_field(p,d) (d==1?p->right: (d==-1?p->left : p->parent))
  599. X
  600. X#ifndef BLAST_C
  601. X#ifdef LONGARGS
  602. X   extern relation  *_fill_info   (relation *, long, long);
  603. X   extern long       _append      (relation *, dataptr);
  604. X   extern mb_err     _balance     (relation *, long,    int,     int);
  605. X   extern mb_err     _check       (relation *, long,    long,    int);
  606. X   extern mb_err     _check_dup   (relation *, dataptr, int,     long);
  607. X   extern void       _close_proc  (relation *);
  608. X   extern mb_err     _clr_lck     (relation *);
  609. X   extern int        _comp_double (double *, double *);
  610. X   extern int        _comp_fld    (relation *, dataptr, dataptr, int);
  611. X   extern int        _comp_float  (float  *, float  *);
  612. X   extern int        _comp_long   (long   *, long   *);
  613. X   extern int        _comp_short  (short  *, short  *);
  614. X   extern int        _comp_string (char   *, char   *, int);
  615. X   extern int        _comp_ulong  (ulong  *, ulong  *);
  616. X   extern int        _comp_ushort (ushort *, ushort *);
  617. X   extern int        _compare     (relation *, dataptr, dataptr, int);
  618. X   extern void       _crypt       (relation *, dataptr);
  619. X   extern void       _cryptf      (dataptr,    int,     int);
  620. X   extern long       _delete      (relation *, long);
  621. X   extern void       _dislink     (relation *, long, int,  long);
  622. X   extern void       _divine_mask (relation *, int);
  623. X   extern void       _drop        (relation *, long,    int,     long);
  624. X   extern void       _dumprec     (relation *, dataptr);
  625. X   extern long       _find_ends   (relation *, int,  int);
  626. X   extern long       _find_seq    (relation *, long, long, int,  int);
  627. X   extern mb_err     _format      (relation *, dataptr, int);
  628. X   extern int        _identify    (relation *);
  629. X   extern mb_err     _link        (relation *, long);
  630. X   extern dataptr    _memrec      (relation *, long, dataptr);
  631. X   extern dataptr    _rec         (relation *, long);
  632. X   extern void       _remove      (relation *, long);
  633. X   extern void       _replace     (relation *, long, long, int);
  634. X   extern long       _search      (relation *, long, int,  mb_action, dataptr);
  635. X   extern mb_err     _set_lck     (relation *);
  636. X   extern void       _seterr      (int);
  637. X   extern void       _strobe      (relation *, int);
  638. X   extern void       _zero        (relation *, long, int);
  639. X   extern cache     *_read_cache  (relation *, long, int);  /* CACHE.C */
  640. X   extern void       _flush_cache (relation *,       int);  /* CACHE.C */
  641. X   extern cache     *_new_cache   (relation *,       int);  /* CACHE.C */
  642. X   extern void       _free_cache  (void);                   /* CACHE.C */
  643. X#else
  644. X   extern relation  *_fill_info();
  645. X   extern long       _append();
  646. X   extern mb_err     _balance();
  647. X   extern mb_err     _check();
  648. X   extern mb_err     _check_dup();
  649. X   extern void       _close_proc();
  650. X   extern mb_err     _clr_lck();
  651. X   extern int        _comp_double();
  652. X   extern int        _comp_fld();
  653. X   extern int        _comp_float();
  654. X   extern int        _comp_long();
  655. X   extern int        _comp_short();
  656. X   extern int        _comp_string();
  657. X   extern int        _comp_ulong();
  658. X   extern int        _comp_ushort();
  659. X   extern int        _compare();
  660. X   extern void       _crypt();
  661. X   extern void       _cryptf();
  662. X   extern long       _delete();
  663. X   extern void       _dislink();
  664. X   extern void       _divine_mask();
  665. X   extern void       _drop();
  666. X   extern void       _dumprec();
  667. X   extern long       _find_ends();
  668. X   extern long       _find_seq();
  669. X   extern mb_err     _format();
  670. X   extern int        _identify();
  671. X   extern mb_err     _link();
  672. X   extern dataptr    _memrec();
  673. X   extern dataptr    _rec();
  674. X   extern void       _remove();
  675. X   extern void       _replace();
  676. X   extern long       _search();
  677. X   extern mb_err     _set_lck();
  678. X   extern void       _seterr();
  679. X   extern void       _strobe();
  680. X   extern void       _zero();
  681. X   extern cache     *_read_cache();     /* CACHE.C */
  682. X   extern void       _flush_cache();    /* CACHE.C */
  683. X   extern cache     *_new_cache();      /* CACHE.C */
  684. X   extern void       _free_cache();     /* CACHE.C */
  685. X#endif
  686. X
  687. X#define GO_BASE(rel,rcd,idx,off) \
  688. X lseek (rel->relcode,          \
  689. X        rel->recz+(rcd-1)*(rel->rec_len+(long)13*rel->num_i)+(long)13*idx+off,0)
  690. X#define GO_TOP(rel,idx)  lseek (rel->relcode, POS_INDICES + (long)4*idx, 0)
  691. X#define GO_NEXTS(rel)    lseek (rel->relcode, POS_NEXTSER, 0)
  692. X#define GO_INDEX(rel,rcd,idx)    GO_BASE (rel, rcd,        idx,  0L)
  693. X#define GO_START(rel,rcd)        GO_BASE (rel, rcd,          0,  0L)
  694. X#define GO_RECID(rel,rcd)        GO_BASE (rel, rcd, rel->num_i,  0L)
  695. X#define GO_BAL(rel,rcd,idx)      GO_BASE (rel, rcd,        idx, 12L)
  696. X#define GO_POINT(rel,rcd,idx,d) \
  697. X                GO_BASE (rel, rcd, idx, (((d)==-1)?0L:((d)==1?4L:8L)) )
  698. X
  699. X#define PARDIR (int)0x80
  700. X#define BAL    (int)0x7F
  701. X
  702. X#define BAL_FL ';'    /* Balance == Far Left  (off balance) */
  703. X#define BAL_LT '<'    /* Balance == Left      (on balance)  */
  704. X#define BAL_EV '='    /* Balance == Even :-]  (ON balance)  */
  705. X#define BAL_RT '>'    /* Balance == Right     (on balance)  */
  706. X#define BAL_FR '?'    /* Balance == Far Right (off balance) */
  707. X
  708. X#define VAL_BAL(b)  ((int)(b-BAL_EV))
  709. X
  710. X#define NUM_BAL(b)  (b==BAL_FL?-1:(b==BAL_LT?-1:(b==BAL_EV?0:(b==BAL_RT?1:1))))
  711. X#define BALANCED(b) (b==BAL_LT || b==BAL_EV || b==BAL_RT)
  712. X
  713. X#define togg(x) (x = 0-x)
  714. X
  715. X#define lckerr(r,e,x)  { _clr_lck(r); _seterr(e); return (mb_err)(x); }
  716. X#define baderr(x)      {              _seterr(x); return (mb_err)(x); }
  717. X#define reterr(e,x)    {              _seterr(e); return (mb_err)(x); }
  718. X#define interr(e,x)    {              _seterr(e); return    (int)(x); }
  719. X#define longerr(e,x)   {              _seterr(e); return   (long)(x); }
  720. X#define relerr(e,x)    {              _seterr(e); return (relation *)(x); }
  721. X
  722. X#define round2(x) (x%2==0?x:(x+2-(x%2)))
  723. X#define round4(x) (x%4==0?x:(x+4-(x%4)))
  724. X#define round8(x) (x%8==0?x:(x+8-(x%8)))
  725. X#endif
  726. X
  727. X#endif
  728. X
  729. END_OF_FILE
  730.   if test 7196 -ne `wc -c <'src/internal.h'`; then
  731.     echo shar: \"'src/internal.h'\" unpacked with wrong size!
  732.   fi
  733.   # end of 'src/internal.h'
  734. fi
  735. if test -f 'src/mbconv.c' -a "${1}" != "-c" ; then 
  736.   echo shar: Will not clobber existing file \"'src/mbconv.c'\"
  737. else
  738.   echo shar: Extracting \"'src/mbconv.c'\" \(7523 characters\)
  739.   sed "s/^X//" >'src/mbconv.c' <<'END_OF_FILE'
  740. X/*
  741. X * METALBASE 5.0
  742. X *
  743. X * Released October 1st, 1992 by Huan-Ti [ richid@owlnet.rice.edu ]
  744. X *                                       [ t-richj@microsoft.com ]
  745. X */
  746. X
  747. X#include "mbase.h"
  748. X#include "internal.h"  /* Because we do some non-standard record moving */
  749. X
  750. X#ifdef LONGARGS
  751. X   void   main       (int,        char **);
  752. X   mb_err convert    (relation *, relation *);
  753. X   void   finalize   (char *,     char *);
  754. X   int    renamefile (char *,     char *);
  755. X#else
  756. X   void   main();
  757. X   mb_err convert();
  758. X   void   finalize();
  759. X   int    renamefile();
  760. X#endif
  761. X
  762. Xrelation *old;
  763. Xrelation *new;
  764. X
  765. Xchar    tempname[128];
  766. X
  767. Xvoid
  768. Xmain  (argc, argv)
  769. Xint    argc;
  770. Xchar **argv;
  771. X{
  772. X   char *str;
  773. X   int   done = 0;
  774. X
  775. X   for (--argc,++argv; argc; --argc,++argv)
  776. X      {
  777. X      if (*(str = *argv) == '-')
  778. X         {
  779. X         fprintf (stderr, "mbconv: option %s unrecognized.%s", 1+str, SNGCR);
  780. X         continue;
  781. X         }
  782. X
  783. X      done = 1;
  784. X
  785. X      if ((old = mb_old (str, 0)) == RNULL)
  786. X         {
  787. X         fprintf (stderr, "mbconv: %s: %s.%s", str, mb_error, SNGCR);
  788. X         continue;
  789. X         }
  790. X
  791. X      if (old->ver == verCURRENT)
  792. X         {
  793. X         fprintf (stderr, "mbconv: %s is already in 5.0 format.%s", str,SNGCR);
  794. X         MB_RemoveRelation (old);
  795. X         continue;
  796. X         }
  797. X
  798. X      if ((new = mb_new ()) == RNULL)
  799. X         {
  800. X         fprintf (stderr, "mbconv: %s.%s", mb_error, SNGCR);
  801. X         mb_die();
  802. X         continue;
  803. X         }
  804. X
  805. X      strcpy (tempname, str);
  806. X      if (! strncmp (&tempname[strlen(tempname)-4], ".rel", 4))
  807. X         {
  808. X         tempname[strlen(tempname)-4] = 0;
  809. X         }
  810. X      strcat (tempname, ".tmp");
  811. X
  812. X      if (convert (new, old) == MB_OKAY)
  813. X         {
  814. X         finalize (tempname, str);  /* Removes original and renames new */
  815. X         }
  816. X      else
  817. X         {
  818. X         fprintf (stderr, "mbconv: %s.%s", mb_error, SNGCR);
  819. X         }
  820. X
  821. X                   /* BECAUSE WE USED MB_NEW(), FREE IT. DON'T DO THIS */
  822. X      free (new);  /* WITH ANY OTHER RELATION!!!  mb_die() won't free  */
  823. X                   /* the memory for a relation made with mb_new().    */
  824. X
  825. X      MB_RemoveRelation (old);  /* Maybe it's still open, maybe not. */
  826. X      }
  827. X
  828. X   if (! done)
  829. X      {
  830. X      fprintf (stderr, "format: mbconv oldrelation [oldrelation...]%s", SNGCR);
  831. X      mb_exit (1);
  832. X      }
  833. X
  834. X   mb_exit (0);
  835. X}
  836. X
  837. Xmb_err
  838. Xconvert  (new,  old)
  839. Xrelation *new, *old;
  840. X{
  841. X   long    nexts, numrec, arg;
  842. X   char    desc[128], temp[5], t2[5];
  843. X   char   *ptr;
  844. X   int     i, j, n, len;
  845. X
  846. X   lseek (old->relcode, 12L +POS_FIELDPTR(old->ver), 0);
  847. X   readx (old->relcode, &numrec, 4);
  848. X   readx (old->relcode, &nexts,  4);
  849. X
  850. X/*
  851. X * First, the fields...
  852. X *
  853. X */
  854. X
  855. X   for (i = 0; i < old->num_f; i++)
  856. X      {
  857. X      arg = 0L;
  858. X
  859. X      if (old->type[i] == T_SERIAL)    arg = nexts;
  860. X      else
  861. X         if (old->type[i] == T_CHAR)   arg = old->siz[i];
  862. X
  863. X      if (mb_addfield (new, old->name[i], old->type[i], arg) != MB_OKAY)
  864. X         return mb_errno;
  865. X      }
  866. X
  867. X/*
  868. X * Next, the indices...
  869. X *
  870. X */
  871. X
  872. X   for (i = 0; i < old->num_i; i++)
  873. X      {
  874. X      desc[0] = 0;
  875. X      strzcpy (temp, old->idxs[i], 3);
  876. X      n = atoi (temp);
  877. X
  878. X      for (j = 0; j < n; j++)
  879. X         {
  880. X         strzcpy (temp, &old->idxs[i][3+ j*3], 3);
  881. X         sprintf (t2, "%d", (int)atoi (temp));
  882. X
  883. X         if (j != 0)  strcat (desc, ",");
  884. X         strcat (desc, t2);
  885. X         }
  886. X
  887. X      if (mb_addindex (new, old->iname[i], old->itype[i], desc) != MB_OKAY)
  888. X         return mb_errno;
  889. X      }
  890. X
  891. X/*
  892. X * Now create it, and open the resulting file...
  893. X *
  894. X */
  895. X
  896. X   if (mb_create (new, tempname, 0) != MB_OKAY)
  897. X      {
  898. X      unlink (tempname);
  899. X      return mb_errno;
  900. X      }
  901. X
  902. X   if ((new->relcode = openx (tempname, OPENMODE)) <= 0)
  903. X      {
  904. X      unlink (tempname);
  905. X      baderr (MB_NO_READ);
  906. X      }
  907. X
  908. X/*
  909. X * The number of records is reset to zero inside the new relation, so since
  910. X * we read it from the old relation earlier, write it out where it needs to
  911. X * be (see why I had to include internal.h?).  Oh, and grab a buffer big
  912. X * enough to move an entire record, with indices intact...
  913. X *
  914. X */
  915. X
  916. X   lseek (new->relcode, 12L +POS_FIELDPTR(verCURRENT), 0);
  917. X   writx (new->relcode, &numrec, 4);
  918. X
  919. X   len = (int)(old->rec_len +13L*(old->num_i));
  920. X
  921. X   if ((ptr = (char *)malloc (len +1)) == NULL)
  922. X      {
  923. X      close (new->relcode);
  924. X      unlink (tempname);
  925. X      baderr (MB_NO_MEMORY);
  926. X      }
  927. X
  928. X/*
  929. X * Great.  Problem is, the new header is bigger than older versions... so
  930. X * read each record, and write it out at the new place in the new relation.
  931. X * Record numbers are offsets relative to ->recz, so they won't have to change
  932. X * this way.
  933. X *
  934. X * We also have to initialize the top-of-index pointers, which aren't set
  935. X * by mb_create() (obviously).
  936. X *
  937. X */
  938. X
  939. X   lseek (old->relcode, 24+ POS_FIELDPTR(old->ver),   0);
  940. X   lseek (new->relcode, 24+ POS_FIELDPTR(verCURRENT), 0);
  941. X
  942. X   for (i = 0; i < old->num_i; i++)
  943. X      {
  944. X      readx (old->relcode, &arg, 4);
  945. X      writx (new->relcode, &arg, 4);
  946. X      }
  947. X
  948. X
  949. X   lseek (old->relcode, old->recz, 0);
  950. X   lseek (new->relcode, new->recz, 0);
  951. X
  952. X   for (arg = 0L; arg < numrec; arg++)  /* arg == which number we're moving */
  953. X      {
  954. X      if ((readx (old->relcode, ptr, len)) != len)
  955. X         {
  956. X         free (ptr);
  957. X         close (new->relcode);
  958. X         unlink (tempname);
  959. X         baderr (MB_CORRUPT);
  960. X         }
  961. X      if ((writx (new->relcode, ptr, len)) != len)
  962. X         {
  963. X         free (ptr);
  964. X         close (new->relcode);
  965. X         unlink (tempname);
  966. X         baderr (MB_DISKFULL);
  967. X         }
  968. X      }
  969. X
  970. X   free (ptr);
  971. X   close (new->relcode);     /* Close this filehandle.  */
  972. X   MB_RemoveRelation (old);  /* Unnecessary now.        */
  973. X   baderr (MB_OKAY);
  974. X}
  975. X
  976. Xint
  977. Xrenamefile (new, old)
  978. Xchar       *new,*old;
  979. X{
  980. X#ifdef MSDOS
  981. X   return rename(old,new);
  982. X#else
  983. X   if (link (old, new) != 0)  return -1;
  984. X   if (unlink (old) != 0)     return -2;
  985. X   return 0;
  986. X#endif
  987. X}
  988. X
  989. Xvoid
  990. Xfinalize (newname, oldname)
  991. Xchar     *newname,*oldname;
  992. X{
  993. X   long  sizea, sizeb;
  994. X   int   fh;
  995. X
  996. X/*
  997. X * If we got here, convert() already closed all file pointers, so we can
  998. X * do this safely.  First come the sanity checks--make sure we can open
  999. X * and read/write both files, and make sure the new file is larger than
  1000. X * the original (if it isn't, we didn't finish converting, regardless of
  1001. X * what convert() said).
  1002. X *
  1003. X */
  1004. X
  1005. X   if (strncmp (&oldname[strlen(oldname)-4], ".rel", 4))
  1006. X      {
  1007. X      strcat (oldname, ".rel");
  1008. X      }
  1009. X
  1010. X   if ((fh = openx (oldname, OPENMODE)) < 0)
  1011. X      {
  1012. X      fprintf (stderr, "mb_conv: could not open %s.%s", oldname, SNGCR);
  1013. X      return;
  1014. X      }
  1015. X   sizea = lseek (fh, 0L, 2);  /* Find the filesize */
  1016. X   close (fh);
  1017. X
  1018. X   if ((fh = openx (newname, OPENMODE)) < 0)
  1019. X      {
  1020. X      fprintf (stderr, "mb_conv: could not open %s.%s", oldname, SNGCR);
  1021. X      return;
  1022. X      }
  1023. X   sizeb = lseek (fh, 0L, 2);  /* Find the filesize */
  1024. X   close (fh);
  1025. X
  1026. X   if (sizea >= sizeb)
  1027. X      {
  1028. X      fprintf (stderr, "mb_conv: could not finish conversion!%s", SNGCR);
  1029. X      return;
  1030. X      }
  1031. X
  1032. X/*
  1033. X * Fine--looks like we converted it just dandy.  So delete the original
  1034. X * file, and rename our temporary one so it looks like the old one.  Note that
  1035. X * rename() for DOS doesn't exist with almost any *nix compiler, so I use my
  1036. X * own renamefile(); args work like *nix MV would (new=first, old=second).
  1037. X *
  1038. X */
  1039. X
  1040. X   printf ("mb_conv: %s converted to 5.0 successfully.%s", oldname, SNGCR);
  1041. X
  1042. X   unlink (oldname);
  1043. X   if (renamefile (oldname, newname) != 0)
  1044. X      {
  1045. X      fprintf (stderr, "But, the rename didn't work.%s", SNGCR);
  1046. X      fprintf (stderr, "Rename %s to %s yourself.%s", newname, oldname, SNGCR);
  1047. X      }
  1048. X}
  1049. X
  1050. END_OF_FILE
  1051.   if test 7523 -ne `wc -c <'src/mbconv.c'`; then
  1052.     echo shar: \"'src/mbconv.c'\" unpacked with wrong size!
  1053.   fi
  1054.   # end of 'src/mbconv.c'
  1055. fi
  1056. if test -f 'src/stdinc.h' -a "${1}" != "-c" ; then 
  1057.   echo shar: Will not clobber existing file \"'src/stdinc.h'\"
  1058. else
  1059.   echo shar: Extracting \"'src/stdinc.h'\" \(5130 characters\)
  1060.   sed "s/^X//" >'src/stdinc.h' <<'END_OF_FILE'
  1061. X/*
  1062. X * METALBASE 5.0
  1063. X *
  1064. X * Released October 1st, 1992 by Huan-Ti [ richid@owlnet.rice.edu ]
  1065. X *                                       [ t-richj@microsoft.com ]
  1066. X */
  1067. X
  1068. X#ifndef STDINC_H
  1069. X#define STDINC_H
  1070. X
  1071. X#ifndef XENIX
  1072. X#ifdef M_V7
  1073. X#define XENIX
  1074. X#else
  1075. X#ifdef M_SYS3
  1076. X#define XENIX
  1077. X#else
  1078. X#ifdef M_SYS5
  1079. X#define XENIX
  1080. X#endif
  1081. X#endif /* M_SYS3 */
  1082. X#endif /* M_V7 */
  1083. X#endif /* XENIX */
  1084. X
  1085. X#ifdef applec
  1086. X#define NON_ANSI  /* Define to skip vt100 codes in output      */
  1087. X#endif
  1088. X
  1089. X#ifdef MSDOS
  1090. X#include <io.h>
  1091. X#include <stdlib.h>
  1092. X#include <process.h>
  1093. X#ifndef ANSI_CODES
  1094. X#define NON_ANSI  /* Define to skip vt100 codes in output */
  1095. X#endif
  1096. X#endif /* MSDOS */
  1097. X
  1098. X#ifdef COHERENT
  1099. X#define SYS_FCNTL
  1100. X#endif
  1101. X
  1102. X#ifdef SYS_FCNTL
  1103. X#include <sys/fcntl.h>
  1104. X#else
  1105. X#include <fcntl.h>
  1106. X#endif
  1107. X
  1108. X#include <stdio.h>
  1109. X#include <ctype.h>
  1110. X#include <sys/types.h>
  1111. X#include <string.h>    /* May need to change to <strings.h> on some systems */
  1112. X#include <time.h>      /* May need to change to whatever on other systems   */
  1113. X#include <sys/stat.h>
  1114. X
  1115. X#ifdef NeXT
  1116. X#include <dir.h>
  1117. X#endif
  1118. X
  1119. X#ifdef COHERENT   /* Another great thing--isdigit() under COHERENT doesn't */
  1120. X#ifdef isdigit    /* work right: it keeps returning 8.  Odd.  Oh well.  :) */
  1121. X#undef isdigit
  1122. X#endif
  1123. X#define isdigit(x) ((x) >= '0' && (x) <= '9')
  1124. X#endif /* COHERENT */
  1125. X
  1126. X#ifdef MSDOS
  1127. X#define SNGCR    "\r\n"
  1128. X#define DUBCR    "\r\n\r\n"
  1129. X#define NUMCR    2
  1130. X#define DIRSEP   '\\'
  1131. X#else
  1132. X#define SNGCR    "\n"
  1133. X#define DUBCR    "\n\n"
  1134. X#define NUMCR    1
  1135. X#define DIRSEP   '/'
  1136. X#endif
  1137. X
  1138. X#ifdef ESC
  1139. X#undef ESC
  1140. X#endif
  1141. X
  1142. X#define CTRL_A (char)1
  1143. X#define CTRL_B (char)2
  1144. X#define CTRL_C (char)3
  1145. X#define CTRL_D (char)4
  1146. X#define CTRL_E (char)5
  1147. X#define CTRL_F (char)6
  1148. X#define CTRL_G (char)7
  1149. X#define CTRL_H (char)8
  1150. X#define CTRL_I (char)9
  1151. X#define CTRL_J (char)10
  1152. X#define CTRL_K (char)11
  1153. X#define CTRL_L (char)12
  1154. X#define CTRL_M (char)13
  1155. X#define CTRL_N (char)14
  1156. X#define CTRL_O (char)15
  1157. X#define CTRL_P (char)16
  1158. X#define CTRL_Q (char)17
  1159. X#define CTRL_R (char)18
  1160. X#define CTRL_S (char)19
  1161. X#define CTRL_T (char)20
  1162. X#define CTRL_U (char)21
  1163. X#define CTRL_V (char)22
  1164. X#define CTRL_W (char)23
  1165. X#define CTRL_X (char)24
  1166. X#define CTRL_Y (char)25
  1167. X#define CTRL_Z (char)26
  1168. X#define ESC    (char)27
  1169. X
  1170. X#ifdef CHAR_IS_UNS
  1171. X   typedef char uchar;
  1172. X#else
  1173. X   typedef unsigned char uchar;
  1174. X#endif
  1175. X
  1176. Xtypedef char * charptr;
  1177. X
  1178. X/*
  1179. X * STANDARD SYSTEM DEPENDENCIES
  1180. X *
  1181. X */
  1182. X
  1183. X#ifdef COHERENT
  1184. X#ifndef NOVOIDPTR
  1185. X#define NOVOIDPTR
  1186. X#endif
  1187. X#ifndef NEED_USHORT
  1188. X#define NEED_USHORT
  1189. X#endif
  1190. X#ifndef NEED_ULONG
  1191. X#define NEED_ULONG
  1192. X#endif
  1193. X#endif
  1194. X
  1195. X#ifdef applec
  1196. X#ifndef NEED_USHORT
  1197. X#define NEED_USHORT
  1198. X#endif
  1199. X#endif
  1200. X
  1201. X#ifdef sgi
  1202. X#ifdef NEED_ULONG
  1203. X#undef NEED_ULONG
  1204. X#endif
  1205. X#endif
  1206. X
  1207. X#ifdef MSDOS
  1208. X#ifndef LONGARGS
  1209. X#define LONGARGS
  1210. X#endif
  1211. X#ifndef NEED_ULONG
  1212. X#define NEED_ULONG
  1213. X#endif
  1214. X#ifndef NEED_USHORT
  1215. X#define NEED_USHORT
  1216. X#endif
  1217. X#endif
  1218. X
  1219. X/*
  1220. X *
  1221. X */
  1222. X
  1223. X#ifdef NOVOIDPTR
  1224. X   typedef char *dataptr;
  1225. X#else
  1226. X   typedef void *dataptr;
  1227. X#endif
  1228. X
  1229. X#ifdef NEED_ULONG
  1230. X   typedef unsigned long ulong;
  1231. X#endif
  1232. X
  1233. X#ifdef NEED_USHORT
  1234. X   typedef unsigned short ushort;
  1235. X#endif
  1236. X
  1237. X#ifdef AMIGA
  1238. X#define CLS  "\014"            /* amiga std */
  1239. X#else
  1240. X
  1241. X#ifdef COHERENT
  1242. X#define CLS  "\033[2O\033[1;1H"  /* I prefer this one myself */
  1243. X#undef LONGARGS
  1244. X#else
  1245. X
  1246. X#define CLS  "\033[2J\033[1;1H"  /* ansi std */
  1247. X
  1248. X#ifndef MSDOS
  1249. X#ifndef applec
  1250. X#define UNIX
  1251. X
  1252. X#include <unistd.h>
  1253. X
  1254. X#endif /* applec */
  1255. X#endif /* UNIX */
  1256. X
  1257. X#endif /* COHERENT */
  1258. X#endif /* AMIGA */
  1259. X
  1260. X#ifdef NON_ANSI
  1261. X#define ANSI ""
  1262. X#define NORM ""
  1263. X#define BOLD ""
  1264. X#define SUBD ""
  1265. X#define ITAL ""
  1266. X#define UNDR ""
  1267. X#define INVR ""
  1268. X#else
  1269. X#define ANSI "\033["
  1270. X#define NORM "\033[0m"
  1271. X#define BOLD "\033[1m"
  1272. X#define SUBD "\033[2m"
  1273. X#define ITAL "\033[3m"
  1274. X#define UNDR "\033[4m"  /* These are so common, I won't even bother with */
  1275. X#define INVR "\033[7m"  /* tgetstr.  Sorry, non-VT users.  :-)           */
  1276. X#endif
  1277. X
  1278. X#define sendchar(x) putchar ((char)(x))
  1279. X#define until(x)    while (!(x))
  1280. X
  1281. X#define New(x) (x *)malloc (sizeof(x))  /* Borrowed from C++.  So sue me. */
  1282. X
  1283. X#ifdef LONGARGS
  1284. X   extern time_t time(time_t *);
  1285. X#else
  1286. X   extern time_t time();
  1287. X#endif
  1288. X
  1289. X#ifndef min
  1290. X#define min(a,b) ((a)<(b)?(a):(b))
  1291. X#endif
  1292. X#ifndef max
  1293. X#define max(a,b) ((a)>(b)?(a):(b))
  1294. X#endif
  1295. X
  1296. X#ifdef tolower  /* Strange to think, but on most systems, tolower() and */
  1297. X#undef tolower  /* toupper() just don't work as you'd expect.  Humph.   */
  1298. X#endif
  1299. X#ifdef toupper
  1300. X#undef toupper
  1301. X#endif
  1302. X#define tolower(x)  (char)(((x)>='A' && (x)<='Z')?((x)+('a'-'A')):(x))
  1303. X#define toupper(x)  (char)(((x)>='a' && (x)<='z')?((x)+('A'-'a')):(x))
  1304. X
  1305. X/*
  1306. X * Generic, portable low-level file operations --------------------------------
  1307. X *
  1308. X */
  1309. X
  1310. X#define readx(f,b,n) read  (f, (char *)b, n)  /* DO NOT use buffered I/O!!! */
  1311. X#define writx(f,b,n) write (f, (char *)b, n)  /* DO NOT use buffered I/O!!! */
  1312. X#define modex(f,n)   chmod (f, n)
  1313. X
  1314. X#ifndef S_IWRITE
  1315. X#undef modex
  1316. X#define modex(f,n)
  1317. X#endif
  1318. X
  1319. X#ifdef applec
  1320. X#define creatx(x) creat(x)
  1321. X#else
  1322. X#define creatx(x) creat(x,0666)
  1323. X#endif
  1324. X
  1325. X#ifdef MSDOS
  1326. X#define OPENMODE O_RDWR|O_BINARY
  1327. X#define READMODE O_RDONLY|O_BINARY
  1328. X#include <share.h>
  1329. X#define openx(f,m)  sopen (f, m, SH_DENYNO, S_IREAD|S_IWRITE)
  1330. X#else
  1331. X#define OPENMODE O_RDWR
  1332. X#define READMODE O_RDONLY
  1333. X#define openx(f,m)  open (f, m)
  1334. X#endif  /* MSDOS */
  1335. X
  1336. X#endif
  1337. X
  1338. END_OF_FILE
  1339.   if test 5130 -ne `wc -c <'src/stdinc.h'`; then
  1340.     echo shar: \"'src/stdinc.h'\" unpacked with wrong size!
  1341.   fi
  1342.   # end of 'src/stdinc.h'
  1343. fi
  1344. if test -f 'src/timedate.c' -a "${1}" != "-c" ; then 
  1345.   echo shar: Will not clobber existing file \"'src/timedate.c'\"
  1346. else
  1347.   echo shar: Extracting \"'src/timedate.c'\" \(7468 characters\)
  1348.   sed "s/^X//" >'src/timedate.c' <<'END_OF_FILE'
  1349. X/*
  1350. X * METALBASE 5.0
  1351. X *
  1352. X * Released October 1st, 1992 by Huan-Ti [ richid@owlnet.rice.edu ]
  1353. X *                                       [ t-richj@microsoft.com ]
  1354. X */
  1355. X
  1356. X#define TIMEDATE_C
  1357. X#include "mbase.h"
  1358. X
  1359. X#define TMsHR(x,n) x|=((((ulong)(n))&   31) << 19)
  1360. X#define TMsMN(x,n) x|=((((ulong)(n))&   63) << 13)
  1361. X#define TMsSC(x,n) x|=((((ulong)(n))&   63) <<  7)
  1362. X#define TMsMI(x,n) x|= (((ulong)(n))&  127)
  1363. X#define DTsYR(x,n) x|=((((ulong)(n))& 8191) <<  9)
  1364. X#define DTsMO(x,n) x|=((((ulong)(n))&   15) <<  5)
  1365. X#define DTsDY(x,n) x|= (((ulong)(n))&   31)
  1366. X#define TMgHR(x)   (int)((x >> 19) &   31)
  1367. X#define TMgMN(x)   (int)((x >> 13) &   63)
  1368. X#define TMgSC(x)   (int)((x >>  7) &   63)
  1369. X#define TMgMI(x)   (int)(x &          127)
  1370. X#define DTgYR(x)   (int)((x >>  9) & 8191)
  1371. X#define DTgMO(x)   (int)((x >>  5) &   15)
  1372. X#define DTgDY(x)   (int)(x & 31)
  1373. X
  1374. Xstruct tm *
  1375. X_getlt ()                 /* == Get LocalTime, in {struct tm *} */
  1376. X{
  1377. X   time_t date;
  1378. X   time (&date);          /* If your compiler complains, try date=time(); */
  1379. X   return localtime (&date);
  1380. X}
  1381. X
  1382. Xlong
  1383. Xelap_t (tme)
  1384. Xmb_time tme;
  1385. X{
  1386. X   long     dif;
  1387. X   mb_time  now;
  1388. X   now = curtime();
  1389. X   dif  = 3600L * (long)(TMgHR(now) - TMgHR(tme));
  1390. X   dif +=   60L * (long)(TMgMN(now) - TMgMN(tme));
  1391. X   dif +=    1L * (long)(TMgSC(now) - TMgSC(tme));
  1392. X   return dif;
  1393. X}
  1394. X
  1395. Xmb_time
  1396. Xtmtotime  (tim)  /* Pass NULL to get current time */
  1397. Xstruct tm *tim;
  1398. X{
  1399. X   struct tm  *ptr;
  1400. X   mb_time     ret;
  1401. X   ptr = (tim == (struct tm *)0) ? _getlt() : tim;
  1402. X   ret = (mb_time)0;
  1403. X   TMsHR(ret, ptr->tm_hour);
  1404. X   TMsMN(ret, ptr->tm_min);
  1405. X   TMsSC(ret, ptr->tm_sec);
  1406. X   TMsMI(ret, 0);
  1407. X   return ret;
  1408. X}
  1409. X
  1410. Xmb_date
  1411. Xtmtodate  (tim)
  1412. Xstruct tm *tim;
  1413. X{
  1414. X   struct tm  *ptr;
  1415. X   mb_date     ret;
  1416. X   ptr = (tim == (struct tm *)0) ? _getlt() : tim;
  1417. X   ret = (mb_date)0;
  1418. X   DTsYR(ret, ptr->tm_year+5996L); /* 1992 : tm_year = 92, ret.year = 6178 */
  1419. X   DTsMO(ret, ptr->tm_mon+1L);
  1420. X   DTsDY(ret, ptr->tm_mday);
  1421. X   return ret;
  1422. X}
  1423. X
  1424. Xstruct tm *
  1425. Xdatetimetotm (dat, tim)
  1426. Xmb_date       dat;
  1427. Xmb_time            tim;
  1428. X{
  1429. X   static struct tm ret, *ptr;
  1430. X   dat = (! dat) ? curdate() : dat;
  1431. X   tim = (! tim) ? curtime() : tim;
  1432. X   ptr = _getlt();
  1433. X   ptr->tm_sec  = TMgSC(tim);
  1434. X   ptr->tm_min  = TMgMN(tim);
  1435. X   ptr->tm_hour = TMgHR(tim);
  1436. X   ptr->tm_mday = DTgDY(dat);
  1437. X   ptr->tm_mon  = DTgMO(dat)-1;
  1438. X   ptr->tm_year = (int)(DTgYR(dat)-5996L);
  1439. X   ptr->tm_wday = ptr->tm_yday = ptr->tm_isdst = 0;
  1440. X   return &ret;
  1441. X}
  1442. X
  1443. Xchar *
  1444. Xfmt_date (dat, opt)
  1445. Xmb_date   dat;
  1446. Xint            opt;
  1447. X{
  1448. X   static char buf[20];
  1449. X   if (DTgYR(dat) < 3096)  DTsYR(dat,4096);
  1450. X   switch (opt)
  1451. X    { case 1: sprintf (buf, "%02d/%02d/%02d", DTgMO(dat),
  1452. X                             DTgDY(dat), DTgYR(dat)-5996L);
  1453. X               break;
  1454. X      case 2: sprintf (buf, "%02d%02d%02d", DTgYR(dat)-5996L,
  1455. X                             DTgMO(dat), DTgDY(dat));
  1456. X               break;
  1457. X      default:sprintf (buf, "%02d/%02d/%04d", DTgMO(dat),
  1458. X                             DTgDY(dat), DTgYR(dat)-4096L);
  1459. X               break;
  1460. X    }
  1461. X   return buf;
  1462. X}
  1463. X
  1464. Xchar *
  1465. Xfmt_time (tim, opt)
  1466. Xmb_time   tim;
  1467. Xint            opt;
  1468. X{
  1469. X   static char buf[20];
  1470. X   switch (opt)
  1471. X    { case  1:  sprintf (buf, "%02d:%02d %s", (TMgHR(tim) % 12),
  1472. X                         TMgMN(tim), (TMgHR(tim) >= 12) ? "pm" : "am");
  1473. X               break;
  1474. X      case  2:  sprintf (buf, "%02d:%02d", TMgHR(tim),
  1475. X                         TMgMN(tim));
  1476. X               break;
  1477. X      default: sprintf (buf,"%02d:%02d:%02d", TMgHR(tim),
  1478. X                         TMgMN(tim), TMgSC(tim));
  1479. X               break;
  1480. X    }
  1481. X   return buf;
  1482. X}
  1483. X
  1484. Xmb_date
  1485. Xscn_date (str)
  1486. Xchar     *str;
  1487. X{
  1488. X   char     buf[80];
  1489. X   char    *a, *b;
  1490. X   long     x;
  1491. X   mb_date  rtn = (mb_date)0;
  1492. X
  1493. X   if (! str || ! *str)  return rtn;
  1494. X   strcpy (buf, str);
  1495. X   if ((a=strchr (buf, '/'))==NULL)
  1496. X    {
  1497. X      strzcpy (buf, &str[0], 2);  DTsYR (rtn, atol (buf)+5996L);
  1498. X      strzcpy (buf, &str[2], 2);  DTsMO (rtn, atol (buf));
  1499. X      strzcpy (buf, &str[4], 2);  DTsDY (rtn, atol (buf));
  1500. X      return rtn;
  1501. X    }
  1502. X   b=strchr(str,'/')+1;
  1503. X
  1504. X   *a = 0;  DTsMO (rtn, atol (buf));  strcpy (buf, b);
  1505. X   if ((b=strchr (b, '/'))==NULL)  return rtn;
  1506. X
  1507. X   a=strchr(buf, '/'); *a = 0; DTsDY(rtn, atol(buf));
  1508. X
  1509. X   strcpy (buf, b+1);  x=atol(buf);
  1510. X   if (strlen (buf) < 3)  x += 1900;
  1511. X   DTsYR (rtn, x + 4096);
  1512. X
  1513. X   return rtn;
  1514. X}
  1515. X
  1516. Xmb_time
  1517. Xscn_time (str)
  1518. Xchar     *str;
  1519. X{
  1520. X   char     buf[80];
  1521. X   char    *a, *b;
  1522. X   long     x;
  1523. X   mb_time  rtn = (mb_time)0;
  1524. X
  1525. X   if (! str || ! *str)  return rtn;
  1526. X   strcpy (buf, str);
  1527. X   if ((a=strchr (buf, ':'))==NULL)  return rtn;
  1528. X   b=strchr(str,':')+1;
  1529. X
  1530. X   *a = 0;  TMsHR(rtn, atol (buf));  strcpy (buf, b);
  1531. X   if ((a=strchr (b, ':'))==NULL)
  1532. X    { x=TMgHR (rtn);  rtn=(mb_time)0;  TMsMN (rtn, atol(buf));
  1533. X      if ((a=strchr (str, 'p'))==NULL)  a=strchr (str, 'P');
  1534. X      if (a)
  1535. X         if ((*(a+1) == 'm' || *(a+1) == 'M') && x < 12)
  1536. X            x += 12;
  1537. X      TMsHR (rtn, x);
  1538. X      return rtn;
  1539. X    }
  1540. X   b=strchr(buf,':');  *b = 0;  TMsMN (rtn, atol (buf));
  1541. X
  1542. X   strcpy (buf, a+1);  TMsSC (rtn, atol (buf));
  1543. X   
  1544. X   return rtn;
  1545. X}
  1546. X
  1547. Xmb_time
  1548. Xadd_time (str)
  1549. Xchar     *str;
  1550. X{
  1551. X   long     s,m,h;
  1552. X   mb_time  now, tmp;
  1553. X
  1554. X   now = curtime  ();
  1555. X   tmp = scn_time (str);
  1556. X
  1557. X   s = TMgSC (now) + TMgSC (tmp);
  1558. X   m = TMgMN (now) + TMgMN (tmp);
  1559. X   h = TMgHR (now) + TMgHR (tmp);
  1560. X
  1561. X   while (s >= 60L)  { s -= 60L; m += 1L; }
  1562. X   while (m >= 60L)  { m -= 60L; h += 1L; }
  1563. X   while (h >= 24L)  { h -= 24L;          }
  1564. X
  1565. X   tmp = 0L;
  1566. X
  1567. X   TMsSC (tmp, s);
  1568. X   TMsMN (tmp, m);
  1569. X   TMsHR (tmp, h);
  1570. X
  1571. X   return tmp;
  1572. X}
  1573. X
  1574. Xchar *
  1575. Xfmt_phone (ac, pre, num, ext, opt)  /* OPT: 1=use () for AC, 0=don't     */
  1576. Xlong       ac, pre, num, ext;       /* (-1==internal use only--tis ugly) */
  1577. Xint                           opt;
  1578. X{
  1579. X   static char buf[25];
  1580. X
  1581. X   buf[0] = 0;
  1582. X
  1583. X   if (!ac && !pre && !num && !ext)
  1584. X      return buf;
  1585. X
  1586. X   if (opt != -1)
  1587. X      {
  1588. X      opt = (opt == 0 || opt == 3) ? 1 : 0;
  1589. X
  1590. X      if (! ext)  opt = (opt == 0) ? 3 : 4;
  1591. X      if (! ac)   opt = (opt <= 1) ? 2 : 5;
  1592. X      }
  1593. X
  1594. X   switch (opt)
  1595. X      {
  1596. X      case -1: sprintf (buf, "%03ld-%03ld-%04ldx%05ld",ac,pre,num, ext); break;
  1597. X      case  1: sprintf (buf, "%ld-%ld-%04ld x%ld",     ac,pre,num, ext); break;
  1598. X      case  2: sprintf (buf, "%ld-%04ld x%ld",            pre,num, ext); break;
  1599. X      case  3: sprintf (buf, "(%ld) %ld-%04ld",        ac,pre,num);      break;
  1600. X      case  4: sprintf (buf, "%ld-%ld-%04ld",          ac,pre,num);      break;
  1601. X      case  5: sprintf (buf, "%ld-%04ld",                 pre,num);      break;
  1602. X      default: sprintf (buf, "(%ld) %ld-%04ld x%ld",   ac,pre,num, ext); break;
  1603. X               break;
  1604. X      }
  1605. X   return buf;
  1606. X}
  1607. X
  1608. Xvoid
  1609. Xscn_phone (ac, pre, num, ext, str)
  1610. Xlong      *ac,*pre,*num,*ext;
  1611. Xchar                            *str;
  1612. X{
  1613. X   char *a, *b, buf[128];
  1614. X
  1615. X   *ac = *pre = *num = *ext = 0L;
  1616. X   strcpy (buf, str);
  1617. X
  1618. X   if ((a = strchr (buf, '(')) != NULL)
  1619. X      {
  1620. X      if ((b = strchr (a, ')')) == NULL)  return;
  1621. X      *b = 0;  b++;
  1622. X      *ac = atol (1+a);
  1623. X      }
  1624. X   else
  1625. X      {
  1626. X      if ((a = strchr (buf, '-')) == NULL)  return;
  1627. X      if (strchr (1+a, '-') != NULL)
  1628. X         {
  1629. X         b = a; *b = 0;  b++;
  1630. X         *ac = atol(buf);
  1631. X         }
  1632. X      else
  1633. X         {
  1634. X         b = &buf[0];  /* No area code */
  1635. X         }
  1636. X      }
  1637. X
  1638. X   if ((a = strchr (b, '-')) == NULL)  { *ac = 0; return; }
  1639. X   *a = 0; a++;
  1640. X   *pre = atol (b);
  1641. X
  1642. X   if ((b = strpbrk (a, " xX")) != NULL)
  1643. X      {
  1644. X      *b = 0;
  1645. X      b++;
  1646. X      }
  1647. X
  1648. X   *num = atol (a);
  1649. X
  1650. X   if (b != NULL)
  1651. X      {
  1652. X      if ((a = strpbrk (b, "xX")) != NULL)
  1653. X         b = 1+a;
  1654. X
  1655. X      *ext = atol (b);
  1656. X      }
  1657. X}
  1658. X
  1659. X
  1660. END_OF_FILE
  1661.   if test 7468 -ne `wc -c <'src/timedate.c'`; then
  1662.     echo shar: \"'src/timedate.c'\" unpacked with wrong size!
  1663.   fi
  1664.   # end of 'src/timedate.c'
  1665. fi
  1666. echo shar: End of archive 6 \(of 8\).
  1667. cp /dev/null ark6isdone
  1668. MISSING=""
  1669. for I in 1 2 3 4 5 6 7 8 ; do
  1670.     if test ! -f ark${I}isdone ; then
  1671.     MISSING="${MISSING} ${I}"
  1672.     fi
  1673. done
  1674. if test "${MISSING}" = "" ; then
  1675.     echo You have unpacked all 8 archives.
  1676.     rm -f ark[1-9]isdone
  1677. else
  1678.     echo You still must unpack the following archives:
  1679.     echo "        " ${MISSING}
  1680. fi
  1681. exit 0
  1682. exit 0 # Just in case...
  1683.