home *** CD-ROM | disk | FTP | other *** search
/ Hall of Fame / HallofFameCDROM.cdr / proglc / zoo141_c.lzh / MISC.C < prev    next >
C/C++ Source or Header  |  1987-02-07  |  9KB  |  346 lines

  1. /* misc.c */
  2. /*
  3. Copyright (C) 1986 Rahul Dhesi -- All rights reserved
  4. */
  5. #include "options.h"
  6. /* Miscellaneous functions needed by Zoo but not by Ooz */
  7.  
  8. #include "zoo.h"
  9. #include <stdio.h>
  10. #include "various.h"
  11.  
  12. #include "errors.i"
  13. #include "zoofns.h"
  14. #ifndef NOSIGNAL
  15. #include <signal.h>
  16. #endif
  17.  
  18. #ifdef NEEDCTYP
  19. #include <ctype.h>
  20. #endif
  21.  
  22. /*
  23. calc_ofs() is given a string that (supposedly) begins with a string
  24. of digits.  It returns a corresponding numeric value.  If no such
  25. string, it returns zero.
  26. */
  27. long calc_ofs(str)
  28. char *str;
  29. {
  30.    long retval;
  31.    int status;
  32.    char *p;
  33.    retval = 0L;
  34.    p = str; /* save for error message */
  35.    while (isdigit(*str)) {
  36.       retval = retval * 10L + (*str-'0');
  37.       str++;
  38.    }
  39.    if (*str != '\0')
  40.       prterror ('f', "Invalid number %s\n", p);
  41.    return (retval);
  42. }
  43.  
  44. /*
  45. choosefname() decides which filename to use.  If a long filename is present,
  46. and if the syntax is that of UNIX, MS-DOS or the portable form, we use it;
  47. else we use the short filename.  Finally, we call a function to fix the 
  48. name to correspond to the syntax of the current host system.
  49. */
  50.  
  51. char *choosefname(direntry)
  52. struct direntry *direntry;
  53. {
  54.    char *retptr;                 /* pointer to name that we will return */
  55.    switch (direntry->system_id) {
  56.       case SYSID_NIX:
  57.       case SYSID_PORTABLE:
  58.       case SYSID_MS:
  59.          retptr = (direntry->namlen > 0) ? direntry->lfname : direntry->fname;
  60.          break;
  61.       default:
  62.          retptr = direntry->fname;
  63.          break;
  64.    }
  65.    return (retptr);
  66. } /* choosefname() */
  67.  
  68. /* 
  69. combine() combines a directory name and a filename, making sure the
  70. two are separated by a path separator 
  71. */
  72. char *combine(result, dirname, fname)
  73. char result[], *dirname, *fname;
  74. {
  75.    *result = '\0';
  76.    if (*dirname != '\0') {
  77.       strcpy(result, dirname);
  78.       if (*lastptr(result) != *PATH_CH)
  79.          strcat(result, PATH_CH);
  80.    }
  81.    strcat(result, fname);
  82.    return (result);
  83. }
  84.  
  85. /* 
  86. ver_too_high returns true if version of provided archive header is
  87. too high for us to manipulate archive 
  88. */
  89.  
  90. int ver_too_high (header)
  91. struct zoo_header *header;
  92. {
  93.    return (header->major_ver > MAJOR_VER ||
  94.             (header->major_ver == MAJOR_VER &&
  95.              header->minor_ver > MINOR_VER));
  96. }
  97.  
  98. /* 
  99. rwheader() reads archive header, checks consistency, makes sure its
  100. version number is not too high, updates it if too low, and seeks to
  101. beginning of first directory entry 
  102. */
  103.  
  104. rwheader (header, zoo_file)
  105. register struct zoo_header *header;
  106. FILE *zoo_file;
  107. {
  108.  
  109.    frd_zooh (header, zoo_file);
  110.  
  111.    if ((header->zoo_start + header->zoo_minus) != 0L)
  112.       prterror ('f', failed_consistency);
  113.    if (ver_too_high (header))
  114.       prterror ('f', wrong_version, header->major_ver, header->minor_ver);
  115.  
  116.    /* We reach here if the archive version is not too high.  Now, if it
  117.    isn't the same as ours, we bring it up to ours so the modified archive 
  118.    will be safe from previous versions of Zoo */
  119.  
  120.    if (header->major_ver != MAJOR_VER || header->minor_ver != MINOR_VER) {
  121.       header->major_ver = MAJOR_VER;
  122.       header->minor_ver = MINOR_VER;
  123.       fseek (zoo_file, 0L, 0);            /* seek to beginning */
  124.       fwr_zooh (header, zoo_file);
  125.    }
  126.    fseek (zoo_file, header->zoo_start, 0); /* seek to where data begins */
  127. } /* rwheader */
  128.  
  129. /*
  130. writedir() write a directory entry with control C disabled
  131. */
  132. void writedir (direntry, zoo_file)
  133. struct direntry *direntry;
  134. FILE *zoo_file;
  135. {
  136. #ifndef NOSIGNAL  
  137.    int (*oldsignal)();
  138.    oldsignal = signal (SIGINT, SIG_IGN);
  139. #endif
  140.    if (fwr_dir (direntry, zoo_file) == -1)
  141.       prterror ('f', disk_full);
  142. #ifndef NOSIGNAL
  143.    signal (SIGINT, oldsignal);
  144. #endif
  145. }
  146.  
  147. /* 
  148. readdir() reads a directory entry from an archive.  If the directory
  149. entry is invalid and if fail is 1, it causes a fatal error;
  150. else it returns.  Return value is 0 if no error else -1;
  151. */
  152.  
  153. int readdir (direntry, zoo_file, fail)    /* read directory entry */
  154. register struct direntry *direntry;
  155. FILE *zoo_file;
  156. int fail;                              /* 0 -> return, 1 -> abort on error */
  157. {
  158.    if (frd_dir (direntry, zoo_file) < 0) {
  159.       if (fail)
  160.          prterror ('f', bad_directory);
  161.       else
  162.          return (-1);
  163.    }
  164.    if (direntry->zoo_tag != ZOO_TAG) {
  165.       if (fail)
  166.          prterror ('f', bad_directory);
  167.       else
  168.          return (-1);
  169.    }
  170.    return (0);
  171. }
  172.  
  173. /* index() searches a string for a substring */
  174. index (s, t)      /* return index of string t in string s, -1 if none */
  175. char s[], t[];    /*  .. from K&R page 67 */
  176. {
  177.    int i;
  178.    register int j, k;
  179.    for (i = 0; s[i] != '\0'; i++) {
  180.       for (j = i, k = 0; t[k] != '\0' && s[j]==t[k]; j++, k++)
  181.          ;
  182.       if (t[k] == '\0')
  183.          return (i);
  184.    }
  185.    return (-1);
  186. }
  187.  
  188. /* cfactor() calculates the compression factor given a directory entry */
  189. int cfactor (org_size, size_now)
  190. long org_size, size_now;
  191. {
  192.    register int size_factor;
  193.    if ((unsigned long) org_size > 1000000) { /* avoid later overflow */
  194.       org_size = (unsigned long) org_size / 1024;
  195.       size_now = (unsigned long) size_now / 1024;
  196.    }
  197.    if (org_size == 0)         /* avoid division by zero */
  198.       size_factor = 0;
  199.    else {
  200.       size_factor = 
  201.          (
  202.             (1000 * 
  203.                ((unsigned long) org_size - (unsigned long) size_now)
  204.             ) / org_size + 5
  205.          ) / 10;
  206.    }
  207.    return (size_factor);
  208. }
  209.  
  210. /***********
  211. strdup() duplicates a string using dynamic memory.
  212. */
  213.  
  214. char *strdup (str)
  215. register char *str;
  216. {
  217.    return (strcpy (emalloc (strlen(str)+1), str));
  218. }
  219.  
  220. /**************
  221. cmpnum() compares two pairs of unsigned integers and returns a negative,
  222. zero, or positive value as the comparison yields less than, equal, or
  223. greater than result.  Each pair of unsigned integers is considered to be the
  224. more significant and the less significant half of a longer unsigned number.
  225.  
  226. Note:  cmpnum is used to compare dates and times.
  227. */
  228.  
  229. int cmpnum (hi1, lo1, hi2, lo2)
  230. register unsigned int hi1, hi2;
  231. unsigned int lo1, lo2;
  232. {
  233.    if (hi1 != hi2)
  234.       return ((int) hi1 - hi2);
  235.    else
  236.       return ((int) lo1 - lo2);
  237. }
  238.  
  239. /*******************/
  240. /* writenull() */
  241. /* writes a null directory entry to the archive whose handle is supplied */
  242. void writenull(handle, length)
  243. int handle, length;
  244. {
  245. #ifndef NOSIGNAL
  246.    int (*oldsignal)();
  247. #endif
  248.    struct direntry newentry;
  249.    memset ((char *) &newentry, 0, sizeof (newentry));
  250.    newentry.zoo_tag = ZOO_TAG;
  251.    newentry.type = 2;
  252.    /* Force entry to be the required length plus possibly 2 stray bytes
  253.    by dividing up the needed padding into dirlen and namlen. */
  254.    if (length > SIZ_DIRL)
  255.       newentry.dirlen = newentry.namlen = (length-SIZ_DIRL)/2 + 2;
  256.    else
  257.       newentry.dirlen = newentry.namlen = 0;
  258. #ifndef NOSIGNAL
  259.    oldsignal = signal (SIGINT, SIG_IGN);
  260. #endif
  261.    if (wr_dir (&newentry, handle) == -1)
  262.       prterror ('f', disk_full);
  263. #ifndef NOSIGNAL
  264.    signal (SIGINT, oldsignal);
  265. #endif
  266. }
  267.  
  268. #ifdef FORCESLASH
  269. /*******************/
  270. /*
  271. fixslash() changes all "\" characters in the supplied string to "/".
  272. */
  273.  
  274. void fixslash (str)
  275. char *str;
  276. {
  277.    register char *p;
  278.    for (p = str; *p != '\0'; p++)
  279.       if (*p == '\\')
  280.          *p = '/';
  281. }
  282. #endif /* FORCESLASH */
  283.  
  284. /* Currently using portable directory I/O for MSC also */
  285. #ifdef COMMENT
  286. #ifndef PORTABLE  
  287. /* portable implementations are elsewhere */
  288. /***********************
  289. Function fwr_dir() writes a directory entry to a FILE.  Return value is -1 on
  290. error, else 0.
  291. */
  292. int fwr_dir(direntry, zoo_file)
  293. struct direntry *direntry;
  294. FILE *zoo_file;
  295. {
  296.    if (fwrite ((char *) direntry, SIZ_DIR, 1, zoo_file) != 1)
  297.       return (-1);
  298.    else
  299.       return (0);
  300. }
  301.  
  302. /***********************
  303. Function wr_dir() writes a directory entry to a handle.  Return value is -1
  304. on error else 0.
  305. */
  306. int wr_dir(direntry, zoo_han)
  307. struct direntry *direntry;
  308. int zoo_han;
  309. {
  310.    if (write (zoo_han, (char *) direntry, SIZ_DIR) != SIZ_DIR)
  311.       return (-1);
  312.    else
  313.       return (0);
  314. }
  315.  
  316. /***********************
  317. Function wr_zooh() writes an archive header to a handle.  Return value -1 if
  318. error else 0.
  319. */
  320. int wr_zooh(zoo_header, zoo_han)
  321. struct zoo_header *zoo_header;
  322. int zoo_han;
  323. {
  324.    if (write (zoo_han, (char *) zoo_header, SIZ_ZOOH) != SIZ_ZOOH)
  325.       return (-1);
  326.    else
  327.       return (0);
  328. }
  329.  
  330. /***********************
  331. Function fwr_zooh() writes an archive header to a FILE.  Return value is -1
  332. if error else 0.
  333. */
  334. int fwr_zooh(zoo_header, zoo_file)
  335. struct zoo_header *zoo_header;
  336. FILE *zoo_file;
  337. {
  338.    if (fwrite ((char *) zoo_header, SIZ_ZOOH, 1, zoo_file) != 1)
  339.       return (-1);
  340.    else
  341.       return (0);
  342. }
  343. #endif /* end of not PORTABLE */
  344. #endif /* COMMENT */
  345.  
  346.