#include "uucnfi.h"
#if USE_RCS_ID
const char _uuconf_vsinfo_rcsid[] = "$Id: vsinfo.c,v 1.17 2002/03/05 19:10:43 ian Rel $";
#endif
#include <errno.h>
#include <ctype.h>
int
_uuconf_iv2_system_internal (qglobal, zsystem, qsys)
struct sglobal *qglobal;
const char *zsystem;
struct uuconf_system *qsys;
{
char *zline;
size_t cline;
char **pzsplit;
size_t csplit;
char **pzcomma;
size_t ccomma;
FILE *e;
int cchars;
pointer pblock;
int iret;
e = fopen (qglobal->qprocess->zv2systems, "r");
if (e == NULL)
{
if (FNO_SUCH_FILE ())
return UUCONF_NOT_FOUND;
qglobal->ierrno = errno;
qglobal->zfilename = qglobal->qprocess->zv2systems;
return (UUCONF_FOPEN_FAILED
| UUCONF_ERROR_ERRNO
| UUCONF_ERROR_FILENAME);
}
zline = NULL;
cline = 0;
pzsplit = NULL;
csplit = 0;
pzcomma = NULL;
ccomma = 0;
pblock = NULL;
iret = UUCONF_SUCCESS;
qglobal->ilineno = 0;
while ((cchars = _uuconf_getline (qglobal, &zline, &cline, e)) > 0)
{
int ctoks, ctimes, i;
struct uuconf_system *qset;
char *z, *zretry;
int cretry;
++qglobal->ilineno;
--cchars;
if (zline[cchars] == '\n')
zline[cchars] = '\0';
zline[strcspn (zline, "#")] = '\0';
ctoks = _uuconf_istrsplit (zline, '\0', &pzsplit, &csplit);
if (ctoks < 0)
{
qglobal->ierrno = errno;
iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
break;
}
if (ctoks < 1
|| strcmp (zsystem, pzsplit[0]) != 0)
continue;
if (pblock == NULL)
{
pblock = uuconf_malloc_block ();
if (pblock == NULL)
{
qglobal->ierrno = errno;
iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
break;
}
_uuconf_uclear_system (qsys);
qsys->uuconf_palloc = pblock;
qset = qsys;
}
else
{
struct uuconf_system **pq;
qset = ((struct uuconf_system *)
uuconf_malloc (pblock, sizeof (struct uuconf_system)));
if (qset == NULL)
{
qglobal->ierrno = errno;
iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
break;
}
_uuconf_uclear_system (qset);
for (pq = &qsys->uuconf_qalternate;
*pq != NULL;
pq = &(*pq)->uuconf_qalternate)
;
*pq = qset;
}
if (uuconf_add_block (pblock, zline) != 0)
{
qglobal->ierrno = errno;
iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
break;
}
zline = NULL;
cline = 0;
qset->uuconf_zname = pzsplit[0];
qset->uuconf_fcall = TRUE;
qset->uuconf_fcalled = TRUE;
if (ctoks < 2)
continue;
zretry = strchr (pzsplit[1], ';');
if (zretry == NULL)
cretry = 55;
else
{
*zretry = '\0';
cretry = (int) strtol (zretry + 1, (char **) NULL, 10);
}
ctimes = _uuconf_istrsplit (pzsplit[1], ',', &pzcomma, &ccomma);
if (ctimes < 0)
{
qglobal->ierrno = errno;
iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
break;
}
for (i = 0; i < ctimes; i++)
{
char *zslash;
char bgrade;
z = pzcomma[i];
zslash = strchr (z, '/');
if (zslash == NULL)
bgrade = UUCONF_GRADE_LOW;
else
{
*zslash = '\0';
bgrade = zslash[1];
if (! UUCONF_GRADE_LEGAL (bgrade))
bgrade = UUCONF_GRADE_LOW;
}
iret = _uuconf_itime_parse (qglobal, z, (long) bgrade, cretry,
_uuconf_itime_grade_cmp,
&qset->uuconf_qtimegrade,
pblock);
if (iret == UUCONF_SYNTAX_ERROR)
iret = UUCONF_SUCCESS;
if (iret != UUCONF_SUCCESS)
break;
if (bgrade != UUCONF_GRADE_LOW)
qset->uuconf_qcalltimegrade = qset->uuconf_qtimegrade;
}
if (iret != UUCONF_SUCCESS)
break;
if (ctoks < 3)
continue;
qset->uuconf_zport = pzsplit[2];
z = strchr (pzsplit[2], ',');
if (z != NULL)
{
qset->uuconf_zprotocols = z + 1;
*z = '\0';
}
if (strcmp (qset->uuconf_zport, "TCP") == 0)
{
qset->uuconf_zport = NULL;
qset->uuconf_qport = ((struct uuconf_port *)
uuconf_malloc (pblock,
sizeof (struct uuconf_port)));
if (qset->uuconf_qport == NULL)
{
qglobal->ierrno = errno;
iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
break;
}
_uuconf_uclear_port (qset->uuconf_qport);
qset->uuconf_qport->uuconf_zname = (char *) "TCP";
qset->uuconf_qport->uuconf_ttype = UUCONF_PORTTYPE_TCP;
qset->uuconf_qport->uuconf_ireliable
= (UUCONF_RELIABLE_ENDTOEND | UUCONF_RELIABLE_RELIABLE
| UUCONF_RELIABLE_EIGHT | UUCONF_RELIABLE_FULLDUPLEX
| UUCONF_RELIABLE_SPECIFIED);
if (ctoks < 4)
qset->uuconf_qport->uuconf_u.uuconf_stcp.uuconf_zport
= (char *) "uucp";
else
qset->uuconf_qport->uuconf_u.uuconf_stcp.uuconf_zport
= pzsplit[3];
qset->uuconf_qport->uuconf_u.uuconf_stcp.uuconf_iversion = 0;
qset->uuconf_qport->uuconf_u.uuconf_stcp.uuconf_pzdialer = NULL;
}
if (ctoks < 4)
continue;
qset->uuconf_ibaud = strtol (pzsplit[3], (char **) NULL, 10);
if (ctoks < 5)
continue;
qset->uuconf_zphone = pzsplit[4];
if (ctoks < 6)
continue;
pzsplit[4] = (char *) "chat";
iret = _uuconf_ichat_cmd (qglobal, ctoks - 4, pzsplit + 4,
&qset->uuconf_schat, pblock);
iret &=~ UUCONF_CMDTABRET_KEEP;
if (iret != UUCONF_SUCCESS)
break;
}
(void) fclose (e);
if (pzcomma != NULL)
free ((pointer) pzcomma);
if (iret != UUCONF_SUCCESS)
{
if (zline != NULL)
free ((pointer) zline);
if (pzsplit != NULL)
free ((pointer) pzsplit);
qglobal->zfilename = qglobal->qprocess->zv2systems;
return iret | UUCONF_ERROR_FILENAME | UUCONF_ERROR_LINENO;
}
if (pblock == NULL)
{
if (zline != NULL)
free ((pointer) zline);
if (pzsplit != NULL)
free ((pointer) pzsplit);
return UUCONF_NOT_FOUND;
}
{
e = fopen (qglobal->qprocess->zv2userfile, "r");
if (e != NULL)
{
char **pzlocal, **pzremote;
boolean fdefault_callback;
char *zdefault_login;
struct uuconf_system *q;
pzlocal = NULL;
pzremote = NULL;
fdefault_callback = FALSE;
zdefault_login = NULL;
qglobal->ilineno = 0;
while ((cchars = getline (&zline, &cline, e)) > 0)
{
int ctoks;
char *zcomma;
boolean fcallback;
char **pzlist, **pznew;
++qglobal->ilineno;
--cchars;
if (zline[cchars] == '\n')
zline[cchars] = '\0';
zline[strcspn (zline, "#")] = '\0';
ctoks = _uuconf_istrsplit (zline, '\0', &pzsplit, &csplit);
if (ctoks < 0)
{
qglobal->ierrno = errno;
iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
break;
}
if (ctoks == 0)
continue;
zcomma = strchr (pzsplit[0], ',');
if (zcomma == NULL)
continue;
*zcomma++ = '\0';
fcallback = FALSE;
pzlist = pzsplit + 1;
--ctoks;
if (ctoks > 0
&& pzsplit[1][0] == 'c'
&& pzsplit[1][1] == '\0')
{
fcallback = TRUE;
pzlist = pzsplit + 2;
--ctoks;
}
if ((pzsplit[0][0] != '\0' || pzlocal != NULL)
&& (zcomma[0] != '\0' || pzremote != NULL)
&& strcmp (zcomma, zsystem) != 0)
continue;
pznew = (char **) uuconf_malloc (pblock,
(ctoks + 1) * sizeof (char *));
if (pznew == NULL)
{
qglobal->ierrno = errno;
iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
break;
}
memcpy ((pointer) pznew, (pointer) pzlist,
ctoks * sizeof (char *));
pznew[ctoks] = NULL;
if (uuconf_add_block (pblock, zline) != 0)
{
qglobal->ierrno = errno;
iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
break;
}
zline = NULL;
cline = 0;
if (pzsplit[0][0] == '\0')
{
pzlocal = pznew;
fdefault_callback = fcallback;
}
else if (zcomma[0] == '\0')
{
pzremote = pznew;
zdefault_login = pzsplit[0];
}
else
{
for (q = qsys; q != NULL; q = q->uuconf_qalternate)
{
q->uuconf_zcalled_login = pzsplit[0];
q->uuconf_fcallback = fcallback;
q->uuconf_pzlocal_send = pznew;
q->uuconf_pzlocal_receive = pznew;
q->uuconf_pzremote_send = pznew;
q->uuconf_pzremote_receive = pznew;
}
break;
}
}
(void) fclose (e);
if (iret != UUCONF_SUCCESS)
{
if (zline != NULL)
free ((pointer) zline);
if (pzsplit != NULL)
free ((pointer) pzsplit);
qglobal->zfilename = qglobal->qprocess->zv2userfile;
return iret | UUCONF_ERROR_FILENAME | UUCONF_ERROR_LINENO;
}
if (qsys->uuconf_pzlocal_send == (char **) &_uuconf_unset
&& pzlocal != NULL)
{
for (q = qsys; q != NULL; q = q->uuconf_qalternate)
{
q->uuconf_fcallback = fdefault_callback;
q->uuconf_pzlocal_send = pzlocal;
q->uuconf_pzlocal_receive = pzlocal;
}
}
if (qsys->uuconf_pzremote_send == (char **) &_uuconf_unset
&& pzremote != NULL)
{
for (q = qsys; q != NULL; q = q->uuconf_qalternate)
{
q->uuconf_zcalled_login = zdefault_login;
q->uuconf_pzremote_send = pzremote;
q->uuconf_pzremote_receive = pzremote;
}
}
}
}
{
e = fopen (qglobal->qprocess->zv2cmds, "r");
if (e != NULL)
{
qglobal->ilineno = 0;
if (getline (&zline, &cline, e) > 0)
{
++qglobal->ilineno;
zline[strcspn (zline, "#\n")] = '\0';
while (*zline == '\0')
{
if (getline (&zline, &cline, e) <= 0)
{
if (zline != NULL)
{
free ((pointer) zline);
zline = NULL;
}
}
else
{
++qglobal->ilineno;
zline[strcspn (zline, "#\n")] = '\0';
}
}
if (zline != NULL
&& strncmp (zline, "PATH=", sizeof "PATH=" - 1) == 0)
{
int ctoks;
char **pznew;
zline += sizeof "PATH=" - 1;
ctoks = _uuconf_istrsplit (zline, ':', &pzsplit, &csplit);
if (ctoks < 0)
{
qglobal->ierrno = errno;
iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
}
pznew = NULL;
if (iret == UUCONF_SUCCESS)
{
pznew = ((char **)
uuconf_malloc (pblock,
(ctoks + 1) * sizeof (char *)));
if (pznew == NULL)
iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
}
if (iret == UUCONF_SUCCESS)
{
memcpy ((pointer) pznew, (pointer) pzsplit,
ctoks * sizeof (char *));
pznew[ctoks] = NULL;
qsys->uuconf_pzpath = pznew;
zline = NULL;
cline = 0;
}
if (getline (&zline, &cline, e) < 0)
{
if (zline != NULL)
{
free ((pointer) zline);
zline = NULL;
}
}
else
++qglobal->ilineno;
}
}
if (iret == UUCONF_SUCCESS && zline != NULL)
{
while (TRUE)
{
zline[strcspn (zline, "#,\n")] = '\0';
if (*zline != '\0')
{
iret = _uuconf_iadd_string (qglobal, zline, TRUE, FALSE,
&qsys->uuconf_pzcmds,
pblock);
if (iret != UUCONF_SUCCESS)
break;
}
if (getline (&zline, &cline, e) < 0)
break;
++qglobal->ilineno;
}
}
(void) fclose (e);
if (iret != UUCONF_SUCCESS)
{
qglobal->zfilename = qglobal->qprocess->zv2cmds;
iret |= UUCONF_ERROR_FILENAME | UUCONF_ERROR_LINENO;
}
}
}
if (zline != NULL)
free ((pointer) zline);
if (pzsplit != NULL)
free ((pointer) pzsplit);
return iret;
}