#include "uucp.h"
#if USE_RCS_ID
const char prott_rcsid[] = "$Id: prott.c,v 1.32 2002/03/05 19:10:41 ian Rel $";
#endif
#include "uudefs.h"
#include "uuconf.h"
#include "conn.h"
#include "trans.h"
#include "system.h"
#include "prot.h"
#define CTBUFSIZE (1024)
#define CTFRAMELEN (4)
#define CTPACKSIZE (512)
static char *zTbuf;
static boolean fTfile;
static int cTtimeout = 120;
struct uuconf_cmdtab asTproto_params[] =
{
{ "timeout", UUCONF_CMDTABTYPE_INT, (pointer) &cTtimeout, NULL },
{ NULL, 0, NULL, NULL }
};
static boolean ftprocess_data P((struct sdaemon *qdaemon, boolean *pfexit,
size_t *pcneed));
boolean
ftstart (qdaemon, pzlog)
struct sdaemon *qdaemon;
char **pzlog;
{
*pzlog = NULL;
if (! fconn_set (qdaemon->qconn, PARITYSETTING_NONE,
STRIPSETTING_EIGHTBITS, XONXOFF_OFF))
return FALSE;
zTbuf = (char *) xmalloc (CTBUFSIZE + CTFRAMELEN);
zTbuf[0] = 0;
zTbuf[1] = 0;
fTfile = FALSE;
usysdep_sleep (2);
return TRUE;
}
boolean
ftshutdown (qdaemon)
struct sdaemon *qdaemon ATTRIBUTE_UNUSED;
{
xfree ((pointer) zTbuf);
zTbuf = NULL;
cTtimeout = 120;
return TRUE;
}
boolean
ftsendcmd (qdaemon, z, ilocal, iremote)
struct sdaemon *qdaemon;
const char *z;
int ilocal ATTRIBUTE_UNUSED;
int iremote ATTRIBUTE_UNUSED;
{
size_t clen, csend;
char *zalc;
boolean fret;
DEBUG_MESSAGE1 (DEBUG_UUCP_PROTO, "ftsendcmd: Sending command \"%s\"", z);
clen = strlen (z);
csend = ((clen / CTPACKSIZE) + 1) * CTPACKSIZE;
zalc = zbufalc (csend);
memcpy (zalc, z, clen);
if (csend > clen)
bzero (zalc + clen, csend - clen);
fret = fsend_data (qdaemon->qconn, zalc, csend, TRUE);
ubuffree (zalc);
return fret;
}
char *
ztgetspace (qdaemon, pclen)
struct sdaemon *qdaemon ATTRIBUTE_UNUSED;
size_t *pclen;
{
*pclen = CTBUFSIZE;
return zTbuf + CTFRAMELEN;
}
boolean
ftsenddata (qdaemon, zdata, cdata, ilocal, iremote, ipos)
struct sdaemon *qdaemon;
char *zdata;
size_t cdata;
int ilocal ATTRIBUTE_UNUSED;
int iremote ATTRIBUTE_UNUSED;
long ipos ATTRIBUTE_UNUSED;
{
zdata[-2] = (char) ((cdata >> 8) & 0xff);
zdata[-1] = (char) (cdata & 0xff);
return fsend_data (qdaemon->qconn, zdata - CTFRAMELEN, cdata + CTFRAMELEN,
FALSE);
}
static boolean
ftprocess_data (qdaemon, pfexit, pcneed)
struct sdaemon *qdaemon;
boolean *pfexit;
size_t *pcneed;
{
int cinbuf, cfirst, clen;
*pfexit = FALSE;
cinbuf = iPrecend - iPrecstart;
if (cinbuf < 0)
cinbuf += CRECBUFLEN;
if (! fTfile)
{
while (cinbuf >= CTPACKSIZE)
{
cfirst = CRECBUFLEN - iPrecstart;
if (cfirst > CTPACKSIZE)
cfirst = CTPACKSIZE;
DEBUG_MESSAGE1 (DEBUG_PROTO,
"ftprocess_data: Got %d command bytes",
cfirst);
if (! fgot_data (qdaemon, abPrecbuf + iPrecstart,
(size_t) cfirst, abPrecbuf,
(size_t) CTPACKSIZE - cfirst,
-1, -1, (long) -1, TRUE, pfexit))
return FALSE;
iPrecstart = (iPrecstart + CTPACKSIZE) % CRECBUFLEN;
if (*pfexit)
return TRUE;
cinbuf -= CTPACKSIZE;
}
if (pcneed != NULL)
*pcneed = CTPACKSIZE - cinbuf;
return TRUE;
}
while (cinbuf >= CTFRAMELEN)
{
clen = (((((((abPrecbuf[iPrecstart] & 0xff) << 8)
+ (abPrecbuf[(iPrecstart + 1) % CRECBUFLEN] & 0xff)) << 8)
+ (abPrecbuf[(iPrecstart + 2) % CRECBUFLEN] & 0xff)) << 8)
+ (abPrecbuf[(iPrecstart + 3) % CRECBUFLEN] & 0xff));
if (cinbuf < clen + CTFRAMELEN)
{
if (pcneed != NULL)
*pcneed = clen + CTFRAMELEN - cinbuf;
return TRUE;
}
iPrecstart = (iPrecstart + CTFRAMELEN) % CRECBUFLEN;
cfirst = CRECBUFLEN - iPrecstart;
if (cfirst > clen)
cfirst = clen;
DEBUG_MESSAGE1 (DEBUG_PROTO,
"ftprocess_data: Got %d data bytes",
clen);
if (! fgot_data (qdaemon, abPrecbuf + iPrecstart,
(size_t) cfirst, abPrecbuf, (size_t) (clen - cfirst),
-1, -1, (long) -1, TRUE, pfexit))
return FALSE;
iPrecstart = (iPrecstart + clen) % CRECBUFLEN;
if (*pfexit)
return TRUE;
cinbuf -= clen + CTFRAMELEN;
}
if (pcneed != NULL)
*pcneed = CTFRAMELEN - cinbuf;
return TRUE;
}
boolean
ftwait (qdaemon)
struct sdaemon *qdaemon;
{
while (TRUE)
{
boolean fexit;
size_t cneed, crec;
if (! ftprocess_data (qdaemon, &fexit, &cneed))
return FALSE;
if (fexit)
return TRUE;
if (! freceive_data (qdaemon->qconn, cneed, &crec, cTtimeout, TRUE))
return FALSE;
if (crec == 0)
{
ulog (LOG_ERROR, "Timed out waiting for data");
return FALSE;
}
}
}
boolean
ftfile (qdaemon, qtrans, fstart, fsend, cbytes, pfhandled)
struct sdaemon *qdaemon ATTRIBUTE_UNUSED;
struct stransfer *qtrans ATTRIBUTE_UNUSED;
boolean fstart;
boolean fsend;
long cbytes ATTRIBUTE_UNUSED;
boolean *pfhandled;
{
*pfhandled = FALSE;
if (! fsend)
fTfile = fstart;
return TRUE;
}