Archive-Unzip-Burst
view release on metacpan or search on metacpan
unzip-6.0/os2/os2.c view on Meta::CPAN
/*
Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2000-Apr-09 or later
(the contents of which are also included in zip.h) for terms of use.
If, for some reason, both of these files are missing, the Info-ZIP license
also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
*/
/*---------------------------------------------------------------------------
os2.c
OS/2-specific routines for use with Info-ZIP's UnZip 5.1 and later.
This file contains the OS/2 versions of the file name/attribute/time/etc
code. Most or all of the routines which make direct use of OS/2 system
calls (i.e., the non-lowercase routines) are Kai Uwe Rommel's. The read-
dir() suite was written by Michael Rendell and ported to OS/2 by Kai Uwe;
it is in the public domain.
Contains: GetCountryInfo()
SetFileSize()
GetFileTime()
SetFileTime() (TIMESTAMP only)
stamp_file() (TIMESTAMP only)
Utime2DosDateTime()
SetPathAttrTimes()
SetEAs()
GetLoadPath()
opendir()
closedir()
readdir()
[ seekdir() ] not used
[ telldir() ] not used
free_dircontents()
getdirent()
IsFileSystemFAT()
do_wild()
mapattr()
mapname()
checkdir()
isfloppy()
IsFileNameValid()
map2fat()
SetLongNameEA()
close_outfile()
check_for_newer()
dateformat()
version()
zcalloc() (16-bit, only)
zcfree() (16-bit, only)
InitNLS()
IsUpperNLS()
ToLowerNLS()
StringLower()
screensize()
DebugMalloc()
---------------------------------------------------------------------------*/
#define UNZIP_INTERNAL
#include "unzip.h"
/* fUnZip does not need anything from here except the zcalloc() & zcfree()
* function pair (when Deflate64 support is enabled in 16-bit environment).
*/
#ifndef FUNZIP
#include "os2acl.h"
extern ZCONST char Far TruncEAs[];
/* local prototypes */
#ifdef TIMESTAMP
static int SetFileTime(ZCONST char *name, ulg stamp);
#endif
#if defined(USE_EF_UT_TIME) || defined(TIMESTAMP)
static ulg Utime2DosDateTime OF((time_t uxtime));
#endif
static int getOS2filetimes OF((__GPRO__
ulg *pM_dt, ulg *pA_dt, ulg *pC_dt));
static void SetPathAttrTimes OF((__GPRO__ int flags, int dir));
static int SetEAs OF((__GPRO__ const char *path,
void *ef_block));
static int SetACL OF((__GPRO__ const char *path,
void *ef_block));
static int EvalExtraFields OF((__GPRO__ const char *path,
void *extra_field, unsigned ef_len));
static int isfloppy OF((int nDrive));
static int IsFileNameValid OF((const char *name));
static void map2fat OF((char *pathcomp, char **pEndFAT));
static int SetLongNameEA OF((char *name, char *longname));
static void InitNLS OF((void));
#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 */
/*****************************/
/* Strings used in os2.c */
/*****************************/
#ifndef SFX
static ZCONST char Far CantAllocateWildcard[] =
"warning: cannot allocate wildcard buffers\n";
#endif
static ZCONST char Far WarnDirTraversSkip[] =
"warning: skipped \"../\" path component(s) in %s\n";
static ZCONST char Far Creating[] = " creating: %-22s ";
static ZCONST char Far ConversionFailed[] =
"mapname: conversion of %s failed\n";
static ZCONST char Far Labelling[] = "labelling %c: %-22s\n";
static ZCONST char Far ErrSetVolLabel[] =
"mapname: error setting volume label\n";
static ZCONST char Far PathTooLong[] = "checkdir error: path too long: %s\n";
static ZCONST char Far CantCreateDir[] = "checkdir error: cannot create %s\n\
unable to process %s.\n";
static ZCONST char Far DirIsntDirectory[] =
"checkdir error: %s exists but is not directory\n\
unable to process %s.\n";
static ZCONST char Far PathTooLongTrunc[] =
"checkdir warning: path too long; truncating\n %s\n\
-> %s\n";
#if (!defined(SFX) || defined(SFX_EXDIR))
static ZCONST char Far CantCreateExtractDir[] =
"checkdir: cannot create extraction directory: %s\n";
#endif
unzip-6.0/os2/os2.c view on Meta::CPAN
if ( DosQueryCtryInfo(sizeof(ctryi), &ctryc, &ctryi, &cbInfo) != NO_ERROR )
return 0;
return ctryi.fsDateFmt;
}
int SetFileSize(FILE *file, ulg filesize)
{
#ifdef __32BIT__
return DosSetFileSize(fileno(file), (size_t)filesize) ? -1 : 0;
#else
return 0;
#endif
}
long GetFileTime(ZCONST char *name)
{
#ifdef __32BIT__
FILESTATUS3 fs;
#else
FILESTATUS fs;
#endif
USHORT nDate, nTime;
if ( DosQueryPathInfo((PSZ) name, 1, (PBYTE) &fs, sizeof(fs)) )
return -1;
nDate = * (USHORT *) &fs.fdateLastWrite;
nTime = * (USHORT *) &fs.ftimeLastWrite;
return ((ULONG) nDate) << 16 | nTime;
}
#ifdef TIMESTAMP
static int SetFileTime(ZCONST char *name, ulg stamp) /* swiped from Zip */
{
FILESTATUS fs;
USHORT fd, ft;
if (DosQueryPathInfo((PSZ) name, FIL_STANDARD, (PBYTE) &fs, sizeof(fs)))
return -1;
fd = (USHORT) (stamp >> 16);
ft = (USHORT) stamp;
fs.fdateLastWrite = fs.fdateCreation = * (FDATE *) &fd;
fs.ftimeLastWrite = fs.ftimeCreation = * (FTIME *) &ft;
if (DosSetPathInfo((PSZ) name, FIL_STANDARD, (PBYTE) &fs, sizeof(fs), 0))
return -1;
return 0;
}
int stamp_file(ZCONST char *fname, time_t modtime)
{
return SetFileTime(fname, Utime2DosDateTime(modtime));
}
#endif /* TIMESTAMP */
/* The following DOS date/time structures are machine-dependent as they
* assume "little-endian" byte order. For OS/2-specific code, which
* is run on x86 CPUs (or emulators?), this assumption is valid; but
* care should be taken when using this code as template for other ports.
*/
typedef union {
ULONG timevalue; /* combined value, useful for comparisons */
struct {
FTIME ft; /* system file time record:
* USHORT twosecs : 5
* USHORT minutes : 6;
* USHORT hours : 5; */
FDATE fd; /* system file date record:
* USHORT day : 5
* USHORT month : 4;
* USHORT year : 7; */
} _fdt;
} F_DATE_TIME, *PF_DATE_TIME;
#if defined(USE_EF_UT_TIME) || defined(TIMESTAMP)
static ulg Utime2DosDateTime(uxtime)
time_t uxtime;
{
F_DATE_TIME dosfiletime;
struct tm *t;
/* round up to even seconds */
/* round up (down if "up" overflows) to even seconds */
if (((ulg)uxtime) & 1)
uxtime = (uxtime + 1 > uxtime) ? uxtime + 1 : uxtime - 1;
t = localtime(&(uxtime));
if (t == (struct tm *)NULL) {
/* time conversion error; use current time instead, hoping
that localtime() does not reject it as well! */
time_t now = time(NULL);
t = localtime(&now);
}
if (t->tm_year < 80) {
dosfiletime._fdt.ft.twosecs = 0;
dosfiletime._fdt.ft.minutes = 0;
dosfiletime._fdt.ft.hours = 0;
dosfiletime._fdt.fd.day = 1;
dosfiletime._fdt.fd.month = 1;
dosfiletime._fdt.fd.year = 0;
} else {
dosfiletime._fdt.ft.twosecs = t->tm_sec >> 1;
dosfiletime._fdt.ft.minutes = t->tm_min;
dosfiletime._fdt.ft.hours = t->tm_hour;
dosfiletime._fdt.fd.day = t->tm_mday;
dosfiletime._fdt.fd.month = t->tm_mon + 1;
dosfiletime._fdt.fd.year = t->tm_year - 80;
}
return dosfiletime.timevalue;
} /* end function Utime2DosDateTime() */
#endif /* USE_EF_UT_TIME || TIMESTAMP */
static int getOS2filetimes(__GPRO__ ulg *pM_dt, ulg *pA_dt, ulg *pC_dt)
{
#ifdef USE_EF_UT_TIME
unsigned eb_izux_flg;
iztimes z_utime;
#endif
/* Copy and/or convert time and date variables, if necessary; */
/* return a flag indicating which time stamps are available. */
#ifdef USE_EF_UT_TIME
if (G.extra_field &&
#ifdef IZ_CHECK_TZ
G.tz_is_valid &&
#endif
((eb_izux_flg = ef_scan_for_izux(G.extra_field,
G.lrec.extra_field_length, 0, G.lrec.last_mod_dos_datetime,
&z_utime, NULL)) & EB_UT_FL_MTIME))
{
TTrace((stderr, "getOS2filetimes: UT e.f. modif. time = %lu\n",
z_utime.mtime));
*pM_dt = Utime2DosDateTime(z_utime.mtime);
if (eb_izux_flg & EB_UT_FL_ATIME) {
TTrace((stderr, "getOS2filetimes: UT e.f. access time = %lu\n",
z_utime.atime));
*pA_dt = Utime2DosDateTime(z_utime.atime);
}
if (eb_izux_flg & EB_UT_FL_CTIME) {
TTrace((stderr, "getOS2filetimes: UT e.f. creation time = %lu\n",
z_utime.ctime));
*pC_dt = Utime2DosDateTime(z_utime.ctime);
} else {
/* no creation time value supplied, set it to modification time */
*pC_dt = *pM_dt;
eb_izux_flg |= EB_UT_FL_CTIME;
}
return (int)eb_izux_flg;
}
#endif /* USE_EF_UT_TIME */
*pC_dt = *pM_dt = G.lrec.last_mod_dos_datetime;
TTrace((stderr, "\ngetOS2filetimes: DOS dir modific./creation time = %lu\n",
*pM_dt));
return (EB_UT_FL_MTIME | EB_UT_FL_CTIME);
}
static void SetPathAttrTimes(__GPRO__ int flags, int dir)
{
HFILE hFile;
#ifdef __32BIT__
ULONG nAction;
#else
USHORT nAction;
#endif
FILESTATUS fs;
USHORT nLength;
char szName[CCHMAXPATH];
ulg Mod_dt, Acc_dt, Cre_dt;
int gotTimes;
strcpy(szName, G.filename);
nLength = strlen(szName);
if (szName[nLength - 1] == '/')
szName[nLength - 1] = 0;
if (dir)
{
if ( DosQueryPathInfo(szName, FIL_STANDARD, (PBYTE) &fs, sizeof(fs)) )
return;
}
else
{
/* for regular files, open them and operate on the file handle, to
work around certain network operating system bugs ... */
if ( DosOpen(szName, &hFile, &nAction, 0, 0,
OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW,
OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_READWRITE, 0) )
return;
if ( DosQueryFileInfo(hFile, FIL_STANDARD, (PBYTE) &fs, sizeof(fs)) )
return;
}
if (uO.D_flag <= (dir ? 1 : 0)) {
/* set date/time stamps */
gotTimes = getOS2filetimes(__G__ &Mod_dt, &Acc_dt, &Cre_dt);
if (gotTimes & EB_UT_FL_MTIME) {
fs.fdateLastWrite = ((F_DATE_TIME *)&Mod_dt)->_fdt.fd;
fs.ftimeLastWrite = ((F_DATE_TIME *)&Mod_dt)->_fdt.ft;
}
unzip-6.0/os2/os2.c view on Meta::CPAN
fclose(G.outfile);
/* set extra fields, both stored-in-zipfile and .LONGNAME flavors */
if (G.extra_field) { /* zipfile extra field may have extended attribs */
int err = EvalExtraFields(__G__ G.filename, G.extra_field,
G.lrec.extra_field_length);
if (err == IZ_EF_TRUNC) {
if (uO.qflag)
Info(slide, 1, ((char *)slide, "%-22s ",
FnFilter1(G.filename)));
Info(slide, 1, ((char *)slide, LoadFarString(TruncEAs),
makeword(G.extra_field+2)-10, uO.qflag? "\n" : ""));
}
}
if (G.os2.longnameEA) {
#ifdef DEBUG
int e =
#endif
SetLongNameEA(G.filename, G.os2.lastpathcomp);
Trace((stderr, "close_outfile: SetLongNameEA() returns %d\n", e));
free(G.os2.lastpathcomp);
}
/* set date/time and permissions */
SetPathAttrTimes(__G__ G.pInfo->file_attr, 0);
} /* end function close_outfile() */
/******************************/
/* Function check_for_newer() */
/******************************/
int check_for_newer(__G__ filename) /* return 1 if existing file newer or equal; */
__GDEF
char *filename; /* 0 if older; -1 if doesn't exist yet */
{
ulg existing, archive;
#ifdef USE_EF_UT_TIME
iztimes z_utime;
#endif
if ((existing = (ulg)GetFileTime(filename)) == (ulg)-1)
return DOES_NOT_EXIST;
#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.lrec.extra_field_length, 0,
G.lrec.last_mod_dos_datetime, &z_utime, NULL)
& EB_UT_FL_MTIME))
{
TTrace((stderr, "check_for_newer: using Unix extra field mtime\n"));
archive = Utime2DosDateTime(z_utime.mtime);
} else {
archive = G.lrec.last_mod_dos_datetime;
}
#else /* !USE_EF_UT_TIME */
archive = G.lrec.last_mod_dos_datetime;
#endif /* ?USE_EF_UT_TIME */
return (existing >= archive);
} /* end function check_for_newer() */
#ifndef SFX
/*************************/
/* Function dateformat() */
/*************************/
int dateformat()
{
/*-----------------------------------------------------------------------------
For those operating systems which support it, this function returns a value
which tells how national convention says that numeric dates are displayed.
Return values are DF_YMD, DF_DMY and DF_MDY.
-----------------------------------------------------------------------------*/
switch (GetCountryInfo()) {
case 0:
return DF_MDY;
case 1:
return DF_DMY;
case 2:
return DF_YMD;
}
return DF_MDY; /* default if error */
} /* end function dateformat() */
/************************/
/* Function version() */
/************************/
void version(__G)
__GDEF
{
int len;
#if defined(__IBMC__) || defined(__WATCOMC__) || defined(_MSC_VER)
char buf[80];
#endif
len = sprintf((char *)slide, LoadFarString(CompiledWith),
#if defined(__GNUC__)
# ifdef __EMX__ /* __EMX__ is defined as "1" only (sigh) */
( run in 1.100 second using v1.01-cache-2.11-cpan-ceb78f64989 )