From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 22-FEB-1991 17:40:47.43
To:	ARISIA::EVERHART
CC:	
Subj:	mirror, part 2 of 2,  multiple terminals to one session.

From:	RELAY-INFO-VAX@CRVAX.SRI.COM@SMTP@CRDGW2
To:	Everhart@Arisia@MRGATE

Received:  by crdgw1.ge.com (5.57/GE 1.83)
	 id AA00211; Fri, 22 Feb 91 17:24:09 EST
Received: From UCBVAX.BERKELEY.EDU by CRVAX.SRI.COM with TCP; Thu, 21 FEB 91 07:19:36 PST
Received: by ucbvax.Berkeley.EDU (5.63/1.42)
	id AA21721; Thu, 21 Feb 91 07:14:20 -0800
Received: from USENET by ucbvax.Berkeley.EDU with netnews
	for info-vax@kl.sri.com (info-vax@kl.sri.com)
	(contact usenet@ucbvax.Berkeley.EDU if you have questions)
Date: 20 Feb 91 13:46:59 GMT
From: uhccux!waikato.ac.nz!comp.vuw.ac.nz!wnv!grace!srghcxp@ames.arc.nasa.gov
Organization: DSIR, Gracefield, New Zealand
Subject: mirror, part 2 of 2,  multiple terminals to one session.
Message-Id: <8615@grace.dsir.govt.nz>
Sender: info-vax-request@kl.sri.com
To: info-vax@kl.sri.com

-+-+-+-+-+-+-+-+ START OF PART 2 -+-+-+-+-+-+-+-+
X    tt_chr.ttchr`7C= TT$M_NOECHO;           /* term will be Noecho */
X    tt_chr.ttchr&= `7ETT$M_HOSTSYNC & `7ETT$M_TTSYNC;   /* it will have `5ES
V */
X    tt_chr.xchar`7C= TT2$M_PASTHRU;           /* it will be PASTRHU */
X    check(SYS$QIOW(0,tt_chn,IO$_SETMODE,0,0,0,&tt_chr,ttchrlen,0,0,0,0));
X`7D
X/*---------------------------------------------------------------*/
Xfix_a_tw()                   /* Set up a Pseudo term */
X`7B
X    int efn=1, dev_depend, tw_chn;
X    struct CHARBLK tw_chr;
X    struct IOSBBLK iosb;
X    struct DVIBLK  dvi_stuff = `7B4, DVI$_DEVDEPEND, &dev_depend, 0, 0`7D;
X
X
X    $DESCRIPTOR(d_pynam,"PYA0:");           /* Template. */
X    $DESCRIPTOR(d_finaltw, &finaltw);
X                       /* Assign a mailbox to PYA */
X    check(LIB$ASN_WTH_MBX(&d_pynam,&mbsiz,&maxsiz,&py_chn,&py_mb_chn));
X/*
X * Use $GETDVI to get the device dependent characteristics, which
X * contains the associated terminal device's unit number.
X */
X    check(SYS$GETDVI(0,py_chn,0,&dvi_stuff,&iosb,0,0,0));
X    check(iosb.stats);
X    sprintf(&finaltw,"TWA%d:",dev_depend);
X    tw_chr= tt_sav_chr;
X    tw_chr.xchar`7C= TT2$M_HANGUP;
X    d_finaltw.dsc$w_length= strlen(&finaltw);
X    check(SYS$ASSIGN(&d_finaltw,&tw_chn,0,0)); /* Get a channel on this TWA
V */
X                       /* Make it look like user's real terminal */
X    st = SYS$QIOW(0,tw_chn,IO$_SETCHAR,0,0,0,&tw_chr,ttchrlen,0,0,0,0);
X    if (st == SS$_NOPRIV)
X`09printf ("WARNING -- PHY_IO privilege required to propagate terminal chara
Vcteristics!\n");
X    else
X`09check(st);
X    check(SYS$DASSGN(tw_chn));     /* We don't need it. only the mailbox */
X                                   /* in fact keeping it kills us. */
X`7D
X/*---------------------------------------------------------------*/
X
X
Xpost_reads()                   /* This sets up ASTs */
X`7B
X                       /* Read AST on Pseudo-term */
X    check(SYS$QIO(0,py_mb_chn,IO$_READVBLK,&miosb,&tw_srv,0,
X                       &py_mb,mbsiz,0,0,0,0));
X                       /* Read AST on real term */
X    check(SYS$QIO(0,tt_mb_chn,IO$_READVBLK,&tiosb,&tt_srv,0,
X                       &tt_mb,mbsiz,0,0,0,0));
X`7D
X/*---------------------------------------------------------------*/
X
X
Xmain(how_many,rscan)
X    int how_many;
X    char *rscan`5B`5D;
X`7B
X    int  exit_handler`5B4`5D= `7B0,quit,0,&st`7D;
X    char filnam`5B40`5D;
X
X    check(LIB$GET_EF(&z_ef));
X    check(SYS$DCLEXH(&exit_handler));  /* Define Exit handler (quit) */
X    get_tt_info();                     /* Get terminal channel & info */
X    fix_a_tw();                        /* Set a pseudo terminal by TT info *
V/
X    check(SYS$CANCEL(py_chn));         /* Don't need this Half of pseudo-ter
V */
X    check(low_lib_spawn(&finaltw,&pid));   /* Spawn a subprocess. */
X    post_reads();
X    enable_hangups= 1;
X    puts ("Begining Mirror session.  Use `5E\\ to abort process");
X    begin_session();
X`7D
Xother_terminal(char *s,int j)
X`7B
X`09static buff`5B1000`5D;
X`09strncpy(buff,s,j);
X`09buff`5Bj`5D=0;
X`09printf("%s",s);
X
X
X`7D
X
X/*---------------------------------------------------------------*/
Xstruct IOSBBLK r_iosb,c_iosb,t_iosb,w_iosb`5B40`5D,ppiosb;
X#define bsize 512
Xchar r_buff`5Bbsize`5D,c_buff`5Bbsize`5D;
Xlong w_chan`5B40`5D,r_chan,c_chan;
Xunsigned int efmask,r_ef,x_ef,t_ef,c_ef,p_ef,w_ef;
Xint nw;
Xbegin_session()
X`7B
X    int j;
X
X    open_mailboxes();
X    pre_read_cont();
X    pre_read_mail();`20
X    pre_read_psuedo();
X    for(;;) `7B          /* Read/write forever loop */
X`09waitforflag();
X`09if (r_iosb.stats!=0) `7B send_psuedo(); pre_read_mail(); `7D
X`09if (c_iosb.stats!=0) `7B new_slave(); pre_read_cont(); `7D
X`09if (piosb.stats!=0) `7B send_screen(); send_mail(); pre_read_psuedo(); `7
VD
X    `7D
X`7D
Xopen_mailboxes()
X`7B
X`09char ss`5B22`5D;
X`09$DESCRIPTOR(w_name, "MIRROR_WRITE"); /* reversed on purpose */
X`09$DESCRIPTOR(r_name, "MIRROR_READ");
X`09$DESCRIPTOR(c_name, "MIRROR_CONTROL");
X
X`09check(SYS$CREMBX(0,&c_chan,0,0,0,0,&c_name));
X`09check(SYS$CREMBX(0,&r_chan,0,0,0,0,&w_name));
X
X`09check(LIB$GET_EF(&x_ef));
X`09check(LIB$GET_EF(&w_ef));
X`09check(LIB$GET_EF(&r_ef));
X`09check(LIB$GET_EF(&p_ef));
X`09check(LIB$GET_EF(&c_ef));
X`09efmask = (1<<(r_ef-32)) + (1<<(p_ef-32)) + (1<<(c_ef-32));
X`7D
Xpre_read_psuedo()
X`7B
X    piosb.stats = 0;
X    check(SYS$QIO(p_ef,py_chn,IO$_READVBLK,&piosb,0,0,
X                                    &twline,90,0,0,0,0));
X`7D
Xpre_read_cont()
X`7B
X    c_iosb.stats = 0;
X    check(SYS$QIO(c_ef,c_chan,IO$_READLBLK,&c_iosb,0,0,
X                               &c_buff,90,0,0,0,0));
X`7D
Xpre_read_mail()
X`7B
X    r_iosb.stats = 0;  `20
X    check(SYS$QIO(r_ef,r_chan,IO$_READLBLK,&r_iosb,0,0,
X                               &r_buff,90,0,0,0,0));
X`7D
Xget_rest()
X`7B
X`09int j,i;
X`09j = piosb.tmoff + piosb.tmsiz;   /* How much stuff did we read? */
X    `09piosb.stats = 0;
X    `09check(SYS$QIO(x_ef,py_chn,IO$_READLBLK`7CIO$M_NOW,&piosb,0,0,
X                                    &twline+j,80,0,0,0,0));
X        check(SYS$WAITFR(x_ef));
X`09check(piosb.stats);
X`09piosb.tmoff = j + piosb.tmoff + piosb.tmsiz;  `20
X`09piosb.tmsiz = 0;
X`7D
Xsend_mail()
X`7B
X`09int j,i;
X        j = piosb.tmoff + piosb.tmsiz;   /* How much stuff did we read? */
X`09for (i=1;i<=nw;i++) `7B`09
X`09check(SYS$QIO(w_ef,w_chan`5Bi`5D,IO$_WRITELBLK,&w_iosb`5Bi`5D,0,0,&twline
V,j,0,0,0,0));
X        check(SYS$WAITFR(w_ef));           /* for some reason QIOW does not
V work */
X`09check(w_iosb`5Bi`5D.stats);
X`09`7D
X`7D
Xsend_screen()
X`7B
X`09int j;
X        j= piosb.tmoff + piosb.tmsiz;   /* How much stuff did we read? */
X        check(SYS$QIO(x_ef,tt_chn,IO$_WRITEVBLK,&t_iosb,0,0,&twline,j,0,0,0,
V0));
X        check(SYS$WAITFR(x_ef));           /* for some reason QIOW does not
V work */
X`09check(t_iosb.stats);
X`7D
Xnew_slave()
X`7B
X`09int j;
X`09char pid`5B20`5D;
X`09static char nams`5B40`5D="MIRROR_00000000";
X`09$DESCRIPTOR(newname, nams); /* reversed on purpose */
X`09j = c_iosb.tmoff; /* + r_iosb.tmsiz;*/
X   `09strncpy(nams,c_buff,j);
X`09newname.dsc$w_length = j;
X`09nams`5B15`5D = 0;
X`09printf("Connecting to `7B%s`7D \n",nams);
X`09nw++;
X`09check(SYS$CREMBX(0,&w_chan`5Bnw`5D,0,0,0,0,&newname));
X`7D
Xsend_psuedo()
X`7B
X`09int j;
X`09j = r_iosb.tmoff; /* + r_iosb.tmsiz;*/
X`09r_buff`5Bj`5D = 0;
X    `09check(SYS$QIO(x_ef,py_chn,IO$_WRITEVBLK,&ppiosb,0,0,&r_buff,j,0,0,0,0
V));
X`09check(SYS$WAITFR(x_ef));           /* for some reason QIOW does not work
V */
X    `09check(ppiosb.stats);
X`7D
Xwaitforflag()
X`7B
X`09check(SYS$WFLOR(33,efmask));
X`09if (c_iosb.stats!=0) `7Bcheck(c_iosb.stats); check(SYS$CLREF(c_ef));`7D
X`09if (r_iosb.stats!=0) `7Bcheck(r_iosb.stats); check(SYS$CLREF(r_ef));`7D
X`09if (piosb.stats!=0) `7Bcheck(piosb.stats); check(SYS$CLREF(p_ef));`7D
X`7D
$ CALL UNPACK MIRROR.C;84 510870095
$ create 'f'
X$ ! @ this procedure to run mirror. e.g. @USERDISK:`5BMIRROR`5DMIRROR.COM
X$ ! Then answer YES on the the first terminal and NO on all others
X$ ! Processes should be in the same group,  or use the alternate`20
X$ ! logical name table as described at the bottom of this file.
X$`20
X$ ! These lines find out where mirror is installed`20
X$ `09root = f$environment("procedure")
X$ `09rootdev = f$parse(root,,,"device","syntax_only")`20
X$ `09rootdir = f$parse(root,,,"directory","syntax_only")`20
X$ `09root = rootdev+rootdir
X$
X$ ! The process or image requires GRPNAM priv to use this.
X$ `09define /table=lnm$process_directory lnm$temporary_mailbox lnm$group
X$ ! *** This alternative logical name table doesn't require GRPNAM to be`20
X$ !     used but needs to be setup by someone with priv to start with.
X$ ! define /table=lnm$process_directory lnm$temporary_mailbox lnm_mirror
X$ `09inquire p1 "Is this the master (first) process"
X$ `09if p1 then run 'root'mirror
X$ `09if .not.(p1) then run 'root'mirrorspy
X$`20
X$`20
X$ ! *** This command defines a logical name table which doesn't require grpn
Vam`20
X$ ! (done in system startups)
X$ ! create /name /parent=lnm$system_directory lnm_mirror /prot=w:rwed
$ CALL UNPACK MIRROR.COM;7 1698851750
$ create 'f'
X#include DESCRIP
X#include FAB
X#include IODEF
X#include RAB
X#include TTDEF
X#include TT2DEF
X#include stdio
X#include JPIDEF
X#include SSDEF
X#include PRCDEF
X#include PRVDEF
X#include DVIDEF
X
X#define  CR             13
X#define  LF             10
X
X#define  bad(j)      !((j) & 1)
X#define  check(a)    if (bad(st = (a))) LIB$SIGNAL(st)
X/*---------------------------------------------------------------*/
Xstruct IOSBBLK `7Bunsigned short stats,
X                               tmoff,
X                               tmntr,
X                               tmsiz;
X               `7D;
Xstruct IOSBBLK t_iosb,r_iosb,w_iosb,p_iosb,c_iosb;
X#define bsize 512
Xchar t_buff`5Bbsize`5D;
Xchar r_buff`5Bbsize`5D;
Xchar c_buff`5Bbsize`5D;
Xlong w_chan,t_chan,r_chan,tt_mb_chn,c_chan;
Xunsigned efmask,st,r_ef,t_ef;
X/*---------------------------------------------------------------*/
Xmain()
X`7B
X`09open_mailboxes();
X`09open_terminal();
X`09pre_read_term();
X`09pre_read_mail();
X`09for (;;) `7B
X`09`09waitforflag();
X`09`09if (r_iosb.stats!=0) `7B print_term(); pre_read_mail(); `7D
X`09`09if (t_iosb.stats!=0) `7B send_mail(); pre_read_term(); `7D
X`09`7D
X`7D
X/*---------------------------------------------------------------*/
Xopen_terminal()
X`7B
X`09static $DESCRIPTOR(tt_desc,"tt");
X`09check(SYS$ASSIGN(&tt_desc,&t_chan,0,0));
X`7D
Xopen_mailboxes()
X`7B
X`09char ss`5B22`5D;
X`09static char nams`5B80`5D="MIRROR_00000000";
X
X`09$DESCRIPTOR(r_name, nams);
X`09$DESCRIPTOR(w_name, "MIRROR_WRITE");
X`09$DESCRIPTOR(c_name, "MIRROR_CONTROL");
X
X`09sprintf(nams,"MIRROR_%X",getpid());
X`09r_name.dsc$w_length = strlen(nams);
X
X`09check(SYS$CREMBX(0,&c_chan,0,0,0,0,&c_name));
X`09check(SYS$CREMBX(0,&w_chan,0,0,0,0,&w_name));
X`09check(SYS$CREMBX(0,&r_chan,0,0,0,0,&r_name));
X
X`09check(LIB$GET_EF(&r_ef));
X
X`09strcpy(c_buff,nams);
X`09check(SYS$QIO(r_ef,c_chan,IO$_WRITELBLK,&c_iosb,0,0,&c_buff,strlen(c_buff
V),0,0,0,0));
X        check(SYS$WAITFR(r_ef));           /* for some reason QIOW does not
V work */
X`09check(c_iosb.stats);
X`09printf("Now connected to Mirror process \n\n");
X`09check(LIB$GET_EF(&t_ef));
X`09efmask = (1<<(r_ef-32)) + (1<<(t_ef-32));
X`7D
Xpre_read_term()
X`7B
X    int read_mask;
X    t_iosb.stats = 0;
X    read_mask = IO$_READLBLK `7C IO$M_NOFILTR `7C IO$M_NOECHO;
X    check(SYS$QIO(t_ef,t_chan,read_mask,&t_iosb,0,0,
X                               &t_buff,1,0,0,0,0));
X`7D
Xpre_read_mail()
X`7B
X    r_iosb.stats = 0;
X    check(SYS$QIO(r_ef,r_chan,IO$_READLBLK,&r_iosb,0,0,
X                               &r_buff,140,0,0,0,0));
X`7D
Xwaitforflag()
X`7B
X`09check(SYS$WFLOR(33,efmask));
X`09if (r_iosb.stats!=0) `7Bcheck(r_iosb.stats); check(SYS$CLREF(r_ef));`7D
X`09if (t_iosb.stats!=0) `7Bcheck(t_iosb.stats); check(SYS$CLREF(t_ef));`7D
X`7D
Xprint_term()
X`7B
X`09char s`5B90`5D;
X`09int j;
X`09j = r_iosb.tmoff; /* + r_iosb.tmsiz;*/
X`09check(SYS$QIOW(0,t_chan,IO$_WRITELBLK,&p_iosb,0,0,&r_buff,j,0,0,0,0));
X`09check(p_iosb.stats);
X`7D
Xsend_mail()
X`7B
X`09int j;
X`09j = t_iosb.tmoff + t_iosb.tmsiz;
X`09check(SYS$QIOW(0,w_chan,IO$_WRITELBLK,&w_iosb,0,0,&t_buff,j,0,0,0,0));
X`09check(w_iosb.stats);
X`7D
X/*
Xwaitforflag()
X`7B
X`09int ef;
X`09check(SYS$WFLOR(1,efmask));
X`09check(SYS$READEF(1,&ef));
X`09printf("got flags %d \n",ef);
X`09if (ef && (1<<(r_ef-32))) got_mail = true;
X`09if (ef && (1<<(t_ef-32))) got_term = true;
X`7D`09`09`09`09
X*/
Xgetpid()
X`7B
X`09int pid=0;
X`09check(LIB$GETJPI(&JPI$_PID,&pid,0,0,0,0));
X`09return pid;
X`7D
$ CALL UNPACK MIRRORSPY.C;18 789806856
$ v=f$verify(v)
$ EXIT

