home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
High Voltage Shareware
/
high1.zip
/
high1
/
DIR3
/
KA9Q212.ZIP
/
RLOGIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-16
|
11KB
|
496 lines
/****************************************************************************
* $Id: rlogin.c 1.8 93/07/16 11:49:47 ROOT_DOS Exp $
* 24 Oct 92 1.1 GT Add ZMODEM. *
* 17 Jan 93 1.2 GT Don't delete first 4 characters from remote. *
* Fix XMODEM download prompt. *
* 30 Jan 93 1.3 GT Fix background file transfers. *
* 07 Feb 93 1.4 GT Re-enable ZMODEM upload. *
* 20 Feb 93 1.5 GT Debugging Tx again. *
* 21 Feb 93 1.6 GT And again. *
* 22 Feb 93 1.7 GT Only allow one file transfer at a time. *
* 08 May 93 1.8 GT Fix warnings. *
****************************************************************************/
#include <stdio.h>
#include <ctype.h>
#include "global.h"
#include "mbuf.h"
#include "socket.h"
#include "session.h"
#include "proc.h"
#include "tty.h"
#include "commands.h"
#include "netuser.h"
#include "sz.h"
#if 0
static char *username = "guest";
#endif
static char terminal[] = "vt102";
static char *termspeed = "/38400";
static char logname[16];
extern FILE *Rawterm;
int rlo_connect __ARGS ((struct session * sp, char *fsocket, int len));
void rlo_output __ARGS ((int unused, void *p1, void *p2));
void rlrecv __ARGS ((struct session * sp));
static int dorwhatever __ARGS ((int argc, char *argv[], void *p));
static void file_xfer __ARGS ((int s, int direction, struct session * sp));
#if 0
static void reporter __ARGS ((int type, void *data));
#endif
#if 0
static char recv_ok; /* nz - ok to run receive */
#endif
/* Execute user rsh command */
int dorsh (argc, argv, p)
int argc;
char *argv[];
void *p;
{
return 0;
}
/* Execute user rlogin command */
int dorlogin (argc, argv, p)
int argc;
char *argv[];
void *p;
{
return dorwhatever (argc, argv, p);
}
/* Execute some sort of r command */
static int dorwhatever (argc, argv, p)
int argc;
char *argv[];
void *p;
{
struct session *sp;
struct sockaddr_in fsocket;
struct sockaddr_in lsocket;
/* Make sure this comes from console - WG7J */
if (Curproc->input != Command->input)
return 0;
/* Allocate a session descriptor */
if ((sp = newsession (argv[1], RLOGIN)) == NULLSESSION)
{
tputs ("Too many sessions");
return 1;
}
fsocket.sin_family = AF_INET;
if (argc < 3)
fsocket.sin_port = IPPORT_RLOGIN;
else
fsocket.sin_port = atoi (argv[2]);
tprintf ("Resolving %s... ", sp->name);
if ((fsocket.sin_addr.s_addr = resolve (sp->name)) == 0L)
{
tprintf (Badhost, sp->name);
keywait (NULLCHAR, 1);
freesession (sp);
return 1;
}
if ((sp->s = socket (AF_INET, SOCK_STREAM, 0)) == -1)
{
tputs ("No Socket");
keywait (NULLCHAR, 1);
freesession (sp);
return 1;
}
lsocket.sin_family = AF_INET;
lsocket.sin_addr.s_addr = INADDR_ANY;
lsocket.sin_port = IPPORT_RLOGIN;
bind (sp->s, (char *) &lsocket, sizeof (lsocket));
return rlo_connect (sp, (char *) &fsocket, SOCKSIZE);
}
/* Generic interactive connect routine */
int rlo_connect (sp, fsocket, len)
struct session *sp;
char *fsocket;
int len;
{
unsigned int index;
index = (unsigned int) (sp - Sessions);
sockmode (sp->s, SOCK_ASCII);
tprintf ("Trying %s...\n", psocket ((struct sockaddr *) fsocket));
if (connect (sp->s, fsocket, len) == -1)
{
tprintf ("%s session %u failed: %s errno %d\n",
Sestypes[sp->type], index, sockerr (sp->s), errno);
keywait (NULLCHAR, 1);
freesession (sp);
return 1;
}
tprintf ("%s session ", Sestypes[sp->type]);
tprintf ("%u connected to %s\n", index, sp->name);
rlrecv (sp);
return 0;
}
/* Rlogin input routine, common to both rlogin and ttylink */
void rlrecv (sp)
struct session *sp;
{
int c, s, index;
char *cp;
s = sp->s;
/* Get the login name. */
tprintf ("login: ");
recvline (sp->input, logname, sizeof (logname));
*(logname + strlen (logname) - 1) = '\0'; /* delete \n */
/* We run both the network and local sockets in transparent mode
* because we have to do our own eol mapping */
seteol (s, "");
seteol (Curproc->input, "");
seteol (Curproc->output, "");
/* Read real keystrokes from the keyboard */
sp->ttystate.crnl = 0;
/* Put tty into raw mode */
sp->ttystate.echo = 0;
sp->ttystate.edit = 0;
setflush (s, '\n');
index = (int) (sp - Sessions);
/* Fork off the transmit process */
#if 0
recv_ok = 1;
#endif
sp->proc1 = newproc ("rlo_out", 2048, rlo_output, 0, sp, NULL, 0);
#if 0
for (c = 0; c < 4; c++)
(void) recvchar (s); /* get response */
#endif
/* Process input on the connection */
while ((c = recvchar (s)) != -1)
{
if (c == '\r' || c == '\n')
{
seteol (Curproc->output, "\r\n");
tputc ((char) c);
seteol (Curproc->output, "");
}
else
{
tputc ((char) c);
}
}
#if 0
for (;;)
{
if (recv_ok == 0)
pwait (&recv_ok); /* suspended */
if (socklen (s, 0) == 0)
{
pwait (NULL); /* nothing to do */
continue;
}
if ((c = recvchar (s)) == -1)
break; /* socket failed */
if (c == '\r' || c == '\n')
{
seteol (Curproc->output, "\r\n");
tputc ((char) c);
seteol (Curproc->output, "");
}
else
{
tputc ((char) c);
}
} /* for (;;) */
#endif
quit: /* A close was received from
* the remote host. Notify
* the user, kill the output
* task and wait for a
* response from the user
* before freeing the
* session. */
cp = sockerr (s);
seteol (s, "\r\n");
seteol (Curproc->input, "\r\n");
seteol (Curproc->output, "\r\n");
tprintf ("%s session %u", Sestypes[sp->type], index);
tprintf (" closed: %s\n", cp != NULLCHAR ? cp : "EOF");
killproc (sp->proc1);
sp->proc1 = NULLPROC;
close_s (sp->s);
sp->s = -1;
keywait (NULLCHAR, 1);
freesession (sp);
}
/* User rlogin output task, started by user rlogin command */
void rlo_output (unused, sp1, p)
int unused;
void *sp1;
void *p;
{
struct session *sp;
struct mbuf *bp;
char *cp;
int c;
sp = (struct session *) sp1;
#if 0
logname = getenv ("USER");
if (logname == NULLCHAR)
logname = username;
#endif
bp = ambufw (1 + strlen (logname) + 1 + strlen (logname) + 1 +
strlen (terminal) + strlen (termspeed) + 1);
cp = bp->data;
*cp++ = '\0';
strcpy (cp, logname);
cp += strlen (logname) + 1;
strcpy (cp, logname);
cp += strlen (logname) + 1;
strcpy (cp, terminal);
cp += strlen (terminal);
strcpy (cp, termspeed);
cp += strlen (termspeed) + 1;
bp->cnt = cp - bp->data;
if (send_mbuf (sp->s, bp, 0, NULLCHAR, 0) != -1)
{
/* Send whatever's typed on the terminal */
#if 0
while (recv_mbuf (sp->input, &bp, 0, NULLCHAR, 0) > 0)
{
if (send_mbuf (sp->s, bp, 0, NULLCHAR, 0) == -1)
break;
}
#endif
while ((c = recvchar (sp->input)) != EOF)
{
/* Check for escape. */
if (c == '~')
{
c = recvchar (sp->input);
if (c == EOF)
break;
switch (c)
{
case 'u':
case 'd':
file_xfer (sp->s, c, sp); /* do [XYZ]MODEM */
continue;
}
} /* if (c == '~') */
/* Send the data. */
usputc (sp->s, (char) c);
usflush (sp->s);
} /* while ((c = recvchar (sp->input)) != EOF) */
}
/* Make sure our parent doesn't try to kill us after we exit */
sp->proc1 = NULLPROC;
}
/****************************************************************************
* file_xfer *
* Do an [XYZ]MODEM file transfer. *
****************************************************************************/
static void file_xfer (s, direction, sp)
int s;
int direction;
struct session *sp;
{
char buf[65]; /* input buffer */
int protocol; /* protocol (X, Y, Z) */
char *filenames[2]; /* list of file names */
#if 0
int oldmode; /* old socket mode */
int oldflush; /* old flush character */
#endif
char *rcv_opts = "bvv"; /* file transfer options */
char *send_opts = "bvv";
static int xferring = 0; /* nz - transfer running */
/* Suspend the receive process. */
sp->ttystate.crnl = 1;
sp->ttystate.echo = 1;
sp->ttystate.edit = 1;
seteol (Curproc->input, "\r\n");
seteol (Curproc->output, "\r\n");
/* See if we are already doing a file transfer. */
if (xferring != 0)
{
tprintf ("Sorry - only one file transfer at a time\n");
sp->ttystate.crnl = 0;
sp->ttystate.echo = 0;
sp->ttystate.edit = 0;
seteol (Curproc->input, "");
seteol (Curproc->output, "");
return;
}
xferring = 1;
suspend (sp->proc);
/* Get the protocol type. */
do
{
tprintf ("\nProtocol (XYZ): ");
recvline (sp->input, buf, sizeof (buf));
protocol = tolower (*buf);
} while (protocol != 'x' && protocol != 'y' && protocol != 'z');
/* Get the file path if required. */
if (protocol == 'x' || direction == 'u')
{
tprintf ("File path: ");
recvline (sp->input, buf, sizeof (buf));
*(buf + strlen (buf) - 1) = '\0';
}
/* Do the transfer. */
filenames[0] = buf;
filenames[1] = "";
if (direction == 'u')
(void) _sendfile (s, protocol, send_opts, filenames, NULL);
else
{
if (protocol == 'x')
(void) _getfile (s, protocol, rcv_opts, filenames[0], NULL);
else
(void) _getfile (s, protocol, rcv_opts, NULL, NULL);
}
/* Restart the receive process. */
usflush (s);
/* Reset raw mode. */
sp->ttystate.crnl = 0;
sp->ttystate.echo = 0;
sp->ttystate.edit = 0;
seteol (Curproc->input, "");
seteol (Curproc->output, "");
xferring = 0;
resume (sp->proc);
pwait (NULL);
}
#if 0
/****************************************************************************
* reporter *
* Do report functions for ZMODEM. *
****************************************************************************/
static void reporter (type, data)
int type;
void *data;
{
#if 0
#if 0
Current->ttystate.echo = 1;
Current->ttystate.crnl = 1;
Current->ttystate.edit = 1;
#endif
switch (type)
{
case 0: /* filename */
tprintf ("FILE: %s", (char *) data);
break;
case 1: /* transfer count */
tprintf ("\r%7ld", *((long *) data));
break;
case 2: /* other text */
seteol (Curproc->output, "\r\n");
tprintf ("\n%s", (char *) data);
seteol (Curproc->output, "");
break;
case 3: /* end of transfer */
seteol (Curproc->output, "\r\n");
tprintf ("\n%7d files transferred.\n", *((int *) data));
seteol (Curproc->output, "");
break;
default:
seteol (Curproc->output, "\r\n");
tprintf ("\nreporter: unknown type %d\n", type);
seteol (Curproc->output, "");
break;
} /* switch (type) */
usflush (Curproc->output);
#if 0
Current->ttystate.echo = 0;
Current->ttystate.crnl = 0;
Current->ttystate.edit = 0;
#endif
#endif
} /* static void reporter (int type, void *data) */
#endif