============================================
* Original From: Paul Edwards, 3:711/934.9
* Original To : All, 0/0
* Original Date: 1997-04-26 23:31
============================================
Well, I've got my first newsgroup come in! I can only get one newsgroup at
a time, but that's just a minor wart which I know about and expect a
solution to soon. So I have moved onto the UUCP side.
I have made uucico.c available for FREQ, which is the negotiation that the
program I run will be using. All I know is the first step, which is that
it sends out Shere=scorpio (my machine is called scorpio).
I'm still working on getting this program to run automatically, and getting
some data to send. Here's a snippet of code from uucico if that's of any
interest...
if (! fchat (qconn, puuconf, &qsys->uuconf_schat, qsys,
(const struct uuconf_dialer *) NULL,
(const char *) NULL, FALSE, zport,
iconn_baud (qconn)))
return FALSE;
*pfcalled = TRUE;
istart_time = ixsysdep_time ((long *) NULL);
*pterr = STATUS_HANDSHAKE_FAILED;
/* We should now see "Shere" from the other system. Newer systems
send "Shere=foo" where foo is the remote name. */
zstr = zget_uucp_cmd (qconn, TRUE, fstrip);
if (zstr == NULL)
return FALSE;
if (strncmp (zstr, "Shere", 5) != 0)
{
ulog (LOG_ERROR, "Bad startup string (expected
\"Shere\" got \"%s\")",
zstr);
ubuffree (zstr);
return FALSE;
}
ulog (LOG_NORMAL, "Login successful");
qstat->ttype = STATUS_TALKING;
qstat->ilast = ixsysdep_time ((long *) NULL);
qstat->cretries = 0;
qstat->cwait = 0;
if (! fsysdep_set_status (qsys, qstat))
return FALSE;
if (zstr[5] == '=')
{
const char *zheresys;
size_t clen;
int icmp;
/* Some UUCP packages only provide seven characters in the Shere
machine name. Others only provide fourteen. */
zheresys = zstr + 6;
clen = strlen (zheresys);
if (clen == 7 || clen == 14)
icmp = strncmp (zheresys, qsys->uuconf_zname, clen);
else
icmp = strcmp (zheresys, qsys->uuconf_zname);
if (icmp != 0)
{
if (qsys->uuconf_pzalias != NULL)
{
char **pz;
for (pz = qsys->uuconf_pzalias; *pz != NULL; pz++)
{
if (clen == 7 || clen == 14)
icmp = strncmp (zheresys, *pz, clen);
else
icmp = strcmp (zheresys, *pz);
if (icmp == 0)
break;
}
}
if (icmp != 0)
{
ulog (LOG_ERROR, "Called wrong system (%s)", zheresys);
ubuffree (zstr);
return FALSE;
}
}
}
#if DEBUG > 1
else if (zstr[5] != '\0')
DEBUG_MESSAGE1 (DEBUG_HANDSHAKE,
"fdo_call: Strange Shere: %s", zstr);
#endif
ubuffree (zstr);
/* We now send "S" name switches, where name is our UUCP name. If
we are using sequence numbers with this system, we send a -Q
argument with the sequence number. If the call-timegrade command
was used, we send a -p argument and a -vgrade= argument with the
grade to send us (we send both argument to make it more likely
that one is recognized). We always send a -N (for new) switch
indicating what new features we support. */
{
long ival;
char bgrade;
char *zsend;
boolean fret;
/* Determine the grade we should request of the other system. A
'\0' means that no restrictions have been made. */
if (! ftimespan_match (qsys->uuconf_qcalltimegrade, &ival,
(int *) NULL))
bgrade = '\0';
else
bgrade = (char) ival;
/* Determine the name we will call ourselves. */
if (qsys->uuconf_zlocalname != NULL)
qdaemon->zlocalname = qsys->uuconf_zlocalname;
else
{
iuuconf = uuconf_localname (puuconf, &qdaemon->zlocalname);
if (iuuconf == UUCONF_NOT_FOUND)
{
qdaemon->zlocalname = zsysdep_localname ();
if (qdaemon->zlocalname == NULL)
return FALSE;
}
else if (iuuconf != UUCONF_SUCCESS)
{
ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
return FALSE;
}
}
zsend = zbufalc (strlen (qdaemon->zlocalname) + 70);
if (! qsys->uuconf_fsequence)
{
if (bgrade == '\0')
sprintf (zsend, "S%s -R -N0%o", qdaemon->zlocalname,
(unsigned int) (FEATURE_SIZES
| FEATURE_EXEC
| FEATURE_RESTART));
else
sprintf (zsend, "S%s -p%c -vgrade=%c -R -N0%o",
qdaemon->zlocalname, bgrade, bgrade,
(unsigned int) (FEATURE_SIZES
| FEATURE_EXEC
| FEATURE_RESTART));
}
else
{
long iseq;
iseq = ixsysdep_get_sequence (qsys);
if (iseq < 0)
return FALSE;
if (bgrade == '\0')
sprintf (zsend, "S%s -Q%ld -R -N0%o", qdaemon->zlocalname, iseq,
(unsigned int) (FEATURE_SIZES
| FEATURE_EXEC
| FEATURE_RESTART));
else
sprintf (zsend, "S%s -Q%ld -p%c -vgrade=%c -R -N0%o",
qdaemon->zlocalname, iseq, bgrade, bgrade,
(unsigned int) (FEATURE_SIZES
| FEATURE_EXEC
| FEATURE_RESTART));
}
fret = fsend_uucp_cmd (qconn, zsend);
ubuffree (zsend);
if (! fret)
return FALSE;
}
/* Now we should see ROK or Rreason where reason gives a cryptic
reason for failure. If we are talking to a counterpart, we will
get back ROKN, possibly with a feature bitfield attached. */
zstr = zget_uucp_cmd (qconn, TRUE, fstrip);
if (zstr == NULL)
return FALSE;
if (zstr[0] != 'R')
{
ulog (LOG_ERROR, "Bad response to handshake string (%s)",
zstr);
ubuffree (zstr);
return FALSE;
}
if (strncmp (zstr + 1, "OKN", sizeof "OKN" - 1) == 0)
{
if (zstr[sizeof "ROKN" - 1] == '\0')
qdaemon->ifeatures |= FEATURE_SIZES | FEATURE_V103;
else
qdaemon->ifeatures |= (int) strtol (zstr + sizeof "ROKN" - 1,
(char **) NULL, 0);
}
else if (strncmp (zstr + 1, "OK", sizeof "OK" - 1) == 0)
{
if (zstr[sizeof "ROK" - 1] != '\0')
{
char *zopt;
/* SVR4 UUCP returns options following the ROK string. */
zopt = zstr + sizeof "ROK" - 1;
while (*zopt != '\0')
{
char b;
long c;
char *zend;
b = *zopt++;
if (isspace (b) || b != '-')
continue;
switch (*zopt)
{
case 'R':
qdaemon->ifeatures |= (FEATURE_RESTART
| FEATURE_SVR4
| FEATURE_SIZES);
break;
case 'U':
c = strtol (zopt, &zend, 0);
if (c > 0 && c <= LONG_MAX / (long) 512)
qdaemon->cmax_receive = c * (long) 512;
zopt = zend;
break;
}
while (*zopt != '\0' && ! isspace (*zopt))
++zopt;
}
}
}
else if (strcmp (zstr + 1, "CB") == 0)
{
ulog (LOG_NORMAL, "Remote system will call back");
qstat->ttype = STATUS_COMPLETE;
(void) fsysdep_set_status (qsys, qstat);
ubuffree (zstr);
return TRUE;
}
else
{
ulog (LOG_ERROR, "Handshake failed (%s)", zstr + 1);
ubuffree (zstr);
return FALSE;
}
ubuffree (zstr);
/* The slave should now send \020Pprotos\0 where protos is a list of
supported protocols. Each protocol is a single character. */
zstr = zget_uucp_cmd (qconn, TRUE, fstrip);
if (zstr == NULL)
return FALSE;
if (zstr[0] != 'P')
{
ulog (LOG_ERROR, "Bad protocol handshake (%s)", zstr);
ubuffree (zstr);
return FALSE;
}
/* Determine the reliability characteristics of the connection by
combining information for the port and the dialer. If we have no
information, default to a reliable eight-bit full-duplex
connection. */
if (qconn->qport != NULL
&& (qconn->qport->uuconf_ireliable &
UUCONF_RELIABLE_SPECIFIED) != 0)
qdaemon->ireliable = qconn->qport->uuconf_ireliable;
if (qdialer != NULL
&& (qdialer->uuconf_ireliable & UUCONF_RELIABLE_SPECIFIED) != 0)
{
if (qdaemon->ireliable != 0)
qdaemon->ireliable &= qdialer->uuconf_ireliable;
else
qdaemon->ireliable = qdialer->uuconf_ireliable;
}
if (qdaemon->ireliable == 0)
qdaemon->ireliable = (UUCONF_RELIABLE_RELIABLE
| UUCONF_RELIABLE_EIGHT
| UUCONF_RELIABLE_FULLDUPLEX
| UUCONF_RELIABLE_SPECIFIED);
/* Now decide which protocol to use. The system and the port may
have their own list of protocols. */
{
int i;
char ab[5];
i = CPROTOCOLS;
if (qsys->uuconf_zprotocols != NULL
|| (qconn->qport != NULL
&& qconn->qport->uuconf_zprotocols != NULL))
{
const char *zproto;
if (qsys->uuconf_zprotocols != NULL)
zproto = qsys->uuconf_zprotocols;
else
zproto = qconn->qport->uuconf_zprotocols;
for (; *zproto != '\0'; zproto++)
{
if (strchr (zstr + 1, *zproto) != NULL)
{
for (i = 0; i < CPROTOCOLS; i++)
if (asProtocols[i].bname == *zproto)
break;
if (i < CPROTOCOLS)
break;
}
}
}
else
{
/* If neither the system nor the port specified a list of
protocols, we want only protocols that match the known
reliability of the dialer and the port. */
for (i = 0; i < CPROTOCOLS; i++)
{
int ipr;
ipr = asProtocols[i].ireliable;
if ((ipr & qdaemon->ireliable) != ipr)
continue;
if (strchr (zstr + 1, asProtocols[i].bname) != NULL)
break;
}
}
ubuffree (zstr);
if (i >= CPROTOCOLS)
{
(void) fsend_uucp_cmd (qconn, "UN");
ulog (LOG_ERROR, "No mutually supported protocols");
return FALSE;
}
qdaemon->qproto = &asProtocols[i];
/* If we are using a half-duplex line, act as though we have only
a single channel; otherwise we might start a send and a receive
at the same time. */
if ((qdaemon->ireliable & UUCONF_RELIABLE_FULLDUPLEX) == 0)
qdaemon->cchans = 1;
else
qdaemon->cchans = asProtocols[i].cchans;
sprintf (ab, "U%c", qdaemon->qproto->bname);
if (! fsend_uucp_cmd (qconn, ab))
return FALSE;
}
/* Run any protocol parameter commands. */
if (qdaemon->qproto->qcmds != NULL)
{
if (qsys->uuconf_qproto_params != NULL)
uapply_proto_params (puuconf, qdaemon->qproto->bname,
qdaemon->qproto->qcmds,
qsys->uuconf_qproto_params);
if (qconn->qport != NULL
&& qconn->qport->uuconf_qproto_params != NULL)
uapply_proto_params (puuconf, qdaemon->qproto->bname,
qdaemon->qproto->qcmds,
qconn->qport->uuconf_qproto_params);
if (qdialer != NULL
&& qdialer->uuconf_qproto_params != NULL)
uapply_proto_params (puuconf, qdaemon->qproto->bname,
qdaemon->qproto->qcmds,
qdialer->uuconf_qproto_params);
}
/* Turn on the selected protocol. */
if (! (*qdaemon->qproto->pfstart) (qdaemon, &zlog))
return FALSE;
if (zlog == NULL)
{
zlog = zbufalc (sizeof "protocol ''" + 1);
sprintf (zlog, "protocol '%c'", qdaemon->qproto->bname);
}
ulog (LOG_NORMAL, "Handshake successful (%s)", zlog);
ubuffree (zlog);
*pterr = STATUS_FAILED;
{
boolean fret;
long iend_time;
fret = floop (qdaemon);
/* Now send the hangup message. As the caller, we send six O's
and expect to receive seven O's. We send the six O's twice to
help the other side. We don't worry about errors here. */
if (fsend_uucp_cmd (qconn, "OOOOOO")
&& fsend_uucp_cmd (qconn, "OOOOOO"))
{
int i, fdone;
/* We look for the remote hangup string to ensure that the
modem has sent out our hangup string. This is only
necessary because some versions of UUCP complain if they
don't get the hangup string. The remote site should send 7
O's, but some versions of UUCP only send 6. We look for
the string several times because supposedly some
implementations send some garbage after the last packet but
before the hangup string. */
for (i = 0; i < 25; i++)
{
zstr = zget_uucp_cmd (qconn, FALSE, fstrip);
if (zstr == NULL)
break;
fdone = strstr (zstr, "OOOOOO") != NULL;
ubuffree (zstr);
if (fdone)
break;
}
}
iend_time = ixsysdep_time ((long *) NULL);
ulog (LOG_NORMAL, "Call complete (%ld seconds %ld bytes %ld bps)",
iend_time - istart_time,
qdaemon->csent + qdaemon->creceived,
(iend_time != istart_time
? (qdaemon->csent + qdaemon->creceived) / (iend_time - istart_time)
: 0));
if (fret)
{
qstat->ttype = STATUS_COMPLETE;
qstat->ilast = iend_time;
(void) fsysdep_set_status (qsys, qstat);
}
if (qdaemon->irunuuxqt == UUCONF_RUNUUXQT_PERCALL
|| (qdaemon->irunuuxqt > 0 && qdaemon->cxfiles_received > 0))
(void) fspawn_uuxqt (TRUE, qdaemon->qsys->uuconf_zname,
qdaemon->zconfig);
return fret;
}
}
@EOT:
---
* Origin: X (3:711/934.9)
|