home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / ARCHIVERS / unzip_src.lzh / MISC.C < prev    next >
Text File  |  1992-12-08  |  25KB  |  751 lines

  1. /*---------------------------------------------------------------------------
  2.  
  3.   misc.c
  4.  
  5.   This file contains a number of useful but not particularly closely related
  6.   functions; their main claim to fame is that they don't change much, so this
  7.   file should rarely need to be recompiled.  The CRC-32 stuff is from crc32.c;
  8.   do_string() is from nunzip.c; makeword() and makelong() are from unzip.c;
  9.   memset() and memcpy() are from zmemset.c and zmemcpy.c, respectively; and
  10.   dos_to_unix_time() is from set_file_time_and_close() in file_io.c.  ebcdic[],
  11.   check_for_newer(), dateformat(), and return_VMS() are new.  Things lumped
  12.   together here to cut down on the size of unzip.c and the number of associ-
  13.   ated files floating around.
  14.  
  15.   ---------------------------------------------------------------------------
  16.  
  17.   Copyrights:  see accompanying file "COPYING" in UnZip source distribution.
  18.  
  19.   ---------------------------------------------------------------------------*/
  20.  
  21.  
  22. #include "unzip.h"
  23.  
  24. /* Screw it... load the damn thing! */
  25. #include <sys/timeb.h>
  26.  
  27.  
  28. #ifdef MSWIN
  29. #  include "wizunzip.h"
  30. #endif
  31.  
  32.  
  33.  
  34. #ifndef ZIPINFO   /* no need to calculate CRCs */
  35.  
  36. /**************************/
  37. /*  Function UpdateCRC()  */
  38. /**************************/
  39.  
  40.  /*--------------------------------------------------------------------
  41.  
  42.    First, the polynomial itself and its table of feedback terms.  The
  43.    polynomial is
  44.    X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
  45.  
  46.    Note that we take it "backwards" and put the highest-order term in
  47.    the lowest-order bit.  The X^32 term is "implied"; the LSB is the
  48.    X^31 term, etc.  The X^0 term (usually shown as "+1") results in
  49.    the MSB being 1.
  50.  
  51.    Note that the usual hardware shift register implementation, which
  52.    is what we're using (we're merely optimizing it by doing eight-bit
  53.    chunks at a time) shifts bits into the lowest-order term.  In our
  54.    implementation, that means shifting towards the right.  Why do we
  55.    do it this way?  Because the calculated CRC must be transmitted in
  56.    order from highest-order term to lowest-order term.  UARTs transmit
  57.    characters in order from LSB to MSB.  By storing the CRC this way,
  58.    we hand it to the UART in the order low-byte to high-byte; the UART
  59.    sends each low-bit to hight-bit; and the result is transmission bit
  60.    by bit from highest- to lowest-order term without requiring any bit
  61.    shuffling on our part.  Reception works similarly.
  62.  
  63.    The feedback terms table consists of 256, 32-bit entries.  Notes:
  64.  
  65.        The table can be generated at runtime if desired; code to do so
  66.        is shown later.  It might not be obvious, but the feedback
  67.        terms simply represent the results of eight shift/xor opera-
  68.        tions for all combinations of data and CRC register values.
  69.  
  70.        The values must be right-shifted by eight bits by the "updcrc"
  71.        logic; the shift must be unsigned (bring in zeroes).  On some
  72.        hardware you could probably optimize the shift in assembler by
  73.        using byte-swap instructions.
  74.        polynomial $edb88320
  75.  
  76.    --------------------------------------------------------------------*/
  77.  
  78. ULONG crc_32_tab[] =
  79. {
  80.     0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
  81.     0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
  82.     0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
  83.     0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
  84.     0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
  85.     0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
  86.     0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
  87.     0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
  88.     0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
  89.     0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
  90.     0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
  91.     0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
  92.     0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
  93.     0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
  94.     0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
  95.     0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
  96.     0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
  97.     0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
  98.     0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
  99.     0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
  100.     0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
  101.     0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
  102.     0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
  103.     0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
  104.     0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
  105.     0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
  106.     0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
  107.     0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
  108.     0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
  109.     0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
  110.     0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
  111.     0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
  112.     0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
  113.     0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
  114.     0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
  115.     0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
  116.     0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
  117.     0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
  118.     0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
  119.     0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
  120.     0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
  121.     0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
  122.     0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
  123.     0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
  124.     0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
  125.     0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
  126.     0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
  127.     0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
  128.     0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
  129.     0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
  130.     0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
  131.     0x2d02ef8dL
  132. }; /* end crc_32_tab[] */
  133.  
  134.  
  135. void UpdateCRC(s, len)
  136.     register byte *s;
  137.     register int len;
  138. {
  139.     register ULONG crcval = crc32val;
  140.  
  141.     /* update running CRC calculation with contents of a buffer */
  142.     while (len--)
  143.         crcval = crc_32_tab[((byte) crcval ^ (*s++)) & 0xff] ^ (crcval >> 8);
  144.     crc32val = crcval;
  145. }
  146.  
  147. #endif /* !ZIPINFO */
  148.  
  149.  
  150.  
  151.  
  152.  
  153. /**************************/
  154. /*  Function do_string()  */
  155. /**************************/
  156.  
  157. int do_string(len, option)      /* return PK-type error code */
  158.     unsigned int len;           /* without prototype, UWORD converted to this */
  159.     int option;
  160. {
  161.     int block_length, error = 0;
  162.     UWORD comment_bytes_left, extra_len;
  163.  
  164.  
  165. /*---------------------------------------------------------------------------
  166.     This function processes arbitrary-length (well, usually) strings.  Three
  167.     options are allowed:  SKIP, wherein the string is skipped pretty logical,
  168.     eh?); DISPLAY, wherein the string is printed to standard output after un-
  169.     dergoing any necessary or unnecessary character conversions; and FILENAME,
  170.     wherein the string is put into the filename[] array after undergoing ap-
  171.     propriate conversions (including case-conversion, if that is indicated:
  172.     see the global variable pInfo->lcflag).  The latter option should be OK,
  173.     since filename is now dimensioned at 1025, but we check anyway.
  174.  
  175.     The string, by the way, is assumed to start at the current file-pointer
  176.     position; its length is given by len.  So start off by checking length
  177.     of string:  if zero, we're already set.
  178.   ---------------------------------------------------------------------------*/
  179.  
  180.     if (!len)
  181.         return (0);             /* 0:  no error */
  182.  
  183.     switch (option) {
  184.  
  185.     /*
  186.      * First case:  print string on standard output.  First set loop vari-
  187.      * ables, then loop through the comment in chunks of OUTBUFSIZ bytes,
  188.      * converting formats and printing as we go.  The second half of the
  189.      * loop conditional was added because the file might be truncated, in
  190.      * which case comment_bytes_left will remain at some non-zero value for
  191.      * all time.  outbuf is used as a scratch buffer because it is avail-
  192.      * able (we should be either before or in between any file processing).
  193.      * [The typecast in front of the MIN() macro was added because of the
  194.      * new promotion rules under ANSI C; readbuf() wants an int, but MIN()
  195.      * returns a signed long, if I understand things correctly.  The proto-
  196.      * type should handle it, but just in case...]
  197.      */
  198.  
  199.     case DISPLAY:
  200.         comment_bytes_left = len;
  201.         block_length = OUTBUFSIZ;    /* for the while statement, first time */
  202.         while (comment_bytes_left > 0 && block_length > 0) {
  203.             if ((block_length = readbuf((char *)outbuf,
  204.                    (int) MIN(OUTBUFSIZ, comment_bytes_left))) <= 0)
  205.                 return 51;                      /* 51:  unexpected EOF */
  206.             comment_bytes_left -= block_length;
  207.             NUKE_CRs(outbuf, block_length);     /* (modifies block_length) */
  208.  
  209.             /*  this is why we allocated an extra byte for outbuf: */
  210.             outbuf[block_length] = '\0';        /* terminate w/zero:  ASCIIZ */
  211.  
  212.             A_TO_N(outbuf);     /* translate string to native */
  213.  
  214.             printf("%s", outbuf);
  215.         }
  216. #ifdef MSWIN
  217.         /* ran out of local mem -- had to cheat */
  218.         WriteStringToMsgWin(outbuf, bRealTimeMsgUpdate);
  219. #else /* !MSWIN */
  220.         printf("\n");   /* assume no newline at end */
  221. #endif /* ?MSWIN */
  222.         break;
  223.  
  224.     /*
  225.      * Second case:  read string into filename[] array.  The filename should
  226.      * never ever be longer than FILNAMSIZ-1 (1024), but for now we'll check,
  227.      * just to be sure.
  228.      */
  229.  
  230.     case FILENAME:
  231.         extra_len = 0;
  232.         if (len >= FILNAMSIZ) {
  233.             fprintf(stderr, "warning:  filename too long--truncating.\n");
  234.             error = 1;          /* 1:  warning error */
  235.             extra_len = len - FILNAMSIZ + 1;
  236.             len = FILNAMSIZ - 1;
  237.         }
  238.         if (readbuf(filename, len) <= 0)
  239.             return 51;          /* 51:  unexpected EOF */
  240.         filename[len] = '\0';   /* terminate w/zero:  ASCIIZ */
  241.  
  242. #ifndef OSK
  243.         A_TO_N(filename);       /* translate string to native */
  244. #endif
  245.  
  246. #ifndef ZIPINFO
  247.         if (pInfo->lcflag)
  248.             TOLOWER(filename, filename);  /* replace with lowercase filename */
  249. #endif
  250.  
  251.         if (!extra_len)         /* we're done here */
  252.             break;
  253.  
  254.         /*
  255.          * We truncated the filename, so print what's left and then fall
  256.          * through to the SKIP routine.
  257.          */
  258.         fprintf(stderr, "[ %s ]\n", filename);
  259.         len = extra_len;
  260.         /*  FALL THROUGH...  */
  261.  
  262.     /*
  263.      * Third case:  skip string, adjusting readbuf's internal variables
  264.      * as necessary (and possibly skipping to and reading a new block of
  265.      * data).
  266.      */
  267.  
  268.     case SKIP:
  269.         LSEEK(cur_zipfile_bufstart + (inptr-inbuf) + len)
  270.         break;
  271.  
  272.     /*
  273.      * Fourth case:  assume we're at the start of an "extra field"; malloc
  274.      * storage for it and read data into the allocated space.
  275.      */
  276.  
  277.     case EXTRA_FIELD:
  278.         if (extra_field != (byte *)NULL)
  279.             free(extra_field);
  280.         if ((extra_field = (byte *)malloc(len)) == (byte *)NULL) {
  281.             fprintf(stderr,
  282.               "warning:  extra field too long (%d).  Ignoring...\n", len);
  283.             LSEEK(cur_zipfile_bufstart + (inptr-inbuf) + len)
  284.         } else
  285.             if (readbuf((char *)extra_field, len) <= 0)
  286.                 return 51;      /* 51:  unexpected EOF */
  287.         break;
  288.  
  289.     } /* end switch (option) */
  290.     return error;
  291.  
  292. } /* end function do_string() */
  293.  
  294.  
  295.  
  296.  
  297.  
  298. #ifndef ZIPINFO
  299. #ifndef VMS
  300.  
  301. /*********************************/
  302. /*  Function dos_to_unix_time()  */
  303. /*********************************/
  304.  
  305. time_t dos_to_unix_time(ddate, dtime)
  306.     unsigned ddate, dtime;
  307. {
  308.     static short yday[]={0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
  309.     int yr, mo, dy, hh, mm, ss, leap;
  310.     long m_time, days=0;
  311. #if (!defined(MACOS) && !defined(MSC) && !defined(__GO32__))
  312. #if (defined(BSD) || defined(MTS) || defined(OSK))
  313. #ifndef __386BSD__
  314.     static struct timeb tbp;
  315. #endif /* __386BSD__ */
  316. #else /* !(BSD || MTS) */
  317.     extern short timezone;    /* declared in <time.h> for MSC (& Borland?) */
  318. #endif /* ?(BSD || MTS) */
  319. #endif /* !MACOS && !MSC && !__GO32__ */
  320.  
  321. #   define YRBASE  1970
  322.  
  323.     /* dissect date */
  324.     yr = ((ddate >> 9) & 0x7f) + (1980 - YRBASE);
  325.     mo = ((ddate >> 5) & 0x0f) - 1;
  326.     dy = (ddate & 0x1f) - 1;
  327.  
  328.     /* dissect time */
  329.     hh = (dtime >> 11) & 0x1f;
  330.     mm = (dtime >> 5) & 0x3f;
  331.     ss = (dtime & 0x1f) * 2;
  332.  
  333.     /* leap = # of leap years from BASE up to but not including current year */
  334.     leap = ((yr + YRBASE - 1) / 4);   /* leap year base factor */
  335.  
  336.     /* How many days from BASE to this year? (& add expired days this year) */
  337.     days = (yr * 365) + (leap - 492) + yday[mo];
  338.  
  339.     /* if year is a leap year and month is after February, add another day */
  340.     if ((mo > 1) && ((yr+YRBASE)%4 == 0) && ((yr+YRBASE) != 2100))
  341.         ++days;                 /* OK through 2199 */
  342.  
  343.     /* convert date & time to seconds relative to 00:00:00, 01/01/YRBASE */
  344.     m_time = ((long)(days + dy) * 86400L) + ((long)hh * 3600) + (mm * 60) + ss;
  345.       /* - 1;   MS-DOS times always rounded up to nearest even second */
  346.  
  347. #if (!defined(MACOS) && !defined(__GO32__))
  348. #if (defined(BSD) || defined(MTS) || defined(OSK))
  349. #ifndef __386BSD__
  350.     ftime(&tbp);
  351.     m_time += tbp.timezone * 60L;
  352. #endif
  353. #else /* !(BSD || MTS) */
  354. #ifdef WIN32
  355.     /* later... */
  356. #else /* !WIN32 */
  357.     tzset();                    /* set `timezone' */
  358. #endif /* ?WIN32 */
  359.     m_time += timezone;         /* account for timezone differences */
  360. #endif /* ?(BSD || MTS) */
  361. #endif /* !MACOS && !__GO32__ */
  362.  
  363. #ifdef __386BSD__
  364.     m_time += localtime((time_t *) &m_time))->tm_gmtoff;
  365. #else
  366.     if (localtime((time_t *)&m_time)->tm_isdst)
  367.         m_time -= 60L * 60L;    /* adjust for daylight savings time */
  368. #endif /* __386BSD__ */
  369.  
  370.     return m_time;
  371.  
  372. } /* end function dos_to_unix_time() */
  373.  
  374. #endif /* !VMS */
  375.  
  376.  
  377.  
  378.  
  379.  
  380. /********************************/
  381. /*  Function check_for_newer()  */  /* could make this into a macro for Unix */
  382. /********************************/
  383.  
  384. int check_for_newer(filename)   /* return 1 if existing file newer or equal; */
  385.     char *filename;             /*  0 if older; -1 if doesn't exist yet */
  386. {
  387. #ifdef VMS
  388.     unsigned short timbuf[7];
  389.     int dy, mo, yr, hh, mm, ss, dy2, mo2, yr2, hh2, mm2, ss2;
  390.     struct FAB fab;
  391.     struct XABDAT xdat;
  392.  
  393.  
  394.     if (stat(filename, &statbuf))
  395.         return DOES_NOT_EXIST;
  396.  
  397.     fab  = cc$rms_fab;
  398.     xdat = cc$rms_xabdat;
  399.  
  400.     fab.fab$l_xab = &xdat;
  401.     fab.fab$l_fna = filename;
  402.     fab.fab$b_fns = strlen(filename);
  403.     fab.fab$l_fop = FAB$M_GET | FAB$M_UFO;
  404.  
  405.     if ((sys$open(&fab) & 1) == 0)       /* open failure:  report exists and */
  406.         return EXISTS_AND_OLDER;         /*  older so new copy will be made  */
  407.     sys$numtim(&timbuf,&xdat.xab$q_cdt);
  408.     fab.fab$l_xab = 0L;
  409.  
  410.     sys$dassgn(fab.fab$l_stv);
  411.     sys$close(&fab);   /* be sure file is closed and RMS knows about it */
  412.  
  413.     yr = timbuf[0];
  414.     yr2 = ((lrec.last_mod_file_date >> 9) & 0x7f) + 1980;
  415.     if (yr > yr2)
  416.         return EXISTS_AND_NEWER;
  417.     else if (yr < yr2)
  418.         return EXISTS_AND_OLDER;
  419.  
  420.     mo = timbuf[1];
  421.     mo2 = ((lrec.last_mod_file_date >> 5) & 0x0f);
  422.     if (mo > mo2)
  423.         return EXISTS_AND_NEWER;
  424.     else if (mo < mo2)
  425.         return EXISTS_AND_OLDER;
  426.  
  427.     dy = timbuf[2];
  428.     dy2 = (lrec.last_mod_file_date & 0x1f);
  429.     if (dy > dy2)
  430.         return EXISTS_AND_NEWER;
  431.     else if (dy < dy2)
  432.         return EXISTS_AND_OLDER;
  433.  
  434.     hh = timbuf[3];
  435.     hh2 = (lrec.last_mod_file_time >> 11) & 0x1f;
  436.     if (hh > hh2)
  437.         return EXISTS_AND_NEWER;
  438.     else if (hh < hh2)
  439.         return EXISTS_AND_OLDER;
  440.  
  441.     mm = timbuf[4];
  442.     mm2 = (lrec.last_mod_file_time >> 5) & 0x3f;
  443.     if (mm > mm2)
  444.         return EXISTS_AND_NEWER;
  445.     else if (mm < mm2)
  446.         return EXISTS_AND_OLDER;
  447.  
  448.     /* round to nearest 2 secs--may become 60, but doesn't matter for compare */
  449.     ss = (int)((float)timbuf[5] + (float)timbuf[6]*.01 + 1.) & -2;
  450.     ss2 = (lrec.last_mod_file_time & 0x1f) * 2;
  451.     if (ss >= ss2)
  452.         return EXISTS_AND_NEWER;
  453.  
  454.     return EXISTS_AND_OLDER;
  455.  
  456. #else /* !VMS */
  457. #ifdef OS2
  458.     long existing, archive;
  459.  
  460.     if ((existing = GetFileTime(filename)) == -1)
  461.         return DOES_NOT_EXIST;
  462.     archive = ((long) lrec.last_mod_file_date) << 16 | lrec.last_mod_file_time;
  463.  
  464.     return (existing >= archive);
  465. #else /* !OS2 */
  466.     time_t existing, archive;
  467.  
  468.     if (stat(filename, &statbuf))
  469.         return DOES_NOT_EXIST;
  470.  
  471.     /* round up existing filetime to nearest 2 seconds for comparison */
  472.     existing = (statbuf.st_mtime & 1) ? statbuf.st_mtime+1 : statbuf.st_mtime;
  473.     archive  = dos_to_unix_time(lrec.last_mod_file_date,
  474.                                 lrec.last_mod_file_time);
  475.  
  476.     return (existing >= archive);
  477. #endif /* ?OS2 */
  478. #endif /* ?VMS */
  479.  
  480. } /* end function check_for_newer() */
  481.  
  482.  
  483.  
  484.  
  485.  
  486. /***************************/
  487. /*  Function dateformat()  */
  488. /***************************/
  489.  
  490. int dateformat()
  491. {
  492.  
  493. /*-----------------------------------------------------------------------------
  494.   For those operating systems which support it, this function returns a value
  495.   which tells how national convention says that numeric dates are displayed.
  496.  
  497.   Return values are DF_YMD, DF_DMY and DF_MDY.  The meanings should be fairly
  498.   obvious.
  499.  -----------------------------------------------------------------------------*/
  500.  
  501. #ifdef OS2
  502.     switch (GetCountryInfo()) {
  503.             case 0 /* DATEFMT_MM_DD_YY */ :
  504.                 return DF_MDY;
  505.             case 1 /* DATEFMT_DD_MM_YY */ :
  506.                 return DF_DMY;
  507.             case 2 /* DATEFMT_YY_MM_DD */ :
  508.                 return DF_YMD;
  509.         }
  510. #else /* !OS2 */
  511. #if (defined(MSDOS) && !defined(MSWIN))
  512.     unsigned short _CountryInfo[18];
  513. #ifdef __GO32__
  514.     unsigned short *CountryInfo = _CountryInfo;
  515.  
  516.     bdos(0x38, (unsigned)CountryInfo, 0);
  517. #else /* !__GO32__ */
  518.     unsigned short far *CountryInfo = _CountryInfo;
  519.     union REGS regs;
  520.     struct SREGS sregs;
  521.  
  522.     regs.x.ax = 0x3800;
  523.     regs.x.dx = FP_OFF(CountryInfo);
  524.     sregs.ds  = FP_SEG(CountryInfo);
  525.     int86x(0x21, ®s, ®s, &sregs);
  526. #endif /* ?__GO32__ */
  527.  
  528.     switch(CountryInfo[0]) {
  529.         case 0:
  530.             return DF_MDY;
  531.         case 1:
  532.             return DF_DMY;
  533.         case 2:
  534.             return DF_YMD;
  535.     }
  536. #endif /* MSDOS && !MSWIN */
  537. #endif /* ?OS2 */
  538.  
  539.     return DF_MDY;   /* default for Unix, VMS, etc. */
  540.  
  541. } /* end function dateformat() */
  542.  
  543. #endif /* !ZIPINFO */
  544.  
  545.  
  546.  
  547.  
  548.  
  549. #ifdef EBCDIC
  550.  
  551. /*
  552.  * This is the MTS ASCII->EBCDIC translation table. It provides a 1-1
  553.  * translation from ISO 8859/1 8-bit ASCII to IBM Code Page 37 EBCDIC.
  554.  */
  555.  
  556. unsigned char ebcdic[] =
  557. {
  558.     0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f,
  559.     0x16, 0x05, 0x25, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  560.     0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26,
  561.     0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f,
  562.     0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d,
  563.     0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61,
  564.     0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
  565.     0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f,
  566.     0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
  567.     0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
  568.     0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
  569.     0xe7, 0xe8, 0xe9, 0xba, 0xe0, 0xbb, 0xb0, 0x6d,
  570.     0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
  571.     0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
  572.     0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
  573.     0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0, 0xa1, 0x07,
  574.     0x20, 0x21, 0x22, 0x23, 0x24, 0x15, 0x06, 0x17,
  575.     0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x1b,
  576.     0x30, 0x31, 0x1a, 0x33, 0x34, 0x35, 0x36, 0x08,
  577.     0x38, 0x39, 0x3a, 0x3b, 0x04, 0x14, 0x3e, 0xff,
  578.     0x41, 0xaa, 0x4a, 0xb1, 0x9f, 0xb2, 0x6a, 0xb5,
  579.     0xbd, 0xb4, 0x9a, 0x8a, 0x5f, 0xca, 0xaf, 0xbc,
  580.     0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3,
  581.     0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab,
  582.     0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68,
  583.     0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77,
  584.     0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf,
  585.     0x80, 0xfd, 0xfe, 0xfb, 0xfc, 0xad, 0xae, 0x59,
  586.     0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48,
  587.     0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57,
  588.     0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1,
  589.     0x70, 0xdd, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf
  590. }; /* end ebcdic[] */
  591.  
  592. #endif                          /* EBCDIC */
  593.  
  594.  
  595.  
  596.  
  597.  
  598. /*************************/
  599. /*  Function makeword()  */
  600. /*************************/
  601.  
  602. UWORD makeword(b)
  603.     byte *b;
  604. {
  605.     /*
  606.      * Convert Intel style 'short' integer to non-Intel non-16-bit
  607.      * host format.  This routine also takes care of byte-ordering.
  608.      */
  609.     return ((b[1] << 8) | b[0]);
  610. }
  611.  
  612.  
  613.  
  614.  
  615.  
  616. /*************************/
  617. /*  Function makelong()  */
  618. /*************************/
  619.  
  620. ULONG makelong(sig)
  621.     byte *sig;
  622. {
  623.     /*
  624.      * Convert intel style 'long' variable to non-Intel non-16-bit
  625.      * host format.  This routine also takes care of byte-ordering.
  626.      */
  627.     return (((ULONG) sig[3]) << 24)
  628.         + (((ULONG) sig[2]) << 16)
  629.         + (((ULONG) sig[1]) << 8)
  630.         + ((ULONG) sig[0]);
  631. }
  632.  
  633.  
  634.  
  635.  
  636.  
  637. #ifdef VMS
  638.  
  639. /***************************/
  640. /*  Function return_VMS()  */
  641. /***************************/
  642.  
  643. void return_VMS(zip_error)
  644.     int zip_error;
  645. {
  646. #ifdef RETURN_CODES
  647. /*---------------------------------------------------------------------------
  648.     Do our own, explicit processing of error codes and print message, since
  649.     VMS misinterprets return codes as rather obnoxious system errors ("access
  650.     violation," for example).
  651.   ---------------------------------------------------------------------------*/
  652.  
  653.     switch (zip_error) {
  654.  
  655.     case 0:
  656.         break;   /* life is fine... */
  657.     case 1:
  658.         fprintf(stderr, "\n[return-code 1:  warning error \
  659. (e.g., failed CRC or unknown compression method)]\n");
  660.         break;
  661.     case 2:
  662.     case 3:
  663.         fprintf(stderr, "\n[return-code %d:  error in zipfile \
  664. (e.g., can't find local file header sig)]\n",
  665.                 zip_error);
  666.         break;
  667.     case 4:
  668.     case 5:
  669.     case 6:
  670.     case 7:
  671.     case 8:
  672.         fprintf(stderr, "\n[return-code %d:  insufficient memory]\n",
  673.           zip_error);
  674.         break;
  675.     case 9:
  676.         fprintf(stderr, "\n[return-code 9:  zipfile not found]\n");
  677.         break;
  678.     case 10:   /* this is the one that gives "access violation," I think */
  679.         fprintf(stderr, "\n[return-code 10:  bad or illegal parameters \
  680. specified on command line]\n");
  681.         break;
  682.     case 11:   /* I'm not sure this one is implemented, but maybe soon? */
  683.         fprintf(stderr,
  684.           "\n[return-code 11:  no files found to extract/view/etc.]\n");
  685.         break;
  686.     case 50:
  687.         fprintf(stderr,
  688.   "\n[return-code 50:  disk full (or otherwise unable to open output file)]\n");
  689.         break;
  690.     case 51:
  691.         fprintf(stderr,
  692.           "\n[return-code 51:  unexpected EOF in zipfile (i.e., truncated)]\n");
  693.         break;
  694.     default:
  695.         fprintf(stderr, "\n[return-code %d:  unknown return-code \
  696. (who put this one in?  Wasn't me...)]\n",
  697.                 zip_error);
  698.         break;
  699.     }
  700. #endif /* RETURN_CODES */
  701.  
  702.     exit(0);   /* everything okey-dokey as far as VMS concerned */
  703.  
  704. } /* end function return_VMS() */
  705.  
  706. #endif /* VMS */
  707.  
  708.  
  709.  
  710.  
  711.  
  712. #ifdef ZMEM   /* memset, memcpy for systems without them */
  713.  
  714. /***********************/
  715. /*  Function memset()  */
  716. /***********************/
  717.  
  718. char *memset(buf, init, len)
  719.     register char *buf, init;   /* buffer loc and initializer */
  720.     register unsigned int len;  /* length of the buffer */
  721. {
  722.     char *start;
  723.  
  724.     start = buf;
  725.     while (len--)
  726.         *(buf++) = init;
  727.     return (start);
  728. }
  729.  
  730.  
  731.  
  732.  
  733.  
  734. /***********************/
  735. /*  Function memcpy()  */
  736. /***********************/
  737.  
  738. char *memcpy(dst, src, len)
  739.     register char *dst, *src;
  740.     register unsigned int len;
  741. {
  742.     char *start;
  743.  
  744.     start = dst;
  745.     while (len-- > 0)
  746.         *dst++ = *src++;
  747.     return (start);
  748. }
  749.  
  750. #endif /* ZMEM */
  751.