Archive-Unzip-Burst

 view release on metacpan or  search on metacpan

unzip-6.0/theos/theos.c  view on Meta::CPAN


  Contains:  do_wild()           <-- generic enough to put in fileio.c?
             mapattr()
             mapname()
             checkdir()
             close_outfile()
             defer_dir_attribs()
             set_direc_attribs()
             stamp_file()
             version()

  ---------------------------------------------------------------------------*/


#define UNZIP_INTERNAL
#include "unzip.h"
#include <direct.h>
#include <sc.h>
#include <fdb.h>
#include <nuc.h>
#include <peek.h>

/* standard function doesn't work with a trailing / */
#define opendir(a) _opendir(a)
extern DIR* _opendir(const char* dirpath);

#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 */
    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 */

#define _FDB_SHARED_EXECUTE_PROTECT _FDB_MODIFIED

uch _um2tm_(ush mask);

int chmodv2_3(const char *fname, short mask)
{
    return _filechange(fname,'p',(size_t) _um2tm_(mask)|0x80);
}

int chlen(char *fname, unsigned short reclen, unsigned short keylen)
{
    size_t a = reclen + ((size_t) keylen << 16);
    return _filechange(fname,'ma',(size_t) &a);
}

#define chgrow(a,b) ((int) _filechange(a,'g',(size_t)(b)))
#define chorg(a,b)  ((int) _filechange(a,'m',(size_t)(b)))

#ifndef SFX

/*************************/
/* Function dateformat() */
/*************************/

int dateformat()
{
/*---------------------------------------------------------------------------
    For those operating systems that support it, this function returns a
    value that tells how national convention says that numeric dates are
    displayed.  Return values are DF_YMD, DF_DMY and DF_MDY (the meanings
    should be fairly obvious).
  ---------------------------------------------------------------------------*/

    switch (peeknuc(&NUC->dateopt) & (aform|eform|iform)) {
    case aform: return DF_MDY;
    case eform: return DF_DMY;
    }
    return DF_YMD;
}


/* usual THEOS match function for filenames */

/* match from Phase One Systems */

/* Returns non-zero if string matches the literal mask */
int match(string, pattern, ignore_case __WDL)
    ZCONST char *string;
    ZCONST char *pattern;
    int ignore_case;            /* unused in this variant of match()! */
    __WDLDEF
{
    int matched, k;

    if (!(*pattern))
        return 1;
    for(;;) {
        if ( (!(*string)) && (!(*pattern)) )
            return(1);
        else if ( !(*pattern) )
            return(0);
        else if (*pattern == '*') {
            if (!*(pattern+1))
                return(1);
            k=0;

unzip-6.0/theos/theos.c  view on Meta::CPAN


/* portabilibity functions to ensure access to port 2.0 and new ports */

int isv2_3()
{
    return G.extra_field[0] == 'T' && G.extra_field[1] == 'h';
}

int isv2_3lib()
{
    return isv2_3() && S_ISLIB((G.pInfo->file_attr >> 8) & 0xFF);
}

int isv2_3dir()
{
    return isv2_3() && S_ISDIR((G.pInfo->file_attr >> 8) & 0xFF);
}

#ifdef OLD_THEOS_EXTRA
#define S_IFMT_     0xf800      /* type of file */
#define S_IFLIB_    0x8000      /* library */
#define S_IFDIR_    0x4000      /* directory */

#define S_ISLIB_(a) (((a) & 0xff) == _FDB_STAT_LIBRARY)
#define S_ISDIR_(a) (((a) & 0xff) == _FDB_STAT_DIRECTORY)

struct extra_block
{
    ush     signature;
    ush     size;
    ush     flags;
    ulg     filesize;
    ush     reclen;
    ush     keylen;
    uch     filegrow;
    uch     reserved[3];
};

struct extra_block *v2_0extra()
{
    return (struct extra_block *) G.extra_field;
}

int isv2_0()
{
    return ((struct extra_block *) G.extra_field)->signature == 0x4854;
}

int isv2_0lib()
{
  return isv2_0() && S_ISLIB_(G.pInfo->file_attr);
}

int isv2_0dir()
{
  return isv2_0() && S_ISDIR_(G.pInfo->file_attr);
}

#define islib() (isv2_0lib() || isv2_3lib())
#define isdir() (isv2_0dir() || isv2_3dir())
#define chmodv2_0(a,b)  ((int) _sc_168(a,'p',(size_t)(b)|0x80))
#undef chmod
#define chmod(a,b) (isv2_0() && chmodv2_0(a,b))||(isv2_3() && chmodv2_3(a,b))
#else
#define islib() isv2_3lib()
#define isdir() isv2_3dir()
#undef chmod
#define chmod(a,b) chmodv2_0(a,b)
#endif

/************************/
/*  Function mapname()  */
/************************/

int mapname(__G__ renamed)
    __GDEF
    int renamed;
/*
 * returns:
 *  MPN_OK          - no problem detected
 *  MPN_INF_TRUNC   - caution (truncated filename)
 *  MPN_INF_SKIP    - info "skip entry" (dir doesn't exist)
 *  MPN_ERR_SKIP    - error -> skip entry
 *  MPN_ERR_TOOLONG - error -> path is too long
 *  MPN_NOMEM       - error (memory allocation failed) -> skip entry
 *  [also MPN_VOL_LABEL, MPN_CREATED_DIR]
 */
{
    char pathcomp[FILNAMSIZ];      /* path-component buffer */
    char *pp, *cp=(char *)NULL;    /* character pointers */
    char *lastsemi=(char *)NULL;   /* pointer to last semi-colon in pathcomp */
#ifdef ACORN_FTYPE_NFS
    char *lastcomma=(char *)NULL;  /* pointer to last comma in pathcomp */
    RO_extra_block *ef_spark;      /* pointer Acorn FTYPE ef block */
#endif
    int killed_ddot = FALSE;       /* is set when skipping "../" pathcomp */
    int error = MPN_OK;
    register unsigned workch;      /* hold the character being tested */


/*---------------------------------------------------------------------------
    Initialize various pointers and counters and stuff.
  ---------------------------------------------------------------------------*/

    if (G.pInfo->vollabel)
        return MPN_VOL_LABEL;   /* can't set disk volume labels in Unix */

    /* can create path as long as not just freshening, or if user told us */
    G.create_dirs = (!uO.fflag || renamed);

    created_dir = FALSE;        /* not yet */

    /* user gave full pathname:  don't prepend rootpath */
    renamed_fullpath = (renamed && (*G.filename == '/'));

    if (checkdir(__G__ (char *)NULL, INIT) == MPN_NOMEM)
        return MPN_NOMEM;       /* initialize path buffer, unless no memory */

    *pathcomp = '\0';           /* initialize translation buffer */
    pp = pathcomp;              /* point to translation buffer */
    if (uO.jflag)               /* junking directories */
        cp = (char *)strrchr(G.filename, '/');
    if (cp == (char *)NULL)     /* no '/' or not junking dirs */
        cp = G.filename;        /* point to internal zipfile-member pathname */
    else
        ++cp;                   /* point to start of last component of path */

/*---------------------------------------------------------------------------

unzip-6.0/theos/theos.c  view on Meta::CPAN

    } 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));
    }
#else
    pzt->mtime = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
    pzt->atime = pzt->mtime;
#endif
}
#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;

/*---------------------------------------------------------------------------
    If symbolic links are supported, allocate a storage area, put the uncom-
    pressed "data" in it, and create the link.  Since we know it's a symbolic
    link to start with, we shouldn't have to worry about overflowing unsigned
    ints with unsigned longs.
  ---------------------------------------------------------------------------*/

    fclose(G.outfile);

    get_extattribs(__G__ &(zt.t3));

    /* set the file's access and modification times */
    if (utime(G.filename, &(zt.t2))) {
        if (uO.qflag)
            Info(slide, 0x201, ((char *)slide,
              "warning:  cannot set times for %s\n", FnFilter1(G.filename)));
        else
            Info(slide, 0x201, ((char *)slide,
              " (warning) cannot set times"));
    }

/*---------------------------------------------------------------------------
    Change the file permissions from default ones to those stored in the
    zipfile.
  ---------------------------------------------------------------------------*/

    if (chmod(G.filename, 0xffff & G.pInfo->file_attr))
        perror("chmod (file attributes) error");

/*---------------------------------------------------------------------------
    Change the file structure and set native .
  ---------------------------------------------------------------------------*/

    if (isv2_3()) {
        chorg(G.filename, G.extra_field[9]);
        chlen(G.filename,
            (ush) G.extra_field[10] | ((ush) G.extra_field[11] << 8),
            (ush) G.extra_field[12] | ((ush) G.extra_field[13] << 8));
        chgrow(G.filename, G.extra_field[14]);
    }
#if OLD_THEOS_EXTRA
     else if (isv2_0()) {
        chorg(G.filename, G.pInfo->file_attr & 0xFF);
        chlen(G.filename, v2_0extra()->reclen, v2_0extra()->keylen);
        chgrow(G.filename, v2_0extra()->filegrow);
    }
#endif
} /* end function close_outfile() */

#endif /* !MTS */




#ifdef SET_DIR_ATTRIB
/* messages of code for setting directory attributes */
static ZCONST char Far DirlistUidGidFailed[] =
  "warning:  cannot set UID %d and/or GID %d for %s\n";
static ZCONST char Far DirlistUtimeFailed[] =
  "warning:  cannot set modification, access times for %s\n";
#  ifndef NO_CHMOD
  static ZCONST char Far DirlistChmodFailed[] =
    "warning:  cannot set permissions for %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;

    get_extattribs(__G__ &(d_entry->u.t3));
    return PK_OK;
} /* end function defer_dir_attribs() */


int set_direc_attribs(__G__ d)
    __GDEF
    direntry *d;
{
    int errval = PK_OK;

    if (utime(d->fn, &UxAtt(d)->u.t2)) {
        Info(slide, 0x201, ((char *)slide,
          LoadFarString(DirlistUtimeFailed), FnFilter1(d->fn)));
        if (!errval)
            errval = PK_WARN;
    }
    if (chmod(d->fn, 0xffff & UxAtt(d)->perms)) {
        Info(slide, 0x201, ((char *)slide,
          LoadFarString(DirlistChmodFailed), FnFilter1(d->fn)));
        /* perror("chmod (file attributes) error"); */
        if (!errval)
            errval = PK_WARN;
    }
    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
{
    char buf1[40];
    extern char Far  CompiledWith[];

    sprintf(slide, CompiledWith,
        "THEOS C ","5.28", "THEOS ", "4.x", " on ", __DATE__);
    (*G.message)((zvoid *)&G, slide, (ulg)strlen((char *)slide), 0);

} /* end function version() */

#endif /* !SFX */



( run in 1.607 second using v1.01-cache-2.11-cpan-a49fcb8fa48 )