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

📄 unzip.c

📁 汇编语言程序的编写虽然有一定的难度,但是它是一门低级的语言,有很强的基础性作用,具有广泛的用途.
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifdef VMS    {        int rtype;        VMSmunch(zipfn, GET_RTYPE, (char *)&rtype);        if (rtype == FAT$C_VARIABLE) {            fprintf(stderr,     "\n     Error:  zipfile is in variable-length record format.  Please\n\     run \"bilf l %s\" to convert the zipfile to stream-LF\n\     record format.  (Bilf.exe, bilf.c and make_bilf.com are included\n\     in the VMS unzip distribution.)\n\n", zipfn);            return 2;           /* 2:  error in zipfile */        }        rtype = FAT$C_STREAMLF; /* Unix I/O loves it */        VMSmunch(zipfn, CHANGE_RTYPE, (char *)&rtype);    }#endif    if (open_input_file())      /* this should never happen, given the */        return (9);             /*   stat() test in main(), but... *//*---------------------------------------------------------------------------    Reconstruct the various PK signature strings; find and process the cen-    tral directory; list, extract or test member files as instructed; and    close the zipfile.  ---------------------------------------------------------------------------*/    strcat(local_hdr_sig, LOCAL_HDR_SIG);    strcat(central_hdr_sig, CENTRAL_HDR_SIG);    strcat(end_central_sig, END_CENTRAL_SIG);    if (find_end_central_dir()) /* not found; nothing to do */        return (2);             /* 2:  error in zipfile */    real_ecrec_offset = cur_zipfile_bufstart+(inptr-inbuf);#ifdef TEST    printf("\n  found end-of-central-dir signature at offset %ld (%.8lXh)\n",      real_ecrec_offset, real_ecrec_offset);    printf("    from beginning of file; offset %d (%.4Xh) within block\n",      inptr-inbuf, inptr-inbuf);#endif    if ((error_in_archive = process_end_central_dir()) > 1)        return (error_in_archive);    if (zflag)        return (0);#ifndef PAKFIX    if (ecrec.number_this_disk == 0) {#else /* PAKFIX */    if ((ecrec.number_this_disk == 0)  ||        (error = ((ecrec.number_this_disk == 1) &&                  (ecrec.num_disk_with_start_central_dir == 1)) )) {        if (error) {            fprintf(stderr,     "\n     Warning:  zipfile claims to be disk 2 of a two-part archive;\n\     attempting to process anyway.  If no further errors occur, this\n\     archive was probably created by PAK v2.5 or earlier.  This bug\n\     was reported to NoGate and should have been fixed by mid-1991.\n\n");            error_in_archive = 1;  /* 1:  warning */        }#endif /* ?PAKFIX */        expect_ecrec_offset = ecrec.offset_start_central_directory +                              ecrec.size_central_directory;        if ((extra_bytes = real_ecrec_offset - expect_ecrec_offset) < 0) {            fprintf(stderr, "\nerror:  missing %ld bytes in zipfile (\attempting to process anyway)\n\n", -extra_bytes);            error_in_archive = 2;       /* 2:  (weak) error in zipfile */        } else if (extra_bytes > 0) {            if ((ecrec.offset_start_central_directory == 0) &&                (ecrec.size_central_directory != 0))   /* zip 1.5 -go bug */            {                fprintf(stderr, "\nerror:  NULL central directory offset (\attempting to process anyway)\n\n");                ecrec.offset_start_central_directory = extra_bytes;                extra_bytes = 0;                error_in_archive = 2;   /* 2:  (weak) error in zipfile */            } else {                fprintf(stderr, "\nwarning:  extra %ld bytes at beginning or\ within zipfile\n          (attempting to process anyway)\n\n", extra_bytes);                error_in_archive = 1;   /* 1:  warning error */            }        }        LSEEK( ecrec.offset_start_central_directory )        if (vflag)            error = list_files();               /* LIST 'EM */        else            error = extract_or_test_files();    /* EXTRACT OR TEST 'EM */        if (error > error_in_archive)   /* don't overwrite stronger error */            error_in_archive = error;   /*  with (for example) a warning */    } else {        fprintf(stderr, "\nerror:  zipfile is part of multi-disk archive \(sorry, not supported).\n");        fprintf(stderr, "Please report to zip-bugs@cs.ucla.edu\n");        error_in_archive = 11;  /* 11:  no files found */    }    close(zipfd);#ifdef VMS    VMSmunch(zipfn, RESTORE_RTYPE, NULL);#endif    return (error_in_archive);}       /* end function process_zipfile() *//************************************//*  Function find_end_central_dir() *//************************************/int find_end_central_dir()/* return 0 if found, 1 otherwise */{    int i, numblks;    longint tail_len;/*---------------------------------------------------------------------------    Treat case of short zipfile separately.  ---------------------------------------------------------------------------*/    if (ziplen <= INBUFSIZ) {        lseek(zipfd, 0L, SEEK_SET);        if ((incnt = read(zipfd,(char *)inbuf,(unsigned int)ziplen)) == ziplen)            /* 'P' must be at least 22 bytes from end of zipfile */            for ( inptr = inbuf+ziplen-22  ;  inptr >= inbuf  ;  --inptr )                if ( (ascii_to_native(*inptr) == 'P')  &&                      !strncmp((char *)inptr, end_central_sig, 4) ) {                    incnt -= inptr - inbuf;                    return(0);  /* found it! */                }               /* ...otherwise fall through & fail *//*---------------------------------------------------------------------------    Zipfile is longer than INBUFSIZ:  may need to loop.  Start with short    block at end of zipfile (if not TOO short).  ---------------------------------------------------------------------------*/    } else {        if ((tail_len = ziplen % INBUFSIZ) > ECREC_SIZE) {            cur_zipfile_bufstart = lseek(zipfd, ziplen-tail_len, SEEK_SET);            if ((incnt = read(zipfd,(char *)inbuf,(unsigned int)tail_len)) != tail_len)                goto fail;      /* shut up, it's expedient. */            /* 'P' must be at least 22 bytes from end of zipfile */            for ( inptr = inbuf+tail_len-22  ;  inptr >= inbuf  ;  --inptr )                if ( (ascii_to_native(*inptr) == 'P')  &&                      !strncmp((char *)inptr, end_central_sig, 4) ) {                    incnt -= inptr - inbuf;                    return(0);  /* found it! */                }               /* ...otherwise search next block */            strncpy((char *)hold, (char *)inbuf, 3);    /* sig may span block                                                           boundary */        } else {            cur_zipfile_bufstart = ziplen - tail_len;        }        /*         * Loop through blocks of zipfile data, starting at the end and going         * toward the beginning.  Need only check last 65557 bytes of zipfile:         * comment may be up to 65535 bytes long, end-of-central-directory rec-         * ord is 18 bytes (shouldn't hardcode this number, but what the hell:         * already did so above (22=18+4)), and sig itself is 4 bytes.         */        /*          ==amt to search==   ==done==   ==rounding==     =blksiz= */        numblks = ( min(ziplen,65557) - tail_len + (INBUFSIZ-1) ) / INBUFSIZ;        for ( i = 1  ;  i <= numblks  ;  ++i ) {            cur_zipfile_bufstart -= INBUFSIZ;            lseek(zipfd, cur_zipfile_bufstart, SEEK_SET);            if ((incnt = read(zipfd,(char *)inbuf,INBUFSIZ)) != INBUFSIZ)                break;          /* fall through and fail */            for ( inptr = inbuf+INBUFSIZ-1  ;  inptr >= inbuf  ;  --inptr )                if ( (ascii_to_native(*inptr) == 'P')  &&                      !strncmp((char *)inptr, end_central_sig, 4) ) {                    incnt -= inptr - inbuf;                    return(0);  /* found it! */                }            strncpy((char *)hold, (char *)inbuf, 3);    /* sig may span block                                                           boundary */        }    } /* end if (ziplen > INBUFSIZ) *//*---------------------------------------------------------------------------    Searched through whole region where signature should be without finding    it.  Print informational message and die a horrible death.  ---------------------------------------------------------------------------*/fail:    fprintf(stderr, "\nFile:  %s\n\n\     End-of-central-directory signature not found.  Either this file is not\n\     a zipfile, or it constitutes one disk of a multi-part archive.  In the\n\     latter case the central directory and zipfile comment will be found on\n\     the last disk(s) of this archive.\n", zipfn);    return(1);}       /* end function find_end_central_dir() *//***************************************//*  Function process_end_central_dir() *//***************************************/int process_end_central_dir()    /* return PK-type error code */{    ec_byte_rec byterec;    int error=0;/*---------------------------------------------------------------------------    Read the end-of-central-directory record and do any necessary machine-    type conversions (byte ordering, structure padding compensation) by    reading data into character array, then copying to struct.  ---------------------------------------------------------------------------*/    if (readbuf((char *) byterec, ECREC_SIZE+4) <= 0)        return (51);    ecrec.number_this_disk =        makeword(&byterec[NUMBER_THIS_DISK]);    ecrec.num_disk_with_start_central_dir =        makeword(&byterec[NUM_DISK_WITH_START_CENTRAL_DIR]);    ecrec.num_entries_centrl_dir_ths_disk =        makeword(&byterec[NUM_ENTRIES_CENTRL_DIR_THS_DISK]);    ecrec.total_entries_central_dir =        makeword(&byterec[TOTAL_ENTRIES_CENTRAL_DIR]);    ecrec.size_central_directory =        makelong(&byterec[SIZE_CENTRAL_DIRECTORY]);    ecrec.offset_start_central_directory =        makelong(&byterec[OFFSET_START_CENTRAL_DIRECTORY]);    ecrec.zipfile_comment_length =        makeword(&byterec[ZIPFILE_COMMENT_LENGTH]);/*---------------------------------------------------------------------------    Get the zipfile comment, if any, and print it out.  (Comment may be up    to 64KB long.  May the fleas of a thousand camels infest the armpits of    anyone who actually takes advantage of this fact.)  Then position the    file pointer to the beginning of the central directory and fill buffer.  ---------------------------------------------------------------------------*/    if (ecrec.zipfile_comment_length && !quietflg) {        if (!zflag)          printf("[%s] comment:\n", zipfn);        if (do_string(ecrec.zipfile_comment_length,DISPLAY)) {            fprintf(stderr, "\ncaution:  zipfile comment truncated\n");            error = 1;          /* 1:  warning error */        }#if 0        if (!zflag)          printf("\n\n");       /* what the heck is this doing here?! */#endif    }    return (error);}       /* end function process_end_central_dir() *//**************************//*  Function list_files() *//**************************/int list_files()    /* return PK-type error code */{    char **fnamev;    int do_this_file=FALSE, ratio, error, error_in_archive=0;    int which_hdr=(vflag>1);    UWORD j, yr, mo, dy, hh, mm, members=0;    ULONG tot_csize=0L, tot_ucsize=0L;    min_info info;    static char *method[NUM_METHODS+1] =        {"Stored", "Shrunk", "Reduce1", "Reduce2", "Reduce3", "Reduce4",         "Implode", "Token", "Deflate", unkn};    static char *Headers[][2] = {        {" Length    Date    Time    Name",         " ------    ----    ----    ----"},        {" Length  Method   Size  Ratio   Date    Time   CRC-32     Name",         " ------  ------   ----  -----   ----    ----   ------     ----"}    };/*---------------------------------------------------------------------------

⌨️ 快捷键说明

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