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

📄 tanunz.c

📁 zip压缩
💻 C
📖 第 1 页 / 共 3 页
字号:
    ulg tmp = G.crec.external_file_attributes;    switch (G.pInfo->hostnum) {        case AMIGA_:            tmp = (unsigned)(tmp>>17 & 7);   /* Amiga RWE bits */            G.pInfo->file_attr = (unsigned)(tmp<<6 | tmp<<3 | tmp);            break;        case THEOS_:            tmp &= 0xF1FFFFFFL;            if ((tmp & 0xF0000000L) != 0x40000000L)                tmp &= 0x01FFFFFFL;     /* not a dir, mask all ftype bits */            else                tmp &= 0x41FFFFFFL;     /* leave directory bit as set */            /* fall through! */        case TANDEM_:        case UNIX_:        case VMS_:        case ACORN_:        case ATARI_:        case BEOS_:        case QDOS_:            G.pInfo->file_attr = (unsigned)(tmp >> 16);            if (G.pInfo->file_attr != 0 || !G.extra_field) {                return 0;            } else {                /* Some (non-Info-ZIP) implementations of Zip for Unix and                   VMS (and probably others ??) leave 0 in the upper 16-bit                   part of the external_file_attributes field. Instead, they                   store file permission attributes in some extra field.                   As a work-around, we search for the presence of one of                   these extra fields and fall back to the MSDOS compatible                   part of external_file_attributes if one of the known                   e.f. types has been detected.                   Later, we might implement extraction of the permission                   bits from the VMS extra field. But for now, the work-around                   should be sufficient to provide "readable" extracted files.                   (For ASI Unix e.f., an experimental remap of the e.f.                   mode value IS already provided!)                 */                ush ebID;                unsigned ebLen;                uch *ef = G.extra_field;                unsigned ef_len = G.crec.extra_field_length;                int r = FALSE;                while (!r && ef_len >= EB_HEADSIZE) {                    ebID = makeword(ef);                    ebLen = (unsigned)makeword(ef+EB_LEN);                    if (ebLen > (ef_len - EB_HEADSIZE))                        /* discoverd some e.f. inconsistency! */                        break;                    switch (ebID) {                      case EF_ASIUNIX:                        if (ebLen >= (EB_ASI_MODE+2)) {                            G.pInfo->file_attr =                              (unsigned)makeword(ef+(EB_HEADSIZE+EB_ASI_MODE));                            /* force stop of loop: */                            ef_len = (ebLen + EB_HEADSIZE);                            break;                        }                        /* else: fall through! */                      case EF_PKVMS:                        /* "found nondecypherable e.f. with perm. attr" */                        r = TRUE;                      default:                        break;                    }                    ef_len -= (ebLen + EB_HEADSIZE);                    ef += (ebLen + EB_HEADSIZE);                }                if (!r)                    return 0;            }            /* fall through! */        /* all remaining cases:  expand MSDOS read-only bit into write perms */        case FS_FAT_:            /* PKWARE's PKZip for Unix marks entries as FS_FAT_, but stores the             * Unix attributes in the upper 16 bits of the external attributes             * field, just like Info-ZIP's Zip for Unix.  We try to use that             * value, after a check for consistency with the MSDOS attribute             * bits (see below).             */            G.pInfo->file_attr = (unsigned)(tmp >> 16);            /* fall through! */        case FS_HPFS_:        case FS_NTFS_:        case MAC_:        case TOPS20_:        default:            /* Ensure that DOS subdir bit is set when the entry's name ends             * in a '/'.  Some third-party Zip programs fail to set the subdir             * bit for directory entries.             */            if ((tmp & 0x10) == 0) {                extent fnlen = strlen(G.filename);                if (fnlen > 0 && G.filename[fnlen-1] == '/')                    tmp |= 0x10;            }            /* read-only bit --> write perms; subdir bit --> dir exec bit */            tmp = !(tmp & 1) << 1  |  (tmp & 0x10) >> 4;            if ((G.pInfo->file_attr & 0700) == (unsigned)(0400 | tmp<<6))                /* keep previous G.pInfo->file_attr setting, when its "owner"                 * part appears to be consistent with DOS attribute flags!                 */                return 0;            G.pInfo->file_attr = (unsigned)(0444 | tmp<<6 | tmp<<3 | tmp);            break;    } /* end switch (host-OS-created-by) */    /* for originating systems without concept of "group," "other," "system" */    umask( (int)(tmp=umask(0)) );    /* apply mask to expanded r/w(/x) perms */    G.pInfo->file_attr &= ~tmp;    return 0;} /* end function mapattr() *//************************//*  Function mapname()  *//************************/int mapname(__G__ renamed)    __GDEF    int renamed;/* * returns: *  MPN_OK          - no problem detected *  MPN_INF_TRUNC   - caution (truncated filename) *  MPN_INF_SKIP    - info "skip entry" (dir doesn't exist) *  MPN_ERR_SKIP    - error -> skip entry *  MPN_ERR_TOOLONG - error -> path is too long *  MPN_NOMEM       - error (memory allocation failed) -> skip entry *  [also MPN_VOL_LABEL, MPN_CREATED_DIR] */{    char pathcomp[FILNAMSIZ];      /* path-component buffer */    char *pp, *cp;                 /* character pointers */    char *lastsemi=(char *)NULL;   /* pointer to last semi-colon in pathcomp */    int quote = FALSE;             /* flags */    int error = MPN_OK;    register unsigned workch;      /* hold the character being tested *//*---------------------------------------------------------------------------    Initialize various pointers and counters and stuff.  ---------------------------------------------------------------------------*/    if (G.pInfo->vollabel)        return MPN_VOL_LABEL;   /* can't set disk volume labels on Tandem */    /* can create path as long as not just freshening, or if user told us */    G.create_dirs = (!uO.fflag || renamed);    created_dir = FALSE;        /* not yet */    /* user gave full pathname:  don't prepend rootpath */    renamed_fullpath = (renamed && (*G.filename == '/'));    if (checkdir(__G__ (char *)NULL, INIT) == MPN_NOMEM)        return MPN_NOMEM;       /* initialize path buffer, unless no memory */    /* TANDEM - call in2ex */    pp = in2ex(__G__ G.filename);    if (pp == (char *)NULL)        return MPN_NOMEM;    strcpy(G.filename, pp);    free(pp);    *pathcomp = '\0';           /* initialize translation buffer */    pp = pathcomp;              /* point to translation buffer */    /* directories have already been junked in in2ex() */    cp = G.filename;            /* point to internal zipfile-member pathname *//*---------------------------------------------------------------------------    Begin main loop through characters in filename.  ---------------------------------------------------------------------------*/    while ((workch = (uch)*cp++) != 0) {        if (quote) {                 /* if character quoted, */            *pp++ = (char)workch;    /*  include it literally */            quote = FALSE;        } else            switch (workch) { /* includes space char, let checkdir handle it */            case TANDEM_DELIMITER: /* can assume -j flag not given */                *pp = '\0';                if (((error = checkdir(__G__ pathcomp, APPEND_DIR)) & MPN_MASK)                     > MPN_INF_TRUNC)                    return error;                pp = pathcomp;    /* reset conversion buffer for next piece */                lastsemi = (char *)NULL; /* leave directory semi-colons alone */                break;            case ';':             /* VMS version (or DEC-20 attrib?) */                lastsemi = pp;                *pp++ = ';';      /* keep for now; remove VMS ";##" */                break;            /*  later, if requested */            case '\026':          /* control-V quote for special chars */                quote = TRUE;     /* set flag for next character */                break;            default:                /* allow European characters in filenames: */                if (isprint(workch) || (128 <= workch && workch <= 254))                    *pp++ = (char)workch;            } /* end switch */    } /* end while loop *//*---------------------------------------------------------------------------    Report if directory was created (and no file to create:  filename ended    in '/'), check name to be sure it exists, and combine path and name be-    fore exiting.  ---------------------------------------------------------------------------*/    if (G.filename[strlen(G.filename) - 1] == TANDEM_DELIMITER) {        checkdir(__G__ G.filename, GETPATH);        if (created_dir) {            if (QCOND2) {                Info(slide, 0, ((char *)slide, "   creating: %s\n",                  FnFilter1(G.filename)));            }            /* set dir time (note trailing '/') */            return (error & ~MPN_MASK) | MPN_CREATED_DIR;        }        /* dir existed already; don't look for data to extract */        return (error & ~MPN_MASK) | MPN_INF_SKIP;    }    *pp = '\0';                   /* done with pathcomp:  terminate it */    /* if not saving them, remove VMS version numbers (appended ";###") */    if (!uO.V_flag && lastsemi) {        pp = lastsemi + 1;        while (isdigit((uch)(*pp)))            ++pp;        if (*pp == '\0')          /* only digits between ';' and end:  nuke */            *lastsemi = '\0';    }    if (*pathcomp == '\0') {        Info(slide, 1, ((char *)slide, "mapname:  conversion of %s failed\n",          FnFilter1(G.filename)));        return (error & ~MPN_MASK) | MPN_ERR_SKIP;    }    checkdir(__G__ pathcomp, APPEND_NAME);  /* returns 1 if truncated: care? */    checkdir(__G__ G.filename, GETPATH);    return error;} /* end function mapname() *//***********************//* Function checkdir() *//***********************/int checkdir(__G__ pathcomp, flag)    __GDEF    char *pathcomp;    int flag;/* * returns: *  MPN_OK          - no problem detected *  MPN_INF_TRUNC   - (on APPEND_NAME) truncated filename *  MPN_INF_SKIP    - path doesn't exist, not allowed to create *  MPN_ERR_SKIP    - path doesn't exist, tried to create and failed; or path *                    exists and is not a directory, but is supposed to be *  MPN_ERR_TOOLONG - path is too long *  MPN_NOMEM       - can't allocate memory for filename buffers *//* By using in2ex() to pre-process the filename we do not need to worry   about the lengths of filename parts.  We just need to cope with mapping the   pseudo file extensions properly of the actual filename (last part of name).   e.g.  "tandem c" -> tandemc         "revsion.h" -> revisioh */{    static int rootlen = 0;   /* length of rootpath */    static char *rootpath;    /* user's "extract-to" directory */    static char *buildpath;   /* full path (so far) to extracted file */    static char *end;         /* pointer to end of buildpath ('\0') */#   define FN_MASK   7#   define FUNCTION  (flag & FN_MASK)    char fname[FILENAME_MAX + 1];    short extension, fnamelen, extlen, trunclen, i;    char ext[EXTENSION_MAX + 1];    char *ptr;/*---------------------------------------------------------------------------    APPEND_DIR:  append the path component to the path being built and check    for its existence.  If doesn't exist and we are creating directories, do    so for this one; else signal success or error as appropriate.  ---------------------------------------------------------------------------*/    if (FUNCTION == APPEND_DIR) {        int too_long = FALSE;        Trace((stderr, "appending dir segment [%s]\n", FnFilter1(pathcomp)));        while ((*end = *pathcomp++) != '\0')            ++end;        if (stat(buildpath, &G.statbuf)) {  /* path doesn't exist */            if (!G.create_dirs) { /* told not to create (freshening) */                free(buildpath);                return MPN_INF_SKIP;    /* path doesn't exist: nothing to do */            }            if (mkdir(buildpath, 0777) == -1) {   /* create the directory */                Info(slide, 1, ((char *)slide,                  "checkdir error:  cannot create %s\n\                 unable to process %s.\n",                  FnFilter2(buildpath), FnFilter1(G.filename)));                free(buildpath);                /* path didn't exist, tried to create, failed */                return MPN_ERR_SKIP;            }            created_dir = TRUE;        } else if (!S_ISDIR(G.statbuf.st_mode)) {            Info(slide, 1, ((char *)slide,              "checkdir error:  %s exists but is not directory\n\                 unable to process %s.\n",                  FnFilter2(buildpath), FnFilter1(G.filename)));            free(buildpath);            /* path existed but wasn't dir */            return MPN_ERR_SKIP;        }        *end++ = TANDEM_DELIMITER;        *end = '\0';        Trace((stderr, "buildpath now = [%s]\n", FnFilter1(buildpath)));        return MPN_OK;    } /* end if (FUNCTION == APPEND_DIR) *//*---------------------------------------------------------------------------    GETPATH:  copy full path to the string pointed at by pathcomp, and free    buildpath.  ---------------------------------------------------------------------------*/

⌨️ 快捷键说明

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