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

📄 os2.c

📁 压缩解压,是unzip540的升级,这个外国网站摘来的源码,是evb编写.
💻 C
📖 第 1 页 / 共 5 页
字号:
 * 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=(char *)NULL;    /* character pointers */    char *lastsemi=(char *)NULL;   /* pointer to last semi-colon in pathcomp */#ifdef ACORN_FTYPE_NFS    char *lastcomma=(char *)NULL;  /* pointer to last comma in pathcomp */    RO_extra_block *ef_spark;      /* pointer Acorn FTYPE ef block */#endif    int killed_ddot = FALSE;       /* is set when skipping "../" pathcomp */    int error = MPN_OK;    register unsigned workch;      /* hold the character being tested *//*---------------------------------------------------------------------------    Initialize various pointers and counters and stuff.  ---------------------------------------------------------------------------*/    /* can create path as long as not just freshening, or if user told us */    G.create_dirs = (!uO.fflag || renamed);    G.os2.created_dir = FALSE;  /* not yet */    G.os2.renamed_fullpath = FALSE;    G.os2.fnlen = strlen(G.filename);/* GRR:  for VMS, convert to internal format now or later? or never? */    if (renamed) {        cp = G.filename - 1;    /* point to beginning of renamed name... */        while (*++cp)            if (*cp == '\\')    /* convert backslashes to forward */                *cp = '/';        cp = G.filename;        /* use temporary rootpath if user gave full pathname */        if (G.filename[0] == '/') {            G.os2.renamed_fullpath = TRUE;            pathcomp[0] = '/';  /* copy the '/' and terminate */            pathcomp[1] = '\0';            ++cp;        } else if (isalpha((uch)G.filename[0]) && G.filename[1] == ':') {            G.os2.renamed_fullpath = TRUE;            pp = pathcomp;            *pp++ = *cp++;      /* copy the "d:" (+ '/', possibly) */            *pp++ = *cp++;            if (*cp == '/')                *pp++ = *cp++;  /* otherwise add "./"? */            *pp = '\0';        }    }    /* pathcomp is ignored unless renamed_fullpath is TRUE: */    if ((error = checkdir(__G__ pathcomp, INIT)) != 0)    /* init path buffer */        return error;           /* ...unless no mem or vol label on hard disk */    *pathcomp = '\0';           /* initialize translation buffer */    pp = pathcomp;              /* point to translation buffer */    if (!renamed) {             /* cp already set if renamed */        if (uO.jflag)           /* junking directories *//* GRR:  watch out for VMS version... */            cp = (char *)strrchr(G.filename, '/');        if (cp == (char *)NULL) /* no '/' or not junking dirs */            cp = G.filename;    /* point to internal zipfile-member pathname */        else            ++cp;               /* point to start of last component of path */    }/*---------------------------------------------------------------------------    Begin main loop through characters in filename.  ---------------------------------------------------------------------------*/    while ((workch = (uch)*cp++) != 0) {        switch (workch) {            case '/':             /* can assume -j flag not given */                *pp = '\0';                if (strcmp(pathcomp, ".") == 0) {                    /* don't bother appending "./" to the path */                    *pathcomp = '\0';                } else if (!uO.ddotflag && strcmp(pathcomp, "..") == 0) {                    /* "../" dir traversal detected, skip over it */                    *pathcomp = '\0';                    killed_ddot = TRUE;     /* set "show message" flag */                }                /* when path component is not empty, append it now */                if (*pathcomp != '\0' &&                    ((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 direct. semi-colons alone */                break;            case ':':             /* drive never stored, so no colon allowed */            case '\\':            /* "non-dos" FSs may  allow '\\' as normal */                *pp++ = '_';      /*  character in filenames */                break;            /* -> map invalid chars to underscore */            case ';':             /* start of VMS version? */                lastsemi = pp;    /* remove VMS version later... */                *pp++ = ';';      /*  but keep semicolon for now */                break;#ifdef ACORN_FTYPE_NFS            case ',':             /* NFS filetype extension */                lastcomma = pp;                *pp++ = ',';      /* keep for now; may need to remove */                break;            /*  later, if requested */#endif            case ' ':             /* keep spaces unless specifically */                if (uO.sflag)     /*  requested to change to underscore */                    *pp++ = '_';                else                    *pp++ = ' ';                break;            default:                /* allow ASCII 255 and European characters in filenames: */                if (isprint(workch) || workch >= 127)                    *pp++ = (char)workch;        } /* end switch */    } /* end while loop */    /* Show warning when stripping insecure "parent dir" path components */    if (killed_ddot && QCOND2) {        Info(slide, 0, ((char *)slide, LoadFarString(WarnDirTraversSkip),          FnFilter1(G.filename)));        if (!(error & ~MPN_MASK))            error = (error & MPN_MASK) | PK_WARN;    }/*---------------------------------------------------------------------------    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[G.os2.fnlen-1] == '/') {        checkdir(__G__ G.filename, GETPATH);        if (G.os2.created_dir) {            if (QCOND2)                Info(slide, 0, ((char *)slide, LoadFarString(Creating),                  FnFilter1(G.filename)));            if (G.extra_field) { /* zipfile extra field has extended attribs */                int err = EvalExtraFields(__G__ G.filename, G.extra_field,                                          G.lrec.extra_field_length);                if (err == IZ_EF_TRUNC) {                    if (uO.qflag)                        Info(slide, 1, ((char *)slide, "%-22s ",                          FnFilter1(G.filename)));                    Info(slide, 1, ((char *)slide, LoadFarString(TruncEAs),                      makeword(G.extra_field+2)-10, "\n"));                } else if (!uO.qflag)                    (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0);            } else if (!uO.qflag)                (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0);            /* set date/time stamps */            SetPathAttrTimes(__G__ G.pInfo->file_attr & ~A_ARCHIVE, 1);            /* dir time already set */            return (error & ~MPN_MASK) | MPN_CREATED_DIR;        } else if (G.extra_field && IS_OVERWRT_ALL) {            /* overwrite EAs of existing directory since user requested it */            int err = EvalExtraFields(__G__ G.filename, G.extra_field,                                      G.lrec.extra_field_length);            if (err == IZ_EF_TRUNC) {                Info(slide, 0x421, ((char *)slide, "%-22s ",                  FnFilter1(G.filename)));                Info(slide, 0x401, ((char *)slide, LoadFarString(TruncEAs),                  makeword(G.extra_field+2)-10, "\n"));            }            /* set date/time stamps (dirs only have creation times) */            SetPathAttrTimes(__G__ G.pInfo->file_attr & ~A_ARCHIVE, 1);        }        /* 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;        /* semi-colon was kept:  expect #s after */        while (isdigit((uch)(*pp)))            ++pp;        if (*pp == '\0')          /* only digits between ';' and end:  nuke */            *lastsemi = '\0';    }#ifdef ACORN_FTYPE_NFS    /* translate Acorn filetype information if asked to do so */    if (uO.acorn_nfs_ext &&        (ef_spark = (RO_extra_block *)                    getRISCOSexfield(G.extra_field, G.lrec.extra_field_length))        != (RO_extra_block *)NULL)    {        /* file *must* have a RISC OS extra field */        long ft = (long)makelong(ef_spark->loadaddr);        /*32-bit*/        if (lastcomma) {            pp = lastcomma + 1;            while (isxdigit((uch)(*pp))) ++pp;            if (pp == lastcomma+4 && *pp == '\0') *lastcomma='\0'; /* nuke */        }        if ((ft & 1<<31)==0) ft=0x000FFD00;        sprintf(pathcomp+strlen(pathcomp), ",%03x", (int)(ft>>8) & 0xFFF);    }#endif /* ACORN_FTYPE_NFS */    if (*pathcomp == '\0') {        Info(slide, 1, ((char *)slide, LoadFarString(ConversionFailed),          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);    Trace((stderr, "mapname returns with filename = [%s] (error = %d)\n\n",      FnFilter1(G.filename), error));    if (G.pInfo->vollabel) {    /* set the volume label now */        VOLUMELABEL FSInfoBuf;/* GRR:  "VOLUMELABEL" defined for IBM C and emx, but haven't checked MSC... */        strcpy(FSInfoBuf.szVolLabel, G.filename);        FSInfoBuf.cch = (BYTE)strlen(FSInfoBuf.szVolLabel);        if (!uO.qflag)            Info(slide, 0, ((char *)slide, LoadFarString(Labelling),              (char)(G.os2.nLabelDrive + 'a' - 1), FnFilter1(G.filename)));        if (DosSetFSInfo(G.os2.nLabelDrive, FSIL_VOLSER, (PBYTE)&FSInfoBuf,                         sizeof(VOLUMELABEL)))        {            Info(slide, 1, ((char *)slide, LoadFarString(ErrSetVolLabel)));            return (error & ~MPN_MASK) | MPN_ERR_SKIP;        }        /* success:  skip the "extraction" quietly */        return (error & ~MPN_MASK) | MPN_INF_SKIP;    }    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 */{  /* moved to os2data.h so they can be global */#if 0    static int rootlen = 0;      /* length of rootpath */    static char *rootpath;       /* user's "extract-to" directory */    static char *buildpathHPFS;  /* full path (so far) to extracted file, */    static char *buildpathFAT;   /*  both HPFS/EA (main) and FAT versions */    static char *endHPFS;        /* corresponding pointers to end of */    static char *endFAT;         /*  buildpath ('\0') */#endif#   define FN_MASK   7#   define FUNCTION  (flag & FN_MASK)/*---------------------------------------------------------------------------    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) {        char *p = pathcomp;        int longdirEA, too_long=FALSE;        Trace((stderr, "appending dir segment [%s]\n", FnFilter1(pathcomp)));        while ((*G.os2.endHPFS = *p++) != '\0')     /* copy to HPFS filename */            ++G.os2.endHPFS;        if (IsFileNameValid(G.os2.buildpathHPFS)) {            longdirEA = FALSE;            p = pathcomp;            while ((*G.os2.endFAT = *p++) != '\0')  /* copy to FAT filename, too */                ++G.os2.endFAT;        } else {            longdirEA = TRUE;/* GRR:  check error return? */            map2fat(pathcomp, &G.os2.endFAT);  /* map, put in FAT fn, update endFAT */        }        /* GRR:  could do better check, see if overrunning buffer as we go:         * check endHPFS-G.os2.buildpathHPFS after each append, set warning variable         * if within 20 of FILNAMSIZ; then if var set, do careful check when         * appending.  Clear variable when begin new path. */        /* next check:  need to append '/', at least one-char name, '\0' */        if ((G.os2.endHPFS-G.os2.buildpathHPFS) > FILNAMSIZ-3)            too_long = TRUE;                 /* check if extracting dir? */#ifdef MSC /* MSC 6.00 bug:  stat(non-existent-dir) == 0 [exists!] */        if (GetFileTime(G.os2.buildpathFAT) == -1 || stat(G.os2.buildpathFAT, &G.statbuf))#else        if (stat(G.os2.buildpathFAT, &G.statbuf))    /* path doesn't exist */#endif        {            if (!G.create_dirs) { /* told not to create (freshening) */                free(G.os2.buildpathHPFS);                free(G.os2.buildpathFAT);                /* path doesn't exist:  nothing to do */                return MPN_INF_SKIP;            }            if (too_long) {   /* GRR:  should allow FAT extraction w/o EAs */                Info(slide, 1, ((char *)slide, LoadFarString(PathTooLong),                  FnFilter1(G.os2.buildpathHPFS)));                free(G.os2.buildpathHPFS);                free(G.os2.buildpathFAT);                /* no room for filenames:  fatal */                return MPN_ERR_TOOLONG;            }            if (MKDIR(G.os2.buildpathFAT, 0777) == -1) {   /* create the directory */                Info(slide, 1, ((char *)slide, LoadFarString(CantCreateDir),                  FnFilter2(G.os2.buildpathFAT), FnFilter1(G.filename)));                free(G.os2.buildpathHPFS);                free(G.os2.buildpathFAT);                /* path didn't exist, tried to create, failed */                return MPN_ERR_SKIP;            }            G.os2.created_dir = TRUE;            /* only set EA if creating directory *//* GRR:  need trailing '/' before function call? */            if (longdirEA) {#ifdef DEBUG                int e =#endif                  SetLongNameEA(G.os2.buildpathFAT, pathcomp);                Trace((stderr, "APPEND_DIR:  SetLongNameEA() returns %d\n", e));            }        } else if (!S_ISDIR(G.statbuf.st_mode)) {            Info(slide, 1, ((char *)slide, LoadFarString(DirIsntDirectory),              FnFilter2(G.os2.buildpathFAT), FnFilter1(G.filename)));            free(G.os2.buildpathHPFS);            free(G.os2.buildpathFAT);            /* path existed but wasn't dir */            return MPN_ERR_SKIP;        }        if (too_long) {            Info(slide, 1, ((char *)slide, LoadFarString(PathTooLong),              FnFilter1(G.os2.buildpathHPFS)));            free(G.os2.buildpathHPFS);            free(G.os2.buildpathFAT);            /* no room for filenames:  fatal */            return MPN_ERR_TOOLONG;        }        *G.os2.endHPFS++ = '/';        *G.os2.endFAT++ = '/';        *G.os2.endHPFS = *G.os2.endFAT = '\0';        Trace((stderr, "buildpathHPFS now = [%s]\n",          FnFilter1(G.os2.buildpathHPFS)));        Trace((stderr, "buildpathFAT now =  [%s]\n",          FnFilter1(G.os2.buildpathFAT)));        return MPN_OK;    } /* end if (FUNCTION == APPEND_DIR) */

⌨️ 快捷键说明

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