#define UNZIP_INTERNAL
#include "unzip.h"
#ifdef WINDLL
# ifdef POCKET_UNZIP
# include "wince/intrface.h"
# else
# include "windll/windll.h"
# endif
#endif
#ifdef TIMESTAMP
static int fn_is_dir OF((__GPRO));
#endif
#ifndef WINDLL
static ZCONST char Far CompFactorStr[] = "%c%d%%";
static ZCONST char Far CompFactor100[] = "100%%";
#ifdef OS2_EAS
static ZCONST char Far HeadersS[] =
" Length EAs ACLs Date Time Name";
static ZCONST char Far HeadersS1[] =
" -------- --- ---- ---- ---- ----";
#else
static ZCONST char Far HeadersS[] = " Length Date Time Name";
static ZCONST char Far HeadersS1[] = " -------- ---- ---- ----";
#endif
static ZCONST char Far HeadersL[] =
" Length Method Size Ratio Date Time CRC-32 Name";
static ZCONST char Far HeadersL1[] =
"-------- ------ ------- ----- ---- ---- ------ ----";
static ZCONST char Far *Headers[][2] =
{ {HeadersS, HeadersS1}, {HeadersL, HeadersL1} };
static ZCONST char Far CaseConversion[] =
"%s (\"^\" ==> case\n%s conversion)\n";
static ZCONST char Far LongHdrStats[] =
"%8lu %-7s%8lu %4s %02u-%02u-%02u %02u:%02u %08lx %c";
static ZCONST char Far LongFileTrailer[] =
"-------- ------- --- \
-------\n%8lu %8lu %4s %lu file%s\n";
#ifdef OS2_EAS
static ZCONST char Far ShortHdrStats[] =
"%9lu %6lu %6lu %02u-%02u-%02u %02u:%02u %c";
static ZCONST char Far ShortFileTrailer[] = " -------- ----- ----- \
-------\n%9lu %6lu %6lu %lu file%s\n";
static ZCONST char Far OS2ExtAttrTrailer[] =
"%lu file%s %lu bytes of OS/2 extended attributes attached.\n";
static ZCONST char Far OS2ACLTrailer[] =
"%lu file%s %lu bytes of access control lists attached.\n";
#else
static ZCONST char Far ShortHdrStats[] =
"%9lu %02u-%02u-%02u %02u:%02u %c";
static ZCONST char Far ShortFileTrailer[] = " -------- \
-------\n%9lu %lu file%s\n";
#endif
#endif
int list_files(__G)
__GDEF
{
int do_this_file=FALSE, cfactor, error, error_in_archive=PK_COOL;
#ifndef WINDLL
char sgn, cfactorstr[10];
int longhdr=(uO.vflag>1);
#endif
int date_format;
ulg j, members=0L;
unsigned methnum;
#ifdef USE_EF_UT_TIME
iztimes z_utime;
struct tm *t;
#endif
unsigned yr, mo, dy, hh, mm;
ulg csiz, tot_csize=0L, tot_ucsize=0L;
#ifdef OS2_EAS
ulg ea_size, tot_easize=0L, tot_eafiles=0L;
ulg acl_size, tot_aclsize=0L, tot_aclfiles=0L;
#endif
min_info info;
char methbuf[8];
static ZCONST char dtype[]="NXFS";
static ZCONST char Far method[NUM_METHODS+1][8] =
{"Stored", "Shrunk", "Reduce1", "Reduce2", "Reduce3", "Reduce4",
"Implode", "Token", "Defl:#", "Def64#", "ImplDCL", "Unk:###"};
G.pInfo = &info;
date_format = DATE_FORMAT;
#ifndef WINDLL
if (uO.qflag < 2) {
if (uO.L_flag)
Info(slide, 0, ((char *)slide, LoadFarString(CaseConversion),
LoadFarStringSmall(Headers[longhdr][0]),
LoadFarStringSmall2(Headers[longhdr][1])));
else
Info(slide, 0, ((char *)slide, "%s\n%s\n",
LoadFarString(Headers[longhdr][0]),
LoadFarStringSmall(Headers[longhdr][1])));
}
#endif
for (j = 1L;;j++) {
if (readbuf(__G__ G.sig, 4) == 0)
return PK_EOF;
if (strncmp(G.sig, central_hdr_sig, 4)) {
if (((unsigned)(j - 1) & (unsigned)0xFFFF) ==
(unsigned)G.ecrec.total_entries_central_dir) {
break;
} else {
Info(slide, 0x401,
((char *)slide, LoadFarString(CentSigMsg), j));
Info(slide, 0x401,
((char *)slide, LoadFarString(ReportMsg)));
return PK_BADERR;
}
}
if ((error = process_cdir_file_hdr(__G)) != PK_COOL)
return error;
if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) !=
PK_COOL)
{
error_in_archive = error;
if (error > PK_WARN)
return error;
}
if (G.extra_field != (uch *)NULL) {
free(G.extra_field);
G.extra_field = (uch *)NULL;
}
if ((error = do_string(__G__ G.crec.extra_field_length, EXTRA_FIELD))
!= 0)
{
error_in_archive = error;
if (error > PK_WARN)
return error;
}
if (!G.process_all_files) {
unsigned i;
do_this_file = FALSE;
for (i = 0; i < G.filespecs; i++)
if (match(G.filename, G.pfnames[i], uO.C_flag)) {
do_this_file = TRUE;
break;
}
if (do_this_file) {
for (i = 0; i < G.xfilespecs; i++)
if (match(G.filename, G.pxnames[i], uO.C_flag)) {
do_this_file = FALSE;
break;
}
}
}
if (G.process_all_files || do_this_file) {
#ifdef OS2DLL
if (G.processExternally) {
if ((G.processExternally)(G.filename, &G.crec))
break;
++members;
} else {
#endif
#ifdef OS2_EAS
{
uch *ef_ptr = G.extra_field;
int ef_size, ef_len = G.crec.extra_field_length;
ea_size = acl_size = 0;
while (ef_len >= EB_HEADSIZE) {
ef_size = makeword(&ef_ptr[EB_LEN]);
switch (makeword(&ef_ptr[EB_ID])) {
case EF_OS2:
ea_size = makelong(&ef_ptr[EB_HEADSIZE]);
break;
case EF_ACL:
acl_size = makelong(&ef_ptr[EB_HEADSIZE]);
break;
}
ef_ptr += (ef_size + EB_HEADSIZE);
ef_len -= (ef_size + EB_HEADSIZE);
}
}
#endif
#ifdef USE_EF_UT_TIME
if (G.extra_field &&
#ifdef IZ_CHECK_TZ
G.tz_is_valid &&
#endif
(ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1,
G.crec.last_mod_dos_datetime, &z_utime, NULL)
& EB_UT_FL_MTIME))
{
TIMET_TO_NATIVE(z_utime.mtime)
t = localtime(&(z_utime.mtime));
} else
t = (struct tm *)NULL;
if (t != (struct tm *)NULL) {
mo = (unsigned)(t->tm_mon + 1);
dy = (unsigned)(t->tm_mday);
yr = (unsigned)(t->tm_year % 100);
hh = (unsigned)(t->tm_hour);
mm = (unsigned)(t->tm_min);
} else
#endif
{
yr = ((((unsigned)(G.crec.last_mod_dos_datetime >> 25) & 0x7f)
+ 80) % (unsigned)100);
mo = ((unsigned)(G.crec.last_mod_dos_datetime >> 21) & 0x0f);
dy = ((unsigned)(G.crec.last_mod_dos_datetime >> 16) & 0x1f);
hh = (((unsigned)G.crec.last_mod_dos_datetime >> 11) & 0x1f);
mm = (((unsigned)G.crec.last_mod_dos_datetime >> 5) & 0x3f);
}
switch (date_format) {
case DF_YMD:
methnum = mo;
mo = yr; yr = dy; dy = methnum;
break;
case DF_DMY:
methnum = mo;
mo = dy; dy = methnum;
}
csiz = G.crec.csize;
if (G.crec.general_purpose_bit_flag & 1)
csiz -= 12;
if ((cfactor = ratio(G.crec.ucsize, csiz)) < 0) {
#ifndef WINDLL
sgn = '-';
#endif
cfactor = (-cfactor + 5) / 10;
} else {
#ifndef WINDLL
sgn = ' ';
#endif
cfactor = (cfactor + 5) / 10;
}
methnum = MIN(G.crec.compression_method, NUM_METHODS);
zfstrcpy(methbuf, method[methnum]);
if (methnum == DEFLATED || methnum == ENHDEFLATED) {
methbuf[5] = dtype[(G.crec.general_purpose_bit_flag>>1) & 3];
} else if (methnum >= NUM_METHODS) {
sprintf(&methbuf[4], "%03u", G.crec.compression_method);
}
#if 0
#if defined(DOS_FLX_NLM_OS2_W32) || defined(THEOS) || defined(UNIX)
for (p = G.filename; *p; ++p)
if (!isprint(*p))
*p = '?';
#endif
#endif
#ifdef WINDLL
(*G.lpUserFunctions->SendApplicationMessage)(G.crec.ucsize, csiz,
(unsigned)cfactor, mo, dy, yr, hh, mm,
(char)(G.pInfo->lcflag ? '^' : ' '),
(LPSTR)fnfilter(G.filename, slide), (LPSTR)methbuf, G.crec.crc32,
(char)((G.crec.general_purpose_bit_flag & 1) ? 'E' : ' '));
#else
if (cfactor == 100)
sprintf(cfactorstr, LoadFarString(CompFactor100));
else
sprintf(cfactorstr, LoadFarString(CompFactorStr), sgn, cfactor);
if (longhdr)
Info(slide, 0, ((char *)slide, LoadFarString(LongHdrStats),
G.crec.ucsize, methbuf, csiz, cfactorstr, mo, dy,
yr, hh, mm, G.crec.crc32, (G.pInfo->lcflag? '^':' ')));
else
#ifdef OS2_EAS
Info(slide, 0, ((char *)slide, LoadFarString(ShortHdrStats),
G.crec.ucsize, ea_size, acl_size,
mo, dy, yr, hh, mm, (G.pInfo->lcflag? '^':' ')));
#else
Info(slide, 0, ((char *)slide, LoadFarString(ShortHdrStats),
G.crec.ucsize,
mo, dy, yr, hh, mm, (G.pInfo->lcflag? '^':' ')));
#endif
fnprint(__G);
#endif
if ((error = do_string(__G__ G.crec.file_comment_length,
QCOND? DISPL_8 : SKIP)) != 0)
{
error_in_archive = error;
if (error > PK_WARN)
return error;
}
tot_ucsize += G.crec.ucsize;
tot_csize += csiz;
++members;
#ifdef OS2_EAS
if (ea_size) {
tot_easize += ea_size;
++tot_eafiles;
}
if (acl_size) {
tot_aclsize += acl_size;
++tot_aclfiles;
}
#endif
#ifdef OS2DLL
}
#endif
} else {
SKIP_(G.crec.file_comment_length)
}
}
if (uO.qflag < 2
#ifdef OS2DLL
&& !G.processExternally
#endif
) {
if ((cfactor = ratio(tot_ucsize, tot_csize)) < 0) {
#ifndef WINDLL
sgn = '-';
#endif
cfactor = (-cfactor + 5) / 10;
} else {
#ifndef WINDLL
sgn = ' ';
#endif
cfactor = (cfactor + 5) / 10;
}
#ifdef WINDLL
G.lpUserFunctions->TotalSizeComp = tot_csize;
G.lpUserFunctions->TotalSize = tot_ucsize;
G.lpUserFunctions->CompFactor = (ulg)cfactor;
G.lpUserFunctions->NumMembers = members;
#else
if (cfactor == 100)
sprintf(cfactorstr, LoadFarString(CompFactor100));
else
sprintf(cfactorstr, LoadFarString(CompFactorStr), sgn, cfactor);
if (longhdr) {
Info(slide, 0, ((char *)slide, LoadFarString(LongFileTrailer),
tot_ucsize, tot_csize, cfactorstr, members, members==1? "":"s"));
#ifdef OS2_EAS
if (tot_easize || tot_aclsize)
Info(slide, 0, ((char *)slide, "\n"));
if (tot_eafiles && tot_easize)
Info(slide, 0, ((char *)slide, LoadFarString(OS2ExtAttrTrailer),
tot_eafiles, tot_eafiles == 1? " has" : "s have a total of",
tot_easize));
if (tot_aclfiles && tot_aclsize)
Info(slide, 0, ((char *)slide, LoadFarString(OS2ACLTrailer),
tot_aclfiles, tot_aclfiles == 1? " has" : "s have a total of",
tot_aclsize));
#endif
} else
#ifdef OS2_EAS
Info(slide, 0, ((char *)slide, LoadFarString(ShortFileTrailer),
tot_ucsize, tot_easize, tot_aclsize, members, members == 1?
"" : "s"));
#else
Info(slide, 0, ((char *)slide, LoadFarString(ShortFileTrailer),
tot_ucsize, members, members == 1? "" : "s"));
#endif
#endif
}
if (strncmp(G.sig, end_central_sig, 4)) {
Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
error_in_archive = PK_WARN;
}
if (members == 0L && error_in_archive <= PK_WARN)
error_in_archive = PK_FIND;
return error_in_archive;
}
#ifdef TIMESTAMP
static int fn_is_dir(__G)
__GDEF
{
extent fn_len = strlen(G.filename);
register char endc;
return fn_len > 0 &&
((endc = lastchar(G.filename, fn_len)) == '/' ||
(G.pInfo->hostnum == FS_FAT_ && !MBSCHR(G.filename, '/') &&
endc == '\\'));
}
int get_time_stamp(__G__ last_modtime, nmember)
__GDEF
time_t *last_modtime;
ulg *nmember;
{
int do_this_file=FALSE, error, error_in_archive=PK_COOL;
ulg j;
#ifdef USE_EF_UT_TIME
iztimes z_utime;
#endif
min_info info;
*last_modtime = 0L;
*nmember = 0L;
G.pInfo = &info;
for (j = 1L;; j++) {
if (readbuf(__G__ G.sig, 4) == 0)
return PK_EOF;
if (strncmp(G.sig, central_hdr_sig, 4)) {
if (((unsigned)(j - 1) & (unsigned)0xFFFF) ==
(unsigned)G.ecrec.total_entries_central_dir) {
break;
} else {
Info(slide, 0x401,
((char *)slide, LoadFarString(CentSigMsg), j));
Info(slide, 0x401,
((char *)slide, LoadFarString(ReportMsg)));
return PK_BADERR;
}
}
if ((error = process_cdir_file_hdr(__G)) != PK_COOL)
return error;
if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) != PK_OK)
{
error_in_archive = error;
if (error > PK_WARN)
return error;
}
if (G.extra_field != (uch *)NULL) {
free(G.extra_field);
G.extra_field = (uch *)NULL;
}
if ((error = do_string(__G__ G.crec.extra_field_length, EXTRA_FIELD))
!= 0)
{
error_in_archive = error;
if (error > PK_WARN)
return error;
}
if (!G.process_all_files) {
unsigned i;
do_this_file = FALSE;
for (i = 0; i < G.filespecs; i++)
if (match(G.filename, G.pfnames[i], uO.C_flag)) {
do_this_file = TRUE;
break;
}
if (do_this_file) {
for (i = 0; i < G.xfilespecs; i++)
if (match(G.filename, G.pxnames[i], uO.C_flag)) {
do_this_file = FALSE;
break;
}
}
}
if ((G.process_all_files || do_this_file) && !fn_is_dir(__G)) {
#ifdef USE_EF_UT_TIME
if (G.extra_field &&
#ifdef IZ_CHECK_TZ
G.tz_is_valid &&
#endif
(ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1,
G.crec.last_mod_dos_datetime, &z_utime, NULL)
& EB_UT_FL_MTIME))
{
if (*last_modtime < z_utime.mtime)
*last_modtime = z_utime.mtime;
} else
#endif
{
time_t modtime = dos_to_unix_time(G.crec.last_mod_dos_datetime);
if (*last_modtime < modtime)
*last_modtime = modtime;
}
++*nmember;
}
SKIP_(G.crec.file_comment_length)
}
if (strncmp(G.sig, end_central_sig, 4)) {
Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
error_in_archive = PK_WARN;
}
if (*nmember == 0L && error_in_archive <= PK_WARN)
error_in_archive = PK_FIND;
return error_in_archive;
}
#endif
int ratio(uc, c)
ulg uc, c;
{
ulg denom;
if (uc == 0)
return 0;
if (uc > 2000000L) {
denom = uc / 1000L;
return ((uc >= c) ?
(int) ((uc-c + (denom>>1)) / denom) :
-((int) ((c-uc + (denom>>1)) / denom)));
} else {
denom = uc;
return ((uc >= c) ?
(int) ((1000L*(uc-c) + (denom>>1)) / denom) :
-((int) ((1000L*(c-uc) + (denom>>1)) / denom)));
}
}
void fnprint(__G)
__GDEF
{
char *name = fnfilter(G.filename, slide);
(*G.message)((zvoid *)&G, (uch *)name, (ulg)strlen(name), 0);
(*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0);
}