📄 vms.c
字号:
ulg sig; struct FAB *fab; struct RAB *rab; ulg size,rest; int status;} Ctx, *Ctxptr;Ctx init_ctx = { CTXSIG, 0L, 0L, 0L, 0L, 0};#define CTXL sizeof(Ctx)#define CHECK_RAB(_r) ( (_r) != 0 && \ (_r) -> rab$b_bid == RAB$C_BID && \ (_r) -> rab$b_bln == RAB$C_BLN && \ (_r) -> rab$l_ctx != 0L && \ (_r) -> rab$l_fab != 0L )/************************** * Function vms_open * **************************/struct RAB *vms_open(name) char *name;{ struct RAB *rab; struct FAB *fab; struct XABFHC *fhc; Ctxptr ctx; if ((fab = (struct FAB *) malloc(FABL)) == (struct FAB *)NULL) return 0; if ((rab = (struct RAB *) malloc(RABL)) == (struct RAB *)NULL) { free(fab); return 0; } if ((fhc = (struct XABFHC *) malloc(XFHCL)) == (struct XABFHC *)NULL) { free(rab); free(fab); return 0; } if ((ctx = (Ctxptr) malloc(CTXL)) == (Ctxptr)NULL) { free(fhc); free(fab); free(rab); return 0; } *fab = cc$rms_fab; *rab = cc$rms_rab; *fhc = cc$rms_xabfhc; fab->fab$l_fna = name; fab->fab$b_fns = strlen(name); fab->fab$b_fac = FAB$M_GET | FAB$M_BIO; fab->fab$l_xab = (char*)fhc; if (ERR(sys$open(fab))) { sys$close(fab); free(fhc); free(fab); free(rab); free(ctx); return 0; } rab->rab$l_fab = fab; rab->rab$l_rop = RAB$M_BIO; if (ERR(sys$connect(rab))) { sys$close(fab); free(fab); free(rab); free(ctx); return 0; } *ctx = init_ctx; ctx->rab = rab; ctx->fab = fab; if( fhc->xab$l_ebk > 0 ) ctx->size = ctx->rest = ( fhc->xab$l_ebk-1 ) * 512 + fhc->xab$w_ffb; else if( fab->fab$b_org == FAB$C_IDX || fab->fab$b_org == FAB$C_REL || fab->fab$b_org == FAB$C_HSH ) /* Special case, when ebk=0: save entire allocated space */ ctx->size = ctx->rest = fhc->xab$l_hbk * 512; else ctx->size = ctx->rest = fhc->xab$w_ffb; free(fhc); fab -> fab$l_xab = 0; rab->rab$l_ctx = (long)ctx; return rab;}/************************** * Function vms_close * **************************/int vms_close(rab) struct RAB *rab;{ struct FAB *fab; Ctxptr ctx; if (!CHECK_RAB(rab)) return RET_ERROR; fab = (ctx = (Ctxptr)(rab->rab$l_ctx))->fab; sys$close(fab); free(fab); 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;}/************************** * Function vms_read * **************************/int vms_read(rab, buf, size) struct RAB *rab;char *buf;int 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(size > 16*Kbyte) /* RMS can not read too much */ size = 16*Kbyte; else size &= ~511L; 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 = 0L; 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;}dump_rms_block(p) unsigned char *p;{ unsigned char 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"); }}#ifdef OLD_COMPRESS# define BC_METHOD BC_00# define COMP_BLK(to,tos,from,froms) _compress( from,to,froms )#else# define BC_METHOD BC_DEFL# define COMP_BLK(to,tos,from,froms) memcompress(to,tos,from,froms)#endifstatic uch *_compress_block(to,from,size,sig)register struct extra_block *to;uch *from,*sig;int size;{ ulg cl; to -> im_sig = *(ush*)SIGNATURE; to -> block_sig = *(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 = BC_STORED; cl = size;#ifdef DEBUG printf("Storing block...\n");#endif } return (uch*)(to) + (to->size = cl + EXTBSL + RESL) + 4;}#define NBITS 32static 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;}int vms_stat(file,s)char *file;struct stat *s;{ int status; int staterr; struct FAB fab; struct XABFHC fhc; /* * In simplest case when stat() returns "ok" and file size is * nonzero or this is directory, finish with this */ if( (staterr=stat(file,s)) == 0 && ( (int)(s->st_size) >= 0 /* Size - ok */ || (s->st_mode & S_IFREG) == 0 /* Not a plain file */ ) ) return staterr; /* * Get here to handle the special case when stat() returns * invalid file size. Use RMS to compute the size. * When EOF block is zero, set file size to its physical size. * One more case to get here is when this is remote file accessed * via DECnet. */ fab = cc$rms_fab; fhc = cc$rms_xabfhc; fab.fab$l_fna = file; fab.fab$b_fns = strlen(file); fab.fab$l_xab = (char*)(&fhc); fab.fab$b_fac = FAB$M_GET; status = sys$open(&fab); fab.fab$l_xab = (char*)0L; sys$close(&fab); if( !ERR(status) ) { if( fhc.xab$l_ebk > 0 ) s->st_size = ( fhc.xab$l_ebk-1 ) * 512 + fhc.xab$w_ffb; else if( fab.fab$b_org == FAB$C_IDX || fab.fab$b_org == FAB$C_REL || fab.fab$b_org == FAB$C_HSH ) /* Special case, when ebk=0: save entire allocated space */ s->st_size = fhc.xab$l_hbk * 512; else s->st_size = fhc.xab$w_ffb; return 0; /* stat() success code */ } else return status;}#endif /* ?VMS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -