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 );
}
Beispiel #3
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);
}
Beispiel #6
0
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
}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
}
Beispiel #10
0
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];
        }
      }
Beispiel #11
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);
    }
  }
}
Beispiel #12
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;
}
Beispiel #13
0
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]);
}
Beispiel #14
0
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;
}
Beispiel #15
0
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;
}
Beispiel #16
0
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;
}
Beispiel #17
0
/* 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;
}
Beispiel #18
0
/*
**++
**  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
}
Beispiel #20
0
/*
**++
**  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 */
Beispiel #21
0
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
}
Beispiel #22
0
/*
**++
**  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 */
Beispiel #23
0
/* 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;
}
Beispiel #24
0
/*
**++
**  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 */
Beispiel #25
0
/*
**++
**  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 */
Beispiel #26
0
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;
}
Beispiel #27
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);
}
Beispiel #28
0
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() */