From:	MERC::"uunet!CRVAX.SRI.COM!RELAY-INFO-VAX" 10-JUL-1992 22:07:02.47
To:	info-vax@kl.sri.com
CC:	
Subj:	mount tape and grab mount-oper-messages


Sorry if this problem has been treated recently, i dont follow this
newsgroup.

I want to mount a tape with system-routine $mount. The messages for
mount-request should be available to the program that calls sys$mount.
The messages are then stored in some special place.

I tried to set up a mailbox and assign sys$output to it. A read-request
is set up on the mailbox and an AST-routine is specified.Inside the
AST, the message is read and another read-request is set up.

This works fine for the first 2 messages. Then the AST is called with
iosb-error-code=SS$_ENDOFFILE. The following (3. and 4.) messages are lost.



Thanks for any suggestions


Urs

------
U.Beckmann, ETH Zurich, Switzerland


/*
mount tape , grab mount-operator-messages,
and print them to stderr.

compiled with GNU-C
*/

#include <errno.h>
#include <stdio.h>
#include <ssdef.h>
#include <descrip.h>
#include <iodef.h>
#include <devdef.h>
#include <dvidef.h>
#include <lnmdef.h>
#include <vms/msgdef.h>
#include <vms/mntdef.h>
#include <mtdef.h>


#define BOOLEAN int
#define TRUE 1
#define FALSE 0

#define TAPEVOLUME "111111"
#define TAPEDEVICE "$2$mua0:"

#define szero(BLOCK) bzero(&BLOCK,sizeof(BLOCK))


struct	iosb {
	short status,count;
	int	deviceinfo;
	}	iosb,mbxiosb,diosb;

struct item {
	short length,code;
	void *addr;
	void *raddr;
};



/* sysout to mailbox-redirection stuff */
short int sysoutmbxchn;
struct iosb sysoutmbxiosb;
char	sysoutmsg[255];




/* 2 prozedures, which direct sys$output-messages to mailbox  */

sysoutmbxast()
/*
This AST is called, when a message has been received
*/
{
	int	r,i,j;


	/* read message from mailbox: */
fprintf(stderr,"sysoutmbxast() called\n");

	sysoutmsg[sysoutmbxiosb.count]=0;
	r=sysoutmbxiosb.status;
fprintf(stderr,"message received: status=%x,length=%d,message=%s\n",
	r,(int) sysoutmbxiosb.count,sysoutmsg);
	if	(!(r&1) && r!=SS$_ENDOFFILE)	{
		fprintf(stderr,"Error from read-sysout-mbx: %x",r);
		return 1;
	}

fprintf(stderr,"before setup next read\n");
	sys$clref(1);
	szero(sysoutmbxiosb);
	r=sys$qio(1,sysoutmbxchn,IO$_READVBLK,&sysoutmbxiosb,
		&sysoutmbxast,0,sysoutmsg,sizeof(sysoutmsg)-1,0,0,0,0);
	if	(!(r&1))	{
		fprintf(stderr,"sys$qio-error:%x\n",r);
		return	1;
	}
fprintf(stderr,"after  setup read\n");

	return	1;
}




setupsysoutmbx()
/* 
A mailbox is created and sys$output is redirected to it.
the channelnr is stored in 'sysoutmbxchn'. As soon as a message
arrives, 'sysoutmbxast()' is called.
rc: 0=ok, -1=error
*/
{
	char 	sysout[]="SYS$OUTPUT";
	char 	sysoutmbxname[100];	
	char	sysoutlogtable[]="LNM$PROCESS_TABLE";
	$DESCRIPTOR(sysoutd,sysout);
	$DESCRIPTOR(sysoutlogtabled,sysoutlogtable);	
	int	r;
	struct item items[2];


	/* create mailbox: */
	r=sys$crembx(0,&sysoutmbxchn,0,0,255,0,0);
	if	(!(r&1))	{
		fprintf(stderr,"sys$crembx-error:%x\n",r);
		return	-1;
	}
		
	/* get device name of mailbox: */
	szero(items);
	items[0].code=DVI$_DEVNAM;
	items[0].length=sizeof(sysoutmbxname);
	items[0].addr=sysoutmbxname;
	r=sys$getdvi(0,sysoutmbxchn,0,items,&sysoutmbxiosb,0,0,0);
	if	(!(r&1))	{
		fprintf(stderr,"sys$getdvi-error:%x\n",r);
		return	-1;
	}
		
	/* assign sys$output to mailbox: */
	szero(items);
	items[0].code=LNM$_STRING;
	items[0].length=strlen(sysoutmbxname);
	items[0].addr=sysoutmbxname;
	r=sys$crelnm(0,&sysoutlogtabled,&sysoutd,0,items);
/*	r=lib$set_logical(&sysoutd,0,&sysoutlogtabled,0,items); */
	if	(!(r&1))	{
		fprintf(stderr,"sys$crelnm-error:%x\n",r);
		return	-1;
	}
fprintf(stderr,"crelnm succeded\n");
		

fprintf(stderr,"before setup read\n");
	sys$clref(1);
	szero(sysoutmbxiosb);
	r=sys$qio(1,sysoutmbxchn,IO$_READVBLK,&sysoutmbxiosb,
		&sysoutmbxast,0,sysoutmsg,sizeof(sysoutmsg)-1,0,0,0,0);
	if	(!(r&1))	{
		fprintf(stderr,"sys$qio-error:%x\n",r);
		return	1;
	}
fprintf(stderr,"after  setup read\n");

	return	0;
}





main()	{
	char	s[100];
	int	i;

	/* sys$output -> client: */
	setupsysoutmbx();
	domount(TAPEVOLUME,TAPEDEVICE,MNT$M_MESSAGE|MNT$M_NOUNLOAD);
	for	(;;)	{ 
		fprintf(stderr,"enter x to exit");
		scanf("%s",s);
		if	(s[0]=='x')
			break;
	}
	return 1;
}


int	bzero(block,size)
/* 
  clear block to 0-bytes
*/
	char	*block;
	unsigned int	size;
{	
	unsigned	int	i;

	for	(i=0;i<size;i++)
		*(block++)=0;
}	



int	domount(volume,device,flags)
char	*volume;	/* nur 1 vol-name */
char	*device;
int	flags;		/* MNT$_-flags */

/* mount volume 
volume: volume-name, if==NULL, no volume is specified
	(mount/foreign)
flags:  $mount-flags (systemservices-manual)


rc: VMS-like
*/

{
int	rc,r,i;
struct item  items[6];
static char  readmsg[]="mount for read-only-access";
static char  writemsg[]="mount for write-access";

	bzero(items,sizeof(items));
	items[0].code=MNT$_DEVNAM;
	items[0].addr=device;
	items[0].length=strlen(device);

	items[1].code=MNT$_FLAGS;
	items[1].addr=&flags;
	items[1].length=4;

	items[2].code=MNT$_COMMENT;
	items[2].addr=(flags&MNT$M_NOWRITE)?readmsg:writemsg;
	items[2].length=strlen(items[2].addr);

	if	(volume!=NULL)	{
		items[3].code=MNT$_VOLNAM;
		items[3].addr=volume;
		items[3].length=strlen(volume);
	}
fprintf(stderr,"before sys$mount\n");
	rc=sys$mount(items);
fprintf(stderr,"after sys$mount,rc=%x\n",rc);
	return rc;
}

