home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / MISC / GNU / MAK358AS.ZIP / ZIPSCAN.C < prev   
Encoding:
C/C++ Source or Header  |  1992-02-22  |  21.5 KB  |  795 lines

  1. /*  zipscan.c - scan .zip archives
  2.     Copyright (C) 1990 by Thorsten Ohl, ohl@gnu.ai.mit.edu
  3.  
  4.     This program is free software; you can redistribute it and/or modify
  5.     it under the terms of the GNU General Public License as published by
  6.     the Free Software Foundation; either version 1, or (at your option)
  7.     any later version.
  8.  
  9.     This program is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     GNU General Public License for more details.
  13.  
  14.     You should have received a copy of the GNU General Public License
  15.     along with this program; if not, write to the Free Software
  16.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18.     IMPORTANT:
  19.  
  20.     This code is not an official part of the GNU project and the
  21.     author is not affiliated to the Free Software Foundation.
  22.     He just likes their code and spirit.  */
  23.  
  24. static char RCS_id[] =
  25. "$Header: e:/gnu/make/RCS/zipscan.c'v 0.2 90/07/18 22:23:26 tho Exp $";
  26.  
  27. /* The following section is taken from the file appnote.txt
  28.    (from the PK(UN)?ZIP v1.1 distribution).  */
  29.  
  30. /*
  31.  
  32. General Format of a ZIP file
  33. ----------------------------
  34.  
  35.   Files stored in arbitrary order.  Large zipfiles can span multiple
  36.   diskette media.
  37.  
  38.   Overall zipfile format:
  39.  
  40.     [local file header+file data] . . .
  41.     [central directory] end of central directory record
  42.  
  43.  
  44.   A.  Local file header:
  45.  
  46.     local file header signature    4 bytes  (0x04034b50)
  47.     version needed to extract    2 bytes
  48.     general purpose bit flag    2 bytes
  49.     compression method        2 bytes
  50.     last mod file time         2 bytes
  51.     last mod file date        2 bytes
  52.     crc-32               4 bytes
  53.     compressed size            4 bytes
  54.     uncompressed size        4 bytes
  55.     filename length            2 bytes
  56.     extra field length        2 bytes
  57.  
  58.     filename (variable size)
  59.     extra field (variable size)
  60.  
  61.  
  62.   B.  Central directory structure:
  63.  
  64.       [file header] . . .  end of central dir record
  65.  
  66.       File header:
  67.  
  68.     central file header signature    4 bytes  (0x02014b50)
  69.     version made by            2 bytes
  70.     version needed to extract    2 bytes
  71.     general purpose bit flag    2 bytes
  72.     compression method        2 bytes
  73.     last mod file time         2 bytes
  74.     last mod file date        2 bytes
  75.     crc-32               4 bytes
  76.     compressed size            4 bytes
  77.     uncompressed size        4 bytes
  78.     filename length            2 bytes
  79.     extra field length        2 bytes
  80.     file comment length        2 bytes
  81.     disk number start        2 bytes
  82.     internal file attributes    2 bytes
  83.     external file attributes    4 bytes
  84.     relative offset of local header    4 bytes
  85.  
  86.     filename (variable size)
  87.     extra field (variable size)
  88.     file comment (variable size)
  89.  
  90.       End of central dir record:
  91.  
  92.     end of central dir signature    4 bytes  (0x06054b50)
  93.     number of this disk        2 bytes
  94.     number of the disk with the
  95.     start of the central directory    2 bytes
  96.     total number of entries in
  97.     the central dir on this disk    2 bytes
  98.     total number of entries in
  99.     the central dir            2 bytes
  100.     size of the central directory   4 bytes
  101.     offset of start of central
  102.     directory with respect to
  103.     the starting disk number    4 bytes
  104.     zipfile comment length        2 bytes
  105.     zipfile comment (variable size)
  106.  
  107.  
  108.  
  109.  
  110.   C.  Explanation of fields:
  111.  
  112.       version made by
  113.  
  114.       The upper byte indicates the host system (OS) for the
  115.       file.  Software can use this information to determine
  116.       the line record format for text files etc.  The current
  117.       mappings are:
  118.  
  119.       0 - MS-DOS and OS/2 (F.A.T. file systems)
  120.       1 - Amiga            2 - VMS
  121.       3 - *nix            4 - VM/CMS
  122.       5 - Atari ST                  6 - OS/2 H.P.F.S.
  123.       7 - Macintosh            8 - Z-System
  124.       9 - CP/M            10 thru 255 - unused
  125.  
  126.       The lower byte indicates the version number of the
  127.       software used to encode the file.  The value/10
  128.       indicates the major version number, and the value
  129.       mod 10 is the minor version number.
  130.  
  131.       version needed to extract
  132.  
  133.       The minimum software version needed to extract the
  134.       file, mapped as above.
  135.  
  136.       general purpose bit flag:
  137.  
  138.           bit 0: If set, indicates that the file is encrypted.
  139.           bit 1: If the compression method used was type 6,
  140.          Imploding, then this bit, if set, indicates
  141.          an 8K sliding dictionary was used.  If clear,
  142.          then a 4K sliding dictionary was used.
  143.           bit 2: If the compression method used was type 6,
  144.          Imploding, then this bit, if set, indicates
  145.          an 3 Shannon-Fano trees were used to encode the
  146.          sliding dictionary output.  If clear, then 2
  147.          Shannon-Fano trees were used.
  148.       Note:  Bits 1 and 2 are undefined if the compression
  149.          method is other than type 6 (Imploding).
  150.  
  151.           The upper three bits are reserved and used internally
  152.       by the software when processing the zipfile.  The
  153.       remaining bits are unused in version 1.0.
  154.  
  155.       compression method:
  156.  
  157.       (see accompanying documentation for algorithm
  158.       descriptions)
  159.  
  160.       0 - The file is stored (no compression)
  161.       1 - The file is Shrunk
  162.       2 - The file is Reduced with compression factor 1
  163.       3 - The file is Reduced with compression factor 2
  164.       4 - The file is Reduced with compression factor 3
  165.       5 - The file is Reduced with compression factor 4
  166.           6 - The file is Imploded
  167.  
  168.       date and time fields:
  169.  
  170.       The date and time are encoded in standard MS-DOS
  171.       format.
  172.  
  173.       CRC-32:
  174.  
  175.       The CRC-32 algorithm was generously contributed by
  176.       David Schwaderer and can be found in his excellent
  177.       book "C Programmers Guide to NetBIOS" published by
  178.       Howard W. Sams & Co. Inc.  The 'magic number' for
  179.       the CRC is 0xdebb20e3.  The proper CRC pre and post
  180.       conditioning is used, meaning that the CRC register
  181.       is pre-conditioned with all ones (a starting value
  182.       of 0xffffffff) and the value is post-conditioned by
  183.       taking the one's complement of the CRC residual.
  184.     
  185.       compressed size:
  186.       uncompressed size:
  187.  
  188.       The size of the file compressed and uncompressed,
  189.       respectively.
  190.  
  191.       filename length:
  192.       extra field length:
  193.       file comment length:
  194.  
  195.       The length of the filename, extra field, and comment
  196.       fields respectively.  The combined length of any
  197.       directory record and these three fields should not
  198.       generally exceed 65,535 bytes.
  199.  
  200.       disk number start:
  201.  
  202.       The number of the disk on which this file begins.
  203.  
  204.       internal file attributes:
  205.  
  206.       The lowest bit of this field indicates, if set, that
  207.       the file is apparently an ASCII or text file.  If not
  208.       set, that the file apparently contains binary data.
  209.       The remaining bits are unused in version 1.0.
  210.  
  211.       external file attributes:
  212.  
  213.       The mapping of the external attributes is
  214.       host-system dependent (see 'version made by').  For
  215.       MS-DOS, the low order byte is the MS-DOS directory
  216.       attribute byte.
  217.  
  218.       relative offset of local header:
  219.  
  220.       This is the offset from the start of the first disk on
  221.       which this file appears, to where the local header should
  222.       be found.
  223.  
  224.       filename:
  225.  
  226.       The name of the file, with optional relative path.
  227.       The path stored should not contain a drive or
  228.       device letter, or a leading slash.  All slashes
  229.       should be forward slashes '/' as opposed to
  230.       backwards slashes '\' for compatibility with Amiga
  231.       and Unix file systems etc.
  232.  
  233.       extra field:
  234.  
  235.       This is for future expansion.  If additional information
  236.       needs to be stored in the future, it should be stored
  237.       here.  Earlier versions of the software can then safely
  238.       skip this file, and find the next file or header.  This
  239.       field will be 0 length in version 1.0.
  240.  
  241.       In order to allow different programs and different types 
  242.       of information to be stored in the 'extra' field in .ZIP 
  243.       files, the following structure should be used for all 
  244.       programs storing data in this field:
  245.  
  246.       header1+data1 + header2+data2 . . .
  247.  
  248.       Each header should consist of:
  249.  
  250.         Header ID - 2 bytes
  251.         Data Size - 2 bytes
  252.  
  253.       Note: all fields stored in Intel low-byte/high-byte order.
  254.  
  255.       The Header ID field indicates the type of data that is in 
  256.       the following data block.
  257.       
  258.       Header ID's of 0 thru 31 are reserved for use by PKWARE.  
  259.       The remaining ID's can be used by third party vendors for 
  260.       proprietary usage.
  261.  
  262.       The Data Size field indicates the size of the following 
  263.       data block. Programs can use this value to skip to the 
  264.       next header block, passing over any data blocks that are 
  265.       not of interest.
  266.  
  267.       Note: As stated above, the size of the entire .ZIP file
  268.         header, including the filename, comment, and extra
  269.         field should not exceed 64K in size.
  270.  
  271.       In case two different programs should appropriate the same 
  272.       Header ID value, it is strongly recommended that each 
  273.       program place a unique signature of at least two bytes in 
  274.       size (and preferably 4 bytes or bigger) at the start of 
  275.       each data area.  Every program should verify that it's 
  276.       unique signature is present, in addition to the Header ID 
  277.       value being correct, before assuming that it is a block of 
  278.       known type.
  279.  
  280.       file comment:
  281.  
  282.       The comment for this file.
  283.  
  284.       number of this disk:
  285.  
  286.       The number of this disk, which contains central
  287.       directory end record.
  288.  
  289.       number of the disk with the start of the central directory:
  290.  
  291.       The number of the disk on which the central
  292.       directory starts.
  293.  
  294.       total number of entries in the central dir on this disk:
  295.  
  296.       The number of central directory entries on this disk.
  297.     
  298.       total number of entries in the central dir:
  299.  
  300.       The total number of files in the zipfile.
  301.  
  302.  
  303.       size of the central directory:
  304.  
  305.       The size (in bytes) of the entire central directory.
  306.  
  307.       offset of start of central directory with respect to
  308.       the starting disk number:
  309.  
  310.       Offset of the start of the central direcory on the
  311.       disk on which the central directory starts.
  312.  
  313.       zipfile comment length:
  314.  
  315.       The length of the comment for this zipfile.
  316.  
  317.       zipfile comment:
  318.  
  319.       The comment for this zipfile.
  320.  
  321.  
  322.   D.  General notes:
  323.  
  324.       1)  All fields unless otherwise noted are unsigned and stored
  325.       in Intel low-byte:high-byte, low-word:high-word order.
  326.  
  327.       2)  String fields are not null terminated, since the
  328.       length is given explicitly.
  329.  
  330.       3)  Local headers should not span disk boundries.  Also, even
  331.       though the central directory can span disk boundries, no
  332.       single record in the central directory should be split
  333.       across disks.
  334.  
  335.       4)  The entries in the central directory may not necessarily
  336.       be in the same order that files appear in the zipfile.
  337.  
  338. */
  339.  
  340. /* Code starts here */
  341.  
  342. #include <stdio.h>
  343. #include <stdlib.h>
  344. #include <stdarg.h>
  345. #include <string.h>
  346. #include <fcntl.h>
  347. #include <time.h>
  348. #include <malloc.h>
  349. #include <io.h>
  350.  
  351.  
  352. #pragma pack(2)
  353.  
  354. struct local_zip_header
  355. {
  356.   unsigned long    signature;    /* 0x04034b50 */
  357.   unsigned int    extr_ver;    /* version needed to extract */
  358.   unsigned int    bit_flag;    /* general purpose bit flag */
  359.   unsigned int    method;        /* compression method */
  360.   unsigned int    last_mod_time;     /* last mod file time */
  361.   unsigned int    last_mod_date;    /* last mod file date */
  362.   unsigned long    crc;        /* crc-32 */
  363.   unsigned long comp_size;    /* compressed size */
  364.   unsigned long uncomp_size;    /* uncompressed size */
  365.   size_t    name_len;    /* filename length */
  366.   size_t    extra_len;    /* extra field length */
  367.  
  368.   /* filename (variable size) */
  369.   /* extra field (variable size) */
  370. };
  371.  
  372. struct zip_header
  373. {
  374.   unsigned long    signature;    /* 0x02014b50 */
  375.   unsigned int    creat_ver;    /* version made by */
  376.   unsigned int    extr_ver;    /* version needed to extract */
  377.   unsigned int    bit_flag;    /* general purpose bit flag */
  378.   unsigned int    method;        /* compression method */
  379.   unsigned int    last_mod_time;     /* last mod file time */
  380.   unsigned int    last_mod_date;    /* last mod file date */
  381.   unsigned long    crc;        /* crc-32 */
  382.   unsigned long comp_size;    /* compressed size */
  383.   unsigned long uncomp_size;    /* uncompressed size */
  384.   size_t    name_len;    /* filename length */
  385.   size_t    extra_len;    /* extra field length */
  386.   size_t    comment_len;    /* file comment length */
  387.   unsigned int    disk_start;    /* disk number start */
  388.   unsigned int    int_attrib;    /* internal file attributes */
  389.   unsigned long    ext_attrib;    /* external file attributes */
  390.   unsigned long offset;        /* relative offset of local header */
  391.  
  392.   /* filename (variable size) */
  393.   /* extra field (variable size) */
  394.   /* file comment (variable size) */
  395. };
  396.  
  397. struct central_dir
  398. {
  399.   unsigned long    signature;    /* 0x06054b50 */
  400.   unsigned int    disk_num;    /* number of this disk */
  401.   unsigned int    cd_disk_num;    /* number of the disk with the start
  402.                    of the central directory */
  403.   unsigned int    dir_entries;    /* total number of entries in the
  404.                    central dir on this disk */
  405.   unsigned int    total_entries;    /* total number of entries in the
  406.                    central dir */
  407.   unsigned long    dir_size;    /* size of the central directory */
  408.   unsigned long    dir_offset;    /* offset of start of central directory
  409.                    with respect to the starting disk number */
  410.   size_t    comment_len;    /* zipfile comment length */
  411.  
  412.   /* zipfile comment (variable size) */
  413. };
  414.  
  415. #pragma pack()
  416.  
  417.  
  418. char *zip_get_first (char *filename, int *fd_ptr,
  419.              struct local_zip_header *header,
  420.              long *header_pos, long *data_pos);
  421. char *zip_get_next (int fd, struct local_zip_header *header,
  422.             long *header_pos, long *data_pos);
  423.  
  424. long ar_scan (char *archive, long (*f) (int, char *, long, long, long, long,
  425.           int, int, int, long), long arg);
  426. static long ar_member_pos (int desc, char *name, long hdrpos, long datapos,
  427.                long size, long date, int uid, int gid, int mode,
  428.                char *mem);
  429. long ar_name_equal (char *name, char *mem);
  430. long ar_member_touch (char *arname, char *memname);
  431.  
  432. time_t dos_time (unsigned int time, unsigned int date);
  433.  
  434. extern void *xmalloc (size_t size);
  435.  
  436. #ifdef TEST
  437. char *program_name;
  438. void fatal (int code, char *format, ... );
  439. #endif
  440.  
  441. static int month_offset[12] =
  442. {
  443.     0, /* January */
  444.    31, /* February */
  445.    59, /* March */
  446.    90, /* April */
  447.   120, /* May */
  448.   151, /* June */
  449.   181, /* July */
  450.   212, /* August */
  451.   243, /* September */
  452.   273, /* October */
  453.   304, /* November */
  454.   334, /* December */
  455. };
  456.  
  457.  
  458. #define leap_year(n)    (((n) & 0x0600) == 0)    /* 1980 was! */
  459. #define year(n)        (((n) & 0xff00) >> 9)
  460. #define month(n)    (((n) & 0x01e0) >> 5)
  461. #define day(n)        ((n) & 0x001f)
  462.  
  463. #define hour(n)        (((n) & 0xf800) >> 11)
  464. #define minutes(n)    (((n) & 0x07e0) >> 5)
  465. #define seconds(n)    (((n) & 0x001f) << 1)
  466.  
  467. time_t
  468. dos_time (unsigned int time, unsigned int date)
  469. {
  470.   time_t result = 3652;        /* 1970 - 1980, (incl. 2 leap years) */
  471.  
  472.   result += year (date) * 365L;
  473.   result += year (date) >> 2;    /* add leap years! */
  474.  
  475.   result += month_offset[month (date) - 1] + day (date);
  476.  
  477.   if (leap_year(date) && month (date) > 2)    /* After Feb. in leap year */
  478.     result++;
  479.   result *= 24L;        /* convert to hours */
  480.   result += hour (time);
  481.  
  482.   result *= 60L;        /* convert to minutes */
  483.   result += minutes (time);
  484.  
  485.   result *= 60L;        /* convert to seconds */
  486.   result += seconds (time);
  487.  
  488.   return result + timezone;
  489. }
  490.  
  491. /* Magic numbers.  */
  492.  
  493. #define ZIP_HEADER_SIGNATURE    0x02014b50    /* "\x50\x4b" = "PK" !!! */
  494. #define LOCAL_HEADER_SIGNATURE    0x04034b50
  495. #define CENTRAL_DIR_SIGNATURE    0x06054b50
  496.  
  497. char *
  498. zip_get_first (char *filename, int *fd_ptr, struct local_zip_header *header,
  499.            long *header_pos, long *data_pos)
  500. {
  501.   tzset ();            /* in case the caller forgot */
  502.  
  503.   *fd_ptr = open (filename, O_RDONLY|O_BINARY);
  504.  
  505.   if (*fd_ptr < 0)
  506.     return NULL;
  507.  
  508.   return zip_get_next (*fd_ptr, header, header_pos, data_pos);
  509. }
  510.  
  511.  
  512. char *
  513. zip_get_next (int fd, struct local_zip_header *header,
  514.           long *header_pos, long *data_pos)
  515. {
  516.   size_t bytes;
  517.   char *member_name = NULL;
  518.  
  519.   *header_pos = tell (fd);
  520.  
  521.   bytes = read (fd, (char *) header, sizeof (struct local_zip_header));
  522.   if (bytes != sizeof (struct local_zip_header))
  523.     return NULL;
  524.  
  525.   if (header->signature != LOCAL_HEADER_SIGNATURE)
  526.     return NULL;
  527.  
  528.   member_name = (char *) xmalloc (header->name_len + 1);
  529.  
  530.   bytes = read (fd, member_name, header->name_len);
  531.   if (bytes != header->name_len)
  532.     return NULL;
  533.  
  534.   member_name[header->name_len] = '\0';
  535.  
  536.   *data_pos = *header_pos + sizeof (struct local_zip_header)
  537.           + header->name_len + header->extra_len;
  538.  
  539.   lseek (fd, header->comp_size + (long) header->extra_len, SEEK_CUR);
  540.  
  541.   return strlwr (member_name);
  542. }
  543.  
  544.  
  545. /* Takes three arguments ARCHIVE, FUNCTION and ARG.
  546.  
  547.    Open the archive named ARCHIVE, find its members one by one,
  548.    and for each one call FUNCTION with the following arguments:
  549.      archive file descriptor for reading the data,
  550.      member name,
  551.      member header position in file,
  552.      member data position in file,
  553.      member data size,
  554.      member date,
  555.      member uid,
  556.      member gid,
  557.      member protection mode,
  558.      ARG.
  559.  
  560.    The descriptor is poised to read the data of the member
  561.    when FUNCTION is called.  It does not matter how much
  562.    data FUNCTION reads.
  563.  
  564.    If FUNCTION returns nonzero, we immediately return
  565.    what FUNCTION returned.
  566.  
  567.    Returns -1 if archive does not exist,
  568.    Returns -2 if archive has invalid format.
  569.    Returns 0 if have scanned successfully.  */
  570.  
  571. long
  572. ar_scan (char *archive,
  573.      long (*f) (int, char *, long, long, long, long, int, int, int, long),
  574.      long arg)
  575. {
  576.   int fd;
  577.   struct local_zip_header header;
  578.   long header_pos;
  579.   long data_pos;
  580.   char *name = zip_get_first (archive, &fd, &header, &header_pos, &data_pos);
  581.  
  582.   if (fd < 0)
  583.     return -1L;
  584.   if (name == NULL)
  585.     return -2L;
  586.  
  587.   while (name && *name)
  588.     {
  589.       time_t time_buf = dos_time (header.last_mod_time, header.last_mod_date);
  590.  
  591.       long fnval = (*f) (fd, name,
  592.              header_pos, data_pos,
  593.              header.uncomp_size,
  594.              time_buf,
  595.              0, 0, 0,
  596.              arg);
  597.  
  598.       if (fnval)
  599.     {
  600.       close (fd);
  601.       return fnval;
  602.     }
  603.  
  604.       free (name);
  605.  
  606.       name = zip_get_next (fd, &header, &header_pos, &data_pos);
  607.     }
  608.  
  609.   close (fd);
  610.   return 0L;
  611. }
  612.  
  613. /* Return nonzero iff NAME matches MEM.  If NAME is longer than
  614.    sizeof (struct ar_hdr.ar_name), MEM may be the truncated version.  */
  615.  
  616. long
  617. ar_name_equal (name, mem)
  618.      char *name, *mem;
  619. {
  620.   return (long) !strcmp (name, mem);
  621. }
  622.  
  623. /* ARGSUSED */
  624. static long int
  625. ar_member_pos (desc, name, hdrpos, datapos, size, date, uid, gid, mode, mem)
  626.      int desc;
  627.      char *name;
  628.      long int hdrpos, datapos, size, date;
  629.      int uid, gid, mode;
  630.      char *mem;
  631. {
  632.   if (!ar_name_equal (name, mem))
  633.     return 0;
  634.   return hdrpos;
  635. }
  636.  
  637. /* Set date of member MEMNAME in archive ARNAME to current time.
  638.    Returns 0 if successful,
  639.    -1 if file ARNAME does not exist,
  640.    -2 if not a valid archive,
  641.    -3 if other random system call error (including file read-only),
  642.    1 if valid but member MEMNAME does not exist.  */
  643.  
  644. long
  645. ar_member_touch (arname, memname)
  646.      char *arname, *memname;
  647. {
  648.   /* CODE ME !!! */
  649.  
  650.   return -3L;
  651. }
  652.  
  653. #ifdef TEST
  654.  
  655. long int
  656. describe_member (desc, name, hdrpos, datapos, size, date, uid, gid, mode)
  657.      int desc;
  658.      char *name;
  659.      long int hdrpos, datapos, size, date;
  660.      int uid, gid, mode;
  661. {
  662.   extern char *ctime ();
  663.  
  664.   printf ("Member %s: %ld bytes at %ld (%ld).\n", name, size, hdrpos, datapos);
  665.   printf ("  Date %s", ctime (&date));
  666.   printf ("  uid = %d, gid = %d, mode = 0%o.\n", uid, gid, mode);
  667.  
  668.   return 0;
  669. }
  670.  
  671. void
  672. main (int argc, char **argv)
  673. {
  674.   ar_scan (argv[1], describe_member);
  675. }
  676.  
  677.  
  678. void *
  679. xmalloc (size_t size)
  680. {
  681.   register void *ptr = malloc (size);
  682.  
  683.   if (ptr == (void *)0)
  684.     fatal (2, "out of memory");
  685.  
  686.   return(ptr);
  687. }
  688.  
  689. void
  690. fatal (int code, char *format, ... )
  691. {
  692.   va_list arg_ptr;        /* variable-length arguments    */
  693.   va_start (arg_ptr, format);
  694.  
  695.   fprintf (stderr, "%s: fatal error: ", program_name);
  696.   vfprintf (stderr, format, arg_ptr);
  697.   fprintf (stderr, ".\n");
  698.   exit (code);
  699. }
  700.  
  701. #endif /* TEST */
  702.  
  703. #if 0
  704.  
  705. /* Look alike to the portable directory functions.*/
  706.  
  707. struct _zipcontents
  708. {
  709.   char *_z_entry;
  710.   struct _zipcontents *_z_next;
  711. };
  712.  
  713. typedef struct _zipdesc
  714. {
  715.   int zd_fd;                /* file handle */
  716.   int zd_access;            /* access mode (O_RDWR or O_RDONLY) */
  717.   struct _zipcontents *zd_contents;    /* root of the list of entries */
  718.   struct _zipcontents *zd_cp;        /* current entry */
  719. } ZIP;
  720.  
  721.  
  722. #define    rewindzip(zipp)    seekzip (zipp, 0L)
  723.  
  724. void seekzip (ZIP *zipp, long off);
  725. long tellzip (ZIP *zipp);
  726. ZIP *openzip (char *name);
  727. void closezip (ZIP *zipp);
  728. struct zip_header *readzip (ZIP *zipp);
  729.  
  730. void
  731. seekzip (ZIP *zipp, long off)
  732. {
  733.   /* CODE ME !!! */
  734.  
  735.   return lseek (zipp->zd_fd, off, SEEK_SET);
  736.  
  737.   /* better: seek() for name! */
  738. }
  739.  
  740. long
  741. tellzip (ZIP *zipp)
  742. {
  743.   /* CODE ME !!! */
  744.  
  745.   return tell (zipp->zd_fd);
  746. }
  747.  
  748. /* Open the zipfile NAME, scan through the local headers and check with
  749.    the central directory for consistency.  Put the central directory
  750.    entries into the linked list rooted by zipp->zd_contents.  */
  751.  
  752. ZIP *
  753. openzip (char *name)
  754. {
  755.   ZIP *zipp;
  756.  
  757.   zipp->zd_access = O_RDWR;    /* we might want to `touch' the archive  */
  758.   zipp->zd_fd = open (name, zipp->zd_access|O_BINARY);
  759.   if (zipp->zd_fd == -1)
  760.     {                /* at least, try to read the archive  */
  761.       zipp->zd_access = O_RDONLY;
  762.       zipp->zd_fd = open (name, zipp->zd_access|O_BINARY);
  763.       if (zipp->zd_fd == -1)
  764.     return NULL;
  765.     }
  766.  
  767.   /* CODE ME !!! */
  768.  
  769.   return zipp;
  770. }
  771.  
  772. void
  773. closezip (ZIP *zipp)
  774. {
  775.   /* CODE ME !!! */
  776.  
  777.   close (zipp->zd_fd);
  778. }
  779.  
  780. struct zip_header *
  781. readzip (ZIP *zipp)
  782. {
  783.   /* CODE ME !!! */
  784. }
  785.  
  786. #endif /* NEVER */
  787.  
  788. /* 
  789.  * Local Variables:
  790.  * mode:C
  791.  * ChangeLog:ChangeLog
  792.  * compile-command:cl -DTEST -W4 zipscan.c
  793.  * End:
  794.  */
  795.