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

📄 os2.c

📁 压缩解压,是unzip540的升级,这个外国网站摘来的源码,是evb编写.
💻 C
📖 第 1 页 / 共 5 页
字号:
/*---------------------------------------------------------------------------    GETPATH:  copy full FAT path to the string pointed at by pathcomp (want    filename to reflect name used on disk, not EAs; if full path is HPFS,    buildpathFAT and buildpathHPFS will be identical).  Also free both paths.  ---------------------------------------------------------------------------*/    if (FUNCTION == GETPATH) {        Trace((stderr, "getting and freeing FAT path [%s]\n",          FnFilter1(G.os2.buildpathFAT)));        Trace((stderr, "freeing HPFS path [%s]\n",          FnFilter1(G.os2.buildpathHPFS)));        strcpy(pathcomp, G.os2.buildpathFAT);        free(G.os2.buildpathFAT);        free(G.os2.buildpathHPFS);        G.os2.buildpathHPFS = G.os2.buildpathFAT = G.os2.endHPFS = G.os2.endFAT = (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) {        char *p = pathcomp;        int error = MPN_OK;        Trace((stderr, "appending filename [%s]\n", FnFilter1(pathcomp)));        while ((*G.os2.endHPFS = *p++) != '\0') {    /* copy to HPFS filename */            ++G.os2.endHPFS;            if ((G.os2.endHPFS-G.os2.buildpathHPFS) >= FILNAMSIZ) {                *--G.os2.endHPFS = '\0';                Info(slide, 1, ((char *)slide, LoadFarString(PathTooLongTrunc),                  FnFilter1(G.filename), FnFilter2(G.os2.buildpathHPFS)));                error = MPN_INF_TRUNC;  /* filename truncated */            }        }/* GRR:  how can longnameEA ever be set before this point???  we don't want * to save the original name to EAs if user renamed it, do we? * * if (!G.os2.longnameEA && ((G.os2.longnameEA = !IsFileNameValid(name)) != 0)) */        if (G.pInfo->vollabel || IsFileNameValid(G.os2.buildpathHPFS)) {            G.os2.longnameEA = FALSE;            p = pathcomp;            while ((*G.os2.endFAT = *p++) != '\0')   /* copy to FAT filename, too */                ++G.os2.endFAT;        } else {            G.os2.longnameEA = TRUE;            if ((G.os2.lastpathcomp = (char *)malloc(strlen(pathcomp)+1)) ==                (char *)NULL)            {                Info(slide, 1, ((char *)slide,                 "checkdir warning:  cannot save longname EA: out of memory\n"));                G.os2.longnameEA = FALSE;                /* can't set .LONGNAME extended attribute */                error = MPN_INF_TRUNC;            } else           /* used and freed in close_outfile() */                strcpy(G.os2.lastpathcomp, pathcomp);            map2fat(pathcomp, &G.os2.endFAT);  /* map, put in FAT fn, update endFAT */        }        Trace((stderr, "buildpathHPFS: %s\nbuildpathFAT:  %s\n",          FnFilter1(G.os2.buildpathHPFS), FnFilter2(G.os2.buildpathFAT)));        return error;  /* could check for existence, prompt for new name... */    } /* end if (FUNCTION == APPEND_NAME) *//*---------------------------------------------------------------------------    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 buildpathHPFS and buildpathFAT to "));#ifdef ACORN_FTYPE_NFS        if ((G.os2.buildpathHPFS = (char *)malloc(G.os2.fnlen+G.os2.rootlen+                                                  (uO.acorn_nfs_ext ? 5 : 1)))#else        if ((G.os2.buildpathHPFS = (char *)malloc(G.os2.fnlen+G.os2.rootlen+1))#endif            == (char *)NULL)            return MPN_NOMEM;#ifdef ACORN_FTYPE_NFS        if ((G.os2.buildpathFAT = (char *)malloc(G.os2.fnlen+G.os2.rootlen+                                                 (uO.acorn_nfs_ext ? 5 : 1)))#else        if ((G.os2.buildpathFAT = (char *)malloc(G.os2.fnlen+G.os2.rootlen+1))#endif            == (char *)NULL) {            free(G.os2.buildpathHPFS);            return MPN_NOMEM;        }        if (G.pInfo->vollabel) {  /* use root or renamed path, but don't store *//* GRR:  for network drives, do strchr() and return IZ_VOL_LABEL if not [1] */            if (G.os2.renamed_fullpath && pathcomp[1] == ':')                *G.os2.buildpathHPFS = (char)ToLower(*pathcomp);            else if (!G.os2.renamed_fullpath && G.os2.rootlen > 1 && G.os2.rootpath[1] == ':')                *G.os2.buildpathHPFS = (char)ToLower(*G.os2.rootpath);            else {                ULONG lMap;                DosQueryCurrentDisk(&G.os2.nLabelDrive, &lMap);                *G.os2.buildpathHPFS = (char)(G.os2.nLabelDrive - 1 + 'a');            }            G.os2.nLabelDrive = *G.os2.buildpathHPFS - 'a' + 1; /* save for mapname() */            if (uO.volflag == 0 || *G.os2.buildpathHPFS < 'a' ||  /* no labels/bogus? */                (uO.volflag == 1 && !isfloppy(G.os2.nLabelDrive))) { /* -$:  no fixed */                free(G.os2.buildpathHPFS);                free(G.os2.buildpathFAT);                return MPN_VOL_LABEL;   /* skipping with message */            }            *G.os2.buildpathHPFS = '\0';        } else if (G.os2.renamed_fullpath)   /* pathcomp = valid data */            strcpy(G.os2.buildpathHPFS, pathcomp);        else if (G.os2.rootlen > 0)            strcpy(G.os2.buildpathHPFS, G.os2.rootpath);        else            *G.os2.buildpathHPFS = '\0';        G.os2.endHPFS = G.os2.buildpathHPFS;        G.os2.endFAT = G.os2.buildpathFAT;        while ((*G.os2.endFAT = *G.os2.endHPFS) != '\0') {            ++G.os2.endFAT;            ++G.os2.endHPFS;        }        Trace((stderr, "[%s]\n", FnFilter1(G.os2.buildpathHPFS)));        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) {            G.os2.rootlen = 0;            return MPN_OK;        }        if (G.os2.rootlen > 0)  /* rootpath was already set, nothing to do */            return MPN_OK;        if ((G.os2.rootlen = strlen(pathcomp)) > 0) {            int had_trailing_pathsep=FALSE, has_drive=FALSE, add_dot=FALSE;            char *tmproot;            if ((tmproot = (char *)malloc(G.os2.rootlen+3)) == (char *)NULL) {                G.os2.rootlen = 0;                return MPN_NOMEM;            }            strcpy(tmproot, pathcomp);            if (isalpha((uch)tmproot[0]) && tmproot[1] == ':')                has_drive = TRUE;   /* drive designator */            if (tmproot[G.os2.rootlen-1] == '/') {                tmproot[--G.os2.rootlen] = '\0';                had_trailing_pathsep = TRUE;            }            if (has_drive && (G.os2.rootlen == 2)) {                if (!had_trailing_pathsep)   /* i.e., original wasn't "x:/" */                    add_dot = TRUE;    /* relative path: add '.' before '/' */            } else if (G.os2.rootlen > 0) {   /* need not check "x:." and "x:/" */#ifdef MSC      /* MSC 6.00 bug:  stat(non-existent-dir) == 0 [exists!] */                if (GetFileTime(tmproot) == -1 ||                    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);                        G.os2.rootlen = 0;                        return MPN_INF_SKIP;    /* treat as stored file */                    }                    /* create directory (could add loop here scanning tmproot                     * to create more than one level, but really necessary?) */                    if (MKDIR(tmproot, 0777) == -1) {                        Info(slide, 1, ((char *)slide,                          LoadFarString(CantCreateExtractDir),                          FnFilter1(tmproot)));                        free(tmproot);                        G.os2.rootlen = 0;                        /* path didn't exist, tried to create, failed: */                        /* file exists, or need 2+ directory levels */                        return MPN_ERR_SKIP;                    }                }            }            if (add_dot)                    /* had just "x:", make "x:." */                tmproot[G.os2.rootlen++] = '.';            tmproot[G.os2.rootlen++] = '/';            tmproot[G.os2.rootlen] = '\0';            if ((G.os2.rootpath = realloc(tmproot, G.os2.rootlen+1)) == NULL) {                free(tmproot);                G.os2.rootlen = 0;                return MPN_NOMEM;            }            Trace((stderr, "rootpath now = [%s]\n", FnFilter1(G.os2.rootpath)));        }        return MPN_OK;    }#endif /* !SFX || SFX_EXDIR *//*---------------------------------------------------------------------------    END:  free rootpath, immediately prior to program exit.  ---------------------------------------------------------------------------*/    if (FUNCTION == END) {        Trace((stderr, "freeing rootpath\n"));        if (G.os2.rootlen > 0) {            free(G.os2.rootpath);            G.os2.rootlen = 0;        }        return MPN_OK;    }    return MPN_INVALID; /* should never reach */} /* end function checkdir() *//***********************//* Function isfloppy() */   /* more precisely, is it removable? *//***********************/static int isfloppy(nDrive)    int nDrive;   /* 1 == A:, 2 == B:, etc. */{    uch ParmList[1] = {0};    uch DataArea[1] = {0};    char Name[3];    HFILE handle;#ifdef __32BIT__    ULONG rc;    ULONG action;#else    USHORT rc;    USHORT action;#endif    Name[0] = (char) (nDrive + 'A' - 1);    Name[1] = ':';    Name[2] = 0;    rc = DosOpen(Name, &handle, &action, 0L, FILE_NORMAL, FILE_OPEN,                 OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR |                 OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, 0L);    if (rc == ERROR_NOT_READY)   /* must be removable */      return TRUE;    else if (rc) {   /* other error:  do default a/b heuristic instead */      Trace((stderr, "error in DosOpen(DASD):  guessing...\n", rc));      return (nDrive == 1 || nDrive == 2)? TRUE : FALSE;    }    rc = DosDevIOCtl(DataArea, sizeof(DataArea), ParmList, sizeof(ParmList),                     DSK_BLOCKREMOVABLE, IOCTL_DISK, handle);    DosClose(handle);    if (rc) {   /* again, just check for a/b */        Trace((stderr, "error in DosDevIOCtl category IOCTL_DISK, function "          "DSK_BLOCKREMOVABLE\n  (rc = 0x%04x):  guessing...\n", rc));        return (nDrive == 1 || nDrive == 2)? TRUE : FALSE;    } else {        return DataArea[0] ? FALSE : TRUE;    }} /* end function isfloppy() */static int IsFileNameValid(const char *name){  HFILE hf;#ifdef __32BIT__  ULONG uAction;#else  USHORT uAction;#endif  switch( DosOpen((PSZ) name, &hf, &uAction, 0, 0, FILE_OPEN,                  OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, 0) )  {  case ERROR_INVALID_NAME:  case ERROR_FILENAME_EXCED_RANGE:    return FALSE;  case NO_ERROR:    DosClose(hf);  default:    return TRUE;  }}/**********************//* Function map2fat() *//**********************/static void map2fat(pathcomp, pEndFAT)    char *pathcomp, **pEndFAT;{    char *ppc = pathcomp;          /* variable pointer to pathcomp */    char *pEnd = *pEndFAT;         /* variable pointer to buildpathFAT */    char *pBegin = *pEndFAT;       /* constant pointer to start of this comp. */    char *last_dot = (char *)NULL; /* last dot not converted to underscore */    int dotname = FALSE;           /* flag:  path component begins with dot */                                   /*  ("." and ".." don't count) */    register unsigned workch;      /* hold the character being tested */    /* Only need check those characters which are legal in HPFS but not     * in FAT:  to get here, must already have passed through mapname.     * (GRR:  oops, small bug--if char was quoted, no longer have any     * knowledge of that.)  Also must truncate path component to ensure     * 8.3 compliance...     */    while ((workch = (uch)*ppc++) != 0) {        switch (workch) {            case '[':               /* add  '"'  '+'  ','  '='  ?? */            case ']':                *pEnd++ = '_';      /* convert brackets to underscores */                break;            case '.':                if (pEnd == *pEndFAT) {   /* nothing appended yet... */                    if (*ppc == '\0')     /* don't bother appending a */                        break;            /*  "./" component to the path */                    else if (*ppc == '.' && ppc[1] == '\0') {   /* "../" */                        *pEnd++ = '.';    /* add first dot, unchanged... */                        ++ppc;            /* skip second dot, since it will */                    } else {              /*  be "added" at end of if-block */                        *pEnd++ = '_';    /* FAT doesn't allow null filename */                        dotname = TRUE;   /*  bodies, so map .exrc -> _.exrc */                    }                     /*  (extra '_' now, "dot" below) */                } else if (dotname) {     /* found a second dot, but still */                    dotname = FALSE;      /*  have extra leading underscore: */                    *pEnd = '\0';         /*  remove it by shifting chars */                    pEnd = *pEndFAT + 1;  /*  left one space (e.g., .p1.p2: */                    while (pEnd[1]) {     /*  __p1 -> _p1_p2 -> _p1.p2 when */                        *pEnd = pEnd[1];  /*  finished) [opt.:  since first */                        ++pEnd;           /*  two chars are same, can start */                    }                     /*  shifting at second position] */                }                last_dot = pEnd;    /* point at last dot so far... */                *pEnd++ = '_';      /* convert dot to underscore for now */                break;            default:                *pEnd++ = (char)workch;        } /* end switch */    } /* end while loop */    *pEnd = '\0';                 /* terminate buildpathFAT */    /* NOTE:  keep in mind that pEnd points to the end of the path     * component, and *pEndFAT still points to the *beginning* of it...     * Also 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 underscore is converted to a dot     * (only if more characters are saved that way).  In no case is     * a dot inserted between existing characters.     */    if (last_dot == (char *)NULL) {  /* no dots:  check for underscores... */        char *plu = strrchr(pBegin, '_');    /* pointer to last underscore */        if (plu == (char *)NULL) { /* no dots, no underscores:  truncate at 8 */            *pEndFAT += 8;         /* chars (could insert '.' and keep 11...) */            if (*pEndFAT > pEnd)                *pEndFAT = pEnd;   /* oops...didn't have 8 chars to truncate */ 

⌨️ 快捷键说明

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