zipup.c

来自「infozip2.2源码」· C语言 代码 · 共 739 行 · 第 1/2 页

C
739
字号
/* Copyright (C) 1990-1997 Mark Adler, Richard B. Wales, Jean-loup Gailly, Kai Uwe Rommel, Onno van der Linden and Igor Mandrichenko. Permission is granted to any individual or institution to use, copy, or redistribute this software so long as all of the original files are included, that it is not sold for profit, and that this copyright notice is retained.*//* *  zipup.c by Mark Adler and Jean-loup Gailly. */#define NOCPYRT         /* this is not a main module */#include <ctype.h>#include "zip.h"#ifndef UTIL            /* This module contains no code for Zip Utilities */#include "revision.h"#include "crypt.h"#ifdef OS2#  include "os2/os2zip.h"#endif#if defined(MMAP)#  include <sys/mman.h>#  ifndef PAGESIZE   /* used to be SYSV, what about pagesize on SVR3 ? */#    define PAGESIZE getpagesize()#  endif#  if defined(NO_VALLOC) && !defined(valloc)#    define valloc malloc#  endif#endif/* Use the raw functions for MSDOS and Unix to save on buffer space.   They're not used for VMS since it doesn't work (raw is weird on VMS).   (This sort of stuff belongs in fileio.c, but oh well.) */#ifdef AMIGA#  include "amiga/zipup.h"#endif /* AMIGA */#ifdef AOSVS#  include "aosvs/zipup.h"#endif /* AOSVS */#ifdef ATARI#  include "atari/zipup.h"#endif#ifdef __BEOS__#  include "beos/zipup.h"#endif#ifdef __human68k__#  include "human68k/zipup.h"#endif /* __human68k__ */#ifdef DOS#  include "msdos/zipup.h"#endif /* DOS */#ifdef OS2#  include "os2/zipup.h"#endif /* OS2 */#ifdef RISCOS#  include "acorn/zipup.h"#endif#ifdef TOPS20#  include "tops20/zipup.h"#endif#ifdef UNIX#  include "unix/zipup.h"#endif#ifdef CMS_MVS#  include "zipup.h"#endif /* CMS_MVS */#ifdef TANDEM#  include "zipup.h"#endif /* TANDEM */#ifdef VMS#  include "vms/zipup.h"#endif /* VMS */#ifdef QDOS#  include "qdos/zipup.h"#endif /* QDOS */#ifdef WIN32#  include "win32/zipup.h"#endif/* Deflate "internal" global data (currently not in zip.h) */#if defined(MMAP) || defined(BIG_MEM)  extern uch * window;          /* Used to read all input file at once */#endifextern ulg window_size;         /* size of said window *//* Local data */  local ulg crc;       /* crc on uncompressed file data */  local ftype ifile;   /* file to compress */#if defined(MMAP) || defined(BIG_MEM)  local long remain;  /* window bytes not yet processed.   *  >= 0 only for BIG_MEM or MMAP, -1 for normal reads.   */#endif /* MMAP || BIG_MEM */#ifdef DEBUG  ulg isize;           /* input file size. global only for debugging */#else /* !DEBUG */  local ulg isize;     /* input file size. */#endif /* ?DEBUG *//* Local functions */#ifndef RISCOS   local int suffixes OF((char *, char *));#else   local int filetypes OF((char *, char *));#endifint percent(n, m)ulg n;ulg m;               /* n is the original size, m is the new size *//* Return the percentage compression from n to m using only integer   operations */{  if (n > 0xffffffL)            /* If n >= 16M */  {                             /*  then divide n and m by 256 */    n += 0x80;  n >>= 8;    m += 0x80;  m >>= 8;  }  return n > m ? (int)(1 + (200 * (n - m)/n)) / 2 : 0;}#ifndef RISCOSlocal int suffixes(a, s)char *a;                /* name to check suffix of */char *s;                /* list of suffixes separated by : or ; *//* Return true if a ends in any of the suffixes in the list s. */{  int m;                /* true if suffix matches so far */  char *p;              /* pointer into special */  char *q;              /* pointer into name a */#ifdef QDOS  short dlen = devlen(a);  a = a + dlen;#endif  m = 1;#ifdef VMS  if( (q = strrchr(a,';')) != NULL )    /* Cut out VMS file version */    --q;  else    q = a + strlen(a) - 1;#else /* !VMS */  q = a + strlen(a) - 1;#endif /* ?VMS */  for (p = s + strlen(s) - 1; p >= s; p--)    if (*p == ':' || *p == ';')      if (m)        return 1;      else      {        m = 1;#ifdef VMS        if( (q = strrchr(a,';')) != NULL )      /* Cut out VMS file version */          --q;        else          q = a + strlen(a) - 1;#else /* !VMS */        q = a + strlen(a) - 1;#endif /* ?VMS */      }    else    {      m = m && q >= a && case_map(*p) == case_map(*q);      q--;    }  return m;}#else /* RISCOS */local int filetypes(a, s)char *a;                /* extra field of file to check filetype of */char *s;                /* list of filetypes separated by : or ; *//* Return true if a is any of the filetypes in the list s. */{ char *p;              /* pointer into special */ char typestr[4];     /* filetype hex string taken from a */ if ((((unsigned*)a)[2] & 0xFFF00000) != 0xFFF00000) { /* The file is not filestamped, always try to compress it */   return 0; } sprintf(typestr,"%.3X",(((unsigned*)a)[2] & 0x000FFF00) >> 8); for (p=s;p<=s+strlen(s)-3;p+=3) { /* p+=3 to skip 3 hex type */   while (*p==':' || *p==';')     p++;   if (typestr[0]==toupper(p[0]) && typestr[1]==toupper(p[1]) && typestr[2]==toupper(p[2]))     return 1; } return 0;}#endif /* ?RISCOS *//* Note: a zip "entry" includes a local header (which includes the file   name), an encryption header if encrypting, the compressed data   and possibly an extended local header. */int zipup(z, y)struct zlist far *z;    /* zip entry to compress */FILE *y;                /* output file *//* Compress the file z->name into the zip entry described by *z and write   it to the file *y. Encrypt if requested.  Return an error code in the   ZE_ class.  Also, update tempzn by the number of bytes written. */{  iztimes f_utim;       /* UNIX GMT timestamps, filled by filetime() */  ulg tim;              /* time returned by filetime() */  ulg a = 0L;           /* attributes returned by filetime() */  char *b;              /* malloc'ed file buffer */  extent k = 0;         /* result of zread */  int l = 0;            /* true if this file is a symbolic link */  int m;                /* method for this entry */  ulg o, p;             /* offsets in zip file */  long q = -3L;         /* size returned by filetime */  int r;                /* temporary variable */  ulg s = 0L;           /* size of compressed data */  int isdir;            /* set for a directory name */  int set_type = 0;     /* set if file type (ascii/binary) unknown */  z->nam = strlen(z->iname);  isdir = z->iname[z->nam-1] == '/';  if ((tim = filetime(z->name, &a, &q, &f_utim)) == 0 || q < -2L)    return ZE_OPEN;  /* q is set to -1 if the input file is a device, -2 for a volume label */  if (q == -2L) {     isdir = 1;     q = 0;  } else if (isdir != ((a & MSDOS_DIR_ATTR) != 0)) {     /* don't overwrite a directory with a file and vice-versa */     return ZE_MISS;  }  z->att = (ush)UNKNOWN; /* will be changed later */  z->atx = 0; /* may be changed by set_extra_field() */  /* Free the old extra fields which are probably obsolete */  if (z->ext) {    free((zvoid *)(z->extra));  }  if (z->cext && z->extra != z->cextra) {    free((zvoid *)(z->cextra));  }  z->extra = z->cextra = NULL;  z->ext = z->cext = 0;#if defined(MMAP) || defined(BIG_MEM)  remain = -1L; /* changed only for MMAP or BIG_MEM */#endif /* MMAP || BIG_MEM */  window_size = 0L;  /* Select method based on the suffix and the global method */#ifndef RISCOS  m = special != NULL && suffixes(z->name, special) ? STORE : method;#else /* RISCOS  must set m after setting extra field */  m = method;#endif /* ?RISCOS */  /* Open file to zip up unless it is stdin */  if (strcmp(z->name, "-") == 0)  {    ifile = (ftype)zstdin;#if defined(MSDOS) || defined(__human68k__)    setmode(zstdin, O_BINARY);#endif    z->tim = tim;  }  else  {#if !(defined(VMS) && defined(VMS_PK_EXTRA))    if (extra_fields) {      /* create extra field and change z->att and z->atx if desired */      set_extra_field(z, &f_utim);#ifdef QLZIP      if(qlflag)          a |= (S_IXUSR) << 16;   /* Cross compilers don't set this */#endif#ifdef RISCOS      m = special != NULL && filetypes(z->extra, special) ? STORE : method;#endif /* RISCOS */    }#endif /* !(VMS && VMS_PK_EXTRA) */    l = issymlnk(a);    if (l)      ifile = fbad;    else if (isdir) { /* directory */      ifile = fbad;      m = STORE;      q = 0;    }    else {#ifdef CMS_MVS      if (bflag) {        if ((ifile = zopen(z->name, fhowb)) == fbad)           return ZE_OPEN;      }      else#endif /* CMS_MVS */      if ((ifile = zopen(z->name, fhow)) == fbad)         return ZE_OPEN;    }    z->tim = tim;#if defined(VMS) && defined(VMS_PK_EXTRA)    /* vms_get_attributes must be called after vms_open() */    if (extra_fields) {      /* create extra field and change z->att and z->atx if desired */      vms_get_attributes(ifile, z, &f_utim);    }#endif /* VMS && VMS_PK_EXTRA */#ifdef MMAP    /* Map ordinary files but not devices. This code should go in fileio.c */    if (q > 0 && !translate_eol) {      if (window != NULL)        free(window);  /* window can't be a mapped file here */      window_size = q + MIN_LOOKAHEAD;      remain = window_size & (PAGESIZE-1);      /* If we can't touch the page beyond the end of file, we must       * allocate an extra page.       */      if (remain > MIN_LOOKAHEAD) {        window = (uch*)mmap(0, window_size, PROT_READ, MAP_PRIVATE, ifile, 0);      } else {        window = (uch*)valloc(window_size - remain + PAGESIZE);        if (window != NULL) {          window = (uch*)mmap((char*)window, window_size - remain, PROT_READ,                        MAP_PRIVATE | MAP_FIXED, ifile, 0);        } else {          window = (uch*)(-1);        }      }      if (window == (uch*)(-1)) {        Trace((mesg, " mmap failure on %s\n", z->name));        window = NULL;        window_size = 0L;        remain = -1L;      } else {        remain = q;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?