void cce_cluster(void ) { enum db_ver database; char fn[256]; struct FAB ccpfab; struct XABFHC xab; sgmnt_data *old_data, *dummy_data; short iosb[4]; unsigned short fn_len; int4 status, size, cluster, space_needed; error_def(ERR_CCERDERR); error_def(ERR_CCEWRTERR); error_def(ERR_CCEDBCL); error_def(ERR_CCEDBNTCL); error_def(ERR_CCEBADFN); error_def(ERR_DBOPNERR); error_def(ERR_DBNOTGDS); error_def(ERR_BADDBVER); error_def(ERR_CCEBGONLY); $DESCRIPTOR(cluster_qualifier, "CLUSTER"); fn_len = SIZEOF(fn); if (!cli_get_str("FILE",fn,&fn_len)) { lib$signal(ERR_CCEBADFN); return; } ccpfab = cc$rms_fab; ccpfab.fab$l_fna = fn; ccpfab.fab$b_fns = fn_len; ccpfab.fab$b_fac = FAB$M_BIO | FAB$M_GET | FAB$M_PUT; ccpfab.fab$l_fop = FAB$M_UFO; xab = cc$rms_xabfhc; ccpfab.fab$l_xab = &xab; status = sys$open(&ccpfab); if (status != RMS$_NORMAL) { lib$signal(ERR_DBOPNERR, 2, ccpfab.fab$b_fns, ccpfab.fab$l_fna, status); return; } dummy_data = malloc(ROUND_UP(SIZEOF(sgmnt_data), OS_PAGELET_SIZE)); status = sys$qiow(EFN$C_ENF, ccpfab.fab$l_stv, IO$_READVBLK, iosb, 0, 0, dummy_data, ROUND_UP(SIZEOF(sgmnt_data), OS_PAGELET_SIZE), 1,0,0,0); if (status & 1) status = iosb[0]; if ((status & 1) == 0) { lib$signal(ERR_CCERDERR, 2, ccpfab.fab$b_fns, ccpfab.fab$l_fna, status); sys$dassgn(ccpfab.fab$l_stv); free(dummy_data); return; } /* Commented out as this is unused code and we are removing the old version database references (SE - 4/2005 V5.0) if (memcmp(&dummy_data->label[0], GDS_LABEL, GDS_LABEL_SZ)) { if (memcmp(&dummy_data->label[0], GDS_LABEL, GDS_LABEL_SZ - 3)) { lib$signal (ERR_DBNOTGDS, 2, ccpfab.fab$b_fns, ccpfab.fab$l_fna); status = sys$dassgn(ccpfab.fab$l_stv); assert(status & 1); free(dummy_data); return; }else { if (!memcmp(&dummy_data->label[GDS_LABEL_SZ - 3],GDS_V23,2)) database = v23; else if (!memcmp(&dummy_data->label[GDS_LABEL_SZ - 3],GDS_V24,2)) database = v24; else if (!memcmp(&dummy_data->label[GDS_LABEL_SZ - 3],GDS_V25,2)) database = v25; else if (!memcmp(&dummy_data->label[GDS_LABEL_SZ - 3],GDS_V254,2)) database = v254; else lib$signal (ERR_BADDBVER, 2, ccpfab.fab$b_fns, ccpfab.fab$l_fna); } } else database = v255; */ if (dummy_data->acc_meth != dba_bg) { lib$signal(ERR_CCEBGONLY); status = sys$dassgn(ccpfab.fab$l_stv); assert(status & 1); free(dummy_data); return; } size = (LOCK_BLOCK(dummy_data) * DISK_BLOCK_SIZE) + LOCK_SPACE_SIZE(dummy_data); old_data = malloc(size); memcpy(old_data, dummy_data, SIZEOF(sgmnt_data)); cluster = cli$present(&cluster_qualifier); if (cluster == CLI$_NEGATED) old_data->clustered = FALSE; else if (cluster == CLI$_PRESENT) { old_data->clustered = TRUE; old_data->trans_hist.lock_sequence = 0; } change_fhead_timer("STALE_INTERVAL", old_data->staleness, -50000000, TRUE); change_fhead_timer("RESPONSE_INTERVAL",old_data->ccp_response_interval, -600000000, TRUE); change_fhead_timer("QUANTUM_INTERVAL", old_data->ccp_quantum_interval, -10000000, FALSE); change_fhead_timer("TICK_INTERVAL", old_data->ccp_tick_interval, -1000000, FALSE); if (old_data->unbacked_cache) { space_needed = (old_data->n_bts + getprime(old_data->n_bts) + 1) * SIZEOF(bt_rec); if (space_needed > old_data->free_space) { old_data->n_bts = old_data->free_space/(2*SIZEOF(bt_rec)); for (;;) { space_needed = (old_data->n_bts + getprime(old_data->n_bts) + 1) * SIZEOF(bt_rec); if (space_needed <= old_data->free_space) { old_data->bt_buckets = getprime(old_data->n_bts); break; } old_data->n_bts--; } util_out_open(0); util_out_print("Only have space for !UL cache records in clustered file !AD, adjusting file",TRUE, old_data->n_bts, fn_len, fn); } old_data->free_space -= space_needed; old_data->unbacked_cache = FALSE; } status = dbcx_ref(old_data, ccpfab.fab$l_stv); if ((status & 1) == 0) lib$signal(ERR_CCEWRTERR, 2, ccpfab.fab$b_fns, ccpfab.fab$l_fna, status); if (cluster != CLI$_ABSENT) lib$signal ((old_data->clustered) ? ERR_CCEDBCL : ERR_CCEDBNTCL, 2, ccpfab.fab$b_fns, ccpfab.fab$l_fna); status = sys$dassgn(ccpfab.fab$l_stv); assert(status & 1); free(dummy_data); free(old_data); return; }
uint4 iomt_wtlblk(uint4 channel, uint4 mask, iosb *stat_blk, void *buff, int size) { return sys$qiow(EFN$C_ENF, channel, mask | IO$_WRITELBLK,stat_blk, 0,0, (char*)buff,size, 0,0,0,0 ); }
main(){ struct _iosb myiosb; char mybuf1[MBXBUFSIZ]="test1"; char mybuf2[MBXBUFSIZ]="test2"; char mybuf3[MBXBUFSIZ]="test3"; char * out1="hello"; char * out2="world"; char * out3="hi"; void *p1, mbxast(); char mbuffer[MBXBUFSIZ]; unsigned short mbxchan1, mbxchan2, mbxchan3, mbxiosb; unsigned int status, outlen; unsigned int mbuflen=MBXBUFSIZ, bufquo=MBXBUFQUO, promsk=0; $DESCRIPTOR(mblognam1,"MAILBOX1"); $DESCRIPTOR(mblognam2,"MAILBOX2"); $DESCRIPTOR(mblognam3,"MAILBOX3"); printf("this was originally in 1: %s\n",mybuf1); printf("this was originally in 2: %s\n",mybuf2); printf("this was originally in 3: %s\n",mybuf3); status = sys$crembx(0,&mbxchan1,mbuflen,bufquo,promsk,0,&mblognam1,0); printf("status %x mbxchan %x \n", status,mbxchan1); if ((status&1)==0) signal(status); status = sys$crembx(0,&mbxchan2,mbuflen,bufquo,promsk,0,&mblognam2,0); printf("status %x mbxchan %x \n", status,mbxchan2); if ((status&1)==0) signal(status); status = sys$crembx(0,&mbxchan3,mbuflen,bufquo,promsk,0,&mblognam3,0); printf("status %x mbxchan %x \n", status,mbxchan3); if ((status&1)==0) signal(status); printf("before qio %x\n",time(0)); status=sys$qio(0,mbxchan1,IO$_READVBLK,0,0,0,mybuf1,512,0,0,0,0); printf("after qio %x\n",time(0)); printf("status %x done %x \n", status,done); if ((status&1)==0) signal(status); printf("before qiow %x\n",time(0)); status=sys$qio(0,mbxchan1,IO$_WRITEVBLK,0,0,0,out1,strlen(out1),0,0,0,0); printf("after qiow %x\n",time(0)); printf("status %x done %x \n", status,done); if ((status&1)==0) signal(status); printf("before qiow %x\n",time(0)); status=sys$qio(0,mbxchan1,IO$_WRITEVBLK,0,0,0,out2,strlen(out2),0,0,0,0); printf("after qiow %x\n",time(0)); printf("status %x done %x \n", status,done); if ((status&1)==0) signal(status); printf("this was read from 1: %s\n",mybuf1); printf("Pausing...\n"); sleep(2); printf("before qio %x\n",time(0)); status=sys$qio(0,mbxchan2,IO$_READVBLK|IO$M_STREAM,0,0,0,mybuf2,512,0,0,0,0); printf("after qio %x\n",time(0)); printf("status %x done %x \n", status,done); if ((status&1)==0) signal(status); printf("before qiow %x\n",time(0)); status=sys$qio(0,mbxchan2,IO$_WRITEVBLK,0,0,0,out1,strlen(out1),0,0,0,0); printf("after qiow %x\n",time(0)); printf("status %x done %x \n", status,done); if ((status&1)==0) signal(status); printf("before qiow %x\n",time(0)); status=sys$qio(0,mbxchan2,IO$_WRITEVBLK,0,0,0,out2,strlen(out2),0,0,0,0); printf("after qiow %x\n",time(0)); printf("status %x done %x \n", status,done); if ((status&1)==0) signal(status); printf("this was read from 2: %s\n",mybuf2); printf("Pausing...\n"); sleep(2); printf("before qio %x\n",time(0)); printf("before qiow %x\n",time(0)); status=sys$qio(0,mbxchan3,IO$_WRITEVBLK,0,0,0,out1,strlen(out1),0,0,0,0); printf("after qiow %x\n",time(0)); printf("status %x done %x \n", status,done); if ((status&1)==0) signal(status); printf("before qiow %x\n",time(0)); status=sys$qio(0,mbxchan3,IO$_WRITEVBLK,0,0,0,out2,strlen(out2),0,0,0,0); printf("after qiow %x\n",time(0)); printf("status %x done %x \n", status,done); if ((status&1)==0) signal(status); status=sys$qiow(0,mbxchan3,IO$_READVBLK|IO$M_STREAM,0,0,0,mybuf3,512,0,0,0,0); printf("after qio %x\n",time(0)); printf("status %x done %x \n", status,done); if ((status&1)==0) signal(status); printf("this was read from 3: %s\n",mybuf3); sleep(2); { struct item_list_3 { short buflen, item_code; void *bufaddr; void *retlenaddr; } itmlist[2]; char buf[50]; int retlen; itmlist[0].item_code=LNM$_STRING; itmlist[0].bufaddr=buf; itmlist[0].buflen=50; itmlist[0].retlenaddr=&retlen; itmlist[1].item_code=0; itmlist[1].buflen=0; itmlist[1].bufaddr=0; $DESCRIPTOR(tab,"LNM$TEMPORARY_MAILBOX"); status = sys$trnlnm(0, &tab, &mblognam1, 0, itmlist); if ((status&1)==0) signal(status); printf("mailbox1 translates to %s\n",buf); } return SS$_NORMAL; }
/* NOTE: WHY BOTH old_data and dummy_data? */ cce_show_file() { char fn[256]; struct FAB ccpfab; struct XABFHC xab; sgmnt_data *old_data, *dummy_data; sgmnt_addrs *cs; short iosb[4]; unsigned short fn_len; short unsigned timlen; struct dsc$descriptor_s time_desc; int4 status, size, cluster; unsigned char *c; unsigned char outbuf[80]; int outbufidx; $DESCRIPTOR(output_qualifier, "OUTPUT"); error_def(ERR_CCERDERR); error_def(ERR_CCEBADFN); error_def(ERR_DBOPNERR); error_def(ERR_DBNOTGDS); error_def(ERR_BADDBVER); error_def(ERR_CCEBGONLY); fn_len = SIZEOF(fn); if (!cli_get_str("FILE",fn,&fn_len)) { lib$signal(ERR_CCEBADFN); return; } ccpfab = cc$rms_fab; ccpfab.fab$l_fna = fn; ccpfab.fab$b_fns = fn_len; ccpfab.fab$b_fac = FAB$M_BIO | FAB$M_GET; ccpfab.fab$b_shr = FAB$M_SHRPUT | FAB$M_SHRGET | FAB$M_UPI; ccpfab.fab$l_fop = FAB$M_UFO; xab = cc$rms_xabfhc; ccpfab.fab$l_xab = &xab; status = sys$open(&ccpfab); if (status != RMS$_NORMAL) { lib$signal(ERR_DBOPNERR, 2, ccpfab.fab$b_fns, ccpfab.fab$l_fna, status); return; } dummy_data = malloc(512); status = sys$qiow(EFN$C_ENF, ccpfab.fab$l_stv, IO$_READVBLK, iosb, 0, 0, dummy_data, 512, 1, 0, 0, 0); if (status & 1) status = iosb[0]; if ((status & 1) == 0) { lib$signal(ERR_CCERDERR, 2, ccpfab.fab$b_fns, ccpfab.fab$l_fna, status); sys$dassgn(ccpfab.fab$l_stv); return; } if (memcmp(&dummy_data->label[0], GDS_LABEL, 12)) { if (memcmp(&dummy_data->label[0], GDS_LABEL, 9)) lib$signal (ERR_DBNOTGDS, 2, ccpfab.fab$b_fns, ccpfab.fab$l_fna); else lib$signal (ERR_BADDBVER, 2, ccpfab.fab$b_fns, ccpfab.fab$l_fna); status = sys$dassgn(ccpfab.fab$l_stv); assert(status & 1); return; } if (dummy_data->acc_meth != dba_bg) { lib$signal(ERR_CCEBGONLY); status = sys$dassgn(ccpfab.fab$l_stv); assert(status & 1); return; } size = (((SIZEOF(sgmnt_data)) + 511)/512) * 512; old_data = malloc(size); status = sys$qiow(EFN$C_ENF, ccpfab.fab$l_stv, IO$_READVBLK, iosb, 0, 0, old_data, size, 1, 0, 0, 0); if (status & 1) status = iosb[0]; if ((status & 1) == 0) { lib$signal(ERR_CCERDERR, 2, ccpfab.fab$b_fns, ccpfab.fab$l_fna, status); status = sys$dassgn(ccpfab.fab$l_stv); assert(status & 1); return; } outbufidx = 0; util_out_open(&output_qualifier); PUTLIT("Database file "); PUTSTR(fn, fn_len); PUTLIT(" is "); if (!old_data->clustered) { PUTLIT(" NOT "); } PUTLIT(" a cluster database"); util_out_write(outbuf, outbufidx); time_desc.dsc$b_dtype = DSC$K_DTYPE_T; time_desc.dsc$b_class = DSC$K_CLASS_S; time_desc.dsc$a_pointer = &outbuf[20]; time_desc.dsc$w_length = 40; PUTTIM("STALE_INTERVAL", old_data->staleness); PUTTIM("RESPONSE_INTERVAL",old_data->ccp_response_interval); PUTTIM("QUANTUM_INTERVAL", old_data->ccp_quantum_interval); PUTTIM("TICK_INTERVAL", old_data->ccp_tick_interval); util_out_close(); status = sys$dassgn(ccpfab.fab$l_stv); assert(status & 1); free(dummy_data); free(old_data); return; }
void cce_dbdump(void) { uint4 channel, status, flags, pid, real_size, req_size, size, addrs[2], sec_addrs[2]; int i, j, k, l; gds_file_id file; m_iosb stat_blk; sgmnt_data *sd; unsigned char mbuff[512], *c, *cptr, *ctop; $DESCRIPTOR(d_sec,mbuff); static readonly $DESCRIPTOR(d_cmd,"install lis/glo"); static readonly $DESCRIPTOR(d_mnam,"CCE$DBDUMPMBX"); static readonly $DESCRIPTOR(d_pnam,"CCE$DBDUMPPRC"); char filename[]="SYS$LOGIN:CCE_DBDUMP.DMP", buff[RECORD_SIZE], id_lab[]=" FILE ID:"; struct FAB fab; struct RAB rab; error_def(ERR_CCEDBDUMP); error_def(ERR_CCEDBNODUMP); util_out_open(0); status = sys$crembx(0, &channel, 512, 0, 0, PSL$C_USER, &d_mnam); if (status != SS$_NORMAL) sys$exit(status); flags = CLI$M_NOWAIT | CLI$M_NOLOGNAM; status = lib$spawn(&d_cmd, 0, &d_mnam, &flags, &d_pnam, &pid); if (status != SS$_NORMAL) { if (status == SS$_DUPLNAM) { util_out_print("Spawned process CCE$DBDUMPPRC already exists, cannot continue rundown",TRUE); } sys$exit(status); } /* the following guess at the dump file size is modeled on the calculation for a section */ size = DIVIDE_ROUND_UP((SIZEOF(sgmnt_data) + (WC_MAX_BUFFS + getprime(WC_MAX_BUFFS) + 1) * SIZEOF(bt_rec) + (DEF_LOCK_SIZE / OS_PAGELET_SIZE) + (WC_MAX_BUFFS + getprime(WC_MAX_BUFFS)) * SIZEOF(cache_rec) + SIZEOF(cache_que_heads)), OS_PAGELET_SIZE); size += EXTRA_SPACE; fab = cc$rms_fab; fab.fab$b_fac = FAB$M_PUT; fab.fab$l_fop = FAB$M_CBT | FAB$M_MXV | FAB$M_TEF; fab.fab$l_fna = filename; fab.fab$b_fns = SIZEOF(filename); fab.fab$b_rfm = FAB$C_FIX; fab.fab$w_mrs = RECORD_SIZE; fab.fab$w_deq = size; fab.fab$l_alq = size; switch (status = sys$create(&fab)) { case RMS$_NORMAL: case RMS$_CREATED: case RMS$_SUPERSEDE: case RMS$_FILEPURGED: break; default: util_out_print("Error: Cannot create dump file !AD.",TRUE,fab.fab$b_fns,fab.fab$l_fna); sys$exit(status); } rab = cc$rms_rab; rab.rab$l_fab = &fab; status = sys$connect(&rab); if (status != RMS$_NORMAL) { util_out_print("Error: Cannot connect to dump file !AD.",TRUE,fab.fab$b_fns,fab.fab$l_fna); sys$exit(status); } rab.rab$w_rsz = SIZEOF(buff); for (; ;) { status = sys$qiow (0, channel,IO$_READVBLK ,&stat_blk, 0, 0, mbuff, 512,0,0,0,0); if (status != SS$_NORMAL) { sys$exit(status); break; } if (stat_blk.status == SS$_ENDOFFILE) break; if (stat_blk.status != SS$_NORMAL) { sys$exit(stat_blk.status); break; } if (!memcmp("GT$S",mbuff,4)) { for ( c = mbuff; *c > 32 ; c++) ; d_sec.dsc$w_length = c - mbuff; flags = SEC$M_GBL | SEC$M_WRT | SEC$M_SYSGBL | SEC$M_PAGFIL | SEC$M_DZRO | SEC$M_PERM; addrs[0] = addrs[1] = 0; fid_from_sec(&d_sec,&file); real_size = cce_sec_size(&file); if (real_size == 0) real_size = size; real_size += 1; assert(OS_PAGE_SIZE % OS_PAGELET_SIZE == 0); /* Request enough pagelets to ensure enough contiguous pages to contain desired number of pagelets. */ req_size = ROUND_UP(real_size, OS_PAGE_SIZE); lib$get_vm_page(&req_size, &addrs[0]); /* addrs will hold addresses of start and end of contiguous block of pagelets for use by $deltva. */ assert((addrs[0] + (req_size * OS_PAGELET_SIZE) - 1) == addrs[1]); /* $get_vm_page returns pagelets; we must align to integral page boundary. */ /* sec_addrs will contain the starting and ending addresses of the mapped section. */ sec_addrs[0] = ROUND_UP(addrs[0], OS_PAGE_SIZE); /* align to first integral page boundary */ sec_addrs[1] = addrs[0] + (real_size * OS_PAGELET_SIZE); sec_addrs[1] = ROUND_UP(addrs[1], OS_PAGE_SIZE) - 1; /* A(last byte of last page) */ status = init_sec(sec_addrs, &d_sec, 0, real_size, flags); if (status & 1) { sd = sec_addrs[0]; memset(buff, 0, RECORD_SIZE); memcpy(buff, d_sec.dsc$a_pointer, d_sec.dsc$w_length); cptr = &buff[0] + d_sec.dsc$w_length; memcpy(cptr,id_lab,SIZEOF(id_lab)); cptr += SIZEOF(id_lab); memcpy(cptr,&file,SIZEOF(file)); rab.rab$l_rbf = buff; status = sys$put(&rab); if (status != RMS$_NORMAL) { util_out_print("Error writing to dump file !AD.",TRUE,fab.fab$b_fns,fab.fab$l_fna); util_out_print("Status code is !UL.",TRUE,status); break; } for (c = sd, i = 0; (real_size + EXTRA_SPACE) >= i; c += RECORD_SIZE, i += (RECORD_SIZE / DISK_BLOCK_SIZE)) { rab.rab$l_rbf = c; status = sys$put(&rab); if (status != RMS$_NORMAL) { util_out_print("Error writing to dump file !AD.",TRUE,fab.fab$b_fns,fab.fab$l_fna); util_out_print("Status code is !UL.",TRUE,status); break; } } lib$signal(ERR_CCEDBDUMP,2,d_sec.dsc$w_length,d_sec.dsc$a_pointer); }else { lib$signal(ERR_CCEDBNODUMP,2,d_sec.dsc$w_length,d_sec.dsc$a_pointer,status,0); } gtm_deltva(&addrs[0],0,0); lib$free_vm_page(&real_size,&addrs[0]); } } sys$exit(SS$_NORMAL); }
main() { struct FAB fab; header_struct *header; gd_addr *addr, *addr1, *addr2, *addr3; gd_region *region; gd_segment *segment; int4 *long_ptr, ret_addr; short iosb[4]; mval v; char file_name1[] = "dtgbld01.gld", file_name2[] = "dtgbld02.gld", file_name3[] = "dtgbld03.gld"; char label[] = GDE_LABEL_LITERAL; char file_name4[]="dtlog1"; uint4 status, size; $DESCRIPTOR(proc_tab, "LNM$PROCESS"); $DESCRIPTOR(gbldir, "GTM$GBLDIR"); $DESCRIPTOR(dtlog, "DTLOG1"); typedef struct { short buf_len; short item; int4 buf_addr; int4 ret_addr; int4 term; } item_list; item_list ilist; char acmo=PSL$C_USER; /************************* Create logical names for tests **********************************************************/ ilist.item = LNM$_STRING; ilist.buf_len = SIZEOF(file_name1) - 1; ilist.buf_addr = file_name1; ilist.term = 0; ilist.ret_addr = &ret_addr; status = sys$crelnm(0, &proc_tab, &gbldir, &acmo, &ilist); if (!(status & 1)) rts_error(VARLSTCNT(1) status); ilist.buf_len = SIZEOF(file_name2) - 1; ilist.buf_addr = file_name2; status = sys$crelnm(0, &proc_tab, &dtlog, &acmo, &ilist); if (!(status & 1)) rts_error(VARLSTCNT(1) status); /************************* Create global directory files for tests *************************************************/ fab = cc$rms_fab; fab.fab$l_alq = 5; fab.fab$l_fna = file_name1; fab.fab$b_fns = SIZEOF(file_name1) - 1; fab.fab$l_fop = (FAB$M_UFO | FAB$M_CBT); fab.fab$b_fac = (FAB$M_PUT | FAB$M_GET | FAB$M_BIO); fab.fab$b_shr = (FAB$M_SHRPUT | FAB$M_SHRGET | FAB$M_UPI); status = sys$create(&fab); if (status != RMS$_CREATED && status != RMS$_FILEPURGED && status != RMS$_NORMAL) sys$exit(status); size = SIZEOF(header_struct) + SIZEOF(gd_addr) + 3 * SIZEOF(gd_binding) + SIZEOF(gd_region) + SIZEOF(gd_segment); header = malloc(((size + 511) / 512) * 512); header->filesize = size; size = ((size + 511) / 512) * 512; memcpy(header->label, label, SIZEOF(label)-1); addr = (char*)header + SIZEOF(header_struct); addr->maps = SIZEOF(gd_addr); addr->n_maps = 3; addr->regions = (int4)(addr->maps) + 3 * SIZEOF(gd_binding); addr->n_regions = 1; addr->segments = (int4)(addr->regions) + SIZEOF(gd_region); addr->n_segments = 1; addr->link = addr->tab_ptr = addr->id = addr->local_locks = 0; addr->max_rec_size = 100; addr->end = addr->segments + SIZEOF(gd_segment); long_ptr = (char*)addr + (int4)(addr->maps); *long_ptr++ = 0xFFFF2F23; *long_ptr++ = 0xFFFFFFFF; *long_ptr++ = addr->regions; *long_ptr++ = 0xFFFFFF24; *long_ptr++ = 0xFFFFFFFF; *long_ptr++ = addr->regions; *long_ptr++ = 0xFFFFFFFF; *long_ptr++ = 0xFFFFFFFF; *long_ptr++ = addr->regions; region = (char*)addr + (int4)(addr->regions); segment = (char*)addr + (int4)(addr->segments); memset(region, 0, SIZEOF(gd_region)); region->rname_len = 5; memcpy(region->rname,"TEMP1",5); region->dyn.offset = addr->segments; region->max_rec_size = 100; region->max_key_size = 64; segment->sname_len = 5; memcpy(segment->sname, "TEMP1", 5); memcpy(segment->fname, "MUMPS1.DAT", 10); segment->fname_len = 10; segment->blk_size = 2 * DISK_BLOCK_SIZE; segment->allocation = 100; segment->ext_blk_count = 100; segment->cm_blk = 0; segment->lock_space = 20; memcpy(segment->defext, ".DAT", 4); segment->global_buffers = 64; segment->buckets = 0; segment->windows = 0; segment->acc_meth = dba_bg; segment->defer_time = 0; segment->file_cntl = 0; status = sys$qiow(EFN$C_ENF, fab.fab$l_stv, IO$_WRITEVBLK, &iosb[0], 0, 0, header, size, 1, 0, 0, 0); if (!(status & 1)) rts_error(VARLSTCNT(1) status); if (!(iosb[0] & 1)) rts_error(VARLSTCNT(1) status); sys$dassgn(fab.fab$l_stv); region->rname_len = 5; memcpy(region->rname,"TEMP2",5); segment->sname_len = 5; memcpy(segment->sname,"TEMP2",5); memcpy(segment->fname,"MUMPS2.DAT",10); segment->fname_len = 10; fab.fab$l_fna = file_name2; fab.fab$b_fns = SIZEOF(file_name3) - 1; status = sys$create(&fab); if (status != RMS$_CREATED && status != RMS$_FILEPURGED && status != RMS$_NORMAL) sys$exit(status); status = sys$qiow(EFN$C_ENF, fab.fab$l_stv, IO$_WRITEVBLK, &iosb[0], 0, 0, header, size, 1, 0, 0, 0); if (!(status & 1)) rts_error(VARLSTCNT(1) status); if (!(iosb[0] & 1)) rts_error(VARLSTCNT(1) status); sys$dassgn(fab.fab$l_stv); region->rname_len = 5; memcpy(region->rname, "TEMP3", 5); segment->sname_len = 5; memcpy(segment->sname, "TEMP3", 5); memcpy(segment->fname, "MUMPS3.DAT", 10); segment->fname_len = 10; fab.fab$l_fna = file_name3; fab.fab$b_fns = SIZEOF(file_name3) - 1; status = sys$create(&fab); if (status != RMS$_CREATED && status != RMS$_FILEPURGED && status != RMS$_NORMAL) sys$exit(status); status = sys$qiow(EFN$C_ENF, fab.fab$l_stv, IO$_WRITEVBLK, &iosb[0], 0, 0, header, size, 1, 0, 0, 0); if (!(status & 1)) rts_error(VARLSTCNT(1) status); if (!(iosb[0] & 1)) rts_error(VARLSTCNT(1) status); sys$dassgn(fab.fab$l_stv); /*************************** Run tests********************************************/ v.str.len = SIZEOF(file_name1) - 1; v.str.addr = file_name1; PRINTF("Open first global directory: dtgbld01.gld\n"); addr1 = zgbldir(&v); PRINTF("Region name is %s, expected TEMP1\n", addr1->regions->rname); PRINTF("Segment name is %s, expected TEMP1\n", addr1->regions->dyn.addr->sname); PRINTF("File name is %s, expected MUMPS1.DAT\n", addr1->regions->dyn.addr->fname); v.str.len = SIZEOF(file_name2) - 1; v.str.addr = file_name2; PRINTF("Open second global directory: dtgbld02.gld\n"); addr2 = zgbldir(&v); PRINTF("Region name is %s, expected TEMP2\n", addr2->regions->rname); PRINTF("Segment name is %s, expected TEMP2\n", addr2->regions->dyn.addr->sname); PRINTF("File name is %s, expected MUMPS2.DAT\n", addr2->regions->dyn.addr->fname); v.str.len = SIZEOF(file_name3) - 1; v.str.addr = file_name3; PRINTF("Open third global directory: dtgbld03.gld\n"); addr3 = zgbldir(&v); PRINTF("Region name is %s, expected TEMP3\n", addr3->regions->rname); PRINTF("Segment name is %s, expected TEMP3\n", addr3->regions->dyn.addr->sname); PRINTF("File name is %s, expected MUMPS3.DAT\n", addr3->regions->dyn.addr->fname); PRINTF("Open null string global directory: dtgbld01.gld\n"); v.str.len = 0; addr = zgbldir(&v); if (addr != addr1) PRINTF("Expected pointer to previous struct, got new structure\n"); else PRINTF("Got same pointer as expected.\n"); PRINTF("Open dtlog1 global directory: dtgbld02.gld\n"); v.str.len = SIZEOF(file_name4) - 1; v.str.addr = file_name4; addr = zgbldir(&v); if (addr != addr2) PRINTF("Expected pointer to previous struct, got new structure\n"); else PRINTF("Got same pointer as expected.\n"); v.str.len = SIZEOF(file_name3) - 1; v.str.addr = file_name3; PRINTF("Reopen third global directory: dtgbld03.gld\n"); addr = zgbldir(&v); if (addr != addr3) PRINTF("Expected pointer to previous struct, got new structure\n"); else PRINTF("Got same pointer as expected.\n"); return; }
int rlMailbox::read(void *buf, int maxlen, int wait) { char *cbuf; status = OK; cbuf = (char *) buf; #ifdef RLUNIX int len; unsigned char *message = new unsigned char [sizeof(long) + maxlen]; if(wait == WAIT ) len = msgrcv(chanid,(struct msgbuf *) message, maxlen,0,0); else len = msgrcv(chanid,(struct msgbuf *) message, maxlen,0,IPC_NOWAIT); if(len < maxlen && len >= 0) { memcpy(buf,&message[sizeof(long)],len); cbuf[len] = '\0'; } else { cbuf[0] = '\0'; } delete [] message; return len; #endif #ifdef __VMS int ret,len; IOSB iosb; if(wait == NOWAIT) { ret = sys$qiow(0, (short) chanid, IO$_READVBLK | IO$M_NOW, // I/O CODE &iosb, 0,0, buf, maxlen,0,0,0,0); } else { ret = sys$qiow(0, (short) chanid, IO$_READVBLK, // I/O CODE &iosb, 0,0, buf, maxlen,0,0,0,0); } len = (int) iosb.msg_len; if(len < maxlen && len >= 0) cbuf[len] = '\0'; if (ret == SS$_NORMAL && iosb.iostat == SS$_NORMAL) return len; else if(iosb.iostat == SS$_NORMAL) { status = -1; return MAILBOX_ERROR; } else if(ret == SS$_NORMAL) { if(wait == NOWAIT && iosb.iostat == SS$_ENDOFFILE) { status = -2; return MAILBOX_ERROR; } else { status = -3; return MAILBOX_ERROR; } } status = -4; return MAILBOX_ERROR; #endif #ifdef RLWIN32 HANDLE h; char mbxname[1024]; unsigned long lenRead; BOOL bret,bret2; if(chanid == -1) { strcpy(mbxname,"\\\\.\\mailslot\\"); strcat(mbxname,name); h = CreateMailslot( mbxname, // pointer to string for mailslot name MAX_MAILBOX, // maximum message size MAILSLOT_WAIT_FOREVER, // milliseconds before read time-out NULL); // pointer to security structure if(h == INVALID_HANDLE_VALUE) { status = GetLastError(); return MAILBOX_ERROR; } chanid = (int) h; bret2 = SetMailslotInfo((HANDLE) chanid, MAILSLOT_WAIT_FOREVER); if(bret2 == 0) { status = GetLastError(); return MAILBOX_ERROR; } } if(wait == NOWAIT) // begin wait { lenRead = 0; bret2 = SetMailslotInfo((HANDLE) chanid, 0); if(bret2 == 0) { status = GetLastError(); return MAILBOX_ERROR; } bret = ReadFile( (HANDLE) chanid, // handle of file to read buf, // pointer to buffer maxlen, // number of bytes to read &lenRead, // pointer to number of bytes read NULL // pointer to structure for data ); bret2 = SetMailslotInfo((HANDLE) chanid, MAILSLOT_WAIT_FOREVER); if(bret2 == 0) { status = GetLastError(); return MAILBOX_ERROR; } if(bret == 0) { status = GetLastError(); return MAILBOX_ERROR; } if((int) lenRead < maxlen && (int) lenRead >= 0) cbuf[lenRead] = '\0'; return lenRead; } // end wait lenRead = 0; bret = ReadFile( (HANDLE) chanid, // handle of file to read buf, // pointer to buffer maxlen, // number of bytes to read &lenRead, // pointer to number of bytes read NULL // pointer to structure for data ); if(bret == 0) { status = GetLastError(); return MAILBOX_ERROR; } if((int) lenRead < maxlen && (int) lenRead >= 0) cbuf[lenRead] = '\0'; return lenRead; #endif }
bool mubinccpy(backup_reg_list *list) { static readonly mval null_str = {MV_STR, 0, 0 , 0 , 0, 0}; int backup_socket; int4 size, size1, bsize, bm_num, hint, lmsize, save_blks, rsize, match, timeout, outsize; uint4 status, total_blks, bplmap, gds_ratio, blks_per_buff, counter, i, lcnt, read_size; uchar_ptr_t bm_blk_buff, ptr1, ptr1_top, ptr, ptr_top; char_ptr_t outptr, data_ptr; unsigned short rd_iosb[4], port; enum db_acc_method access; blk_hdr *bp, *bptr; struct FAB *fcb, temp_fab, mubincfab; struct RAB temp_rab, mubincrab; inc_header *outbuf; mval val; mstr *file; sgmnt_data_ptr_t header; char *common, addr[SA_MAXLEN + 1]; void (*common_write)(); void (*common_close)(); muinc_blk_hdr_ptr_t sblkh_p; trans_num blk_tn; block_id blk_num_base, blk_num; boolean_t is_bitmap_blk, backup_this_blk; enum db_ver dummy_odbv; int4 blk_bsiz; error_def(ERR_BCKUPBUFLUSH); error_def(ERR_COMMITWAITSTUCK); error_def(ERR_DBCCERR); error_def(ERR_ERRCALL); assert(list->reg == gv_cur_region); assert(incremental); /* Make sure inc_header can be same size on all platforms. Some platforms pad 8 byte aligned structures that end on a 4 byte boundary and some do not. It is critical that this structure is the same size on all platforms as it is sent across TCP connections when doing TCP backup. */ assert(0 == (SIZEOF(inc_header) % 8)); /* ================= Initialization and some checks ======================== */ header = list->backup_hdr; file = &(list->backup_file); if (!mubtomag) mubmaxblk = BACKUP_TEMPFILE_BUFF_SIZE; fcb = ((vms_gds_info *)(gv_cur_region->dyn.addr->file_cntl->file_info))->fab; if (list->tn >= header->trans_hist.curr_tn) { util_out_print("!/TRANSACTION number is greater than or equal to current transaction,", TRUE); util_out_print("No blocks backed up from database !AD", TRUE, fcb->fab$b_fns, fcb->fab$l_fna); return TRUE; } /* =========== open backup destination and define common_write ================= */ backup_write_errno = 0; backup_close_errno = 0; switch(list->backup_to) { case backup_to_file: /* open the file and define the common_write function */ mubincfab = cc$rms_fab; mubincfab.fab$b_fac = FAB$M_PUT; mubincfab.fab$l_fop = FAB$M_CBT | FAB$M_MXV | FAB$M_TEF | FAB$M_POS & (~FAB$M_RWC) & (~FAB$M_RWO); mubincfab.fab$l_fna = file->addr; mubincfab.fab$b_fns = file->len; mubincfab.fab$l_alq = cs_addrs->hdr->start_vbn + STARTING_BLOCKS * cs_addrs->hdr->blk_size / DISK_BLOCK_SIZE; mubincfab.fab$w_mrs = mubmaxblk; mubincfab.fab$w_deq = EXTEND_SIZE; switch (status = sys$create(&mubincfab)) { case RMS$_NORMAL: case RMS$_CREATED: case RMS$_SUPERSEDE: case RMS$_FILEPURGED: break; default: gtm_putmsg(status, 0, mubincfab.fab$l_stv); util_out_print("Error: Cannot create backup file !AD.", TRUE, mubincfab.fab$b_fns, mubincfab.fab$l_fna); return FALSE; } mubincrab = cc$rms_rab; mubincrab.rab$l_fab = &mubincfab; mubincrab.rab$l_rop = RAB$M_WBH; if (RMS$_NORMAL != (status = sys$connect(&mubincrab))) { gtm_putmsg(status, 0, mubincrab.rab$l_stv); util_out_print("Error: Cannot connect to backup file !AD.", TRUE, mubincfab.fab$b_fns, mubincfab.fab$l_fna); mubincfab.fab$l_fop |= FAB$M_DLT; sys$close(&mubincfab); return FALSE; } common = (char *)(&mubincrab); common_write = file_write; common_close = file_close; break; case backup_to_exec: util_out_print("Error: Backup to pipe is yet to be implemented.", TRUE); util_out_print("Error: Your request to backup database !AD to !AD is currently not valid.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna, file->len, file->addr); return FALSE; case backup_to_tcp: iotcp_fillroutine(); /* parse it first */ switch (match = SSCANF(file->addr, "%[^:]:%hu", addr, &port)) { case 1 : port = DEFAULT_BKRS_PORT; case 2 : break; default : util_out_print("ERROR: A hostname has to be specified to backup through a TCP connection.", TRUE); return FALSE; } if ((0 == cli_get_int("NETTIMEOUT", &timeout)) || (0 > timeout)) timeout = DEFAULT_BKRS_TIMEOUT; if (0 > (backup_socket = tcp_open(addr, port, timeout, FALSE))) { util_out_print("ERROR: Cannot open tcp connection due to the above error.", TRUE); return FALSE; } common_write = tcp_write; common_close = tcp_close; common = (char *)(&backup_socket); break; default : util_out_print("ERROR: Backup format !UL not supported.", TRUE, list->backup_to); util_out_print("Error: Your request to backup database !AD to !AD is not valid.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna, file->len, file->addr); return FALSE; } /* ============================= write inc_header =========================================== */ outptr = malloc(SIZEOF(inc_header)); outbuf = (inc_header *)outptr; MEMCPY_LIT(&outbuf->label[0], INC_HEADER_LABEL); stringpool.free = stringpool.base; op_horolog(&val); stringpool.free = stringpool.base; op_fnzdate(&val, &mu_bin_datefmt, &null_str, &null_str, &val); memcpy(&outbuf->date[0], val.str.addr, val.str.len); memcpy(&outbuf->reg[0], gv_cur_region->rname, MAX_RN_LEN); outbuf->start_tn = list->tn; outbuf->end_tn = header->trans_hist.curr_tn; outbuf->db_total_blks = header->trans_hist.total_blks; outbuf->blk_size = header->blk_size; outbuf->blks_to_upgrd = header->blks_to_upgrd; COMMON_WRITE(common, outptr, SIZEOF(inc_header)); free(outptr); if (mu_ctrly_occurred || mu_ctrlc_occurred) { error_mupip = TRUE; COMMON_CLOSE(common); util_out_print("WARNING: DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna); return FALSE; } /* ============================ read/write appropriate blocks =============================== */ bsize = header->blk_size; gds_ratio = bsize / DISK_BLOCK_SIZE; blks_per_buff = BACKUP_READ_SIZE / bsize; read_size = blks_per_buff * bsize; outsize = SIZEOF(muinc_blk_hdr) + bsize; outptr = (char_ptr_t)malloc(MAX(outsize, mubmaxblk)); sblkh_p = (muinc_blk_hdr_ptr_t)outptr; data_ptr = (char_ptr_t)(sblkh_p + 1); bp = (blk_hdr_ptr_t)mubbuf; bm_blk_buff = (uchar_ptr_t)malloc(SIZEOF(blk_hdr) + (BLKS_PER_LMAP * BML_BITS_PER_BLK / BITS_PER_UCHAR)); mubincrab.rab$l_rbf = outptr; save_blks = 0; access = header->acc_meth; memset(sblkh_p, 0, SIZEOF(*sblkh_p)); if (access == dba_bg) bp = mubbuf; else { ptr = cs_addrs->db_addrs[0] + (cs_addrs->hdr->start_vbn - 1) * DISK_BLOCK_SIZE; ptr_top = cs_addrs->db_addrs[1] + 1; } sblkh_p->use.bkup.ondsk_blkver = GDSNOVER; for (blk_num_base = 0; blk_num_base < header->trans_hist.total_blks; blk_num_base += blks_per_buff) { if (online && (0 != cs_addrs->shmpool_buffer->failed)) break; if (header->trans_hist.total_blks - blk_num_base < blks_per_buff) { blks_per_buff = header->trans_hist.total_blks - blk_num_base; read_size = blks_per_buff * bsize; } if (access == dba_bg) { if ((SS$_NORMAL != (status = sys$qiow(EFN$C_ENF, fcb->fab$l_stv, IO$_READVBLK, &rd_iosb, 0, 0, bp, read_size, cs_addrs->hdr->start_vbn + (gds_ratio * blk_num_base), 0, 0, 0))) || (SS$_NORMAL != (status = rd_iosb[0]))) { gtm_putmsg(VARLSTCNT(1) status); util_out_print("Error reading data from database !AD.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna); free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); return FALSE; } } else { assert(dba_mm == access); bp = ptr + blk_num_base * bsize; } bptr = (blk_hdr *)bp; /* The blocks we back up will be whatever version they are. There is no implicit conversion in this part of the backup/restore. Since we aren't even looking at the blocks (and indeed some of these blocks could potentially contain unintialized garbage data), we set the block version to GDSNOVER to signal that the block version is unknown. The above applies to "regular" blocks but not to bitmap blocks which we know are initialized. Because we have to read the bitmap blocks, they will be converted as necessary. */ for (i = 0; i < blks_per_buff && ((blk_num_base + i) < header->trans_hist.total_blks); i++, bptr = (blk_hdr *)((char *)bptr + bsize)) { blk_num = blk_num_base + i; if (mu_ctrly_occurred || mu_ctrlc_occurred) { free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); util_out_print("WARNING: DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna); return FALSE; } /* Before we check if this block needs backing up, check if this is a new bitmap block or not. If it is, we can fall through and back it up as normal. But if this is NOT a bitmap block, use the existing bitmap to determine if this block has ever been allocated or not. If not, we don't want to even look at this block. It could be uninitialized which will just make things run slower if we go to read it and back it up. */ if (0 != ((BLKS_PER_LMAP - 1) & blk_num)) { /* Not a local bitmap block */ if (!gvcst_blk_ever_allocated(bm_blk_buff + SIZEOF(blk_hdr), ((blk_num * BML_BITS_PER_BLK) % (BLKS_PER_LMAP * BML_BITS_PER_BLK)))) continue; /* Bypass never-set blocks to avoid conversion problems */ is_bitmap_blk = FALSE; if (SIZEOF(v15_blk_hdr) <= (blk_bsiz = ((v15_blk_hdr_ptr_t)bptr)->bsiz)) { /* We have either a V4 block or uninitialized garbage */ if (blk_bsiz > bsize) /* This is not a valid V4 block so ignore it */ continue; blk_tn = ((v15_blk_hdr_ptr_t)bptr)->tn; } else { /* Assume V5 block */ if ((blk_bsiz = bptr->bsiz) > bsize) /* Not a valid V5 block either */ continue; blk_tn = bptr->tn; } } else { /* This is a bitmap block so save it into our bitmap block buffer. It is used as the basis of whether or not we have to process a given block or not. We process allocated and recycled blocks leaving free (never used) blocks alone as they have no data worth saving. But after saving it, upgrade it to the current format if necessary. */ is_bitmap_blk = TRUE; memcpy(bm_blk_buff, bptr, BM_SIZE(header->bplmap)); if (SIZEOF(v15_blk_hdr) <= ((v15_blk_hdr_ptr_t)bm_blk_buff)->bsiz) { /* This is a V4 format block -- needs upgrading */ status = gds_blk_upgrade(bm_blk_buff, bm_blk_buff, bsize, &dummy_odbv); if (SS_NORMAL != status) { free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); util_out_print("Error: Block 0x!XL is too large for automatic upgrade", TRUE, sblkh_p->blkid); return FALSE; } } assert(BM_SIZE(header->bplmap) == ((blk_hdr_ptr_t)bm_blk_buff)->bsiz); assert(LCL_MAP_LEVL == ((blk_hdr_ptr_t)bm_blk_buff)->levl); assert(gvcst_blk_is_allocated(bm_blk_buff + SIZEOF(blk_hdr), ((blk_num * BML_BITS_PER_BLK) % (BLKS_PER_LMAP * BML_BITS_PER_BLK)))); blk_bsiz = BM_SIZE(header->bplmap); blk_tn = ((blk_hdr_ptr_t)bm_blk_buff)->tn; } /* The conditions for backing up a block or ignoring it (in order of evaluation): 1) If blk is larger than size of db at time backup was initiated, we ignore the block. 2) Always backup blocks 0, 1, and 2 as these are the only blocks that can contain data and still have a transaction number of 0. 3) For bitmap blocks, if blks_to_upgrd != 0 and the TN is 0 and the block number >= last_blk_at_last_bkup, then backup the block. This way we get the correct version of the bitmap block in the restore (otherwise have no clue what version to create them in as bitmaps are created with a TN of 0 when before image journaling is enabled). 4) If the block TN is below our TN threshold, ignore the block. 5) Else if none of the above conditions, backup the block. */ if (online && (header->trans_hist.curr_tn <= blk_tn)) backup_this_blk = FALSE; else if (3 > blk_num || (is_bitmap_blk && 0 != header->blks_to_upgrd && (trans_num)0 == blk_tn && blk_num >= list->last_blk_at_last_bkup)) backup_this_blk = TRUE; else if ((blk_tn < list->tn)) backup_this_blk = FALSE; else backup_this_blk = TRUE; if (!backup_this_blk) { if (online) cs_addrs->nl->nbb = blk_num; continue; /* not applicable */ } sblkh_p->blkid = blk_num; memcpy(data_ptr, bptr, blk_bsiz); sblkh_p->valid_data = TRUE; /* Validation marker */ COMMON_WRITE(common, outptr, outsize); if (online) { if (0 != cs_addrs->shmpool_buffer->failed) break; cs_addrs->nl->nbb = blk_num; } save_blks++; } } /* ============================= write saved information for online backup ========================== */ if (online && (0 == cs_addrs->shmpool_buffer->failed)) { /* -------- make sure everyone involved finishes -------- */ cs_addrs->nl->nbb = BACKUP_NOT_IN_PROGRESS; /* By getting crit here, we ensure that there is no process still in transaction logic that sees (nbb != BACKUP_NOT_IN_PRORESS). After rel_crit(), any process that enters transaction logic will see (nbb == BACKUP_NOT_IN_PRORESS) because we just set it to that value. At this point, backup buffer is complete and there will not be any more new entries in the backup buffer until the next backup. */ grab_crit(gv_cur_region); assert(cs_data == cs_addrs->hdr); if (dba_bg == cs_data->acc_meth) { /* Now that we have crit, wait for any pending phase2 updates to finish. Since phase2 updates happen * outside of crit, we dont want them to keep writing to the backup temporary file even after the * backup is complete and the temporary file has been deleted. */ if (cs_addrs->nl->wcs_phase2_commit_pidcnt && !wcs_phase2_commit_wait(cs_addrs, NULL)) { gtm_putmsg(VARLSTCNT(7) ERR_COMMITWAITSTUCK, 5, process_id, 1, cs_addrs->nl->wcs_phase2_commit_pidcnt, DB_LEN_STR(gv_cur_region)); rel_crit(gv_cur_region); free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); return FALSE; } } if (debug_mupip) { util_out_print("MUPIP INFO: Current Transaction # at end of backup is 0x!16@XQ", TRUE, &cs_data->trans_hist.curr_tn); } rel_crit(gv_cur_region); counter = 0; while (0 != cs_addrs->shmpool_buffer->backup_cnt) { if (0 != cs_addrs->shmpool_buffer->failed) { util_out_print("Process !UL encountered the following error.", TRUE, cs_addrs->shmpool_buffer->failed); if (0 != cs_addrs->shmpool_buffer->backup_errno) gtm_putmsg(VARLSTCNT(1) cs_addrs->shmpool_buffer->backup_errno); free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); return FALSE; } backup_buffer_flush(gv_cur_region); if (++counter > MAX_BACKUP_FLUSH_TRY) { gtm_putmsg(VARLSTCNT(1) ERR_BCKUPBUFLUSH); free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); return FALSE; } if (counter & 0xF) wcs_sleep(counter); else { /* Force shmpool recovery to see if it can find the lost blocks */ if (!shmpool_lock_hdr(gv_cur_region)) { gtm_putmsg(VARLSTCNT(9) ERR_DBCCERR, 2, REG_LEN_STR(gv_cur_region), ERR_ERRCALL, 3, CALLFROM); free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); assert(FALSE); return FALSE;; } shmpool_abandoned_blk_chk(gv_cur_region, TRUE); shmpool_unlock_hdr(gv_cur_region); } } /* -------- Open the temporary file -------- */ temp_fab = cc$rms_fab; temp_fab.fab$b_fac = FAB$M_GET; temp_fab.fab$l_fna = list->backup_tempfile; temp_fab.fab$b_fns = strlen(list->backup_tempfile); temp_rab = cc$rms_rab; temp_rab.rab$l_fab = &temp_fab; for (lcnt = 1; MAX_OPEN_RETRY >= lcnt; lcnt++) { if (RMS$_FLK != (status = sys$open(&temp_fab, NULL, NULL))) break; wcs_sleep(lcnt); } if (RMS$_NORMAL != status) { gtm_putmsg(status, 0, temp_fab.fab$l_stv); util_out_print("WARNING: DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna); free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); return FALSE; } if (RMS$_NORMAL != (status = sys$connect(&temp_rab))) { gtm_putmsg(status, 0, temp_rab.rab$l_stv); util_out_print("WARNING: DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna); free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); return FALSE; } /* -------- read and write every record in the temporary file -------- */ while (1) { temp_rab.rab$w_usz = outsize; temp_rab.rab$l_ubf = outptr; status = sys$get(&temp_rab); if (RMS$_NORMAL != status) { if (RMS$_EOF == status) status = RMS$_NORMAL; break; } assert(outsize == temp_rab.rab$w_rsz); /* Still validly sized blk? */ assert((outsize - SIZEOF(shmpool_blk_hdr)) >= ((blk_hdr_ptr_t)(outptr + SIZEOF(shmpool_blk_hdr)))->bsiz); COMMON_WRITE(common, outptr, temp_rab.rab$w_rsz); } if (RMS$_NORMAL != status) { gtm_putmsg(status, 0, temp_rab.rab$l_stv); util_out_print("WARNING: DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna); free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); return FALSE; } /* ---------------- Close the temporary file ----------------------- */ if (RMS$_NORMAL != (status = sys$close(&temp_fab))) { gtm_putmsg(status, 0, temp_fab.fab$l_stv); util_out_print("WARNING: DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna); free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); return FALSE; } } /* ============================= write end_msg and fileheader ======================================= */ if ((!online) || (0 == cs_addrs->shmpool_buffer->failed)) { MEMCPY_LIT(outptr, END_MSG); /* Although the write only need be of length SIZEOF(END_MSG) - 1 for file IO, if the write is going to TCP we have to write all these records with common length so just write the "regular" sized buffer. The extra garbage left over from the last write will be ignored as we key only on the this end text. */ COMMON_WRITE(common, outptr, outsize); ptr1 = header; size1 = ROUND_UP(SIZEOF(sgmnt_data), DISK_BLOCK_SIZE); ptr1_top = ptr1 + size1; for (;ptr1 < ptr1_top ; ptr1 += size1) { if ((size1 = ptr1_top - ptr1) > mubmaxblk) size1 = (mubmaxblk / DISK_BLOCK_SIZE) * DISK_BLOCK_SIZE; COMMON_WRITE(common, ptr1, size1); } MEMCPY_LIT(outptr, HDR_MSG); COMMON_WRITE(common, outptr, SIZEOF(HDR_MSG)); ptr1 = MM_ADDR(header); size1 = ROUND_UP(MASTER_MAP_SIZE(header), DISK_BLOCK_SIZE); ptr1_top = ptr1 + size1; for (;ptr1 < ptr1_top ; ptr1 += size1) { if ((size1 = ptr1_top - ptr1) > mubmaxblk) size1 = (mubmaxblk / DISK_BLOCK_SIZE) * DISK_BLOCK_SIZE; COMMON_WRITE(common, ptr1, size1); } MEMCPY_LIT(outptr, MAP_MSG); COMMON_WRITE(common, outptr, SIZEOF(MAP_MSG)); } /* ================== close backup destination, output and return ================================== */ if (online && (0 != cs_addrs->shmpool_buffer->failed)) { util_out_print("Process !UL encountered the following error.", TRUE, cs_addrs->shmpool_buffer->failed); if (0 != cs_addrs->shmpool_buffer->backup_errno) gtm_putmsg(VARLSTCNT(1) cs_addrs->shmpool_buffer->backup_errno); free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); return FALSE; } COMMON_CLOSE(common); free(outptr); free(bm_blk_buff); util_out_print("DB file !AD incrementally backed up in !AD", TRUE, fcb->fab$b_fns, fcb->fab$l_fna, file->len, file->addr); util_out_print("!UL blocks saved.", TRUE, save_blks); util_out_print("Transactions from 0x!16@XQ to 0x!16@XQ are backed up.", TRUE, &cs_addrs->shmpool_buffer->inc_backup_tn, &header->trans_hist.curr_tn); cs_addrs->hdr->last_inc_backup = header->trans_hist.curr_tn; if (record) cs_addrs->hdr->last_rec_backup = header->trans_hist.curr_tn; file_backed_up = TRUE; return TRUE; }
short iott_open(io_log_name *dev_name, mval *pp, int fd, mval *mspace, int4 timeout) { bool ast_get_static(int); /* TODO; move to a header */ unsigned char buf[256], ch, sensemode[8]; short dummy; int4 bufsz, devtype, buflen; uint4 status; unsigned int req_code; d_tt_struct *tt_ptr; io_desc *ioptr; iosb dvisb; t_cap t_mode; int p_offset; struct { item_list_3 item[1]; int4 terminator; } item_list; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; ioptr = dev_name->iod; if (dev_never_opened == ioptr->state) ioptr->dev_sp = (d_tt_struct *)(malloc(SIZEOF(d_tt_struct))); tt_ptr = (d_tt_struct *)ioptr->dev_sp; if (dev_open != ioptr->state) { short channel; $DESCRIPTOR(file_name, ""); if (FALSE == ast_get_static(TERMINAL_STATIC_ASTS)) rts_error(VARLSTCNT(1) ERR_TERMASTQUOTA); file_name.dsc$a_pointer = dev_name->dollar_io; file_name.dsc$w_length = (unsigned short)dev_name->len; if (SS$_DEVALLOC == (status = sys$assign(&file_name, &channel, 0, 0)) || (SS$_INSFMEM == status) || (SS$_NOIOCHAN == status)) { astq_dyn_avail += TERMINAL_STATIC_ASTS; astq_dyn_alloc += TERMINAL_STATIC_ASTS; return FALSE; } if ((SS$_NORMAL != status) && (SS$_REMOTE != status)) { astq_dyn_avail += TERMINAL_STATIC_ASTS; rts_error(VARLSTCNT(1) status); } tt_ptr->channel = (int4)channel; tt_ptr->io_pending = tt_ptr->io_inuse = tt_ptr->io_free = tt_ptr->io_buffer = malloc(RING_BUF_SZ); tt_ptr->io_buftop = tt_ptr->io_buffer + RING_BUF_SZ; tt_ptr->sb_pending = tt_ptr->sb_free = tt_ptr->sb_buffer = malloc(IOSB_BUF_SZ * SIZEOF(iosb_struct)); tt_ptr->sb_buftop = tt_ptr->sb_buffer + IOSB_BUF_SZ; } if (dev_never_opened == ioptr->state) { status = sys$qiow(EFN$C_ENF, tt_ptr->channel, IO$_SENSEMODE, &tt_ptr->stat_blk, 0, 0, &t_mode, 12, 0, 0, 0, 0); if (SS$_NORMAL == status) status = tt_ptr->stat_blk.status; if (SS$_NORMAL != status) { astq_dyn_avail += TERMINAL_STATIC_ASTS; rts_error(VARLSTCNT(1) status); } tt_ptr->read_mask = IO_FUNC_R; tt_ptr->write_mask = IO_FUNC_W; tt_ptr->clock_on = FALSE; tt_ptr->term_char = t_mode.term_char; tt_ptr->ext_cap = t_mode.ext_cap; ioptr->width = t_mode.pg_width; ioptr->length = t_mode.pg_length; tt_ptr->in_buf_sz = TTDEF_BUF_SZ; tt_ptr->term_chars_twisted = FALSE; tt_ptr->enbld_outofbands.x = 0; if ((spc_inp_prc & (SHFT_MSK << CTRL_U)) && (tt_ptr->term_char & TT$M_SCOPE) && !(tt_ptr->ext_cap & TT2$M_PASTHRU)) tt_ptr->ctrlu_msk = (SHFT_MSK << CTRL_U); else tt_ptr->ctrlu_msk = 0; if (io_std_device.in) /* if this is the principal device, io_std_device.in is not yet set up, therefore the resetast is done later in term_setup so that it can pick the correct handler */ iott_resetast(ioptr); status = sys$qiow(EFN$C_ENF, tt_ptr->channel ,IO$_SENSEMODE|IO$M_RD_MODEM ,&tt_ptr->stat_blk, 0, 0 ,sensemode ,0, 0, 0, 0, 0); /* The first time this code is called is to open the principal device * and io_root_log_name->iod will be == 0, when that is true we do * not want to do the lat connect even if it is a lat device */ if ((SS$_NORMAL == status) && (SS$_NORMAL == tt_ptr->stat_blk.status) && (DT$_LAT == sensemode[0]) && (0 != io_root_log_name->iod)) { status = sys$qiow(EFN$C_ENF, tt_ptr->channel, IO$_TTY_PORT|IO$M_LT_CONNECT, &tt_ptr->stat_blk, 0, 0, 0, 0, 0, 0, 0, 0); /* If we try to open the principal device with a statement like * open "LTA66:" we will come through here and will get the * illegal io function error...just ignore it */ if (SS$_NORMAL == status) status = tt_ptr->stat_blk.status; if ((SS$_NORMAL != status) && (SS$_ILLIOFUNC != status)) { astq_dyn_avail += TERMINAL_STATIC_ASTS; rts_error(VARLSTCNT(1) status); } } item_list.item[0].buffer_length = SIZEOF(devtype); item_list.item[0].item_code = DVI$_DEVTYPE; item_list.item[0].buffer_address = &devtype; item_list.item[0].return_length_address = &dummy; item_list.terminator = 0; status = sys$getdviw(EFN$C_ENF, tt_ptr->channel, 0, &item_list, &dvisb, 0, 0, 0); if (SS$_NORMAL == status) status = dvisb.status; if (SS$_NORMAL != status) rts_error(VARLSTCNT(1) status); status = smg$init_term_table_by_type(&devtype, &tt_ptr->term_tab_entry, 0); if (!(status & 1)) { tt_ptr->erase_to_end_line.len = 0; tt_ptr->key_up_arrow.len = 0; tt_ptr->key_down_arrow.len = 0; tt_ptr->clearscreen.len = 0; } else { bufsz = SIZEOF(buf); req_code = SMG$K_ERASE_TO_END_LINE; status = smg$get_term_data(&tt_ptr->term_tab_entry, &req_code, &bufsz, &buflen, buf, 0); if (status & 1) { tt_ptr->erase_to_end_line.len = buflen; tt_ptr->erase_to_end_line.addr = malloc(tt_ptr->erase_to_end_line.len); memcpy(tt_ptr->erase_to_end_line.addr, buf, buflen); } else tt_ptr->erase_to_end_line.len = 0; req_code = SMG$K_KEY_UP_ARROW; status = smg$get_term_data(&tt_ptr->term_tab_entry, &req_code, &bufsz, &buflen, buf, 0); if (status & 1) { tt_ptr->key_up_arrow.len = buflen; tt_ptr->key_up_arrow.addr = malloc(tt_ptr->key_up_arrow.len); memcpy(tt_ptr->key_up_arrow.addr, buf, buflen); } else tt_ptr->key_up_arrow.len = 0; req_code = SMG$K_KEY_DOWN_ARROW; status = smg$get_term_data(&tt_ptr->term_tab_entry, &req_code, &bufsz, &buflen, buf, 0); if (status & 1) { tt_ptr->key_down_arrow.len = buflen; tt_ptr->key_down_arrow.addr = malloc(tt_ptr->key_down_arrow.len); memcpy(tt_ptr->key_down_arrow.addr, buf, buflen); } else tt_ptr->key_down_arrow.len = 0; req_code = SMG$K_ERASE_TO_END_DISPLAY; status = smg$get_term_data(&tt_ptr->term_tab_entry, &req_code, &bufsz, &buflen, buf, 0); if (status & 1) { tt_ptr->clearscreen.len = buflen; tt_ptr->clearscreen.addr = malloc(tt_ptr->clearscreen.len); memcpy(tt_ptr->clearscreen.addr, buf, buflen); } else tt_ptr->clearscreen.len = 0; } tt_ptr->item_len = 3 * SIZEOF(item_list_struct); tt_ptr->item_list[0].buf_len = 0; tt_ptr->item_list[0].item_code = TRM$_MODIFIERS; tt_ptr->item_list[0].addr = TRM$M_TM_TRMNOECHO; tt_ptr->item_list[0].ret_addr = 0; tt_ptr->item_list[1].buf_len = 0; tt_ptr->item_list[1].item_code = TRM$_TIMEOUT; tt_ptr->item_list[1].addr = NO_M_TIMEOUT; tt_ptr->item_list[1].ret_addr = 0; tt_ptr->item_list[2].buf_len = SIZEOF(io_termmask); tt_ptr->item_list[2].item_code = TRM$_TERM; tt_ptr->item_list[2].addr = malloc(SIZEOF(io_termmask)); memset(tt_ptr->item_list[2].addr, 0, SIZEOF(io_termmask)); ((io_termmask *)tt_ptr->item_list[2].addr)->mask[0] = (spc_inp_prc & (SHFT_MSK << CTRL_Z)) ? (TERM_MSK | (SHFT_MSK << CTRL_Z)) : TERM_MSK; tt_ptr->item_list[2].ret_addr = 0; tt_ptr->item_list[3].buf_len = 0; tt_ptr->item_list[3].item_code = TRM$_ESCTRMOVR; tt_ptr->item_list[3].addr = ESC_LEN - 1; tt_ptr->item_list[3].ret_addr = 0; tt_ptr->item_list[4].buf_len = (TREF(gtmprompt)).len; tt_ptr->item_list[4].item_code = TRM$_PROMPT; tt_ptr->item_list[4].addr = (TREF(gtmprompt)).addr; tt_ptr->item_list[4].ret_addr = 0; tt_ptr->item_list[5].buf_len = 0; tt_ptr->item_list[5].item_code = TRM$_INISTRNG; tt_ptr->item_list[5].addr = 0; tt_ptr->item_list[5].ret_addr = 0; if (0 != (t_mode.term_char & TT$M_WRAP)) ioptr->wrap = TRUE; } ioptr->state = dev_open; p_offset = 0; while (iop_eol != *(pp->str.addr + p_offset)) { if (iop_exception == (ch = *(pp->str.addr + p_offset++))) { ioptr->error_handler.len = *(pp->str.addr + p_offset); ioptr->error_handler.addr = pp->str.addr + p_offset + 1; s2pool(&ioptr->error_handler); break; } p_offset += ((IOP_VAR_SIZE == io_params_size[ch]) ? (unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[ch]); } return TRUE; }
static int vmsWrite( sqlite3_file *id, /* File to read from */ const void *vBuf, /* The bytes to be written */ int amt, /* Number of bytes to write */ sqlite3_int64 offset /* Offset into the file to begin writing at */ ){ struct atrdef atr[2]; struct ile3 jpilst[2]; FAT fat; struct fibdef fib; char buf[SQLITE_DEFAULT_SECTOR_SIZE]; const char *pBuf = vBuf; int bcnt, extend = 0, filesize, needed, remainder; struct dsc$descriptor fibdsc; unsigned short iosb[4]; int status; vmsFile *pFile = (vmsFile *)id; /* ** Determine the virtual block we are to write to, and a possbile byte ** position within that block. */ int vbn = (offset / SQLITE_DEFAULT_SECTOR_SIZE) + 1; int vpos = offset % SQLITE_DEFAULT_SECTOR_SIZE; memset(&fib, 0, sizeof(fib)); fib.fib$v_writethru = 1; fib.fib$w_fid[0] = pFile->nam.nam$w_fid[0]; fib.fib$w_fid[1] = pFile->nam.nam$w_fid[1]; fib.fib$w_fid[2] = pFile->nam.nam$w_fid[2]; fibdsc.dsc$w_length = sizeof(fib); fibdsc.dsc$a_pointer = (char *)&fib; atr[0].atr$w_size = ATR$S_RECATTR; atr[0].atr$w_type = ATR$C_RECATTR; atr[0].atr$l_addr = &fat; atr[1].atr$w_size = 0; atr[1].atr$w_type = 0; /* ** Before doing a write we determine the size of the file ** and if we need to extend it to perform the requested ** I/O. */ status = sys$qiow(EFN$C_ENF, pFile->chan, IO$_ACCESS, iosb, 0, 0, &fibdsc, 0, 0, 0, atr, 0); if( $VMS_STATUS_SUCCESS(status) && $VMS_STATUS_SUCCESS(status = iosb[0]) ){ filesize = (fat.fat$w_hiblkh << 16) | fat.fat$w_hiblkl; needed = (vbn + (amt / SQLITE_DEFAULT_SECTOR_SIZE)) + 1; if( pFile->szHint > 0 ){ needed = pFile->szHint > needed ? pFile->szHint : needed; pFile->szHint = 0; } if( filesize < needed ){ fib.fib$v_extend = 1; fib.fib$l_exvbn = 0; fib.fib$l_exsz = 0; /* ** Here we first check to see if the user has indicated their ** own extension size, otherwise we attempt to respect the ** default extensions of the file. Someone might have ** SET FILE/EXTENSION on the database file as a performance ** measure. However, if none is set, we just extend by how much ** we need of the system default, whichever is larger. */ if( pFile->szChunk > 0 ){ do{ fib.fib$l_exsz += pFile->szChunk; }while( fib.fib$l_exsz < needed ); }else{ if( fat.fat$w_defext ){ do{ fib.fib$l_exsz += fat.fat$w_defext; }while( fib.fib$l_exsz < needed ); }else{ jpilst[0].itmcod = JPI$_RMS_EXTEND_SIZE; jpilst[0].buflen = sizeof(extend); jpilst[0].bufadr = &extend; jpilst[0].retlen = 0; jpilst[1].itmcod = 0; jpilst[1].buflen = 0; sys$getjpiw(EFN$C_ENF, 0, 0, jpilst, iosb, 0, 0); fib.fib$l_exsz = extend ? extend : needed; fib.fib$v_aldef = 1; } } status = sys$qiow(EFN$C_ENF, pFile->chan, IO$_MODIFY, iosb, 0, 0, &fibdsc, 0, 0, 0, 0, 0); if( $VMS_STATUS_SUCCESS(status) && $VMS_STATUS_SUCCESS(status = iosb[0]) ){ fib.fib$v_extend = 0; fib.fib$l_exvbn += fib.fib$l_exsz; fat.fat$w_ffbyte = 0; fat.fat$w_efblkh = (unsigned short)(fib.fib$l_exvbn >> 16); fat.fat$w_efblkl = (unsigned short)fib.fib$l_exvbn; status = sys$qiow(EFN$C_ENF, pFile->chan, IO$_MODIFY, iosb, 0, 0, &fibdsc, 0, 0, 0, atr, 0); if( $VMS_STATUS_SUCCESS(status) ){ status = iosb[0]; } }
asmlinkage int exe$get_security(void *clsnam, void *objnam, unsigned int *objhan, unsigned int flags, void *itmlst, unsigned int *contxt, unsigned int *acmode) { struct dsc$descriptor * cls = clsnam; struct _ile3 * itmlst3 = itmlst; if (strncmp(cls->dsc$a_pointer, "FILE", 4)==0) { struct dsc$descriptor * fildsc = objnam; char * filename = fildsc->dsc$a_pointer; struct _xabfhcdef cc$rms_xabfhc = {XAB$C_FHC,0,0,0,0,0,0,0,0,0,0,0}; struct _xabdatdef cc$rms_xabdat={XAB$C_DAT,XAB$C_DATLEN,0,0,0,0,0,0,0,0,0,0}; struct _fabdef * fab = kmalloc(sizeof(struct _fabdef), GFP_KERNEL); #if 0 struct _rabdef * rab = kmalloc(sizeof(struct _rabdef), GFP_KERNEL); #endif // remember too free next two struct _xabdatdef * dat = kmalloc(sizeof(struct _xabdatdef), GFP_KERNEL); struct _xabfhcdef * fhc = kmalloc(sizeof(struct _xabfhcdef), GFP_KERNEL); *fab = cc$rms_fab; #if 0 *rab = cc$rms_rab; #endif *dat = cc$rms_xabdat; *fhc = cc$rms_xabfhc; fab->fab$l_xab = dat; dat->xab$l_nxt = fhc; fab->fab$l_fna = filename; fab->fab$b_fns = strlen(fab->fab$l_fna); #if 1 struct _namdef cc$rms_nam = {0,0,0,0,0,0,0,0,0,0,0,NULL,0,NULL,0,NULL,0,NULL,0,NULL,0,NULL,0,NULL,0,0,0}; char res[NAM$C_MAXRSS + 1], rsa[NAM$C_MAXRSS + 1]; struct _namdef nam = cc$rms_nam; nam.nam$l_esa = res; nam.nam$b_ess = NAM$C_MAXRSS; nam.nam$l_rsa = rsa; nam.nam$b_rss = NAM$C_MAXRSS; fab->fab$l_nam = &nam; #endif int exe$open(); int sts = exe$open(fab, 0, 0); if ((sts & 1) == 0) { printk("Open error: %d\n",sts); } else { struct _atrdef atr[2]; char * retbuf = itmlst3[0].ile3$ps_bufaddr; atr[0].atr$l_addr=retbuf; atr[0].atr$w_type=ATR$C_HEADER; atr[0].atr$w_size=ATR$S_HEADER; atr[1].atr$w_type=0; struct dsc$descriptor fibdsc; fibdsc.dsc$w_length=sizeof(struct _fibdef); void * get_wccfile_fib(struct _fabdef * fab); fibdsc.dsc$a_pointer=get_wccfile_fib(fab); int ifi_no = fab->fab$w_ifi; int get_ifb_table_chan(int); #define RMS_EF 29 struct _iosb iosb; sts = sys$qiow(RMS_EF,get_ifb_table_chan(ifi_no),IO$_ACCESS|IO$M_ACCESS,&iosb,0,0, &fibdsc,0,0,0,atr,0); sts = iosb.iosb$w_status; int exe$close(); sts = exe$close(fab, 0, 0); } } }
static int vmsRead( sqlite3_file *id, /* File to read from */ void *vBuf, /* Write content into this buffer */ int amt, /* Number of bytes to read */ sqlite3_int64 offset /* Begin reading at this offset */ ){ int bcnt; char *pBuf = vBuf; int remainder; char buf[SQLITE_DEFAULT_SECTOR_SIZE]; unsigned short iosb[4]; int status = SS$_NORMAL; vmsFile *pFile = (vmsFile *)id; /* ** Determine the virtual block we are to read from, and a possbile byte ** position within that block. */ int vbn = (offset / SQLITE_DEFAULT_SECTOR_SIZE) + 1; int vpos = offset % SQLITE_DEFAULT_SECTOR_SIZE; if( vpos ){ status = sys$qiow(EFN$C_ENF, pFile->chan, IO$_READVBLK, iosb, 0, 0, buf, SQLITE_DEFAULT_SECTOR_SIZE, vbn++, 0, 0, 0); if( $VMS_STATUS_SUCCESS(status) && $VMS_STATUS_SUCCESS(status = iosb[0]) ){ bcnt = min(amt, SQLITE_DEFAULT_SECTOR_SIZE - vpos); memcpy(pBuf, &buf[vpos], bcnt); pBuf += bcnt; amt -= bcnt; } } if( (amt >= SQLITE_DEFAULT_SECTOR_SIZE) && $VMS_STATUS_SUCCESS(status) ){ remainder = amt % SQLITE_DEFAULT_SECTOR_SIZE; status = sys$qiow(EFN$C_ENF, pFile->chan, IO$_READVBLK, iosb, 0, 0, pBuf, amt - remainder, vbn, 0, 0, 0); if( $VMS_STATUS_SUCCESS(status) && $VMS_STATUS_SUCCESS(status = iosb[0]) ){ bcnt = iosb[1] | (iosb[2] << 16); if( bcnt < (amt - remainder) ){ remainder = amt - bcnt; status = SS$_ENDOFFILE; }else{ bcnt = amt - remainder; } pBuf += bcnt; vbn += bcnt / SQLITE_DEFAULT_SECTOR_SIZE; amt = remainder; } } if( (amt > 0) && $VMS_STATUS_SUCCESS(status) ){ status = sys$qiow(EFN$C_ENF, pFile->chan, IO$_READVBLK, iosb, 0, 0, buf, SQLITE_DEFAULT_SECTOR_SIZE, vbn, 0, 0, 0); if( $VMS_STATUS_SUCCESS(status) && $VMS_STATUS_SUCCESS(status = iosb[0]) ){ memcpy(pBuf, buf, amt); } } if( status == SS$_ENDOFFILE ){ /* ** Unread parts of the buffer must be zero-filled. */ memset(pBuf, '\0', amt); return SQLITE_IOERR_SHORT_READ; }else if( !$VMS_STATUS_SUCCESS(status) ){ return SQLITE_IOERR_READ; } return SQLITE_OK; }
int main (int argc, char *argv[]) { int status; /* Routine status */ int chan; /* Device channel */ int efn; /* Event flag */ char dev_name[31]; /* Device name string */ char string[128]; /* Buffer for ID strings */ IOSB_T iosb; /* I/O status block for QIO call */ int debug_info[128]; /* Define debug information buffer */ int i; /* Loop counter */ int tmo_time; /* Timeout time */ struct dsc$descriptor_d /* Define a string descriptor */ dev_dsc = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0}; /* Get device name */ if (argc == 2) { /* Is there one argument ? */ ++argv; /* Move to second argument */ strcpy(dev_name,*argv); /* Get the device name */ } else { printf("\nUsage: ide-info <device-name>\n"); exit(SS$_INSFARG); /* Exit */ } /* Assign a channel to the device */ dev_dsc.dsc$w_length = strlen(dev_name); /* Set string length */ dev_dsc.dsc$a_pointer= dev_name; /* Point to the string */ status = sys$assign(&dev_dsc,&chan,0,0,0); /* Assign the channel */ if (!$VMS_STATUS_SUCCESS(status)) { /* Check for success */ printf("? Failed to assign channel, status is %X\n",status); exit(status); /* Exit with status */ } /* Get an EFN to use */ status = lib$get_ef(&efn); /* Acquire an EFN */ if (!$VMS_STATUS_SUCCESS(status)) { /* Check for success */ printf("? Failed to acquire EFN, status = %X\n",status); exit(status); /* Exit with status */ } /* Ask for the ID page from the drive */ status = sys$qiow(efn,chan,IO$_READRCT,&iosb,0,0,&buffer,512,0,0,0,0); if (!$VMS_STATUS_SUCCESS(status)) { printf("? QIO service call failed, status is %X\n",status); exit(status); /* Exit with failure status */ } if (!$VMS_STATUS_SUCCESS(iosb.status)) { printf("? QIO operation failed, IOSB status is %X\n",iosb.status); exit(iosb.status); /* Exit with status */ } /* Print the information obtained from the page */ printf("ID Page information for %s:\n\n",dev_name); copy(string,buffer.model_number,MODEL_LENGTH); printf("Drive Model: \"%s\"\n",string); copy(string,buffer.serial_number,20); printf("\tS/N: \"%s\" ",string); copy(string,buffer.firmware_revision,8); printf("F/W rev: \"%s\"\n",string); printf("Config: %x\n",buffer.config); printf("Geometry: Cylinders: %d ",buffer.cyls); printf("Heads: %d ",buffer.heads); printf("Sectors: %d\n",buffer.sectors); printf("Unformatted: bytes/track: %d ",buffer.ubytes_track); printf("bytes/sector: %d\n",buffer.ubytes_sector); printf("Buffer type: %d ",buffer.buffer_type); printf("Buffer size (in blocks): %d\n",buffer.buffer_size_blocks); printf("Number of ECC bytes/sector: %d\n",buffer.ecc_bytes); printf("Number of sectors/interrupt: %d\n",buffer.rw_multiple); printf("Vendor unique: %d\n",buffer.unique47); printf("Doubleword I/O flag: %d\n",buffer.dblword_io); printf("Capabilities: %x (LBA - %d, DMA - %d)\n",buffer.capabilities, ((buffer.capabilities&0x100)>>8),((buffer.capabilities&0x200)>>9)); printf("Reserved: %d\n",buffer.rsvd50); printf("Cycle times: PIO %d ",buffer.pio_cycle); printf("DMA %d\n",buffer.dma_cycle); printf("Valid bit for next 4 fields: %d\n",buffer.valid54_58); printf("Current: Cylinders %d ",buffer.curr_cyls); printf("Heads %d ",buffer.curr_heads); printf("Sectors %d ",buffer.curr_sectors); printf("Maximum sector number %d\n",buffer.max_sectors); printf("Current sectors/interrupt setting: %d valid: %d\n",buffer.multiple_sectors&0xFF, ((buffer.multiple_sectors&0x100)>>8)); printf("LBA mode maximum block number: %d\n",buffer.lba_maxblock); printf("Single word DMA info: %d\n",buffer.single_word_dma); printf("Multi word DMA info: %d\n",buffer.multi_word_dma); /* Ask for the debug information from the driver */ printf("\n\nDebug Information:\n\n"); status = sys$qiow(efn,chan,IO$_RDSTATS,&iosb,0,0,&debug_info, sizeof(debug_info),0,0,0,0); if (!$VMS_STATUS_SUCCESS(status)) { printf("? QIO service call failed, status is %X\n",status); exit(status); /* Exit with failure status */ } if (!$VMS_STATUS_SUCCESS(iosb.status)) { if (iosb.status == SS$_NODATA) { printf("\t%% DEBUG driver is not loaded\n"); exit(SS$_NORMAL); /* Just exit at this point */ } else { printf("? QIO operation failed, IOSB status is %X\n",iosb.status); exit(iosb.status); /* Exit with status */ } } /* Print out the debug information */ printf("Total interrupts: %d",debug_info[0]); printf("\tTotal unexpected interrupts: %d\n",debug_info[1]); printf("Number of CRAMs - %d\n",debug_info[2]); printf("Transfer buffer address - %x\n",debug_info[3]); printf("Base SPTE address - %x",debug_info[4]); printf("\tBase S0 address - %x\n",debug_info[5]); tmo_time = debug_info[6]-2; printf("Timeout time: %d seconds\n",tmo_time); printf("\n\tSeconds\tCount\n"); for (i=0; i<=tmo_time; i++) { printf("\t%d\t%d\n",i,debug_info[7+i]); } printf("\t>%d\t%d\n",tmo_time,debug_info[7+tmo_time+1]); }
bool TouchFile(const string& path) { int i; FibDesc.dsc$w_length = sizeof (Fib); FibDesc.dsc$b_dtype = DSC$K_DTYPE_Z; FibDesc.dsc$b_class = DSC$K_CLASS_S; FibDesc.dsc$a_pointer = (char *) &Fib; DevDesc.dsc$b_dtype = DSC$K_DTYPE_T; DevDesc.dsc$b_class = DSC$K_CLASS_S; DevDesc.dsc$a_pointer = &Nam.nam$t_dvi[1]; FileName.dsc$b_dtype = DSC$K_DTYPE_T; FileName.dsc$b_class = DSC$K_CLASS_S; MyAtr.atr$w_size = sizeof (Rdate); MyAtr.atr$w_type = ATR$C_REVDATE; MyAtr.atr$l_addr = &Rdate; MyAtr.fill = 0; struct stat sbuf; status = sys$gettim(&CurTime); check_status(status, "sys$gettim", "TouchFile"); if (stat(path.c_str(), &sbuf) != 0) { // File does not exist, create it: int fd = open(path.c_str(), O_WRONLY | O_CREAT, 0666); if (fd < 0) { return false; } close(fd); return true; } // File does exist: /* initialize RMS structures, we need a NAM to retrieve the FID */ Fab = cc$rms_fab; Fab.fab$l_fna = (char *) path.c_str(); /* name of file */ Fab.fab$b_fns = strlen(path.c_str()); Fab.fab$l_nam = &Nam; /* FAB has an associated NAM */ Nam = cc$rms_nam; Nam.nam$l_esa = EName; /* expanded filename */ Nam.nam$b_ess = sizeof (EName); Nam.nam$l_rsa = RName; /* resultant filename */ Nam.nam$b_rss = sizeof (RName); /* do $PARSE and $SEARCH here */ status = sys$parse(&Fab); check_rms_status(status, Fab.fab$l_stv, "sys$parse", "parse_name"); // Open the file. DevDesc.dsc$w_length = Nam.nam$t_dvi[0]; status = sys$assign(&DevDesc, &DevChan, 0, 0); check_status(status, "sys$assign", "assign_name"); // Get current file revision date. FileName.dsc$a_pointer = Nam.nam$l_name; FileName.dsc$w_length = Nam.nam$b_name + Nam.nam$b_type + Nam.nam$b_ver; /* Initialize the FIB */ for (i = 0; i < 3; i++) { Fib.fib$w_fid[i] = Nam.nam$w_fid[i]; Fib.fib$w_did[i] = Nam.nam$w_did[i]; } status = sys$qiow( 0, DevChan, IO$_ACCESS, &Iosb, 0, 0, &FibDesc, (__int64) & FileName, 0, 0, (__int64) & MyAtr, 0); if ((status & 1) == 1) { status = Iosb.iosb$w_status; } check_status (status, "sys$qio", "get_attr"); // Get current time. Rdate = CurTime; // Set new file revision time. status = sys$qiow( 0, DevChan, IO$_MODIFY, &Iosb, 0, 0, &FibDesc, (__int64) & FileName, 0, 0, (__int64) & MyAtr, 0); if ((status & 1) == 1) { status = Iosb.iosb$w_status; } check_status(status, "sys$qio", "set_attr"); // Release file. status = sys$dassgn (DevChan); check_status(status, "sys$dassgn", "deassign_name"); return true; }
void iott_close(io_desc *v, mval *pp) /* exception is the only deviceparameter allowed */ { unsigned short iosb[4]; uint4 dummy_msk, enable_msk, status; d_tt_struct *tt_ptr; t_cap s_mode; params ch; int p_offset; assert(v->type == tt); if (v->state != dev_open) return; assert((v->pair.in == v) || (v->pair.out == v)); tt_ptr = (d_tt_struct *)(v->dev_sp); if (v->pair.out == v) { status = sys$dclast(iott_wtclose, tt_ptr, 0); if (status != SS$_NORMAL) rts_error(VARLSTCNT(1) status); } if (v->pair.in == v && tt_ptr->term_chars_twisted) { status = sys$qiow(EFN$C_ENF, tt_ptr->channel, IO$_SENSEMODE, iosb, 0, 0, &s_mode, 12, 0, 0, 0, 0); if (status == SS$_NORMAL) status = iosb[0]; if (status != SS$_NORMAL) rts_error(VARLSTCNT(1) status); s_mode.ext_cap &= (~TT2$M_PASTHRU & ~TT2$M_EDITING); s_mode.ext_cap |= (tt_ptr->ext_cap & (TT2$M_PASTHRU | TT2$M_EDITING)); s_mode.term_char &= (~TT$M_ESCAPE); s_mode.term_char |= (tt_ptr->term_char & TT$M_ESCAPE); status = sys$qiow(EFN$C_ENF, tt_ptr->channel, IO$_SETMODE, iosb, 0, 0, &s_mode, 12, 0, 0, 0, 0); if (status == SS$_NORMAL) status = iosb[0]; if (status != SS$_NORMAL) rts_error(VARLSTCNT(1) status); } if (v->pair.in == io_std_device.in) { enable_msk = std_dev_outofband_msk & CTRLY_MSK; if (enable_msk == CTRLY_MSK) status = lib$enable_ctrl(&enable_msk, &dummy_msk); if (status != SS$_NORMAL) rts_error(VARLSTCNT(1) status); } status = sys$dassgn(tt_ptr->channel); if (status != SS$_NORMAL) rts_error(VARLSTCNT(1) status); p_offset = 0; while (*(pp->str.addr + p_offset) != iop_eol) { if ((ch = *(pp->str.addr + p_offset++)) == iop_exception) { v->error_handler.len = *(pp->str.addr + p_offset); v->error_handler.addr = pp->str.addr + p_offset + 1; s2pool(&v->error_handler); } p_offset += ((IOP_VAR_SIZE == io_params_size[ch]) ? (unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[ch]); } v->state = dev_closed; astq_dyn_alloc += TERMINAL_STATIC_ASTS; astq_dyn_avail += TERMINAL_STATIC_ASTS; free(tt_ptr->sb_buffer); free(tt_ptr->io_buffer); return; }
unsigned domount(int userarg) { setvbuf(stdout, NULL, _IONBF, 0); // need this to see i/o at all int sts; $DESCRIPTOR(bind, "bind"); $DESCRIPTOR(p, "p1"); char c[80]; struct dsc$descriptor o; o.dsc$a_pointer=c; o.dsc$w_length=80; memset (c, 0, 80); sts = cli$present(&p); if ((sts&1)==0) return sts; int retlen; char bindnam[80]; struct dsc$descriptor binddes; binddes.dsc$a_pointer=bindnam; binddes.dsc$w_length=80; memset (bindnam, 0, 80); int bind_sts = cli$present(&bind); if (bind_sts&1) { sts = cli$get_value(&bind, &binddes, &retlen); binddes.dsc$w_length = retlen; } char *dev = c; char *lab = 0; int devices = 0; char *devs[100],*labs[100]; #if 0 while (*lab != '\0') { labs[devices++] = lab; while (*lab != ',' && *lab != '\0') lab++; if (*lab != '\0') { *lab++ = '\0'; } else { break; } } #endif #if 0 // amd64 not happy with this? while (cli$get_value(&p, &o, &retlen)&1) { devs[devices++] = strdup(c); } #else cli$get_value(&p, &o, &retlen); devs[devices++] = strdup(c); #endif if (bind_sts&1) { for (dev = 0; dev < devices; dev ++) { short int chan; char buf[512]; struct _hm2 * hm2 = buf; struct dsc$descriptor dsc; dsc.dsc$w_length = strlen(devices[dev]); dsc.dsc$a_pointer = devices[dev]; sts=sys$assign(&dsc,&chan,0,0,0); char * nam = devices[dev]; int part = nam[3] - '1'; struct _iosb iosb; sts = sys$qiow(0, chan, IO$_READPBLK, &iosb, 0, 0, buf , 512, 1, part, 0, 0); hm2->hm2$w_rvn = dev + 1; memcpy(hm2->hm2$t_strucname, binddes.dsc$a_pointer, binddes.dsc$w_length); sts = sys$qiow(0, chan, IO$_WRITEPBLK, &iosb, 0, 0, buf , 512, 1, part, 0, 0); sys$dassgn(chan); } return 1; } #if 0 devices = 0; while (*dev != '\0') { devs[devices++] = dev; while (*dev != ',' && *dev != '\0') dev++; if (*dev != '\0') { *dev++ = '\0'; } else { break; } } #endif if (devices > 0) { unsigned i; struct VCB *vcb; struct item_list_3 it[2]; it[0].item_code=1; /*not yet */ it[0].buflen=strlen(devs[0]); it[0].bufaddr=devs[0]; it[1].item_code=0; // sts = mount(options,devices,devs,labs,&vcb); sts = sys$mount(it); #if 0 if (sts & 1) { for (i = 0; i < vcb->devices; i++) if (vcb->vcbdev[i].dev != NULL) printf("%%MOUNT-I-MOUNTED, Volume %12.12s mounted on %s\n", vcb->vcbdev[i].home.hm2$t_volname,vcb->vcbdev[i].dev->devnam); if (setdef_count == 0) { char *colon,defdir[256]; strcpy(defdir,vcb->vcbdev[0].dev->devnam); colon = strchr(defdir,':'); if (colon != NULL) *colon = '\0'; strcpy(defdir + strlen(defdir),":[000000]"); setdef(defdir); test_vcb = vcb; } } else { printf("Mount failed with %d\n",sts); } #endif } return sts; }
/* Internal functions to open, handle and close a channel to the console. */ static int open_console(UI *ui) { CRYPTO_THREAD_write_lock(ui->lock); is_a_tty = 1; #if defined(OPENSSL_SYS_VXWORKS) tty_in = stdin; tty_out = stderr; #elif defined(_WIN32) && !defined(_WIN32_WCE) if ((tty_out = fopen("conout$", "w")) == NULL) tty_out = stderr; if (GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &tty_orig)) { tty_in = stdin; } else { is_a_tty = 0; if ((tty_in = fopen("conin$", "r")) == NULL) tty_in = stdin; } #else # ifdef OPENSSL_SYS_MSDOS # define DEV_TTY "con" # else # define DEV_TTY "/dev/tty" # endif if ((tty_in = fopen(DEV_TTY, "r")) == NULL) tty_in = stdin; if ((tty_out = fopen(DEV_TTY, "w")) == NULL) tty_out = stderr; #endif #if defined(TTY_get) && !defined(OPENSSL_SYS_VMS) if (TTY_get(fileno(tty_in), &tty_orig) == -1) { # ifdef ENOTTY if (errno == ENOTTY) is_a_tty = 0; else # endif # ifdef EINVAL /* * Ariel Glenn [email protected] reports that solaris can return * EINVAL instead. This should be ok */ if (errno == EINVAL) is_a_tty = 0; else # endif return 0; } #endif #ifdef OPENSSL_SYS_VMS status = sys$assign(&terminal, &channel, 0, 0); if (status != SS$_NORMAL) return 0; status = sys$qiow(0, channel, IO$_SENSEMODE, &iosb, 0, 0, tty_orig, 12, 0, 0, 0, 0); if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) return 0; #endif return 1; }
/* **++ ** ROUTINE: netlib_accept ** ** FUNCTIONAL DESCRIPTION: ** ** tbs ** ** RETURNS: cond_value, longword (unsigned), write only, by value ** ** PROTOTYPE: ** ** tbs ** ** IMPLICIT INPUTS: None. ** ** IMPLICIT OUTPUTS: None. ** ** COMPLETION CODES: ** ** ** SIDE EFFECTS: None. ** **-- */ unsigned int netlib_accept (struct CTX **xctx, struct CTX **xnewctx, struct SINDEF *sa, unsigned int *sasize, unsigned int *salen, struct NETLIBIOSBDEF *iosb, void (*astadr)(), void *astprm) { struct CTX *ctx, *newctx; ITMLST sname; unsigned int status; int argc; VERIFY_CTX(xctx, ctx); SETARGCOUNT(argc); if (argc < 2) return SS$_INSFARG; if (xnewctx == 0) return SS$_BADPARAM; status = netlib___alloc_ctx(&newctx, SPECCTX_SIZE); if (!OK(status)) return status; status = sys$assign(&inetdevice_v5, &newctx->chan, 0, 0); if (!OK(status)) { status = sys$assign(&inetdevice, &newctx->chan, 0, 0); } if (!OK(status)) { netlib___free_ctx(newctx); return status; } if (argc > 6 && astadr != 0) { struct IOR *ior; GET_IOR(ior, ctx, iosb, astadr, (argc > 7) ? astprm : 0); ior->spec_userfrom = (sasize == 0) ? 0 : sa; ior->spec_length = (sasize == 0) ? 0 : *sasize; ior->spec_retlen = salen; ior->spec_xnewctx = xnewctx; ior->spec_newctx = newctx; ITMLST_INIT(sname, 0, sizeof(struct SINDEF), &ior->specior.from, &ior->specior.fromlen); ior->iorflags = IOR_M_COPY_FROM|IOR_M_NEW_CONTEXT; status = sys$qio(netlib_asynch_efn, ctx->chan, IO$_ACCESS|IO$M_ACCEPT, &ior->iosb, io_completion, ior, 0, 0, &sname, &newctx->chan, 0, 0); if (!OK(status)) FREE_IOR(ior); } else { struct SINDEF from; struct NETLIBIOSBDEF myiosb; unsigned short fromlen; ITMLST_INIT(sname, 0, sizeof(struct SINDEF), &from, &fromlen); status = sys$qiow(netlib_synch_efn, ctx->chan, IO$_ACCESS|IO$M_ACCEPT, &myiosb, 0, 0, 0, 0, &sname, &newctx->chan, 0, 0); if (OK(status)) status = netlib___cvt_status(&myiosb); if (argc > 5 && iosb != 0) netlib___cvt_iosb(iosb, &myiosb); if (OK(status)) { *xnewctx = newctx; if (argc > 3 && sa != 0 && sasize != 0) { unsigned int len; len = fromlen; if (len > *sasize) len = *sasize; memcpy(sa, &from, len); if (argc > 4 && salen != 0) *salen = len; } } } return status; } /* netlib_accept */
int rlMailbox::write(const void *buf, int len) { status = OK; #ifdef RLUNIX int retlen; unsigned char *message = new unsigned char [sizeof(long) + len]; long *lptr = (long *) message; *lptr = 1; // mtype memcpy(&message[sizeof(long)],buf,len); retlen = msgsnd(chanid,(struct msgbuf *) message, len, 0); delete [] message; return retlen; #endif #ifdef __VMS int ret; IOSB iosb; ret = sys$qiow (0, (short) chanid, IO$_WRITEVBLK | IO$M_NOW | IO$M_NORSWAIT, &iosb, 0,0, buf, len,0,0,0,0); len = iosb.msg_len; if (ret == SS$_MBFULL) return MAILBOX_FULL; else if(ret != SS$_NORMAL) return MAILBOX_ERROR; else return len; // Success #endif #ifdef RLWIN32 BOOL bret; unsigned long numWritten; if(chanid == -1) { HANDLE h; char mbxname[1024]; strcpy(mbxname,"\\\\.\\mailslot\\"); strcat(mbxname,name); h = CreateFile( mbxname, // pointer to name of the file GENERIC_READ | GENERIC_WRITE, // access (read-write) mode FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode NULL, // pointer to security attributes OPEN_EXISTING, // how to create FILE_ATTRIBUTE_NORMAL, // file attributes NULL // handle to file with attributes to copy ); if(h == INVALID_HANDLE_VALUE) { status = GetLastError(); return MAILBOX_ERROR; } chanid = (int) h; } bret = WriteFile( (HANDLE) chanid, // handle to file to write to buf, // pointer to data to write to file len, // number of bytes to write &numWritten, // pointer to number of bytes written NULL // pointer to structure for overlapped I/O ); if(bret==0) { status = GetLastError(); CloseHandle((HANDLE) chanid); chanid = -1; return MAILBOX_ERROR; } return numWritten; #endif }
/* **++ ** ROUTINE: netlib_name_to_address ** ** FUNCTIONAL DESCRIPTION: ** ** Uses the UCX IO$_ACPCONTROL $QIO function to translate a host ** name into one or more IP addresses. ** ** RETURNS: cond_value, longword (unsigned), write only, by value ** ** PROTOTYPE: ** ** NETLIB_NAME_TO_ADDRESS ctx, which, namdsc, addrlist, listsize [,count] [,iosb] [,astadr] [,astprm] ** ** IMPLICIT INPUTS: None. ** ** IMPLICIT OUTPUTS: None. ** ** COMPLETION CODES: ** ** ** SIDE EFFECTS: None. ** **-- */ unsigned int netlib_name_to_address (struct CTX **xctx, unsigned int *whichp, struct dsc$descriptor *namdsc, struct INADDRDEF *addrlist, unsigned int *listsize, unsigned int *count, struct NETLIBIOSBDEF *iosb, void (*astadr)(), void *astprm) { struct CTX *ctx; struct INADDRDEF addr; struct NETLIBIOSBDEF myiosb; struct HOSTENT hostent; unsigned int status, subfunction; ITMLST2 subfdsc; ITMLST2 entdsc; unsigned short helen; int argc; VERIFY_CTX(xctx, ctx); SETARGCOUNT(argc); if (argc < 5) return SS$_INSFARG; if (namdsc == 0 || addrlist == 0 || listsize == 0) return SS$_BADPARAM; if (OK(netlib_strtoaddr(namdsc, &addr))) { addrlist[0] = addr; if (argc > 5 && count != 0) *count = 1; if (argc > 6 && iosb != 0) { iosb->iosb_w_status = SS$_NORMAL; iosb->iosb_w_count = 1; iosb->iosb_l_unused = 0; } if (argc > 7 && astadr != 0) { return sys$dclast(astadr, (argc > 8) ? astprm : 0, 0); } else { return SS$_NORMAL; } } if (argc > 7 && astadr != 0) { struct IOR *ior; GET_IOR(ior, ctx, iosb, astadr, (argc > 8) ? astprm : 0); status = lib$get_vm(&hostent_size, &ior->spec_hostent); if (!OK(status)) { FREE_IOR(ior); return status; } ior->specior.subfunction = (INETACP$C_HOSTENT_OFFSET << 8) | INETACP_FUNC$C_GETHOSTBYNAME; ITMLST2_INIT(subfdsc, 0, sizeof(ior->specior.subfunction), &ior->specior.subfunction); ITMLST2_INIT(entdsc, 0, hostent_size, ior->spec_hostent); ior->spec_useralist = addrlist; ior->spec_length = *listsize; ior->spec_retlen = count; ior->iorflags = IOR_M_COPY_ADDRS; status = sys$qio(netlib_asynch_efn, ctx->chan, IO$_ACPCONTROL, &ior->iosb, io_completion, ior, &subfdsc, namdsc, &ior->specior.fromlen, &entdsc, 0, 0); if (!OK(status)) FREE_IOR(ior); return status; } subfunction = (INETACP$C_HOSTENT_OFFSET << 8) | INETACP_FUNC$C_GETHOSTBYNAME; ITMLST2_INIT(subfdsc, 0, sizeof(subfunction), &subfunction); ITMLST2_INIT(entdsc, 0, hostent_size, &hostent); status = sys$qiow(netlib_synch_efn, ctx->chan, IO$_ACPCONTROL, &myiosb, 0, 0, &subfdsc, namdsc, &helen, &entdsc, 0, 0); if (OK(status)) status = netlib___cvt_status(&myiosb); if (argc > 6 && iosb != 0) netlib___cvt_iosb(iosb, &myiosb); if (OK(status)) { char *base; unsigned int *offlst; int i; base = (char *) &hostent; i = 0; if (hostent.addrlist_offset != 0) { offlst = (unsigned int *) (base+hostent.addrlist_offset); while (i < *listsize && offlst[i] != 0) { addrlist[i] = *(struct INADDRDEF *) (base + offlst[i]); i++; } } if (argc > 5 && count != 0) *count = i; } return status; } /* netlib_name_to_address */
int getloadavg (double loadavg[], int nelem) { int elem = 0; /* Return value. */ # ifdef NO_GET_LOAD_AVG # define LDAV_DONE /* Set errno to zero to indicate that there was no particular error; this function just can't work at all on this system. */ errno = 0; elem = -1; # endif # if !defined (LDAV_DONE) && defined (HAVE_LIBKSTAT) /* Use libkstat because we don't have to be root. */ # define LDAV_DONE kstat_ctl_t *kc; kstat_t *ksp; kstat_named_t *kn; kc = kstat_open (); if (kc == 0) return -1; ksp = kstat_lookup (kc, "unix", 0, "system_misc"); if (ksp == 0 ) return -1; if (kstat_read (kc, ksp, 0) == -1) return -1; kn = kstat_data_lookup (ksp, "avenrun_1min"); if (kn == 0) { /* Return -1 if no load average information is available. */ nelem = 0; elem = -1; } if (nelem >= 1) loadavg[elem++] = (double) kn->value.ul/FSCALE; if (nelem >= 2) { kn = kstat_data_lookup (ksp, "avenrun_5min"); if (kn != 0) { loadavg[elem++] = (double) kn->value.ul/FSCALE; if (nelem >= 3) { kn = kstat_data_lookup (ksp, "avenrun_15min"); if (kn != 0) loadavg[elem++] = (double) kn->value.ul/FSCALE; } } } kstat_close (kc); # endif /* HAVE_LIBKSTAT */ # if !defined (LDAV_DONE) && defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC) /* Use pstat_getdynamic() because we don't have to be root. */ # define LDAV_DONE # undef LOAD_AVE_TYPE struct pst_dynamic dyn_info; if (pstat_getdynamic (&dyn_info, sizeof (dyn_info), 0, 0) < 0) return -1; if (nelem > 0) loadavg[elem++] = dyn_info.psd_avg_1_min; if (nelem > 1) loadavg[elem++] = dyn_info.psd_avg_5_min; if (nelem > 2) loadavg[elem++] = dyn_info.psd_avg_15_min; # endif /* hpux && HAVE_PSTAT_GETDYNAMIC */ # if !defined (LDAV_DONE) && defined (__linux__) # define LDAV_DONE # undef LOAD_AVE_TYPE # ifndef LINUX_LDAV_FILE # define LINUX_LDAV_FILE "/proc/loadavg" # endif char ldavgbuf[40]; double load_ave[3]; int fd, count; fd = open (LINUX_LDAV_FILE, O_RDONLY); if (fd == -1) return -1; count = read (fd, ldavgbuf, 40); (void) close (fd); if (count <= 0) return -1; /* The following sscanf must use the C locale. */ setlocale (LC_NUMERIC, "C"); count = sscanf (ldavgbuf, "%lf %lf %lf", &load_ave[0], &load_ave[1], &load_ave[2]); setlocale (LC_NUMERIC, ""); if (count < 1) return -1; for (elem = 0; elem < nelem && elem < count; elem++) loadavg[elem] = load_ave[elem]; return elem; # endif /* __linux__ */ # if !defined (LDAV_DONE) && defined (__NetBSD__) # define LDAV_DONE # undef LOAD_AVE_TYPE # ifndef NETBSD_LDAV_FILE # define NETBSD_LDAV_FILE "/kern/loadavg" # endif unsigned long int load_ave[3], scale; int count; FILE *fp; fp = fopen (NETBSD_LDAV_FILE, "r"); if (fp == NULL) return -1; count = fscanf (fp, "%lu %lu %lu %lu\n", &load_ave[0], &load_ave[1], &load_ave[2], &scale); (void) fclose (fp); if (count != 4) return -1; for (elem = 0; elem < nelem; elem++) loadavg[elem] = (double) load_ave[elem] / (double) scale; return elem; # endif /* __NetBSD__ */ # if !defined (LDAV_DONE) && defined (NeXT) # define LDAV_DONE /* The NeXT code was adapted from iscreen 3.2. */ host_t host; struct processor_set_basic_info info; unsigned info_count; /* We only know how to get the 1-minute average for this system, so even if the caller asks for more than 1, we only return 1. */ if (!getloadavg_initialized) { if (processor_set_default (host_self (), &default_set) == KERN_SUCCESS) getloadavg_initialized = 1; } if (getloadavg_initialized) { info_count = PROCESSOR_SET_BASIC_INFO_COUNT; if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host, (processor_set_info_t) &info, &info_count) != KERN_SUCCESS) getloadavg_initialized = 0; else { if (nelem > 0) loadavg[elem++] = (double) info.load_average / LOAD_SCALE; } } if (!getloadavg_initialized) return -1; # endif /* NeXT */ # if !defined (LDAV_DONE) && defined (UMAX) # define LDAV_DONE /* UMAX 4.2, which runs on the Encore Multimax multiprocessor, does not have a /dev/kmem. Information about the workings of the running kernel can be gathered with inq_stats system calls. We only know how to get the 1-minute average for this system. */ struct proc_summary proc_sum_data; struct stat_descr proc_info; double load; register unsigned int i, j; if (cpus == 0) { register unsigned int c, i; struct cpu_config conf; struct stat_descr desc; desc.sd_next = 0; desc.sd_subsys = SUBSYS_CPU; desc.sd_type = CPUTYPE_CONFIG; desc.sd_addr = (char *) &conf; desc.sd_size = sizeof conf; if (inq_stats (1, &desc)) return -1; c = 0; for (i = 0; i < conf.config_maxclass; ++i) { struct class_stats stats; memset (&stats, '\0', sizeof stats); desc.sd_type = CPUTYPE_CLASS; desc.sd_objid = i; desc.sd_addr = (char *) &stats; desc.sd_size = sizeof stats; if (inq_stats (1, &desc)) return -1; c += stats.class_numcpus; } cpus = c; samples = cpus < 2 ? 3 : (2 * cpus / 3); } proc_info.sd_next = 0; proc_info.sd_subsys = SUBSYS_PROC; proc_info.sd_type = PROCTYPE_SUMMARY; proc_info.sd_addr = (char *) &proc_sum_data; proc_info.sd_size = sizeof (struct proc_summary); proc_info.sd_sizeused = 0; if (inq_stats (1, &proc_info) != 0) return -1; load = proc_sum_data.ps_nrunnable; j = 0; for (i = samples - 1; i > 0; --i) { load += proc_sum_data.ps_nrun[j]; if (j++ == PS_NRUNSIZE) j = 0; } if (nelem > 0) loadavg[elem++] = load / samples / cpus; # endif /* UMAX */ # if !defined (LDAV_DONE) && defined (DGUX) # define LDAV_DONE /* This call can return -1 for an error, but with good args it's not supposed to fail. The first argument is for no apparent reason of type 'long int *'. */ dg_sys_info ((long int *) &load_info, DG_SYS_INFO_LOAD_INFO_TYPE, DG_SYS_INFO_LOAD_VERSION_0); if (nelem > 0) loadavg[elem++] = load_info.one_minute; if (nelem > 1) loadavg[elem++] = load_info.five_minute; if (nelem > 2) loadavg[elem++] = load_info.fifteen_minute; # endif /* DGUX */ # if !defined (LDAV_DONE) && defined (apollo) # define LDAV_DONE /* Apollo code from [email protected] (Ray Lischner). This system call is not documented. The load average is obtained as three long integers, for the load average over the past minute, five minutes, and fifteen minutes. Each value is a scaled integer, with 16 bits of integer part and 16 bits of fraction part. I'm not sure which operating system first supported this system call, but I know that SR10.2 supports it. */ extern void proc1_$get_loadav (); unsigned long load_ave[3]; proc1_$get_loadav (load_ave); if (nelem > 0) loadavg[elem++] = load_ave[0] / 65536.0; if (nelem > 1) loadavg[elem++] = load_ave[1] / 65536.0; if (nelem > 2) loadavg[elem++] = load_ave[2] / 65536.0; # endif /* apollo */ # if !defined (LDAV_DONE) && defined (OSF_MIPS) # define LDAV_DONE struct tbl_loadavg load_ave; table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave)); loadavg[elem++] = (load_ave.tl_lscale == 0 ? load_ave.tl_avenrun.d[0] : (load_ave.tl_avenrun.l[0] / (double) load_ave.tl_lscale)); # endif /* OSF_MIPS */ # if !defined (LDAV_DONE) && (defined (__MSDOS__) || defined (WINDOWS32)) # define LDAV_DONE /* A faithful emulation is going to have to be saved for a rainy day. */ for ( ; elem < nelem; elem++) { loadavg[elem] = 0.0; } # endif /* __MSDOS__ || WINDOWS32 */ # if !defined (LDAV_DONE) && defined (OSF_ALPHA) # define LDAV_DONE struct tbl_loadavg load_ave; table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave)); for (elem = 0; elem < nelem; elem++) loadavg[elem] = (load_ave.tl_lscale == 0 ? load_ave.tl_avenrun.d[elem] : (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale)); # endif /* OSF_ALPHA */ # if !defined (LDAV_DONE) && defined (VMS) /* VMS specific code -- read from the Load Ave driver. */ LOAD_AVE_TYPE load_ave[3]; static int getloadavg_initialized = 0; # ifdef eunice struct { int dsc$w_length; char *dsc$a_pointer; } descriptor; # endif /* Ensure that there is a channel open to the load ave device. */ if (!getloadavg_initialized) { /* Attempt to open the channel. */ # ifdef eunice descriptor.dsc$w_length = 18; descriptor.dsc$a_pointer = "$$VMS_LOAD_AVERAGE"; # else $DESCRIPTOR (descriptor, "LAV0:"); # endif if (sys$assign (&descriptor, &channel, 0, 0) & 1) getloadavg_initialized = 1; } /* Read the load average vector. */ if (getloadavg_initialized && !(sys$qiow (0, channel, IO$_READVBLK, 0, 0, 0, load_ave, 12, 0, 0, 0, 0) & 1)) { sys$dassgn (channel); getloadavg_initialized = 0; } if (!getloadavg_initialized) return -1; # endif /* VMS */ # if !defined (LDAV_DONE) && defined(LOAD_AVE_TYPE) && !defined(VMS) /* UNIX-specific code -- read the average from /dev/kmem. */ # define LDAV_PRIVILEGED /* This code requires special installation. */ LOAD_AVE_TYPE load_ave[3]; /* Get the address of LDAV_SYMBOL. */ if (offset == 0) { # ifndef sgi # ifndef NLIST_STRUCT strcpy (nl[0].n_name, LDAV_SYMBOL); strcpy (nl[1].n_name, ""); # else /* NLIST_STRUCT */ # ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME nl[0].n_un.n_name = LDAV_SYMBOL; nl[1].n_un.n_name = 0; # else /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */ nl[0].n_name = LDAV_SYMBOL; nl[1].n_name = 0; # endif /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */ # endif /* NLIST_STRUCT */ # ifndef SUNOS_5 if ( # if !(defined (_AIX) && !defined (ps2)) nlist (KERNEL_FILE, nl) # else /* _AIX */ knlist (nl, 1, sizeof (nl[0])) # endif >= 0) /* Omit "&& nl[0].n_type != 0 " -- it breaks on Sun386i. */ { # ifdef FIXUP_KERNEL_SYMBOL_ADDR FIXUP_KERNEL_SYMBOL_ADDR (nl); # endif offset = nl[0].n_value; } # endif /* !SUNOS_5 */ # else /* sgi */ int ldav_off; ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN); if (ldav_off != -1) offset = (long) ldav_off & 0x7fffffff; # endif /* sgi */ } /* Make sure we have /dev/kmem open. */ if (!getloadavg_initialized) { # ifndef SUNOS_5 channel = open ("/dev/kmem", 0); if (channel >= 0) { /* Set the channel to close on exec, so it does not litter any child's descriptor table. */ # ifdef F_SETFD # ifndef FD_CLOEXEC # define FD_CLOEXEC 1 # endif (void) fcntl (channel, F_SETFD, FD_CLOEXEC); # endif getloadavg_initialized = 1; } # else /* SUNOS_5 */ /* We pass 0 for the kernel, corefile, and swapfile names to use the currently running kernel. */ kd = kvm_open (0, 0, 0, O_RDONLY, 0); if (kd != 0) { /* nlist the currently running kernel. */ kvm_nlist (kd, nl); offset = nl[0].n_value; getloadavg_initialized = 1; } # endif /* SUNOS_5 */ } /* If we can, get the load average values. */ if (offset && getloadavg_initialized) { /* Try to read the load. */ # ifndef SUNOS_5 if (lseek (channel, offset, 0) == -1L || read (channel, (char *) load_ave, sizeof (load_ave)) != sizeof (load_ave)) { close (channel); getloadavg_initialized = 0; } # else /* SUNOS_5 */ if (kvm_read (kd, offset, (char *) load_ave, sizeof (load_ave)) != sizeof (load_ave)) { kvm_close (kd); getloadavg_initialized = 0; } # endif /* SUNOS_5 */ } if (offset == 0 || !getloadavg_initialized) return -1; # endif /* LOAD_AVE_TYPE and not VMS */ # if !defined (LDAV_DONE) && defined (LOAD_AVE_TYPE) /* Including VMS. */ if (nelem > 0) loadavg[elem++] = LDAV_CVT (load_ave[0]); if (nelem > 1) loadavg[elem++] = LDAV_CVT (load_ave[1]); if (nelem > 2) loadavg[elem++] = LDAV_CVT (load_ave[2]); # define LDAV_DONE # endif /* !LDAV_DONE && LOAD_AVE_TYPE */ # ifdef LDAV_DONE return elem; # else /* Set errno to zero to indicate that there was no particular error; this function just can't work at all on this system. */ errno = 0; return -1; # endif }
/* **++ ** ROUTINE: netlib_address_to_name ** ** FUNCTIONAL DESCRIPTION: ** ** Uses the UCX IO$_ACPCONTROL $QIO function to translate an ** IP address into a host name. ** ** RETURNS: cond_value, longword (unsigned), write only, by value ** ** PROTOTYPE: ** ** NETLIB_ADDRESS_TO_NAME ctx, which, addr, addrsize, namdsc [,retlen] [,iosb] [,astadr] [,astprm] ** ** IMPLICIT INPUTS: None. ** ** IMPLICIT OUTPUTS: None. ** ** COMPLETION CODES: ** ** ** SIDE EFFECTS: None. ** **-- */ unsigned int netlib_address_to_name (struct CTX **xctx, unsigned int *whichp, struct INADDRDEF *addr, unsigned int *addrsize, struct dsc$descriptor *namdsc, unsigned short *retlen, struct NETLIBIOSBDEF *iosb, void (*astadr)(), void *astprm) { struct CTX *ctx; struct NETLIBIOSBDEF myiosb; ITMLST2 subfdsc, entdsc, adrdsc; unsigned int status, subfunction; char buf[1024]; #ifdef TCPWARE char tmp[64]; struct dsc$descriptor tmpdsc; #endif /* TCPWARE */ unsigned short length; int argc; VERIFY_CTX(xctx, ctx); SETARGCOUNT(argc); if (argc < 5) return SS$_INSFARG; if (addr == 0 || addrsize == 0 || namdsc == 0) return SS$_BADPARAM; if (*addrsize != sizeof(struct INADDRDEF)) return SS$_BADPARAM; #ifdef TCPWARE INIT_SDESC (tmpdsc, sizeof(tmp), tmp); status = netlib_addrtostr(addr, &tmpdsc, &tmpdsc.dsc$w_length); if (!OK(status)) return status; #else ITMLST2_INIT(adrdsc, 0, *addrsize, addr); #endif /* TCPWARE */ if (argc > 7 && astadr != 0) { struct IOR *ior; struct HOSTENT *h; GET_IOR(ior, ctx, iosb, astadr, (argc > 8) ? astprm : 0); status = lib$get_vm(&hostent_size, &h); if (!OK(status)) { FREE_IOR(ior); return status; } ior->spec_usrdsc = namdsc; ior->spec_retlen = retlen; ior->specior.subfunction = #ifndef TCPWARE (INETACP$C_TRANS << 8) | #endif /* not TCPWARE */ INETACP_FUNC$C_GETHOSTBYADDR; ITMLST2_INIT(subfdsc, 0, sizeof(ior->specior.subfunction), &ior->specior.subfunction); ITMLST2_INIT(entdsc, 0, sizeof(h->buffer), h->buffer); ior->spec_hostent = h; ior->iorflags = IOR_M_COPY_HOSTNAME; status = sys$qio(netlib_asynch_efn, ctx->chan, IO$_ACPCONTROL, &ior->iosb, io_completion, ior, &subfdsc, #ifdef TCPWARE &tmpdsc, #else &adrdsc, #endif /* TCPWARE */ &ior->specior.fromlen, &entdsc, 0, 0); if (!OK(status)) FREE_IOR(ior); return status; } subfunction = #ifndef TCPWARE (INETACP$C_TRANS << 8) | #endif INETACP_FUNC$C_GETHOSTBYADDR; ITMLST2_INIT(subfdsc, 0, sizeof(subfunction), &subfunction); ITMLST2_INIT(entdsc, 0, sizeof(buf), buf); status = sys$qiow(netlib_synch_efn, ctx->chan, IO$_ACPCONTROL, &myiosb, 0, 0, &subfdsc, #ifdef TCPWARE &tmpdsc, #else &adrdsc, #endif /* TCPWARE */ &length, &entdsc, 0, 0); if (OK(status)) status = netlib___cvt_status(&myiosb); if (argc > 6 && iosb != 0) netlib___cvt_iosb(iosb, &myiosb); if (OK(status)) { str$copy_r(namdsc, &length, buf); if (argc > 5 && retlen != 0) *retlen = length; } return status; } /* netlib_address_to_name */
/* Internal functions to open, handle and close a channel to the console. */ static int open_console(UI *ui) { CRYPTO_THREAD_write_lock(ui->lock); is_a_tty = 1; #if defined(OPENSSL_SYS_VXWORKS) tty_in = stdin; tty_out = stderr; #elif defined(_WIN32) && !defined(_WIN32_WCE) if ((tty_out = fopen("conout$", "w")) == NULL) tty_out = stderr; if (GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &tty_orig)) { tty_in = stdin; } else { is_a_tty = 0; if ((tty_in = fopen("conin$", "r")) == NULL) tty_in = stdin; } #else # ifdef OPENSSL_SYS_MSDOS # define DEV_TTY "con" # else # define DEV_TTY "/dev/tty" # endif if ((tty_in = fopen(DEV_TTY, "r")) == NULL) tty_in = stdin; if ((tty_out = fopen(DEV_TTY, "w")) == NULL) tty_out = stderr; #endif #if defined(TTY_get) && !defined(OPENSSL_SYS_VMS) if (TTY_get(fileno(tty_in), &tty_orig) == -1) { # ifdef ENOTTY if (errno == ENOTTY) is_a_tty = 0; else # endif # ifdef EINVAL /* * Ariel Glenn [email protected] reports that solaris can return * EINVAL instead. This should be ok */ if (errno == EINVAL) is_a_tty = 0; else # endif # ifdef ENODEV /* * MacOS X returns ENODEV (Operation not supported by device), * which seems appropriate. */ if (errno == ENODEV) is_a_tty = 0; else # endif { char tmp_num[10]; BIO_snprintf(tmp_num, sizeof(tmp_num) - 1, "%d", errno); UIerr(UI_F_OPEN_CONSOLE, UI_R_UNKNOWN_TTYGET_ERRNO_VALUE); ERR_add_error_data(2, "errno=", tmp_num); return 0; } } #endif #ifdef OPENSSL_SYS_VMS status = sys$assign(&terminal, &channel, 0, 0); /* if there isn't a TT device, something is very wrong */ if (status != SS$_NORMAL) { char tmp_num[12]; BIO_snprintf(tmp_num, sizeof(tmp_num) - 1, "%%X%08X", status); UIerr(UI_F_OPEN_CONSOLE, UI_R_SYSASSIGN_ERROR); ERR_add_error_data(2, "status=", tmp_num); return 0; } status = sys$qiow(0, channel, IO$_SENSEMODE, &iosb, 0, 0, tty_orig, 12, 0, 0, 0, 0); /* If IO$_SENSEMODE doesn't work, this is not a terminal device */ if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) is_a_tty = 0; #endif return 1; }
/* **++ ** ROUTINE: netlib_read ** ** FUNCTIONAL DESCRIPTION: ** ** tbs ** ** RETURNS: cond_value, longword (unsigned), write only, by value ** ** PROTOTYPE: ** ** tbs ** ** IMPLICIT INPUTS: None. ** ** IMPLICIT OUTPUTS: None. ** ** COMPLETION CODES: ** ** ** SIDE EFFECTS: None. ** **-- */ unsigned int netlib_read (struct CTX **xctx, struct dsc$descriptor *dsc, struct SINDEF *sa, unsigned int *sasize, unsigned int *salen, TIME *timeout, struct NETLIBIOSBDEF *iosb, void (*astadr)(), void *astprm) { struct CTX *ctx; struct IOR *ior; unsigned int status; ITMLST sname; int argc, do_from; VERIFY_CTX(xctx, ctx); SETARGCOUNT(argc); if (dsc->dsc$b_dtype != DSC$K_DTYPE_T && dsc->dsc$b_dtype != 0) return SS$_BADPARAM; if (dsc->dsc$b_class == DSC$K_CLASS_D) { if (dsc->dsc$w_length == 0) return SS$_BADPARAM; } else { if (dsc->dsc$b_class != DSC$K_CLASS_S && dsc->dsc$b_class != 0) return SS$_BADPARAM; } do_from = (argc > 3 && sa != 0 && sasize != 0 && *sasize != 0); if (argc > 7 && astadr != 0) { struct IOR *ior; GET_IOR(ior, ctx, iosb, astadr, (argc > 8) ? astprm : 0); if (do_from) ITMLST_INIT(sname, 0, sizeof(struct SINDEF), &ior->specior.from, &ior->specior.fromlen); if (do_from) { ior->spec_userfrom = sa; ior->spec_length = *sasize; ior->spec_retlen = salen; ior->iorflags = IOR_M_COPY_FROM; } else ior->iorflags = 0; if (timeout != 0) { ior->iorflags |= IOR_M_IO_TIMED; status = sys$setimr(netlib_asynch_efn, timeout, io_timeout, ior); if (!OK(status)) { FREE_IOR(ior); return status; } } status = sys$qio(netlib_asynch_efn, ctx->chan, IO$_READVBLK, &ior->iosb, io_completion, ior, dsc->dsc$a_pointer, dsc->dsc$w_length, do_from ? &sname : 0, 0, 0, 0); if (!OK(status)) { if (timeout != 0) sys$cantim(ior, 0); FREE_IOR(ior); } } else { struct NETLIBIOSBDEF myiosb; struct SINDEF from; unsigned short fromlen; int timed_out; if (do_from) ITMLST_INIT(sname, 0, sizeof(struct SINDEF), &from, &fromlen); timed_out = 0; if (argc > 5 && timeout != 0) { GET_IOR(ior, ctx, 0, 0, 0); ior->iorflags = IOR_M_IO_TIMED; status = sys$setimr(netlib_asynch_efn, timeout, io_timeout, ior); if (!OK(status)) { FREE_IOR(ior); return status; } } status = sys$qiow(netlib_synch_efn, ctx->chan, IO$_READVBLK, &myiosb, 0, 0, dsc->dsc$a_pointer, dsc->dsc$w_length, do_from ? &sname : 0, 0, 0, 0); if (argc > 5 && timeout != 0) { sys$cantim(ior, 0); timed_out = ior->iorflags & IOR_M_IO_TIMEOUT; FREE_IOR(ior); } if (OK(status)) { if (timed_out && myiosb.iosb_w_status == SS$_CANCEL) myiosb.iosb_w_status = SS$_TIMEOUT; status = netlib___cvt_status(&myiosb); } if (argc > 6 && iosb != 0) netlib___cvt_iosb(iosb, &myiosb); if (OK(status) && do_from) { unsigned int len; len = fromlen; if (len > *sasize) len = *sasize; memcpy(sa, &from, len); if (argc > 4 && salen != 0) *salen = len; } } return status; } /* netlib_read */
/* **++ ** ROUTINE: sp_open ** ** FUNCTIONAL DESCRIPTION: ** ** Spawns a subprocess, possibly passing it an initial command. ** ** RETURNS: cond_value, longword (unsigned), write only, by value ** ** PROTOTYPE: ** ** sp_open(SPHANDLE *ctxpp, struct dsc$descriptor *inicmd, ** unsigned int (*rcvast)(void *), void *rcvastprm); ** ** IMPLICIT INPUTS: None. ** ** IMPLICIT OUTPUTS: None. ** ** COMPLETION CODES: ** SS$_NORMAL: Normal successful completion. ** ** SIDE EFFECTS: None. ** **-- */ unsigned int sp_open (SPHANDLE *ctxpp, void *inicmd, unsigned int (*rcvast)(void *), void *rcvastprm) { SPHANDLE ctx; unsigned int dvi_devnam = DVI$_DEVNAM, dvi_devbufsiz = DVI$_DEVBUFSIZ; unsigned int spawn_flags = CLI$M_NOWAIT|CLI$M_NOKEYPAD; unsigned int status; struct dsc$descriptor inbox, outbox; status = lib$get_vm(&spb_size, &ctx); if (!OK(status)) return status; /* ** Assign the SPHANDLE address for the caller immediately to avoid timing issues with ** WRTATTN AST that passes the ctx as rcvastprm (which sp_once does). */ *ctxpp = ctx; ctx->sendque.head = ctx->sendque.tail = &ctx->sendque; ctx->ok_to_send = 0; /* ** Create the mailboxes we'll be using for I/O with the subprocess */ status = sys$crembx(0, &ctx->inchn, 1024, 1024, 0xff00, 0, 0, 0); if (!OK(status)) { lib$free_vm(&spb_size, &ctx); return status; } status = sys$crembx(0, &ctx->outchn, 1024, 1024, 0xff00, 0, 0, 0); if (!OK(status)) { sys$dassgn(ctx->inchn); lib$free_vm(&spb_size, &ctx); return status; } /* ** Now that they're created, let's find out what they're called so we ** can tell LIB$SPAWN */ INIT_DYNDESC(inbox); INIT_DYNDESC(outbox); lib$getdvi(&dvi_devnam, &ctx->inchn, 0, 0, &inbox); lib$getdvi(&dvi_devnam, &ctx->outchn, 0, 0, &outbox); lib$getdvi(&dvi_devbufsiz, &ctx->outchn, 0, &ctx->bufsiz); /* ** Create the output buffer for the subprocess. */ status = lib$get_vm(&ctx->bufsiz, &ctx->bufptr); if (!OK(status)) { sys$dassgn(ctx->outchn); sys$dassgn(ctx->inchn); str$free1_dx(&inbox); str$free1_dx(&outbox); lib$free_vm(&spb_size, &ctx); return status; } /* ** Set the "receive AST" routine to be invoked by SP_WRTATTN_AST */ ctx->rcvast = rcvast; ctx->astprm = rcvastprm; sys$qiow(0, ctx->outchn, IO$_SETMODE|IO$M_WRTATTN, 0, 0, 0, sp_wrtattn_ast, ctx, 0, 0, 0, 0); sys$qiow(0, ctx->inchn, IO$_SETMODE|IO$M_READATTN, 0, 0, 0, sp_readattn_ast, ctx, 0, 0, 0, 0); /* ** Get us a termination event flag */ status = lib$get_ef(&ctx->termefn); if (OK(status)) lib$get_ef(&ctx->inefn); if (OK(status)) lib$get_ef(&ctx->outefn); if (!OK(status)) { sys$dassgn(ctx->outchn); sys$dassgn(ctx->inchn); str$free1_dx(&inbox); str$free1_dx(&outbox); lib$free_vm(&ctx->bufsiz, &ctx->bufptr); lib$free_vm(&spb_size, &ctx); return status; } /* ** Now create the subprocess */ status = lib$spawn(inicmd, &inbox, &outbox, &spawn_flags, 0, &ctx->pid, 0, &ctx->termefn); if (!OK(status)) { lib$free_ef(&ctx->termefn); lib$free_ef(&ctx->outefn); lib$free_ef(&ctx->inefn); sys$dassgn(ctx->outchn); sys$dassgn(ctx->inchn); str$free1_dx(&inbox); str$free1_dx(&outbox); lib$free_vm(&ctx->bufsiz, &ctx->bufptr); lib$free_vm(&spb_size, &ctx); return status; } /* ** Set up the exit handler, if we haven't done so already */ status = sys$setast(0); if (!exh_declared) { sys$dclexh(&exhblk); exh_declared = 1; } if (status == SS$_WASSET) sys$setast(1); /* ** Save the SPB in our private queue */ queue_insert(ctx, spque.tail); /* ** Clean up and return */ str$free1_dx(&inbox); str$free1_dx(&outbox); return SS$_NORMAL; } /* sp_open */
void dm_read(mval *v) { boolean_t done; unsigned short iosb[4]; int cl, index; uint4 max_width, save_modifiers, save_term_msk, status; read_iosb stat_blk; io_desc *io_ptr; t_cap s_mode; d_tt_struct *tt_ptr; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; if (tt == io_curr_device.out->type) iott_flush(io_curr_device.out); if (!comline_base) { comline_base = malloc(MAX_RECALL * SIZEOF(mstr)); memset(comline_base, 0, (MAX_RECALL * SIZEOF(mstr))); } io_ptr = io_curr_device.in; assert(tt == io_ptr->type); assert(dev_open == io_ptr->state); if (io_ptr->dollar.zeof) op_halt(); if (outofband) { outofband_action(FALSE); assert(FALSE); } tt_ptr = (d_tt_struct *)io_ptr->dev_sp; max_width = (io_ptr->width > tt_ptr->in_buf_sz) ? io_ptr->width : tt_ptr->in_buf_sz; assert(stringpool.free >= stringpool.base); assert(stringpool.free <= stringpool.top); ENSURE_STP_FREE_SPACE(max_width); active_device = io_ptr; index = 0; /* the following section of code puts the terminal in "easy of use" mode */ status = sys$qiow(EFN$C_ENF, tt_ptr->channel, IO$_SENSEMODE, &stat_blk, 0, 0, &s_mode, 12, 0, 0, 0, 0); if (SS$_NORMAL == status) status = stat_blk.status; if (SS$_NORMAL != status) rts_error(VARLSTCNT(1) status); if ((s_mode.ext_cap & TT2$M_PASTHRU) || !(s_mode.ext_cap & TT2$M_EDITING) || !(s_mode.term_char & TT$M_ESCAPE) || !(s_mode.term_char & TT$M_TTSYNC)) { s_mode.ext_cap &= (~TT2$M_PASTHRU); s_mode.ext_cap |= TT2$M_EDITING; s_mode.term_char |= (TT$M_ESCAPE | TT$M_TTSYNC); status = sys$qiow(EFN$C_ENF, tt_ptr->channel, IO$_SETMODE, &stat_blk, 0, 0, &s_mode, 12, 0, 0, 0, 0); if (SS$_NORMAL == status) status = stat_blk.status; if (SS$_NORMAL != status) /* The following error is probably going to cause the terminal state to get mucked up */ rts_error(VARLSTCNT(1) status); /* the following flag is normally used by iott_rdone, iott_readfl and iott_use but dm_read resets it when done */ tt_ptr->term_chars_twisted = TRUE; } save_modifiers = (unsigned)tt_ptr->item_list[0].addr; tt_ptr->item_list[0].addr = (unsigned)tt_ptr->item_list[0].addr | TRM$M_TM_NORECALL & (~TRM$M_TM_NOECHO); tt_ptr->item_list[1].addr = NO_M_TIMEOUT; /* reset key click timeout */ save_term_msk = ((io_termmask *)tt_ptr->item_list[2].addr)->mask[0]; ((io_termmask *)tt_ptr->item_list[2].addr)->mask[0] = TERM_MSK | (SHFT_MSK << CTRL_B) | (SHFT_MSK << CTRL_Z); tt_ptr->item_list[4].buf_len = (TREF(gtmprompt)).len; do { done = TRUE; assert(0 <= index && index <= MAX_RECALL + 1); cl = clmod(comline_index - index); if ((0 == index) || (MAX_RECALL + 1 == index)) tt_ptr->item_list[5].buf_len = 0; else { tt_ptr->item_list[5].buf_len = comline_base[cl].len; tt_ptr->item_list[5].addr = comline_base[cl].addr; } status = sys$qiow(EFN$C_ENF, tt_ptr->channel, tt_ptr->read_mask, &stat_blk, 0, 0, stringpool.free, tt_ptr->in_buf_sz, 0, 0, tt_ptr->item_list, 6 * SIZEOF(item_list_struct)); if (outofband) break; if (SS$_NORMAL != status) { if (io_curr_device.in == io_std_device.in && io_curr_device.out == io_std_device.out) { if (prin_in_dev_failure) sys$exit(status); else prin_in_dev_failure = TRUE; } break; } if (stat_blk.term_length > ESC_LEN - 1) { stat_blk.term_length = ESC_LEN - 1; if (SS$_NORMAL == stat_blk.status) stat_blk.status = SS$_PARTESCAPE; } if (SS$_NORMAL != stat_blk.status) { if (ctrlu_occurred) { index = 0; done = FALSE; ctrlu_occurred = FALSE; iott_wtctrlu(stat_blk.char_ct + (TREF(gtmprompt)).len, io_ptr); } else { status = stat_blk.status; break; } } else { if ((CTRL_B == stat_blk.term_char) || (stat_blk.term_length == tt_ptr->key_up_arrow.len && !memcmp(tt_ptr->key_up_arrow.addr, stringpool.free + stat_blk.char_ct, tt_ptr->key_up_arrow.len))) { done = FALSE; if ((MAX_RECALL + 1 != index) && (comline_base[cl].len || !index)) index++; } else { if (stat_blk.term_length == tt_ptr->key_down_arrow.len && !memcmp(tt_ptr->key_down_arrow.addr, stringpool.free + stat_blk.char_ct, tt_ptr->key_down_arrow.len)) { done = FALSE; if (index) --index; } } if (!done) { status = sys$qiow(EFN$C_ENF, tt_ptr->channel, IO$_WRITEVBLK, &iosb, NULL, 0, tt_ptr->erase_to_end_line.addr, tt_ptr->erase_to_end_line.len, 0, CCRECALL, 0, 0); } else { if (stat_blk.char_ct > 0 && (('R' == *stringpool.free) || ('r' == *stringpool.free)) && (TRUE == m_recall(stat_blk.char_ct, stringpool.free, &index, tt_ptr->channel))) { assert(-1 <= index && index <= MAX_RECALL); done = FALSE; flush_pio(); status = sys$qiow(EFN$C_ENF, tt_ptr->channel, IO$_WRITEVBLK, &iosb, NULL, 0, 0, 0, 0, CCPROMPT, 0, 0); if ((-1 == index) || (CTRL_Z == stat_blk.term_char)) index = 0; } } if (!done) { if (SS$_NORMAL == status) status = iosb[0]; if (SS$_NORMAL != status) break; } else { if (CTRL_Z == stat_blk.term_char) io_curr_device.in->dollar.zeof = TRUE; } } } while (!done); /* put the terminal back the way the user had it set up */ tt_ptr->item_list[0].addr = save_modifiers; ((io_termmask *)tt_ptr->item_list[2].addr)->mask[0] = save_term_msk; if (tt_ptr->term_chars_twisted) { s_mode.ext_cap &= (~TT2$M_PASTHRU & ~TT2$M_EDITING); s_mode.ext_cap |= (tt_ptr->ext_cap & (TT2$M_PASTHRU | TT2$M_EDITING)); s_mode.term_char &= (~TT$M_ESCAPE); s_mode.term_char |= (tt_ptr->term_char & TT$M_ESCAPE); status = sys$qiow(EFN$C_ENF, tt_ptr->channel, IO$_SETMODE, iosb, 0, 0, &s_mode, 12, 0, 0, 0, 0); if (SS$_NORMAL == status) status = iosb[0]; tt_ptr->term_chars_twisted = FALSE; } if (SS$_NORMAL != status) rts_error(VARLSTCNT(1) status); if (outofband) { /* outofband not going to help more than a error so it's checked 2nd */ outofband_action(FALSE); assert(FALSE); } v->mvtype = MV_STR; v->str.len = stat_blk.char_ct; v->str.addr = stringpool.free; if (stat_blk.char_ct) { cl = clmod(comline_index - 1); if (stat_blk.char_ct != comline_base[cl].len || memcmp(comline_base[cl].addr, stringpool.free, stat_blk.char_ct)) { comline_base[comline_index] = v->str; comline_index = clmod(comline_index + 1); } stringpool.free += stat_blk.char_ct; } assert(stringpool.free <= stringpool.top); if ((io_ptr->dollar.x += stat_blk.char_ct) > io_ptr->width && io_ptr->wrap) { /* dm_read doesn't maintain the other io status isv's, but it does $x and $y so the user can find out where they wound up */ io_ptr->dollar.y += io_ptr->dollar.x / io_ptr->width; if (io_ptr->length) io_ptr->dollar.y %= io_ptr->length; io_ptr->dollar.x %= io_ptr->width; } active_device = 0; }
/* return 0 if ok, 1 (or -1) otherwise */ int des_read_pw(char *buf, char *buff, int size, const char *prompt, int verify) { # ifdef OPENSSL_SYS_VMS struct IOSB iosb; $DESCRIPTOR(terminal, "TT"); long tty_orig[3], tty_new[3]; long status; unsigned short channel = 0; # else # if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__) TTY_STRUCT tty_orig, tty_new; # endif # endif int number; int ok; /* * statics are simply to avoid warnings about longjmp clobbering things */ static int ps; int is_a_tty; static FILE *tty; char *p; if (setjmp(save)) { ok = 0; goto error; } number = 5; ok = 0; ps = 0; is_a_tty = 1; tty = NULL; # ifdef OPENSSL_SYS_MSDOS if ((tty = fopen("con", "r")) == NULL) tty = stdin; # elif defined(MAC_OS_pre_X) || defined(OPENSSL_SYS_VXWORKS) tty = stdin; # else # ifndef OPENSSL_SYS_MPE if ((tty = fopen("/dev/tty", "r")) == NULL) # endif tty = stdin; # endif # if defined(TTY_get) && !defined(OPENSSL_SYS_VMS) if (TTY_get(fileno(tty), &tty_orig) == -1) { # ifdef ENOTTY if (errno == ENOTTY) is_a_tty = 0; else # endif # ifdef EINVAL /* * Ariel Glenn [email protected] reports that solaris can return * EINVAL instead. This should be ok */ if (errno == EINVAL) is_a_tty = 0; else # endif return (-1); } memcpy(&(tty_new), &(tty_orig), sizeof(tty_orig)); # endif # ifdef OPENSSL_SYS_VMS status = sys$assign(&terminal, &channel, 0, 0); if (status != SS$_NORMAL) return (-1); status = sys$qiow(0, channel, IO$_SENSEMODE, &iosb, 0, 0, tty_orig, 12, 0, 0, 0, 0); if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) return (-1); # endif pushsig(); ps = 1; # ifdef TTY_FLAGS tty_new.TTY_FLAGS &= ~ECHO; # endif # if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) if (is_a_tty && (TTY_set(fileno(tty), &tty_new) == -1)) # ifdef OPENSSL_SYS_MPE ; /* MPE lies -- echo really has been disabled */ # else return (-1); # endif # endif # ifdef OPENSSL_SYS_VMS tty_new[0] = tty_orig[0]; tty_new[1] = tty_orig[1] | TT$M_NOECHO; tty_new[2] = tty_orig[2]; status = sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12, 0, 0, 0, 0); if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) return (-1); # endif ps = 2; while ((!ok) && (number--)) { fputs(prompt, stderr); fflush(stderr); buf[0] = '\0'; fgets(buf, size, tty); if (feof(tty)) goto error; if (ferror(tty)) goto error; if ((p = (char *)strchr(buf, '\n')) != NULL) *p = '\0'; else read_till_nl(tty); if (verify) { fprintf(stderr, "\nVerifying password - %s", prompt); fflush(stderr); buff[0] = '\0'; fgets(buff, size, tty); if (feof(tty)) goto error; if ((p = (char *)strchr(buff, '\n')) != NULL) *p = '\0'; else read_till_nl(tty); if (strcmp(buf, buff) != 0) { fprintf(stderr, "\nVerify failure"); fflush(stderr); break; /* continue; */ } } ok = 1; } error: fprintf(stderr, "\n"); # if 0 perror("fgets(tty)"); # endif /* What can we do if there is an error? */ # if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) if (ps >= 2) TTY_set(fileno(tty), &tty_orig); # endif # ifdef OPENSSL_SYS_VMS if (ps >= 2) status = sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_orig, 12, 0, 0, 0, 0); # endif if (ps >= 1) popsig(); if (stdin != tty) fclose(tty); # ifdef OPENSSL_SYS_VMS status = sys$dassgn(channel); # endif return (!ok); }
int VMSmunch( char *filename, int action, char *ptr ) { /* original file.c variables */ static struct FAB Fab; static struct NAM Nam; static struct fibdef Fib; /* short fib */ static struct dsc$descriptor FibDesc = {sizeof(Fib),DSC$K_DTYPE_Z,DSC$K_CLASS_S,(char *)&Fib}; static struct dsc$descriptor_s DevDesc = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,&Nam.nam$t_dvi[1]}; static struct fatdef Fat; static union { struct fchdef fch; long int dummy; } uchar; static struct fjndef jnl; static long int Cdate[2],Rdate[2],Edate[2],Bdate[2]; static short int revisions; static unsigned long uic; #if defined(__DECC) || defined(__DECCXX) #pragma __member_alignment __save #pragma __nomember_alignment #endif /* __DECC || __DECCXX */ static union { unsigned short int value; struct { unsigned system : 4; unsigned owner : 4; unsigned group : 4; unsigned world : 4; } bits; } prot; #if defined(__DECC) || defined(__DECCXX) #pragma __member_alignment __restore #endif /* __DECC || __DECCXX */ static struct atrdef Atr[] = { {sizeof(Fat),ATR$C_RECATTR,&Fat}, /* record attributes */ {sizeof(uchar),ATR$C_UCHAR,&uchar}, /* File characteristics */ {sizeof(Cdate),ATR$C_CREDATE,&Cdate[0]}, /* Creation date */ {sizeof(Rdate),ATR$C_REVDATE,&Rdate[0]}, /* Revision date */ {sizeof(Edate),ATR$C_EXPDATE,&Edate[0]}, /* Expiration date */ {sizeof(Bdate),ATR$C_BAKDATE,&Bdate[0]}, /* Backup date */ {sizeof(revisions),ATR$C_ASCDATES,&revisions}, /* number of revisions */ {sizeof(prot),ATR$C_FPRO,&prot}, /* file protection */ {sizeof(uic),ATR$C_UIC,&uic}, /* file owner */ {sizeof(jnl),ATR$C_JOURNAL,&jnl}, /* journal flags */ {0,0,0} } ; static char EName[NAM$C_MAXRSS]; static char RName[NAM$C_MAXRSS]; static struct dsc$descriptor_s FileName = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0}; static struct dsc$descriptor_s string = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0}; static short int DevChan; static short int iosb[4]; static long int i,status; /* static char *retval; */ /* new VMSmunch variables */ static int old_rtype=FAT$C_FIXED; /* storage for record type */ /*--------------------------------------------------------------------------- Initialize attribute blocks, parse filename, resolve any wildcards, and get the file info. ---------------------------------------------------------------------------*/ /* initialize RMS structures, we need a NAM to retrieve the FID */ Fab = cc$rms_fab; Fab.fab$l_fna = filename; Fab.fab$b_fns = strlen(filename); Fab.fab$l_nam = &Nam; /* FAB has an associated NAM */ Nam = cc$rms_nam; Nam.nam$l_esa = EName; /* expanded filename */ Nam.nam$b_ess = sizeof(EName); Nam.nam$l_rsa = RName; /* resultant filename */ Nam.nam$b_rss = sizeof(RName); /* do $PARSE and $SEARCH here */ status = sys$parse(&Fab); if (!(status & 1)) return(status); /* search for the first file.. If none signal error */ status = sys$search(&Fab); if (!(status & 1)) return(status); while (status & 1) { /* initialize Device name length, note that this points into the NAM to get the device name filled in by the $PARSE, $SEARCH services */ DevDesc.dsc$w_length = Nam.nam$t_dvi[0]; status = sys$assign(&DevDesc,&DevChan,0,0); if (!(status & 1)) return(status); FileName.dsc$a_pointer = Nam.nam$l_name; FileName.dsc$w_length = Nam.nam$b_name+Nam.nam$b_type+Nam.nam$b_ver; /* Initialize the FIB */ for (i=0;i<3;i++) Fib.FIB$W_FID[i]=Nam.nam$w_fid[i]; for (i=0;i<3;i++) Fib.FIB$W_DID[i]=Nam.nam$w_did[i]; /* Use the IO$_ACCESS function to return info about the file */ /* Note, used this way, the file is not opened, and the expiration */ /* and revision dates are not modified */ status = sys$qiow(0,DevChan,IO$_ACCESS,&iosb,0,0, &FibDesc,&FileName,0,0,&Atr,0); if (!(status & 1)) return(status); status = iosb[0]; if (!(status & 1)) return(status); /*----------------------------------------------------------------------- We have the current information from the file: now see what user wants done with it. -----------------------------------------------------------------------*/ switch (action) { case GET_TIMES: asctim(((struct VMStimbuf *)ptr)->modtime, Cdate); asctim(((struct VMStimbuf *)ptr)->actime, Rdate); break; case SET_TIMES: bintim(((struct VMStimbuf *)ptr)->modtime, Cdate); bintim(((struct VMStimbuf *)ptr)->actime, Rdate); break; case GET_RTYPE: /* non-modifying */ *(int *)ptr = Fat.fat$v_rtype; return RMS$_NORMAL; /* return to user */ break; case CHANGE_RTYPE: old_rtype = Fat.fat$v_rtype; /* save current one */ if ((*(int *)ptr < FAT$C_UNDEFINED) || (*(int *)ptr > FAT$C_STREAMCR)) Fat.fat$v_rtype = FAT$C_STREAMLF; /* Unix I/O happy */ else Fat.fat$v_rtype = *(int *)ptr; break; case RESTORE_RTYPE: Fat.fat$v_rtype = old_rtype; break; default: return SS$_BADPARAM; /* anything better? */ } /*----------------------------------------------------------------------- Go back and write modified data to the file header. -----------------------------------------------------------------------*/ /* note, part of the FIB was cleared by earlier QIOW, so reset it */ Fib.FIB$L_ACCTL = FIB$M_NORECORD; for (i=0;i<3;i++) Fib.FIB$W_FID[i]=Nam.nam$w_fid[i]; for (i=0;i<3;i++) Fib.FIB$W_DID[i]=Nam.nam$w_did[i]; /* Use the IO$_MODIFY function to change info about the file */ /* Note, used this way, the file is not opened, however this would */ /* normally cause the expiration and revision dates to be modified. */ /* Using FIB$M_NORECORD prohibits this from happening. */ status = sys$qiow(0,DevChan,IO$_MODIFY,&iosb,0,0, &FibDesc,&FileName,0,0,&Atr,0); if (!(status & 1)) return(status); status = iosb[0]; if (!(status & 1)) return(status); status = sys$dassgn(DevChan); if (!(status & 1)) return(status); /* look for next file, if none, no big deal.. */ status = sys$search(&Fab); } return(status); } /* end function VMSmunch() */