home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
300-399
/
ff319.lzh
/
CNewsSrc
/
uupc.lzh
/
uupc
/
dcpsys.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-01-16
|
19KB
|
876 lines
/*
* dcpsys.c
*
* Revised edition of dcp
*
* Stuart Lynne May/87
*
* Copyright (c) Richard H. Lamb 1985, 1986, 1987
* Changes Copyright (c) Stuart Lynne 1987
*
* $Id: dcpsys.c,v 1.4 90/01/16 10:25:14 crash Exp Locker: crash $
*/
#ifndef lint
static char RCSid[] = "$Id: dcpsys.c,v 1.4 90/01/16 10:25:14 crash Exp Locker: crash $";
#endif /* lint */
/*
* "DCP" a uucp clone. Copyright Richard H. Lamb 1985,1986,1987
* Get the next system, and other support routines
*/
#include "dcp.h"
#ifdef AMIGA
# include <libraries/dos.h> /* For TICKS_PER_SECOND */
#endif
/*#define PROTOS "trkg"*/
#define PROTOS "g"
#define MAXLOGTRY 3
Proto Protolst[] = {
'g', ggetpkt, gsendpkt, gopenpk, gclosepk,
#if 0
'k', kgetpkt, ksendpkt, kopenpk, kclosepk,
'r', rgetpkt, rsendpkt, ropenpk, rclosepk,
't', tgetpkt, tsendpkt, topenpk, tclosepk,
#endif
'0'};
#define EOTMSG "\004\r\004\r"
procref getpkt, sendpkt, openpk, closepk;
#ifdef FJE
#define MAXSYS 20
static short sys_cnt = 0;
static char sys_name[MAXSYS][8];
already_called(name)
char *name;
{
register int i;
for (i=sys_cnt; i-- > 0; )
if (strncmp(sys_name[i], name, 8) == SAME) return( TRUE );
return( FALSE );
}
#endif /* FJE */
/*
* getsystem
* Process an "systems" file entry (like "Systems")
*/
getsystem()
{
int i;
extern int filecount; /* From dcpxfer.c */
#ifdef FJE
do {
if ( fgets( sysline, BUFSIZ, fsys ) == (char *)NULL )
return( 'A' );
} while (*sysline == '#' || isspace(*sysline));
#else /* !FJE */
if ( fgets( sysline, BUFSIZ, fsys ) == (char *)NULL )
return( 'A' );
#endif /* FJE */
printmsg( 4, "%s", sysline );
filecount = 0;
kflds = getargs( sysline, flds );
strncpy( rmtname, flds[FLD_REMOTE], 8 ); /* boake2 */
rmtname[8] = '\0';
cctime = flds[FLD_CCTIME]; /* Any */
strcpy( device, flds[FLD_DEVICE] ); /* SER: */
#if 0
strcpy( type, flds[FLD_TYPE] ); /* DIR */
#endif
strcpy( speed, flds[FLD_SPEED] ); /* 2400 or phone# */
strcpy( proto, flds[FLD_PROTO] ); /* g */
if (debuglevel > 4)
for (i = FLD_EXPECT; i < kflds; i += 2)
fprintf( stderr, "expect[%02d]:\t%s\nsend [%02d]:\t%s\n",
i, flds[i], i+1, flds[i+1] );
printmsg( 2, "remote = %s, call time = %s", rmtname, cctime );
printmsg( 2, "device = %s ", device );
printmsg( 2, "speed = %s, protocol = %s", speed, proto );
fw = (FILE *)NULL;
if (
(checktime( cctime )) || /* Any time is okay */
( strcmp( Rmtname, "all" ) == SAME ) ||
( strcmp( Rmtname, rmtname ) == SAME ) ||
( (strcmp( Rmtname, "any" ) == SAME) && scandir() == 'S' )
) {
if ( fw != (FILE *)NULL )
fclose( fw ); /* in case we matched with scandir */
#ifdef FJE
if ( already_called( rmtname ) )
return( 'G' );
/*
* Keep track of the systems we have called so far;
* there's no need to call'em twice...
*/
if (sys_cnt < MAXSYS) {
strncpy(sys_name[sys_cnt], rmtname, 8);
sys_name[sys_cnt++][8] = '\0';
}
#endif
return( 'S' ); /* startup this system */
} else
return('G');
}
/*
* checkname
* Do we know the guy ?
*/
checkname(name)
char name[];
{
FILE *ff;
char line[BUFSIZ], tmp[20]; /* can change to 8 if %8s works */
if ( ( ff = FOPEN( s_systems, "r", 't' )) == (char *)NULL )
return( FAILED );
while ( fgets( line, BUFSIZ, ff ) != (char *)NULL ){
#ifdef FJE
if (*line == '#' || isspace(*line))
continue;
#endif /* FJE */
sscanf( line, "%8s ", tmp );
printmsg( 3, "wanted = %s, found = %s", name, tmp );
if ( strncmp( tmp, line, 7 ) == SAME ) {
fclose( ff );
return ( OK ); /* OK, I like you */
}
}
fclose( ff );
return( FAILED ); /* Who are you? */
}
/*
* checktime
* check if we may make a call at this time
* ------------> to be implemented. Again. Didn't think it crucial
*/
checktime(xtime)
char xtime[];
{
return(0); /* OK, go to it */
}
/*
* sysend
* end UUCP session negotiation
*/
sysend()
{
char msg[80];
msg[1] = '\0';
msgtime = 2 * MSGTIME;
wmsg("OOOOOO", 2);
closeline();
if ( remote == MASTER )
return('I');
return('A');
}
#if 0
/*
* delay
*/
ddelay(dtime)
int dtime;
{
int i, j;
for (i = 0; i < dtime; )
i++;
}
#endif
/*
* wmsg
* write a ^P type msg to the remote uucp
*/
wmsg(msg, syn)
int syn;
char msg[];
{
int len;
len = strlen(msg);
if (syn == 2)
swrite("\0\020", 2);
swrite(msg, len);
if (syn == 2)
swrite("\0", 1);
}
/*
* rmsg
* read a ^P msg from UUCP
*/
rmsg(msg, syn)
int syn;
char msg[];
{
int ii;
char c, cc[5];
c = 'a';
if (syn == 2) {
while ((c & 0x7f) != '\020') {
if (sread(cc, 1, msgtime) < 1)
return(-1);
/* Don't ask. MSC needs more than a byte to breathe */
c = cc[0];
}
}
for (ii = 0; ii < 132 && c ; ii++) {
if (sread(cc, 1, msgtime) < 1)
return(-1);
c = cc[0] & 0x7f;
if (c == '\r' || c == '\n')
c = '\0';
msg[ii] = c;
}
return(strlen(msg));
}
/*
* startup
*/
startup()
{
char msg[80], tmp1[20], tmp2[20];
if ( remote == MASTER ) {
msgtime = 2 * MSGTIME;
if (rmsg(msg, 2) == -1)
return('Y');
printmsg( 2, "1st msg = %s", msg );
if (msg[5] == '=' && strncmp(&msg[6], rmtname, 7))
return('Y');
#if 0
/* -Q0 -x16 remote debuglevel set */
sprintf(msg, "S%.7s -Q0 -x%d", nodename, debuglevel);
#else
sprintf(msg, "S%.7s", nodename);
#endif
wmsg(msg, 2);
if (rmsg(msg, 2) == -1)
return('Y');
printmsg( 2, "2nd msg = %s", msg );
if (strncmp(&msg[1], "OK", 2))
return('Y');
if (rmsg(msg, 2) == -1)
return('Y');
printmsg( 2, "3rd msg = %s", msg );
/*
* [FJE] Protocol negotiation right here...
* Note the "index(..., proto[0])" would become a search
* through a list of protocols, looking for the first
* which matched, in order of most efficient (?). Here,
* "proto" comes from the Systems file...
*/
if (msg[0] != 'P' || index(&msg[1], proto[0]) == (char *)NULL) {
wmsg("UN", 2);
return('Y');
}
sprintf(msg, "U%c", proto[0]);
wmsg(msg, 2);
setproto(proto[0]);
return('D');
} else {
msgtime = 2 * MSGTIME;
sprintf(msg, "Shere=%s", nodename);
wmsg(msg, 2);
if (rmsg(msg, 2) == -1)
return('Y');
sscanf(&msg[1], "%s %s %s", rmtname, tmp1, tmp2);
sscanf(tmp2, "-x%d", &debuglevel);
printmsg( 1, "debug level from remote = %d", debuglevel );
printmsg( 2, "1st msg from remote = %s", msg );
if (checkname(rmtname))
return('Y');
wmsg("ROK", 2);
sprintf(msg, "P%s", PROTOS);
wmsg(msg, 2);
if (rmsg(msg, 2) == -1)
return('Y');
if (msg[0] != 'U' || index(PROTOS, msg[1]) == (char *)NULL )
return('Y');
proto[0] = msg[1];
setproto(proto[0]);
return('R');
}
}
/******* set the protocol **********/
setproto(pr)
char pr;
{
int i;
Proto *tproto;
for (tproto = Protolst;
tproto->type != '\0' && pr != tproto->type;
tproto++)
printmsg( 3, "setproto: %c %c", pr, tproto->type );
if (tproto->type == '\0') {
printmsg( 0,
"setproto: You said I had '%c', but I can't find it", pr );
exit(1);
}
getpkt = tproto->a;
sendpkt = tproto->b;
openpk = tproto->c;
closepk = tproto->d;
}
int prefix(sh, lg)
register char *sh, *lg;
{
sh--;
while (*++sh && (*sh == *lg++))
;
return( !*sh );
}
int notin(sh, lg)
char *sh, *lg;
{
while (*lg) {
if (prefix(sh, lg++))
return( FALSE );
}
return( TRUE );
}
#define MAXR 300
unsigned int g_timeout = 30;
static char rdvec[MAXR];
int expectstr( str, timeout )
char *str;
int timeout;
{
char *rp = rdvec;
int kr;
char nextch;
printmsg( 2, "wanted :%s:", prt(str, strlen(str)) );
*rp = 0;
if ( strcmp(str, "\"\"") == SAME )
return( TRUE );
while ( notin( str, rdvec ) ) {
kr = sread( &nextch, 1, timeout /* 40 */ );
if (kr <= 0) {
printmsg( 4, "read :%s:", prt(rdvec, rp-rdvec));
return( FALSE );
}
if (*rp = (nextch & 0177))
*++rp = '\0';
if (rp >= rdvec + MAXR) {
printmsg( 4, "read :%s:", prt(rdvec, rp-rdvec));
return( FALSE );
}
}
printmsg( 3, "read :%s:", prt(rdvec, rp-rdvec));
return( TRUE );
}
int writestr(s)
register char *s;
{
register char last;
register char * m;
int nocr;
last = '\0';
nocr = FALSE;
printmsg( 6, "writing <%s>", prt(s, strlen(s)));
while (*s) {
if (last == '\\') {
switch (*s) {
case 'p': /* 1/2 second pause */
case 'P':
ticks( (long) TICKS_PER_SECOND >> 1 );
break;
case 'd':
case 'D': /* delay */
sleep(2);
break;
case 'k': /* Break signal */
case 'K':
ssendbrk(3);
break;
case 'c':
case 'C': /* end string don't output CR */
nocr = TRUE;
break;
case 'r':
case 'R': /* carriage return */
case 'm':
case 'M':
swrite( "\r", 1 );
break;
case 'n':
case 'N': /* newline */
swrite( "\n", 1 );
break;
case 'b':
case 'B': /* backspace */
swrite( "\b", 1 );
break;
case 't':
case 'T': /* tab */
swrite( "\t", 1 );
break;
case 's':
case 'S': /* space */
swrite( " ", 1 );
break;
case 'w': /* Set the delay time for expect strings */
case 'W': /* up to 120 seconds (2 minutes) */
g_timeout = 0;
for (s++; isdigit(*s); )
g_timeout = g_timeout*10 + (*s++ - '0');
if (g_timeout > 120)
g_timeout = 30;
s--;
break;
case 'z': /* Set the baud rate... */
case 'Z':
SIOSpeed( ++s );
while ( *s != '\0' && *s != '\\' )
s++;
if ( *s == '\\' )
s++;
break;
default:
swrite( s, 1 );
}
last = '\0';
} else if (*s != '\\') {
swrite( s, 1 );
} else
last = *s;
s++;
}
return( nocr );
}
/***
* void sendthem(str) send line of login sequence
* char *str;
*
* return codes: none
*/
void sendstr(str)
char *str;
{
int nw, ns;
long nulls;
printmsg( 2, "sending %s", str );
if (prefix("BREAK", str)) {
sscanf(&str[5], "%1d", &nulls);
if (nulls <= 0 || nulls > 10)
nulls = 3;
/* send break */
ssendbrk(nulls);
return;
}
if ( strcmp(str, "EOT") == SAME ) {
swrite(EOTMSG, strlen(EOTMSG));
return;
}
if ( strcmp(str,"\"\"") == SAME )
*str = '\0';
if ( strcmp(str,"") != SAME ) {
if (!writestr(str))
swrite ("\r", 1);
} else
swrite("\r", 1);
return;
}
int sendexpect( s, e, timeout )
char *s;
char *e;
int timeout;
{
sendstr( s );
return( expectstr( e, timeout ) );
}
dial()
{
int flg, kk, jj, ll, firstflg;
char buf[4], *prsend;
char *exp;
char *alternate;
int ok;
int i;
if ( strcmp( flds[FLD_TYPE], "HAYES" ) != SAME ) {
printmsg( 0, "dial: unsupported dialer %s", flds[FLD_TYPE] );
return( FALSE );
}
printmsg( 3, "calling host %s", rmtname );
if (openline(device, "2400" ))
return( FALSE );
printmsg( 0, "hayes: trying 2400" );
if ( sendexpect( "ATZ", "OK", 2 ) != TRUE ) {
sendexpect( "\\d+++\\d", "OK", 2 );
if ( sendexpect( "ATZ", "OK", 2 ) != TRUE ) {
printmsg( 0, "hayes: trying 1200" );
SIOSpeed( "1200" );
if ( sendexpect( "ATZ", "OK", 2 ) != TRUE ) {
sendexpect( "\\d+++\\d", "OK", 2 );
if ( sendexpect( "ATZ", "OK", 2 ) != TRUE )
return( FALSE);
}
}
}
printmsg( 0, "hayes: got modem response" );
/*
* DO NOT REMOVE THE \d FROM THE LINE BELOW!!!
*
* My SupraModem seemed pretty critical about returning an "OK"
* response but not really being interested in user commands for
* another second or so. And since \d is about 2 seconds...
*/
sendexpect( "ATX4\\r\\d", "OK\n\r", 2 );
printmsg( 4, "attempting to dial :%s:", speed );
#ifdef FJE
sendstr( speed );
/*
* Typical character stream after the command to dial:
AT DT 123-4567\n -- computer sends this, and gets back...
AT DT 123-4567\r
(pauses while dialing; waiting for carrier)
\nCONNECT xx00\r\n
*/
if (expectstr( "\r", 10 ) != TRUE) { /* eat echoing of dial command */
printmsg(1, "hayes: modem not responding after reset!?\n");
return( FALSE );
}
if (expectstr("\n", 50) != TRUE) {
printmsg(1, "hayes: modem not responding after dial command!?\n");
return( FALSE );
}
if (expectstr("\r\n", 6) != TRUE) {
printmsg(1, "hayes: didn't get expected response [%s]",
prt(rdvec, strlen(rdvec)));
}
/*
* This block used to be part of the above "if" stmt...
*/
{
register char *resp = rdvec, *prt();
extern int atoi();
if (strnicmp( resp, "BUSY", 4 ) == SAME) {
printmsg(1, "hayes: BUSY -- phone line busy\n");
return( FALSE );
} else if (strnicmp( resp, "NO DIALTONE", 11 ) == SAME) {
printmsg(1, "hayes: NO DIALTONE -- check phone line\n");
return( FALSE );
} else if (strnicmp( resp, "NO CARRIER", 10 ) == SAME) {
printmsg(1, "hayes: NO CARRIER -- answered, but no carrier\n");
return( FALSE );
} else if (strnicmp( resp, "NO ANSWER", 9 ) == SAME) {
printmsg(1, "hayes: NO ANSWER -- call not answered\n");
return( FALSE );
} else if (strnicmp( resp, "CONNECT", 7 ) == SAME) {
printmsg( 3, "hayes: got CONNECT" );
if (atoi(resp+8)) {
printmsg( 3, "hayes: speed select %s",
prt(resp+8,strlen(resp+8)) );
SIOSpeed( resp+8 );
}
} else {
printmsg(1, "hayes: unknown modem response! [%s]\n",
prt(resp, strlen(resp)));
return( FALSE );
}
}
# if 0
else {
printmsg(1, "hayes: modem not responding to dial command!? [%s]\n",
prt(rdvec, strlen(rdvec)));
return( FALSE );
}
# endif
#else /* !FJE */
if ( sendexpect( speed, "CONNECT", 40 ) != TRUE ) {
printmsg( 0, "hayes: no answer");
return( FALSE );
}
printmsg( 3, "hayes: got CONNECT" );
if ( sread( buf, 5, 5 ) == 5 ) {
printmsg( 3, "hayes: speed select %s", buf );
/* set speed appropriately */
SIOSpeed( buf );
}
#endif
return( TRUE );
}
/*
* callup
* script processor - nothing fancy!
*/
callup()
{
int flg, kk, jj, ll, firstflg;
char *prsend;
char *exp;
char *alternate;
int ok;
int i;
printmsg( 0, "calling host %s", rmtname );
if ( strcmp( flds[FLD_TYPE], "DIR" ) != SAME ) {
if ( dial() == FALSE )
return( 'G' );
} else if (openline(device, speed))
return( 'G' );
for (i = 6; i < kflds; i+=2) {
exp = flds[i];
printmsg( 3, "callup: expect %d of %d \"%s\"", i, kflds, exp );
ok = FALSE;
while (ok != TRUE) {
alternate = index( exp, '-' );
if (alternate != (char *)NULL)
*alternate++ = '\0';
ok = expectstr( exp, g_timeout );
printmsg( 3, "got %s", ok != TRUE ? "?" : "that" );
if ( ok == TRUE )
break;
if ( alternate == (char *)NULL ) {
printmsg( 0, "LOGIN FAILED" );
return( 'Y' );
}
exp = index( alternate, '-' );
if ( exp != (char *)NULL )
*exp++ = '\0';
printmsg( 3, "send alternate" );
sendstr( alternate );
}
printmsg(3, "callup: send %d of %d \"%s\"", i+1,kflds, flds[i+1]);
sleep(1);
sendstr(flds[i+1]);
}
return('P');
}
#if 0
/*
* slowrite
* comunication slow write. needed for auto-baud modems
*/
slowrite(st)
register char *st;
{
int len, j;
char c;
len = strlen(st);
printmsg( 3, "sent %s", st );
for (j = 0; j < len; j++) {
swrite(&st[j], 1);
ddelay(80000);
}
}
#endif
/*
* scandir
*/
#include "ndir.h"
#define Direct struct direct
dcmp(a, b)
Direct *a, *b;
{
return( strcmp(b->d_name, a->d_name) );
}
/*
* scandir
* scan work dir for C. files matching current remote host (rmtname)
*
* [FJE] There's foom for optimization here: cache the directory entries
* so we don't have to search again. Primarily an advantage when
* running off of floppies. Same goes for "dscandir()", below.
* [FJE] The directory caching has been implemented. It even worked
* first try!!! There _MUST BE_ something wrong!
*
* return:
* A - abort, couldn't open directory
* Y - at least one file exists, but can't open it
* S - at least one file found, FILE * in "fw"
* Q - no files that match
*/
scandir()
{
int fn, len, i;
char cname[40], tmp[132];
DIR *dirp;
struct direct *dp;
#ifdef FJE
static Direct *cache = 0, *malloc(), *realloc();
static short count;
if (count) {
strcpy(cfile, cache[--count].d_name);
printmsg( 3, "scandir: uncaching %s", cfile );
return( -1 );
} else {
if (cache) free(cache);
cache = malloc(sizeof(Direct));
count = 0;
}
#endif /* FJE */
if ((dirp = opendir( spooldir )) == (DIR *)NULL ) {
fprintf( stderr, "couldn't open dir %s\n", spooldir );
return( 'A' );
}
sprintf(cname, CALLFILE, rmtname);
len = strlen(cname);
while ((dp = readdir(dirp)) != (struct direct *)NULL) {
if (strnicmp(cname, dp->d_name, len) == SAME) {
#ifndef FJE
printmsg( 3, "scandir: file = %s", dp->d_name );
strcpy(cfile, dp->d_name);
closedir( dirp );
if ((fw = FOPEN( cfile, "r", 't' )) == (char *)NULL )
return('Y');
return('S');
#else
if ((count % 8) == 0)
cache = realloc(cache, sizeof(Direct) * (count+8));
strcpy(cache[count++].d_name, dp->d_name);
printmsg( 3, "scandir: caching %s", dp->d_name );
#endif /* FJE */
}
}
closedir( dirp );
#ifdef FJE
if (count) {
qsort(cache, count, sizeof(Direct), dcmp);
strcpy(cfile, cache[--count].d_name);
printmsg(3, "scandir: %hd files; uncaching %s", count+1, cfile);
return( -1 );
}
#endif /* FJE */
return('Q');
}
/*
* dscandir -- looks for X.<rmtname> files
* scan the directory, [FJE] using a cache of the current
* contents. When the cache is empty, the directory is scanned
* again to see if anything new has come in.
*
* returns:
* ret(0) if no $SPOOLDIR or no X. files in $SPOOLDIR
* ret(-1) if at least one file found
*/
dscandir()
{
int fn, len, i;
char cname[40], tmp[132];
DIR *dirp;
Direct *dp;
#ifdef FJE
static Direct *cache = 0, *malloc(), *realloc();
static short count;
if (count) {
strcpy(cfile, cache[--count].d_name);
printmsg( 3, "dscandir: uncaching %s", cfile );
return( -1 );
} else {
if (cache) free(cache);
cache = (Direct *) malloc(sizeof(Direct));
count = 0;
}
#endif /* FJE */
if ((dirp = opendir( spooldir )) == (DIR *)NULL ) {
fprintf( stderr, "couldn't open dir %s\n", spooldir );
return(0);
}
sprintf(cname, XQTFILE, rmtname);
len = strlen(cname);
while ((dp = readdir(dirp)) != (Direct *)NULL) {
if ( strnicmp( cname, dp->d_name, len ) == SAME ) {
#ifndef FJE
printmsg( 3, "dscandir: file = %s", dp->d_name );
strcpy(cfile, dp->d_name);
closedir( dirp );
return( -1 );
#else
if ((count % 8) == 0)
cache = realloc(cache, sizeof(Direct) * (count+8));
strcpy(cache[count++].d_name, dp->d_name);
printmsg( 3, "dscandir: caching %s", dp->d_name );
#endif /* FJE */
}
}
closedir( dirp );
#ifdef FJE
if (count) {
qsort(cache, count, sizeof(Direct), dcmp);
strcpy(cfile, cache[--count].d_name);
printmsg(3, "dscandir: %hd files; uncaching %s", count+1, cfile);
return( -1 );
}
#endif /* FJE */
return( 0 );
}