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 )