#include "uucp.h"
#if USE_RCS_ID
const char prote_rcsid[] = "$Id: prote.c,v 1.23 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 CEBUFSIZE (CRECBUFLEN / 2)
#define CEFRAMELEN (20)
static char *zEbuf;
static boolean fEfile;
static long cEbytes;
static int cEtimeout = 120;
struct uuconf_cmdtab asEproto_params[] =
{
{ "timeout", UUCONF_CMDTABTYPE_INT, (pointer) &cEtimeout, NULL },
{ NULL, 0, NULL, NULL }
};
static boolean feprocess_data P((struct sdaemon *qdaemon, boolean *pfexit,
size_t *pcneed));
boolean
festart (qdaemon, pzlog)
struct sdaemon *qdaemon;
char **pzlog;
{
*pzlog = NULL;
if (! fconn_set (qdaemon->qconn, PARITYSETTING_NONE,
STRIPSETTING_EIGHTBITS, XONXOFF_OFF))
return FALSE;
zEbuf = (char *) xmalloc (CEBUFSIZE);
fEfile = FALSE;
usysdep_sleep (2);
return TRUE;
}
boolean
feshutdown (qdaemon)
struct sdaemon *qdaemon ATTRIBUTE_UNUSED;
{
xfree ((pointer) zEbuf);
zEbuf = NULL;
cEtimeout = 120;
return TRUE;
}
boolean
fesendcmd (qdaemon, z, ilocal, iremote)
struct sdaemon *qdaemon;
const char *z;
int ilocal ATTRIBUTE_UNUSED;
int iremote ATTRIBUTE_UNUSED;
{
DEBUG_MESSAGE1 (DEBUG_UUCP_PROTO, "fesendcmd: Sending command \"%s\"", z);
return fsend_data (qdaemon->qconn, z, strlen (z) + 1, TRUE);
}
char *
zegetspace (qdaemon, pclen)
struct sdaemon *qdaemon ATTRIBUTE_UNUSED;
size_t *pclen;
{
*pclen = CEBUFSIZE;
return zEbuf;
}
boolean
fesenddata (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;
{
#if DEBUG > 0
cEbytes -= cdata;
if (cEbytes < 0)
{
ulog (LOG_ERROR, "Protocol 'e' internal error");
return FALSE;
}
#endif
return fsend_data (qdaemon->qconn, zdata, cdata, FALSE);
}
static boolean
feprocess_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 (! fEfile)
{
while (cinbuf > 0)
{
char *pnull;
cfirst = CRECBUFLEN - iPrecstart;
if (cfirst > cinbuf)
cfirst = cinbuf;
pnull = memchr (abPrecbuf + iPrecstart, '\0', (size_t) cfirst);
if (pnull != NULL)
cfirst = pnull - (abPrecbuf + iPrecstart) + 1;
DEBUG_MESSAGE1 (DEBUG_PROTO,
"feprocess_data: Got %d command bytes",
cfirst);
if (! fgot_data (qdaemon, abPrecbuf + iPrecstart,
(size_t) cfirst, (const char *) NULL, (size_t) 0,
-1, -1, (long) -1, TRUE, pfexit))
return FALSE;
iPrecstart = (iPrecstart + cfirst) % CRECBUFLEN;
if (*pfexit)
return TRUE;
cinbuf = iPrecend - iPrecstart;
if (cinbuf < 0)
cinbuf += CRECBUFLEN;
}
if (pcneed != NULL)
*pcneed = 1;
return TRUE;
}
if (cEbytes == -1)
{
char ab[CEFRAMELEN + 1];
if (cinbuf < CEFRAMELEN)
{
if (pcneed != NULL)
*pcneed = CEFRAMELEN - cinbuf;
return TRUE;
}
cfirst = CRECBUFLEN - iPrecstart;
if (cfirst >= CEFRAMELEN)
memcpy (ab, abPrecbuf + iPrecstart, (size_t) CEFRAMELEN);
else
{
memcpy (ab, abPrecbuf + iPrecstart, (size_t) cfirst);
memcpy (ab + cfirst, abPrecbuf, (size_t) CEFRAMELEN - cfirst);
}
ab[CEFRAMELEN] = '\0';
cEbytes = strtol (ab, (char **) NULL, 10);
iPrecstart = (iPrecstart + CEFRAMELEN) % CRECBUFLEN;
cinbuf = iPrecend - iPrecstart;
if (cinbuf < 0)
cinbuf += CRECBUFLEN;
if (cEbytes == 0)
{
if (! fgot_data (qdaemon, abPrecbuf, (size_t) 0,
(const char *) NULL, (size_t) 0,
-1, -1, (long) -1, TRUE, pfexit))
return FALSE;
if (*pfexit)
return TRUE;
}
}
while (cinbuf > 0)
{
clen = cinbuf;
if ((long) clen > cEbytes)
clen = (int) cEbytes;
cfirst = CRECBUFLEN - iPrecstart;
if (cfirst > clen)
cfirst = clen;
DEBUG_MESSAGE1 (DEBUG_PROTO,
"feprocess_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;
cEbytes -= clen;
if (cEbytes == 0)
{
if (! fgot_data (qdaemon, abPrecbuf, (size_t) 0,
(const char *) NULL, (size_t) 0,
-1, -1, (long) -1, TRUE, pfexit))
return FALSE;
if (*pfexit)
return TRUE;
}
cinbuf -= clen;
}
if (pcneed != NULL)
{
if (cEbytes > CRECBUFLEN / 2)
*pcneed = CRECBUFLEN / 2;
else
*pcneed = (int) cEbytes;
}
return TRUE;
}
boolean
fewait (qdaemon)
struct sdaemon *qdaemon;
{
while (TRUE)
{
boolean fexit;
size_t cneed, crec;
if (! feprocess_data (qdaemon, &fexit, &cneed))
return FALSE;
if (fexit)
return TRUE;
if (! freceive_data (qdaemon->qconn, cneed, &crec, cEtimeout, TRUE))
return FALSE;
if (crec == 0)
{
ulog (LOG_ERROR, "Timed out waiting for data");
return FALSE;
}
}
}
boolean
fefile (qdaemon, qtrans, fstart, fsend, cbytes, pfhandled)
struct sdaemon *qdaemon;
struct stransfer *qtrans ATTRIBUTE_UNUSED;
boolean fstart;
boolean fsend;
long cbytes;
boolean *pfhandled;
{
*pfhandled = FALSE;
if (fstart)
{
if (fsend)
{
char ab[CEFRAMELEN];
DEBUG_MESSAGE1 (DEBUG_PROTO,
"Protocol 'e' starting to send %ld bytes",
cbytes);
bzero (ab, (size_t) CEFRAMELEN);
sprintf (ab, "%ld", cbytes);
if (! fsend_data (qdaemon->qconn, ab, (size_t) CEFRAMELEN, TRUE))
return FALSE;
cEbytes = cbytes;
}
else
{
cEbytes = -1;
fEfile = TRUE;
}
}
else
{
if (! fsend)
fEfile = FALSE;
#if DEBUG > 0
if (cEbytes != 0)
{
ulog (LOG_ERROR,
"Protocol 'e' internal error: %ld bytes left over",
cEbytes);
return FALSE;
}
#endif
}
return TRUE;
}