📄 vms.c
字号:
/************************************************************************* * * * 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 by Igor Mandrichenko * version 1.1-2 * * This module contains routines to extract VMS file attributes * from extra field and create file with these attributes. This * source is mainly based on sources of file_io.c from UNZIP 4.1 * by Info-ZIP. [Info-ZIP note: very little of this code is from * file_io.c; it has virtually been written from the ground up. * Of the few lines which are from the older code, most are mine * (G. Roelofs) and I make no claims upon them. On the contrary, * my/our thanks to Igor for his contributions!] *//* * Revision history: * 1.0-1 Mandrichenko 16-feb-1992 * Recognize -c option * 1.0-2 Mandrichenko 17-feb-1992 * Do not use ASYnchroneous mode. * 1.0-3 Mandrichenko 2-mar-1992 * Make code more standard * Use lrec instead of crec -- unzip4.2p do not provide * crec now. * 1.1 Mandrichenko 5-mar-1992 * Make use of asynchronous output. * Be ready to extract RMS blocks of invalid size (because diff * VMS version used to compress). * 1.1-1 Mandrichenko 11-mar-1992 * Use internal file attributes saved in pInfo to decide * if the file is text. [GRR: temporarily disabled, since * no way to override and force binary extraction] * 1.1-2 Mandrichenko 13-mar-1992 * Do not restore owner/protection info if -X not specified. */#ifdef VMS /* VMS only ! *//************************************//* File_IO Includes, Defines, etc. *//************************************/#ifdef VAXC#include rms#include descrip#include syidef#else#include <rms.h>#include <descrip.h>#include <syidef.h>#endif#include "unzip.h"#define ERR(s) !((s) & 1)#define BUFS512 8192*2 /* Must be a multiple of 512 */static int WriteBuffer __((int fd, unsigned char *buf, int len));static int _flush_blocks __((void));static int _flush_records __((void));static byte *extract_block __((byte *));/** Local static storage*/static struct FAB *outfab = 0;static struct RAB *outrab = 0;static struct FAB fileblk;static struct XABFHC *xabfhc = 0;static struct XABDAT dattim, *xabdat = 0;static struct XABRDT *xabrdt = 0;static struct XABPRO *xabpro = 0;static struct XABKEY *xabkey = 0;static struct XABALL *xaball = 0;static struct RAB rab;static int text_file = 0;static char locbuf[BUFS512];static int loccnt = 0;static char *locptr;struct bufdsc{ struct bufdsc *next; byte *buf; int bufcnt;};static struct bufdsc b1,b2,*curbuf;static byte buf1[BUFS512],buf2[BUFS512];int create_output_file(){ /* return non-0 if sys$create failed */ int ierr, yr, mo, dy, hh, mm, ss; char timbuf[24]; /* length = first entry in "stupid" + 1 */ int attr_given = 0; /* =1 if VMS attributes are present in * extra_field */ rab = cc$rms_rab; /* fill FAB & RAB with default values */ fileblk = cc$rms_fab; text_file = /* pInfo->text || */ aflag || cflag; if (attr_given = find_vms_attrs()) { text_file = 0; if( cflag ) { printf("Can not put VMS file %s to stdout.\n", filename); return 50; } } if (!attr_given) { outfab = &fileblk; outfab->fab$l_xab = 0L; if (text_file) { outfab->fab$b_rfm = FAB$C_VAR; /* variable length records */ outfab->fab$b_rat = FAB$M_CR; /* carriage-return carriage ctrl */ } else { outfab->fab$b_rfm = FAB$C_STMLF; /* stream-LF record format */ outfab->fab$b_rat = FAB$M_CR; /* carriage-return carriage ctrl */ } } if(!cflag) outfab->fab$l_fna = filename; else outfab->fab$l_fna = "sys$output:"; outfab->fab$b_fns = strlen(outfab->fab$l_fna); if (!attr_given || xabdat == 0) { static char *month[] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"}; /* fixed-length string descriptor (why not just a pointer to timbuf? sigh.) */ struct dsc$descriptor stupid = {23, DSC$K_DTYPE_T, DSC$K_CLASS_S, timbuf}; yr = ((lrec.last_mod_file_date >> 9) & 0x7f) + 1980; /* dissect date */ mo = ((lrec.last_mod_file_date >> 5) & 0x0f) - 1; dy = (lrec.last_mod_file_date & 0x1f); hh = (lrec.last_mod_file_time >> 11) & 0x1f; /* dissect time */ mm = (lrec.last_mod_file_time >> 5) & 0x3f; ss = (lrec.last_mod_file_time & 0x1f) * 2; dattim = cc$rms_xabdat; /* fill XAB with default values */ dattim.xab$l_nxt = outfab->fab$l_xab; outfab->fab$l_xab = (char*)(xabdat = &dattim); sprintf(timbuf, "%02d-%3s-%04d %02d:%02d:%02d.00", dy, month[mo], yr, hh, mm, ss); sys$bintim(&stupid, &dattim.xab$q_cdt); }#ifdef DEBUG printf("XAB chain before CREATE dump:\n"); dump_rms_block(outfab); { struct XABALL *x; for (x = outfab->fab$l_xab; x != 0L; x = x->xab$l_nxt) dump_rms_block(x); }#endif outfab->fab$w_ifi = 0; /* Clear IFI. It may be nonzero after ZIP */ if ((ierr = sys$create(outfab)) != RMS$_NORMAL) { message("[ can not create output file ]\n", ierr); message("", outfab->fab$l_stv); fprintf(stderr, "Can't create output file: %s\n", filename); return (1); } if (!text_file && !cflag) /* Do not reopen text files and stdout * Just open them in right mode */ { /* * Reopen file for Block I/O with no XABs. */ if ((ierr = sys$close(outfab)) != RMS$_NORMAL) {#ifdef DEBUG message("[ create_output_file: sys$close failed ]\n", ierr); message("", outfab->fab$l_stv);#endif fprintf(stderr, "Can't create output file: %s\n", filename); return (1); } outfab->fab$b_fac = FAB$M_BIO | FAB$M_PUT; /* Get ready for block * output */ outfab->fab$l_xab = 0L; /* Unlink all XABs */ if ((ierr = sys$open(outfab)) != RMS$_NORMAL) { message("[ Can not open output file ]\n", ierr); message("", outfab->fab$l_stv); return (1); } } outrab = &rab; rab.rab$l_fab = outfab; if( !text_file ) rab.rab$l_rop |= RAB$M_BIO; if( !text_file ) rab.rab$l_rop |= RAB$M_ASY; rab.rab$b_rac = RAB$C_SEQ; if ((ierr = sys$connect(outrab)) != RMS$_NORMAL) {#ifdef DEBUG fprintf(stderr, "create_output_file: sys$connect failed on file %s\n", filename); fprintf(stderr, " status = %d\n", ierr); fprintf(stderr, " fab.sts = %d\n", outfab->fab$l_sts); fprintf(stderr, " fab.stv = %d\n", outfab->fab$l_stv);#endif fprintf(stderr, "Can't create output file: %s\n", filename); return (1); } locptr = &locbuf[0]; loccnt = 0; b1.buf = &buf1[0]; b1.bufcnt = 0; b1.next = &b2; b2.buf = &buf2[0]; b2.bufcnt = 0; b2.next = &b1; curbuf = &b1; return (0);}/** Extra record format* ===================* signature (2 bytes) = 'I','M'* size (2 bytes)* block signature (4 bytes)* flags (2 bytes)* uncomprssed size(2 bytes) * reserved (4 bytes) * data ((size-12) bytes)* ....*/struct extra_block{ UWORD sig; /* Extra field block header structure */ UWORD size; ULONG bid; UWORD flags; UWORD length; ULONG reserved; byte body[1];};/* * Extra field signature and block signatures */#define SIGNATURE "IM"#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 EXTBSL 4 /* Block signature length */#define RESL 8 /* Rserved 8 bytes */#define EXTHL (4+EXTBSL)#define FABSIG "VFAB"#define XALLSIG "VALL"#define XFHCSIG "VFHC"#define XDATSIG "VDAT"#define XRDTSIG "VRDT"#define XPROSIG "VPRO"#define XKEYSIG "VKEY"#define XNAMSIG "VNAM"#define VERSIG "VMSV"#define W(p) (*(unsigned short*)(p))#define L(p) (*(unsigned long*)(p))#define EQL_L(a,b) ( L(a) == L(b) )#define EQL_W(a,b) ( W(a) == W(b) )/**************************************************************** * Function find_vms_attrs scans ZIP entry extra field if any * * and looks for VMS attribute records. Returns 0 if either no * * attributes found or no fab given. * ****************************************************************/int find_vms_attrs(){ byte *scan = extra_field; struct extra_block *blk; struct XABALL *first_xab = 0L, *last_xab = 0L; int len; outfab = xabfhc = xabdat = xabrdt = xabpro = 0L; if (scan == NULL) return 0;/* if (crec.extra_field_length) len = crec.extra_field_length; else*/ len = lrec.extra_field_length;#define LINK(p) { \ if( first_xab == 0L ) \ first_xab = p; \ if( last_xab != 0L ) \ last_xab -> xab$l_nxt = p; \ last_xab = p; \ p -> xab$l_nxt = 0; \ } /* End of macro LINK */ while (len > 0) { blk = (struct block *)scan; if (EQL_W(&blk->sig, SIGNATURE)) { byte *block_id; block_id = &blk->bid; if (EQL_L(block_id, FABSIG)) { outfab = (struct FAB *) extract_block(blk, 0, &cc$rms_fab, FABL); } else if (EQL_L(block_id, XALLSIG)) { xaball = (struct XABALL *) extract_block(blk, 0, &cc$rms_xaball, XALLL); LINK(xaball); } else if (EQL_L(block_id, XKEYSIG)) { xabkey = (struct XABKEY *) extract_block(blk, 0, &cc$rms_xabkey, XKEYL); LINK(xabkey); } else if (EQL_L(block_id, XFHCSIG)) { xabfhc = (struct XABFHC *) extract_block(blk, 0, &cc$rms_xabfhc, XFHCL); LINK(xabfhc); } else if (EQL_L(block_id, XDATSIG)) { xabdat = (struct XABDAT *) extract_block(blk, 0, &cc$rms_xabdat, XDATL); LINK(xabdat); } else if (EQL_L(block_id, XRDTSIG)) { xabrdt = (struct XABRDT *) extract_block(blk, 0, &cc$rms_xabrdt, XRDTL); /* LINK(xabrdt); -- Do not link xabrdt */ } else if (EQL_L(block_id, XPROSIG)) { xabpro = (struct XABPRO *) extract_block(blk, 0, &cc$rms_xabpro, XPROL); /* LINK(xabpro); -- Do not link xabpro until close */ } else if (EQL_L(block_id, VERSIG)) { char verbuf[80]; int verlen = 0; int vl = 0; int item = SYI$_VERSION; $DESCRIPTOR(version, verbuf); byte *vers; lib$getsyi(&item, 0, &version, &verlen, 0, 0); verbuf[verlen] = 0; vers = extract_block(blk, &vl, 0, 0); if (strncmp(verbuf, vers, verlen)) { printf("[ Warning: VMS version mismatch."); printf(" This version %s --", verbuf); strncpy(verbuf, vers, vl); verbuf[vl] = 0; printf(" version made by %s ]\n", verbuf); } free(vers); } else fprintf(stderr, "[ Warning: Unknown block signature %s ]\n", block_id); } len -= blk->size + 4; scan += blk->size + 4;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -