⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vmszip.c

📁 给出了 zip 压缩算法的完整实现过程。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  Copyright (c) 1990-2005 Info-ZIP.  All rights reserved.  See the accompanying file LICENSE, version 2004-May-22 or later  (the contents of which are also included in zip.h) for terms of use.  If, for some reason, both of these files are missing, the Info-ZIP license  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html*//* 2004-09-25 SMS.   Added case-insensitive file name comparisons, with the option of   preserving case in file names.  Defining VMS_PRESERVE_CASE will cause   incompatibility with Zip 2.3 and earlier.*//* #define VMS_PRESERVE_CASE */  /* Not for general use. */#include "zip.h"#include <ctype.h>#include <time.h>#include <unixlib.h>/* Judge availability of str[n]casecmp() in C RTL.   (Note: This must follow a "#include <decc$types.h>" in something to   ensure that __CRTL_VER is as defined as it will ever be.  DEC C on   VAX may not define it itself.)*/#ifdef __CRTL_VER#if __CRTL_VER >= 70000000#define HAVE_STRCASECMP#endif /* __CRTL_VER >= 70000000 */#endif /* def __CRTL_VER */#ifdef HAVE_STRCASECMP#include <strings.h>    /* str[n]casecmp() */#endif /* def HAVE_STRCASECMP */#include <descrip.h>#include <rms.h>#include <ssdef.h>#include <starlet.h>#define PATH_START '['#define PATH_END ']'#define PATH_START2 '<'#define PATH_END2 '>'#include "vms/vmsmunch.h"/* Extra malloc() space in names for cutpath() */#define PAD 5         /* may have to change .FOO] to ]FOO.DIR;1 */#ifndef UTIL    /* the companion #endif is a bit of ways down ... *//* The C RTL from OpenVMS 7.0 and newer supplies POSIX compatible versions of * opendir() et al. Thus, we have to use other names in our private code for * directory scanning to prevent symbol name conflicts at link time. * For now, we do not use the library supplied "dirent.h" functions, since * our private implementation provides some functionality which may not be * present in the library versions.  For example: * ==> zopendir("DISK:[DIR.SUB1]SUB2.DIR") scans "DISK:[DIR.SUB1.SUB2]". */typedef struct zdirent {  int d_wild;                /* flag for wildcard vs. non-wild */  struct FAB fab;  struct NAM nam;  char d_qualwildname[NAM$C_MAXRSS + 1];  char d_name[NAM$C_MAXRSS + 1];} zDIR;extern char *label;local ulg label_time = 0;local ulg label_mode = 0;local time_t label_utim = 0;/* Local functions */local void vms_wild OF((char *, zDIR *));local zDIR *zopendir OF((ZCONST char *));local char *readd OF((zDIR *));local char *strlower OF((char *));local char *strupper OF((char *));/* 2004-09-25 SMS.   str[n]casecmp() replacement for old C RTL.   Assumes a prehistorically incompetent toupper().*/#ifndef HAVE_STRCASECMPint strncasecmp( s1, s2, n)char *s1;char *s2;size_t n;{  /* Initialization prepares for n == 0. */  char c1 = '\0';  char c2 = '\0';  while (n-- > 0)  {    /* Set c1 and c2.  Convert lower-case characters to upper-case. */    if (islower( c1 = *s1))      c1 = toupper( c1);    if (islower( c2 = *s2))      c2 = toupper( c2);    /* Quit at inequality or NUL. */    if ((c1 != c2) || (c1 == '\0'))      break;    s1++;    s2++;  }return ((unsigned int)c1 - (unsigned int)c2);}#ifndef UINT_MAX#define UINT_MAX 4294967295U#endif#define strcasecmp( s1, s2) strncasecmp( s1, s2, UINT_MAX)#endif /* ndef HAVE_STRCASECMP *//* 2004-09-27 SMS.   eat_carets().   Delete ODS5 extended file name escape characters ("^") in the   original buffer.   Note that the current scheme handles only simple EFN cases, but it   could be made more complicated.*/local void eat_carets( str)char *str;      /* Source pointer. */{  char *strd;   /* Destination pointer. */  /* Skip ahead to the first "^", if any. */  while ((*str != '\0') && (*str != '^'))     str++;  /* If no caret was found, quit early. */  if (*str != '\0')  {    /* Shift characters leftward as carets are found. */    strd = str;    while (*str != '\0')    {      if (*str == '^')      {        /* Found a caret.  Skip it, and take the next character. */        *strd = *(++str);      }      else      {        /* Found a non-caret.  Take it. */        *strd = *str;      }      /* Advance destination and source pointers. */      strd++;      str++;    }    /* Terminate the destination string. */    *strd = '\0';  }}/*---------------------------------------------------------------------------    _vms_findfirst() and _vms_findnext(), based on public-domain DECUS C    fwild() and fnext() routines (originally written by Martin Minow, poss-    ibly modified by Jerry Leichter for bintnxvms.c), were written by Greg    Roelofs and are still in the public domain.  Routines approximate the    behavior of MS-DOS (MSC and Turbo C) findfirst and findnext functions.  ---------------------------------------------------------------------------*/static char wild_version_part[10]="\0";local void vms_wild(p, d)char *p;zDIR *d;{  /*   * Do wildcard setup   */  /* set up the FAB and NAM blocks. */  d->fab = cc$rms_fab;             /* initialize fab */  d->nam = cc$rms_nam;             /* initialize nam */  d->fab.fab$l_nam = &d->nam;           /* fab -> nam */  d->fab.fab$l_fna = p;                 /* argument wild name */  d->fab.fab$b_fns = strlen(p);         /* length */  d->fab.fab$l_dna = "sys$disk:[]";     /* Default fspec */  d->fab.fab$b_dns = sizeof("sys$disk:[]")-1;  d->nam.nam$l_esa = d->d_qualwildname; /* qualified wild name */  d->nam.nam$b_ess = NAM$C_MAXRSS;      /* max length */  d->nam.nam$l_rsa = d->d_name;         /* matching file name */  d->nam.nam$b_rss = NAM$C_MAXRSS;      /* max length */  /* parse the file name */  if (sys$parse(&d->fab) != RMS$_NORMAL)    return;  /* Does this replace d->fab.fab$l_fna with a new string in its own space?     I sure hope so, since p is free'ed before this routine returns. */  /* have qualified wild name (i.e., disk:[dir.subdir]*.*); null-terminate   * and set wild-flag */  d->d_qualwildname[d->nam.nam$b_esl] = '\0';  d->d_wild = (d->nam.nam$l_fnb & NAM$M_WILDCARD)? 1 : 0;   /* not used... */#ifdef DEBUG  fprintf(mesg, "  incoming wildname:  %s\n", p);  fprintf(mesg, "  qualified wildname:  %s\n", d->d_qualwildname);#endif /* DEBUG */}local zDIR *zopendir(n)ZCONST char *n;         /* directory to open *//* Start searching for files in the VMS directory n */{  char *c;              /* scans VMS path */  zDIR *d;              /* malloc'd return value */  int m;                /* length of name */  char *p;              /* malloc'd temporary string */  if ((d = (zDIR *)malloc(sizeof(zDIR))) == NULL ||      (p = malloc((m = strlen(n)) + 4)) == NULL) {    if (d != NULL) free((zvoid *)d);    return NULL;  }  /* Directory may be in form "[DIR.SUB1.SUB2]" or "[DIR.SUB1]SUB2.DIR;1".     If latter, convert to former. */  if (m > 0  &&  *(c = strcpy(p,n)+m-1) != ']')  {    while (--c > p  &&  *c != ';')      ;    if ((c- p < 5)  ||  strncasecmp( (c- 4), ".DIR", 4))    {      free((zvoid *)d);  free((zvoid *)p);      return NULL;    }    c -= 3;    *c-- = '\0';        /* terminate at "DIR;#" */    *c = ']';           /* "." --> "]" */    while (c > p  &&  *--c != ']')      ;    *c = '.';           /* "]" --> "." */  }  strcat(p, "*.*");  strcat(p, wild_version_part);  vms_wild(p, d);       /* set up wildcard */  free((zvoid *)p);  return d;}local char *readd(d)zDIR *d;                /* directory stream to read from *//* Return a pointer to the next name in the directory stream d, or NULL if   no more entries or an error occurs. */{  int r;                /* return code */  do {    d->fab.fab$w_ifi = 0;       /* internal file index:  what does this do? */    /* get next match to possible wildcard */    if ((r = sys$search(&d->fab)) == RMS$_NORMAL)    {        d->d_name[d->nam.nam$b_rsl] = '\0';   /* null terminate */        return (char *)d->d_name;   /* OK */    }  } while (r == RMS$_PRV);  return NULL;}int wild(p)char *p;                /* path/pattern to match *//* Expand the pattern based on the contents of the file system.  Return an   error code in the ZE_ class. */{  zDIR *d;              /* stream for reading directory */  char *e;              /* name found in directory */  int f;                /* true if there was a match */  /* special handling of stdin request */  if (strcmp(p, "-") == 0)   /* if compressing stdin */    return newname(p, 0, 0);  /* Search given pattern for matching names */  if ((d = (zDIR *)malloc(sizeof(zDIR))) == NULL)    return ZE_MEM;  vms_wild(p, d);       /* pattern may be more than just directory name */  /*   * Save version specified by user to use in recursive drops into   * subdirectories.   */  strncpy(wild_version_part,d->nam.nam$l_ver,d->nam.nam$b_ver);  wild_version_part[d->nam.nam$b_ver] = '\0';  f = 0;  while ((e = readd(d)) != NULL)        /* "dosmatch" is already built in */    if (procname(e, 0) == ZE_OK)      f = 1;  free(d);  /* Done */  return f ? ZE_OK : ZE_MISS;}int procname(n, caseflag)char *n;                /* name to process */int caseflag;           /* true to force case-sensitive match *//* Process a name or sh expression to operate on (or exclude).  Return   an error code in the ZE_ class. */{  zDIR *d;              /* directory stream from zopendir() */  char *e;              /* pointer to name from readd() */  int m;                /* matched flag */  char *p;              /* path for recursion */  struct stat s;        /* result of stat() */  struct zlist far *z;  /* steps through zfiles list */  if (strcmp(n, "-") == 0)   /* if compressing stdin */    return newname(n, 0, caseflag);  else if (LSSTAT(n, &s)#if defined(__TURBOC__) || defined(VMS) || defined(__WATCOMC__)           /* For these 3 compilers, stat() succeeds on wild card names! */           || isshexp(n)#endif          )  {    /* Not a file or directory--search for shell expression in zip file */    if (caseflag) {      p = malloc(strlen(n) + 1);      if (p != NULL)        strcpy(p, n);    } else      p = ex2in(n, 0, (int *)NULL);     /* shouldn't affect matching chars */    m = 1;    for (z = zfiles; z != NULL; z = z->nxt) {      if (MATCH(p, z->iname, caseflag))      {        z->mark = pcount ? filter(z->zname, caseflag) : 1;        if (verbose)            fprintf(mesg, "zip diagnostic: %scluding %s\n",

⌨️ 快捷键说明

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