📄 zipup.c
字号:
/* Copyright (c) 1990-2006 Info-ZIP. All rights reserved. See the accompanying file LICENSE, version 2005-Feb-10 or later (the contents of which are also included in zip.h) for terms of use. If, for some reason, all these files are missing, the Info-ZIP license also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html*//* * zipup.c by Mark Adler and Jean-loup Gailly. */#define __ZIPUP_C#include "zip.h"#include <ctype.h>#ifndef UTIL /* This module contains no code for Zip Utilities */#include "revision.h"#include "crypt.h"#ifdef USE_ZLIB# include "zlib.h"#endif#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). */#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 __ATHEOS__# include "atheos/zipup.h"#endif /* __ATHEOS__ */#ifdef __human68k__# include "human68k/zipup.h"#endif /* __human68k__ */#ifdef MACOS# include "macos/zipup.h"#endif#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#ifdef THEOS# include "theos/zipup.h"#endif/* Local functions */#ifndef RISCOS local int suffixes OF((char *, char *));#else local int filetypes OF((char *, char *));#endiflocal unsigned file_read OF((char *buf, unsigned size));#ifdef USE_ZLIB local int zl_deflate_init OF((int pack_level));#else /* !USE_ZLIB */# ifdef ZP_NEED_MEMCOMPR local unsigned mem_read OF((char *buf, unsigned size));# endif#endif /* ?USE_ZLIB */local ulg filecompress OF((struct zlist far *z_entry, FILE *zipfile, int *cmpr_method));/* Deflate "internal" global data (currently not in zip.h) */#if defined(MMAP) || defined(BIG_MEM)# ifdef USE_ZLIB local uch *window = NULL; /* Used to read all input file at once */ local ulg window_size; /* size of said window */# else /* !USE_ZLIB */ extern uch *window; /* Used to read all input file at once */#endif /* ?USE_ZLIB */#endif /* MMAP || BIG_MEM */#ifndef USE_ZLIB extern ulg window_size; /* size of said window */ unsigned (*read_buf) OF((char *buf, unsigned size)) = file_read; /* Current input function. Set to mem_read for in-memory compression */#endif /* !USE_ZLIB *//* Local data */local ulg crc; /* crc on uncompressed file data */local ftype ifile; /* file to compress */#if defined(MMAP) || defined(BIG_MEM) local ulg remain; /* window bytes not yet processed. * special value "(ulg)-1L" reserved to signal normal reads. */#endif /* MMAP || BIG_MEM */#ifdef USE_ZLIB local int deflInit; /* flag: zlib deflate is initialized */ local z_stream zstrm; /* zlib's data interface structure */ local char *f_ibuf = NULL; local char *f_obuf = NULL;#else /* !USE_ZLIB */ local FILE *zfile; /* output zip file */ local char file_outbuf[1024]; /* output buffer for compression to file */# ifdef ZP_NEED_MEMCOMPR local char *in_buf; /* Current input buffer, in_buf is used only for in-memory compression. */ local unsigned in_offset; /* Current offset in input buffer. in_offset is used only for in-memory * compression. On 16 bit machines, the buffer is limited to 64K. */ local unsigned in_size; /* size of current input buffer */# endif /* ZP_NEED_MEMCOMPR */#endif /* ?USE_ZLIB */#ifdef DEBUG ulg isize; /* input file size. global only for debugging */#else /* !DEBUG */ local ulg isize; /* input file size. */#endif /* ?DEBUG */int 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 = 0, 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 */ ulg last_o; /* used to check if we wrapped beyond what fseek can handle */ z->nam = strlen(z->iname); isdir = z->iname[z->nam-1] == (char)0x2f; /* ascii[(unsigned)('/')] */ if ((tim = filetime(z->name, &a, &q, &f_utim)) == 0 || q == -3L) 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 = (ulg)-1L; /* changed only for MMAP or BIG_MEM */#endif /* MMAP || BIG_MEM */#if (!defined(USE_ZLIB) || defined(MMAP) || defined(BIG_MEM)) window_size = 0L;#endif /* !USE_ZLIB || MMAP || BIG_MEM */ /* 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__) if (isatty(zstdin) == 0) /* keep default mode if stdin is a terminal */ 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; m = STORE; } else if (isdir) { /* directory */ ifile = fbad; m = STORE; q = 0; }#ifdef THEOS else if (((a >> 16) & S_IFMT) == S_IFLIB) { /* library */ ifile = fbad; m = STORE; q = 0; }#endif 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -