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

📄 unzip.c

📁 另一个解zip文件的程序
💻 C
📖 第 1 页 / 共 5 页
字号:
            ++NumLoseFiles;
        else
            ++NumWinFiles;

        if (error > error_in_archive)
            error_in_archive = error;
        Trace((stderr, "do_seekable(1) returns %d\n", error));
    }
#endif /* ?SFX */

    FFLUSH(stdout);
    FFLUSH(stderr);

/*---------------------------------------------------------------------------
    Print summary of all zipfiles, assuming zipfile spec was a wildcard (no
    need for a summary if just one zipfile).
  ---------------------------------------------------------------------------*/

#ifndef SFX
    if (iswild(wildzipfn)) {
        if (NumMissFiles + NumLoseFiles + NumWarnFiles > 0 || NumWinFiles != 1)
            FPRINTF(stderr, "\n");
        if ((NumWinFiles > 1) || (NumWinFiles == 1 &&
            NumMissDirs + NumMissFiles + NumLoseFiles + NumWarnFiles > 0))
            FPRINTF(stderr, LoadFarString(FilesProcessOK),
              NumWinFiles, (NumWinFiles == 1)? " was" : "s were");
        if (NumWarnFiles > 0)
            FPRINTF(stderr, LoadFarString(ArchiveWarning),
              NumWarnFiles, (NumWarnFiles == 1)? "" : "s");
        if (NumLoseFiles > 0)
            FPRINTF(stderr, LoadFarString(ArchiveFatalError),
              NumLoseFiles, (NumLoseFiles == 1)? "" : "s");
        if (NumMissFiles > 0)
            FPRINTF(stderr, LoadFarString(FileHadNoZipfileDir),
              NumMissFiles, (NumMissFiles == 1)? "" : "s");
        if (NumMissDirs == 1)
            FPRINTF(stderr, LoadFarString(ZipfileWasDir));
        else if (NumMissDirs > 0)
            FPRINTF(stderr, LoadFarString(ManyZipfilesWereDir), NumMissDirs);
        if (NumWinFiles + NumLoseFiles + NumWarnFiles == 0)
            FPRINTF(stderr, LoadFarString(NoZipfileFound));
    }
#endif /* !SFX */

    /* free allocated memory */
    inflate_free();
    checkdir((char *)NULL, END);
#ifndef SMALL_MEM
    if (outbuf2)
        free(outbuf2);   /* malloc'd ONLY if unshrink and -a */
#endif
    free(outbuf);
    free(inbuf);

    return error_in_archive;

} /* end function process_zipfiles() */





/**************************/
/* Function do_seekable() */
/**************************/

int do_seekable(lastchance)    /* return PK-type error code */
    int lastchance;
{
#ifndef SFX
    static int no_ecrec = FALSE;
    int maybe_exe=FALSE;
#endif
    int error=0, error_in_archive;


/*---------------------------------------------------------------------------
    Open the zipfile for reading in BINARY mode to prevent CR/LF translation,
    which would corrupt the bit streams.
  ---------------------------------------------------------------------------*/

    if (SSTAT(zipfn, &statbuf) || (error = S_ISDIR(statbuf.st_mode)) != 0) {
#ifndef SFX
        if (lastchance)
            if (no_ecrec)
                FPRINTF(stderr, LoadFarString(CantFindZipfileDirMsg),
                  zipinfo_mode? "zipinfo" : "unzip",
                  wildzipfn, zipinfo_mode? "  " : "",
#ifdef UNIX
                                                     wildzipfn,
#endif
                                                               zipfn);
            else
                FPRINTF(stderr,
                  LoadFarString(CantFindEitherZipfile),
                  zipinfo_mode? "zipinfo" : "unzip", wildzipfn,
#ifdef UNIX
                                                               wildzipfn,
#endif
                                                                         zipfn);
#endif /* !SFX */
        return error? IZ_DIR : PK_NOZIP;
    }
    ziplen = statbuf.st_size;

#ifndef SFX
#if defined(UNIX) || defined(DOS_NT_OS2)
    if (statbuf.st_mode & S_IEXEC)   /* no extension on Unix exec's:  might */
        maybe_exe = TRUE;            /*  find unzip, not unzip.zip; etc. */
#endif
#endif /* !SFX */

#ifdef VMS
    if (check_format())      /* check for variable-length format */
        return PK_ERR;
#endif

    if (open_input_file())   /* this should never happen, given */
        return PK_NOZIP;     /*  the stat() test above, but... */

/*---------------------------------------------------------------------------
    Find and process the end-of-central-directory header.  UnZip need only
    check last 65557 bytes of zipfile:  comment may be up to 65535, end-of-
    central-directory record is 18 bytes, and signature itself is 4 bytes;
    add some to allow for appended garbage.  Since ZipInfo is often used as
    a debugging tool, search the whole zipfile if zipinfo_mode is true.
  ---------------------------------------------------------------------------*/

    cur_zipfile_bufstart = 0;
    inptr = inbuf;

    if (!qflag && !zipinfo_mode)
        PRINTF("Archive:  %s\n", zipfn);

    if ((
#ifndef NO_ZIPINFO
         zipinfo_mode &&
          ((error_in_archive = find_ecrec(ziplen)) != 0 ||
          (error_in_archive = zi_end_central()) > PK_WARN))
        || (!zipinfo_mode &&
#endif
          ((error_in_archive = find_ecrec(MIN(ziplen,66000L))) != 0 ||
          (error_in_archive = uz_end_central()) > PK_WARN)))
    {
        close(zipfd);
#ifdef SFX
        ++lastchance;   /* avoid picky compiler warnings */
        return error_in_archive;
#else
        if (maybe_exe)
            FPRINTF(stderr, LoadFarString(MaybeExe), zipfn);
        if (lastchance)
            return error_in_archive;
        else {
            no_ecrec = TRUE;    /* assume we found wrong file:  e.g., */
            return PK_NOZIP;    /*  unzip instead of unzip.zip */
        }
#endif /* ?SFX */
    }

    if ((zflag > 0) && !zipinfo_mode) {   /* in unzip, zflag = comment ONLY */
        close(zipfd);
        return error_in_archive;
    }

/*---------------------------------------------------------------------------
    Test the end-of-central-directory info for incompatibilities (multi-disk
    archives) or inconsistencies (missing or extra bytes in zipfile).
  ---------------------------------------------------------------------------*/

#ifdef NO_MULTIPART
    error = !zipinfo_mode && (ecrec.number_this_disk == 1) &&
            (ecrec.num_disk_with_start_central_dir == 1);
#else
    error = !zipinfo_mode && (ecrec.number_this_disk != 0);
#endif

#ifndef SFX
    if (zipinfo_mode &&
        ecrec.number_this_disk != ecrec.num_disk_with_start_central_dir)
    {
        FPRINTF(stderr, LoadFarString(CentDirNotInZipMsg));
        error_in_archive = PK_FIND;
#ifdef NO_MULTIPART   /* concatenation of multiple parts works in some cases */
    } else if (!zipinfo_mode && !error && ecrec.number_this_disk != 0) {
        FPRINTF(stderr, LoadFarString(NoMultiDiskArcSupport), zipfn);
        error_in_archive = PK_FIND;
#endif
    } else {   /* this is a (relatively) normal zipfile:  process normally */
        if (error) {
            FPRINTF(stderr, LoadFarString(MaybePakBug), zipfn);
            error_in_archive = PK_WARN;
        }
#endif
        if ((extra_bytes = real_ecrec_offset-expect_ecrec_offset) < (LONGINT)0)
        {
            FPRINTF(stderr, LoadFarString(MissingBytes), zipfn,
              (long)(-extra_bytes));
            error_in_archive = PK_ERR;
        } else if (extra_bytes > 0) {
            if ((ecrec.offset_start_central_directory == 0) &&
                (ecrec.size_central_directory != 0))   /* zip 1.5 -go bug */
            {
                FPRINTF(stderr, LoadFarString(NullCentDirOffset), zipfn);
                ecrec.offset_start_central_directory = extra_bytes;
                extra_bytes = 0;
                error_in_archive = PK_ERR;
            }
#ifndef SFX
            else {
                FPRINTF(stderr, LoadFarString(ExtraBytesAtStart), zipfn,
                  (long)extra_bytes);
                error_in_archive = PK_WARN;
            }
#endif
        }

    /*-----------------------------------------------------------------------
        Check for empty zipfile and exit now if so.
      -----------------------------------------------------------------------*/

        if (expect_ecrec_offset == 0L  &&  ecrec.size_central_directory == 0) {
            if (zipinfo_mode)
                PRINTF("%sEmpty zipfile.\n", lflag>9 ? "\n  " : "");
            else
                FPRINTF(stderr, LoadFarString(ZipfileEmpty), zipfn);
            close(zipfd);
            return (error_in_archive > PK_WARN)? error_in_archive : PK_WARN;
        }

    /*-----------------------------------------------------------------------
        Compensate for missing or extra bytes, and seek to where the start
        of central directory should be.  If header not found, uncompensate
        and try again (necessary for at least some Atari archives created
        with STZip, as well as archives created by J.H. Holm's ZIPSPLIT 1.1).
      -----------------------------------------------------------------------*/

        LSEEK( ecrec.offset_start_central_directory )
#ifdef OLD_SEEK_TEST
        if (readbuf(sig, 4) == 0) {
            close(zipfd);
            return PK_ERR;  /* file may be locked, or possibly disk error(?) */
        }
        if (strncmp(sig, central_hdr_sig, 4))
#else
        if ((readbuf(sig, 4) == 0) || strncmp(sig, central_hdr_sig, 4))
#endif
        {
            long tmp = extra_bytes;

            extra_bytes = 0;
            LSEEK( ecrec.offset_start_central_directory )
            if ((readbuf(sig, 4) == 0) || strncmp(sig, central_hdr_sig, 4)) {
                FPRINTF(stderr, LoadFarString(CentDirStartNotFound), zipfn,
                  LoadFarStringSmall(ReportMsg));
                close(zipfd);
                return PK_BADERR;
            }
            FPRINTF(stderr, LoadFarString(CentDirTooLong), zipfn, -tmp);
            error_in_archive = PK_ERR;
        }

    /*-----------------------------------------------------------------------
        Seek to the start of the central directory one last time, since we
        have just read the first entry's signature bytes; then list, extract
        or test member files as instructed, and close the zipfile.
      -----------------------------------------------------------------------*/

        Trace((stderr, "about to extract/list files (error = %d)\n",
          error_in_archive));

        LSEEK( ecrec.offset_start_central_directory )

#ifndef NO_ZIPINFO
        if (zipinfo_mode) {
            error = zipinfo();                     /* ZIPINFO 'EM */
            if (lflag > 9)
                PRINTF("\n");
        } else
#endif
#ifndef SFX
            if (vflag && !tflag && !cflag)
                error = list_files();              /* LIST 'EM */
            else
#endif
                error = extract_or_test_files();   /* EXTRACT OR TEST 'EM */

        Trace((stderr, "done with extract/list files (error = %d)\n", error));

        if (error > error_in_archive)   /* don't overwrite stronger error */
            error_in_archive = error;   /*  with (for example) a warning */
#ifndef SFX
    }
#endif

    close(zipfd);
    return error_in_archive;

} /* end function do_seekable() */





/*****************************/
/* Function uz_end_central() */
/*****************************/

int uz_end_central()    /* return PK-type error code */
{
    int error = PK_COOL;


/*---------------------------------------------------------------------------
    Get the zipfile comment (up to 64KB long), if any, and print it out.
    Then position the file pointer to the beginning of the central directory
    and fill buffer.
  ---------------------------------------------------------------------------*/

#ifdef MSWIN
    cchComment = ecrec.zipfile_comment_length; /* save for comment button */
    if (ecrec.zipfile_comment_length && (zflag > 0))
#else
    if (ecrec.zipfile_comment_length && (zflag > 0 || (zflag == 0 && !qflag)))
#endif
    {
#if 0
#ifndef MSWIN
        if (zflag == 0)       (add "&& single_zipfile" perhaps; unnecessary with
            PRINTF("[%s] comment:\n", zipfn);  multiple zipfiles: "Archive:...")
#endif /* !MSWIN */
#endif /* 0 */
        if (do_string(ecrec.zipfile_comment_length,DISPLAY)) {
            FPRINTF(stderr, LoadFarString(ZipfileCommTrunc1));
            error = PK_WARN;
        }
    }
    return error;

} /* end function uz_end_central() */





/************************************/
/* Function process_cdir_file_hdr() */
/************************************/

int process_cdir_file_hdr()    /* return PK-type error code */
{
    int error;


/*---------------------------------------------------------------------------
    Get central directory info, save host and method numbers, and set flag
    for lowercase conversion of filename, depending on the OS from which the
    file is coming.
  ---------------------------------------------------------------------------*/

    if ((error = get_cdir_ent()) != 0)
        return error;

    pInfo->hostnum = MIN(crec.version_made_by[1], NUM_HOSTS);
/*  extnum = MIN(crec.v

⌨️ 快捷键说明

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