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

📄 tanzip.c

📁 给出了 zip 压缩算法的完整实现过程。
💻 C
📖 第 1 页 / 共 2 页
字号:
  }  local char *readd(d)    DIR *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. */  {    struct dirent *e;    e = readdir(d);    return e == NULL ? (char *) NULL : e->d_name;  }  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. */  {    char *a;              /* path and name for recursion */    DIR *d;               /* directory stream from opendir() */    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 (stat(n, &s))    {      /* Not a file or directory--search for shell expression in zip file */      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->zname, caseflag))        {          z->mark = pcount ? filter(z->zname, caseflag) : 1;          if (verbose)              fprintf(mesg, "zip diagnostic: %scluding %s\n",                 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 ((p = malloc(strlen(n)+4)) == NULL)        return ZE_MEM;      strcpy(p, n);      /* No concept of directories on Tandem - so do not store them ...*/      /* code removed from which attempted to save dir name if dirnames set */      /*  Test for recurse being set removed, since Tandem has no dir concept*/      /*  recurse into template */      if ((d = opendir(n)) != NULL)      {        while ((e = readd(d)) != NULL) {          if ((m = procname(e, caseflag)) != ZE_OK)   /* recurse on name */          {            if (m == ZE_MISS)              zipwarn("name not matched: ", e);            else              ziperr(m, e);          }        }        closedir(d);      }      free((zvoid *)p);    } /* (s.st_mode & S_IFDIR) == 0) */    return ZE_OK;  }  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;    char *p;               /* pointer to temp area */    char fname[FILENAME_MAX + 1]= ""; /* file name */    char ext[EXTENSION_MAX + 1] = ""; /* extension name */    short extension;    /* does the filename contain an extension */    dosflag = dosify;  /* default for non-DOS non-OS/2 */    /* Find starting point in name before doing malloc */    if (*x == '=')      t = x + 1;   /* store DEFINE names without the '=' */    else      t = x;    /* Make changes, if any, to the copied name (leave original intact) */    if (!pathput)      t = last(t, TANDEM_DELIMITER);    /* Malloc space for internal name and copy it */    if ((n = malloc(strlen(t) + 4)) == NULL) /* + 4 for safety */      return NULL;    extension = parsename(t,fname,ext);    t = fname;    *n= '\0';    while (*t != '\0') {  /* File part could be sys,vol,subvol or file */      if (*t == TANDEM_NODE) {    /* System Name */        strcat(n, INTERNAL_NODE_STR);        t++;      }      else if (*t == TANDEM_DELIMITER) {  /* Volume or Subvol */             strcat(n, INTERNAL_DELIMITER_STR);             t++;           };      p = strchr(t,TANDEM_DELIMITER);      if (p == NULL) break;      strncat(n,t,(p - t));      t = p;    }    strcat(n,t);  /* mop up any left over characters */    if (extension) {      strcat(n,DOS_EXTENSION_STR);      strcat(n,ext);    };    if (isdir == 42) return n;      /* avoid warning on unused variable */    if (dosify)      msname(n);    /* Returned malloc'ed name */    if (pdosflag)      *pdosflag = dosflag;    return n;  }  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. */  {    ztimbuf u;            /* argument for utime() */    /* Convert DOS time to time_t format in u.actime and u.modtime */    u.actime = u.modtime = dos2unixtime(d);    utime(f, &u);  }  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 and modification time */  {    struct stat s;    nsk_stat_ov *nsk_ov;    if (strcmp(f, "-") == 0) {    /* if compressing stdin */      if (n != NULL) {        *n = -1L;      }    }    if (stat(f, &s) != 0) return 0;    if (a!= NULL) {      *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWUSR);      if ((s.st_mode & S_IFMT) == S_IFDIR) {        *a |= MSDOS_DIR_ATTR;      }    }    if (n!= NULL)      *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L;    if (t != NULL) {      t->atime = s.st_atime;      t->mtime = s.st_mtime;      nsk_ov = (nsk_stat_ov *)&s.st_reserved[0];      t->ctime = nsk_ov->ov.creation_time;    }    return unix2dostime(&s.st_mtime);  }  int set_extra_field(z, z_utim)    struct zlist far *z;    iztimes *z_utim;    /* create extra field and change z->att if desired */    /* store full data in local header but just modification time stamp info       in central header */  {    struct stat s;    nsk_stat_ov *nsk_ov = (nsk_stat_ov *)&s.st_reserved[0];    nsk_file_attrs *nsk_attr = (nsk_file_attrs *)&nsk_ov->ov.nsk_ef_start;    char *ext, *cext;    int lsize, csize;#ifdef USE_EF_UT_TIME    char *UTptr, *Uxptr;#endif /* USE_EF_UT_TIME */    /* For the Tandem and UT local field including the UID/GID fields, we       have to stat the file again. */    if (LSSTAT(z->name, &s))      return ZE_OPEN;    z->ext = z->cext = 0;  #define EB_TANDEM_SIZE 20  #define EF_TANDEM_SIZE (EB_HEADSIZE + EB_TANDEM_SIZE)    /* allocate size of buffers to allow Tandem field */    lsize = EF_TANDEM_SIZE;    csize = EF_TANDEM_SIZE;#ifdef USE_EF_UT_TIME  #define EB_L_UT_SIZE    (EB_HEADSIZE + EB_UT_LEN(3))  #define EB_C_UT_SIZE    (EB_HEADSIZE + EB_UT_LEN(1))  #define EB_L_UX2_SIZE   (EB_HEADSIZE + EB_UX2_MINLEN)  #define EB_C_UX2_SIZE   EB_HEADSIZE  #define EF_L_UNIX_SIZE  (EB_L_UT_SIZE + EB_L_UX2_SIZE)  #define EF_C_UNIX_SIZE  (EB_C_UT_SIZE + EB_C_UX2_SIZE)    /* resize to allow for UT fields */    lsize += EF_L_UNIX_SIZE;    csize += EF_C_UNIX_SIZE;#endif /* USE_EF_UT_TIME */    if ((z->extra = (char *)malloc(lsize)) == NULL)      return ZE_MEM;    ext = z->extra;    if ((z->cextra = (char *)malloc(csize)) == NULL)      return ZE_MEM;    cext = z->cextra;    /* Place Tandem field first so its on an even boundary */    *ext++ = *cext++ = 'T';    *ext++ = *cext++ = 'A';    *ext++ = *cext++ = (char)EB_TANDEM_SIZE;  /*length of data part of e.f.*/    *ext++ = *cext++  = 0;    /* Copy Tandem specific file information */    memcpy(ext, (char *)nsk_attr, EB_TANDEM_SIZE);    ext += EB_TANDEM_SIZE;    z->ext += EF_TANDEM_SIZE;    /* Copy same data to central field */    memcpy(cext, (char *)nsk_attr, EB_TANDEM_SIZE);    cext += EB_TANDEM_SIZE;    z->cext += EF_TANDEM_SIZE;#ifdef USE_EF_UT_TIME    UTptr = ext;    *ext++  = 'U';    *ext++  = 'T';    *ext++  = (char)EB_UT_LEN(3);    /* length of data part of local e.f. */    *ext++  = 0;    *ext++  = EB_UT_FL_MTIME | EB_UT_FL_ATIME | EB_UT_FL_CTIME;    *ext++  = (char)(s.st_mtime);    *ext++  = (char)(s.st_mtime >> 8);    *ext++  = (char)(s.st_mtime >> 16);    *ext++  = (char)(s.st_mtime >> 24);    *ext++  = (char)(s.st_atime);    *ext++ = (char)(s.st_atime >> 8);    *ext++ = (char)(s.st_atime >> 16);    *ext++ = (char)(s.st_atime >> 24);    *ext++ = (char)(nsk_ov->ov.creation_time);    *ext++ = (char)(nsk_ov->ov.creation_time >> 8);    *ext++ = (char)(nsk_ov->ov.creation_time >> 16);    *ext++ = (char)(nsk_ov->ov.creation_time >> 24);    Uxptr = ext;    *ext++ = 'U';    *ext++ = 'x';    *ext++ = (char)EB_UX2_MINLEN;   /* length of data part of local e.f. */    *ext++ = 0;    *ext++ = (char)(s.st_uid);    *ext++ = (char)(s.st_uid >> 8);    *ext++ = (char)(s.st_gid);    *ext++ = (char)(s.st_gid >> 8);    z->ext += EF_L_UNIX_SIZE;    memcpy(cext, UTptr, EB_C_UT_SIZE);    cext[EB_LEN] = (char)EB_UT_LEN(1);    memcpy(cext+EB_C_UT_SIZE, Uxptr, EB_C_UX2_SIZE);    cext[EB_LEN+EB_C_UT_SIZE] = 0;    z->cext += EF_C_UNIX_SIZE;    cext += EF_C_UNIX_SIZE;#endif /* USE_EF_UT_TIME */    return ZE_OK;  }

⌨️ 快捷键说明

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