📄 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() 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() InitNLS() IsUpperNLS() ToLowerNLS() StringLower() DebugMalloc() ---------------------------------------------------------------------------*/#define UNZIP_INTERNAL#include "unzip.h"#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));#endifstatic 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));/*****************************//* Strings used in os2.c *//*****************************/#ifndef SFX static char Far CantAllocateWildcard[] = "warning: cannot allocate wildcard buffers\n";#endifstatic char Far Creating[] = " creating: %-22s ";static char Far ConversionFailed[] = "mapname: conversion of %s failed\n";static char Far Labelling[] = "labelling %c: %-22s\n";static char Far ErrSetVolLabel[] = "mapname: error setting volume label\n";static char Far PathTooLong[] = "checkdir error: path too long: %s\n";static char Far CantCreateDir[] = "checkdir error: cannot create %s\n\ unable to process %s.\n";static char Far DirIsntDirectory[] = "checkdir error: %s exists but is not directory\n\ unable to process %s.\n";static char Far PathTooLongTrunc[] = "checkdir warning: path too long; truncating\n %s\n\ -> %s\n";#if (!defined(SFX) || defined(SFX_EXDIR)) static char Far CantCreateExtractDir[] = "checkdir: cannot create extraction directory: %s\n";#endif#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#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#endiftypedef struct{ ush nID; ush nSize; ulg lSize;}EFHEADER, *PEFHEADER;#ifdef __32BIT__#define DosFindFirst(p1, p2, p3, p4, p5, p6) \ DosFindFirst(p1, p2, p3, p4, p5, p6, 1)#elsetypedef struct{ ULONG oNextEntryOffset; BYTE fEA; BYTE cbName; USHORT cbValue; CHAR szName[1];}FEA2, *PFEA2;typedef struct{ ULONG cbList; FEA2 list[1];}FEA2LIST, *PFEA2LIST;#define DosQueryCurrentDisk DosQCurDisk#define DosQueryFSAttach(p1, p2, p3, p4, p5) \ DosQFSAttach(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#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 DosQueryFileInfo DosQFileInfo#define DosMapCase DosCaseMap#define DosQueryCtryInfo DosGetCtryInfo#endif /* !__32BIT__ *//* * @(#) dir.h 1.4 87/11/06 Public Domain. */#define A_RONLY 0x01#define A_HIDDEN 0x02#define A_SYSTEM 0x04#define A_LABEL 0x08#define A_DIR 0x10#define A_ARCHIVE 0x20const int attributes = A_DIR | A_HIDDEN | A_SYSTEM;extern DIR *opendir(__GPRO__ ZCONST char *);extern struct direct *readdir(__GPRO__ DIR *);extern void seekdir(DIR *, long);extern long telldir(DIR *);extern void closedir(DIR *);#define rewinddir(dirp) seekdir(dirp, 0L)int IsFileSystemFAT(__GPRO__ ZCONST char *dir);char *StringLower(char *szArg);/* * @(#)dir.c 1.4 87/11/06 Public Domain. */#ifndef S_IFMT# define S_IFMT 0xF000#endif#ifndef SFX static char *getdirent(__GPRO__ ZCONST char *); static void free_dircontents(struct _dircontents *);#endif /* !SFX */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(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 TIMESTAMPstatic 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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -