📄 vms.c
字号:
if ( ERR(status = sys$parse(&fileblk)) ) { vms_msg(__G__ "create_qio_output: sys$parse failed.\n", status); return PK_WARN; } pka_devdsc.dsc$w_length = (unsigned short)nam.nam$t_dvi[0]; if ( ERR(status = sys$assign(&pka_devdsc,&pka_devchn,0,0)) ) { vms_msg(__G__ "create_qio_output: sys$assign failed.\n", status); return PK_WARN; } pka_fnam.dsc$a_pointer = nam.nam$l_name; pka_fnam.dsc$w_length = nam.nam$b_name + nam.nam$b_type; if ( uO.V_flag /* keep versions */ ) pka_fnam.dsc$w_length += nam.nam$b_ver; for (i=0;i<3;i++) { pka_fib.FIB$W_DID[i]=nam.nam$w_did[i]; pka_fib.FIB$W_FID[i]=0; } /* 2004-11-23 SMS. * Set the "sequential access only" flag, as otherwise, on a * file system with highwater marking enabled, allocating space * for a large file may lock the disk for a long time (minutes). * (The "no other readers" flag is also required, if you want * the "sequential access only" flag to have any effect.) */ pka_fib.FIB$L_ACCTL = FIB$M_WRITE | FIB$M_SEQONLY | FIB$M_NOREAD; /* Allocate space for the file */ pka_fib.FIB$W_EXCTL = FIB$M_EXTEND; if ( pka_uchar & FCH$M_CONTIG ) pka_fib.FIB$W_EXCTL |= FIB$M_ALCON | FIB$M_FILCON; if ( pka_uchar & FCH$M_CONTIGB ) pka_fib.FIB$W_EXCTL |= FIB$M_ALCONB;#define SWAPW(x) ( (((x)>>16)&0xFFFF) + ((x)<<16) ) pka_fib.fib$l_exsz = SWAPW(pka_rattr.fat$l_hiblk); status = sys$qiow(0, pka_devchn, IO$_CREATE|IO$M_CREATE|IO$M_ACCESS, &pka_acp_sb, 0, 0, &pka_fibdsc, &pka_fnam, 0, 0, &pka_atr, 0); if ( !ERR(status) ) status = pka_acp_sb.status; if ( ERR(status) ) { vms_msg(__G__ "[ Create file QIO failed. ]\n", status); sys$dassgn(pka_devchn); return PK_WARN; }#ifdef ASYNCH_QIO init_buf_ring(); pka_io_pending = FALSE;#else locptr = locbuf; loccnt = 0;#endif pka_vbn = 1; _flush_routine = _flush_qio; _close_routine = _close_qio; } /* end if (!uO.cflag) */ return PK_COOL;}static int replace(__GPRO){ /* * File exists. Inquire user about further action. */ char answ[10]; struct NAM nam; int ierr; if (query == '\0') { do { Info(slide, 0x81, ((char *)slide, "%s exists: [o]verwrite, new [v]ersion or [n]o extract?\n\ (uppercase response [O,V,N] = do same for all files): ", FnFilter1(G.filename))); fflush(stderr); } while (fgets(answ, 9, stderr) == NULL && !isalpha(answ[0]) && tolower(answ[0]) != 'o' && tolower(answ[0]) != 'v' && tolower(answ[0]) != 'n'); if (isupper(answ[0])) query = answ[0] = tolower(answ[0]); } else answ[0] = query; switch (answ[0]) { case 'n': ierr = 0; break; case 'v': nam = cc$rms_nam; nam.nam$l_rsa = G.filename; nam.nam$b_rss = FILNAMSIZ - 1; outfab->fab$l_fop |= FAB$M_MXV; outfab->fab$l_nam = &nam; ierr = sys$create(outfab); if (!ERR(ierr)) { outfab->fab$l_nam = NULL; G.filename[outfab->fab$b_fns = nam.nam$b_rsl] = '\0'; } break; case 'o': outfab->fab$l_fop |= FAB$M_SUP; ierr = sys$create(outfab); break; } return ierr;}#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. * ****************************************************************/static int find_vms_attrs(__G) __GDEF{ uch *scan = G.extra_field; struct EB_header *hdr; int len; int type=VAT_NONE; outfab = NULL; xabfhc = NULL; xabdat = NULL; xabrdt = NULL; xabpro = NULL; first_xab = last_xab = NULL; if (scan == NULL) return VAT_NONE; len = G.lrec.extra_field_length;#define LINK(p) {/* Link xaballs and xabkeys into chain */ \ if ( first_xab == NULL ) \ first_xab = (void *) p; \ if ( last_xab != NULL ) \ last_xab->xab$l_nxt = (void *) p; \ last_xab = (void *) p; \ p->xab$l_nxt = NULL; \ } /* End of macro LINK */ while (len > 0) { hdr = (struct EB_header *)scan; if (EQL_W(&hdr->tag, IZ_SIGNATURE)) { /* * Info-ZIP style extra block decoding */ uch *blk; unsigned siz; uch *block_id; type = VAT_IZ; siz = hdr->size; blk = (uch *)(&hdr->data[0]); block_id = (uch *)(&((struct IZ_block *)hdr)->bid); if (EQL_L(block_id, FABSIG)) { outfab = (struct FAB *)extract_izvms_block(__G__ blk, siz, NULL, (uch *)&cc$rms_fab, FABL); } else if (EQL_L(block_id, XALLSIG)) { xaball = (struct XABALL *)extract_izvms_block(__G__ blk, siz, NULL, (uch *)&cc$rms_xaball, XALLL); LINK(xaball); } else if (EQL_L(block_id, XKEYSIG)) { xabkey = (struct XABKEY *)extract_izvms_block(__G__ blk, siz, NULL, (uch *)&cc$rms_xabkey, XKEYL); LINK(xabkey); } else if (EQL_L(block_id, XFHCSIG)) { xabfhc = (struct XABFHC *) extract_izvms_block(__G__ blk, siz, NULL, (uch *)&cc$rms_xabfhc, XFHCL); } else if (EQL_L(block_id, XDATSIG)) { xabdat = (struct XABDAT *) extract_izvms_block(__G__ blk, siz, NULL, (uch *)&cc$rms_xabdat, XDATL); } else if (EQL_L(block_id, XRDTSIG)) { xabrdt = (struct XABRDT *) extract_izvms_block(__G__ blk, siz, NULL, (uch *)&cc$rms_xabrdt, XRDTL); } else if (EQL_L(block_id, XPROSIG)) { xabpro = (struct XABPRO *) extract_izvms_block(__G__ blk, siz, NULL, (uch *)&cc$rms_xabpro, XPROL); } else if (EQL_L(block_id, VERSIG)) {#ifdef CHECK_VERSIONS char verbuf[80]; unsigned verlen = 0; uch *vers; char *m; get_vms_version(verbuf, sizeof(verbuf)); vers = extract_izvms_block(__G__ blk, siz, &verlen, NULL, 0); if ((m = strrchr((char *) vers, '-')) != NULL) *m = '\0'; /* Cut out release number */ if (strcmp(verbuf, (char *) vers) && uO.qflag < 2) { Info(slide, 0, ((char *)slide, "[ Warning: VMS version mismatch.")); Info(slide, 0, ((char *)slide, " This version %s --", verbuf)); strncpy(verbuf, (char *) vers, verlen); verbuf[verlen] = '\0'; Info(slide, 0, ((char *)slide, " version made by %s ]\n", verbuf)); } free(vers);#endif /* CHECK_VERSIONS */ } else { Info(slide, 1, ((char *)slide, "[ Warning: Unknown block signature %s ]\n", block_id)); } } else if (hdr->tag == PK_SIGNATURE) { /* * PKWARE-style extra block decoding */ struct PK_header *blk; register byte *scn; register int len; type = VAT_PK; blk = (struct PK_header *)hdr; len = blk->size - (PK_HEADER_SIZE - EB_HEADSIZE); scn = (byte *)(&blk->data); pka_idx = 0; if (blk->crc32 != crc32(CRCVAL_INITIAL, scn, (extent)len)) { Info(slide, 1, ((char *)slide, "[Warning: CRC error, discarding PKWARE extra field]\n")); len = 0; type = VAT_NONE; } while (len > PK_FLDHDR_SIZE) { register struct PK_field *fld; int skip=0; fld = (struct PK_field *)scn; switch(fld->tag) { case ATR$C_UCHAR: pka_uchar = L(&fld->value); break; case ATR$C_RECATTR: pka_rattr = *(struct fatdef *)(&fld->value); break; case ATR$C_UIC: case ATR$C_ADDACLENT: skip = !uO.X_flag; break; } if ( !skip ) { pka_atr[pka_idx].atr$w_size = fld->size; pka_atr[pka_idx].atr$w_type = fld->tag; pka_atr[pka_idx].atr$l_addr = GVTC &fld->value; ++pka_idx; } len -= fld->size + PK_FLDHDR_SIZE; scn += fld->size + PK_FLDHDR_SIZE; } pka_atr[pka_idx].atr$w_size = 0; /* End of list */ pka_atr[pka_idx].atr$w_type = 0; pka_atr[pka_idx].atr$l_addr = 0; /* NULL when DECC VAX gets fixed */ } len -= hdr->size + EB_HEADSIZE; scan += hdr->size + EB_HEADSIZE; } if ( type == VAT_IZ ) { if (outfab != NULL) { /* Do not link XABPRO,XABRDT now. Leave them for sys$close() */ outfab->fab$l_xab = NULL; if (xabfhc != NULL) { xabfhc->xab$l_nxt = outfab->fab$l_xab; outfab->fab$l_xab = (void *) xabfhc; } if (xabdat != NULL) { xabdat->xab$l_nxt = outfab->fab$l_xab; outfab->fab$l_xab = (void *) xabdat; } if (first_xab != NULL) /* Link xaball,xabkey subchain */ { last_xab->xab$l_nxt = outfab->fab$l_xab; outfab->fab$l_xab = (void *) first_xab; } } else type = VAT_NONE; } return type;}static void free_up(){ /* * Free up all allocated xabs */ if (xabdat != NULL) free(xabdat); if (xabpro != NULL) free(xabpro); if (xabrdt != NULL) free(xabrdt); if (xabfhc != NULL) free(xabfhc); while (first_xab != NULL) { struct XAB *x; x = (struct XAB *) first_xab->xab$l_nxt; free(first_xab); first_xab = x; } if (outfab != NULL && outfab != &fileblk) free(outfab);}#ifdef CHECK_VERSIONSstatic 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 */}#endif /* CHECK_VERSIONS *//* flush contents of output buffer */int flush(__G__ rawbuf, size, unshrink) /* return PK-type error code */ __GDEF uch *rawbuf; ulg size; int unshrink;{ G.crc32val = crc32(G.crc32val, rawbuf, (extent)size); if (uO.tflag) return PK_COOL; /* Do not output. Update CRC only */ else return (*_flush_routine)(__G__ rawbuf, size, 0);}static int _flush_blocks(__G__ rawbuf, size, final_flag) /* Asynchronous version */ __GDEF uch *rawbuf; unsigned size; int final_flag; /* 1 if this is the final flushout */{ int status; unsigned off = 0; while (size > 0) { if (curbuf->bufcnt < BUFS512) { unsigned ncpy; ncpy = size > (BUFS512 - curbuf->bufcnt) ? (BUFS512 - curbuf->bufcnt) : size; memcpy(curbuf->buf + curbuf->bufcnt, rawbuf + off, ncpy); size -= ncpy; curbuf->bufcnt += ncpy; off += ncpy; } if (curbuf->bufcnt == BUFS512) { status = WriteBuffer(__G__ curbuf->buf, curbuf->bufcnt); if (status) return status; curbuf = curbuf->next; curbuf->bufcnt = 0; } } return (final_flag && (curbuf->bufcnt > 0)) ? WriteBuffer(__G__ curbuf->buf, curbuf->bufcnt) : PK_COOL;}#ifdef ASYNCH_QIOstatic int WriteQIO(__G__ buf, len) __GDEF uch *buf; unsigned len;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -