Archive-Unzip-Burst
view release on metacpan or search on metacpan
unzip-6.0/unix/unix.c view on Meta::CPAN
set_direc_attribs()
stamp_file()
version()
---------------------------------------------------------------------------*/
#define UNZIP_INTERNAL
#include "unzip.h"
#ifdef SCO_XENIX
# define SYSNDIR
#else /* SCO Unix, AIX, DNIX, TI SysV, Coherent 4.x, ... */
# if defined(__convexc__) || defined(SYSV) || defined(CRAY) || defined(BSD4_4)
# define DIRENT
# endif
#endif
#if defined(_AIX) || defined(__mpexl)
# define DIRENT
#endif
#ifdef COHERENT
# if defined(_I386) || (defined(__COHERENT__) && (__COHERENT__ >= 0x420))
# define DIRENT
# endif
#endif
#ifdef _POSIX_VERSION
# ifndef DIRENT
# define DIRENT
# endif
#endif
#ifdef DIRENT
# include <dirent.h>
#else
# ifdef SYSV
# ifdef SYSNDIR
# include <sys/ndir.h>
# else
# include <ndir.h>
# endif
# else /* !SYSV */
# ifndef NO_SYSDIR
# include <sys/dir.h>
# endif
# endif /* ?SYSV */
# ifndef dirent
# define dirent direct
# endif
#endif /* ?DIRENT */
#ifdef SET_DIR_ATTRIB
typedef struct uxdirattr { /* struct for holding unix style directory */
struct uxdirattr *next; /* info until can be sorted and set at end */
char *fn; /* filename of directory */
union {
iztimes t3; /* mtime, atime, ctime */
ztimbuf t2; /* modtime, actime */
} u;
unsigned perms; /* same as min_info.file_attr */
int have_uidgid; /* flag */
ulg uidgid[2];
char fnbuf[1]; /* buffer stub for directory name */
} uxdirattr;
#define UxAtt(d) ((uxdirattr *)d) /* typecast shortcut */
#endif /* SET_DIR_ATTRIB */
#ifdef ACORN_FTYPE_NFS
/* Acorn bits for NFS filetyping */
typedef struct {
uch ID[2];
uch size[2];
uch ID_2[4];
uch loadaddr[4];
uch execaddr[4];
uch attr[4];
} RO_extra_block;
#endif /* ACORN_FTYPE_NFS */
/* static int created_dir; */ /* used in mapname(), checkdir() */
/* static int renamed_fullpath; */ /* ditto */
static unsigned filtattr OF((__GPRO__ unsigned perms));
/*****************************/
/* Strings used multiple */
/* times in unix.c */
/*****************************/
#ifndef MTS
/* messages of code for setting file/directory attributes */
static ZCONST char CannotSetItemUidGid[] =
"warning: cannot set UID %lu and/or GID %lu for %s\n %s\n";
static ZCONST char CannotSetUidGid[] =
" (warning) cannot set UID %lu and/or GID %lu\n %s";
static ZCONST char CannotSetItemTimestamps[] =
"warning: cannot set modif./access times for %s\n %s\n";
static ZCONST char CannotSetTimestamps[] =
" (warning) cannot set modif./access times\n %s";
#endif /* !MTS */
#ifndef SFX
#ifdef NO_DIR /* for AT&T 3B1 */
#define opendir(path) fopen(path,"r")
#define closedir(dir) fclose(dir)
typedef FILE DIR;
typedef struct zdir {
FILE *dirhandle;
struct dirent *entry;
} DIR
DIR *opendir OF((ZCONST char *dirspec));
void closedir OF((DIR *dirp));
struct dirent *readdir OF((DIR *dirp));
DIR *opendir(dirspec)
ZCONST char *dirspec;
{
DIR *dirp;
unzip-6.0/unix/unix.c view on Meta::CPAN
return (char *)NULL;
}
/* If we've gotten this far, we've read and matched at least one entry
* successfully (in a previous call), so dirname has been copied into
* matchname already.
*/
while ((file = readdir((DIR *)G.wild_dir)) != (struct dirent *)NULL) {
Trace((stderr, "do_wild: readdir returns %s\n",
FnFilter1(file->d_name)));
if (file->d_name[0] == '.' && G.wildname[0] != '.')
continue; /* Unix: '*' and '?' do not match leading dot */
if (match(file->d_name, G.wildname, 0 WISEP)) { /* 0 == case sens. */
Trace((stderr, "do_wild: match() succeeds\n"));
if (G.have_dirname) {
/* strcpy(G.matchname, G.dirname); */
strcpy(G.matchname+G.dirnamelen, file->d_name);
} else
strcpy(G.matchname, file->d_name);
return G.matchname;
}
}
closedir((DIR *)G.wild_dir); /* at least one entry read; nothing left */
G.wild_dir = (zvoid *)NULL;
G.notfirstcall = FALSE; /* reset for new wildspec */
if (G.have_dirname)
free(G.dirname);
return (char *)NULL;
} /* end function do_wild() */
#endif /* !SFX */
#ifndef S_ISUID
# define S_ISUID 0004000 /* set user id on execution */
#endif
#ifndef S_ISGID
# define S_ISGID 0002000 /* set group id on execution */
#endif
#ifndef S_ISVTX
# define S_ISVTX 0001000 /* save swapped text even after use */
#endif
/************************/
/* Function filtattr() */
/************************/
/* This is used to clear or keep the SUID and SGID bits on file permissions.
* It's possible that a file in an archive could have one of these bits set
* and, unknown to the person unzipping, could allow others to execute the
* file as the user or group. The new option -K bypasses this check.
*/
static unsigned filtattr(__G__ perms)
__GDEF
unsigned perms;
{
/* keep setuid/setgid/tacky perms? */
if (!uO.K_flag)
perms &= ~(S_ISUID | S_ISGID | S_ISVTX);
return (0xffff & perms);
} /* end function filtattr() */
/**********************/
/* Function mapattr() */
/**********************/
int mapattr(__G)
__GDEF
{
int r;
ulg tmp = G.crec.external_file_attributes;
G.pInfo->file_attr = 0;
/* initialized to 0 for check in "default" branch below... */
switch (G.pInfo->hostnum) {
case AMIGA_:
tmp = (unsigned)(tmp>>17 & 7); /* Amiga RWE bits */
G.pInfo->file_attr = (unsigned)(tmp<<6 | tmp<<3 | tmp);
break;
case THEOS_:
tmp &= 0xF1FFFFFFL;
if ((tmp & 0xF0000000L) != 0x40000000L)
tmp &= 0x01FFFFFFL; /* not a dir, mask all ftype bits */
else
tmp &= 0x41FFFFFFL; /* leave directory bit as set */
/* fall through! */
case UNIX_:
case VMS_:
case ACORN_:
case ATARI_:
case ATHEOS_:
case BEOS_:
case QDOS_:
case TANDEM_:
r = FALSE;
G.pInfo->file_attr = (unsigned)(tmp >> 16);
if (G.pInfo->file_attr == 0 && G.extra_field) {
/* Some (non-Info-ZIP) implementations of Zip for Unix and
* VMS (and probably others ??) leave 0 in the upper 16-bit
* part of the external_file_attributes field. Instead, they
* store file permission attributes in some extra field.
* As a work-around, we search for the presence of one of
* these extra fields and fall back to the MSDOS compatible
* part of external_file_attributes if one of the known
* e.f. types has been detected.
* Later, we might implement extraction of the permission
* bits from the VMS extra field. But for now, the work-around
* should be sufficient to provide "readable" extracted files.
* (For ASI Unix e.f., an experimental remap of the e.f.
* mode value IS already provided!)
*/
unzip-6.0/unix/unix.c view on Meta::CPAN
G.rootlen = 0;
return MPN_NOMEM;
}
Trace((stderr, "rootpath now = [%s]\n", FnFilter1(G.rootpath)));
}
return MPN_OK;
}
#endif /* !SFX || SFX_EXDIR */
/*---------------------------------------------------------------------------
END: free rootpath, immediately prior to program exit.
---------------------------------------------------------------------------*/
if (FUNCTION == END) {
Trace((stderr, "freeing rootpath\n"));
if (G.rootlen > 0) {
free(G.rootpath);
G.rootlen = 0;
}
return MPN_OK;
}
return MPN_INVALID; /* should never reach */
} /* end function checkdir() */
#ifdef NO_MKDIR
/********************/
/* Function mkdir() */
/********************/
int mkdir(path, mode)
ZCONST char *path;
int mode; /* ignored */
/*
* returns: 0 - successful
* -1 - failed (errno not set, however)
*/
{
char command[FILNAMSIZ+40]; /* buffer for system() call */
/* GRR 930416: added single quotes around path to avoid bug with
* creating directories with ampersands in name; not yet tested */
sprintf(command, "IFS=\" \t\n\" /bin/mkdir '%s' 2>/dev/null", path);
if (system(command))
return -1;
return 0;
}
#endif /* NO_MKDIR */
#if (!defined(MTS) || defined(SET_DIR_ATTRIB))
static int get_extattribs OF((__GPRO__ iztimes *pzt, ulg z_uidgid[2]));
static int get_extattribs(__G__ pzt, z_uidgid)
__GDEF
iztimes *pzt;
ulg z_uidgid[2];
{
/*---------------------------------------------------------------------------
Convert from MSDOS-format local time and date to Unix-format 32-bit GMT
time: adjust base year from 1980 to 1970, do usual conversions from
yy/mm/dd hh:mm:ss to elapsed seconds, and account for timezone and day-
light savings time differences. If we have a Unix extra field, however,
we're laughing: both mtime and atime are ours. On the other hand, we
then have to check for restoration of UID/GID.
---------------------------------------------------------------------------*/
int have_uidgid_flg;
unsigned eb_izux_flg;
eb_izux_flg = (G.extra_field ? ef_scan_for_izux(G.extra_field,
G.lrec.extra_field_length, 0, G.lrec.last_mod_dos_datetime,
#ifdef IZ_CHECK_TZ
(G.tz_is_valid ? pzt : NULL),
#else
pzt,
#endif
z_uidgid) : 0);
if (eb_izux_flg & EB_UT_FL_MTIME) {
TTrace((stderr, "\nget_extattribs: Unix e.f. modif. time = %ld\n",
pzt->mtime));
} else {
pzt->mtime = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
}
if (eb_izux_flg & EB_UT_FL_ATIME) {
TTrace((stderr, "get_extattribs: Unix e.f. access time = %ld\n",
pzt->atime));
} else {
pzt->atime = pzt->mtime;
TTrace((stderr, "\nget_extattribs: modification/access times = %ld\n",
pzt->mtime));
}
/* if -X option was specified and we have UID/GID info, restore it */
have_uidgid_flg =
#ifdef RESTORE_UIDGID
(uO.X_flag && (eb_izux_flg & EB_UX2_VALID));
#else
0;
#endif
return have_uidgid_flg;
}
#endif /* !MTS || SET_DIR_ATTRIB */
#ifndef MTS
/****************************/
/* Function close_outfile() */
/****************************/
void close_outfile(__G) /* GRR: change to return PK-style warning level */
__GDEF
{
union {
iztimes t3; /* mtime, atime, ctime */
ztimbuf t2; /* modtime, actime */
} zt;
ulg z_uidgid[2];
int have_uidgid_flg;
have_uidgid_flg = get_extattribs(__G__ &(zt.t3), z_uidgid);
/*---------------------------------------------------------------------------
If symbolic links are supported, allocate storage for a symlink control
structure, put the uncompressed "data" and other required info in it, and
add the structure to the "deferred symlinks" chain. Since we know it's a
symbolic link to start with, we shouldn't have to worry about overflowing
unsigned ints with unsigned longs.
---------------------------------------------------------------------------*/
#ifdef SYMLINKS
if (G.symlnk) {
extent ucsize = (extent)G.lrec.ucsize;
# ifdef SET_SYMLINK_ATTRIBS
extent attribsize = sizeof(unsigned) +
(have_uidgid_flg ? sizeof(z_uidgid) : 0);
# else
extent attribsize = 0;
# endif
/* size of the symlink entry is the sum of
* (struct size (includes 1st '\0') + 1 additional trailing '\0'),
* system specific attribute data size (might be 0),
* and the lengths of name and link target.
*/
extent slnk_entrysize = (sizeof(slinkentry) + 1) + attribsize +
ucsize + strlen(G.filename);
slinkentry *slnk_entry;
if (slnk_entrysize < ucsize) {
Info(slide, 0x201, ((char *)slide,
"warning: symbolic link (%s) failed: mem alloc overflow\n",
FnFilter1(G.filename)));
fclose(G.outfile);
return;
}
if ((slnk_entry = (slinkentry *)malloc(slnk_entrysize)) == NULL) {
Info(slide, 0x201, ((char *)slide,
"warning: symbolic link (%s) failed: no mem\n",
FnFilter1(G.filename)));
fclose(G.outfile);
return;
}
slnk_entry->next = NULL;
slnk_entry->targetlen = ucsize;
slnk_entry->attriblen = attribsize;
# ifdef SET_SYMLINK_ATTRIBS
memcpy(slnk_entry->buf, &(G.pInfo->file_attr),
sizeof(unsigned));
if (have_uidgid_flg)
memcpy(slnk_entry->buf + 4, z_uidgid, sizeof(z_uidgid));
# endif
slnk_entry->target = slnk_entry->buf + slnk_entry->attriblen;
slnk_entry->fname = slnk_entry->target + ucsize + 1;
strcpy(slnk_entry->fname, G.filename);
/* move back to the start of the file to re-read the "link data" */
rewind(G.outfile);
if (fread(slnk_entry->target, 1, ucsize, G.outfile) != ucsize)
{
Info(slide, 0x201, ((char *)slide,
"warning: symbolic link (%s) failed\n",
FnFilter1(G.filename)));
free(slnk_entry);
fclose(G.outfile);
return;
}
fclose(G.outfile); /* close "link" file for good... */
slnk_entry->target[ucsize] = '\0';
if (QCOND2)
Info(slide, 0, ((char *)slide, "-> %s ",
FnFilter1(slnk_entry->target)));
/* add this symlink record to the list of deferred symlinks */
if (G.slink_last != NULL)
G.slink_last->next = slnk_entry;
else
G.slink_head = slnk_entry;
G.slink_last = slnk_entry;
return;
}
#endif /* SYMLINKS */
#ifdef QLZIP
if (G.extra_field) {
static void qlfix OF((__GPRO__ uch *ef_ptr, unsigned ef_len));
qlfix(__G__ G.extra_field, G.lrec.extra_field_length);
}
#endif
#if (defined(NO_FCHOWN))
fclose(G.outfile);
#endif
/* if -X option was specified and we have UID/GID info, restore it */
if (have_uidgid_flg
/* check that both uid and gid values fit into their data sizes */
&& ((ulg)(uid_t)(z_uidgid[0]) == z_uidgid[0])
&& ((ulg)(gid_t)(z_uidgid[1]) == z_uidgid[1])) {
TTrace((stderr, "close_outfile: restoring Unix UID/GID info\n"));
#if (defined(NO_FCHOWN))
if (chown(G.filename, (uid_t)z_uidgid[0], (gid_t)z_uidgid[1]))
#else
if (fchown(fileno(G.outfile), (uid_t)z_uidgid[0], (gid_t)z_uidgid[1]))
#endif
{
if (uO.qflag)
Info(slide, 0x201, ((char *)slide, CannotSetItemUidGid,
z_uidgid[0], z_uidgid[1], FnFilter1(G.filename),
strerror(errno)));
else
Info(slide, 0x201, ((char *)slide, CannotSetUidGid,
z_uidgid[0], z_uidgid[1], strerror(errno)));
}
}
#if (!defined(NO_FCHOWN) && defined(NO_FCHMOD))
fclose(G.outfile);
#endif
#if (!defined(NO_FCHOWN) && !defined(NO_FCHMOD))
/*---------------------------------------------------------------------------
Change the file permissions from default ones to those stored in the
zipfile.
---------------------------------------------------------------------------*/
if (fchmod(fileno(G.outfile), filtattr(__G__ G.pInfo->file_attr)))
perror("fchmod (file attributes) error");
fclose(G.outfile);
#endif /* !NO_FCHOWN && !NO_FCHMOD */
/* skip restoring time stamps on user's request */
if (uO.D_flag <= 1) {
/* set the file's access and modification times */
if (utime(G.filename, &(zt.t2))) {
if (uO.qflag)
Info(slide, 0x201, ((char *)slide, CannotSetItemTimestamps,
FnFilter1(G.filename), strerror(errno)));
else
Info(slide, 0x201, ((char *)slide, CannotSetTimestamps,
strerror(errno)));
}
}
#if (defined(NO_FCHOWN) || defined(NO_FCHMOD))
/*---------------------------------------------------------------------------
Change the file permissions from default ones to those stored in the
zipfile.
---------------------------------------------------------------------------*/
#ifndef NO_CHMOD
if (chmod(G.filename, filtattr(__G__ G.pInfo->file_attr)))
perror("chmod (file attributes) error");
#endif
#endif /* NO_FCHOWN || NO_FCHMOD */
} /* end function close_outfile() */
#endif /* !MTS */
#if (defined(SYMLINKS) && defined(SET_SYMLINK_ATTRIBS))
int set_symlnk_attribs(__G__ slnk_entry)
__GDEF
slinkentry *slnk_entry;
{
if (slnk_entry->attriblen > 0) {
# if (!defined(NO_LCHOWN))
if (slnk_entry->attriblen > sizeof(unsigned)) {
ulg *z_uidgid_p = (zvoid *)(slnk_entry->buf + sizeof(unsigned));
/* check that both uid and gid values fit into their data sizes */
if (((ulg)(uid_t)(z_uidgid_p[0]) == z_uidgid_p[0]) &&
((ulg)(gid_t)(z_uidgid_p[1]) == z_uidgid_p[1])) {
TTrace((stderr,
"set_symlnk_attribs: restoring Unix UID/GID info for\n\
%s\n",
FnFilter1(slnk_entry->fname)));
if (lchown(slnk_entry->fname,
(uid_t)z_uidgid_p[0], (gid_t)z_uidgid_p[1]))
{
Info(slide, 0x201, ((char *)slide, CannotSetItemUidGid,
z_uidgid_p[0], z_uidgid_p[1], FnFilter1(slnk_entry->fname),
strerror(errno)));
}
}
}
# endif /* !NO_LCHOWN */
# if (!defined(NO_LCHMOD))
TTrace((stderr,
"set_symlnk_attribs: restoring Unix attributes for\n %s\n",
FnFilter1(slnk_entry->fname)));
if (lchmod(slnk_entry->fname,
filtattr(__G__ *(unsigned *)(zvoid *)slnk_entry->buf)))
perror("lchmod (file attributes) error");
# endif /* !NO_LCHMOD */
}
/* currently, no error propagation... */
return PK_OK;
} /* end function set_symlnk_attribs() */
#endif /* SYMLINKS && SET_SYMLINK_ATTRIBS */
#ifdef SET_DIR_ATTRIB
/* messages of code for setting directory attributes */
# ifndef NO_CHMOD
static ZCONST char DirlistChmodFailed[] =
"warning: cannot set permissions for %s\n %s\n";
# endif
int defer_dir_attribs(__G__ pd)
__GDEF
direntry **pd;
{
uxdirattr *d_entry;
d_entry = (uxdirattr *)malloc(sizeof(uxdirattr) + strlen(G.filename));
*pd = (direntry *)d_entry;
if (d_entry == (uxdirattr *)NULL) {
return PK_MEM;
}
d_entry->fn = d_entry->fnbuf;
strcpy(d_entry->fn, G.filename);
d_entry->perms = G.pInfo->file_attr;
d_entry->have_uidgid = get_extattribs(__G__ &(d_entry->u.t3),
d_entry->uidgid);
return PK_OK;
} /* end function defer_dir_attribs() */
int set_direc_attribs(__G__ d)
__GDEF
direntry *d;
{
int errval = PK_OK;
if (UxAtt(d)->have_uidgid &&
/* check that both uid and gid values fit into their data sizes */
((ulg)(uid_t)(UxAtt(d)->uidgid[0]) == UxAtt(d)->uidgid[0]) &&
((ulg)(gid_t)(UxAtt(d)->uidgid[1]) == UxAtt(d)->uidgid[1]) &&
chown(UxAtt(d)->fn, (uid_t)UxAtt(d)->uidgid[0],
(gid_t)UxAtt(d)->uidgid[1]))
{
Info(slide, 0x201, ((char *)slide, CannotSetItemUidGid,
UxAtt(d)->uidgid[0], UxAtt(d)->uidgid[1], FnFilter1(d->fn),
strerror(errno)));
if (!errval)
errval = PK_WARN;
}
/* Skip restoring directory time stamps on user' request. */
if (uO.D_flag <= 0) {
/* restore directory timestamps */
if (utime(d->fn, &UxAtt(d)->u.t2)) {
Info(slide, 0x201, ((char *)slide, CannotSetItemTimestamps,
FnFilter1(d->fn), strerror(errno)));
if (!errval)
errval = PK_WARN;
}
}
#ifndef NO_CHMOD
if (chmod(d->fn, UxAtt(d)->perms)) {
Info(slide, 0x201, ((char *)slide, DirlistChmodFailed,
FnFilter1(d->fn), strerror(errno)));
if (!errval)
errval = PK_WARN;
}
#endif /* !NO_CHMOD */
return errval;
} /* end function set_direc_attribs() */
#endif /* SET_DIR_ATTRIB */
#ifdef TIMESTAMP
/***************************/
/* Function stamp_file() */
/***************************/
int stamp_file(fname, modtime)
ZCONST char *fname;
time_t modtime;
{
ztimbuf tp;
tp.modtime = tp.actime = modtime;
return (utime(fname, &tp));
} /* end function stamp_file() */
#endif /* TIMESTAMP */
#ifndef SFX
/************************/
/* Function version() */
/************************/
void version(__G)
__GDEF
unzip-6.0/unix/unix.c view on Meta::CPAN
#endif /* 486 */
#endif /* 586 */
#endif /* 686 */
#endif /* Cygwin */
#endif /* 386BSD */
#endif /* BSDI BSD/386 */
#endif /* NetBSD */
#endif /* FreeBSD */
#endif /* SCO Xenix */
#endif /* SCO Unix */
#endif /* Minix */
#endif /* Linux */
#endif /* NeXT */
#endif /* Amdahl */
#endif /* Cray */
#endif /* RT/AIX */
#endif /* AIX */
#endif /* OSF/1 */
#endif /* HP-UX */
#endif /* Sun */
#endif /* SGI */
#ifdef __DATE__
" on ", __DATE__
#else
"", ""
#endif
);
(*G.message)((zvoid *)&G, slide, (ulg)strlen((char *)slide), 0);
} /* end function version() */
#endif /* !SFX */
#ifdef QLZIP
struct qdirect {
long d_length __attribute__ ((packed)); /* file length */
unsigned char d_access __attribute__ ((packed)); /* file access type */
unsigned char d_type __attribute__ ((packed)); /* file type */
long d_datalen __attribute__ ((packed)); /* data length */
long d_reserved __attribute__ ((packed));/* Unused */
short d_szname __attribute__ ((packed)); /* size of name */
char d_name[36] __attribute__ ((packed));/* name area */
long d_update __attribute__ ((packed)); /* last update */
long d_refdate __attribute__ ((packed));
long d_backup __attribute__ ((packed)); /* EOD */
};
#define LONGID "QDOS02"
#define EXTRALEN (sizeof(struct qdirect) + 8)
#define JBLONGID "QZHD"
#define JBEXTRALEN (sizeof(jbextra) - 4 * sizeof(char))
typedef struct {
char eb_header[4] __attribute__ ((packed)); /* place_holder */
char longid[8] __attribute__ ((packed));
struct qdirect header __attribute__ ((packed));
} qdosextra;
typedef struct {
char eb_header[4]; /* place_holder */
char longid[4];
struct qdirect header;
} jbextra;
/* The following two functions SH() and LG() convert big-endian short
* and long numbers into native byte order. They are some kind of
* counterpart to the generic UnZip's makeword() and makelong() functions.
*/
static ush SH(ush val)
{
uch swapbuf[2];
swapbuf[1] = (uch)(val & 0xff);
swapbuf[0] = (uch)(val >> 8);
return (*(ush *)swapbuf);
}
static ulg LG(ulg val)
{
/* convert the big-endian unsigned long number `val' to the machine
* dependent representation
*/
ush swapbuf[2];
swapbuf[1] = SH((ush)(val & 0xffff));
swapbuf[0] = SH((ush)(val >> 16));
return (*(ulg *)swapbuf);
}
static void qlfix(__G__ ef_ptr, ef_len)
__GDEF
uch *ef_ptr;
unsigned ef_len;
{
while (ef_len >= EB_HEADSIZE)
{
unsigned eb_id = makeword(EB_ID + ef_ptr);
unsigned eb_len = makeword(EB_LEN + ef_ptr);
if (eb_len > (ef_len - EB_HEADSIZE)) {
/* discovered some extra field inconsistency! */
Trace((stderr,
"qlfix: block length %u > rest ef_size %u\n", eb_len,
ef_len - EB_HEADSIZE));
break;
}
switch (eb_id) {
case EF_QDOS:
{
struct _ntc_
{
long id;
long dlen;
} ntc;
long dlen = 0;
qdosextra *extra = (qdosextra *)ef_ptr;
jbextra *jbp = (jbextra *)ef_ptr;
if (!strncmp(extra->longid, LONGID, strlen(LONGID)))
{
if (eb_len != EXTRALEN)
if (uO.qflag)
Info(slide, 0x201, ((char *)slide,
"warning: invalid length in Qdos field for %s\n",
FnFilter1(G.filename)));
else
Info(slide, 0x201, ((char *)slide,
"warning: invalid length in Qdos field"));
if (extra->header.d_type)
{
dlen = extra->header.d_datalen;
}
}
if (!strncmp(jbp->longid, JBLONGID, strlen(JBLONGID)))
{
if (eb_len != JBEXTRALEN)
if (uO.qflag)
Info(slide, 0x201, ((char *)slide,
"warning: invalid length in QZ field for %s\n",
FnFilter1(G.filename)));
else
Info(slide, 0x201, ((char *)slide,
"warning: invalid length in QZ field"));
if (jbp->header.d_type)
{
dlen = jbp->header.d_datalen;
}
}
if ((long)LG(dlen) > 0)
{
zfseeko(G.outfile, -8, SEEK_END);
fread(&ntc, 8, 1, G.outfile);
if (ntc.id != *(long *)"XTcc")
{
ntc.id = *(long *)"XTcc";
ntc.dlen = dlen;
fwrite (&ntc, 8, 1, G.outfile);
}
Info(slide, 0x201, ((char *)slide, "QData = %d", LG(dlen)));
}
return; /* finished, cancel further extra field scanning */
}
default:
Trace((stderr,"qlfix: unknown extra field block, ID=%d\n",
eb_id));
}
/* Skip this extra field block */
ef_ptr += (eb_len + EB_HEADSIZE);
ef_len -= (eb_len + EB_HEADSIZE);
}
}
#endif /* QLZIP */
( run in 1.195 second using v1.01-cache-2.11-cpan-ceb78f64989 )