|
|
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.