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

📄 vms.c

📁 压缩算法的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************
 *                                                                       *
 * VMS portions copyright (C) 1992 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 unmodified, that it is not sold for profit, and that     *
 * this copyright notice is retained.                                    *
 *                                                                       *
 *************************************************************************/

/*
 *  vms.c (zip) by Igor Mandrichenko    Version 2.1-1
 *
 *  Revision history:
 *  ...
 *  2.1-1       16-feb-1992     I.Mandrichenko  
 *      Get file size from XABFHC and check bytes rest in file before
 *      reading. 
 *  2.1-2       2-mar-1992      I.Mandrichenko
 *      Make code more standard
 *  2.2         21-jun-1992     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
 */

#ifdef VMS                      /* For VMS only ! */

#define OLD_COMPRESS    /*To use old compression method define it.*/

#include <rms.h>
#include <descrip.h>
#include <syidef.h>

#ifndef VAXC
                                /* This definition may be missed */
struct XAB {
    unsigned char xab$b_cod;
    unsigned char xab$b_bln;
    short int xabdef$$_fill_1;
    char *xab$l_nxt;
};

#endif

#ifndef SYI$_VERSION
#define SYI$_VERSION 4096       /* VMS 5.4 definition */
#endif

#include "zip.h"

#define ERR(s)  !((s)&1)

#define RET_ERROR 1
#define RET_SUCCESS 0
#define RET_EOF 0

#define Kbyte 1024

typedef struct XAB *xabptr;

/*
*   Extra record format
*   ===================
*   signature       (2 bytes)   = 'I','M'
*   size            (2 bytes)
*   block signature (4 bytes)
*   flags           (2 butes)
*   uncomprssed size(2 bytes)
*   reserved        (4 bytes)
*   data            (size-12 bytes)
*   ....
*/


/*
*   Extra field signature and block signatures
*/
#define SIGNATURE "IM"
#define EXTBSL  4               /* Block signature length   */
#define RESL    8

#define BC_MASK         07      /* 3 bits for compression type */       
#define BC_STORED       0       /* Stored */
#define BC_00           1       /* 0byte -> 0bit compression */
#define BC_DEFL         2       /* Deflated */

struct extra_block
{       ush     im_sig;
        ush     size;
        ulg     block_sig;
        ush     flags;
        ush     length;
        ulg     reserved;
        uch     body[1];        /* The actual size is unknown */
};

#define FABSIG  "VFAB"
#define XALLSIG "VALL"
#define XFHCSIG "VFHC"
#define XDATSIG "VDAT"
#define XRDTSIG "VRDT"
#define XPROSIG "VPRO"
#define XKEYSIG "VKEY"
#define VERSIG  "VMSV"
/*
*   Block sizes
*/
#define FABL    (cc$rms_fab.fab$b_bln)
#define RABL    (cc$rms_rab.rab$b_bln)
#define XALLL   (cc$rms_xaball.xab$b_bln)
#define XDATL   (cc$rms_xabdat.xab$b_bln)
#define XFHCL   (cc$rms_xabfhc.xab$b_bln)
#define XKEYL   (cc$rms_xabkey.xab$b_bln)
#define XPROL   (cc$rms_xabpro.xab$b_bln)
#define XRDTL   (cc$rms_xabrdt.xab$b_bln)
#define XSUML   (cc$rms_xabsum.xab$b_bln)
#define EXTHL   (4+EXTBSL+RESL)
#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 failes */
static int _compress();

/***********************************
 *   Function get_vms_attributes   *
 ***********************************/

static uch *_compress_block();
static int get_vms_version();

int get_vms_attributes(z)
  struct zlist *z;
/*
 *      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;

    /*
    *   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("get_vms_attributes: 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 ind link them
    */

    xabfhc.xab$l_nxt = (char*)&xabdat;
    xabdat.xab$l_nxt = (char*)&xabpro;
    xabpro.xab$l_nxt = (char*)&xabrdt;
    xabrdt.xab$l_nxt = (char*)0L;

    xab_chain = (xabptr)(&xabfhc);
    last_xab  = (xabptr)(&xabrdt);

#define INIT(ptr,size,init)     \
        if( (ptr = (uch*)malloc(size)) == NULL )        \
        {                                               \
              printf( "get_vms_attributes: 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, cc$rms_xabkey);
        k->xab$b_ref = i;
        if (last_xab != 0L)
            last_xab->xab$l_nxt = (char*)k;
        last_xab = (xabptr)k;
    }
    for (i = 0; i < na; i++)
    {
        struct XABALL *a;
        INIT(a, XALLL, cc$rms_xaball);
        a->xab$b_aid = i;
        if (last_xab != 0L)
            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 != 0L; x = x->xab$l_nxt)
        dump_rms_block(x);
#endif
    /*
    *   Get information on the file structure etc.
    */
    status = sys$display(&fab, 0, 0);
    if (ERR(status))
    {
#ifdef DEBUG
        printf("get_vms_attributes: 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 != 0L; x = x->xab$l_nxt)
        dump_rms_block(x);
#endif

    fab.fab$l_xab = 0;  /* Keep XABs */
    status = sys$close(&fab);
    if (ERR(status))
    {
#ifdef DEBUG
        printf("get_vms_attributes: 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)) )
    {   extra_l += verlen + EXTHL;
#ifndef OLD_COMPRESS
        extra_l += PAD;
#endif
    }

    if ((scan = extra = (uch *) malloc(extra_l)) == (uch*)NULL)
    {
#ifdef DEBUG
        printf("get_vms_attributes: Insufficient memory to allocate extra buffer\n");
#endif
        goto err_exit;
    }


    if( verlen > 0 )
        scan = _compress_block(scan,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 = fab.fab$l_nam = fab.fab$l_xab = fab.fab$l_dna = (char*)0L;

#ifdef DEBUG
    dump_rms_block( &fab );
#endif
    scan = _compress_block(scan,&fab, FABL, FABSIG);
    for (x = xab_chain; x != 0L;)
    {
        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(scan,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 != 0L; )
    {   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;

⌨️ 快捷键说明

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