📄 process.c
字号:
case VMS_: /* our Zip uses lowercase, but ASi's doesn't */ /* case Z_SYSTEM_: ? */ /* case QDOS_: ? */ G.pInfo->lcflag = 1; /* convert filename to lowercase */ break; default: /* AMIGA_, FS_HPFS_, FS_NTFS_, MAC_, UNIX_, ATARI_, */ break; /* FS_VFAT_, BEOS_ (Z_SYSTEM_): no conversion */ } /* do Amigas (AMIGA_) also have volume labels? */ if (IS_VOLID(G.crec.external_file_attributes) && (G.pInfo->hostnum == FS_FAT_ || G.pInfo->hostnum == FS_HPFS_ || G.pInfo->hostnum == FS_NTFS_ || G.pInfo->hostnum == ATARI_)) { G.pInfo->vollabel = TRUE; G.pInfo->lcflag = 0; /* preserve case of volume labels */ } else G.pInfo->vollabel = FALSE; return PK_COOL;} /* end function process_cdir_file_hdr() *//***************************//* Function get_cdir_ent() *//***************************/int get_cdir_ent(__G) /* return PK-type error code */ __GDEF{ cdir_byte_hdr byterec;/*--------------------------------------------------------------------------- Read the next central directory entry and do any necessary machine-type conversions (byte ordering, structure padding compensation--do so by copying the data from the array into which it was read (byterec) to the usable struct (crec)). ---------------------------------------------------------------------------*/ if (readbuf(__G__ (char *)byterec, CREC_SIZE) == 0) return PK_EOF; G.crec.version_made_by[0] = byterec[C_VERSION_MADE_BY_0]; G.crec.version_made_by[1] = byterec[C_VERSION_MADE_BY_1]; G.crec.version_needed_to_extract[0] = byterec[C_VERSION_NEEDED_TO_EXTRACT_0]; G.crec.version_needed_to_extract[1] = byterec[C_VERSION_NEEDED_TO_EXTRACT_1]; G.crec.general_purpose_bit_flag = makeword(&byterec[C_GENERAL_PURPOSE_BIT_FLAG]); G.crec.compression_method = makeword(&byterec[C_COMPRESSION_METHOD]); G.crec.last_mod_dos_datetime = makelong(&byterec[C_LAST_MOD_DOS_DATETIME]); G.crec.crc32 = makelong(&byterec[C_CRC32]); G.crec.csize = makelong(&byterec[C_COMPRESSED_SIZE]); G.crec.ucsize = makelong(&byterec[C_UNCOMPRESSED_SIZE]); G.crec.filename_length = makeword(&byterec[C_FILENAME_LENGTH]); G.crec.extra_field_length = makeword(&byterec[C_EXTRA_FIELD_LENGTH]); G.crec.file_comment_length = makeword(&byterec[C_FILE_COMMENT_LENGTH]); G.crec.disk_number_start = makeword(&byterec[C_DISK_NUMBER_START]); G.crec.internal_file_attributes = makeword(&byterec[C_INTERNAL_FILE_ATTRIBUTES]); G.crec.external_file_attributes = makelong(&byterec[C_EXTERNAL_FILE_ATTRIBUTES]); /* LONG, not word! */ G.crec.relative_offset_local_header = makelong(&byterec[C_RELATIVE_OFFSET_LOCAL_HEADER]); return PK_COOL;} /* end function get_cdir_ent() *//*************************************//* Function process_local_file_hdr() *//*************************************/int process_local_file_hdr(__G) /* return PK-type error code */ __GDEF{ local_byte_hdr byterec;/*--------------------------------------------------------------------------- Read the next local file header and do any necessary machine-type con- versions (byte ordering, structure padding compensation--do so by copy- ing the data from the array into which it was read (byterec) to the usable struct (lrec)). ---------------------------------------------------------------------------*/ if (readbuf(__G__ (char *)byterec, LREC_SIZE) == 0) return PK_EOF; G.lrec.version_needed_to_extract[0] = byterec[L_VERSION_NEEDED_TO_EXTRACT_0]; G.lrec.version_needed_to_extract[1] = byterec[L_VERSION_NEEDED_TO_EXTRACT_1]; G.lrec.general_purpose_bit_flag = makeword(&byterec[L_GENERAL_PURPOSE_BIT_FLAG]); G.lrec.compression_method = makeword(&byterec[L_COMPRESSION_METHOD]); G.lrec.last_mod_dos_datetime = makelong(&byterec[L_LAST_MOD_DOS_DATETIME]); G.lrec.crc32 = makelong(&byterec[L_CRC32]); G.lrec.csize = makelong(&byterec[L_COMPRESSED_SIZE]); G.lrec.ucsize = makelong(&byterec[L_UNCOMPRESSED_SIZE]); G.lrec.filename_length = makeword(&byterec[L_FILENAME_LENGTH]); G.lrec.extra_field_length = makeword(&byterec[L_EXTRA_FIELD_LENGTH]); G.csize = (long) G.lrec.csize; G.ucsize = (long) G.lrec.ucsize; if ((G.lrec.general_purpose_bit_flag & 8) != 0) { /* can't trust local header, use central directory: */ G.lrec.crc32 = G.pInfo->crc; G.csize = (long)(G.lrec.csize = G.pInfo->compr_size); G.ucsize = (long)(G.lrec.ucsize = G.pInfo->uncompr_size); } return PK_COOL;} /* end function process_local_file_hdr() */#ifdef USE_EF_UT_TIME/*******************************//* Function ef_scan_for_izux() *//*******************************/unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos_mdatetime, z_utim, z_uidgid) uch *ef_buf; /* buffer containing extra field */ unsigned ef_len; /* total length of extra field */ int ef_is_c; /* flag indicating "is central extra field" */ ulg dos_mdatetime; /* last_mod_file_date_time in DOS format */ iztimes *z_utim; /* return storage: atime, mtime, ctime */ ush *z_uidgid; /* return storage: uid and gid */{ unsigned flags = 0; unsigned eb_id; unsigned eb_len; int have_new_type_eb = FALSE; int ut_zip_unzip_compatible = FALSE;/*--------------------------------------------------------------------------- This function scans the extra field for EF_TIME, EF_IZUNIX2, EF_IZUNIX, or EF_PKUNIX blocks containing Unix-style time_t (GMT) values for the entry's access, creation, and modification time. If a valid block is found, the time stamps are copied to the iztimes structure (provided the z_utim pointer is not NULL). If a IZUNIX2 block is found or the IZUNIX block contains UID/GID fields, and the z_uidgid array pointer is valid (!= NULL), the owner info is transfered as well. The presence of an EF_TIME or EF_IZUNIX2 block results in ignoring all data from probably present obsolete EF_IZUNIX blocks. If multiple blocks of the same type are found, only the information from the last block is used. The return value is a combination of the EF_TIME Flags field with an additional flag bit indicating the presence of valid UID/GID info, or 0 in case of failure. ---------------------------------------------------------------------------*/ if (ef_len == 0 || ef_buf == NULL || (z_utim == 0 && z_uidgid == NULL)) return 0; TTrace((stderr,"\nef_scan_for_izux: scanning extra field of length %u\n", ef_len)); while (ef_len >= EB_HEADSIZE) { eb_id = makeword(EB_ID + ef_buf); eb_len = makeword(EB_LEN + ef_buf); if (eb_len > (ef_len - EB_HEADSIZE)) { /* discovered some extra field inconsistency! */ TTrace((stderr, "ef_scan_for_izux: block length %u > rest ef_size %u\n", eb_len, ef_len - EB_HEADSIZE)); break; } switch (eb_id) { case EF_TIME: flags &= ~0x0ff; /* ignore previous IZUNIX or EF_TIME fields */ have_new_type_eb = TRUE; if ( eb_len >= EB_UT_MINLEN && z_utim != NULL) { unsigned eb_idx = EB_UT_TIME1; TTrace((stderr,"ef_scan_for_izux: found TIME extra field\n")); flags |= (ef_buf[EB_HEADSIZE+EB_UT_FLAGS] & 0x0ff); if ((flags & EB_UT_FL_MTIME)) { if ((eb_idx+4) <= eb_len) { z_utim->mtime = makelong((EB_HEADSIZE+eb_idx) + ef_buf); eb_idx += 4; TTrace((stderr," UT e.f. modification time = %ld\n", z_utim->mtime)); if ((ulg)(z_utim->mtime) & (ulg)(0x80000000L)) { ut_zip_unzip_compatible = ((time_t)0x80000000L < (time_t)0L) ? (dos_mdatetime == DOSTIME_MINIMUM) : (dos_mdatetime >= DOSTIME_2038_01_18); if (!ut_zip_unzip_compatible) { /* UnZip interpretes mtime differently than Zip; without modtime: ignore complete UT field */ flags &= ~0x0ff; /* no time_t times available */ TTrace((stderr, " UT modtime range error; ignore e.f.!\n")); break; /* stop scanning this field */ } } else { /* cannot determine, safe assumption is FALSE */ ut_zip_unzip_compatible = FALSE; } } else { flags &= ~EB_UT_FL_MTIME; TTrace((stderr," UT e.f. truncated; no modtime\n")); } } if (ef_is_c) { break; /* central version of TIME field ends here */ } if (flags & EB_UT_FL_ATIME) { if ((eb_idx+4) <= eb_len) { z_utim->atime = makelong((EB_HEADSIZE+eb_idx) + ef_buf); eb_idx += 4; TTrace((stderr," UT e.f. access time = %ld\n", z_utim->atime)); if (((ulg)(z_utim->atime) & (ulg)(0x80000000L)) && !ut_zip_unzip_compatible) { flags &= ~EB_UT_FL_ATIME; TTrace((stderr, " UT access time range error: skip time!\n")); } } else { flags &= ~EB_UT_FL_ATIME; } } if (flags & EB_UT_FL_CTIME) { if ((eb_idx+4) <= eb_len) { z_utim->ctime = makelong((EB_HEADSIZE+eb_idx) + ef_buf); TTrace((stderr," UT e.f. creation time = %ld\n", z_utim->ctime)); if (((ulg)(z_utim->ctime) & (ulg)(0x80000000L)) && !ut_zip_unzip_compatible) { flags &= ~EB_UT_FL_CTIME; TTrace((stderr, " UT creation time range error: skip time!\n")); } } else { flags &= ~EB_UT_FL_CTIME; } } } break; case EF_IZUNIX2: if (!have_new_type_eb) { flags &= ~0x0ff; /* ignore any previous IZUNIX field */ have_new_type_eb = TRUE; } if (eb_len >= EB_UX2_MINLEN && z_uidgid != NULL) { z_uidgid[0] = makeword((EB_HEADSIZE+EB_UX2_UID) + ef_buf); z_uidgid[1] = makeword((EB_HEADSIZE+EB_UX2_GID) + ef_buf); flags |= EB_UX2_VALID; /* signal success */ } break; case EF_IZUNIX: case EF_PKUNIX: /* PKUNIX e.f. layout is identical to IZUNIX */ if (eb_len >= EB_UX_MINLEN) { TTrace((stderr,"ef_scan_for_izux: found %s extra field\n", (eb_id == EF_IZUNIX ? "IZUNIX" : "PKUNIX"))); if (have_new_type_eb) { break; /* Ignore IZUNIX extra field block ! */ } if (z_utim != NULL) { z_utim->atime = makelong((EB_HEADSIZE+EB_UX_ATIME)+ef_buf); z_utim->mtime = makelong((EB_HEADSIZE+EB_UX_MTIME)+ef_buf); TTrace((stderr," Unix EF actime = %ld\n", z_utim->atime)); TTrace((stderr," Unix EF modtime = %ld\n", z_utim->mtime)); flags |= (EB_UT_FL_MTIME | EB_UT_FL_ATIME); if ((ulg)(z_utim->mtime) & (ulg)(0x80000000L)) { ut_zip_unzip_compatible = ((time_t)0x80000000L < (time_t)0L) ? (dos_mdatetime == DOSTIME_MINIMUM) : (dos_mdatetime >= DOSTIME_2038_01_18); if (!ut_zip_unzip_compatible) { /* UnZip interpretes mtime differently than Zip; without modtime: ignore complete UT field */ flags &= ~0x0ff; /* no time_t times available */ TTrace((stderr, " UX modtime range error: ignore e.f.!\n")); } } else { /* cannot determine, safe assumption is FALSE */ ut_zip_unzip_compatible = FALSE; } if ((ulg)(z_utim->atime) & (ulg)(0x80000000L) && !ut_zip_unzip_compatible && (flags & 0x0ff)) { /* atime not in range of UnZip's time_t */ flags &= ~EB_UT_FL_ATIME; TTrace((stderr, " UX access time range error: skip time!\n")); } } if (eb_len >= EB_UX_FULLSIZE && z_uidgid != NULL) { z_uidgid[0] = makeword((EB_HEADSIZE+EB_UX_UID) + ef_buf); z_uidgid[1] = makeword((EB_HEADSIZE+EB_UX_GID) + ef_buf); flags |= EB_UX2_VALID; } } break; default: break; } /* Skip this extra field block */ ef_buf += (eb_len + EB_HEADSIZE); ef_len -= (eb_len + EB_HEADSIZE); } return flags;}#endif /* USE_EF_UT_TIME */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -