home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3603 < prev    next >
Encoding:
Internet Message Format  |  1991-07-11  |  41.6 KB

  1. From: dhesi@bsu-cs.bsu.edu (Rahul Dhesi)
  2. Newsgroups: alt.sources
  3. Subject: zoo 2.1 source part 07/15
  4. Message-ID: <12774@bsu-cs.bsu.edu>
  5. Date: 10 Jul 91 10:04:21 GMT
  6.  
  7. Checksum: 3482471535 (verify with "brik -cv")
  8. Submitted-by: dhesi@bsu-cs.bsu.edu
  9. Archive-name: zoo210/part07
  10.  
  11. ---- Cut Here and feed the following to sh ----
  12. #!/bin/sh
  13. # This is part 07 of zoo210
  14. # ============= options.h ==============
  15. if test -f 'options.h' -a X"$1" != X"-c"; then
  16.     echo 'x - skipping options.h (File already exists)'
  17. else
  18. echo 'x - extracting options.h (Text)'
  19. sed 's/^X//' << 'SHAR_EOF' > 'options.h' &&
  20. /* @(#) options.h 2.22 88/08/24 15:27:36 */
  21. X
  22. /*
  23. The contents of this file are hereby released to the public domain.
  24. X                           -- Rahul Dhesi 1991/07/06
  25. X
  26. For documentation about this file, see options.doc.
  27. */
  28. X
  29. #define ZOO                /* always defined */
  30. #define PORTABLE        /* always defined */
  31. #define ZOOCOMMENT    /* always defined */
  32. X
  33. X
  34. /***********************************************************************/
  35. /* SYSTEM V (should be compatible with most releases)                  */
  36. /***********************************************************************/
  37. X
  38. #ifdef SYS_V
  39. #define FILTER
  40. #define IO_MACROS
  41. #define EXISTS(f)        (access(f, 00) == 0)
  42. #define FNLIMIT 14
  43. #define CHEKDIR
  44. #define NIXTIME
  45. #define NIXFNAME
  46. #define NEEDCTYP
  47. #define NOENUM
  48. #define REN_LINK
  49. #define SETBUF
  50. #define GETTZ
  51. #define FATTR
  52. #define T_SIGNAL    void
  53. #define VARARGS
  54. #define NEED_MEMMOVE
  55. /* #define NEED_MEMCPY */
  56. #define T_UINT16        unsigned short        /* must be 16 bit unsigned */
  57. #define HAVE_ISATTY
  58. /* #define NEED_VPRINTF */
  59. #endif /* SYS_V */
  60. X
  61. /***********************************************************************/
  62. /* Turbo C++ 1.0 under MS-DOS                                          */
  63. /***********************************************************************/
  64. X
  65. #ifdef TURBOC
  66. #undef PORTABLE
  67. #define ANSI_HDRS
  68. #define USE_ASCII
  69. #define SPECINIT
  70. #define SPECEXIT
  71. #define PURIFY
  72. #define DISK_CH ':'
  73. #define IGNORECASE
  74. #define WILDCARD "*.*"
  75. #define FOLD
  76. #define FORCESLASH
  77. #define FNLIMIT 12
  78. #define CUR_DIR "."
  79. #define PATH_SEP ":/\\"
  80. #define EXT_SEP  ":/\\."
  81. #define SETMODE
  82. /* 0x8000 and 0x4000 taken from <fcntl.h> for Turbo C */
  83. #define MODE_BIN(f)      setmode(fileno(f), 0x8000)
  84. #define MODE_TEXT(f)     setmode(fileno(f), 0x4000)
  85. #define NEED_STDIO
  86. #define ANSI_PROTO
  87. #define VOIDPTR        void *
  88. #define REN_STDC
  89. #define STDARG
  90. #define T_UINT16        unsigned short        /* must be 16 bit unsigned */
  91. /* #define UNBUF_IO */
  92. /* #define UNBUF_LIMIT    512 */
  93. #define  T_SIGNAL void
  94. #define DIRECT_CONVERT
  95. #define STDARG
  96. #define CHECK_BREAK
  97. #define check_break kbhit
  98. #define HAVE_ISATTY
  99. #ifdef  PORTABLE        /* for testing only */
  100. # define SPECNEXT
  101. # define NIXTIME
  102. # undef  WILDCARD
  103. #endif
  104. #endif /* TURBOC */
  105. X
  106. /***********************************************************************/
  107. /* Older BSD 4.3 and most derivatives                                  */
  108. /***********************************************************************/
  109. X
  110. #ifdef BSD4_3
  111. #define NOSTRCHR /* not really needed for 4.3BSD */
  112. #define FILTER
  113. #define IO_MACROS
  114. #define EXISTS(f)        (access(f, 00) == 0)
  115. #define FNLIMIT 1023
  116. #define CHEKDIR
  117. #define NIXTIME
  118. #define NIXFNAME
  119. #define NEEDCTYP
  120. #define NOENUM
  121. #define REN_STDC
  122. #define SETBUF
  123. #define GETTZ
  124. #define FATTR
  125. #define T_SIGNAL    int
  126. #define VARARGS
  127. #define NEED_MEMMOVE
  128. #define T_UINT16        unsigned short        /* must be 16 bit unsigned */
  129. #define HAVE_ISATTY
  130. #define NEED_VPRINTF        /* older BSDs only; newer ones have vprintf */
  131. #endif /* BSD4_3 */
  132. X
  133. /*  Ultrix 4.1 */
  134. #ifdef ULTRIX
  135. #define NO_STDIO_FN    /* avoid declaring certain stdio functions */
  136. #define NOSTRCHR /* needed? */
  137. #define FILTER
  138. #define IO_MACROS
  139. #define EXISTS(f)        (access(f, 00) == 0)
  140. #define FNLIMIT 1023
  141. #define CHEKDIR
  142. #define NIXTIME
  143. #define NIXFNAME
  144. #define NEEDCTYP
  145. #define NOENUM
  146. #define REN_STDC
  147. #define SETBUF
  148. #define GETTZ
  149. #define FATTR
  150. #define T_SIGNAL    void
  151. #define VARARGS
  152. #define NEED_MEMMOVE
  153. #define T_UINT16    unsigned short    /* must be 16 bit unsigned */
  154. #define HAVE_ISATTY
  155. /* #define NEED_VPRINTF */
  156. #define BSD4_3        /* for I/O definitions */
  157. #endif /* ULTRIX */
  158. X
  159. /***********************************************************************/
  160. /* Newer BSD 4.4 (projected)                                           */
  161. /***********************************************************************/
  162. X
  163. #ifdef BSD4_4
  164. /* #define NOSTRCHR */
  165. #define FILTER
  166. #define IO_MACROS
  167. #define EXISTS(f)        (access(f, 00) == 0)
  168. #define FNLIMIT 1023
  169. #define CHEKDIR
  170. #define NIXTIME
  171. #define NIXFNAME
  172. #define NEEDCTYP
  173. /* #define NOENUM */
  174. #define REN_STDC
  175. #define SETBUF
  176. #define GETTZ
  177. #define FATTR
  178. #define T_SIGNAL    void
  179. /* #define VARARGS */
  180. /* #define NEED_MEMMOVE */
  181. #define T_UINT16        unsigned short        /* must be 16 bit unsigned */
  182. #define HAVE_ISATTY
  183. /* #define NEED_VPRINTF */
  184. #endif /* BSD4_4 */
  185. X
  186. /***********************************************************************/
  187. /* VAX/VMS version 5.3 or so                                           */
  188. /***********************************************************************/
  189. X
  190. #ifdef VMS
  191. X
  192. /*
  193. Select VMS pre-4.6 or later next line.  Pre-4.6 library does not have
  194. rename() and memset() so zoo defines its own;  4.6 has these, so we
  195. must use them, else VMS library functions will conflict with our
  196. own.
  197. */
  198. # if 0        /* Make this 1 for VMS version 4.5 or earlier */
  199. #  define NEED_VMS_RENAME    /* used in vms.c */
  200. #  define NEED_MEMSET
  201. # endif
  202. #define REN_STDC
  203. #define IO_MACROS
  204. #define SPEC_WILD
  205. #define EXT_ANYWAY
  206. #define VER_CH ';'
  207. #define SPECEXIT
  208. #define CHEKUDIR
  209. #define FNLIMIT 78
  210. #define DIR_SEP '.'  /* separates dir fields */
  211. #define DISK_CH ':'
  212. #define DIR_LBRACK "[" /* left bracketing symbol dir dir name */
  213. #define PATH_CH "]"
  214. #define PATH_SEP ":]"
  215. #define EXT_SEP ":]."
  216. #define CUR_DIR "."
  217. #define NIXTIME
  218. #define NEEDCTYP
  219. #define NOENUM
  220. #define IGNORECASE
  221. #define SPECMOD
  222. #define SPECNEXT
  223. #define WILDCARD "*.*"
  224. #define FOLD
  225. #define NO_STDIO_FN
  226. #define T_SIGNAL    void
  227. #define T_UINT16        unsigned short        /* must be 16 bit unsigned */
  228. #define VARARGS
  229. #endif /* VMS */
  230. X
  231. /***********************************************************************/
  232. /* AMIGA, SOME VERSION -- NOT TESTED, MAY NEED PORTING                 */
  233. /***********************************************************************/
  234. X
  235. #ifdef MCH_AMIGA
  236. #define PURIFY
  237. #define DISK_CH ':'
  238. #define SPECNEXT
  239. #define WILDCARD "*"
  240. #define IGNORECASE
  241. #define FNLIMIT 30
  242. #define NEEDCTYP
  243. #define CUR_DIR "."
  244. #define PATH_SEP ":/"
  245. #define EXT_SEP  ":/."
  246. #define NOSIGNAL
  247. #define REN_STDC
  248. #define NOENUM
  249. #define SETBUF
  250. #define CHEKUDIR
  251. #define GETUTIME
  252. #define NIXTIME
  253. #endif
  254. X
  255. /***********************************************************************/
  256. /* GENERIC **IX SYSTEM -- GOOD STARTING POINT FOR YOURS                */
  257. /***********************************************************************/
  258. X
  259. #ifdef GENERIC
  260. /* #define SPECNEXT */
  261. /* #define IGNORECASE */
  262. #define FNLIMIT 14
  263. #define NEEDCTYP
  264. #define CUR_DIR "."
  265. #define PATH_SEP "/"
  266. #define EXT_SEP  "/."
  267. /* #define NOSIGNAL */
  268. /* REN_LINK is UNIX-specific.  Can't find a generic rename() function */
  269. #define REN_LINK
  270. #define NOENUM
  271. /* #define SETBUF */
  272. #define CHEKDIR
  273. #define NIXTIME
  274. #define HAVE_ISATTY
  275. #define NEED_MEMMOVE
  276. #endif /* GENERIC */
  277. X
  278. X
  279. /***********************************************************************/
  280. /* REST OF THIS FILE SHOULD NOT NEED ANY CHANGES                       */
  281. /***********************************************************************/
  282. X
  283. /***********************************************************************/
  284. /*  Common filename conventions for **IX systems                       */
  285. /***********************************************************************/
  286. X
  287. #ifdef NIXFNAME
  288. #define CUR_DIR "."
  289. #define PATH_SEP "/"
  290. #define EXT_CH '.'
  291. #define EXT_SEP  "/."
  292. #define EXT_DFLT ".zoo"
  293. #endif
  294. X
  295. /* Compensate for strchr/index differences */
  296. #ifdef NOSTRCHR
  297. #define    strchr    index
  298. #define    strrchr    rindex
  299. #endif
  300. X
  301. /* let non-**IX lints under **IX work (see makefile) */
  302. #ifdef CROSS_LINT
  303. # undef ANSI_HDRS
  304. # undef ANSI_PROTO
  305. # ifdef STDARG
  306. #  undef STDARG
  307. #  define VARARGS
  308. # endif /* STDARG */
  309. #endif
  310. X
  311. /* assume certain defaults */
  312. #ifndef VOIDPTR
  313. # define VOIDPTR   char *
  314. #endif
  315. X
  316. #ifndef VER_DISPLAY
  317. # define VER_DISPLAY ";"
  318. #endif
  319. #ifndef VER_INPUT
  320. # define VER_INPUT ":;"
  321. #endif
  322. #ifndef PATH_CH
  323. # define PATH_CH "/"
  324. #endif
  325. #ifndef EXT_CH
  326. # define EXT_CH '.'
  327. #endif
  328. #ifndef EXT_DFLT
  329. # define EXT_DFLT ".zoo"
  330. #endif
  331. X
  332. #ifndef STDARG
  333. # ifndef VARARGS
  334. #  define VARARGS
  335. # endif
  336. #endif
  337. X
  338. #ifndef T_SIGNAL
  339. # define T_SIGNAL        int
  340. #endif
  341. X
  342. #ifdef STDARG
  343. # ifdef VARARGS
  344. # include "DO NOT DEFINE BOTH STDARG AND VARARGS"
  345. # endif
  346. #endif
  347. X
  348. /* We supply a default for T_UINT16 if it is not defined.  But this
  349. value is critical, so we compile in a runtime check. */
  350. X
  351. #ifndef T_UINT16
  352. # define T_UINT16    unsigned short
  353. # define CHECK_TUINT    /* will do runtime check for correct size */
  354. #endif
  355. X
  356. /* ANSI compatibility in declarations -- see zoofns.h for usage */
  357. #ifndef PARMS
  358. # ifdef ANSI_PROTO
  359. #  define PARMS(x)        x
  360. # else
  361. #  define PARMS(x)        ()
  362. # endif
  363. #endif
  364. SHAR_EOF
  365. chmod 0644 options.h ||
  366. echo 'restore of options.h failed'
  367. Wc_c="`wc -c < 'options.h'`"
  368. test 8466 -eq "$Wc_c" ||
  369.     echo 'options.h: original size 8466, current size' "$Wc_c"
  370. fi
  371. # ============= options.opt ==============
  372. if test -f 'options.opt' -a X"$1" != X"-c"; then
  373.     echo 'x - skipping options.opt (File already exists)'
  374. else
  375. echo 'x - extracting options.opt (Text)'
  376. sed 's/^X//' << 'SHAR_EOF' > 'options.opt' &&
  377. sys$share:vaxcrtl.exe/share
  378. SHAR_EOF
  379. chmod 0644 options.opt ||
  380. echo 'restore of options.opt failed'
  381. Wc_c="`wc -c < 'options.opt'`"
  382. test 28 -eq "$Wc_c" ||
  383.     echo 'options.opt: original size 28, current size' "$Wc_c"
  384. fi
  385. # ============= parse.c ==============
  386. if test -f 'parse.c' -a X"$1" != X"-c"; then
  387.     echo 'x - skipping parse.c (File already exists)'
  388. else
  389. echo 'x - extracting parse.c (Text)'
  390. sed 's/^X//' << 'SHAR_EOF' > 'parse.c' &&
  391. #ifndef LINT
  392. static char sccsid[]="@(#) parse.c 2.1 87/12/25 12:24:10";
  393. #endif /* LINT */
  394. X
  395. /*
  396. The contents of this file are hereby released to the public domain.
  397. X
  398. X                                 -- Rahul Dhesi 1986/11/14
  399. X
  400. */
  401. X
  402. #include "options.h"
  403. #include "zoo.h"
  404. #include "zooio.h"
  405. #include "various.h"
  406. #include "zoofns.h"
  407. X
  408. #include "parse.h"
  409. #include "assert.h"
  410. X
  411. /*
  412. parse() accepts a filename and return its component parts in a structure.
  413. The component parts are:  disk drive, path prefix, root name of filename, 
  414. and extension.  
  415. X
  416. If DISK_CH is not defined, it is assumed that filenames may be
  417. preceded with a disk prefix terminated by the character DISK_CH.
  418. The first character of the disk prefix, followed by DISK_CH,
  419. is returned in the drive field.
  420. X
  421. If the symbol DISK_CH is defined, a null string is returned in the
  422. disk field.
  423. */
  424. void parse (path_st, fname)
  425. register struct path_st *path_st;
  426. char *fname;
  427. {
  428. X   char tempname[LFNAMESIZE];       /* working copy of supplied fname */
  429. X   char *namep;                   /* points to relevant part of tempname */
  430. X
  431. X   char *p;
  432. X   strcpy (tempname, fname);
  433. X
  434. #ifdef DEBUG
  435. printf ("parse:  supplied name is [%s].\n", tempname);
  436. #endif
  437. X
  438. #ifndef DISK_CH
  439. X   path_st->drive[0] = '\0';
  440. X   namep = tempname;           /* points to pathname+filename */
  441. #else
  442. X   path_st->drive[0] = '\0';
  443. X   p = strchr (tempname, DISK_CH);      /* point to first ':' */
  444. X
  445. X   if (p != NULL) {
  446. X      path_st->drive[0] = *tempname;/* use only first char of drive name */
  447. X      path_st->drive[1] = DISK_CH;
  448. X      path_st->drive[2] = '\0';
  449. X      namep = ++p;                /* point to pathname+filename */
  450. X   } else {
  451. X      path_st->drive[0] = '\0';
  452. X      namep = tempname;           /* points to pathname+filename */
  453. X   }
  454. #endif /* end of not DISK_CH */
  455. X   
  456. X   /* Note:  findlast() finds last occurrence in the subject string of 
  457. X      any one of a set of chars */
  458. X
  459. X   /* save the long filename */
  460. X   p = findlast (namep, PATH_SEP);
  461. X
  462. X   /* if path separator found, copy next char onwards; else entire string */
  463. X   strncpy (path_st->lfname,
  464. X               (p != NULL) ? p+1 : namep,
  465. X               LFNAMESIZE);
  466. X   path_st->lfname[LFNAMESIZE-1] = '\0';     /* force null termination */
  467. X
  468. #ifdef DEBUG
  469. printf ("parse:  path = [%s] long filename = [%s]\n", 
  470. X         namep, path_st->lfname);
  471. #endif
  472. X
  473. /* Separate out the extension */
  474. p = findlast (namep, EXT_SEP);                        /* look for . or /        */
  475. if (p != NULL && *p != EXT_CH)                        /* found .?                    */
  476. X    p = NULL;                                                /* ... if not, ignore / */
  477. X
  478. #ifdef DEBUG
  479. if (p == NULL)
  480. X   printf ("parse:  no extension found for [%s]\n", namep);
  481. else
  482. X   printf ("parse:  extension for [%s] is [%s]\n", namep, p);
  483. #endif
  484. X   
  485. X   path_st->ext[0] = '\0';                      /* assume no extension  */
  486. X   if (p != NULL) {                             /* found extension      */
  487. X      strncpy (path_st->ext, (p+1), EXTLEN);    /* save extension       */
  488. X      path_st->ext[EXTLEN] = '\0';              /* force termination    */
  489. X      *p = '\0';                                /* null out extension   */
  490. X   }
  491. X
  492. X   /* separate out root of filename if any */
  493. X   p = findlast (namep, PATH_SEP);
  494. X
  495. X   if (p != NULL) {
  496. X      ++p;
  497. X      strncpy (path_st->fname, p, ROOTSIZE);  /* save filename        */
  498. X      *p = '\0';               /* null out filename */
  499. X   } else {
  500. X      strncpy (path_st->fname, namep, ROOTSIZE);
  501. X      *namep = '\0';                   /* null out filename    */
  502. X   }
  503. X   path_st->fname[ROOTSIZE] = '\0';           /* force termination    */
  504. X
  505. X   /* what remains, whether null or not, is the path prefix */
  506. X   path_st->dir[0] = '\0';             /* in case *namep is '\0' */
  507. X
  508. X   strncpy (path_st->dir, namep, PATHSIZE);
  509. X
  510. X   /* remove trailing path-separater from directory name, but don't
  511. X      remove it if it is also the leading separater */
  512. X   { 
  513. X      int n;
  514. X      n = strlen(path_st->dir);
  515. X      if (n != 1)
  516. X         path_st->dir[n-1] = '\0';
  517. X   }
  518. X
  519. #ifdef DEBUG
  520. printf ("parse:  path prefix = [%s].\n", namep);
  521. #endif
  522. X   /* if extension is null, and if long filename contains more than
  523. X      ROOTSIZE  characters, transfer some of them to extension */
  524. X   if (path_st->ext[0] == '\0' && strlen(path_st->lfname) > ROOTSIZE) {
  525. X      strncpy(path_st->ext, &path_st->lfname[ROOTSIZE], EXTLEN);
  526. X      path_st->ext[3] = '\0';
  527. X   }
  528. }
  529. X
  530. /*******************/
  531. /* 
  532. findlast() finds last occurrence in provided string of any of the characters
  533. except the null character in the provided set.
  534. X
  535. If found, return value is pointer to character found, else it is NULL.
  536. */
  537. X
  538. char *findlast (str, set)
  539. register char *str;        /* subject string     */
  540. char *set;                 /* set of characters to look for */
  541. X
  542. {
  543. X   register char *p;
  544. X
  545. X   if (str == NULL || set == NULL || *str == '\0' || *set == '\0')
  546. X      return (NULL);
  547. X
  548. X   p = lastptr (str);   /* pointer to last char of string */
  549. X   assert(p != NULL);
  550. X
  551. X   while (p != str && strchr (set, *p) == NULL) {
  552. X      --p;
  553. X   }                 
  554. X
  555. X   /* either p == str or we found a character or both */
  556. X   if (strchr (set, *p) == NULL)
  557. X      return (NULL);
  558. X   else
  559. X      return (p);
  560. }
  561. X
  562. /*******************/
  563. /*
  564. lastptr() returns a pointer to the last non-null character in the string, if
  565. any.  If the string is null it returns NULL
  566. */
  567. X
  568. char *lastptr (str)
  569. register char *str;                 /* string in which to find last char */
  570. {
  571. X   register char *p;
  572. X   if (str == NULL)
  573. X      prterror ('f', "lastptr:  received null pointer\n");
  574. X   if (*str == '\0')
  575. X      return (NULL);
  576. X   p = str;
  577. X   while (*p != '\0')            /* find trailing null char */
  578. X      ++p;
  579. X   --p;                          /* point to just before it */
  580. X   return (p);
  581. }
  582. SHAR_EOF
  583. chmod 0644 parse.c ||
  584. echo 'restore of parse.c failed'
  585. Wc_c="`wc -c < 'parse.c'`"
  586. test 5640 -eq "$Wc_c" ||
  587.     echo 'parse.c: original size 5640, current size' "$Wc_c"
  588. fi
  589. # ============= parse.h ==============
  590. if test -f 'parse.h' -a X"$1" != X"-c"; then
  591.     echo 'x - skipping parse.h (File already exists)'
  592. else
  593. echo 'x - extracting parse.h (Text)'
  594. sed 's/^X//' << 'SHAR_EOF' > 'parse.h' &&
  595. /* @(#) parse.h 2.1 87/12/25 12:24:15 */
  596. X
  597. /*
  598. The contents of this file are hereby released to the public domain.
  599. X
  600. X                           -- Rahul Dhesi 1986/11/14
  601. */
  602. X
  603. /*
  604. defines structure used in call to parse()
  605. */
  606. #define XTRA  2         /* extra space to avoid off-by-one errors */
  607. X
  608. X
  609. struct path_st {
  610. X   char drive[2+1+XTRA];            /* drive name            */
  611. X   char dir[PATHSIZE+1+XTRA];       /* path prefix           */
  612. X   char fname[8+1+XTRA];            /* root name of filename */
  613. X   char lfname[LFNAMESIZE+1+XTRA];  /* long filename    */
  614. X   char ext[EXTLEN+1+XTRA];         /* extension        */
  615. };
  616. X
  617. #ifdef LINT_ARGS
  618. void parse (struct path_st *, char *);
  619. #else
  620. void parse();
  621. #endif
  622. SHAR_EOF
  623. chmod 0644 parse.h ||
  624. echo 'restore of parse.h failed'
  625. Wc_c="`wc -c < 'parse.h'`"
  626. test 704 -eq "$Wc_c" ||
  627.     echo 'parse.h: original size 704, current size' "$Wc_c"
  628. fi
  629. # ============= portable.c ==============
  630. if test -f 'portable.c' -a X"$1" != X"-c"; then
  631.     echo 'x - skipping portable.c (File already exists)'
  632. else
  633. echo 'x - extracting portable.c (Text)'
  634. sed 's/^X//' << 'SHAR_EOF' > 'portable.c' &&
  635. #ifndef LINT
  636. /* @(#) portable.c 2.24 88/08/24 01:22:06 */
  637. static char sccsid[]="@(#) portable.c 2.24 88/08/24 01:22:06";
  638. #endif /* LINT */
  639. X
  640. #include "options.h"
  641. /*
  642. Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
  643. (C) Copyright 1988 Rahul Dhesi -- All rights reserved
  644. */
  645. /**********************
  646. portable.c contains functions needed to make Zoo portable to various
  647. implementations of C.
  648. X
  649. Note:  Provided a 2's complement machine is used, all functions in
  650. this file are themselves machine-independent and need not be changed
  651. when implementing Zoo on a different machine.  Some code will choke
  652. on 1's complement machines--I think.  
  653. X
  654. For machine-dependent declarations see files "machine.h" and "options.h". 
  655. X
  656. For machine-dependent functions see file "machine.c"
  657. */
  658. X
  659. #include "zoo.h"
  660. #include "zooio.h"
  661. X
  662. #include "various.h"
  663. #include "zoofns.h"
  664. X
  665. #include "machine.h"
  666. #include "debug.h"
  667. #include "assert.h"
  668. X
  669. #ifdef NEEDCTYP
  670. #include <ctype.h>              /* for tolower() */
  671. #endif
  672. X
  673. #include "portable.h"
  674. X
  675. #ifdef TRACE_IO
  676. extern int verbose;
  677. #endif
  678. X
  679. /* Functions defined for use within this file only.  */
  680. long to_long PARMS((BYTE[]));
  681. int to_int PARMS((BYTE[]));
  682. void b_to_zooh PARMS((struct zoo_header *, BYTE[]));
  683. void b_to_dir PARMS((struct direntry *, BYTE[]));
  684. int dir_to_b PARMS((BYTE[], struct direntry *));
  685. void zooh_to_b PARMS((BYTE[], struct zoo_header *));
  686. void splitlong PARMS((BYTE[], long));
  687. void splitint PARMS((BYTE[], int));
  688. X
  689. #ifdef TRACE_IO
  690. void show_h PARMS ((struct zoo_header *));
  691. void show_dir PARMS ((struct direntry *));
  692. #endif /* TRACE_IO */
  693. X
  694. extern unsigned int crccode;
  695. X
  696. /************************************************************************/
  697. /* I/O functions */
  698. /************************************************************************/
  699. X
  700. /* some functions get defined only if they aren't already macros */
  701. X
  702. #ifndef zooread
  703. int zooread (file, buffer, count)
  704. ZOOFILE file; char *buffer; int count;
  705. { return (fread (buffer, 1, count, file)); }
  706. #endif /* zooread */
  707. X
  708. #ifndef FIZ
  709. #ifndef zoowrite
  710. int zoowrite (file, buffer, count)
  711. ZOOFILE file; char *buffer; int count;
  712. X    if (file == NULLFILE)
  713. X       return (count);
  714. X    else
  715. X        return (fwrite (buffer, 1, count, file)); 
  716. }
  717. #endif /* zoowrite */
  718. X
  719. ZOOFILE zoocreate (fname)
  720. char *fname;
  721. { return ((ZOOFILE) fopen (fname, Z_NEW)); }
  722. X
  723. #endif /* FIZ */
  724. X
  725. #ifndef zooseek
  726. long zooseek (file, offset, whence)
  727. ZOOFILE file; long offset; int whence;
  728. { return (fseek (file, offset, whence)); }
  729. #endif /* zooseek */
  730. X
  731. ZOOFILE zooopen (fname, option)
  732. char *fname; char *option;
  733. { return ((ZOOFILE) fopen (fname, option)); }
  734. X
  735. #ifndef zootell
  736. long zootell (file)
  737. ZOOFILE file;
  738. { return ftell (file); }
  739. #endif /* zootell */
  740. X
  741. int zooclose (file)
  742. ZOOFILE file;
  743. { return fclose (file); }
  744. X
  745. /**********************
  746. low_ch() is a macro that returns a lowercased char; it may be
  747. used with any char, whether or not it is uppercase.   It will
  748. be used below by one or two functions.
  749. */
  750. X
  751. #define low_ch(c)        (isupper(c) ? tolower(c) : c)
  752. X
  753. /************************************************************************/
  754. /*** Following are functions that make up for various implementations ***/
  755. /*** of C not having certain library routines.                        ***/
  756. /************************************************************************/
  757. X
  758. #ifndef FIZ
  759. /**********************
  760. str_lwr() converts a string to lowercase and returns a pointer to the string
  761. */
  762. char *str_lwr (str)
  763. char *str;
  764. {
  765. X   register char *s;
  766. X   s = str;
  767. X   while (*s != '\0') {
  768. X      *s = toascii(*s);
  769. X        *s = low_ch(*s);
  770. X      s++;
  771. X   }
  772. X   return (str);
  773. }
  774. X
  775. /**********************
  776. str_icmp() compares strings just like strcmp() but it does it without regard to
  777. case.
  778. */
  779. int str_icmp (s1, s2)
  780. register char *s1, *s2;
  781. {
  782. X   for ( ; low_ch(*s1) == low_ch(*s2);  s1++, s2++)
  783. X      if (*s1 == '\0')
  784. X         return(0);
  785. X   return(low_ch(*s1) - low_ch(*s2));
  786. }
  787. X
  788. #ifdef NEED_MEMSET
  789. /**********************
  790. memset() it sets the first "count" bytes of "dest" to the character
  791. "c" and returns a pointer to "dest".
  792. */
  793. VOIDPTR memset (dest, c, count)
  794. register VOIDPTR dest;
  795. int c;
  796. unsigned count;
  797. {
  798. X   register unsigned i;
  799. X   for (i = 0; i < count; i++) {
  800. X      *((char *) (dest + i)) = c;
  801. X   }
  802. X   return dest;
  803. }
  804. #endif /* NEED_MEMSET */
  805. X
  806. #ifdef NEED_MEMCPY
  807. /**********************
  808. memcpy() copies "count" bytes from "src" to "dest" and returns 
  809. a pointer to "dest".  Not necessarily safe for overlapping moves. */
  810. X
  811. VOIDPTR memcpy(dest, src, count)
  812. register VOIDPTR dest;
  813. register VOIDPTR src;
  814. unsigned count;
  815. {
  816. X    VOIDPTR savedest = dest;
  817. X    while (count > 0) {
  818. X        *((char *) dest++) = *((char *) src++);
  819. X        count--;
  820. X    }
  821. }
  822. #endif /* NEED_MEMCPY */
  823. X
  824. #ifndef FPUTCHAR
  825. /**********************
  826. fputchar() writes a character to stdout.  It is identical to putchar
  827. but is a function, not a macro.
  828. */
  829. int fputchar (c)
  830. int c;
  831. {
  832. X   return (fputc(c, stdout));
  833. }
  834. #endif /* FPUTCHAR */
  835. #endif /* FIZ */
  836. X
  837. /***********************************************************************/
  838. /*** Following are declarations and functions that are written in a  ***/
  839. /*** machine-independent way but they implement machine-dependent    ***/
  840. /*** activities                                                      ***/
  841. /***********************************************************************/
  842. X
  843. #ifndef DIRECT_CONVERT
  844. /**********************
  845. to_long() converts four consecutive bytes, in order of increasing
  846. significance, to a long integer.  It is used to make Zoo independent of the
  847. byte order of the system.  
  848. */
  849. long to_long(data)
  850. BYTE data[];
  851. {
  852. X   return (long) ((unsigned long) data[0] | ((unsigned long) data[1] << 8) |
  853. X         ((unsigned long) data[2] << 16) | ((unsigned long) data[3] << 24));
  854. }
  855. X
  856. #ifndef FIZ
  857. /********************
  858. splitlong() converts a long integer to four consecutive BYTEs in order
  859. of increasing significance.
  860. */
  861. void splitlong(bytes, bigword)
  862. BYTE bytes[];
  863. long bigword;
  864. {
  865. X   int i;
  866. X   for (i = 0; i < 4; i++) {
  867. X      bytes[i] = bigword & 0xff;
  868. X      bigword = (unsigned long) bigword >> 8;
  869. X   }
  870. }     
  871. #endif /* FIZ */
  872. X
  873. /*******************
  874. splitint() converts an integer to two consecutive BYTEs in order
  875. of increasing significance.
  876. */
  877. void splitint(bytes, word)
  878. BYTE bytes[];
  879. int word;
  880. {
  881. X   bytes[0] = word & 0xff;
  882. X   word = (unsigned int) word >> 8;
  883. X   bytes[1] = word & 0xff;
  884. }
  885. X
  886. /**********************
  887. to_int() converts two consecutive bytes, in order of increasing
  888. significance, to an integer, in a machine-independent manner
  889. */
  890. int to_int(data)
  891. BYTE data[];
  892. {
  893. X   return (int) ((unsigned int) data[0] | ((unsigned int) data[1] << 8));
  894. }
  895. X
  896. #else /* else of ifndef DIRECT_CONVERT */
  897. X
  898. long to_long(data)
  899. BYTE data[];
  900. {
  901. X   return ( * (long *) data );
  902. }
  903. X
  904. #ifndef FIZ
  905. /********************
  906. splitlong() converts a long integer to four consecutive BYTEs in order
  907. of increasing significance.
  908. */
  909. void splitlong(bytes, bigword)
  910. BYTE bytes[];
  911. long bigword;
  912. {
  913. X   * (long *) bytes = bigword;
  914. }
  915. #endif /* FIZ */
  916. X
  917. /*******************
  918. splitint() converts an integer to two consecutive BYTEs in order
  919. of increasing significance.
  920. */
  921. void splitint(bytes, word)
  922. BYTE bytes[];
  923. int word;
  924. {
  925. X   * (int *) bytes = word;
  926. }
  927. X
  928. /**********************
  929. to_int() converts two consecutive bytes, in order of increasing
  930. significance, to an integer.
  931. */
  932. int to_int(data)
  933. BYTE data[];
  934. {
  935. X   return (*(int *) data);
  936. }
  937. X
  938. #endif /* ifndef DIRECT_CONVERT .. else ... */
  939. X
  940. #ifndef FIZ
  941. /**********************
  942. Function frd_zooh() reads the header of a Zoo archive in a machine-
  943. independent manner, from a ZOOFILE.
  944. */
  945. int frd_zooh(zoo_header, zoo_file)
  946. struct zoo_header *zoo_header;
  947. ZOOFILE zoo_file;
  948. {
  949. X   int status;
  950. X   BYTE bytes[SIZ_ZOOH];         /* canonical header representation */
  951. #ifdef TRACE_IO
  952. X   if (verbose) {
  953. X      printf("At file position [%8lx] ", ftell(zoo_file));
  954. X   }
  955. #endif
  956. X   status = zooread (zoo_file, (char *) bytes, SIZ_ZOOH);
  957. X   b_to_zooh (zoo_header, bytes);   /* convert array to structure */
  958. #ifdef TRACE_IO
  959. X   if (verbose) {
  960. X      printf("frd_zooh: reading\n");
  961. X      show_h(zoo_header);
  962. X   }
  963. #endif
  964. X   if (status < MINZOOHSIZ)
  965. X      return (-1);
  966. X   else
  967. X      return (0);
  968. }
  969. #endif /* FIZ */
  970. X
  971. /**********************
  972. Function frd_dir() reads a directory entry in a machine-independent manner,
  973. from a ZOOFILE.
  974. */
  975. int frd_dir(direntry, zoo_file) 
  976. struct direntry *direntry; 
  977. ZOOFILE zoo_file;
  978. {
  979. X   int status;
  980. X   BYTE bytes[MAXDIRSIZE];    /* big enough to hold variable part too */
  981. X
  982. X   /* To simplify things, we read the maximum possible size of the
  983. X   directory entry including the variable size and discard what is not
  984. X   needed */
  985. #ifdef TRACE_IO
  986. X   if (verbose) {
  987. X      printf("At file position [%8lx] ", ftell(zoo_file));
  988. X   }
  989. #endif
  990. X   status = zooread (zoo_file, (char *) bytes, MAXDIRSIZE);
  991. X   if (status < SIZ_DIR)
  992. X      return (-1);
  993. X   b_to_dir (direntry, bytes);
  994. #ifdef TRACE_IO
  995. X   if (verbose) {
  996. X      printf("frd_dir: reading\n");
  997. X      show_dir(direntry);
  998. X   }
  999. #endif
  1000. X   return (0);
  1001. }
  1002. X
  1003. #ifndef FIZ
  1004. /***********************
  1005. Function fwr_dir() writes a directory entry in a machine-independent manner
  1006. to a ZOOFILE.  Return value is -1 on error, else 0.
  1007. */
  1008. int fwr_dir(direntry, zoo_file)
  1009. struct direntry *direntry;
  1010. ZOOFILE zoo_file;
  1011. {
  1012. X   int size;
  1013. X   BYTE bytes[MAXDIRSIZE];
  1014. X   assert (direntry->type <= 2);
  1015. X   size = dir_to_b (bytes, direntry);
  1016. #ifdef TRACE_IO
  1017. X   if (verbose) {
  1018. X      printf("At file position [%8lx] ", ftell(zoo_file));
  1019. X      printf("fwr_dir: writing\n");
  1020. X      show_dir(direntry);
  1021. X   }
  1022. #endif
  1023. X
  1024. X   if (zoowrite (zoo_file, (char *) bytes, size) != size)
  1025. X      return (-1);
  1026. X   else
  1027. X      return (0);
  1028. }
  1029. X
  1030. /***********************
  1031. Function fwr_zooh() writes an archive header in a machine-independent manner
  1032. to a ZOOFILE.  Return value is -1 if error else 0.
  1033. */
  1034. int fwr_zooh(zoo_header, zoo_file)
  1035. struct zoo_header *zoo_header;
  1036. ZOOFILE zoo_file;
  1037. {
  1038. X   BYTE bytes[SIZ_ZOOH];    /* was SIZ_DIR -- probably a typo */
  1039. X    int hsize;                    /* how much to write -- depends on header type */
  1040. X    hsize = MINZOOHSIZ;                /* in case it's an old type 0 header */
  1041. X    if (zoo_header->type > 0)        /* but if it's a newer header... */
  1042. X        hsize = SIZ_ZOOH;                /* ...size of new type 1 header */
  1043. X   zooh_to_b (bytes, zoo_header);
  1044. X   if (zoowrite (zoo_file, (char *) bytes, hsize) != hsize)
  1045. X      return (-1);
  1046. X   else
  1047. X      return (0);
  1048. }
  1049. X
  1050. /***********************
  1051. b_to_zooh() converts an array of BYTE to a zoo_header structure.
  1052. */
  1053. void b_to_zooh (zoo_header, bytes)
  1054. struct zoo_header *zoo_header;
  1055. BYTE bytes[];
  1056. {
  1057. X   int i;
  1058. X   for (i = 0; i < SIZ_TEXT; i++)                     /* copy text */
  1059. X      zoo_header->text[i] = bytes[TEXT_I + i];
  1060. X   zoo_header->zoo_tag = to_long(&bytes[ZTAG_I]);     /* copy zoo_tag */
  1061. X   zoo_header->zoo_start = to_long(&bytes[ZST_I]);    /* copy zoo_start */
  1062. X   zoo_header->zoo_minus = to_long(&bytes[ZSTM_I]);
  1063. X   zoo_header->major_ver = bytes[MAJV_I];          /* copy versions */
  1064. X   zoo_header->minor_ver = bytes[MINV_I];
  1065. X    /* default is no archive comment and a header type of 0 */
  1066. X    zoo_header->type = 0;
  1067. X    zoo_header->acmt_pos = 0L;
  1068. X    zoo_header->acmt_len = 0;
  1069. X    zoo_header->vdata        = 0;
  1070. X    if (zoo_header->zoo_start != FIXED_OFFSET) {            /* if newer header */
  1071. X        zoo_header->type = bytes[HTYPE_I];
  1072. X        zoo_header->acmt_pos = to_long(&bytes[ACMTPOS_I]);
  1073. X        zoo_header->acmt_len = to_int(&bytes[ACMTLEN_I]);
  1074. X        zoo_header->vdata        = bytes[HVDATA_I];
  1075. X    }
  1076. }
  1077. X
  1078. /***********************
  1079. zooh_to_b() converts a zoo_header structure to an array of BYTE.
  1080. */
  1081. void zooh_to_b (bytes, zoo_header)
  1082. struct zoo_header *zoo_header;
  1083. BYTE bytes[];
  1084. {
  1085. X   int i;
  1086. X   for (i = 0; i < SIZ_TEXT; i++)                     /* copy text */
  1087. X      bytes[TEXT_I + i] = zoo_header->text[i];
  1088. X   splitlong (&bytes[ZTAG_I], zoo_header->zoo_tag);
  1089. X   splitlong (&bytes[ZST_I], zoo_header->zoo_start);
  1090. X   splitlong (&bytes[ZSTM_I], zoo_header->zoo_minus);
  1091. X   bytes[MAJV_I] =   zoo_header->major_ver;           /* copy versions */ 
  1092. X   bytes[MINV_I] =   zoo_header->minor_ver;
  1093. X    bytes[HTYPE_I] =    zoo_header->type;                        /* header type */
  1094. X    if (zoo_header->type > 0) {
  1095. X        splitlong (&bytes[ACMTPOS_I], zoo_header->acmt_pos);    /* comment posn */
  1096. X        splitint (&bytes[ACMTLEN_I], zoo_header->acmt_len);    /* comment len */
  1097. X        bytes[HVDATA_I] = zoo_header->vdata;                    /* version data */
  1098. X    }
  1099. } /* zooh_to_b() */
  1100. X
  1101. /************************
  1102. dir_to_b() converts a directory entry structure to an array of BYTE.
  1103. */
  1104. int dir_to_b (bytes, direntry)
  1105. struct direntry *direntry;
  1106. BYTE bytes[];
  1107. {
  1108. X   int i;
  1109. X   int cursize;
  1110. X   int fixsize;
  1111. X    int totalsize;
  1112. X   splitlong(&bytes[DTAG_I], direntry->zoo_tag);
  1113. X   bytes[DTYP_I] = direntry->type ;
  1114. X   bytes[PKM_I] = direntry->packing_method ;
  1115. X   splitlong(&bytes[NXT_I], direntry->next);
  1116. X   splitlong(&bytes[OFS_I], direntry->offset);
  1117. X   splitint(&bytes[DAT_I], direntry->date);
  1118. X   splitint(&bytes[TIM_I], direntry->time);
  1119. X   splitint(&bytes[CRC_I], direntry->file_crc);
  1120. X   splitlong(&bytes[ORGS_I], direntry->org_size);
  1121. X   splitlong(&bytes[SIZNOW_I], direntry->size_now);
  1122. X   bytes[DMAJ_I] = direntry->major_ver;
  1123. X   bytes[DMIN_I] = direntry->minor_ver;
  1124. X   bytes[DEL_I] = direntry->deleted;
  1125. X   bytes[STRUC_I] = direntry->struc;
  1126. X   splitlong(&bytes[CMT_I], direntry->comment);
  1127. X   splitint(&bytes[CMTSIZ_I], direntry->cmt_size);
  1128. X   for (i = 0; i < FNM_SIZ; i++)
  1129. X      bytes[FNAME_I + i] = direntry->fname[i];
  1130. X   bytes[TZ_I] = NO_TZ;       /* assume unknown */
  1131. X   bytes[NAMLEN_I] = 0;
  1132. X   bytes[DIRLEN_I] = 0;
  1133. X
  1134. X   cursize = SIZ_DIR;         /* to count size of directory */
  1135. X   fixsize = SIZ_DIR;         /* size of fixed part */
  1136. X   assert (direntry->type <= 2);
  1137. X   if (direntry->type == 2) { /* handle stuff relevant to type 2 */
  1138. X      cursize = SIZ_DIRL;
  1139. X      fixsize = SIZ_DIRL;
  1140. X      bytes[TZ_I] = direntry->tz;
  1141. X      assert(direntry->namlen < 256 && direntry->namlen >= 0);
  1142. X        cursize += 2;        /* space for namlen and dirlen */
  1143. X      if (direntry->namlen != 0) {
  1144. X         bytes[NAMLEN_I] = direntry->namlen;
  1145. X         for (i = 0; i < direntry->namlen; i++)
  1146. X            bytes[LFNAME_I+i] = direntry->lfname[i];
  1147. X         cursize += direntry->namlen;
  1148. X      }
  1149. X      assert(direntry->dirlen < 256 && direntry->dirlen >= 0);
  1150. X      if (direntry->dirlen != 0) {
  1151. X         bytes[DIRLEN_I] = direntry->dirlen;
  1152. X         for (i = 0; i < direntry->dirlen; i++)
  1153. X            bytes[cursize+i] = direntry->dirname[i];
  1154. X         cursize += direntry->dirlen;
  1155. X      }
  1156. X        /* Can't store system id if no namlen & dirlen...BUG!...now fixed.
  1157. X            Fortunately, system_id was always 0 so far so it probably
  1158. X            got interpreted as namlen=0 and dirlen=0 (2 bytes) */
  1159. X      splitint(&bytes[cursize], direntry->system_id);
  1160. X        cursize += 2;
  1161. X        bytes[cursize] = direntry->fattr & 0xff;                              /* byte 0 */
  1162. X        splitint(&bytes[cursize+1], (int) (direntry->fattr >> 8));  /* 1 & 2 */
  1163. X        cursize += 3;
  1164. X        bytes[cursize] = (direntry->vflag & 0xff);            /* version flag */
  1165. X        splitint(&bytes[cursize+1], direntry->version_no);    /* version number */
  1166. X        cursize += 3;
  1167. X   }
  1168. X
  1169. X   splitint(&bytes[VARDIRLEN_I], direntry->var_dir_len);
  1170. X   assert(cursize == 
  1171. X            ((bytes[DIRLEN_I] > 0 || bytes[NAMLEN_I] > 0) ? 2 : 0) +
  1172. X            fixsize + bytes[DIRLEN_I] + bytes[NAMLEN_I]
  1173. X         );
  1174. X
  1175. X    /* total size of dir entry is size of fixed part + size of var. part */
  1176. X    totalsize = fixsize + direntry->var_dir_len;
  1177. X
  1178. X   /* Do CRC assuming CRC field is zero, and stuff CRC into field. */
  1179. X   splitint(&bytes[DCRC_I], 0);           /* fill with zeroes */
  1180. X   crccode = 0;
  1181. X   /* avoid mixing pointers to signed and unsigned char */
  1182. X   addbfcrc((char *) bytes, totalsize);         /* update CRC */
  1183. X   splitint(&bytes[DCRC_I], crccode);
  1184. X
  1185. X   /* return total length of directory entry */
  1186. X   return (totalsize);
  1187. X
  1188. } /* dir_to_b() */
  1189. #endif /* FIZ */
  1190. X
  1191. /* b_to_dir() converts bytes to directory entry structure.  The CRC of the
  1192. directory bytes, if any, is checked and a zero or nonzero value is returned
  1193. in direntry->dir_crc according as the check is good or bad */
  1194. X
  1195. void b_to_dir(direntry, bytes)
  1196. struct direntry *direntry;
  1197. BYTE bytes[];
  1198. {
  1199. X   int i;
  1200. X    int sysid_offs;            /* temp variable */
  1201. X   unsigned int savecrc;
  1202. X   direntry->zoo_tag = to_long(&bytes[DTAG_I]);
  1203. X   direntry->type = bytes[DTYP_I];
  1204. X   direntry->packing_method = bytes[PKM_I];
  1205. X   direntry->next = to_long(&bytes[NXT_I]);
  1206. X   direntry->offset = to_long(&bytes[OFS_I]);
  1207. X   direntry->date = to_int(&bytes[DAT_I]);
  1208. X   direntry->time = to_int(&bytes[TIM_I]);
  1209. X   direntry->file_crc = to_int(&bytes[CRC_I]);
  1210. X   direntry->org_size = to_long(&bytes[ORGS_I]);
  1211. X   direntry->size_now = to_long(&bytes[SIZNOW_I]);
  1212. X   direntry->major_ver = bytes[DMAJ_I];
  1213. X   direntry->minor_ver = bytes[DMIN_I];
  1214. X   direntry->deleted = bytes[DEL_I];
  1215. X   direntry->struc = bytes[STRUC_I];
  1216. X   direntry->comment = to_long(&bytes[CMT_I]);
  1217. X   direntry->cmt_size = to_int(&bytes[CMTSIZ_I]);
  1218. X    /* for now, versions not implemented */
  1219. X    direntry->vflag = 0;
  1220. X    direntry->version_no = 0;
  1221. X   for (i = 0; i < FNM_SIZ; i++)
  1222. X      direntry->fname[i] = bytes[FNAME_I + i];
  1223. X
  1224. X   /* start by assuming variable part is zero bytes */
  1225. X   direntry->var_dir_len = direntry->dir_crc    = 0;
  1226. X   direntry->namlen      = direntry->dirlen     = 0;
  1227. X   direntry->lfname[0]   = direntry->dirname[0] = '\0';
  1228. X   direntry->tz = NO_TZ;               /* assume unknown */
  1229. X   direntry->system_id = SYSID_NIX;    /* default system_id if not present */
  1230. X    direntry->fattr = NO_FATTR;            /* assume none */
  1231. X
  1232. X   assert (direntry->type <= 2);
  1233. X   if (direntry->type == 2) {
  1234. X      direntry->var_dir_len = to_int(&bytes[VARDIRLEN_I]);
  1235. X      assert(direntry->var_dir_len <= MAXDIRSIZE);
  1236. X      if (direntry->var_dir_len > MAXDIRSIZE)
  1237. X         direntry->var_dir_len = MAXDIRSIZE;
  1238. X      direntry->tz = bytes[TZ_I];   
  1239. X      if (direntry->var_dir_len > 0)
  1240. X         direntry->namlen = bytes[NAMLEN_I];
  1241. X      if (direntry->var_dir_len > 1)
  1242. X         direntry->dirlen = bytes[DIRLEN_I];
  1243. X      for (i = 0; i < direntry->namlen; i++)
  1244. X         direntry->lfname[i] = bytes[LFNAME_I + i];
  1245. X      for (i = 0; i < direntry->dirlen; i++)
  1246. X         direntry->dirname[i] = bytes[DIRNAME_I + direntry->namlen + i];
  1247. X        sysid_offs = DIRNAME_I + direntry->namlen + i;    /* offset of system id */
  1248. X        if (direntry->var_dir_len > direntry->namlen + direntry->dirlen + 2) {
  1249. X            direntry->system_id = to_int(&bytes[sysid_offs]);
  1250. X        }
  1251. X        if (direntry->var_dir_len > direntry->namlen + direntry->dirlen + 4) {
  1252. X            direntry->fattr = ((unsigned long) bytes[sysid_offs + 2]) |
  1253. X                                    ((unsigned long) bytes[sysid_offs + 3] << 8) |
  1254. X                                    ((unsigned long) bytes[sysid_offs + 4] << 16);
  1255. X        }
  1256. X        if (direntry->var_dir_len > direntry->namlen + direntry->dirlen + 7) {
  1257. X            direntry->vflag = bytes[sysid_offs + 5];
  1258. X            direntry->version_no = to_int(&bytes[sysid_offs + 6]);
  1259. X        }
  1260. X      /* do CRC calculation */
  1261. X      savecrc = (unsigned int) to_int(&bytes[DCRC_I]);
  1262. X      crccode = 0;
  1263. X      splitint(&bytes[DCRC_I], 0);
  1264. X      addbfcrc((char *) bytes, SIZ_DIRL + direntry->var_dir_len);
  1265. X      direntry->dir_crc = crccode - savecrc;
  1266. X   }
  1267. }
  1268. X
  1269. #ifdef FILTER
  1270. #define TWOBYTES    2    /* better than literal 2;  figure out why */
  1271. X
  1272. /* rdint() reads two bytes from standard input in archive order */
  1273. int rdint (val)
  1274. unsigned int *val;
  1275. {
  1276. X    BYTE bytes[TWOBYTES];
  1277. X    if (zooread (STDIN, bytes, TWOBYTES) == TWOBYTES) {
  1278. X        *val = to_int(bytes);
  1279. X        return (0);
  1280. X    } else
  1281. X        return (1);
  1282. }
  1283. X
  1284. /* wrint() writes an unsigned int to standard output in archive order */
  1285. int wrint (val)
  1286. unsigned int val;
  1287. {
  1288. X    BYTE bytes[TWOBYTES];
  1289. X    splitint (bytes, val);
  1290. X    if (zoowrite (STDOUT, bytes, TWOBYTES) == TWOBYTES)
  1291. X        return (0);
  1292. X    else
  1293. X        return (1);
  1294. }
  1295. #endif /* FILTER */
  1296. X
  1297. #ifdef TRACE_IO
  1298. /* dump contents of archive header */
  1299. void show_h (zoo_header)
  1300. struct zoo_header *zoo_header;
  1301. {
  1302. X   int i;
  1303. X   printf ("Header text:\n");
  1304. X   for (i = 0; i < SIZ_TEXT;  i++) {      /* ASSUMES ASCII TEXT */
  1305. X      int c;
  1306. X      c = zoo_header->text[i];
  1307. X      if (c >= ' ' && c < 0x7f)
  1308. X         putchar (c);
  1309. X      else {
  1310. X         putchar ('^');
  1311. X         putchar (i & 0x40);
  1312. X      }
  1313. X   }
  1314. X   putchar('\n');
  1315. X   printf ("zoo_tag = [%8lx] zoo_start = [%8lx] zoo_minus = [%8lx]\n",
  1316. X            zoo_header->zoo_tag, zoo_header->zoo_start, 
  1317. X            zoo_header->zoo_minus);
  1318. X   printf ("major_ver.minor_ver = [%d.%d]\n",
  1319. X            zoo_header->major_ver, zoo_header->minor_ver);
  1320. X    if (zoo_header->zoo_start != FIXED_OFFSET) {
  1321. X        printf ("type = [%d] ", zoo_header->type);
  1322. X        printf ("acmt_pos = [%8lx] acmt_len = [%4x] vdata = [%2x]",
  1323. X                    zoo_header->acmt_pos, zoo_header->acmt_len, zoo_header->vdata);
  1324. X        printf ("\n");
  1325. X    }
  1326. X   printf ("---------\n");
  1327. }
  1328. X
  1329. /* dump contents of directory entry */
  1330. void show_dir (direntry)
  1331. struct direntry *direntry;
  1332. {
  1333. X   printf ("Directory entry for file [%s][%s]:\n",
  1334. X            direntry->fname, direntry->lfname);
  1335. X   printf ("tag = [%8lx] type = [%d] PM = [%d] Next = [%8lx] Offset = [%8lx]\n",
  1336. X            direntry->zoo_tag, (int) direntry->type, 
  1337. X            (int) direntry->packing_method, direntry->next, 
  1338. X            direntry->offset);
  1339. X   printf ("Orig size = [%ld] Size now = [%ld] dmaj_v.dmin_v = [%d.%d]\n",
  1340. X         direntry->org_size, direntry->size_now,
  1341. X         (int) direntry->major_ver, (int) direntry->minor_ver);
  1342. X   printf ("Struc = [%d] DEL = [%d] comment_offset = [%8lx] cmt_size = [%d]\n",
  1343. X         (int) direntry->struc, (int) direntry->deleted, direntry->comment,
  1344. X         direntry->cmt_size);
  1345. X   printf ("var_dir_len = [%d] TZ = [%d] dir_crc = [%4x]\n",
  1346. X            direntry->var_dir_len, (int) direntry->tz, direntry->dir_crc);
  1347. X   printf ("system_id = [%d]  dirlen = [%d]  namlen = [%d] fattr=[%24lx]\n", 
  1348. X        direntry->system_id, direntry->dirlen, direntry->namlen, direntry->fattr);
  1349. X    printf ("vflag = [%4x] version_no = [%4x]\n",
  1350. X                direntry->vflag, direntry->version_no);
  1351. X   if (direntry->dirlen > 0)
  1352. X      printf ("dirname = [%s]\n", direntry->dirname);
  1353. X   printf ("---------\n");
  1354. }
  1355. #endif   /* TRACE_IO */
  1356. SHAR_EOF
  1357. chmod 0644 portable.c ||
  1358. echo 'restore of portable.c failed'
  1359. Wc_c="`wc -c < 'portable.c'`"
  1360. test 21613 -eq "$Wc_c" ||
  1361.     echo 'portable.c: original size 21613, current size' "$Wc_c"
  1362. fi
  1363. # ============= portable.h ==============
  1364. if test -f 'portable.h' -a X"$1" != X"-c"; then
  1365.     echo 'x - skipping portable.h (File already exists)'
  1366. else
  1367. echo 'x - extracting portable.h (Text)'
  1368. sed 's/^X//' << 'SHAR_EOF' > 'portable.h' &&
  1369. /* @(#) portable.h 2.3 87/12/26 12:25:49 */
  1370. /* @(#) portable.h 2.4 88/08/24 00:56:43 */
  1371. X
  1372. /* Definitions for portable I/O
  1373. X
  1374. The contents of this file are hereby released to the public domain.
  1375. X
  1376. X                           -- Rahul Dhesi 1986/11/14
  1377. X
  1378. X
  1379. X
  1380. X                       DEFINITIONS IN THIS FILE
  1381. X
  1382. Symbols:
  1383. X
  1384. Z_WRITE, Z_READ, and Z_RDWR are the parameters to supply to zooopen()
  1385. and to open an existing file for write, read, and read-write 
  1386. respectively.  Z_NEW is the parameter to supply to zoocreate() to
  1387. open an existing file or create a new file for write and read.  The
  1388. file must be opened in binary format, with no newline translation of
  1389. any kind.
  1390. X
  1391. Macros or functions:
  1392. X
  1393. zgetc(x) reads a character from ZOOFILE x.
  1394. zputc(c, f) writes a character to a ZOOFILE x.
  1395. zputchar(c) writes a character c to standard output.
  1396. MKDIR(x) creates a directory x.
  1397. */
  1398. X
  1399. /* Borland's Turbo C. */
  1400. #ifdef   TURBOC
  1401. /* options for zooopen(), zoocreate() */
  1402. #define  Z_WRITE        "r+b"
  1403. #define  Z_READ         "rb"
  1404. #define  Z_RDWR         "r+b"
  1405. #define    Z_NEW                "w+b"
  1406. #define    zgetc(x)            getc(x)
  1407. #define  zputc(c, f)        putc(c, f)
  1408. #define    zputchar(c)        putchar(c)
  1409. #define  MKDIR(x)       mkdir(x)
  1410. int mkdir PARMS((char *));
  1411. #endif
  1412. X
  1413. /* Microsoft C 3.0 */
  1414. #ifdef   MSC
  1415. /* options for zooopen(), zoocreate() */
  1416. #define  Z_WRITE        "r+b"
  1417. #define  Z_READ         "rb"
  1418. #define  Z_RDWR         "r+b"
  1419. #define    Z_NEW                "w+b"
  1420. #define    zgetc(x)            getc(x)
  1421. #define  zputc(c, f)        putc(c, f)
  1422. #define    zputchar(c)        putchar(c)
  1423. #define  MKDIR(x)       mkdir(x)
  1424. int mkdir (char *);
  1425. #endif
  1426. X
  1427. #ifdef VMS
  1428. #define Z_WRITE        "r+"
  1429. #define Z_READ            "r"
  1430. #define Z_RDWR            "r+"
  1431. #define    Z_NEW            "w+b"
  1432. #define zgetc(x)    getc(x)
  1433. #define  zputc(c, f)        putc(c, f)
  1434. #define zputchar(c)    putchar(c)
  1435. #define MKDIR(x)    vmsmkdir (x, 0)
  1436. #endif
  1437. X
  1438. #ifdef GENERIC
  1439. /* **IX I/O, but MKDIR() is a no-operation */
  1440. #define  NIX_IO      /* standard **IX I/O */
  1441. #define  MKDIR(x)
  1442. #endif
  1443. X
  1444. /* **IX System V release 2.1 */
  1445. #ifdef   SYS_V
  1446. #define  NIX_IO      /* standard **IX I/O */
  1447. #define  MKDIR(x)       mkdir(x) /* define this in sysv.c */
  1448. #endif
  1449. X
  1450. /* Xenix */
  1451. #ifdef   XENIX
  1452. #define  NIX_IO      /* standard **IX I/O */
  1453. #endif
  1454. X
  1455. /* 4.3BSD */
  1456. #ifdef BSD4_3
  1457. #define NIX_IO       /* standard **IX I/O */
  1458. #define  MKDIR(x)       mkdir(x, 0777)
  1459. #endif
  1460. X
  1461. /* Amiga */
  1462. #ifdef MCH_AMIGA
  1463. # include "MCH_AMIGA NEEDS REVISION"
  1464. #endif
  1465. X
  1466. /* Standard **IX I/O definitions */
  1467. #ifdef   NIX_IO
  1468. /* options for zooopen(), zoocreate() */
  1469. #define  Z_WRITE        "r+"
  1470. #define  Z_READ         "r"
  1471. #define  Z_RDWR         "r+"
  1472. #define    Z_NEW                "w+"
  1473. #define    zgetc(x)            getc(x)
  1474. #define  zputc(c, f)        putc(c, f)
  1475. #define    zputchar(c)        putchar(c)
  1476. #endif   /* NIX_IO */
  1477. SHAR_EOF
  1478. chmod 0644 portable.h ||
  1479. echo 'restore of portable.h failed'
  1480. Wc_c="`wc -c < 'portable.h'`"
  1481. test 2657 -eq "$Wc_c" ||
  1482.     echo 'portable.h: original size 2657, current size' "$Wc_c"
  1483. fi
  1484. true || echo 'restore of prterror.c failed'
  1485. echo End of part 7, continue with part 8
  1486. exit 0
  1487.