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

📄 aosvs.c

📁 完整的解压zip文件的源码。包含密码功能
💻 C
📖 第 1 页 / 共 3 页
字号:
  ---------------------------------------------------------------------------*/    while ((workch = (uch)*cp++) != 0) {        if (quote) {                 /* if character quoted, */            *pp++ = (char)workch;    /*  include it literally */            quote = FALSE;        } else            switch (workch) {            case '/':             /* can assume -j flag not given */                *pp = '\0';                if ((error = checkdir(__G__ pathcomp, APPEND_DIR)) > 1)                    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;#ifdef MTS            case ' ':             /* change spaces to underscore under */                *pp++ = '_';      /*  MTS; leave as spaces under Unix */                break;#endif            default:                /* allow European characters in filenames: */                if (isprint(workch) || (128 <= workch && workch <= 254))                    *pp++ = (char)workch;            } /* end switch */    } /* end while loop */    *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';    }/*---------------------------------------------------------------------------    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] == '/') {        checkdir(__G__ G.filename, GETPATH);        if (created_dir) {            if (QCOND2) {                Info(slide, 0, ((char *)slide, "   creating: %s\n",                  G.filename));            }            return IZ_CREATED_DIR;   /* set dir time (note trailing '/') */        }        return 2;   /* dir existed already; don't look for data to extract */    }    if (*pathcomp == '\0') {        Info(slide, 1, ((char *)slide, "mapname:  conversion of %s failed\n",          G.filename));        return 3;    }    checkdir(__G__ pathcomp, APPEND_NAME);  /* returns 1 if truncated: care? */    checkdir(__G__ G.filename, GETPATH);    return error;} /* end function mapname() */#if 0  /*========== NOTES ==========*/  extract-to dir:      a:path/  buildpath:           path1/path2/ ...   (NULL-terminated)  pathcomp:                filename  mapname():    loop over chars in zipfile member name      checkdir(path component, COMPONENT | CREATEDIR) --> map as required?        (d:/tmp/unzip/)                    (disk:[tmp.unzip.)        (d:/tmp/unzip/jj/)                 (disk:[tmp.unzip.jj.)        (d:/tmp/unzip/jj/temp/)            (disk:[tmp.unzip.jj.temp.)    finally add filename itself and check for existence? (could use with rename)        (d:/tmp/unzip/jj/temp/msg.outdir)  (disk:[tmp.unzip.jj.temp]msg.outdir)    checkdir(name, GETPATH)     -->  copy path to name and free space#endif /* 0 *//***********************//* Function checkdir() *//***********************/int checkdir(__G__ pathcomp, flag)    __GDEF    char *pathcomp;    int flag;/* * returns:  1 - (on APPEND_NAME) truncated filename *           2 - path doesn't exist, not allowed to create *           3 - path doesn't exist, tried to create and failed; or *               path exists and is not a directory, but is supposed to be *           4 - path is too long *          10 - 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') */#   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;#ifdef SHORT_NAMES        char *old_end = end;#endif        Trace((stderr, "appending dir segment [%s]\n", pathcomp));        while ((*end = *pathcomp++) != '\0')            ++end;#ifdef SHORT_NAMES   /* path components restricted to 14 chars, typically */        if ((end-old_end) > FILENAME_MAX)  /* GRR:  proper constant? */            *(end = old_end + FILENAME_MAX) = '\0';#endif        /* 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? */        /* for AOS/VS, try to create so as to not use searchlist: */        if ( /*stat(buildpath, &G.statbuf)*/ 1) {            if (!G.create_dirs) { /* told not to create (freshening) */                free(buildpath);                return 2;         /* path doesn't exist:  nothing to do */            }            if (too_long) {                Info(slide, 1, ((char *)slide,                  "checkdir error:  path too long: %s\n", buildpath));                free(buildpath);                return 4;         /* no room for filenames:  fatal */            }            /* create the directory */            if (zvs_credir(buildpath,-1L,-1L,-1L,(char *) -1,-1,0L,-1,-1) == -1)            {                Info(slide, 1, ((char *)slide,                  "checkdir error:  cannot create %s\n\                 unable to process %s.\n", buildpath, G.filename));                free(buildpath);                return 3;      /* path didn't exist, tried to create, failed */            }            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", buildpath, G.filename));            free(buildpath);            return 3;          /* path existed but wasn't dir */        }        if (too_long) {            Info(slide, 1, ((char *)slide,              "checkdir error:  path too long: %s\n", buildpath));            free(buildpath);            return 4;         /* no room for filenames:  fatal */        }        *end++ = '/';        *end = '\0';        Trace((stderr, "buildpath now = [%s]\n", buildpath));        return 0;    } /* 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", pathcomp));        free(buildpath);        buildpath = end = (char *)NULL;        return 0;    }/*---------------------------------------------------------------------------    APPEND_NAME:  assume the path component is the filename; append it and    return without checking for existence.  ---------------------------------------------------------------------------*/    if (FUNCTION == APPEND_NAME) {#ifdef SHORT_NAMES        char *old_end = end;#endif        Trace((stderr, "appending filename [%s]\n", pathcomp));        while ((*end = *pathcomp++) != '\0') {            ++end;#ifdef SHORT_NAMES  /* truncate name at 14 characters, typically */            if ((end-old_end) > FILENAME_MAX)      /* GRR:  proper constant? */                *(end = old_end + FILENAME_MAX) = '\0';#endif            if ((end-buildpath) >= FILNAMSIZ) {                *--end = '\0';                Info(slide, 1, ((char *)slide,                  "checkdir warning:  path too long; truncating\n\                   %s\n                -> %s\n", G.filename, buildpath));                return 1;   /* filename truncated */            }        }        Trace((stderr, "buildpath now = [%s]\n", buildpath));        return 0;  /* could check for existence here, prompt for new 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.  ---------------------------------------------------------------------------*//* GRR:  for VMS and TOPS-20, add up to 13 to strlen */    if (FUNCTION == INIT) {        Trace((stderr, "initializing buildpath to "));        if ((buildpath = (char *)malloc(strlen(G.filename)+rootlen+1)) ==            (char *)NULL)            return 10;        if ((rootlen > 0) && !renamed_fullpath) {            strcpy(buildpath, rootpath);            end = buildpath + rootlen;        } else {            *buildpath = '\0';            end = buildpath;        }        Trace((stderr, "[%s]\n", buildpath));        return 0;    }/*---------------------------------------------------------------------------    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.  ---------------------------------------------------------------------------*/#if (!defined(SFX) || defined(SFX_EXDIR))    if (FUNCTION == ROOT) {        Trace((stderr, "initializing root path to [%s]\n", pathcomp));        if (pathcomp == (char *)NULL) {            rootlen = 0;            return 0;        }        if ((rootlen = strlen(pathcomp)) > 0) {            if (pathcomp[rootlen-1] == '/') {                pathcomp[--rootlen] = '\0';            }            if (rootlen > 0 && (stat(pathcomp, &G.statbuf) ||                !S_ISDIR(G.statbuf.st_mode)))       /* path does not exist */            {                if (!G.create_dirs /* || iswild(pathcomp) */ ) {                    rootlen = 0;                    return 2;   /* skip (or treat as stored file) */                }                /* create the directory (could add loop here to scan pathcomp                 * and create more than one level, but why really necessary?) */                if (zvs_credir(pathcomp,-1L,-1L,-1L,(char *) -1,-1,0L,-1,-1)                    == -1)                {                    Info(slide, 1, ((char *)slide,                      "checkdir:  cannot create extraction directory: %s\n",                      pathcomp));                    rootlen = 0;   /* path didn't exist, tried to create, and */                    return 3;  /* failed:  file exists, or 2+ levels required */                }            }            if ((rootpath = (char *)malloc(rootlen+2)) == (char *)NULL) {                rootlen = 0;                return 10;            }            strcpy(rootpath, pathcomp);            rootpath[rootlen++] = '/';            rootpath[rootlen] = '\0';            Trace((stderr, "rootpath now = [%s]\n", rootpath));        }        return 0;    }#endif /* !SFX || SFX_EXDIR *//*---------------------------------------------------------------------------    END:  free rootpath, immediately prior to program exit.  ---------------------------------------------------------------------------*/    if (FUNCTION == END) {        Trace((stderr, "freeing rootpath\n"));        if (rootlen > 0) {            free(rootpath);            rootlen = 0;        }        return 0;    }    return 99;  /* should never reach */} /* end function checkdir() */#ifdef MORE/**************************//* Function screenlines() *//**************************/int screenlines(){    char *envptr, *getenv();    int n;    /* GRR:  this is overly simplistic; should use winsize struct and     * appropriate TIOCGWINSZ ioctl(), assuming exists on enough systems     */    envptr = getenv("LINES");    if (envptr == (char *)NULL || (n = atoi(envptr)) < 5)        return 24;   /* VT-100 assumed to be minimal hardware */    else        return n;}#endif /* MORE *//****************************//* Function close_outfile() *//****************************/void close_outfile(__G)    /* GRR: change to return PK-style warning level */    __GDEF{/*---------------------------------------------------------------------------    If symbolic links are supported, allocate a storage area, put the uncom-    pressed "data" in it, and create the link.  Since we know it's a symbolic    link to start with, we shouldn't have to worry about overflowing unsigned    ints with unsigned longs.  ---------------------------------------------------------------------------*/#ifdef SYMLINKS    if (G.symlnk) {        unsigned ucsize = (unsigned)G.lrec.ucsize;        char *linktarget = (char *)malloc((unsigned)G.lrec.ucsize+1);        fclose(G.outfile);                      /* close "data" file... */        G.outfile = fopen(G.filename, FOPR);    /* ...and reopen for reading */        if (!linktarget || fread(linktarget, 1, ucsize, G.outfile) !=                           (int)ucsize)        {            Info(slide, 0x201, ((char *)slide,              "warning:  symbolic link (%s) failed\n", G.filename));            if (linktarget)                free(linktarget);            fclose(G.outfile);            return;        }        fclose(G.outfile);                  /* close "data" file for good... */        unlink(G.filename);                 /* ...and delete it */        linktarget[ucsize] = '\0';        if (QCOND2)            Info(slide, 0, ((char *)slide, "-> %s ", linktarget));        if (symlink(linktarget, G.filename))  /* create the real link */            perror("symlink error");        free(linktarget);        return;                             /* can't set time on symlinks */    }#endif /* SYMLINKS */    fclose(G.outfile);/*---------------------------------------------------------------------------    Change the file permissions from default ones to those stored in the    zipfile.  ---------------------------------------------------------------------------*/#ifndef NO_CHMOD    if (chmod(G.filename, 0xffff & G.pInfo->file_attr))        perror("chmod (file attributes) error");#endif/*---------------------------------------------------------------------------    AOS/VS only allows setting file times at creation but has its own permis-    sions scheme which is better invoked here if the necessary information    was in fact stored.  In theory, we should look through an entire series    of extra fields that might exist for the same file, but we're not going    to bother.  If we set up other types of extra fields, or if we run into    other environments that add their own stuff to existing entries in ZIP    files, we'll have to.  NOTE:  already copied extra-field stuff into    zzextrafld structure when file was created.  ---------------------------------------------------------------------------*/    if (G.extra_field != NULL) {        if (!memcmp(ZEXTRA_HEADID, zzextrafld.extra_header_id,                    sizeof(zzextrafld.extra_header_id))  &&            !memcmp(ZEXTRA_SENTINEL, zzextrafld.extra_sentinel,                    sizeof(zzextrafld.extra_sentinel))  &&            zzextrafld.fstat_packet.norm_fstat_packet.styp_type != $FLNK)            /* (AOS/VS links don't have ACLs) */        {            /* vs_path was set (in this case) when we created the file */            if (sys_sacl(vs_path, zzextrafld.aclbuf)) {                Info(slide, 0x201, ((char *)slide,                  "error: cannot set ACL for %s\n", G.filename));                perror("sys_sacl()");            }        }    }} /* end function close_outfile() */

⌨️ 快捷键说明

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