123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926 |
- /*
- Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2007-Mar-4 or later
- (the contents of which are also included in zip.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_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.
- * 3.0 23-Oct-2004 Steven Schweda
- * Changed to maintain compatibility with VMS_PK.C. Note that
- * reading with sys$read() prevents getting any data past EOF,
- * regardless of appearances. Moved the VMS_PK_EXTRA test into
- * here from VMS.C to allow more general automatic dependency
- * generation.
- * 17-Feb-2005 Steven Schweda
- * Added support for ODS5 extended names.
- */
- #ifdef VMS /* For VMS only ! */
- #ifndef VMS_PK_EXTRA
- #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 1024
- typedef 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 DEBUG
- static void dump_rms_block(uch *p);
- #endif /* DEBUG */
- /********************************
- * Function set_extra_field *
- ********************************/
- /*
- | 2004-11-11 SMS.
- | Changed to use separate storage for ->extra and ->cextra. Zip64
- | processing may move (reallocate) one and not the other.
- */
- 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 *xtra;
- uch *cxtra;
- uch *scan;
- extent extra_l;
- static struct FAB fab;
- static struct NAM_STRUCT nam;
- 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.
- */
- # ifdef IZ_CHECK_TZ
- if (!zp_tz_is_valid)
- return ZE_OK; /* skip silently if no valid TZ info */
- # endif
- if ((xtra = (uch *) malloc( EB_HEADSIZE+ EB_UT_LEN( 1))) == NULL)
- return ZE_MEM;
- if ((cxtra = (uch *) malloc( EB_HEADSIZE+ EB_UT_LEN( 1))) == NULL)
- return ZE_MEM;
- /* Fill xtra[] with data. */
- xtra[ 0] = 'U';
- xtra[ 1] = 'T';
- xtra[ 2] = EB_UT_LEN(1); /* length of data part of e.f. */
- xtra[ 3] = 0;
- xtra[ 4] = EB_UT_FL_MTIME;
- xtra[ 5] = (uch) (z_utim->mtime);
- xtra[ 6] = (uch) (z_utim->mtime >> 8);
- xtra[ 7] = (uch) (z_utim->mtime >> 16);
- xtra[ 8] = (uch) (z_utim->mtime >> 24);
- /* Copy xtra[] data into cxtra[]. */
- memcpy( cxtra, xtra, (EB_HEADSIZE+ EB_UT_LEN( 1)));
- /* Set sizes and pointers. */
- z->cext = z->ext = (EB_HEADSIZE+ EB_UT_LEN( 1));
- z->extra = (char *) xtra;
- z->cextra = (char *) cxtra;
- #endif /* USE_EF_UT_TIME */
- return RET_SUCCESS;
- }
- /*
- * Initialize RMS control blocks and link them
- */
- fab = cc$rms_fab;
- nam = CC_RMS_NAM;
- xabsum = cc$rms_xabsum;
- xabdat = cc$rms_xabdat;
- xabfhc = cc$rms_xabfhc;
- xabpro = cc$rms_xabpro;
- xabrdt = cc$rms_xabrdt;
- fab.FAB_NAM = &nam;
- fab.fab$l_xab = (char*)&xabsum;
- /*
- * Open the file and read summary information.
- */
- #ifdef NAML$C_MAXRSS
- fab.fab$l_dna = (char *) -1; /* Using NAML for default name. */
- fab.fab$l_fna = (char *) -1; /* Using NAML for file name. */
- #endif /* def NAML$C_MAXRSS */
- FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNA = z->name;
- FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNS = strlen( z->name);
- #ifdef NAML$M_OPEN_SPECIAL
- /* 2007-02-28 SMS.
- * If processing symlinks as symlinks ("-y"), then $OPEN the
- * link, not the target file.
- *
- * (nam.naml$v_open_special gets us the symlink itself instead of
- * its target. fab.fab$v_bio is necessary to allow sys$open() to
- * work. Without it, you get status %x0001860c, "%RMS-F-ORG,
- * invalid file organization value".)
- */
- if (linkput)
- {
- nam.naml$v_open_special = 1;
- fab.fab$v_bio = 1;
- }
- #endif /* def NAML$M_OPEN_SPECIAL */
- 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 = xtra = (uch *) malloc( extra_l)) == (uch*)NULL)
- {
- #ifdef DEBUG
- printf(
- "set_extra_field: Insufficient memory to allocate extra L buffer\n");
- #endif
- goto err_exit;
- }
- if ((cxtra = (uch *) malloc( extra_l)) == (uch*)NULL)
- {
- #ifdef DEBUG
- printf(
- "set_extra_field: Insufficient memory to allocate extra C 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_dna = NULL;
- fab.fab$l_fna = NULL;
- fab.fab$l_nam = NULL;
- #ifdef NAML$C_MAXRSS
- fab.fab$l_naml = NULL;
- #endif /* def NAML$C_MAXRSS */
- fab.fab$l_xab = 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;
- }
- /* Copy xtra[] data into cxtra[]. */
- memcpy( cxtra, xtra, (scan- xtra));
- /* Set sizes and pointers. */
- z->cext = z->ext = scan- xtra;
- z->extra = (char*) xtra;
- z->cextra = (char*) cxtra;
- 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;
- *m = 0;
- /* Cut out release number "V5.4-3" -> "V5.4" */
- if ((m = strrchr(verbuf, '-')) != NULL)
- *m = 0;
- return strlen(verbuf) + 1; /* Transmit ending 0 too */
- }
- #define CTXSIG ((ulg)('CtXx'))
- typedef struct user_context
- {
- ulg sig;
- struct FAB *fab;
- struct NAM_STRUCT *nam;
- struct RAB *rab;
- uzoff_t size;
- uzoff_t rest;
- int status;
- } Ctx, *Ctxptr;
- Ctx init_ctx =
- {
- CTXSIG,
- NULL,
- NULL,
- NULL,
- 0L,
- 0L,
- 0
- };
- #define CTXL sizeof(Ctx)
- #define CHECK_RAB(_r) ( (_r) != NULL && \
- (_r) -> rab$b_bid == RAB$C_BID && \
- (_r) -> rab$b_bln == RAB$C_BLN && \
- (_r) -> rab$l_ctx != 0 && \
- (_r) -> rab$l_fab != NULL )
- #define BLOCK_BYTES 512
- /**************************
- * Function vms_open *
- **************************/
- struct RAB *vms_open(name)
- char *name;
- {
- struct FAB *fab;
- struct NAM_STRUCT *nam;
- struct RAB *rab;
- struct XABFHC *fhc;
- Ctxptr ctx;
- if ((fab = (struct FAB *) malloc(FABL)) == NULL)
- return NULL;
- if ((nam =
- (struct NAM_STRUCT *) malloc( sizeof( struct NAM_STRUCT))) == NULL)
- {
- free(fab);
- return NULL;
- }
- if ((rab = (struct RAB *) malloc(RABL)) == NULL)
- {
- free(fab);
- free(nam);
- return NULL;
- }
- if ((fhc = (struct XABFHC *) malloc(XFHCL)) == (struct XABFHC *)NULL)
- {
- free(fab);
- free(nam);
- free(rab);
- return (struct RAB *)NULL;
- }
- if ((ctx = (Ctxptr) malloc(CTXL)) == (Ctxptr)NULL)
- {
- free(fab);
- free(nam);
- free(rab);
- free(fhc);
- return (struct RAB *)NULL;
- }
- *fab = cc$rms_fab;
- *nam = CC_RMS_NAM;
- *rab = cc$rms_rab;
- *fhc = cc$rms_xabfhc;
- fab->FAB_NAM = nam;
- #ifdef NAML$C_MAXRSS
- fab->fab$l_dna = (char *) -1; /* Using NAML for default name. */
- fab->fab$l_fna = (char *) -1; /* Using NAML for file name. */
- #endif /* def NAML$C_MAXRSS */
- FAB_OR_NAML( fab, nam)->FAB_OR_NAML_FNA = name;
- FAB_OR_NAML( fab, nam)->FAB_OR_NAML_FNS = strlen( name);
- fab->fab$b_fac = FAB$M_GET | FAB$M_BIO;
- fab->fab$l_xab = (char*)fhc;
- #ifdef NAML$M_OPEN_SPECIAL
- /* 2007-02-28 SMS.
- * If processing symlinks as symlinks ("-y"), then $OPEN the
- * link, not the target file. (Note that here the required
- * fab->fab$v_bio flag was set above.)
- */
- if (linkput)
- {
- nam->naml$v_open_special = 1;
- }
- #endif /* def NAML$M_OPEN_SPECIAL */
- if (ERR(sys$open(fab)))
- {
- sys$close(fab);
- free(fab);
- free(nam);
- free(rab);
- free(fhc);
- free(ctx);
- return (struct RAB *)NULL;
- }
- rab->rab$l_fab = fab;
- rab->rab$l_rop = RAB$M_BIO;
- if (ERR(sys$connect(rab)))
- {
- sys$close(fab);
- free(fab);
- free(nam);
- free(rab);
- free(ctx);
- return (struct RAB *)NULL;
- }
- *ctx = init_ctx;
- ctx->fab = fab;
- ctx->nam = nam;
- ctx->rab = rab;
- if (fhc->xab$l_ebk == 0)
- {
- /* Only known size is all allocated blocks.
- (This occurs with a zero-length file, for example.)
- */
- ctx->size =
- ctx->rest = ((uzoff_t) fhc->xab$l_hbk)* BLOCK_BYTES;
- }
- else
- {
- /* Store normal (used) size in ->size.
- If only one -V, store normal (used) size in ->rest.
- If -VV, store allocated-blocks size in ->rest.
- */
- ctx->size =
- (((uzoff_t) fhc->xab$l_ebk)- 1)* BLOCK_BYTES+ fhc->xab$w_ffb;
- if (vms_native < 2)
- ctx->rest = ctx->size;
- else
- ctx->rest = ((uzoff_t) fhc->xab$l_hbk)* BLOCK_BYTES;
- }
- free(fhc);
- fab->fab$l_xab = NULL;
- rab->rab$l_ctx = (unsigned) ctx;
- return rab;
- }
- /**************************
- * Function vms_close *
- **************************/
- int vms_close(rab)
- struct RAB *rab;
- {
- struct FAB *fab;
- struct NAM_STRUCT *nam;
- Ctxptr ctx;
- if (!CHECK_RAB(rab))
- return RET_ERROR;
- fab = (ctx = (Ctxptr)(rab->rab$l_ctx))->fab;
- nam = (ctx = (Ctxptr)(rab->rab$l_ctx))->nam;
- sys$close(fab);
- free(fab);
- free(nam);
- free(rab);
- free(ctx);
- return RET_SUCCESS;
- }
- /**************************
- * Function vms_rewind *
- **************************/
- int vms_rewind(rab)
- struct RAB *rab;
- {
- Ctxptr ctx;
- int status;
- if (!CHECK_RAB(rab))
- return RET_ERROR;
- ctx = (Ctxptr) (rab->rab$l_ctx);
- if (ERR(status = sys$rewind(rab)))
- {
- ctx->status = status;
- return RET_ERROR;
- }
- ctx->status = 0;
- ctx->rest = ctx->size;
- return RET_SUCCESS;
- }
- #define KByte (2* BLOCK_BYTES)
- #define MAX_READ_BYTES (32* KByte)
- /**************************
- * Function vms_read *
- **************************/
- size_t vms_read(rab, buf, size)
- struct RAB *rab;
- char *buf;
- size_t size;
- /*
- * size must be greater or equal to 512 !
- */
- {
- int status;
- Ctxptr ctx;
- ctx = (Ctxptr)rab->rab$l_ctx;
- if (!CHECK_RAB(rab))
- return 0;
- if (ctx -> rest == 0)
- return 0; /* Eof */
- /* If request is smaller than a whole block, fail.
- This really should never happen. (assert()?)
- */
- if (size < BLOCK_BYTES)
- return 0;
- /* 2004-09-27 SMS.
- Code here now resembles low-level QIO code in VMS_PK.C, but I
- doubt that sys$read() will actually get past the official EOF.
- */
- /* Adjust request size as appropriate. */
- if (size > MAX_READ_BYTES)
- {
- /* Restrict request to MAX_READ_BYTES. */
- size = MAX_READ_BYTES;
- }
- else
- {
- /* Round odd-ball request up to the next whole block.
- This really should never happen. (assert()?)
- */
- size = (size+ BLOCK_BYTES- 1)& ~(BLOCK_BYTES- 1);
- }
- /* Reduce "size" when next (last) read would overrun the EOF,
- but never below one byte (so we'll always get a nice EOF).
- */
- if (size > ctx->rest)
- size = ctx->rest;
- if (size == 0)
- size = 1;
- rab->rab$l_ubf = buf;
- rab->rab$w_usz = size;
- status = sys$read(rab);
- if (!ERR(status) && rab->rab$w_rsz > 0)
- {
- ctx -> status = 0;
- ctx -> rest -= rab->rab$w_rsz;
- return rab->rab$w_rsz;
- }
- else
- {
- ctx->status = (status==RMS$_EOF ? 0:status);
- if (status == RMS$_EOF)
- ctx -> rest = 0;
- return 0;
- }
- }
- /**************************
- * Function vms_error *
- **************************/
- int vms_error(rab)
- struct RAB *rab;
- {
- if (!CHECK_RAB(rab))
- return RET_ERROR;
- return ((Ctxptr) (rab->rab$l_ctx))->status;
- }
- #ifdef DEBUG
- static void dump_rms_block(p)
- uch *p;
- {
- uch bid, len;
- int err;
- char *type;
- char buf[132];
- int i;
- err = 0;
- bid = p[0];
- len = p[1];
- switch (bid)
- {
- case FAB$C_BID:
- type = "FAB";
- break;
- case XAB$C_ALL:
- type = "xabALL";
- break;
- case XAB$C_KEY:
- type = "xabKEY";
- break;
- case XAB$C_DAT:
- type = "xabDAT";
- break;
- case XAB$C_RDT:
- type = "xabRDT";
- break;
- case XAB$C_FHC:
- type = "xabFHC";
- break;
- case XAB$C_PRO:
- type = "xabPRO";
- break;
- default:
- type = "Unknown";
- err = 1;
- break;
- }
- printf("Block @%08X of type %s (%d).", p, type, bid);
- if (err)
- {
- printf("\n");
- return;
- }
- printf(" Size = %d\n", len);
- printf(" Offset - Hex - Dec\n");
- for (i = 0; i < len; i += 8)
- {
- int j;
- printf("%3d - ", i);
- for (j = 0; j < 8; j++)
- if (i + j < len)
- printf("%02X ", p[i + j]);
- else
- printf(" ");
- printf(" - ");
- for (j = 0; j < 8; j++)
- if (i + j < len)
- printf("%03d ", p[i + j]);
- else
- printf(" ");
- printf("\n");
- }
- }
- #endif /* DEBUG */
- #ifdef OLD_COMPRESS
- # define BC_METHOD EB_IZVMS_BC00
- # define COMP_BLK(to,tos,from,froms) _compress( from,to,froms )
- #else
- # define BC_METHOD EB_IZVMS_BCDEFL
- # define COMP_BLK(to,tos,from,froms) memcompress(to,tos,from,froms)
- #endif
- static uch *_compress_block(to,from,size,sig)
- register struct IZ_block *to;
- uch *from;
- int size;
- char *sig;
- {
- ulg cl;
- to -> sig = *(ush*)IZ_SIGNATURE;
- to -> bid = *(ulg*)(sig);
- to -> flags = BC_METHOD;
- to -> length = size;
- #ifdef DEBUG
- printf("\nmemcompr(%d,%d,%d,%d)\n",&(to->body[0]),size+PAD,from,size);
- #endif
- cl = COMP_BLK( &(to->body[0]), size+PAD, from, size );
- #ifdef DEBUG
- printf("Compressed to %d\n",cl);
- #endif
- if (cl >= size)
- {
- memcpy(&(to->body[0]), from, size);
- to->flags = EB_IZVMS_BCSTOR;
- cl = size;
- #ifdef DEBUG
- printf("Storing block...\n");
- #endif
- }
- return (uch*)(to) + (to->size = cl + EXTBSL + RESL) + EB_HEADSIZE;
- }
- #define NBITS 32
- static int _compress(from,to,size)
- uch *from,*to;
- int size;
- {
- int off=0;
- ulg bitbuf=0;
- int bitcnt=0;
- int i;
- #define _BIT(val,len) { \
- if (bitcnt + (len) > NBITS) \
- while(bitcnt >= 8) \
- { \
- to[off++] = (uch)bitbuf; \
- bitbuf >>= 8; \
- bitcnt -= 8; \
- } \
- bitbuf |= ((ulg)(val))<<bitcnt; \
- bitcnt += len; \
- }
- #define _FLUSH { \
- while(bitcnt>0) \
- { \
- to[off++] = (uch)bitbuf; \
- bitbuf >>= 8; \
- bitcnt -= 8; \
- } \
- }
- for (i=0; i<size; i++)
- {
- if (from[i])
- {
- _BIT(1,1);
- _BIT(from[i],8);
- }
- else
- _BIT(0,1);
- }
- _FLUSH;
- return off;
- }
- #endif /* !UTIL */
- #endif /* ndef VMS_PK_EXTRA */
- #endif /* VMS */
|