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

📄 vmszip.c

📁 给出了 zip 压缩算法的完整实现过程。
💻 C
📖 第 1 页 / 共 2 页
字号:
               z->mark ? "in" : "ex", z->name);        m = 0;      }    }    free((zvoid *)p);    return m ? ZE_MISS : ZE_OK;  }  /* Live name--use if file, recurse if directory */  if ((s.st_mode & S_IFDIR) == 0)  {    /* add or remove name of file */    if ((m = newname(n, 0, caseflag)) != ZE_OK)      return m;  } else {    if (dirnames && (m = newname(n, 1, caseflag)) != ZE_OK) {      return m;    }    /* recurse into directory */    if (recurse && (d = zopendir(n)) != NULL)    {      while ((e = readd(d)) != NULL) {        if ((m = procname(e, caseflag)) != ZE_OK)     /* recurse on name */        {          free(d);          return m;        }      }      free(d);    }  } /* (s.st_mode & S_IFDIR) == 0) */  return ZE_OK;}/* 2004-09-24 SMS.   Cuter strlower() and strupper() functions.*/local char *strlower( s)char *s;/* Convert all uppercase letters to lowercase in string s */{  for ( ; *s != '\0'; s++)    if (isupper( *s))      *s = tolower( *s);  return s;}local char *strupper( s)char *s;/* Convert all lowercase letters to uppercase in string s */{  for ( ; *s != '\0'; s++)    if (islower( *s))      *s = toupper( *s);  return s;}char *ex2in(x, isdir, pdosflag)char *x;                /* external file name */int isdir;              /* input: x is a directory */int *pdosflag;          /* output: force MSDOS file attributes? *//* Convert the external file name to a zip file name, returning the malloc'ed   string or NULL if not enough memory. */{  char *n;              /* internal file name (malloc'ed) */  char *t;              /* shortened name */  int dosflag;  dosflag = dosify; /* default for non-DOS and non-OS/2 */  /* Find starting point in name before doing malloc */  t = x;  if ((n = strrchr(t, ':')) != NULL)    t = n + 1;  if ( (*t == PATH_START && (n = strrchr(t, PATH_END)) != NULL)      || (*t == PATH_START2 && (n = strrchr(t, PATH_END2)) != NULL) )    /* external name contains valid VMS path specification */    if (*(++t) == '.')      /* path is relative to current directory, skip leading '.' */      t++;  if (!pathput)    t = last(last(t, PATH_END), PATH_END2);  /* Malloc space for internal name and copy it */  if ((n = malloc(strlen(t) + 1)) == NULL)    return NULL;  strcpy(n, t);  if (((t = strrchr(n, PATH_END)) != NULL) ||       (t = strrchr(n, PATH_END2)) != NULL)  {    *t = '/';    while (--t > n)      if (*t == '.')        *t = '/';  }  /* Fix from Greg Roelofs: */  /* Get current working directory and strip from n (t now = n) */  {    char cwd[256], *p, *q;    int c;    q = getcwd( cwd, 256);    /* 2004-09-24 SMS.       With SET PROCESSS /PARSE = EXTENDED, getcwd() can return a       mixed-case result, confounding the comparisons below with an       all-uppercase name in "n".  Always use a case-insensitive       comparison around here.    */#if 0 /* fix by Igor */    if ((q != NULL) && ((p = strchr(cwd, '.')) != NULL))#else    if ((q != NULL) && ((p = strchr(cwd, PATH_START)) != NULL ||                        (p = strchr(cwd, PATH_START2)) != NULL))#endif    {      if (*(++p) == '.')        p++;      if ((q = strrchr(p, PATH_END)) != NULL ||          (q = strrchr(p, PATH_END2)) != NULL)      {        *q = '/';        while (--q > p)          if (*q == '.')            *q = '/';        /* strip bogus path parts from n */        if (strncasecmp( n, p, (c = strlen( p))) == 0)        {          q = n + c;          while (*t++ = *q++)            ;        }      }    }  }#ifndef VMS_PRESERVE_CASE  strlower( n);#endif /* ndef VMS_PRESERVE_CASE */  /* Remove simple ODS5 extended file name escape characters. */  eat_carets( n);  if (isdir)  {    if (strcasecmp( (t = n + strlen( n) - 6), ".DIR;1"))      error("directory not version 1");    else      if (pathput)        strcpy(t, "/");      else        *n = '\0';              /* directories are discarded with zip -rj */  }  else if (!vmsver)    if ((t = strrchr(n, ';')) != NULL)      *t = '\0';  if ((t = strrchr(n, '.')) != NULL)  {    if ( t[1] == '\0')          /* "filename." -> "filename" */      *t = '\0';    else if (t[1] == ';')       /* "filename.;vvv" -> "filename;vvv" */    {      char *f = t+1;      while (*t++ = *f++) ;    }  }  if (dosify)    msname(n);  /* Returned malloc'ed name */  if (pdosflag)    *pdosflag = dosflag;  return n;}char *in2ex(n)char *n;                /* internal file name *//* Convert the zip file name to an external file name, returning the malloc'ed   string or NULL if not enough memory. */{  char *x;              /* external file name */  char *t;              /* scans name */  if ((t = strrchr(n, '/')) == NULL)  {    if ((x = malloc(strlen(n) + 1 + PAD)) == NULL)      return NULL;    strcpy(x, n);  }  else  {    if ((x = malloc(strlen(n) + 3 + PAD)) == NULL)      return NULL;    x[0] = PATH_START;    x[1] = '.';    strcpy(x + 2, n);    *(t = x + 2 + (t - n)) = PATH_END;    while (--t > x)      if (*t == '/')        *t = '.';  }#ifndef VMS_PRESERVE_CASE  strupper( x);#endif /* ndef VMS_PRESERVE_CASE */  return x;}void stamp(f, d)char *f;                /* name of file to change */ulg d;                  /* dos-style time to change it to *//* Set last updated and accessed time of file f to the DOS time d. */{  int tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year;  char timbuf[24];  static ZCONST char *month[] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN",                                 "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};  struct VMStimbuf {      char *actime;           /* VMS revision date, ASCII format */      char *modtime;          /* VMS creation date, ASCII format */  } ascii_times;  ascii_times.actime = ascii_times.modtime = timbuf;  /* Convert DOS time to ASCII format for VMSmunch */  tm_sec = (int)(d << 1) & 0x3e;  tm_min = (int)(d >> 5) & 0x3f;  tm_hour = (int)(d >> 11) & 0x1f;  tm_mday = (int)(d >> 16) & 0x1f;  tm_mon = ((int)(d >> 21) & 0xf) - 1;  tm_year = ((int)(d >> 25) & 0x7f) + 1980;  sprintf(timbuf, "%02d-%3s-%04d %02d:%02d:%02d.00", tm_mday, month[tm_mon],    tm_year, tm_hour, tm_min, tm_sec);  /* Set updated and accessed times of f */  if (VMSmunch(f, SET_TIMES, (char *)&ascii_times) != RMS$_NMF)    zipwarn("can't set zipfile time: ", f);}ulg filetime(f, a, n, t)char *f;                /* name of file to get info on */ulg *a;                 /* return value: file attributes */long *n;                /* return value: file size */iztimes *t;             /* return value: access, modific. and creation times *//* If file *f does not exist, return 0.  Else, return the file's last   modified date and time as an MSDOS date and time.  The date and   time is returned in a long with the date most significant to allow   unsigned integer comparison of absolute times.  Also, if a is not   a NULL pointer, store the file attributes there, with the high two   bytes being the Unix attributes, and the low byte being a mapping   of that to DOS attributes.  If n is not NULL, store the file size   there.  If t is not NULL, the file's access, modification and creation   times are stored there as UNIX time_t values.   If f is "-", use standard input as the file. If f is a device, return   a file size of -1 */{  struct stat s;        /* results of stat() */  /* malloc name so not dependent on FNMAX - 11/8/04 EG */  char *name;  int len = strlen(f);  if (f == label) {    if (a != NULL)      *a = label_mode;    if (n != NULL)      *n = -2; /* convention for a label name */    if (t != NULL)      t->atime = t->mtime = t->ctime = label_utim;    return label_time;  }  if ((name = malloc(len + 1)) == NULL) {    ZIPERR(ZE_MEM, "filetime");  }  strcpy(name, f);  if (name[len - 1] == '/')    name[len - 1] = '\0';  /* not all systems allow stat'ing a file with / appended */  if (strcmp(f, "-") == 0) {    if (fstat(fileno(stdin), &s) != 0) {      free(name);      error("fstat(stdin)");    }  } else if (LSSTAT(name, &s) != 0) {             /* Accept about any file kind including directories              * (stored with trailing / with -r option)              */    free(name);    return 0;  }  free(name);  if (a != NULL) {    *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE);    if ((s.st_mode & S_IFDIR) != 0) {      *a |= MSDOS_DIR_ATTR;    }  }  if (n != NULL)    *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1;  if (t != NULL) {    t->atime = s.st_mtime;#ifdef USE_MTIME    t->mtime = s.st_mtime;            /* Use modification time in VMS */#else    t->mtime = s.st_ctime;            /* Use creation time in VMS */#endif    t->ctime = s.st_ctime;  }#ifdef USE_MTIME  return unix2dostime((time_t *)&s.st_mtime); /* Use modification time in VMS */#else  return unix2dostime((time_t *)&s.st_ctime); /* Use creation time in VMS */#endif}int deletedir(d)char *d;                /* directory to delete *//* Delete the directory *d if it is empty, do nothing otherwise.   Return the result of rmdir(), delete(), or system().   For VMS, d must be in format [x.y]z.dir;1  (not [x.y.z]). */{    /* code from Greg Roelofs, who horked it from Mark Edwards (unzip) */    int r, len;    char *s;              /* malloc'd string for system command */    len = strlen(d);    if ((s = malloc(len + 34)) == NULL)      return 127;    system(strcat(strcpy(s, "set prot=(o:rwed) "), d));    r = delete(d);    free(s);    return r;}#endif /* !UTIL */

⌨️ 快捷键说明

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