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

📄 aosvs.c

📁 给出了 zip 压缩算法的完整实现过程。
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 : -1L;  if (t != NULL) {    t->atime = s.st_atime;    t->mtime = s.st_mtime;    t->ctime = s.st_ctime;  }  free(name);  return unix2dostime(&s.st_ctime);}int deletedir(d)char *d;{   return rmdir(d);}int set_extra_field(z, z_utim)  struct zlist far *z;  iztimes *z_utim;  /* create extra field and change z->att if desired */  /* NOTE: this AOS/VS version assumes the pathname in z->name is an   * AOS/VS pathname, not a unix-style one.  Since you can zip up using   * unix-style pathnames, this may create problems occasionally.   * We COULD add code to parse back to AOS/VS format ...   * (This might also fail for other reasons such as access denied, but   * that should already have occurred.)   * We set the central-dir extra fld pointer & length here to the same data.   */{  int             aclend = 0;/* * use this to simplify because different calls depending on * whether links are resolved */  unsigned short  errc;  z->ext = 0;               /* init to no extra field *//* get the ?FSTAT info & the acl - if no errors, get memory & store. * (first, we have to cut off the trailing slash that was added if * it's a dir, since AOS/VS doesn't accept that kind of thing) */  strncpy(znamebuf, z->name, $MXPL);  znamebuf[$MXPL-1] = '\0';  if (znamebuf[strlen(znamebuf)-1] == '/')    znamebuf[strlen(znamebuf)-1] = '\0';  if (linkput)    errc = sys_fstat(znamebuf, BIT1, &(zzextrafld.fstat_packet));  else    errc = sys_fstat(znamebuf, 0, &(zzextrafld.fstat_packet));  if (errc)  {    fprintf(stderr,            "\n    Warning: can't get ?FSTAT info & acl of %s - error %d\n    ",            znamebuf, errc);    perror("sys_fstat()");  }  else  {    /* store the ACL - or, if a link (no ACL!), store the resolution name */    if (zzextrafld.fstat_packet.norm_fstat_packet.styp_type != $FLNK)    {      if ((errc = sys_gacl(znamebuf, zzextrafld.aclbuf)) != 0)      {        fprintf(stderr, "\n    Warning: can't get acl of %s - error %d\n    ",                z->name, errc);        perror("sys_gacl()");      }      else      {        /* find length of ACL - ends with double-null */        while (aclend++ < $MXACL  &&               (zzextrafld.aclbuf[aclend - 1] != '\0'  ||                zzextrafld.aclbuf[aclend] != '\0'))          /* EMPTY LOOP */ ;        if ((z->cextra = z->extra =             malloc(sizeof(ZEXTRAFLD) - $MXACL + aclend + 4)) != NULL)        {          strncpy(zzextrafld.extra_header_id, ZEXTRA_HEADID,                  sizeof(zzextrafld.extra_header_id));          strncpy(zzextrafld.extra_sentinel, ZEXTRA_SENTINEL,                  sizeof(zzextrafld.extra_sentinel));          zzextrafld.extra_rev = ZEXTRA_REV;    /* this is a char, no need                                                   to worry about byte order */          /* set size (Intel (little-endian)) 2-byte int, which we've set             as array to make it easier */          errc = (unsigned short) (sizeof(ZEXTRAFLD) - $MXACL + aclend + 4 -                                   sizeof(zzextrafld.extra_header_id) -                                   sizeof(zzextrafld.extra_data_size));          zzextrafld.extra_data_size[0] = errc & 0xFF;  /* low-order byte */          zzextrafld.extra_data_size[1] = errc >> 8;    /* high-order byte */          memcpy((char *) z->extra, (char *) &zzextrafld,                 sizeof(ZEXTRAFLD) - $MXACL + aclend + 4);          z->cext = z->ext = sizeof(ZEXTRAFLD) - $MXACL + aclend + 4;        }      }    }    else /* a link */    {      if ((errc = sys_glink(z->name, zzextrafld.aclbuf)) != 0)      {        fprintf(stderr,              "\n    Warning: can't get link-resolution of %s - error %d\n    ",                z->name, errc);        perror("sys_glink()");      }      else      {        aclend = strlen(zzextrafld.aclbuf) + 1;        if ((z->extra = malloc(sizeof(ZEXTRAFLD) - $MXACL + aclend + 4))            != NULL)        {          strncpy(zzextrafld.extra_header_id, ZEXTRA_HEADID,                  sizeof(zzextrafld.extra_header_id));          strncpy(zzextrafld.extra_sentinel, ZEXTRA_SENTINEL,                  sizeof(zzextrafld.extra_sentinel));          zzextrafld.extra_rev = ZEXTRA_REV;    /* this is a char, no need                                                   to worry about byte order */          /* set size (Intel (little-endian)) 2-byte int, which we've set             as array to make it easier */          errc = (unsigned short) (sizeof(ZEXTRAFLD) - $MXACL + aclend + 4 -                                   sizeof(zzextrafld.extra_header_id) -                                   sizeof(zzextrafld.extra_data_size));          zzextrafld.extra_data_size[0] = errc & 0xFF;  /* low-order byte */          zzextrafld.extra_data_size[1] = errc >> 8;    /* high-order byte */          memcpy((char *) z->extra, (char *) &zzextrafld,                 sizeof(ZEXTRAFLD) - $MXACL + aclend + 4);          z->ext = sizeof(ZEXTRAFLD) - $MXACL + aclend + 4;        }      }    }  }  return ZE_OK;}#endif /* !UTIL */void version_local(){    printf("Compiled with %s under %s.\n",      "a C compiler",      "AOS/VS"    );}/* * This file defines for AOS/VS two Unix functions relating to links; * the calling code should have the following defines: * *    #define       lstat(path,buf)             zvs_lstat(path,buf) *    #define       readlink(path,buf,nbytes)   zvs_readlink(path,buf,nbytes) * * For these functions, I'm going to define yet 2 MORE filename buffers * and also insert code to change pathnames to Unix & back.  This is * easier than changing all the other places this kind of thing happens to * be efficient.  This is a kludge.  I'm also going to put the functions * here for my immediate convenience rather than somewhere else for * someone else's. * * WARNING: the use of static buffers means that you'd better get your * data out of these buffers before the next call to any of these functions! * *//* ========================================================================= * ZVS_LSTAT() - get (or simulate) stat information WITHOUT following symlinks *      This is intended to look to the outside like the unix lstat() *      function.  We do a quick-&-dirty filename conversion. * *      If the file is NOT a symbolic link, we can just do a stat() on it and *      that should be fine.  But if it IS a link, we have to set the elements *      of the stat struct ourselves, since AOS/VS doesn't have a built-in *      lstat() function. * *      RETURNS: 0 on success, or -1 otherwise * */int zvs_lstat(char *path, struct stat *buf){    char        *cp_vs = vsnamebuf;    char        *cp_ux = path;    int         mm, dd, yy;    /*     * Convert the Unix pathname to an AOS/VS pathname.     * This is quick & dirty; it won't handle (for instance) pathnames with     * ../ in the middle of them, and may choke on other Unixisms.  We hope     * they're unlikely.     */    if (!strncmp(cp_ux, "../", 3))    {        *cp_vs++ = '^';        /* AOS/VS for ../ */        cp_ux += 3;    }    else if (!strncmp(cp_ux, "./", 2))    {        *cp_vs++ = '=';        /* AOS/VS for ./ */        cp_ux += 2;    }    do    {        if (*cp_ux == '/')        {            *cp_vs++ = ':';        }        else        {            *cp_vs++ = (char) toupper(*cp_ux);        }    } while (*cp_ux++ != '\0'  &&  cp_vs - vsnamebuf < sizeof(vsnamebuf));    /* If Unix name was too long for our buffer, return an error return */    if (cp_vs - vsnamebuf >= sizeof(vsnamebuf)  &&  *(cp_vs - 1) != '\0')        return (-1);     /* error */    /* Make AOS/VS ?FSTAT call that won't follow links & see if we find     * anything.  If not, we return error.     */    if (sys_fstat(vsnamebuf,                  BIT1,                 /* BIT1 says to not resolve links */                  &vsfstatbuf))        return (-1);     /* error */    /* If we DID find the file but it's not a link,     * call stat() and return its value.     */    if (vsfstatbuf.styp_type != $FLNK)        return (stat(path, buf));        /* call with Unix pathname ... */    /* Otherwise, we have to kludge up values for the stat structure */    memset((char *) buf, 0, sizeof(*buf));   /* init to nulls (0 values) */    buf->st_mode = S_IFLNK | 0777;           /* link and rwxrwxrwx */    buf->st_uid = -1;                        /* this is what we get on AOS/VS                                                anyway (maybe unless we set up                                                a dummy password file?) */    buf->st_nlink = 1;    /* The DG date we've got is days since 12/31/67 and seconds/2.  So we     * need to subtract 732 days (if that's not negative), convert to seconds,     * and add adjusted seconds.     */    if (vsfstatbuf.stch.short_time[0] < 732)        buf->st_ctime = buf->st_mtime = buf->st_atime = 0L;    else    {        buf->st_ctime = buf->st_mtime = buf->st_atime =                ((long) vsfstatbuf.stch.short_time[0] - 732L) * 24L * 3600L +                2L * (long) vsfstatbuf.stch.short_time[1];    }    /* And we need to get the filename linked to and use its length as     * the file size.  We'll use the Unix pathname buffer for this - hope     * it's big enough.  (We won't overwrite anything, but we could get a     * truncated path.)  If there's an error, here's our last chance to     * say anything.     */    if ((buf->st_size = zvs_readlink(vsnamebuf, uxnamebuf, FNMAX)) < 0)        return (-1);    else        return (0);} /* end zvs_lstat() *//* ========================================================================= * ZVS_READLINK() - get pathname pointed to by an AOS/VS link file *      This is intended to look to the outside like the unix readlink() *      function.  We do a quick-&-dirty filename conversion. * *      RETURNS: the length of the output path (in bytes), or -1 if an error * */int zvs_readlink(char *path, char *buf, int nbytes){    char    *cp_vs = vsnamebuf;    char    *cp_ux = buf;    /* This is called with z->name, the filename the user gave, so we'll get     * the link-resolution name on the assumption that it's a valid AOS/VS     * name. We're also assuming a reasonable value (> 5) for nbytes.     */    if (sys_glink(path, vsnamebuf))        return (-1);     /* readlink() is supposed to return -1 on error */    /* Now, convert the AOS/VS pathname to a Unix pathname.     * Note that sys_glink(), unlike readlink(), does add a null.     */    if (*cp_vs == '^')        /* AOS/VS for ../ */    {        strncpy(cp_ux, "../", 3);        cp_ux += 3;        cp_vs++;    }    else if (*cp_vs == '@')   /* AOS/VS for :PER:, kind of like /dev/ */    {        strncpy(cp_ux, "/PER/", 5);        cp_ux += 5;        cp_vs++;    }    else if (*cp_vs == '=')   /* AOS/VS for ./ */    {        strncpy(cp_ux, "./", 2);        cp_ux += 2;        cp_vs++;    }    while (*cp_vs != '\0'  &&  cp_ux - buf < nbytes)    {        if (*cp_vs == ':')        {            *cp_ux++ = '/';        }        else        {            *cp_ux++ = (char) toupper(*cp_vs);        }        cp_vs++;    }    return (cp_ux - buf);   /* # characters in Unix path (no trailing null) */} /* end zvs_readlink() */

⌨️ 快捷键说明

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