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

📄 vms_im.c

📁 infozip2.2源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************* *                                                                       * * VMS portions copyright (C) 1993 Igor Mandrichenko.                    * * Permission is granted to any individual or institution to use, copy,  * * or redistribute this software so long as all of the original files    * * are included, that it is not sold for profit, and that this copyright * * notice is retained.                                                   * *                                                                       * *************************************************************************//* *  vms_im.c (zip) by Igor Mandrichenko    Version 2.2-2 * *  Revision history: *  ... *  2.1-1       16-feb-1993     I.Mandrichenko *      Get file size from XABFHC and check bytes rest in file before *      reading. *  2.1-2       2-mar-1993      I.Mandrichenko *      Make code more standard *  2.2         21-jun-1993     I.Mandrichenko *      Free all allocated space, use more static storage. *      Use memcompress() from bits.c (deflation) for block compression. *      To revert to old compression method #define OLD_COMPRESS *  2.2-2       28-sep-1995     C.Spieler *      Reorganized code for easier maintance of the two incompatible *      flavours (IM style and PK style) VMS attribute support. *      Generic functions (common to both flavours) are now collected *      in a `wrapper' source file that includes one of the VMS attribute *      handlers. */#ifdef VMS                      /* For VMS only ! */#define OLD_COMPRESS            /*To use old compression method define it.*/#ifdef VMS_ZIP#undef VMS_ZIP                  /* do NOT include PK style Zip definitions */#endif#include "vms.h"#ifndef __LIB$ROUTINES_LOADED#include <lib$routines.h>#endif#ifndef UTIL#define RET_ERROR 1#define RET_SUCCESS 0#define RET_EOF 0#define Kbyte 1024typedef struct XAB *xabptr;/* *   Block sizes */#define EXTL0   ((FABL + EXTHL)+        \                (XFHCL + EXTHL)+        \                (XPROL + EXTHL)+        \                (XDATL + EXTHL)+        \                (XRDTL + EXTHL))#ifdef OLD_COMPRESS#define PAD     sizeof(uch)#else#define PAD     10*sizeof(ush)          /* Two extra bytes for compr. header */#endif#define PAD0    (5*PAD)                 /* Reserve space for the case when                                         *  compression fails */static int _compress(uch *from, uch *to, int size);#ifdef DEBUGstatic void dump_rms_block(uch *p);#endif /* DEBUG *//******************************** *   Function set_extra_field   * ********************************/static uch *_compress_block(register struct IZ_block *to,                            uch *from, int size, char *sig);static int get_vms_version(char *verbuf, int len);int set_extra_field(z, z_utim)  struct zlist far *z;  iztimes *z_utim;/* *      Get file VMS file attributes and store them into extent fields. *      Store VMS version also. *      On error leave z intact. */{    int status;    uch *extra=(uch*)NULL, *scan;    extent extra_l;    static struct FAB fab;    static struct XABSUM xabsum;    static struct XABFHC xabfhc;    static struct XABDAT xabdat;    static struct XABPRO xabpro;    static struct XABRDT xabrdt;    xabptr x = (xabptr)NULL, xab_chain = (xabptr)NULL, last_xab = (xabptr)NULL;    int nk, na;    int i;    int rc=RET_ERROR;    char verbuf[80];    int verlen = 0;    if (!vms_native)    {#ifdef USE_EF_UT_TIME       /*        *  A `portable' zipfile entry is created. Create an "UT" extra block        *  containing UNIX style modification time stamp in UTC, which helps        *  maintaining the `real' "last modified" time when the archive is        *  transfered across time zone boundaries.        */       if ((extra = (uch *)malloc(EB_HEADSIZE+EB_UT_LEN(1))) == NULL)           return ZE_MEM;       extra[0]  = 'U';       extra[1]  = 'T';       extra[2]  = EB_UT_LEN(1);          /* length of data part of e.f. */       extra[3]  = 0;       extra[4]  = EB_UT_FL_MTIME;       extra[5]  = (uch)(z_utim->mtime);       extra[6]  = (uch)(z_utim->mtime >> 8);       extra[7]  = (uch)(z_utim->mtime >> 16);       extra[8]  = (uch)(z_utim->mtime >> 24);       z->cext = z->ext = (EB_HEADSIZE+EB_UT_LEN(1));       z->cextra = z->extra = (char*)extra;#endif /* USE_EF_UT_TIME */       return RET_SUCCESS;    }    /*     *  Initialize RMS control blocks and link them     */    fab =    cc$rms_fab;    xabsum = cc$rms_xabsum;    xabdat = cc$rms_xabdat;    xabfhc = cc$rms_xabfhc;    xabpro = cc$rms_xabpro;    xabrdt = cc$rms_xabrdt;    fab.fab$l_xab = (char*)&xabsum;    /*     *  Open the file and read summary information.     */    fab.fab$b_fns = strlen(z->name);    fab.fab$l_fna = z->name;    status = sys$open(&fab);    if (ERR(status))    {#ifdef DEBUG        printf("set_extra_field: sys$open for file %s:\n  error status = %d\n",               z->name, status);#endif        goto err_exit;    }    nk = xabsum.xab$b_nok;    na = xabsum.xab$b_noa;#ifdef DEBUG    printf("%d keys, %d alls\n", nk, na);#endif    /*     *  Allocate XABKEY and XABALL blocks and link them     */    xabfhc.xab$l_nxt = (char*)&xabdat;    xabdat.xab$l_nxt = (char*)&xabpro;    xabpro.xab$l_nxt = (char*)&xabrdt;    xabrdt.xab$l_nxt = NULL;    xab_chain = (xabptr)(&xabfhc);    last_xab  = (xabptr)(&xabrdt);#define INIT(ptr,size,type,init)     \        if ( (ptr = (type *)malloc(size)) == NULL )     \        {                                               \              printf( "set_extra_field: Insufficient memory.\n" );   \                      goto err_exit;                    \        }                                               \        *(ptr) = (init);    /*     *  Allocate and initialize all needed XABKEYs and XABALLs     */    for (i = 0; i < nk; i++)    {        struct XABKEY *k;        INIT(k, XKEYL, struct XABKEY, cc$rms_xabkey);        k->xab$b_ref = i;        if (last_xab != NULL)            last_xab->xab$l_nxt = (char*)k;        last_xab = (xabptr)k;    }    for (i = 0; i < na; i++)    {        struct XABALL *a;        INIT(a, XALLL, struct XABALL, cc$rms_xaball);        a->xab$b_aid = i;        if (last_xab != NULL)            last_xab->xab$l_nxt = (char*)a;        last_xab = (xabptr)a;    }    fab.fab$l_xab = (char*)xab_chain;#ifdef DEBUG    printf("Dump of XAB chain before $DISPLAY:\n");    for (x = xab_chain; x != NULL; x = x->xab$l_nxt)        dump_rms_block((uch *)x);#endif    /*     *  Get information on the file structure etc.     */    status = sys$display(&fab, 0, 0);    if (ERR(status))    {#ifdef DEBUG        printf("set_extra_field: sys$display for file %s:\n  error status = %d\n",               z->name, status);#endif        goto err_exit;    }#ifdef DEBUG    printf("\nDump of XAB chain after $DISPLAY:\n");    for (x = xab_chain; x != NULL; x = x->xab$l_nxt)        dump_rms_block((uch *)x);#endif    fab.fab$l_xab = NULL;  /* Keep XABs */    status = sys$close(&fab);    if (ERR(status))    {#ifdef DEBUG        printf("set_extra_field: sys$close for file %s:\n  error status = %d\n",               z->name, status);#endif        goto err_exit;    }    extra_l = EXTL0 + nk * (XKEYL + EXTHL) + na * (XALLL + EXTHL);#ifndef OLD_COMPRESS    extra_l += PAD0 + (nk+na) * PAD;#endif    if ( (verlen = get_vms_version(verbuf, sizeof(verbuf))) > 0 )    {        extra_l += verlen + EXTHL;#ifndef OLD_COMPRESS        extra_l += PAD;#endif    }    if ((scan = extra = (uch *) malloc(extra_l)) == (uch*)NULL)    {#ifdef DEBUG        printf("set_extra_field: Insufficient memory to allocate extra buffer\n");#endif        goto err_exit;    }    if (verlen > 0)        scan = _compress_block((struct IZ_block *)scan, (uch *)verbuf,                               verlen, VERSIG);    /*     *  Zero all unusable fields to improve compression     */    fab.fab$b_fns = fab.fab$b_shr = fab.fab$b_dns = fab.fab$b_fac = 0;    fab.fab$w_ifi = 0;    fab.fab$l_stv = fab.fab$l_sts = fab.fab$l_ctx = 0;    fab.fab$l_fna = NULL;    fab.fab$l_nam = NULL;    fab.fab$l_xab = NULL;    fab.fab$l_dna = NULL;#ifdef DEBUG    dump_rms_block( (uch *)&fab );#endif    scan = _compress_block((struct IZ_block *)scan, (uch *)&fab, FABL, FABSIG);    for (x = xab_chain; x != NULL;)    {        int bln;        char *sig;        xabptr next;        next = (xabptr)(x->xab$l_nxt);        x->xab$l_nxt = 0;        switch (x->xab$b_cod)        {            case XAB$C_ALL:                bln = XALLL;                sig = XALLSIG;                break;            case XAB$C_KEY:                bln = XKEYL;                sig = XKEYSIG;                break;            case XAB$C_PRO:                bln = XPROL;                sig = XPROSIG;                break;            case XAB$C_FHC:                bln = XFHCL;                sig = XFHCSIG;                break;            case XAB$C_DAT:                bln = XDATL;                sig = XDATSIG;                break;            case XAB$C_RDT:                bln = XRDTL;                sig = XRDTSIG;                break;            default:                bln = 0;                sig = 0L;                break;        }        if (bln > 0)            scan = _compress_block((struct IZ_block *)scan, (uch *)x,                                   bln, sig);        x = next;    }    z->ext = z->cext = scan-extra;    z->extra = z->cextra = (char*)extra;    rc = RET_SUCCESS;err_exit:    /*     *  Give up all allocated blocks     */    for (x = (struct XAB *)xab_chain; x != NULL; )    {        struct XAB *next;        next = (xabptr)(x->xab$l_nxt);        if (x->xab$b_cod == XAB$C_ALL || x->xab$b_cod == XAB$C_KEY)            free(x);        x = next;    }    return rc;}static int get_vms_version(verbuf, len)char *verbuf;int len;{    int i = SYI$_VERSION;    int verlen = 0;    struct dsc$descriptor version;    char *m;    version.dsc$a_pointer = verbuf;    version.dsc$w_length  = len - 1;    version.dsc$b_dtype   = DSC$K_DTYPE_B;    version.dsc$b_class   = DSC$K_CLASS_S;    if (ERR(lib$getsyi(&i, 0, &version, &verlen, 0, 0)) || verlen == 0)        return 0;    /* Cut out trailing spaces "V5.4-3   " -> "V5.4-3" */    for (m = verbuf + verlen, i = verlen - 1; i > 0 && verbuf[i] == ' '; --i)        --m;

⌨️ 快捷键说明

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