2 Get information about a system from the V2 configuration files.
4 Copyright (C) 1992, 1993, 1995 Ian Lance Taylor
6 This file is part of the Taylor UUCP uuconf library.
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public License
10 as published by the Free Software Foundation; either version 2 of
11 the License, or (at your option) any later version.
13 This library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
18 You should have received a copy of the GNU Library General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 The author of the program may be contacted at ian@airs.com or
23 c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
29 const char _uuconf_vsinfo_rcsid[] = "$FreeBSD$";
35 /* Get the information for a particular system from the V2
36 configuration files. This does not make sure that all the default
40 _uuconf_iv2_system_internal (qglobal, zsystem, qsys)
41 struct sglobal *qglobal;
43 struct uuconf_system *qsys;
56 e = fopen (qglobal->qprocess->zv2systems, "r");
60 return UUCONF_NOT_FOUND;
61 qglobal->ierrno = errno;
62 qglobal->zfilename = qglobal->qprocess->zv2systems;
63 return (UUCONF_FOPEN_FAILED
65 | UUCONF_ERROR_FILENAME);
76 iret = UUCONF_SUCCESS;
80 while ((cchars = _uuconf_getline (qglobal, &zline, &cline, e)) > 0)
83 struct uuconf_system *qset;
90 if (zline[cchars] == '\n')
92 zline[strcspn (zline, "#")] = '\0';
94 ctoks = _uuconf_istrsplit (zline, '\0', &pzsplit, &csplit);
97 qglobal->ierrno = errno;
98 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
102 /* If this isn't the system we're looking for, keep reading
105 || strcmp (zsystem, pzsplit[0]) != 0)
108 /* If this is the first time we've found the system, we want
109 to set *qsys directly. Otherwise, we allocate a new
113 pblock = uuconf_malloc_block ();
116 qglobal->ierrno = errno;
117 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
120 _uuconf_uclear_system (qsys);
121 qsys->uuconf_palloc = pblock;
126 struct uuconf_system **pq;
128 qset = ((struct uuconf_system *)
129 uuconf_malloc (pblock, sizeof (struct uuconf_system)));
132 qglobal->ierrno = errno;
133 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
136 _uuconf_uclear_system (qset);
137 for (pq = &qsys->uuconf_qalternate;
139 pq = &(*pq)->uuconf_qalternate)
144 /* Add this line to the memory block we are building for the
146 if (uuconf_add_block (pblock, zline) != 0)
148 qglobal->ierrno = errno;
149 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
156 /* The format of a line in Systems is
157 system time device speed phone chat
159 airs Any ACU 9600 5551212 ogin: foo pass: bar
162 /* Get the system name. */
164 qset->uuconf_zname = pzsplit[0];
165 qset->uuconf_fcall = TRUE;
166 qset->uuconf_fcalled = TRUE;
171 /* A time string is "time/grade,time/grade;retry". A missing
172 grade is taken as BGRADE_LOW. On some versions the retry
173 time is actually separated by a comma, which won't work right
175 zretry = strchr (pzsplit[1], ';');
181 cretry = (int) strtol (zretry + 1, (char **) NULL, 10);
184 ctimes = _uuconf_istrsplit (pzsplit[1], ',', &pzcomma, &ccomma);
187 qglobal->ierrno = errno;
188 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
192 for (i = 0; i < ctimes; i++)
198 zslash = strchr (z, '/');
200 bgrade = UUCONF_GRADE_LOW;
205 if (! UUCONF_GRADE_LEGAL (bgrade))
206 bgrade = UUCONF_GRADE_LOW;
209 iret = _uuconf_itime_parse (qglobal, z, (long) bgrade, cretry,
210 _uuconf_itime_grade_cmp,
211 &qset->uuconf_qtimegrade,
214 /* We treat a syntax error in the time field as equivalent
215 to ``never'', on the assumption that that is what V2
217 if (iret == UUCONF_SYNTAX_ERROR)
218 iret = UUCONF_SUCCESS;
220 if (iret != UUCONF_SUCCESS)
223 /* Treat any time/grade setting as both a timegrade and a
225 if (bgrade != UUCONF_GRADE_LOW)
226 qset->uuconf_qcalltimegrade = qset->uuconf_qtimegrade;
229 if (iret != UUCONF_SUCCESS)
235 /* Pick up the device name. It can be followed by a comma and a
236 list of protocols (this is not actually supported by most V2
237 systems, but it should be compatible). */
238 qset->uuconf_zport = pzsplit[2];
239 z = strchr (pzsplit[2], ',');
242 qset->uuconf_zprotocols = z + 1;
246 /* If the port is "TCP", we set up a system specific port. The
247 baud rate becomes the service number and the phone number
248 becomes the address (still stored in qsys->zphone). */
249 if (strcmp (qset->uuconf_zport, "TCP") == 0)
251 qset->uuconf_zport = NULL;
252 qset->uuconf_qport = ((struct uuconf_port *)
253 uuconf_malloc (pblock,
254 sizeof (struct uuconf_port)));
255 if (qset->uuconf_qport == NULL)
257 qglobal->ierrno = errno;
258 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
261 _uuconf_uclear_port (qset->uuconf_qport);
262 qset->uuconf_qport->uuconf_zname = (char *) "TCP";
263 qset->uuconf_qport->uuconf_ttype = UUCONF_PORTTYPE_TCP;
264 qset->uuconf_qport->uuconf_ireliable
265 = (UUCONF_RELIABLE_ENDTOEND | UUCONF_RELIABLE_RELIABLE
266 | UUCONF_RELIABLE_EIGHT | UUCONF_RELIABLE_FULLDUPLEX
267 | UUCONF_RELIABLE_SPECIFIED);
269 qset->uuconf_qport->uuconf_u.uuconf_stcp.uuconf_zport
272 qset->uuconf_qport->uuconf_u.uuconf_stcp.uuconf_zport
274 qset->uuconf_qport->uuconf_u.uuconf_stcp.uuconf_pzdialer = NULL;
280 qset->uuconf_ibaud = strtol (pzsplit[3], (char **) NULL, 10);
285 /* Get the phone number. */
286 qset->uuconf_zphone = pzsplit[4];
291 /* Get the chat script. We just hand this off to the chat
292 script processor, so that it will parse subsend and
293 subexpect strings correctly. */
294 pzsplit[4] = (char *) "chat";
295 iret = _uuconf_ichat_cmd (qglobal, ctoks - 4, pzsplit + 4,
296 &qset->uuconf_schat, pblock);
297 iret &=~ UUCONF_CMDTABRET_KEEP;
298 if (iret != UUCONF_SUCCESS)
305 free ((pointer) pzcomma);
307 if (iret != UUCONF_SUCCESS)
310 free ((pointer) zline);
312 free ((pointer) pzsplit);
313 qglobal->zfilename = qglobal->qprocess->zv2systems;
314 return iret | UUCONF_ERROR_FILENAME | UUCONF_ERROR_LINENO;
320 free ((pointer) zline);
322 free ((pointer) pzsplit);
323 return UUCONF_NOT_FOUND;
326 /* Now read USERFILE and L.cmds to get permissions. We can't fully
327 handle USERFILE since that specifies permissions based on local
328 users which we do not support. */
330 e = fopen (qglobal->qprocess->zv2userfile, "r");
333 char **pzlocal, **pzremote;
334 boolean fdefault_callback;
335 char *zdefault_login;
336 struct uuconf_system *q;
340 fdefault_callback = FALSE;
341 zdefault_login = NULL;
343 qglobal->ilineno = 0;
345 while ((cchars = getline (&zline, &cline, e)) > 0)
350 char **pzlist, **pznew;
355 if (zline[cchars] == '\n')
356 zline[cchars] = '\0';
357 zline[strcspn (zline, "#")] = '\0';
359 ctoks = _uuconf_istrsplit (zline, '\0', &pzsplit, &csplit);
362 qglobal->ierrno = errno;
363 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
370 /* The first field is username,machinename */
371 zcomma = strchr (pzsplit[0], ',');
377 /* The rest of the line is the list of directories, except
378 that if the first directory is "c" we must call the
381 pzlist = pzsplit + 1;
384 && pzsplit[1][0] == 'c'
385 && pzsplit[1][1] == '\0')
388 pzlist = pzsplit + 2;
392 /* Now pzsplit[0] is the user name, zcomma is the system
393 name, fcallback indicates whether a call back is
394 required, ctoks is the number of directories and pzlist
395 points to the directories. If the system name matches,
396 then the user name is the name that the system must use
397 to log in, and the list of directories is what may be
398 transferred in by either local or remote request.
399 Otherwise, if no system name matches, then the first
400 line with no user name gives the list of directories
401 that may be transferred by local request, and the first
402 line with no system name gives the list of directories
403 that may be transferred by remote request. */
404 if ((pzsplit[0][0] != '\0' || pzlocal != NULL)
405 && (zcomma[0] != '\0' || pzremote != NULL)
406 && strcmp (zcomma, zsystem) != 0)
409 /* NULL terminate the list of directories. */
410 pznew = (char **) uuconf_malloc (pblock,
411 (ctoks + 1) * sizeof (char *));
414 qglobal->ierrno = errno;
415 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
418 memcpy ((pointer) pznew, (pointer) pzlist,
419 ctoks * sizeof (char *));
422 if (uuconf_add_block (pblock, zline) != 0)
424 qglobal->ierrno = errno;
425 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
431 if (pzsplit[0][0] == '\0')
434 fdefault_callback = fcallback;
436 else if (zcomma[0] == '\0')
439 zdefault_login = pzsplit[0];
443 /* Both the login name and the machine name were
444 listed; require the machine to be logged in under
445 this name. This is not fully backward compatible,
446 and perhaps should be changed. On the other hand,
447 it is more useful. */
448 for (q = qsys; q != NULL; q = q->uuconf_qalternate)
450 q->uuconf_zcalled_login = pzsplit[0];
451 q->uuconf_fcallback = fcallback;
452 q->uuconf_pzlocal_send = pznew;
453 q->uuconf_pzlocal_receive = pznew;
454 q->uuconf_pzremote_send = pznew;
455 q->uuconf_pzremote_receive = pznew;
464 if (iret != UUCONF_SUCCESS)
467 free ((pointer) zline);
469 free ((pointer) pzsplit);
470 qglobal->zfilename = qglobal->qprocess->zv2userfile;
471 return iret | UUCONF_ERROR_FILENAME | UUCONF_ERROR_LINENO;
474 if (qsys->uuconf_pzlocal_send == (char **) &_uuconf_unset
477 for (q = qsys; q != NULL; q = q->uuconf_qalternate)
479 q->uuconf_fcallback = fdefault_callback;
480 q->uuconf_pzlocal_send = pzlocal;
481 q->uuconf_pzlocal_receive = pzlocal;
485 if (qsys->uuconf_pzremote_send == (char **) &_uuconf_unset
488 for (q = qsys; q != NULL; q = q->uuconf_qalternate)
490 q->uuconf_zcalled_login = zdefault_login;
491 q->uuconf_pzremote_send = pzremote;
492 q->uuconf_pzremote_receive = pzremote;
498 /* Now we must read L.cmds to determine which commands may be
501 e = fopen (qglobal->qprocess->zv2cmds, "r");
504 qglobal->ilineno = 0;
506 if (getline (&zline, &cline, e) > 0)
510 zline[strcspn (zline, "#\n")] = '\0';
512 while (*zline == '\0')
514 if (getline (&zline, &cline, e) <= 0)
518 free ((pointer) zline);
525 zline[strcspn (zline, "#\n")] = '\0';
530 && strncmp (zline, "PATH=", sizeof "PATH=" - 1) == 0)
535 zline += sizeof "PATH=" - 1;
536 ctoks = _uuconf_istrsplit (zline, ':', &pzsplit, &csplit);
539 qglobal->ierrno = errno;
540 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
544 if (iret == UUCONF_SUCCESS)
547 uuconf_malloc (pblock,
548 (ctoks + 1) * sizeof (char *)));
550 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
552 if (iret == UUCONF_SUCCESS)
554 memcpy ((pointer) pznew, (pointer) pzsplit,
555 ctoks * sizeof (char *));
557 qsys->uuconf_pzpath = pznew;
562 if (getline (&zline, &cline, e) < 0)
566 free ((pointer) zline);
575 if (iret == UUCONF_SUCCESS && zline != NULL)
579 zline[strcspn (zline, "#,\n")] = '\0';
582 iret = _uuconf_iadd_string (qglobal, zline, TRUE, FALSE,
583 &qsys->uuconf_pzcmds,
585 if (iret != UUCONF_SUCCESS)
588 if (getline (&zline, &cline, e) < 0)
596 if (iret != UUCONF_SUCCESS)
598 qglobal->zfilename = qglobal->qprocess->zv2cmds;
599 iret |= UUCONF_ERROR_FILENAME | UUCONF_ERROR_LINENO;
605 free ((pointer) zline);
607 free ((pointer) pzsplit);