📄 vms_im.c
字号:
/************************************************************************* * * * 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 + -