⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vms.c

📁 zip压缩
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  Copyright (c) 1990-2002 Info-ZIP.  All rights reserved.  See the accompanying file LICENSE, version 2000-Apr-09 or later  (the contents of which are also included in unzip.h) for terms of use.  If, for some reason, all these files are missing, the Info-ZIP license  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html*//*---------------------------------------------------------------------------  vms.c                                        Igor Mandrichenko and others  This file contains routines to extract VMS file attributes from a zipfile  extra field and create a file with these attributes.  The code was almost  entirely written by Igor, with a couple of routines by GRR and lots of  modifications and fixes by Christian Spieler.  Contains:  check_format()             open_outfile()             find_vms_attrs()             flush()             close_outfile()             dos_to_unix_time()         (TIMESTAMP only)             stamp_file()               (TIMESTAMP only)             do_wild()             mapattr()             mapname()             checkdir()             check_for_newer()             return_VMS             screensize()             screenlinewrap()             version()  ---------------------------------------------------------------------------*/#ifdef VMS                      /* VMS only! */#define UNZIP_INTERNAL#include "unzip.h"#include "vms.h"#include "vmsdefs.h"#ifdef MORE#  include <ttdef.h>#endif#include <lib$routines.h>#include <unixlib.h>#define ASYNCH_QIO              /* Use asynchronous PK-style QIO writes *//* buffer size for a single block write (using RMS or QIO WRITEVBLK),   must be less than 64k and a multiple of 512 ! */#define BUFS512 (((OUTBUFSIZ>0xFFFF) ? 0xFFFF : OUTBUFSIZ) & (~511))/* buffer size for record output (RMS limit for max. record size) */#define BUFSMAXREC 32767/* allocation size for RMS and QIO output buffers */#define BUFSALLOC (BUFS512 * 2 > BUFSMAXREC ? BUFS512 * 2 : BUFSMAXREC)        /* locbuf size */#define OK(s)   ((s)&1)         /* VMS success or warning status */#define STRICMP(s1,s2)  STRNICMP(s1,s2,2147483647)/* *   Local static storage */static struct FAB       fileblk;static struct XABDAT    dattim;static struct XABRDT    rdt;static struct RAB       rab;static struct NAM       nam;static struct FAB *outfab = NULL;static struct RAB *outrab = NULL;static struct XABFHC *xabfhc = NULL;static struct XABDAT *xabdat = NULL;static struct XABRDT *xabrdt = NULL;static struct XABPRO *xabpro = NULL;static struct XABKEY *xabkey = NULL;static struct XABALL *xaball = NULL;static struct XAB *first_xab = NULL, *last_xab = NULL;static char query = '\0';static uch rfm;static uch locbuf[BUFSALLOC];           /* Space for 2 buffers of BUFS512 */static unsigned loccnt = 0;static uch *locptr;static char got_eol = 0;struct bufdsc{    struct bufdsc *next;    uch *buf;    unsigned bufcnt;};static struct bufdsc b1, b2, *curbuf;   /* buffer ring for asynchronous I/O */static int  _flush_blocks(__GPRO__ uch *rawbuf, unsigned size, int final_flag),            _flush_stream(__GPRO__ uch *rawbuf, unsigned size, int final_flag),            _flush_varlen(__GPRO__ uch *rawbuf, unsigned size, int final_flag),            _flush_qio(__GPRO__ uch *rawbuf, unsigned size, int final_flag),            _close_rms(__GPRO),            _close_qio(__GPRO),#ifdef ASYNCH_QIO            WriteQIO(__GPRO__ uch *buf, unsigned len),#endif            WriteBuffer(__GPRO__ uch *buf, unsigned len),            WriteRecord(__GPRO__ uch *rec, unsigned len);static int  (*_flush_routine)(__GPRO__ uch *rawbuf, unsigned size,                              int final_flag),            (*_close_routine)(__GPRO);static void init_buf_ring(void);static void set_default_datetime_XABs(__GPRO);static int  create_default_output(__GPRO),            create_rms_output(__GPRO),            create_qio_output(__GPRO);static int  replace(__GPRO);static int  find_vms_attrs(__GPRO);static void free_up(void);#ifdef CHECK_VERSIONSstatic int  get_vms_version(char *verbuf, int len);#endif /* CHECK_VERSIONS */static unsigned find_eol(uch *p, unsigned n, unsigned *l);#ifdef TIMESTAMPstatic time_t mkgmtime(struct tm *tm);static void uxtime2vmstime(time_t utimeval, long int binval[2]);#endif /* TIMESTAMP */static void vms_msg(__GPRO__ char *string, int status);int check_format(__G)    __GDEF{    int rtype;    struct FAB fab;    fab = cc$rms_fab;    fab.fab$l_fna = G.zipfn;    fab.fab$b_fns = strlen(G.zipfn);    if ((sys$open(&fab) & 1) == 0)    {        Info(slide, 1, ((char *)slide, "\n\     error:  cannot open zipfile [ %s ] (access denied?).\n\n",          FnFilter1(G.zipfn)));        return PK_ERR;    }    rtype = fab.fab$b_rfm;    sys$close(&fab);    if (rtype == FAB$C_VAR || rtype == FAB$C_VFC)    {        Info(slide, 1, ((char *)slide, "\n\     Error:  zipfile is in variable-length record format.  Please\n\     run \"bilf l %s\" to convert the zipfile to stream-LF\n\     record format.  (BILF is available at various VMS archives.)\n\n",          FnFilter1(G.zipfn)));        return PK_ERR;    }    return PK_COOL;}#define PRINTABLE_FORMAT(x)      ( (x) == FAB$C_VAR     \                                || (x) == FAB$C_STMLF   \                                || (x) == FAB$C_STMCR   \                                || (x) == FAB$C_STM     )/* VMS extra field types */#define VAT_NONE    0#define VAT_IZ      1   /* old Info-ZIP format */#define VAT_PK      2   /* PKWARE format *//* *  open_outfile() assignments: * *  VMS attributes ?        create_xxx      _flush_xxx *  ----------------        ----------      ---------- *  not found               'default'       text mode ? *                                          yes -> 'stream' *                                          no  -> 'block' * *  yes, in IZ format       'rms'           uO.cflag ? *                                          yes -> switch (fab.rfm) *                                              VAR  -> 'varlen' *                                              STM* -> 'stream' *                                              default -> 'block' *                                          no -> 'block' * *  yes, in PK format       'qio'           uO.cflag ? *                                          yes -> switch (pka_rattr) *                                              VAR  -> 'varlen' *                                              STM* -> 'stream' *                                              default -> 'block' *                                          no -> 'qio' * *  "text mode" == G.pInfo->textmode || (uO.cflag && !uO.bflag) *  (simplified, for complete expression see create_default_output() code) */int open_outfile(__G)           /* return 1 (PK_WARN) if fail */    __GDEF{    switch (find_vms_attrs(__G))    {        case VAT_NONE:        default:            return  create_default_output(__G);        case VAT_IZ:            return  create_rms_output(__G);        case VAT_PK:            return  create_qio_output(__G);    }}static void init_buf_ring(){    locptr = &locbuf[0];    loccnt = 0;    b1.buf = &locbuf[0];    b1.bufcnt = 0;    b1.next = &b2;    b2.buf = &locbuf[BUFS512];    b2.bufcnt = 0;    b2.next = &b1;    curbuf = &b1;}/* Static data storage for time conversion: *//*   string constants for month names */static ZCONST char *month[] =            {"JAN", "FEB", "MAR", "APR", "MAY", "JUN",             "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};/*   buffer for time string */static char timbuf[24];         /* length = first entry in "date_str" + 1 *//*   fixed-length string descriptor for timbuf: */static ZCONST struct dsc$descriptor date_str =            {sizeof(timbuf)-1, DSC$K_DTYPE_T, DSC$K_CLASS_S, timbuf};static void set_default_datetime_XABs(__GPRO){    unsigned yr, mo, dy, hh, mm, ss;#ifdef USE_EF_UT_TIME    iztimes z_utime;    struct tm *t;    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))        t = localtime(&(z_utime.mtime));    else        t = (struct tm *)NULL;    if (t != (struct tm *)NULL)    {        yr = t->tm_year + 1900;        mo = t->tm_mon;        dy = t->tm_mday;        hh = t->tm_hour;        mm = t->tm_min;        ss = t->tm_sec;    }    else    {        yr = ((G.lrec.last_mod_dos_datetime >> 25) & 0x7f) + 1980;        mo = ((G.lrec.last_mod_dos_datetime >> 21) & 0x0f) - 1;        dy = (G.lrec.last_mod_dos_datetime >> 16) & 0x1f;        hh = (G.lrec.last_mod_dos_datetime >> 11) & 0x1f;        mm = (G.lrec.last_mod_dos_datetime >> 5) & 0x3f;        ss = (G.lrec.last_mod_dos_datetime << 1) & 0x3e;    }#else /* !USE_EF_UT_TIME */    yr = ((G.lrec.last_mod_dos_datetime >> 25) & 0x7f) + 1980;    mo = ((G.lrec.last_mod_dos_datetime >> 21) & 0x0f) - 1;    dy = (G.lrec.last_mod_dos_datetime >> 16) & 0x1f;    hh = (G.lrec.last_mod_dos_datetime >> 11) & 0x1f;    mm = (G.lrec.last_mod_dos_datetime >> 5) & 0x3f;    ss = (G.lrec.last_mod_dos_datetime << 1) & 0x1f;#endif /* ?USE_EF_UT_TIME */    dattim = cc$rms_xabdat;     /* fill XABs with default values */    rdt = cc$rms_xabrdt;    sprintf(timbuf, "%02u-%3s-%04u %02u:%02u:%02u.00", dy, month[mo],            yr, hh, mm, ss);    sys$bintim(&date_str, &dattim.xab$q_cdt);    memcpy(&rdt.xab$q_rdt, &dattim.xab$q_cdt, sizeof(rdt.xab$q_rdt));}static int create_default_output(__GPRO)      /* return 1 (PK_WARN) if fail */{    int ierr;    int text_output, bin_fixed;    /* extract the file in text (variable-length) format, when     * a) explicitely requested by the user (through the -a option)     *  or     * b) piping to SYS$OUTPUT, unless "binary" piping was requested     *    by the user (through the -b option)     */    text_output = G.pInfo->textmode ||                  (uO.cflag &&                   (!uO.bflag || (!(uO.bflag - 1) && G.pInfo->textfile)));    /* use fixed length 512 byte record format for disk file when     * a) explicitly requested by the user (-b option)     *  and     * b) entry is not extracted in text mode     */    bin_fixed = !text_output &&                (uO.bflag != 0) && ((uO.bflag != 1) || !G.pInfo->textfile);    rfm = FAB$C_STMLF;  /* Default, stream-LF format from VMS or UNIX */    if (!uO.cflag)              /* Redirect output */    {        rab = cc$rms_rab;       /* fill RAB with default values */        fileblk = cc$rms_fab;   /* fill FAB with default values */        outfab = &fileblk;        outfab->fab$l_xab = NULL;        if (text_output)        {   /* Default format for output `real' text file */            outfab->fab$b_rfm = FAB$C_VAR;      /* variable length records */            outfab->fab$b_rat = FAB$M_CR;       /* implied (CR) carriage ctrl */        }        else if (bin_fixed)        {   /* Default format for output `real' binary file */            outfab->fab$b_rfm = FAB$C_FIX;      /* fixed length record format */            outfab->fab$w_mrs = 512;            /* record size 512 bytes */            outfab->fab$b_rat = 0;              /* no carriage ctrl */        }        else        {   /* Default format for output misc (bin or text) file */            outfab->fab$b_rfm = FAB$C_STMLF;    /* stream-LF record format */            outfab->fab$b_rat = FAB$M_CR;       /* implied (CR) carriage ctrl */        }        outfab->fab$l_fna = G.filename;        outfab->fab$b_fns = strlen(outfab->fab$l_fna);        {            set_default_datetime_XABs(__G);            dattim.xab$l_nxt = outfab->fab$l_xab;            outfab->fab$l_xab = (void *) &dattim;        }        outfab->fab$w_ifi = 0;  /* Clear IFI. It may be nonzero after ZIP */        outfab->fab$b_fac = FAB$M_BRO | FAB$M_PUT;  /* {block|record} output */        ierr = sys$create(outfab);        if (ierr == RMS$_FEX)            ierr = replace(__G);        if (ierr == 0)          /* Canceled */            return (free_up(), PK_WARN);        if (ERR(ierr))        {            char buf[256];            sprintf(buf, "[ Cannot create output file %s ]\n", G.filename);            vms_msg(__G__ buf, ierr);            vms_msg(__G__ "", outfab->fab$l_stv);            free_up();            return PK_WARN;        }        outrab = &rab;        rab.rab$l_fab = outfab;        if (!text_output)        {            rab.rab$l_rop |= (RAB$M_BIO | RAB$M_ASY);        }        rab.rab$b_rac = RAB$C_SEQ;        if ((ierr = sys$connect(outrab)) != RMS$_NORMAL)        {#ifdef DEBUG            vms_msg(__G__ "create_default_output: sys$connect failed.\n", ierr);            vms_msg(__G__ "", outfab->fab$l_stv);#endif            Info(slide, 1, ((char *)slide,                 "Can't create output file:  %s\n", FnFilter1(G.filename)));            free_up();            return PK_WARN;        }    }                   /* end if (!uO.cflag) */    init_buf_ring();    _flush_routine = text_output ? got_eol=0,_flush_stream : _flush_blocks;    _close_routine = _close_rms;    return PK_COOL;}static int create_rms_output(__GPRO)          /* return 1 (PK_WARN) if fail */{    int ierr;    int text_output;    /* extract the file in text (variable-length) format, when     * piping to SYS$OUTPUT, unless "binary" piping was requested     * by the user (through the -b option); the "-a" option is     * ignored when extracting zip entries with VMS attributes saved     */    text_output = uO.cflag &&                  (!uO.bflag || (!(uO.bflag - 1) && G.pInfo->textfile));    rfm = outfab->fab$b_rfm;    /* Use record format from VMS extra field */    if (uO.cflag)    {        if (text_output && !PRINTABLE_FORMAT(rfm))        {            Info(slide, 1, ((char *)slide,               "[ File %s has illegal record format to put to screen ]\n",               FnFilter1(G.filename)));            free_up();            return PK_WARN;        }    }    else                        /* Redirect output */    {        rab = cc$rms_rab;       /* fill RAB with default values */        /* The output FAB has already been initialized with the values         * found in the Zip file's "VMS attributes" extra field */        outfab->fab$l_fna = G.filename;        outfab->fab$b_fns = strlen(outfab->fab$l_fna);        if (!(xabdat && xabrdt))        /* Use date/time info                                         *  from zipfile if                                         *  no attributes given                                         */        {            set_default_datetime_XABs(__G);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -