home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / ENTERPRS / CPM / UTILS / A / BOOZ4CPM.LZH / BOOZ.C < prev    next >
Text File  |  1988-09-05  |  9KB  |  326 lines

  1. #define  VERSION  "Version 1.02 (1988/08/25)\r\n"
  2.  
  3. /*
  4.     Minor changes for compilation with Aztec C 1.06D for CP/M
  5.     9/4/88
  6.     Bob Presswood
  7. */
  8.  
  9. /* booz.c -- small, memory-efficient Barebones Ooz to extract Zoo archives.
  10.  
  11. For maximum portability, Booz does not use the data type `unsigned long'.
  12.  
  13. The functions and system calls required by Tiny Booz are:
  14.    read()
  15.    write()
  16.    strlen()
  17.    exit()
  18.    malloc()
  19.    lseek()
  20.    open() and/or creat()
  21.    close()
  22.    unlink()                -- may be defined to be an empty function
  23.  
  24.  
  25. Small Booz additionally uses the following functions:
  26.    strcat()
  27.    strcpy()
  28.  
  29. Big Booz additionally use the following function:
  30.    strncat()
  31. */
  32.  
  33. /* 
  34. The contents of this file are hereby released to the public domain.
  35.  
  36.                                    -- Rahul Dhesi 1988/08/25
  37. */
  38.  
  39. #include "options.h"
  40. #include "func.h"
  41. #include "zoo.h"
  42.  
  43. main(argc,argv)
  44. register int argc;
  45. register char **argv;
  46. {
  47. #ifdef TINY
  48.    static char usage[]=
  49.       "Usage:  booz archive.zoo\r\n";
  50.    if (argc < 2) {
  51.       putstr ("Public domain Barebones Ooz\r\nZoo archive extractor (Tiny) by Rahul Dhesi\r\n");
  52.       putstr (VERSION);
  53.       putstr (usage);
  54.       exit (1);
  55.    }
  56. #endif
  57.  
  58. #ifdef SMALL
  59.    static char usage[]=
  60.       "Usage:  booz archive[.zoo] [ file ... ]\r\n";
  61.    if (argc < 2) {
  62.       putstr ("Public domain Barebones Ooz\r\nZoo archive extractor (Small) by Rahul Dhesi\r\n");
  63.       putstr (VERSION);
  64.       putstr (usage);
  65.       exit (1);
  66.    }
  67. #endif
  68.  
  69. #ifdef BIG
  70.    static char usage[]=
  71.       "Usage:  booz {lxt} archive[.zoo] [ file ... ]\r\n";
  72.    if (argc < 3) {
  73.       putstr ("Public domain Barebones Ooz\r\nZoo archive extractor/lister (Big) by Rahul Dhesi\r\n");
  74.       putstr (VERSION);
  75.       putstr (usage);
  76.       putstr ("l = list, x = extract, t = test\r\n");
  77.       exit (1);
  78.    }
  79. #endif
  80.  
  81. #ifdef TINY
  82.    oozext (argv[1]);
  83. #endif
  84.  
  85. #ifdef SMALL
  86.    oozext (argv[1], argc - 2, &argv[2]);
  87. #endif
  88.  
  89. #ifdef BIG
  90.    {
  91.       char *p;
  92.       p = argv[1];
  93.       if (*p == 'L')
  94.          *p = 'l';
  95.       if (*p == 'X')
  96.          *p = 'x';
  97.       if (*p == 'T')
  98.          *p = 't';
  99.       if (*p != 'l' && *p != 'x' && *p != 't') {
  100.          putstr (usage);
  101.          exit (1);
  102.       }
  103.       oozext (argv[2], p, argc - 3, &argv[3]);
  104.    }
  105. #endif
  106.  
  107.    exit (0);
  108. }
  109.  
  110. /**********************/
  111. /* putstr()
  112. This function prints a string to the standard output handle without
  113. using printf() or the standard I/O library.  If a null string, nothing 
  114. is printed (not even the null character).
  115. */
  116. int putstr (str)
  117. register char *str;
  118. {
  119.    if (str != (char *) 0)
  120.       write (1, str, strlen(str));
  121. }
  122.  
  123. /**********************/
  124. /* prterror()
  125. Prints an error message.  The first character controls the severity
  126. of the error and the result.
  127.  
  128.    'm'   informative message
  129.    'w'   warning     -- execution continues
  130.    'e'   error       -- execution continues
  131.    'f'   fatal error -- program exits
  132. */
  133.  
  134. int prterror (level, a, b, c)
  135. int level;
  136. char *a, *b, *c;
  137.  
  138. {
  139.  
  140. #ifdef DEBUG
  141.    {
  142.       char tmp[2];
  143.       tmp[0] = level & 0x7f;
  144.       tmp[1] = '\0';
  145.       putstr ("prterror:  level = ");
  146.       putstr (tmp);
  147.       putstr ("\r\n");
  148.    }
  149. #endif
  150.  
  151.    switch (level & 0x7f) {
  152.       case 'm': break;
  153.       case 'w': putstr ("WARNING:  "); break;
  154.       case 'e': putstr ("ERROR:  "); break;
  155.       case 'f': putstr ("FATAL:  "); break;
  156.       default: prterror ('f', "Internal error\r\n", ((char *) 0), ((char *) 0));
  157.    }
  158.    putstr (a);
  159.    putstr (b);
  160.    putstr (c);
  161.  
  162.    if (level == 'f')       /* and abort on fatal error 'f' but not 'F' */
  163.       exit (1);
  164. }
  165.  
  166. /*************
  167. This function copies count characters from the source file to the
  168. destination Function return value is 0 if no error, 2 if write error,
  169. and 3 if read error.  
  170.  
  171. The global variable crccode is updated.
  172. */
  173. extern char out_buf_adr[];
  174.  
  175. int getfile(input_han, output_han, count)
  176. int input_han, output_han;
  177. long count;
  178. {
  179.    register int how_much;
  180.  
  181.    while (count > 0) {
  182.       if (count > OUT_BUF_SIZE)
  183.          how_much = OUT_BUF_SIZE;
  184.       else
  185.          how_much = count;
  186.       count -= how_much;
  187.       if (read (input_han, out_buf_adr, how_much) != how_much)
  188.          return (3);
  189.       addbfcrc (out_buf_adr, how_much);
  190.       if (output_han != -2 &&
  191.             write (output_han, out_buf_adr, how_much) != how_much)
  192.          return (2);
  193.    }
  194.    return (0);
  195. }
  196.  
  197. #ifndef TINY
  198.  
  199. int needed (fname, argc, argv)
  200. char *fname;
  201. int argc;
  202. char *argv[];
  203. {
  204.    register int i;
  205.    if (argc == 0)
  206.       return (1);
  207.    for (i = 0; i < argc; i++) {
  208.       if (match (fname, argv[i]))
  209.          return (1);
  210.    }
  211.    return (0);
  212. }
  213.  
  214. /***********************/
  215. /*
  216. match() compares a pattern with a string.  Wildcards accepted in
  217. the pattern are:  "*" for zero or more arbitrary characters;  "?"
  218. for any one characters.  Unlike the MS-DOS wildcard match, "*" is
  219. correctly handled even if it isn't at the end of the pattern. ".'
  220. is not special.
  221.  
  222. Originally written by Jeff Damens of Columbia University Center for
  223. Computing Activities.  Taken from the source code for C-Kermit version
  224. 4C.
  225. */
  226.  
  227. int match (string, pattern) 
  228. register char *string, *pattern;
  229. {
  230.    char *psave,*ssave;        /* back up pointers for failure */
  231.    psave = ssave = ((char *) 0);
  232.    while (1) {
  233.       for (; *pattern == *string; pattern++,string++)  /* skip first */
  234.          if (*string == '\0') 
  235.             return(1);                          /* end of strings, succeed */
  236.       if (*string != '\0' && *pattern == '?') {
  237.          pattern++;                             /* '?', let it match */
  238.          string++;
  239.       } else if (*pattern == '*') {             /* '*' ... */
  240.          psave = ++pattern;                     /* remember where we saw it */
  241.          ssave = string;                        /* let it match 0 chars */
  242.       } else if (ssave != ((char *) 0) && *ssave != '\0') {   /* if not at end  */
  243.          /* ...have seen a star */
  244.          string = ++ssave;                      /* skip 1 char from string */
  245.          pattern = psave;                       /* and back up pattern */
  246.       } else 
  247.          return(0);                             /* otherwise just fail */
  248.    }
  249. }
  250.  
  251. #endif /* ndef TINY */
  252.  
  253. int memerr()
  254. {
  255.    prterror ('f', "Ran out of memory\r\n");
  256. }
  257.  
  258. #ifdef BIG
  259. /* cfactor() calculates the compression factor given a directory entry */
  260. int cfactor (org_size, size_now)
  261. long org_size, size_now;
  262. {
  263.    register int size_factor;
  264.  
  265.    while (org_size > 10000) { /* avoid overflow below */
  266.       org_size = org_size >> 4;
  267.       size_now = size_now >> 4;
  268.    }
  269.    if (org_size == 0)         /* avoid division by zero */
  270.       size_factor = 0;
  271.    else {
  272.       size_factor = 
  273.          (
  274.             (1000 * 
  275.                (org_size - size_now)
  276.             ) / org_size + 5
  277.          ) / 10;
  278.    }
  279.    return (size_factor);
  280. }
  281.  
  282. /******
  283. Function itoa() converts a positive long integer into a text string of
  284. digits.  The buffer pointer buf must point to a buffer to receive the
  285. digit string.  The digit string is stored right justified in the
  286. buffer with leading blanks.  If the supplied number is negative, or if
  287. overflow occurs, a single '*' is returned.
  288. */
  289.  
  290. char *itoa (pad_ch, n, buf, buflen)
  291. char pad_ch;                  /* leading pad character */
  292. long n;                       /* positive long int to convert */
  293. char *buf;                    /* buffer to receive digit string */
  294. int buflen;                   /* length of buffer */
  295. {
  296.    char *p;
  297.    int i;
  298.    for (i = 0;  i < buflen;  i++)         /* fill buffer with pad char */
  299.       buf[i] = pad_ch;
  300.    p = buf + buflen - 1;
  301.    *p-- = '\0';                           /* ensure null termination */
  302.    i = buflen - 1;
  303.    for (;;) {
  304.       if (n < 0) {                        /* can't handle negative n */
  305.          goto overflow;
  306.       } else {
  307.          *p-- = (int) (n % 10) + '0';     /* store a converted digit */
  308.          n = n / 10;
  309.          i--;
  310.          if (n == 0 || i == 0)
  311.             break;
  312.       } /* end of else of if (n < 0) */
  313.    } /* end while (buflen > 0) */
  314.    if (n != 0)                            /* buffer overflow */
  315.       goto overflow;
  316.    return (buf);
  317.  
  318. overflow:                                 /* bad value filled with stars */
  319.    for (i = 0; i < buflen; i++)
  320.       buf[i] = '*';
  321.    buf[buflen-1] = '\0';
  322.    return (buf);
  323. }
  324.  
  325. #endif /* BIG */
  326.