|
|
researchv10 Norman
#include <stdio.h>
#include <dk.h>
#include <sgtty.h>
#include <sys/stream.h>
#include <errno.h>
#include <signal.h>
#include <sys/stat.h>
/*
* program to connect to
* another cpu on Datakit w/ transparent ioctls
*/
int rem; /* remote file descriptor */
extern int mesg_ld, dkp_ld;
extern errno;
extern char *dkerror;
struct sgttyb sgbuf;
char *ttyn;
int perms;
struct sigmsg {
struct mesg m;
char sig[1];
};
#define msglen(mp) ((mp)->losize + ((mp)->hisize<<8))
main(argc, argv)
char **argv;
{
char *host;
char dest[128];
struct stat sb;
extern int hupcatch();
char *ttyname();
while(argc > 1 && argv[1][0] == '-'){
argv++;
argc--;
}
host = argv[1];
if(host==0){
printf("usage: %s host\n", argv[0]);
exit(1);
}
ioctl(0, TIOCGETP, &sgbuf);
sprintf(dest, "%s.mesgdcon", host);
rem = tdkdial(dest, 0);
if (rem<0) {
printf("%s: call to %s failed: %s\n", argv[0], dest, dkerror);
exit(1);
}
if(dkproto(rem, dkp_ld) < 0){
printf("%s: can't push dk line discipline\n", argv[0]);
exit(1);
}
if(tdklogin(rem) < 0){
printf("%s: can't log in\n", argv[0]);
exit(1);
}
signal(SIGHUP, hupcatch);
signal(SIGQUIT, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
if ((ttyn = ttyname(0)) != NULL
&& stat(ttyn, &sb) >= 0) {
perms = sb.st_mode & ~S_IFMT;
chmod(ttyn, 0);
}
ioctl(0, TIOCFLUSH, (char *)0); /* race with readahead still possible */
if(ioctl(0, FIOPUSHLD, &mesg_ld) < 0){
printf("%s: can't push mesg_ld\n", argv[0]);
finish(1);
}
go(rem);
finish(0);
/* NOTREACHED */
}
go(fd)
{
int rbits, wbits, n;
char buf[4096+MSGHLEN];
struct mesg *mp;
mp = (struct mesg *) buf;
wbits = 0;
while(1){
rbits = 1 | (1<<fd);
if(select(20, &rbits, &wbits, 20000) < 0){
if(errno != EINTR)
return;
continue;
}
if(rbits & 1){
n = read(0, buf, sizeof(buf));
if(n <= 0)
return;
if (mp->type==M_SIGNAL
&& ((struct sigmsg *)mp)->sig[0]==SIGQUIT) {
dolocal(fd, buf, n);
continue;
}
mp->magic = MSGMAGIC; /* temp safety */
if(write(fd, buf, n) != n)
return;
if(mp->type == M_FLUSH) {
remflush();
rbits = 0;
}
}
if(rbits & (1<<fd)){
n = read(fd, buf, sizeof(buf));
if(n <= 0)
return;
if(mp->type == M_HANGUP)
return;
if(mp->type == M_IOCTL){
doioctl(buf, n);
} else {
mp->magic = MSGMAGIC; /* temp safety */
if(write(1, buf, n) != n)
return;
}
}
}
}
doioctl(buf, n)
char *buf;
{
struct mesg *mp;
struct iofoo{
int cmd;
union{
int i;
char errno;
struct insld insld;
} u;
} *iop;
int cmd, ld;
iop = (struct iofoo *)(buf + MSGHLEN);
mp = (struct mesg *) buf;
cmd = iop->cmd;
n -= MSGHLEN;
n -= sizeof(iop->cmd);
switch(cmd){
case FIOLOOKLD:
if(n > 0)
ld = iop->u.i;
else
ld = 0;
ld++;
if(ioctl(1, FIOLOOKLD, &ld) < 0)
goto bad;
iop->cmd = ld;
n = sizeof(iop->cmd);
break;
case FIOPOPLD:
if(n > 0)
ld = iop->u.i;
else
ld = 0;
ld++;
if(ioctl(1, FIOPOPLD, &ld) < 0)
goto bad;
n = 0;
break;
case FIOPUSHLD:
iop->u.insld.level = 0;
/* fall through... */
case FIOINSLD:
iop->u.insld.level++;
if(ioctl(1, FIOINSLD, &(iop->u.insld)) < 0)
goto bad;
n = 0;
break;
default:
mp->magic = MSGMAGIC; /* safety */
write(1, buf, MSGHLEN + msglen(mp));
return;
}
/* locally successful */
mp->type = M_IOCACK;
mp->magic = MSGMAGIC;
setmsgl(mp, n);
write(rem, buf, MSGHLEN + msglen(mp));
return;
bad:
mp->type = M_IOCNAK;
mp->magic = MSGMAGIC;
setmsgl(mp, sizeof(struct iofoo));
iop->u.errno = errno;
write(rem, buf, MSGHLEN + msglen(mp));
}
remflush()
{
char buf[5000];
struct mesg *mp;
int n;
mp = (struct mesg *) buf;
mp->type = M_IOCTL;
setmsgl(mp, sizeof(int));
mp->magic = MSGMAGIC;
write(rem, buf, sizeof(struct mesg) + msglen(mp));
while((n = read(rem, buf, sizeof(buf))) > 0){
if(mp->type == M_IOCNAK || mp->type == M_IOCACK)
return;
}
}
setmsgl(mp, n)
register struct mesg *mp;
int n;
{
mp->losize = n;
mp->hisize = n >> 8;
}
hupcatch()
{
finish(0);
}
finish(sts)
{
struct mesg m;
if(ioctl(0, FIOLOOKLD, 0) == mesg_ld)
ioctl(0, FIOPOPLD, 0);
if (ttyn)
chmod(ttyn, perms);
if (sts == 0)
printf("Eof\n");
exit(sts);
}
dolocal(fp, buf, n)
char *buf;
{
char lbuf[128+1];
register char *lp;
struct sgttyb nsgbuf;
register struct mesg *mp = (struct mesg *)buf;
ioctl(0, FIOPOPLD, (char *)0);
ioctl(0, TIOCFLUSH, (char *)0);
ioctl(0, TIOCGETP, &nsgbuf);
ioctl(0, TIOCSETP, &sgbuf);
chmod(ttyn, perms);
for (;;) {
lp = lbuf;
printf( "dcon>> ");
fflush(stdout);
while (lp < &lbuf[128] && read(0, lp, 1)>0 && *lp!='\n')
lp++;
*lp = '\0';
if (*lbuf=='i')
break;
else if (*lbuf=='q'||*lbuf=='x'||*lbuf=='.')
exit(0);
else if (*lbuf=='!') {
system(lbuf+1);
printf("!!\n");
fflush(stdout);
mp->type = 0;
break;
} else if (*lbuf=='\0') {
mp->type = 0;
break;
} else {
printf("[qx.] to exit, i for quit signal, !cmd for shell\n");
fflush(stdout);
}
}
ioctl(0, TIOCSETP, &nsgbuf);
ioctl(0, FIOPUSHLD, &mesg_ld);
chmod(ttyn, 0);
if (mp->type) {
mp->magic = MSGMAGIC; /* safety */
write(fp, buf, n);
}
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.