|
|
1.1 ! root 1: /* hsinfo.c ! 2: Get information about a system from the HDB 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_hsinfo_rcsid[] = "$Id: hsinfo.c,v 1.1 93/07/30 08:07:17 bin Exp Locker: bin $"; ! 30: #endif ! 31: ! 32: #include <errno.h> ! 33: #include <ctype.h> ! 34: ! 35: static int ihadd_machine_perm P((struct sglobal *qglobal, ! 36: struct uuconf_system *qsys, ! 37: struct shpermissions *qperm)); ! 38: static int ihadd_logname_perm P((struct sglobal *qglobal, ! 39: struct uuconf_system *qsys, ! 40: struct shpermissions *qperm)); ! 41: ! 42: /* Get the information for a particular system from the HDB ! 43: configuration files. This does not make sure that all the default ! 44: values are set. */ ! 45: ! 46: int ! 47: _uuconf_ihdb_system_internal (qglobal, zsystem, qsys) ! 48: struct sglobal *qglobal; ! 49: const char *zsystem; ! 50: struct uuconf_system *qsys; ! 51: { ! 52: int iret; ! 53: struct shpermissions *qperm; ! 54: char *zline; ! 55: size_t cline; ! 56: char **pzsplit; ! 57: size_t csplit; ! 58: char **pzcomma; ! 59: size_t ccomma; ! 60: pointer pblock; ! 61: char **pz; ! 62: boolean ffound_machine, ffound_login; ! 63: struct shpermissions *qother_machine; ! 64: struct uuconf_system *qalt; ! 65: ! 66: if (! qglobal->qprocess->fhdb_read_permissions) ! 67: { ! 68: iret = _uuconf_ihread_permissions (qglobal); ! 69: if (iret != UUCONF_SUCCESS) ! 70: return iret; ! 71: } ! 72: ! 73: /* First look through the Permissions information to see if this is ! 74: an alias for some system. I assume that an alias applies to the ! 75: first name in the corresponding MACHINE entry. */ ! 76: ! 77: for (qperm = qglobal->qprocess->qhdb_permissions; ! 78: qperm != NULL; ! 79: qperm = qperm->qnext) ! 80: { ! 81: if (qperm->pzalias == NULL ! 82: || qperm->pzmachine == NULL ! 83: || qperm->pzalias == (char **) &_uuconf_unset ! 84: || qperm->pzmachine == (char **) &_uuconf_unset) ! 85: continue; ! 86: ! 87: for (pz = qperm->pzalias; *pz != NULL; pz++) ! 88: { ! 89: if (strcmp (*pz, zsystem) == 0) ! 90: { ! 91: zsystem = qperm->pzmachine[0]; ! 92: break; ! 93: } ! 94: } ! 95: if (*pz != NULL) ! 96: break; ! 97: } ! 98: ! 99: zline = NULL; ! 100: cline = 0; ! 101: pzsplit = NULL; ! 102: csplit = 0; ! 103: pzcomma = NULL; ! 104: ccomma = 0; ! 105: ! 106: pblock = NULL; ! 107: ! 108: iret = UUCONF_SUCCESS; ! 109: ! 110: for (pz = qglobal->qprocess->pzhdb_systems; *pz != NULL; pz++) ! 111: { ! 112: FILE *e; ! 113: int cchars; ! 114: ! 115: e = fopen (*pz, "r"); ! 116: if (e == NULL) ! 117: { ! 118: if (FNO_SUCH_FILE ()) ! 119: continue; ! 120: qglobal->ierrno = errno; ! 121: iret = UUCONF_FOPEN_FAILED | UUCONF_ERROR_ERRNO; ! 122: break; ! 123: } ! 124: ! 125: qglobal->ilineno = 0; ! 126: ! 127: while ((cchars = _uuconf_getline (qglobal, &zline, &cline, e)) > 0) ! 128: { ! 129: int ctoks, ctimes, i; ! 130: struct uuconf_system *qset; ! 131: char *z, *zretry; ! 132: int cretry; ! 133: ! 134: ++qglobal->ilineno; ! 135: ! 136: --cchars; ! 137: if (zline[cchars] == '\n') ! 138: zline[cchars] = '\0'; ! 139: if (isspace (BUCHAR (zline[0])) || zline[0] == '#') ! 140: continue; ! 141: ! 142: ctoks = _uuconf_istrsplit (zline, '\0', &pzsplit, &csplit); ! 143: if (ctoks < 0) ! 144: { ! 145: qglobal->ierrno = errno; ! 146: iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO; ! 147: break; ! 148: } ! 149: ! 150: /* If this isn't the system we're looking for, keep reading ! 151: the file. */ ! 152: if (ctoks < 1 ! 153: || strcmp (zsystem, pzsplit[0]) != 0) ! 154: continue; ! 155: ! 156: /* If this is the first time we've found the system, we want ! 157: to set *qsys directly. Otherwise, we allocate a new ! 158: alternate. */ ! 159: if (pblock == NULL) ! 160: { ! 161: pblock = uuconf_malloc_block (); ! 162: if (pblock == NULL) ! 163: { ! 164: qglobal->ierrno = errno; ! 165: iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO; ! 166: break; ! 167: } ! 168: _uuconf_uclear_system (qsys); ! 169: qsys->uuconf_palloc = pblock; ! 170: qset = qsys; ! 171: } ! 172: else ! 173: { ! 174: struct uuconf_system **pq; ! 175: ! 176: qset = ((struct uuconf_system *) ! 177: uuconf_malloc (pblock, sizeof (struct uuconf_system))); ! 178: if (qset == NULL) ! 179: { ! 180: qglobal->ierrno = errno; ! 181: iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO; ! 182: break; ! 183: } ! 184: _uuconf_uclear_system (qset); ! 185: for (pq = &qsys->uuconf_qalternate; ! 186: *pq != NULL; ! 187: pq = &(*pq)->uuconf_qalternate) ! 188: ; ! 189: *pq = qset; ! 190: } ! 191: ! 192: /* Add this line to the memory block we are building for the ! 193: system. */ ! 194: if (uuconf_add_block (pblock, zline) != 0) ! 195: { ! 196: qglobal->ierrno = errno; ! 197: iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO; ! 198: break; ! 199: } ! 200: ! 201: zline = NULL; ! 202: cline = 0; ! 203: ! 204: /* The format of a line in Systems is ! 205: system time device speed phone chat ! 206: For example, ! 207: airs Any ACU 9600 5551212 ogin: foo pass: bar ! 208: */ ! 209: ! 210: /* Get the system name. */ ! 211: ! 212: qset->uuconf_zname = pzsplit[0]; ! 213: qset->uuconf_fcall = TRUE; ! 214: qset->uuconf_fcalled = FALSE; ! 215: ! 216: if (ctoks < 2) ! 217: continue; ! 218: ! 219: /* A time string is "time/grade,time/grade;retry". A ! 220: missing grade is taken as BGRADE_LOW. */ ! 221: zretry = strchr (pzsplit[1], ';'); ! 222: if (zretry == NULL) ! 223: cretry = 0; ! 224: else ! 225: { ! 226: *zretry = '\0'; ! 227: cretry = (int) strtol (zretry + 1, (char **) NULL, 10); ! 228: } ! 229: ! 230: ctimes = _uuconf_istrsplit (pzsplit[1], ',', &pzcomma, &ccomma); ! 231: if (ctimes < 0) ! 232: { ! 233: qglobal->ierrno = errno; ! 234: iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO; ! 235: break; ! 236: } ! 237: ! 238: for (i = 0; i < ctimes; i++) ! 239: { ! 240: char *zslash; ! 241: char bgrade; ! 242: ! 243: z = pzcomma[i]; ! 244: zslash = strchr (z, '/'); ! 245: if (zslash == NULL) ! 246: bgrade = UUCONF_GRADE_LOW; ! 247: else ! 248: { ! 249: *zslash = '\0'; ! 250: bgrade = zslash[1]; ! 251: if (! UUCONF_GRADE_LEGAL (bgrade)) ! 252: bgrade = UUCONF_GRADE_LOW; ! 253: } ! 254: ! 255: iret = _uuconf_itime_parse (qglobal, z, (long) bgrade, ! 256: cretry, _uuconf_itime_grade_cmp, ! 257: &qset->uuconf_qtimegrade, ! 258: pblock); ! 259: if (iret != UUCONF_SUCCESS) ! 260: break; ! 261: } ! 262: ! 263: if (iret != UUCONF_SUCCESS) ! 264: break; ! 265: ! 266: if (ctoks < 3) ! 267: continue; ! 268: ! 269: /* Pick up the device name. It can be followed by a comma ! 270: and a list of protocols. */ ! 271: qset->uuconf_zport = pzsplit[2]; ! 272: z = strchr (pzsplit[2], ','); ! 273: if (z != NULL) ! 274: { ! 275: qset->uuconf_zprotocols = z + 1; ! 276: *z = '\0'; ! 277: } ! 278: ! 279: if (ctoks < 4) ! 280: continue; ! 281: ! 282: /* The speed entry can be a numeric speed, or a range of ! 283: speeds, or "Any", or "-". If it starts with a letter, ! 284: the initial nonnumeric prefix is a modem class, which ! 285: gets appended to the port name. */ ! 286: z = pzsplit[3]; ! 287: if (strcasecmp (z, "Any") != 0 ! 288: && strcmp (z, "-") != 0) ! 289: { ! 290: char *zend; ! 291: ! 292: while (*z != '\0' && ! isdigit (BUCHAR (*z))) ! 293: ++z; ! 294: ! 295: qset->uuconf_ibaud = strtol (z, &zend, 10); ! 296: if (*zend == '-') ! 297: qset->uuconf_ihighbaud = strtol (zend + 1, (char **) NULL, ! 298: 10); ! 299: ! 300: if (z != pzsplit[3]) ! 301: { ! 302: size_t cport, cclass; ! 303: ! 304: cport = strlen (pzsplit[2]); ! 305: cclass = z - pzsplit[3]; ! 306: qset->uuconf_zport = uuconf_malloc (pblock, ! 307: cport + cclass + 1); ! 308: if (qset->uuconf_zport == NULL) ! 309: { ! 310: qglobal->ierrno = errno; ! 311: iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO; ! 312: break; ! 313: } ! 314: memcpy ((pointer) qset->uuconf_zport, (pointer) pzsplit[2], ! 315: cport); ! 316: memcpy ((pointer) (qset->uuconf_zport + cport), ! 317: (pointer) pzsplit[3], cclass); ! 318: qset->uuconf_zport[cport + cclass] = '\0'; ! 319: } ! 320: } ! 321: ! 322: if (ctoks < 5) ! 323: continue; ! 324: ! 325: /* Get the phone number. */ ! 326: qset->uuconf_zphone = pzsplit[4]; ! 327: ! 328: if (ctoks < 6) ! 329: continue; ! 330: ! 331: /* Get the chat script. We just hand this off to the chat ! 332: script processor, so that it will parse subsend and ! 333: subexpect strings correctly. */ ! 334: pzsplit[4] = (char *) "chat"; ! 335: iret = _uuconf_ichat_cmd (qglobal, ctoks - 4, pzsplit + 4, ! 336: &qset->uuconf_schat, pblock); ! 337: iret &=~ UUCONF_CMDTABRET_KEEP; ! 338: if (iret != UUCONF_SUCCESS) ! 339: break; ! 340: } ! 341: ! 342: (void) fclose (e); ! 343: ! 344: if (iret != UUCONF_SUCCESS) ! 345: break; ! 346: } ! 347: ! 348: if (zline != NULL) ! 349: free ((pointer) zline); ! 350: if (pzsplit != NULL) ! 351: free ((pointer) pzsplit); ! 352: if (pzcomma != NULL) ! 353: free ((pointer) pzcomma); ! 354: ! 355: if (iret != UUCONF_SUCCESS) ! 356: { ! 357: qglobal->zfilename = *pz; ! 358: return iret | UUCONF_ERROR_FILENAME; ! 359: } ! 360: ! 361: if (pblock == NULL) ! 362: return UUCONF_NOT_FOUND; ! 363: ! 364: /* Now we have to put in the Permissions information. The relevant ! 365: Permissions entries are those with this system in the MACHINE ! 366: list and (if this system does not have a VALIDATE entry) those ! 367: with a LOGNAME list but no MACHINE list. If no entry is found ! 368: with this system in the MACHINE list, then we must look for an ! 369: entry with "OTHER" in the MACHINE list. */ ! 370: ffound_machine = FALSE; ! 371: ffound_login = FALSE; ! 372: qother_machine = NULL; ! 373: for (qperm = qglobal->qprocess->qhdb_permissions; ! 374: qperm != NULL; ! 375: qperm = qperm->qnext) ! 376: { ! 377: boolean fmachine; ! 378: ! 379: /* MACHINE=OTHER is recognized specially. It appears that OTHER ! 380: need only be recognized by itself, not when combined with ! 381: other machine names. */ ! 382: if (qother_machine == NULL ! 383: && qperm->pzmachine != NULL ! 384: && qperm->pzmachine != (char **) &_uuconf_unset ! 385: && qperm->pzmachine[0][0] == 'O' ! 386: && strcmp (qperm->pzmachine[0], "OTHER") == 0) ! 387: qother_machine = qperm; ! 388: ! 389: /* If this system is named in a MACHINE entry, we must add the ! 390: appropriate information to every alternate that could be used ! 391: for calling out. */ ! 392: fmachine = FALSE; ! 393: if (! ffound_machine ! 394: && qperm->pzmachine != NULL ! 395: && qperm->pzmachine != (char **) &_uuconf_unset) ! 396: { ! 397: for (pz = qperm->pzmachine; *pz != NULL; pz++) ! 398: { ! 399: if ((*pz)[0] == zsystem[0] ! 400: && strcmp (*pz, zsystem) == 0) ! 401: { ! 402: for (qalt = qsys; ! 403: qalt != NULL; ! 404: qalt = qalt->uuconf_qalternate) ! 405: { ! 406: if (qalt->uuconf_fcall) ! 407: { ! 408: iret = ihadd_machine_perm (qglobal, qalt, qperm); ! 409: if (iret != UUCONF_SUCCESS) ! 410: return iret; ! 411: } ! 412: } ! 413: ! 414: fmachine = TRUE; ! 415: ffound_machine = TRUE; ! 416: ! 417: break; ! 418: } ! 419: } ! 420: } ! 421: ! 422: /* A LOGNAME line applies to this machine if it is listed in the ! 423: corresponding VALIDATE entry, or if it is not listed in any ! 424: VALIDATE entry. On this pass through the Permissions entry ! 425: we pick up the information if the system appears in a ! 426: VALIDATE entry; if it does not, we make another pass to put ! 427: in all the LOGNAME lines. */ ! 428: if (qperm->pzlogname != NULL ! 429: && qperm->pzlogname != (char **) &_uuconf_unset ! 430: && qperm->pzvalidate != NULL ! 431: && qperm->pzvalidate != (char **) &_uuconf_unset) ! 432: { ! 433: for (pz = qperm->pzvalidate; *pz != NULL; ++pz) ! 434: if ((*pz)[0] == zsystem[0] ! 435: && strcmp (*pz, zsystem) == 0) ! 436: break; ! 437: if (*pz != NULL) ! 438: { ! 439: for (pz = qperm->pzlogname; *pz != NULL; ++pz) ! 440: { ! 441: /* If this LOGNAME line is also a matching MACHINE ! 442: line, we can add the LOGNAME permissions to the ! 443: first alternate. Otherwise, we must create a new ! 444: alternate. We cannot put a LOGNAME line in the ! 445: first alternate if MACHINE does not match, ! 446: because certain permissions (e.g. READ) may be ! 447: specified by both types of lines, and we must use ! 448: LOGNAME entries only when accepting calls and ! 449: MACHINE entries only when placing calls. */ ! 450: if (fmachine ! 451: && (qsys->uuconf_zcalled_login == NULL ! 452: || (qsys->uuconf_zcalled_login ! 453: == (char *) &_uuconf_unset))) ! 454: { ! 455: qsys->uuconf_zcalled_login = *pz; ! 456: iret = ihadd_logname_perm (qglobal, qsys, qperm); ! 457: } ! 458: else ! 459: { ! 460: struct uuconf_system *qnew; ! 461: struct uuconf_system **pq; ! 462: ! 463: qnew = ((struct uuconf_system *) ! 464: uuconf_malloc (pblock, ! 465: sizeof (struct uuconf_system))); ! 466: if (qnew == NULL) ! 467: { ! 468: qglobal->ierrno = errno; ! 469: return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO; ! 470: } ! 471: ! 472: *qnew = *qsys; ! 473: qnew->uuconf_qalternate = NULL; ! 474: for (pq = &qsys->uuconf_qalternate; ! 475: *pq != NULL; ! 476: pq = &(*pq)->uuconf_qalternate) ! 477: ; ! 478: *pq = qnew; ! 479: ! 480: qnew->uuconf_zcalled_login = *pz; ! 481: qnew->uuconf_fcall = FALSE; ! 482: iret = ihadd_logname_perm (qglobal, qnew, qperm); ! 483: } ! 484: ! 485: if (iret != UUCONF_SUCCESS) ! 486: return iret; ! 487: } ! 488: ! 489: ffound_login = TRUE; ! 490: } ! 491: } ! 492: } ! 493: ! 494: /* If we didn't find an entry for the machine, we must use the ! 495: MACHINE=OTHER entry, if any. */ ! 496: if (! ffound_machine && qother_machine != NULL) ! 497: { ! 498: for (qalt = qsys; qalt != NULL; qalt = qalt->uuconf_qalternate) ! 499: { ! 500: if (qalt->uuconf_fcall) ! 501: { ! 502: iret = ihadd_machine_perm (qglobal, qalt, qother_machine); ! 503: if (iret != UUCONF_SUCCESS) ! 504: return iret; ! 505: } ! 506: } ! 507: } ! 508: ! 509: /* If this system was not listed in any VALIDATE entry, then we must ! 510: add a called-login for each LOGNAME entry in Permissions. */ ! 511: if (! ffound_login) ! 512: { ! 513: for (qperm = qglobal->qprocess->qhdb_permissions; ! 514: qperm != NULL; ! 515: qperm = qperm->qnext) ! 516: { ! 517: if (qperm->pzlogname == NULL ! 518: || qperm->pzlogname == (char **) &_uuconf_unset) ! 519: continue; ! 520: ! 521: for (pz = qperm->pzlogname; *pz != NULL; pz++) ! 522: { ! 523: struct uuconf_system *qnew; ! 524: struct uuconf_system **pq; ! 525: ! 526: qnew = ((struct uuconf_system *) ! 527: uuconf_malloc (pblock, ! 528: sizeof (struct uuconf_system))); ! 529: if (qnew == NULL) ! 530: { ! 531: qglobal->ierrno = errno; ! 532: return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO; ! 533: } ! 534: ! 535: *qnew = *qsys; ! 536: qnew->uuconf_qalternate = NULL; ! 537: for (pq = &qsys->uuconf_qalternate; ! 538: *pq != NULL; ! 539: pq = &(*pq)->uuconf_qalternate) ! 540: ; ! 541: *pq = qnew; ! 542: ! 543: /* We recognize LOGNAME=OTHER specially, although this ! 544: appears to be an SCO innovation. */ ! 545: if (strcmp (*pz, "OTHER") == 0) ! 546: qnew->uuconf_zcalled_login = (char *) "ANY"; ! 547: else ! 548: qnew->uuconf_zcalled_login = *pz; ! 549: qnew->uuconf_fcall = FALSE; ! 550: iret = ihadd_logname_perm (qglobal, qnew, qperm); ! 551: if (iret != UUCONF_SUCCESS) ! 552: return iret; ! 553: } ! 554: } ! 555: } ! 556: ! 557: /* HDB permits local requests to receive to any directory, which is ! 558: not the default put in by _uuconf_isystem_basic_default. We set ! 559: it here instead. */ ! 560: for (qalt = qsys; qalt != NULL; qalt = qalt->uuconf_qalternate) ! 561: { ! 562: iret = _uuconf_iadd_string (qglobal, (char *) ZROOTDIR, ! 563: FALSE, FALSE, ! 564: &qalt->uuconf_pzlocal_receive, ! 565: pblock); ! 566: if (iret != UUCONF_SUCCESS) ! 567: return iret; ! 568: } ! 569: ! 570: /* HDB does not have a maximum number of retries if a retry time is ! 571: given in the time field. */ ! 572: if (qsys->uuconf_qtimegrade != NULL ! 573: && qsys->uuconf_qtimegrade != (struct uuconf_timespan *) &_uuconf_unset ! 574: && qsys->uuconf_qtimegrade->uuconf_cretry > 0) ! 575: qsys->uuconf_cmax_retries = 0; ! 576: ! 577: return UUCONF_SUCCESS; ! 578: } ! 579: ! 580: /* Add the settings of a MACHINE line in Permissions to a system. */ ! 581: ! 582: /*ARGSIGNORED*/ ! 583: static int ! 584: ihadd_machine_perm (qglobal, qsys, qperm) ! 585: struct sglobal *qglobal; ! 586: struct uuconf_system *qsys; ! 587: struct shpermissions *qperm; ! 588: { ! 589: if (qperm->frequest >= 0) ! 590: qsys->uuconf_fsend_request = qperm->frequest; ! 591: else ! 592: qsys->uuconf_fsend_request = FALSE; ! 593: qsys->uuconf_pzremote_send = qperm->pzread; ! 594: qsys->uuconf_pzremote_receive = qperm->pzwrite; ! 595: qsys->uuconf_pzcmds = qperm->pzcommands; ! 596: qsys->uuconf_zlocalname = qperm->zmyname; ! 597: qsys->uuconf_zpubdir = qperm->zpubdir; ! 598: qsys->uuconf_pzalias = qperm->pzalias; ! 599: ! 600: return UUCONF_SUCCESS; ! 601: } ! 602: ! 603: /* Add the settings of a LOGNAME line in Permissions to a system. */ ! 604: ! 605: /*ARGSIGNORED*/ ! 606: static int ! 607: ihadd_logname_perm (qglobal, qsys, qperm) ! 608: struct sglobal *qglobal; ! 609: struct uuconf_system *qsys; ! 610: struct shpermissions *qperm; ! 611: { ! 612: qsys->uuconf_fcalled = TRUE; ! 613: if (qperm->frequest >= 0) ! 614: qsys->uuconf_fsend_request = qperm->frequest; ! 615: else ! 616: qsys->uuconf_fsend_request = FALSE; ! 617: qsys->uuconf_fcalled_transfer = qperm->fsendfiles; ! 618: qsys->uuconf_pzremote_send = qperm->pzread; ! 619: qsys->uuconf_pzremote_receive = qperm->pzwrite; ! 620: qsys->uuconf_fcallback = qperm->fcallback; ! 621: qsys->uuconf_zlocalname = qperm->zmyname; ! 622: qsys->uuconf_zpubdir = qperm->zpubdir; ! 623: ! 624: return UUCONF_SUCCESS; ! 625: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.