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

📄 zipinfo.c

📁 汇编大全 中国矿业大学计算机学院 汇编实验5
💻 C
📖 第 1 页 / 共 4 页
字号:
        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 end-    of-central-directory header and the central directory; 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 (ecrec.number_this_disk == ecrec.num_disk_with_start_central_dir) {        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");                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 ((error = process_central_dir()) > error_in_archive)            error_in_archive = error;    /* don't overwrite stronger error */        if (lflag > 9)            printf("\n");    } else {        fprintf(stderr, "\n\     Zipfile is part of a multi-disk archive, and this is not the disk on\     which the central zipfile directory begins.\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,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(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,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(inptr, end_central_sig, 4) ) {                    incnt -= inptr - inbuf;                    return(0);  /* found it! */                }               /* ...otherwise search next block */            strncpy(hold, 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.         *          * zipinfo:  check the whole file, just in case some transfer protocol         * has appended a whole bunch of garbage at the end of the archive.         */#ifndef ZIPINFO        /*         ==amt to search==   ==done==   ==rounding==    =blksiz= */        numblks = (min(ziplen,65557) - tail_len + (INBUFSIZ-1)) / INBUFSIZ;#else        numblks = (    ziplen        - tail_len + (INBUFSIZ-1)) / INBUFSIZ;#endif        for ( i = 1  ;  i <= numblks  ;  ++i ) {            cur_zipfile_bufstart -= INBUFSIZ;            lseek(zipfd, cur_zipfile_bufstart, SEEK_SET);            if ((incnt = read(zipfd,inbuf,INBUFSIZ)) != INBUFSIZ)                break;          /* fall through and fail */            for ( inptr = inbuf+INBUFSIZ-1  ;  inptr >= inbuf  ;  --inptr )                if ( (ascii_to_native(*inptr) == 'P')  &&                      !strncmp(inptr, end_central_sig, 4) ) {                    incnt -= inptr - inbuf;                    return(0);  /* found it! */                }            strncpy(hold, 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, "\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");    return(1);          /* failed */}       /* 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    copying character array 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]);/*---------------------------------------------------------------------------    Print out various interesting things about the zipfile.  ---------------------------------------------------------------------------*/    if (lflag == 2) {        if (process_all_files)           /* fits on one line, for anything up to 10GB and 10000 files */           printf((strlen(zipfn)<39)? "Archive:  %s   %ld bytes   %d file%s\n"             : "Archive:  %s   %ld   %d\n", zipfn, ziplen,             ecrec.total_entries_central_dir,             (ecrec.total_entries_central_dir==1)? "":"s");    } else if (lflag > 9) {   /* verbose format */        printf("\nEnd-of-central-directory record:\n");        printf("-------------------------------\n\n");        if (ecrec.number_this_disk == 0) {            printf("\  This zipfile constitutes the sole disk of a single-part archive; its\n\  central directory contains %u %s.  The central directory is %lu\n\  (%.8lXh) bytes long, and its offset in bytes from the beginning of\n\  the zipfile is %lu (%.8lXh).\n\n",              ecrec.total_entries_central_dir,              (ecrec.total_entries_central_dir == 1)? "entry" : "entries",              ecrec.size_central_directory, ecrec.size_central_directory,              ecrec.offset_start_central_directory,              ecrec.offset_start_central_directory);        } else {            printf("\  This zipfile constitutes disk %u of a multi-part archive.  The central\n\  directory starts on disk %u; %u of its entries %s contained within\n\  this zipfile, out of a total of %u %s.  The entire central\n\  directory is %lu (%.8lXh) bytes long, and its offset in bytes from\n\  the beginning of the zipfile in which it begins is %lu (%.8lXh).\n\n",              ecrec.number_this_disk,              ecrec.num_disk_with_start_central_dir,              ecrec.num_entries_centrl_dir_ths_disk,              (ecrec.num_entries_centrl_dir_ths_disk == 1)? "is" : "are",              ecrec.total_entries_central_dir,              (ecrec.total_entries_central_dir == 1) ? "entry" : "entries",              ecrec.size_central_directory, ecrec.size_central_directory,              ecrec.offset_start_central_directory,              ecrec.offset_start_central_directory);        }    /*-----------------------------------------------------------------------        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 arm-        pits of anyone who actually takes advantage of this fact.)      -----------------------------------------------------------------------*/        if (!ecrec.zipfile_comment_length)            printf("  There is no zipfile comment.\n");        else {            printf("  The zipfile comment is %u bytes long and contains the following text:\n\n",              ecrec.zipfile_comment_length );            printf("======================== zipfile comment begins ==========================\n");            if (do_string(ecrec.zipfile_comment_length, DISPLAY))                error = 1;          /* 1:  warning error */            printf("\n========================= zipfile comment ends ===========================\n");            if (error)                printf("\n  The zipfile comment is truncated.\n");        } /* endif (comment exists) */    } /* endif (verbose) */    return error;}       /* end function process_end_central_dir() *//******************************************//*  Function process_central_directory()  *//******************************************/int process_central_dir()   /* return PK-type error code */{    char    **fnamev;    int     do_this_file=FALSE, none_found=TRUE, error, error_in_archive=0;    UWORD   j, members=0;    ULONG   tot_csize=0L, tot_ucsize=0L;/*---------------------------------------------------------------------------    Set file pointer to start of central directory, then loop through cen-    tral directory entries.  Check that directory-entry signature bytes are    actually there (just a precaution), then process the entry.  We know    the entire central directory is on this disk:  we wouldn't have any of    this information unless the end-of-central-directory record was on this    disk, and we wouldn't have gotten to this routine unless this is also    the disk on which the central directory starts.  In practice, this had    better be the *only* disk in the archive, but maybe someday we'll add    multi-disk support.  ---------------------------------------------------------------------------*/    pInfo->lcflag = 0;   /* match(), do_string():  never TRUE in zipinfo */    for (j = 0;  j < ecrec.total_entries_central_dir;  ++j) {        if (readbuf(sig, 4) <= 0)            return (51);        /* 51:  unexpected EOF */        if (strncmp(sig, central_hdr_sig, 4)) {  /* just to make sure */            fprintf(stderr, CentSigMsg, j);  /* sig not found */            return (3);         /* 3:  error in zipfile */        }        if ((error = process_cdir_file_hdr()) != 0)            return (error);     /* only 51 (EOF) defined */        if ((error = do_string(crec.filename_length, FILENAME)) != 0) {          error_in_archive = error;   /* might be warning */          if (error > 1)        /* fatal */              return (error);        }        if (!process_all_files) {   /* check if specified on command line */            do_this_file = FALSE;            fnamev = fnv;       /* don't destroy permanent filename ptr */            for (--fnamev;  *++fnamev; )                if (match(filename, *fnamev)) {                    do_this_file = TRUE;                    none_found = FALSE;                    break;      /* found match, so stop looping */                }        }    /*-----------------------------------------------------------------------        If current file was specified on command line, or if no names were

⌨️ 快捷键说明

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