home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
convergent.tar.gz
/
convergent.tar
/
ctlogi.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-20
|
12KB
|
435 lines
char *loginv = "Script login CTOS Version-2.00, Apr 1992";
/* C K L O G I -- Login script for logging onto remote system */
/*
The module expects a login string of the expect send [expect send] ...
format. It is intended to operate similarly to the way the common
uucp "L.sys" login entries work. Conditional responses are supported
expect[-send-expect[...]] as with uucp. The send keyword EOT sends a
control-d, and the keyword BREAK sends a break. Letters prefixed
by '~' are '~b' backspace, '~s' space, '~n' linefeed, '~r' return,
'~t' tab, '~q' ? (not allowed on kermit command lines), '~' ~, '~'',
'~"', '~c' don't append return, '~o[o[o]]' octal character. As with
some uucp systems, sent strings are followed by ~r (not ~n) unless they
end with ~c. Null expect strings (e.g., ~0 or --) cause a short
delay, and are useful for sending sequences requiring slight pauses.
Author: Herm Fischer, Litton Data Systems, Van Nuys CA (HFISCHER@USC-ECLB)
*/
/* modified for CTOS C2.0 by Joel Dunn, UNC-CH, October 1986 */
/* modified to implement MS-DOS like INPUT, REINPUT, and OUTPUT */
/* commands. INPUT looks for a string of up to 7 bytes */
/* coming from the current line. OUTPUT puts a string */
/* out to the current line. numerics up to 65535 that */
/* are preceeded by "//" are converted to their ASCII */
/* character equivalent. Numerics of greater than 65535 */
/* are sent verbatum. */
/* D. Drury, E. Arnerich - ITT Federal Services 7/91 */
/* Modified RecvSeq to send exp_alrm value to use exp_alrm */
/* value instead of 1 second for inter-character */
/* timeout value. */
/* D. Drury, E. Arnerich - ITT Federal Services 4/92 */
#include "ctermi.h"
extern int local, speed, flow, seslog, mdmtyp, techo, tlevel;
extern char ttname[];
static char * chstr();
int exp_alrm = 30; /* Time to wait for expect string */
#define NULL_EXP 2 /* Time to pause on null expect strg*/
/* changed from 5 to 2, was 1 in Unix source, this change was 1.01 */
#define SBUFL 300 /* Login Sequence buffer */
static char seq_buf[SBUFL], *s;
static char savinput[SBUFL];
static int got_it, no_cr;
/*
Sequence interpreter -- pick up next sequence from command string,
decode escapes and place into seq_buf
*/
static
sequenc() {
int i;
char c, oct_char;
no_cr = 0; /* output needs cr appended */
for (i=0; i<SBUFL; ) {
if (*s == '\0' || *s == '-' || *s == ' ') { /* done */
seq_buf[i] = '\0';
return ;
}
if (*s == '~') { /* escape character */
switch (c = *(++s) ) {
case 'n': seq_buf[i++] = '\n'; break;
case 'r': seq_buf[i++] = '\r'; break;
case 't': seq_buf[i++] = '\t'; break;
case 'b': seq_buf[i++] = '\b'; break;
case 'q': seq_buf[i++] = '?'; break;
case '~': seq_buf[i++] = '~'; break;
case '\'': seq_buf[i++] = '\''; break;
case '\"': seq_buf[i++] = '\"'; break;
case 's': seq_buf[i++] = ' '; break;
case 'c': no_cr = 1; break;
default:
if ( isdigit(c) ) { /* octal character */
oct_char = (c & 7); /* most significant digit */
if (isdigit( *(s+1) ) ) {
oct_char = (oct_char<<3) | ( (*(++s)) & 7 ) ;
if (isdigit( *(s+1) ) ) {
oct_char = (oct_char<<3) | ( (*(++s)) & 7 ) ;
}
}
seq_buf[i++] = oct_char;
break;
}
}
}
else seq_buf[i++] = *s; /* plain old character */
s++;
}
seq_buf[i] = '\0';
return; /* end of space, return anyway */
}
/*
Receive sequence -- see if expected response comes return success
(or failure) in got_it
*/
static
recvSeq() {
char *e, got[7], trace[SBUFL];
int i, l;
int exchwait;
int timerexit;
struct ctostimer trb1;
struct ctostimer *ptrb1;
int cterc;
l = strlen(e=seq_buf); /* no more than 7 chars allowed */
if (l > 7) {
e += l-7;
l = 7;
}
tlog(F111,"expecting sequence",e,(long) l);
if (l == 0) { /* null sequence, just delay a little */
delay (NULL_EXP*10);
got_it = 1;
tlog(F100,"got it (null sequence)","",0l);
return;
}
*trace = '\0';
for (i=0; i<7; i++) got[i]='\0';
timerexit = 0;
allocexch(&exchwait);
trb1.ctt_counter = 10*exp_alrm;
trb1.ctt_reload = 0;
trb1.ctt_cevents = 0;
trb1.ctt_exchresp = exchwait;
trb1.ctt_ercret = 0;
trb1.ctt_rqcode = exchwait;
openrtclock(&trb1);
while ((!got_it) && (!timerexit))
{
for (i=0; i<(l-1); i++) got[i] = got[i+1]; /* shift over one */
got[l-1] = ttinc(1) & 0177;
while (got[l-1] == 023) /* ignore ctl-s */
got[l-1] = ttinc(exp_alrm) & 0177; /* next char */
if (strlen(trace) < sizeof(trace)-2 )
strcat(trace,chstr(got[l-1]));
got_it = (!strncmp(seq_buf, got, l) ) ;
if (!check(exchwait, &ptrb1))
{
if (ptrb1->ctt_rqcode == exchwait)
{
timerexit = 1;
got_it = 0;
}
}
}
deallocexch(exchwait);
closertclock(&trb1);
for(i=0; i<SBUFL && trace[i] != '\0'; i++) /* save what we got */
savinput[i] = trace[i]; /* regardless of success or failure */
if (i == SBUFL) i--;
savinput[i] = '\0'; /* make sure its null terminated */
tlog(F110,"received sequence: ",trace,0l);
tlog(F101,"returning with got-it code","",(long) got_it);
return;
}
/*
Output A Sequence starting at pointer s,
return 0 if okay,
1 if failed to read (modem hangup or whatever)
*/
static int
outSeq() {
char *sb;
int l;
l = strlen(seq_buf);
tlog(F111,"sending sequence ",seq_buf,(long) l);
if (!strcmp(seq_buf,"EOT")) ttoc(dopar('\004'));
else if (!strcmp(seq_buf,"BREAK")) ttsndb();
else {
if (l > 0) {
for ( sb=seq_buf; *sb; sb++) *sb = dopar(*sb);
ttol(seq_buf,l); /* with parity */
}
if (!no_cr) ttoc( dopar('\r') );
}
return(0);
}
/* L O G I N -- Process script to login or send commands remote system */
login(cmdstr) char *cmdstr; {
char *e;
int x;
s = cmdstr; /* make global to cklogi.c */
tlog(F100,loginv,"",0l);
x = initline();
if (x != 0) return(x); /* return error if initline failed */
if((tlevel < 0) || techo)
printf("Logging on thru %s, speed %d.\r\n",ttname,speed);
*seq_buf=0;
for (e=s; *e; e++) strcat(seq_buf, chstr(*e) );
if ((tlevel < 0) || techo)
printf("The script string is: %s\r\n",seq_buf);
tlog(F110,"Script command string: ",seq_buf, 0l);
/* start expect - send sequence */
while (*s) { /* while not done with buffer */
while (*s && *s == ' ') s++; /* skip over separating blanks */
/* gather up expect sequence */
got_it = 0;
sequenc();
recvSeq();
while (!got_it) {
/* no, is there a conditional send */
if (*s++ != '-') goto failRet; /* no -- return failure */
/* start of conditional send */
ttflui(); /* flush out input buffer */
sequenc();
if (outSeq()) goto failRet; /* if unable to send! */
if (*s++ != '-') goto failRet; /* must have condit respon.*/
sequenc();
recvSeq();
} /* loop back and check got_it */
while (*s && *s++ != ' ') ; /* skip over conditionals and spaces */
ttflui(); /* Flush */
if (*s) {
sequenc();
if (outSeq()) goto failRet; /* if any */
}
}
if ((tlevel < 0) || techo)
printf("Script successful!\r\n");
tlog(F100,"Script successful!","",0l);
return(0);
failRet:
if ((tlevel < 0) || techo)
printf("Sorry, script failed\r\n");
tlog(F100,"Script failed","",0l);
return(-2);
}
/* C H S T R -- Make printable string from a character */
static char *
chstr(c) char c; {
static char sc[4];
if (c < SP) sprintf(sc, "^%c",ctl(c) );
else sprintf(sc, "%c", c);
return(sc);
}
/* I N I T L I N E -- initializes the line for login/input/output */
/* return 0 if successful otherwise return -2 */
initline() {
if (!local) {
printf("Sorry, you must 'set line' first\n");
return(-2);
}
if (speed < 0) {
printf("Sorry, you must 'set speed' first\n");
return(-2);
}
if (ttopen(ttname,local,mdmtyp) < 0) {
sprintf(seq_buf,"Sorry, can't open %s",ttname);
perror(seq_buf);
return(-2);
}
/* Condition console terminal and communication line */
if (ttvt(speed,flow) < 0) {
printf("Sorry, Can't condition communication line\n");
return(-2);
}
/* ttflui(); flush stale input */
return (0);
}
/* D O I N P U T -- UNIX/DOS like input command */
/* the maximum input string length is 7 */
doinput (cmdstr, timeout) char *cmdstr; int timeout;
{
int x;
char *e;
s = cmdstr;
if (!local) {
printf("Sorry, you must 'set line' first\n");
return(-2);
}
if (speed < 0) {
printf("Sorry, you must 'set speed' first\n");
return(-2);
}
/* x = initline();
if(x != 0) return(x); */
*seq_buf = 0;
for (e = s; *e; e++)
strcat(seq_buf, chstr(*e));
exp_alrm = timeout;
got_it = 0;
recvSeq();
if (got_it == 0) return(-2); /* return failure if not found */
return(0); /* otherwise return success */
}
/* D O R E I N P U T -- UNIX/DOS like reinput */
/* not timeout value is used or required */
dorinput(cmdstr) char *cmdstr;
{
int rc = -2; /* init result code to not found */
int i, len;
char *start;
s = cmdstr;
while (*s != ' ') /* get to spaces */
s++;
while (*s == ' ') /* get past spaces */
s++;
len = strlen(s);
start = savinput;
for(i = 0; i < SBUFL && (savinput[i] != '\0') && rc; i++) {
if (!strncmp(s, start, len))
rc = 0; /* found it! */
start++;
}
tlog(F110,"reinput searching for: ",s,0l);
tlog(F110,"received sequence: ",savinput,0l);
tlog(F101,"returning with result code","",(long) rc);
return(rc); /* return result code */
}
/* D O O U T P U T -- UNIX/DOS like output command */
/* looks for '\', and if found processes following numerics as decimal */
/* to be converted to ASCII characters, then outputs the total length */
/* of the input buffer - including any NULLs which may be generated by */
/* converting the numeric to ASCII. This routine does not add cr */
/* The maximum decimal value processed is 65535. Anything larger is */
/* put out as a character string */
dooutput(cmdstr) char *cmdstr;
{
#define MAX_VALUE 65535L
int x, y, len;
char e, *digitpos;
unsigned long numbr;
int j;
numbr = 0;
s = cmdstr;
if (!local) {
printf("Sorry, you must 'set line' first\n");
return(-2);
}
if (speed < 0) {
printf("Sorry, you must 'set speed' first\n");
return(-2);
}
x = initline();
if (x != 0) return(-2);
*seq_buf = 0;
len = strlen(s);
x = 0;
seq_buf[x] = '\0';
while (*s) {
digitpos = s;
digitpos++;
if (*s == '\\' && isdigit(*digitpos)) { /* quoted sequence? */
numbr = 0;
while (1) {
e = *digitpos;
if (isdigit(e)) {
j = e & 0x0f;
numbr = numbr*10 + (unsigned long) j;
digitpos++;
}
else
break; /* exit while, on first non-digit */
}
if (numbr <= MAX_VALUE) { /* now that its a num make it str */
seq_buf[x++] = (numbr & 0xff); /* get low order first */
/* followed by high order byte if high order byte > 0 */
if (numbr > 256)
seq_buf[x++] = (numbr >> 8);
s = digitpos;
continue;
}
}
seq_buf[x++] = *s++;
}
/* now put all x bytes out */
tlog(F111, "sending output ", seq_buf, (long) x);
if (x > 0) {
for (y=0; y<x; y++) seq_buf[y] = dopar(seq_buf[y]);
ttol(seq_buf,x);
}
return(0);
}