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

📄 msdos.c

📁 压缩解压,是unzip540的升级,这个外国网站摘来的源码,是evb编写.
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************/static void maskDOSdevice(__G__ pathcomp, last_dot)    __GDEF    char *pathcomp, *last_dot;{/*---------------------------------------------------------------------------    Put an underscore in front of the file name if the file name is a    DOS/WINDOWS device name like CON.*, AUX.*, PRN.*, etc. Trying to    extract such a file would fail at best and wedge us at worst.  ---------------------------------------------------------------------------*/#if !defined(S_IFCHR) && defined(_S_IFCHR)#  define S_IFCHR _S_IFCHR#endif#if !defined(S_ISCHR)# if defined(_S_ISCHR)#  define S_ISCHR(m) _S_ISCHR(m)# elif defined(S_IFCHR)#  define S_ISCHR(m) ((m) & S_IFCHR)# endif#endif#ifdef DEBUG    if (stat(pathcomp, &G.statbuf) == 0) {        Trace((stderr,               "maskDOSdevice() stat(\"%s\", buf) st_mode result: %X, %o\n",               FnFilter1(pathcomp), G.statbuf.st_mode, G.statbuf.st_mode));    } else {        Trace((stderr, "maskDOSdevice() stat(\"%s\", buf) failed\n",               FnFilter1(pathcomp)));    }#endif    if (stat(pathcomp, &G.statbuf) == 0 && S_ISCHR(G.statbuf.st_mode)) {        extent i;        /* pathcomp contains a name of a DOS character device (builtin or         * installed device driver).         * Prepend a '_' to allow creation of the item in the file system.         */        for (i = strlen(pathcomp) + 1; i > 0; --i)            pathcomp[i] = pathcomp[i - 1];        pathcomp[0] = '_';        if (last_dot != (char *)NULL)            last_dot++;    }} /* end function maskDOSdevice() */#ifdef MAYBE_PLAIN_FAT/**********************//* Function map2fat() *//**********************/static void map2fat(pathcomp, last_dot)    char *pathcomp, *last_dot;{    char *pEnd = pathcomp + strlen(pathcomp);/*---------------------------------------------------------------------------    Case 1:  filename has no dot, so figure out if we should add one.  Note    that the algorithm does not try to get too fancy:  if there are no dots    already, the name either gets truncated at 8 characters or the last un-    derscore is converted to a dot (only if more characters are saved that    way).  In no case is a dot inserted between existing characters.              GRR:  have problem if filename is volume label??  ---------------------------------------------------------------------------*/    if (last_dot == (char *)NULL) {   /* no dots:  check for underscores... */        char *plu = strrchr(pathcomp, '_');   /* pointer to last underscore */        if ((plu != (char *)NULL) &&    /* found underscore: convert to dot? */            (MIN(plu - pathcomp, 8) + MIN(pEnd - plu - 1, 3) > 8)) {            last_dot = plu;       /* be lazy:  drop through to next if-block */        } else if ((pEnd - pathcomp) > 8)            /* no underscore; or converting underscore to dot would save less               chars than leaving everything in the basename */            pathcomp[8] = '\0';     /* truncate at 8 chars */        /* else whole thing fits into 8 chars or less:  no change */    }/*---------------------------------------------------------------------------    Case 2:  filename has dot in it, so truncate first half at 8 chars (shift    extension if necessary) and second half at three.  ---------------------------------------------------------------------------*/    if (last_dot != (char *)NULL) {     /* one dot is OK: */        *last_dot = '.';                /* put the last back in */        if ((last_dot - pathcomp) > 8) {            char *p, *q;            int i;            p = last_dot;            q = last_dot = pathcomp + 8;            for (i = 0;  (i < 4) && *p;  ++i) /* too many chars in basename: */                *q++ = *p++;                  /*  shift extension left and */            *q = '\0';                        /*  truncate/terminate it */        } else if ((pEnd - last_dot) > 4)            last_dot[4] = '\0';               /* too many chars in extension */        /* else filename is fine as is:  no change */        if ((last_dot - pathcomp) > 0 && last_dot[-1] == ' ')            last_dot[-1] = '_';               /* NO blank in front of '.'! */    }} /* end function map2fat() */#endif /* MAYBE_PLAIN_FAT *//***********************//* 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 */{    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') */#ifdef MSC    int attrs;                /* work around MSC stat() bug */#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) {        int too_long = FALSE;        Trace((stderr, "appending dir segment [%s]\n", FnFilter1(pathcomp)));        while ((*end = *pathcomp++) != '\0')            ++end;        /* GRR:  could do better check, see if overrunning buffer as we go:         * check end-buildpath 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. */        if ((end-buildpath) > FILNAMSIZ-3)  /* need '/', one-char name, '\0' */            too_long = TRUE;                /* check if extracting directory? */#ifdef MSC /* MSC 6.00 bug:  stat(non-existent-dir) == 0 [exists!] */        if (_dos_getfileattr(buildpath, &attrs) || stat(buildpath, &G.statbuf))#else        if (SSTAT(buildpath, &G.statbuf))   /* path doesn't exist */#endif        {            if (!G.create_dirs) { /* told not to create (freshening) */                free(buildpath);                /* path doesn't exist:  nothing to do */                return MPN_INF_SKIP;            }            if (too_long) {                Info(slide, 1, ((char *)slide, LoadFarString(PathTooLong),                  FnFilter1(buildpath)));                free(buildpath);                /* no room for filenames:  fatal */                return MPN_ERR_TOOLONG;            }            if (MKDIR(buildpath, 0777) == -1) {   /* create the directory */                Info(slide, 1, ((char *)slide, LoadFarString(CantCreateDir),                  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, LoadFarString(DirIsntDirectory),              FnFilter2(buildpath), FnFilter1(G.filename)));            free(buildpath);            /* path existed but wasn't dir */            return MPN_ERR_SKIP;        }        if (too_long) {            Info(slide, 1, ((char *)slide, LoadFarString(PathTooLong),              FnFilter1(buildpath)));            free(buildpath);            /* no room for filenames:  fatal */            return MPN_ERR_TOOLONG;        }        *end++ = '/';        *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.  ---------------------------------------------------------------------------*/    if (FUNCTION == GETPATH) {        strcpy(pathcomp, buildpath);        Trace((stderr, "getting and freeing path [%s]\n",          FnFilter1(pathcomp)));        free(buildpath);        buildpath = end = (char *)NULL;        return MPN_OK;    }/*---------------------------------------------------------------------------    APPEND_NAME:  assume the path component is the filename; append it and    return without checking for existence.  ---------------------------------------------------------------------------*/    if (FUNCTION == APPEND_NAME) {#ifdef NOVELL_BUG_WORKAROUND        if (end == buildpath && !G.pInfo->vollabel) {            /* work-around for Novell's "overwriting executables" bug:               prepend "./" to name when no path component is specified */            *end++ = '.';            *end++ = '/';        }#endif /* NOVELL_BUG_WORKAROUND */        Trace((stderr, "appending filename [%s]\n", FnFilter1(pathcomp)));        while ((*end = *pathcomp++) != '\0') {            ++end;            if ((end-buildpath) >= FILNAMSIZ) {                *--end = '\0';                Info(slide, 1, ((char *)slide, LoadFarString(PathTooLongTrunc),                  FnFilter1(G.filename), FnFilter2(buildpath)));                return MPN_INF_TRUNC;   /* filename truncated */            }        }        Trace((stderr, "buildpath now = [%s]\n", FnFilter1(buildpath)));        /* could check for existence here, prompt for new name... */        return MPN_OK;    }/*---------------------------------------------------------------------------    INIT:  allocate and initialize buffer space for the file currently being    extracted.  If file was renamed with an absolute path, don't prepend the    extract-to path.  ---------------------------------------------------------------------------*/    if (FUNCTION == INIT) {        Trace((stderr, "initializing buildpath to "));        /* allocate space for full filename, root path, and maybe "./" */        if ((buildpath = (char *)malloc(strlen(G.filename)+rootlen+3)) ==            (char *)NULL)            return MPN_NOMEM;        if (G.pInfo->vollabel) {/* GRR:  for network drives, do strchr() and return IZ_VOL_LABEL if not [1] */            if (renamed_fullpath && pathcomp[1] == ':')                *buildpath = (char)ToLower(*pathcomp);            else if (!renamed_fullpath && rootlen > 1 && rootpath[1] == ':')                *buildpath = (char)ToLower(*rootpath);            else {                GETDRIVE(nLabelDrive);   /* assumed that a == 1, b == 2, etc. */                *buildpath = (char)(nLabelDrive - 1 + 'a');            }            nLabelDrive = *buildpath - 'a' + 1;        /* save for mapname() */            if (uO.volflag == 0 || *buildpath < 'a' || /* no label/bogus disk */               (uO.volflag == 1 && !isfloppy(nLabelDrive))) /* -$:  no fixed */            {                free(buildpath);                return MPN_VOL_LABEL;    /* skipping with message */            }            *buildpath = '\0';            end = buildpath;        } else if (renamed_fullpath) {   /* pathcomp = valid data */            end = buildpath;            while ((*end = *pathcomp++) != '\0')                ++end;        } else if (rootlen > 0) {            strcpy(buildpath, rootpath);            end = buildpath + rootlen;        } else {            *buildpath = '\0';            end = buildpath;        }        Trace((stderr, "[%s]\n", FnFilter1(buildpath)));        return MPN_OK;    }/*---------------------------------------------------------------------------    ROOT:  if appropriate, store the path in rootpath and create it if neces-    sary; else assume it's a zipfile member and return.  This path segment    gets used in extracting all members from every zipfile specified on the    command line.  Note that under OS/2 and MS-DOS, if a candidate extract-to    directory specification includes a drive letter (leading "x:"), it is    treated just as if it had a trailing '/'--that is, one directory level    will be created if the path doesn't exist, unless this is otherwise pro-    hibited (e.g., freshening).  ---------------------------------------------------------------------------*/#if (!defined(SFX) || defined(SFX_EXDIR))    if (FUNCTION == ROOT) {        Trace((stderr, "initializing root path to [%s]\n",          FnFilter1(pathcomp)));        if (pathcomp == (char *)NULL) {            rootlen = 0;            return MPN_OK;        }        if (rootlen > 0)        /* rootpath was already set, nothing to do */            return MPN_OK;        if ((rootlen = strlen(pathcomp)) > 0) {            int had_trailing_pathsep=FALSE, has_drive=FALSE, add_dot=FALSE;            char *tmproot;            if ((tmproot = (char *)malloc(rootlen+3)) == (char *)NULL) {                rootlen = 0;                return MPN_NOMEM;            }            strcpy(tmproot, pathcomp);            if (isalpha((uch)tmproot[0]) && tmproot[1] == ':')                has_drive = TRUE;   /* drive designator */            if (tmproot[rootlen-1] == '/' || tmproot[rootlen-1] == '\\') {                tmproot[--rootlen] = '\0';                had_trailing_pathsep = TRUE;            }            if (has_drive && (rootlen == 2)) {                if (!had_trailing_pathsep)   /* i.e., original wasn't "x:/" */                    add_dot = TRUE;    /* relative path: add '.' before '/' */            } else if (rootlen > 0) {     /* need not check "x:." and "x:/" */#ifdef MSC                /* MSC 6.00 bug:  stat(non-existent-dir) == 0 [exists!] */                if (_dos_getfileattr(tmproot, &attrs) ||                    SSTAT(tmproot, &G.statbuf) || !S_ISDIR(G.statbuf.st_mode))#else                if (SSTAT(tmproot, &G.statbuf) || !S_ISDIR(G.statbuf.st_mode))#endif                {                    /* path does not exist */                    if (!G.create_dirs /* || iswild(tmproot) */ ) {                        free(tmproot);                        rootlen = 0;                        /* treat as stored file */                        return MPN_INF_SKIP;                    }/* GRR:  scan for wildcard characters?  OS-dependent...  if find any, return 2: * treat as stored file(s) */                    /* create directory (could add loop here scanning tmproot                     * to create more than one level, but really necessary?) */

⌨️ 快捷键说明

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