int debug; /* true if debugging */
int ctl = -1; /* control fd (for break's) */
int raw; /* true if raw is on */
int consctl = -1; /* control fd for cons */
int ttypid; /* pid's if the 2 processes (used to kill them) */
int outfd = 1; /* local output file descriptor */
int cooked; /* non-zero forces cooked mode */
int returns; /* non-zero forces carriage returns not to be filtered out */
int crtonl; /* non-zero forces carriage returns to be converted to nls coming from net */
int strip; /* strip off parity bits */
char firsterr[2*ERRMAX];
char transerr[2*ERRMAX];
int limited;
char *remuser; /* for BSD rlogin authentication */
int verbose;
int baud;
int notkbd;
int nltocr; /* translate kbd nl to cr and vice versa */
static char *srv;
#define MAXMSG (2*8192)
int dodial(char*, char*, char*);
void fromkbd(int);
void fromnet(int);
long iread(int, void*, int);
long iwrite(int, void*, int);
int menu(int);
void notifyf(void*, char*);
void pass(int, int, int);
void rawoff(void);
void rawon(void);
void stdcon(int);
char* system(int, char*);
void dosystem(int, char*);
int wasintr(void);
void punt(char*);
char* syserr(void);
void seterr(char*);
/*
* just dial and use as a byte stream with remote echo
*/
void
simple(char *dest, char *cmd)
{
int net;
net = dodial(dest, 0, 0);
if(net < 0)
return;
if(cmd)
dosystem(net, cmd);
if(!cooked)
rawon();
stdcon(net);
exits(0);
}
/*
* dial, do UCB authentication, use as a byte stream with local echo
*
* return if dial failed
*/
void
rlogin(char *dest, char *cmd)
{
int net;
char buf[128];
char *p;
char *localuser;
/* only useful on TCP */
if(strchr(dest, '!')
&& (strncmp(dest, "tcp!", 4)!=0 && strncmp(dest, "net!", 4)!=0))
return;
net = dodial(dest, "tcp", "login");
if(net < 0)
return;
/*
* the real work. two processes pass bytes back and forth between the
* terminal and the network.
*/
void
stdcon(int net)
{
int netpid;
int p[2];
char *svc;
svc = nil;
if (srv) {
if(pipe(p) < 0)
sysfatal("pipe: %r");
if (srv[0] != '/')
svc = smprint("/srv/%s", srv);
else
svc = srv;
post(svc, p[0]);
close(p[0]);
dup(p[1], 0);
dup(p[1], 1);
/* pipe is now std in & out */
}
ttypid = getpid();
switch(netpid = rfork(RFMEM|RFPROC)){
case -1:
perror("con");
exits("fork");
case 0:
notify(notifyf);
fromnet(net);
if (svc)
remove(svc);
postnote(PNPROC, ttypid, "die yankee dog");
exits(0);
default:
notify(notifyf);
fromkbd(net);
if (svc)
remove(svc);
if(notkbd)
for(;;)
sleep(0);
postnote(PNPROC, netpid, "die yankee dog");
exits(0);
}
}
/*
* Read the keyboard and write it to the network. '^\' gets us into
* the menu.
*/
void
fromkbd(int net)
{
long n;
char buf[MAXMSG];
char *p, *ep;
int eofs;
/*
* Read from the network and write to the screen.
* Filter out spurious carriage returns.
*/
void
fromnet(int net)
{
long n;
char buf[MAXMSG];
char *cp, *ep;
p = system(fd, cmd);
if(p){
print("con: %s terminated with %s\n", cmd, p);
exits(p);
}
}
/*
* run a command with the network connection as standard IO
*/
char *
system(int fd, char *cmd)
{
int pid;
int p;
static Waitmsg msg;
int pfd[2];
int n;
char buf[4096];