📄 os2.c
字号:
/*---------------------------------------------------------------------------
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()
GetFileTime()
SetPathInfo()
IsEA()
SetEAs()
SizeOfEAs()
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()
InitNLS()
IsUpperNLS()
ToLowerNLS()
StringLower()
DebugMalloc()
---------------------------------------------------------------------------*/
#include "unzip.h"
char *StringLower(char *szArg);
/* local prototypes */
static int isfloppy __((int nDrive));
static int IsFileNameValid __((char *name));
static void map2fat __((char *pathcomp, char **pEndFAT));
static int SetLongNameEA __((char *name, char *longname));
static void InitNLS __((void));
#ifndef __EMX__
# if (_MSC_VER >= 600) || defined(__IBMC__)
# include <direct.h> /* have special MSC/IBM C mkdir prototype */
# else /* own prototype because dir.h conflicts? */
int mkdir(const char *path);
# endif
# define MKDIR(path,mode) mkdir(path)
#else
# define MKDIR(path,mode) mkdir(path,mode)
#endif
#define INCL_NOPM
#define INCL_DOSNLS
#define INCL_DOSPROCESS
#define INCL_DOSDEVICES
#define INCL_DOSDEVIOCTL
#define INCL_DOSERRORS
#include <os2.h>
#ifdef __32BIT__
USHORT DosDevIOCtl32(PVOID pData, USHORT cbData, PVOID pParms, USHORT cbParms,
USHORT usFunction, USHORT usCategory, HFILE hDevice)
{
ULONG ulParmLengthInOut = cbParms, ulDataLengthInOut = cbData;
return (USHORT) DosDevIOCtl(hDevice, usCategory, usFunction,
pParms, cbParms, &ulParmLengthInOut,
pData, cbData, &ulDataLengthInOut);
}
# define DosDevIOCtl DosDevIOCtl32
#else
# define DosDevIOCtl DosDevIOCtl2
#endif
#define EAID 0x0009
typedef struct
{
ush nID;
ush nSize;
ulg lSize;
}
EAHEADER, *PEAHEADER;
#ifndef __32BIT__
typedef struct
{
ULONG oNextEntryOffset;
BYTE fEA;
BYTE cbName;
USHORT cbValue;
CHAR szName[1];
}
FEA2, *PFEA2;
typedef struct
{
ULONG cbList;
FEA2 list[1];
}
FEA2LIST, *PFEA2LIST;
#define DosSetPathInfo(p1, p2, p3, p4, p5) \
DosSetPathInfo(p1, p2, p3, p4, p5, 0)
#define DosQueryPathInfo(p1, p2, p3, p4) \
DosQPathInfo(p1, p2, p3, p4, 0)
#define DosMapCase DosCaseMap
#define DosQueryCtryInfo DosGetCtryInfo
#endif /* !__32BIT__ */
/*
* @(#) dir.h 1.4 87/11/06 Public Domain.
*/
#define MAXNAMLEN 256
#define MAXPATHLEN 256
#define A_RONLY 0x01
#define A_HIDDEN 0x02
#define A_SYSTEM 0x04
#define A_LABEL 0x08
#define A_DIR 0x10
#define A_ARCHIVE 0x20
struct direct
{
ino_t d_ino; /* a bit of a farce */
int d_reclen; /* more farce */
int d_namlen; /* length of d_name */
char d_name[MAXNAMLEN + 1]; /* null terminated */
/* nonstandard fields */
long d_size; /* size in bytes */
unsigned d_mode; /* MS-DOS or OS/2 file attributes */
unsigned d_time;
unsigned d_date;
};
/* The fields d_size and d_mode are extensions by me (Kai Uwe Rommel). The
* find_first and find_next calls deliver these data without any extra cost.
* If these data are needed, the fields save a lot of extra calls to stat()
* (each stat() again performs a find_first call !).
*/
struct _dircontents
{
char *_d_entry;
long _d_size;
unsigned _d_mode, _d_time, _d_date;
struct _dircontents *_d_next;
};
typedef struct _dirdesc
{
int dd_id; /* uniquely identify each open directory */
long dd_loc; /* where we are in directory entry is this */
struct _dircontents *dd_contents; /* pointer to contents of dir */
struct _dircontents *dd_cp; /* pointer to current position */
}
DIR;
extern DIR *opendir(char *);
extern struct direct *readdir(DIR *);
extern void seekdir(DIR *, long);
extern long telldir(DIR *);
extern void closedir(DIR *);
#define rewinddir(dirp) seekdir(dirp, 0L)
int IsFileSystemFAT(char *dir);
char *StringLower(char *);
/*
* @(#)dir.c 1.4 87/11/06 Public Domain.
*/
#ifdef __32BIT__
# define DosFindFirst(p1, p2, p3, p4, p5, p6) \
DosFindFirst(p1, p2, p3, p4, p5, p6, 1)
#else
# define DosQueryCurrentDisk DosQCurDisk
# define DosQueryFSAttach(p1, p2, p3, p4, p5) \
DosQFSAttach(p1, p2, p3, p4, p5, 0)
# define DosQueryPathInfo(p1, p2, p3, p4) \
DosQPathInfo(p1, p2, p3, p4, 0)
# define DosSetPathInfo(p1, p2, p3, p4, p5) \
DosSetPathInfo(p1, p2, p3, p4, p5, 0)
# define DosEnumAttribute(p1, p2, p3, p4, p5, p6, p7) \
DosEnumAttribute(p1, p2, p3, p4, p5, p6, p7, 0)
# define DosFindFirst(p1, p2, p3, p4, p5, p6) \
DosFindFirst(p1, p2, p3, p4, p5, p6, 0)
# define DosMapCase DosCaseMap
#endif
#ifndef S_IFMT
# define S_IFMT 0xF000
#endif
#ifdef __WATCOMC__
unsigned char __near _osmode = OS2_MODE;
#endif
#ifndef SFX
static char *getdirent(char *);
static void free_dircontents(struct _dircontents *);
static int attributes = A_DIR | A_HIDDEN | A_SYSTEM;
# ifdef __32BIT__
static HDIR hdir;
static ULONG count;
static FILEFINDBUF3 find;
# else
static HDIR hdir; /* GRR: is there a difference? HDIR2?? */
static USHORT count;
static FILEFINDBUF find;
# endif
#endif /* !SFX */
static int created_dir; /* used by mapname(), checkdir() */
static int renamed_fullpath; /* ditto */
static int fnlen; /* ditto */
#ifdef __32BIT__
static ULONG nLabelDrive; /* ditto */
#else
static USHORT nLabelDrive;
#endif
static int longnameEA; /* checkdir(), close_outfile() */
static char *lastpathcomp; /* ditto */
int GetCountryInfo(void)
{
COUNTRYINFO ctryi;
COUNTRYCODE ctryc;
#ifdef __32BIT__
ULONG cbInfo;
#else
USHORT cbInfo;
#endif
ctryc.country = ctryc.codepage = 0;
if ( DosQueryCtryInfo(sizeof(ctryi), &ctryc, &ctryi, &cbInfo) != NO_ERROR )
return 0;
return ctryi.fsDateFmt;
}
long GetFileTime(char *name)
{
#ifdef __32BIT__
FILESTATUS3 fs;
#else
FILESTATUS fs;
#endif
USHORT nDate, nTime;
if ( DosQueryPathInfo(name, 1, (PBYTE) &fs, sizeof(fs)) )
return -1;
nDate = * (USHORT *) &fs.fdateLastWrite;
nTime = * (USHORT *) &fs.ftimeLastWrite;
return ((ULONG) nDate) << 16 | nTime;
}
void SetPathInfo(char *path, ush moddate, ush modtime, int flags)
{
union {
FDATE fd; /* system file date record */
ush zdate; /* date word */
} ud;
union {
FTIME ft; /* system file time record */
ush ztime; /* time word */
} ut;
FILESTATUS fs;
USHORT nLength;
char szName[CCHMAXPATH];
strcpy(szName, path);
nLength = strlen(szName);
if (szName[nLength - 1] == '/')
szName[nLength - 1] = 0;
if ( DosQueryPathInfo(szName, FIL_STANDARD, (PBYTE) &fs, sizeof(fs)) )
return;
ud.zdate = moddate;
ut.ztime = modtime;
fs.fdateLastWrite = fs.fdateCreation = ud.fd;
fs.ftimeLastWrite = fs.ftimeCreation = ut.ft;
if ( flags != -1 )
fs.attrFile = flags; /* hidden, system, archive, read-only */
DosSetPathInfo(szName, FIL_STANDARD, (PBYTE) &fs, sizeof(fs), 0);
}
typedef struct
{
ULONG cbList; /* length of value + 22 */
#ifdef __32BIT__
ULONG oNext;
#endif
BYTE fEA; /* 0 */
BYTE cbName; /* length of ".LONGNAME" = 9 */
USHORT cbValue; /* length of value + 4 */
BYTE szName[10]; /* ".LONGNAME" */
USHORT eaType; /* 0xFFFD for length-preceded ASCII */
USHORT eaSize; /* length of value */
BYTE szValue[CCHMAXPATH];
}
FEALST;
int IsEA(void *extra_field)
{
EAHEADER *pEAblock = (PEAHEADER) extra_field;
return extra_field != NULL && pEAblock -> nID == EAID;
}
void SetEAs(char *path, void *eablock)
{
EAHEADER *pEAblock = (PEAHEADER) eablock;
#ifdef __32BIT__
EAOP2 eaop;
PFEA2LIST pFEA2list;
#else
EAOP eaop;
PFEALIST pFEAlist;
PFEA pFEA;
PFEA2LIST pFEA2list;
PFEA2 pFEA2;
ULONG nLength2;
#endif
USHORT nLength;
char szName[CCHMAXPATH];
if ( !IsEA(eablock) )
return;
strcpy(szName, path);
nLength = strlen(szName);
if (szName[nLength - 1] == '/')
szName[nLength - 1] = 0;
if ( (pFEA2list = (PFEA2LIST) malloc((size_t) pEAblock -> lSize)) == NULL )
return;
if ( memextract((char *) pFEA2list, pEAblock -> lSize,
(char *) (pEAblock + 1),
pEAblock -> nSize - sizeof(pEAblock -> lSize)) )
{
free(pFEA2list);
return;
}
#ifdef __32BIT__
eaop.fpGEA2List = NULL;
eaop.fpFEA2List = pFEA2list;
#else
pFEAlist = (PVOID) pFEA2list;
pFEA2 = pFEA2list -> list;
pFEA = pFEAlist -> list;
do
{
nLength2 = pFEA2 -> oNextEntryOffset;
nLength = sizeof(FEA) + pFEA2 -> cbName + 1 + pFEA2 -> cbValue;
memcpy(pFEA, (PCH) pFEA2 + sizeof(pFEA2 -> oNextEntryOffset), nLength);
pFEA2 = (PFEA2) ((PCH) pFEA2 + nLength2);
pFEA = (PFEA) ((PCH) pFEA + nLength);
}
while ( nLength2 != 0 );
pFEAlist -> cbList = (PCH) pFEA - (PCH) pFEAlist;
eaop.fpGEAList = NULL;
eaop.fpFEAList = pFEAlist;
#endif
eaop.oError = 0;
DosSetPathInfo(szName, FIL_QUERYEASIZE, (PBYTE) &eaop, sizeof(eaop), 0);
if (!tflag && (qflag < 2))
PRINTF(" (%ld bytes EA's)", pFEA2list -> cbList);
free(pFEA2list);
}
ulg SizeOfEAs(void *extra_field)
{
EAHEADER *pEAblock = (PEAHEADER)extra_field;
if (extra_field != NULL && makeword((uch *)&pEAblock->nID) == EAID)
return makelong((uch *)&pEAblock->lSize);
return 0L;
}
#ifdef SFX
char *GetLoadPath(void)
{
#ifdef __32BIT__ /* generic for 32-bit API */
PTIB pptib;
PPIB pppib;
char *szPath;
DosGetInfoBlocks(&pptib, &pppib);
szPath = pppib -> pib_pchenv;
while (*szPath) /* find end of process environment */
szPath = strchr(szPath, 0) + 1;
return szPath + 1; /* .exe file name follows environment */
#else /* 16-bit, specific for MS C 6.00, note: requires large data model */
extern char _far *_pgmptr;
return _pgmptr;
#endif
} /* end function GetLoadPath() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -