|
|
1.1 root 1: /* vsinfo.c
2: Get information about a system from the V2 configuration files.
3:
4: Copyright (C) 1992 Ian Lance Taylor
5:
6: This file is part of the Taylor UUCP uuconf library.
7:
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.
12:
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.
17:
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., 675 Mass Ave, Cambridge, MA 02139, USA.
21:
22: The author of the program may be contacted at [email protected] or
23: c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
24: */
25:
26: #include "uucnfi.h"
27:
28: #if USE_RCS_ID
29: const char _uuconf_vsinfo_rcsid[] = "$Id: vsinfo.c,v 1.1 93/07/30 08:08:21 bin Exp Locker: bin $";
30: #endif
31:
32: #include <errno.h>
33: #include <ctype.h>
34:
35: /* Get the information for a particular system from the V2
36: configuration files. This does not make sure that all the default
37: values are set. */
38:
39: int
40: _uuconf_iv2_system_internal (qglobal, zsystem, qsys)
41: struct sglobal *qglobal;
42: const char *zsystem;
43: struct uuconf_system *qsys;
44: {
45: char *zline;
46: size_t cline;
47: char **pzsplit;
48: size_t csplit;
49: char **pzcomma;
50: size_t ccomma;
51: FILE *e;
52: int cchars;
53: pointer pblock;
54: int iret;
55:
56: e = fopen (qglobal->qprocess->zv2systems, "r");
57: if (e == NULL)
58: {
59: if (FNO_SUCH_FILE ())
60: return UUCONF_NOT_FOUND;
61: qglobal->ierrno = errno;
62: qglobal->zfilename = qglobal->qprocess->zv2systems;
63: return (UUCONF_FOPEN_FAILED
64: | UUCONF_ERROR_ERRNO
65: | UUCONF_ERROR_FILENAME);
66: }
67:
68: zline = NULL;
69: cline = 0;
70: pzsplit = NULL;
71: csplit = 0;
72: pzcomma = NULL;
73: ccomma = 0;
74:
75: pblock = NULL;
76: iret = UUCONF_SUCCESS;
77:
78: qglobal->ilineno = 0;
79:
80: while ((cchars = getline (&zline, &cline, e)) > 0)
81: {
82: int ctoks, ctimes, i;
83: struct uuconf_system *qset;
84: char *z, *zretry;
85: int cretry;
86:
87: ++qglobal->ilineno;
88:
89: --cchars;
90: if (zline[cchars] == '\n')
91: zline[cchars] = '\0';
92: zline[strcspn (zline, "#")] = '\0';
93:
94: ctoks = _uuconf_istrsplit (zline, '\0', &pzsplit, &csplit);
95: if (ctoks < 0)
96: {
97: qglobal->ierrno = errno;
98: iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
99: break;
100: }
101:
102: /* If this isn't the system we're looking for, keep reading
103: the file. */
104: if (ctoks < 1
105: || strcmp (zsystem, pzsplit[0]) != 0)
106: continue;
107:
108: /* If this is the first time we've found the system, we want
109: to set *qsys directly. Otherwise, we allocate a new
110: alternate. */
111: if (pblock == NULL)
112: {
113: pblock = uuconf_malloc_block ();
114: if (pblock == NULL)
115: {
116: qglobal->ierrno = errno;
117: iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
118: break;
119: }
120: _uuconf_uclear_system (qsys);
121: qsys->uuconf_palloc = pblock;
122: qset = qsys;
123: }
124: else
125: {
126: struct uuconf_system **pq;
127:
128: qset = ((struct uuconf_system *)
129: uuconf_malloc (pblock, sizeof (struct uuconf_system)));
130: if (qset == NULL)
131: {
132: qglobal->ierrno = errno;
133: iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
134: break;
135: }
136: _uuconf_uclear_system (qset);
137: for (pq = &qsys->uuconf_qalternate;
138: *pq != NULL;
139: pq = &(*pq)->uuconf_qalternate)
140: ;
141: *pq = qset;
142: }
143:
144: /* Add this line to the memory block we are building for the
145: system. */
146: if (uuconf_add_block (pblock, zline) != 0)
147: {
148: qglobal->ierrno = errno;
149: iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
150: break;
151: }
152:
153: zline = NULL;
154: cline = 0;
155:
156: /* The format of a line in Systems is
157: system time device speed phone chat
158: For example,
159: airs Any ACU 9600 5551212 ogin: foo pass: bar
160: */
161:
162: /* Get the system name. */
163:
164: qset->uuconf_zname = pzsplit[0];
165: qset->uuconf_fcall = TRUE;
166: qset->uuconf_fcalled = TRUE;
167:
168: if (ctoks < 2)
169: continue;
170:
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
174: here. */
175: zretry = strchr (pzsplit[1], ';');
176: if (zretry == NULL)
177: cretry = 0;
178: else
179: {
180: *zretry = '\0';
181: cretry = (int) strtol (zretry + 1, (char **) NULL, 10);
182: }
183:
184: ctimes = _uuconf_istrsplit (pzsplit[1], ',', &pzcomma, &ccomma);
185: if (ctimes < 0)
186: {
187: qglobal->ierrno = errno;
188: iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
189: break;
190: }
191:
192: for (i = 0; i < ctimes; i++)
193: {
194: char *zslash;
195: char bgrade;
196:
197: z = pzcomma[i];
198: zslash = strchr (z, '/');
199: if (zslash == NULL)
200: bgrade = UUCONF_GRADE_LOW;
201: else
202: {
203: *zslash = '\0';
204: bgrade = zslash[1];
205: if (! UUCONF_GRADE_LEGAL (bgrade))
206: bgrade = UUCONF_GRADE_LOW;
207: }
208:
209: iret = _uuconf_itime_parse (qglobal, z, (long) bgrade, cretry,
210: _uuconf_itime_grade_cmp,
211: &qset->uuconf_qtimegrade,
212: pblock);
213: if (iret != UUCONF_SUCCESS)
214: break;
215: }
216:
217: if (iret != UUCONF_SUCCESS)
218: break;
219:
220: if (ctoks < 3)
221: continue;
222:
223: /* Pick up the device name. It can be followed by a comma and a
224: list of protocols (this is not actually supported by most V2
225: systems, but it should be compatible). */
226: qset->uuconf_zport = pzsplit[2];
227: z = strchr (pzsplit[2], ',');
228: if (z != NULL)
229: {
230: qset->uuconf_zprotocols = z + 1;
231: *z = '\0';
232: }
233:
234: /* If the port is "TCP", we set up a system specific port. The
235: baud rate becomes the service number and the phone number
236: becomes the address (still stored in qsys->zphone). */
237: if (strcmp (qset->uuconf_zport, "TCP") == 0)
238: {
239: qset->uuconf_zport = NULL;
240: qset->uuconf_qport = ((struct uuconf_port *)
241: uuconf_malloc (pblock,
242: sizeof (struct uuconf_port)));
243: if (qset->uuconf_qport == NULL)
244: {
245: qglobal->ierrno = errno;
246: iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
247: break;
248: }
249: _uuconf_uclear_port (qset->uuconf_qport);
250: qset->uuconf_qport->uuconf_zname = (char *) "TCP";
251: qset->uuconf_qport->uuconf_ttype = UUCONF_PORTTYPE_TCP;
252: qset->uuconf_qport->uuconf_ireliable
253: = (UUCONF_RELIABLE_ENDTOEND | UUCONF_RELIABLE_RELIABLE
254: | UUCONF_RELIABLE_EIGHT | UUCONF_RELIABLE_FULLDUPLEX
255: | UUCONF_RELIABLE_SPECIFIED);
256: if (ctoks < 4)
257: qset->uuconf_qport->uuconf_u.uuconf_stcp.uuconf_zport
258: = (char *) "uucp";
259: else
260: qset->uuconf_qport->uuconf_u.uuconf_stcp.uuconf_zport
261: = pzsplit[3];
262: }
263:
264: if (ctoks < 4)
265: continue;
266:
267: qset->uuconf_ibaud = strtol (pzsplit[3], (char **) NULL, 10);
268:
269: if (ctoks < 5)
270: continue;
271:
272: /* Get the phone number. */
273: qset->uuconf_zphone = pzsplit[4];
274:
275: if (ctoks < 6)
276: continue;
277:
278: /* Get the chat script. We just hand this off to the chat
279: script processor, so that it will parse subsend and
280: subexpect strings correctly. */
281: pzsplit[4] = (char *) "chat";
282: iret = _uuconf_ichat_cmd (qglobal, ctoks - 4, pzsplit + 4,
283: &qset->uuconf_schat, pblock);
284: iret &=~ UUCONF_CMDTABRET_KEEP;
285: if (iret != UUCONF_SUCCESS)
286: break;
287: }
288:
289: (void) fclose (e);
290:
291: if (pzcomma != NULL)
292: free ((pointer) pzcomma);
293:
294: if (iret != UUCONF_SUCCESS)
295: {
296: if (zline != NULL)
297: free ((pointer) zline);
298: if (pzsplit != NULL)
299: free ((pointer) pzsplit);
300: qglobal->zfilename = qglobal->qprocess->zv2systems;
301: return iret | UUCONF_ERROR_FILENAME | UUCONF_ERROR_LINENO;
302: }
303:
304: if (pblock == NULL)
305: {
306: if (zline != NULL)
307: free ((pointer) zline);
308: if (pzsplit != NULL)
309: free ((pointer) pzsplit);
310: return UUCONF_NOT_FOUND;
311: }
312:
313: /* Now read USERFILE and L.cmds to get permissions. We can't fully
314: handle USERFILE since that specifies permissions based on local
315: users which we do not support. */
316: {
317: e = fopen (qglobal->qprocess->zv2userfile, "r");
318: if (e != NULL)
319: {
320: char **pzlocal, **pzremote;
321: boolean fdefault_callback;
322: char *zdefault_login;
323: struct uuconf_system *q;
324:
325: pzlocal = NULL;
326: pzremote = NULL;
327: fdefault_callback = FALSE;
328: zdefault_login = NULL;
329:
330: qglobal->ilineno = 0;
331:
332: while ((cchars = getline (&zline, &cline, e)) > 0)
333: {
334: int ctoks;
335: char *zcomma;
336: boolean fcallback;
337: char **pzlist, **pznew;
338:
339: ++qglobal->ilineno;
340:
341: --cchars;
342: if (zline[cchars] == '\n')
343: zline[cchars] = '\0';
344: zline[strcspn (zline, "#")] = '\0';
345:
346: ctoks = _uuconf_istrsplit (zline, '\0', &pzsplit, &csplit);
347: if (ctoks < 0)
348: {
349: qglobal->ierrno = errno;
350: iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
351: break;
352: }
353:
354: if (ctoks == 0)
355: continue;
356:
357: /* The first field is username,machinename */
358: zcomma = strchr (pzsplit[0], ',');
359: if (zcomma == NULL)
360: continue;
361:
362: *zcomma++ = '\0';
363:
364: /* The rest of the line is the list of directories, except
365: that if the first directory is "c" we must call the
366: system back. */
367: fcallback = FALSE;
368: pzlist = pzsplit + 1;
369: --ctoks;
370: if (ctoks > 0
371: && pzsplit[1][0] == 'c'
372: && pzsplit[1][1] == '\0')
373: {
374: fcallback = TRUE;
375: pzlist = pzsplit + 2;
376: --ctoks;
377: }
378:
379: /* Now pzsplit[0] is the user name, zcomma is the system
380: name, fcallback indicates whether a call back is
381: required, ctoks is the number of directories and pzlist
382: points to the directories. If the system name matches,
383: then the user name is the name that the system must use
384: to log in, and the list of directories is what may be
385: transferred in by either local or remote request.
386: Otherwise, if no system name matches, then the first
387: line with no user name gives the list of directories
388: that may be transferred by local request, and the first
389: line with no system name gives the list of directories
390: that may be transferred by remote request. */
391: if ((pzsplit[0][0] != '\0' || pzlocal != NULL)
392: && (zcomma[0] != '\0' || pzremote != NULL)
393: && strcmp (zcomma, zsystem) != 0)
394: continue;
395:
396: /* NULL terminate the list of directories. */
397: pznew = (char **) uuconf_malloc (pblock,
398: (ctoks + 1) * sizeof (char *));
399: if (pznew == NULL)
400: {
401: qglobal->ierrno = errno;
402: iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
403: break;
404: }
405: memcpy ((pointer) pznew, (pointer) pzlist,
406: ctoks * sizeof (char *));
407: pznew[ctoks] = NULL;
408:
409: if (uuconf_add_block (pblock, zline) != 0)
410: {
411: qglobal->ierrno = errno;
412: iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
413: break;
414: }
415: zline = NULL;
416: cline = 0;
417:
418: if (pzsplit[0][0] == '\0')
419: {
420: pzlocal = pznew;
421: fdefault_callback = fcallback;
422: }
423: else if (zcomma[0] == '\0')
424: {
425: pzremote = pznew;
426: zdefault_login = pzsplit[0];
427: }
428: else
429: {
430: /* Both the login name and the machine name were
431: listed; require the machine to be logged in under
432: this name. This is not fully backward compatible,
433: and perhaps should be changed. On the other hand,
434: it is more useful. */
435: for (q = qsys; q != NULL; q = q->uuconf_qalternate)
436: {
437: q->uuconf_zcalled_login = pzsplit[0];
438: q->uuconf_fcallback = fcallback;
439: q->uuconf_pzlocal_send = pznew;
440: q->uuconf_pzlocal_receive = pznew;
441: q->uuconf_pzremote_send = pznew;
442: q->uuconf_pzremote_receive = pznew;
443: }
444:
445: break;
446: }
447: }
448:
449: (void) fclose (e);
450:
451: if (iret != UUCONF_SUCCESS)
452: {
453: if (zline != NULL)
454: free ((pointer) zline);
455: if (pzsplit != NULL)
456: free ((pointer) pzsplit);
457: qglobal->zfilename = qglobal->qprocess->zv2userfile;
458: return iret | UUCONF_ERROR_FILENAME | UUCONF_ERROR_LINENO;
459: }
460:
461: if (qsys->uuconf_pzlocal_send == (char **) &_uuconf_unset
462: && pzlocal != NULL)
463: {
464: for (q = qsys; q != NULL; q = q->uuconf_qalternate)
465: {
466: q->uuconf_fcallback = fdefault_callback;
467: q->uuconf_pzlocal_send = pzlocal;
468: q->uuconf_pzlocal_receive = pzlocal;
469: }
470: }
471:
472: if (qsys->uuconf_pzremote_send == (char **) &_uuconf_unset
473: && pzremote != NULL)
474: {
475: for (q = qsys; q != NULL; q = q->uuconf_qalternate)
476: {
477: q->uuconf_zcalled_login = zdefault_login;
478: q->uuconf_pzremote_send = pzremote;
479: q->uuconf_pzremote_receive = pzremote;
480: }
481: }
482: }
483: }
484:
485: /* Now we must read L.cmds to determine which commands may be
486: executed. */
487: {
488: e = fopen (qglobal->qprocess->zv2cmds, "r");
489: if (e != NULL)
490: {
491: qglobal->ilineno = 0;
492:
493: if (getline (&zline, &cline, e) > 0)
494: {
495: ++qglobal->ilineno;
496:
497: zline[strcspn (zline, "#\n")] = '\0';
498: if (strncmp (zline, "PATH=", sizeof "PATH=" - 1) == 0)
499: {
500: int ctoks;
501: char **pznew;
502:
503: zline += sizeof "PATH=" - 1;
504: ctoks = _uuconf_istrsplit (zline, ':', &pzsplit, &csplit);
505: if (ctoks < 0)
506: {
507: qglobal->ierrno = errno;
508: iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
509: }
510:
511: pznew = NULL;
512: if (iret == UUCONF_SUCCESS)
513: {
514: pznew = ((char **)
515: uuconf_malloc (pblock,
516: (ctoks + 1) * sizeof (char *)));
517: if (pznew == NULL)
518: iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
519: }
520: if (iret == UUCONF_SUCCESS)
521: {
522: memcpy ((pointer) pznew, (pointer) pzsplit,
523: ctoks * sizeof (char *));
524: pznew[ctoks] = NULL;
525: qsys->uuconf_pzpath = pznew;
526: zline = NULL;
527: cline = 0;
528: }
529:
530: if (getline (&zline, &cline, e) < 0)
531: {
532: if (zline != NULL)
533: {
534: free ((pointer) zline);
535: zline = NULL;
536: }
537: }
538: else
539: ++qglobal->ilineno;
540: }
541: }
542:
543: if (iret == UUCONF_SUCCESS && zline != NULL)
544: {
545: while (TRUE)
546: {
547: zline[strcspn (zline, "#\n")] = '\0';
548: iret = _uuconf_iadd_string (qglobal, zline, TRUE, FALSE,
549: &qsys->uuconf_pzcmds,
550: pblock);
551: if (iret != UUCONF_SUCCESS)
552: break;
553: if (getline (&zline, &cline, e) < 0)
554: break;
555: ++qglobal->ilineno;
556: }
557: }
558:
559: (void) fclose (e);
560:
561: if (iret != UUCONF_SUCCESS)
562: {
563: qglobal->zfilename = qglobal->qprocess->zv2cmds;
564: iret |= UUCONF_ERROR_FILENAME | UUCONF_ERROR_LINENO;
565: }
566: }
567: }
568:
569: if (zline != NULL)
570: free ((pointer) zline);
571: if (pzsplit != NULL)
572: free ((pointer) pzsplit);
573:
574: return iret;
575: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.