|
|
1.1 ! root 1: /* tsinfo.c ! 2: Get information about a system from the Taylor UUCP 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_tsinfo_rcsid[] = "$Id: tsinfo.c,v 1.1 93/07/30 08:08:05 bin Exp Locker: bin $"; ! 30: #endif ! 31: ! 32: #include <errno.h> ! 33: #include <ctype.h> ! 34: ! 35: #ifndef SEEK_SET ! 36: #define SEEK_SET 0 ! 37: #endif ! 38: ! 39: static void uiset_call P((struct uuconf_system *qsys)); ! 40: static int iisizecmp P((long i1, long i2)); ! 41: ! 42: /* Local functions needed to parse the system information file. */ ! 43: ! 44: #define CMDTABFN(z) \ ! 45: static int z P((pointer, int, char **, pointer, pointer)) ! 46: ! 47: CMDTABFN (iisystem); ! 48: CMDTABFN (iialias); ! 49: CMDTABFN (iialternate); ! 50: CMDTABFN (iidefault_alternates); ! 51: CMDTABFN (iitime); ! 52: CMDTABFN (iitimegrade); ! 53: CMDTABFN (iisize); ! 54: CMDTABFN (iibaud_range); ! 55: CMDTABFN (iiport); ! 56: CMDTABFN (iichat); ! 57: CMDTABFN (iicalled_login); ! 58: CMDTABFN (iiproto_param); ! 59: CMDTABFN (iirequest); ! 60: CMDTABFN (iitransfer); ! 61: CMDTABFN (iiforward); ! 62: CMDTABFN (iiunknown); ! 63: ! 64: #undef CMDTABFN ! 65: ! 66: /* We have to pass a fair amount of information in and out of the ! 67: various system commands. Using global variables would make the ! 68: code non-reentrant, so we instead pass a pointer to single ! 69: structure as the pinfo argument to the system commands. */ ! 70: ! 71: struct sinfo ! 72: { ! 73: /* The system information we're building up. */ ! 74: struct uuconf_system *qsys; ! 75: /* Whether any alternates have been used. */ ! 76: boolean falternates; ! 77: /* A list of the previous alternates. */ ! 78: struct uuconf_system salternate; ! 79: /* Whether to use extra alternates from the file wide defaults. */ ! 80: int fdefault_alternates; ! 81: }; ! 82: ! 83: /* The command table for system commands. */ ! 84: static const struct cmdtab_offset asIcmds[] = ! 85: { ! 86: { "system", UUCONF_CMDTABTYPE_FN | 2, (size_t) -1, iisystem }, ! 87: { "alias", UUCONF_CMDTABTYPE_FN | 2, (size_t) -1, iialias }, ! 88: { "alternate", UUCONF_CMDTABTYPE_FN | 0, (size_t) -1, iialternate }, ! 89: { "default-alternates", UUCONF_CMDTABTYPE_FN | 2, (size_t) -1, ! 90: iidefault_alternates }, ! 91: { "time", UUCONF_CMDTABTYPE_FN | 0, ! 92: offsetof (struct uuconf_system, uuconf_qtimegrade), iitime }, ! 93: { "timegrade", UUCONF_CMDTABTYPE_FN | 0, ! 94: offsetof (struct uuconf_system, uuconf_qtimegrade), iitimegrade }, ! 95: { "max-retries", UUCONF_CMDTABTYPE_INT, ! 96: offsetof (struct uuconf_system, uuconf_cmax_retries), NULL }, ! 97: { "success-wait", UUCONF_CMDTABTYPE_INT, ! 98: offsetof (struct uuconf_system, uuconf_csuccess_wait), NULL }, ! 99: { "call-timegrade", UUCONF_CMDTABTYPE_FN | 3, ! 100: offsetof (struct uuconf_system, uuconf_qcalltimegrade), iitimegrade }, ! 101: { "call-local-size", UUCONF_CMDTABTYPE_FN | 3, ! 102: offsetof (struct uuconf_system, uuconf_qcall_local_size), iisize }, ! 103: { "call-remote-size", UUCONF_CMDTABTYPE_FN | 3, ! 104: offsetof (struct uuconf_system, uuconf_qcall_remote_size), iisize }, ! 105: { "called-local-size", UUCONF_CMDTABTYPE_FN | 3, ! 106: offsetof (struct uuconf_system, uuconf_qcalled_local_size), iisize }, ! 107: { "called-remote-size", UUCONF_CMDTABTYPE_FN | 3, ! 108: offsetof (struct uuconf_system, uuconf_qcalled_remote_size), iisize }, ! 109: { "timetable", UUCONF_CMDTABTYPE_FN | 3, (size_t) -1, _uuconf_itimetable }, ! 110: { "baud", UUCONF_CMDTABTYPE_LONG, ! 111: offsetof (struct uuconf_system, uuconf_ibaud), NULL }, ! 112: { "speed", UUCONF_CMDTABTYPE_LONG, ! 113: offsetof (struct uuconf_system, uuconf_ibaud), NULL }, ! 114: { "baud-range", UUCONF_CMDTABTYPE_FN | 3, 0, iibaud_range }, ! 115: { "speed-range", UUCONF_CMDTABTYPE_FN | 3, 0, iibaud_range }, ! 116: { "port", UUCONF_CMDTABTYPE_FN | 0, (size_t) -1, iiport }, ! 117: { "phone", UUCONF_CMDTABTYPE_STRING, ! 118: offsetof (struct uuconf_system, uuconf_zphone), NULL }, ! 119: { "address", UUCONF_CMDTABTYPE_STRING, ! 120: offsetof (struct uuconf_system, uuconf_zphone), NULL }, ! 121: { "chat", UUCONF_CMDTABTYPE_PREFIX | 0, ! 122: offsetof (struct uuconf_system, uuconf_schat), iichat }, ! 123: { "call-login", UUCONF_CMDTABTYPE_STRING, ! 124: offsetof (struct uuconf_system, uuconf_zcall_login), NULL }, ! 125: { "call-password", UUCONF_CMDTABTYPE_STRING, ! 126: offsetof (struct uuconf_system, uuconf_zcall_password), NULL }, ! 127: { "called-login", UUCONF_CMDTABTYPE_FN | 0, ! 128: offsetof (struct uuconf_system, uuconf_zcalled_login), iicalled_login }, ! 129: { "callback", UUCONF_CMDTABTYPE_BOOLEAN, ! 130: offsetof (struct uuconf_system, uuconf_fcallback), NULL }, ! 131: { "sequence", UUCONF_CMDTABTYPE_BOOLEAN, ! 132: offsetof (struct uuconf_system, uuconf_fsequence), NULL }, ! 133: { "protocol", UUCONF_CMDTABTYPE_STRING, ! 134: offsetof (struct uuconf_system, uuconf_zprotocols), NULL }, ! 135: { "protocol-parameter", UUCONF_CMDTABTYPE_FN | 0, ! 136: offsetof (struct uuconf_system, uuconf_qproto_params), iiproto_param }, ! 137: { "called-chat", UUCONF_CMDTABTYPE_PREFIX | 0, ! 138: offsetof (struct uuconf_system, uuconf_scalled_chat), iichat }, ! 139: { "debug", UUCONF_CMDTABTYPE_STRING, ! 140: offsetof (struct uuconf_system, uuconf_zdebug), NULL }, ! 141: { "max-remote-debug", UUCONF_CMDTABTYPE_STRING, ! 142: offsetof (struct uuconf_system, uuconf_zmax_remote_debug), NULL }, ! 143: { "send-request", UUCONF_CMDTABTYPE_BOOLEAN, ! 144: offsetof (struct uuconf_system, uuconf_fsend_request), NULL }, ! 145: { "receive-request", UUCONF_CMDTABTYPE_BOOLEAN, ! 146: offsetof (struct uuconf_system, uuconf_frec_request), NULL }, ! 147: { "request", UUCONF_CMDTABTYPE_FN | 2, (size_t) -1, iirequest }, ! 148: { "call-transfer", UUCONF_CMDTABTYPE_BOOLEAN, ! 149: offsetof (struct uuconf_system, uuconf_fcall_transfer), NULL }, ! 150: { "called-transfer", UUCONF_CMDTABTYPE_BOOLEAN, ! 151: offsetof (struct uuconf_system, uuconf_fcalled_transfer), NULL }, ! 152: { "transfer", UUCONF_CMDTABTYPE_FN | 2, (size_t) -1, iitransfer }, ! 153: { "local-send", UUCONF_CMDTABTYPE_FULLSTRING, ! 154: offsetof (struct uuconf_system, uuconf_pzlocal_send), NULL }, ! 155: { "remote-send", UUCONF_CMDTABTYPE_FULLSTRING, ! 156: offsetof (struct uuconf_system, uuconf_pzremote_send), NULL }, ! 157: { "local-receive", UUCONF_CMDTABTYPE_FULLSTRING, ! 158: offsetof (struct uuconf_system, uuconf_pzlocal_receive), NULL }, ! 159: { "remote-receive", UUCONF_CMDTABTYPE_FULLSTRING, ! 160: offsetof (struct uuconf_system, uuconf_pzremote_receive), NULL }, ! 161: { "command-path", UUCONF_CMDTABTYPE_FULLSTRING, ! 162: offsetof (struct uuconf_system, uuconf_pzpath), NULL }, ! 163: { "commands", UUCONF_CMDTABTYPE_FULLSTRING, ! 164: offsetof (struct uuconf_system, uuconf_pzcmds), NULL }, ! 165: { "free-space", UUCONF_CMDTABTYPE_LONG, ! 166: offsetof (struct uuconf_system, uuconf_cfree_space), NULL }, ! 167: { "forward-from", UUCONF_CMDTABTYPE_FULLSTRING, ! 168: offsetof (struct uuconf_system, uuconf_pzforward_from), NULL }, ! 169: { "forward-to", UUCONF_CMDTABTYPE_FULLSTRING, ! 170: offsetof (struct uuconf_system, uuconf_pzforward_to), NULL }, ! 171: { "forward", UUCONF_CMDTABTYPE_FN | 0, (size_t) -1, iiforward }, ! 172: { "pubdir", UUCONF_CMDTABTYPE_STRING, ! 173: offsetof (struct uuconf_system, uuconf_zpubdir), NULL }, ! 174: { "myname", UUCONF_CMDTABTYPE_STRING, ! 175: offsetof (struct uuconf_system, uuconf_zlocalname), NULL }, ! 176: { NULL, 0, 0, NULL } ! 177: }; ! 178: ! 179: #define CSYSTEM_CMDS (sizeof asIcmds / sizeof asIcmds[0]) ! 180: ! 181: /* Get information about the system zsystem from the Taylor UUCP ! 182: configuration files. Sets *qsys. This does not ensure that all ! 183: default information is set. */ ! 184: ! 185: int ! 186: _uuconf_itaylor_system_internal (qglobal, zsystem, qsys) ! 187: struct sglobal *qglobal; ! 188: const char *zsystem; ! 189: struct uuconf_system *qsys; ! 190: { ! 191: int iret; ! 192: struct stsysloc *qloc; ! 193: struct uuconf_cmdtab as[CSYSTEM_CMDS]; ! 194: struct sinfo si; ! 195: struct uuconf_system sdefaults; ! 196: ! 197: if (! qglobal->qprocess->fread_syslocs) ! 198: { ! 199: iret = _uuconf_iread_locations (qglobal); ! 200: if (iret != UUCONF_SUCCESS) ! 201: return iret; ! 202: } ! 203: ! 204: /* Find the system in the list of locations. */ ! 205: for (qloc = qglobal->qprocess->qsyslocs; qloc != NULL; qloc = qloc->qnext) ! 206: if (qloc->zname[0] == zsystem[0] ! 207: && strcmp (qloc->zname, zsystem) == 0) ! 208: break; ! 209: if (qloc == NULL) ! 210: return UUCONF_NOT_FOUND; ! 211: ! 212: /* If this is an alias, then the real system is the next non-alias ! 213: in the list. */ ! 214: while (qloc->falias) ! 215: { ! 216: qloc = qloc->qnext; ! 217: if (qloc == NULL) ! 218: return UUCONF_NOT_FOUND; ! 219: } ! 220: ! 221: _uuconf_ucmdtab_base (asIcmds, CSYSTEM_CMDS, (char *) qsys, as); ! 222: ! 223: rewind (qloc->e); ! 224: ! 225: /* Read the file wide defaults from the start of the file. */ ! 226: _uuconf_uclear_system (qsys); ! 227: ! 228: si.qsys = qsys; ! 229: si.falternates = FALSE; ! 230: si.fdefault_alternates = TRUE; ! 231: qsys->uuconf_palloc = uuconf_malloc_block (); ! 232: if (qsys->uuconf_palloc == NULL) ! 233: { ! 234: qglobal->ierrno = errno; ! 235: return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO; ! 236: } ! 237: ! 238: iret = uuconf_cmd_file ((pointer) qglobal, qloc->e, as, (pointer) &si, ! 239: iiunknown, UUCONF_CMDTABFLAG_BACKSLASH, ! 240: qsys->uuconf_palloc); ! 241: if (iret != UUCONF_SUCCESS) ! 242: { ! 243: qglobal->zfilename = qloc->zfile; ! 244: return iret | UUCONF_ERROR_FILENAME; ! 245: } ! 246: ! 247: if (! si.falternates) ! 248: uiset_call (qsys); ! 249: else ! 250: { ! 251: /* Attach the final alternate. */ ! 252: iret = iialternate ((pointer) qglobal, 0, (char **) NULL, ! 253: (pointer) NULL, (pointer) &si); ! 254: if (iret != UUCONF_SUCCESS) ! 255: return iret; ! 256: } ! 257: ! 258: /* Save off the defaults. */ ! 259: sdefaults = *qsys; ! 260: ! 261: /* Advance to the information for the system we want. */ ! 262: if (fseek (qloc->e, qloc->iloc, SEEK_SET) != 0) ! 263: { ! 264: qglobal->ierrno = errno; ! 265: qglobal->zfilename = qloc->zfile; ! 266: return (UUCONF_FSEEK_FAILED ! 267: | UUCONF_ERROR_ERRNO ! 268: | UUCONF_ERROR_FILENAME); ! 269: } ! 270: ! 271: /* Read in the system we want. */ ! 272: _uuconf_uclear_system (qsys); ! 273: qsys->uuconf_zname = (char *) qloc->zname; ! 274: qsys->uuconf_palloc = sdefaults.uuconf_palloc; ! 275: ! 276: si.falternates = FALSE; ! 277: ! 278: iret = uuconf_cmd_file (qglobal, qloc->e, as, (pointer) &si, iiunknown, ! 279: UUCONF_CMDTABFLAG_BACKSLASH, qsys->uuconf_palloc); ! 280: qglobal->ilineno += qloc->ilineno; ! 281: ! 282: if (iret == UUCONF_SUCCESS) ! 283: { ! 284: if (! si.falternates) ! 285: uiset_call (qsys); ! 286: else ! 287: iret = iialternate ((pointer) qglobal, 0, (char **) NULL, ! 288: (pointer) NULL, (pointer) &si); ! 289: } ! 290: ! 291: /* Merge in the defaults. */ ! 292: if (iret == UUCONF_SUCCESS) ! 293: iret = _uuconf_isystem_default (qglobal, qsys, &sdefaults, ! 294: si.fdefault_alternates); ! 295: ! 296: /* The first alternate is always available for calling in. */ ! 297: if (iret == UUCONF_SUCCESS) ! 298: qsys->uuconf_fcalled = TRUE; ! 299: ! 300: if (iret != UUCONF_SUCCESS) ! 301: { ! 302: qglobal->zfilename = qloc->zfile; ! 303: iret |= UUCONF_ERROR_FILENAME; ! 304: } ! 305: ! 306: return iret; ! 307: } ! 308: ! 309: /* Set the fcall and fcalled field for the system. This marks a ! 310: particular alternate for use when calling out or calling in. This ! 311: is where we implement the semantics described in the documentation: ! 312: a change to a relevant field implies that the alternate is used. ! 313: If all the relevant fields are unchanged, the alternate is not ! 314: used. */ ! 315: ! 316: static void ! 317: uiset_call (qsys) ! 318: struct uuconf_system *qsys; ! 319: { ! 320: qsys->uuconf_fcall = ! 321: (qsys->uuconf_qtimegrade != (struct uuconf_timespan *) &_uuconf_unset ! 322: || qsys->uuconf_zport != (char *) &_uuconf_unset ! 323: || qsys->uuconf_qport != (struct uuconf_port *) &_uuconf_unset ! 324: || qsys->uuconf_ibaud >= 0 ! 325: || qsys->uuconf_zphone != (char *) &_uuconf_unset ! 326: || qsys->uuconf_schat.uuconf_pzchat != (char **) &_uuconf_unset ! 327: || qsys->uuconf_schat.uuconf_pzprogram != (char **) &_uuconf_unset); ! 328: ! 329: qsys->uuconf_fcalled = ! 330: qsys->uuconf_zcalled_login != (char *) &_uuconf_unset; ! 331: } ! 332: ! 333: /* Handle the "system" command. Because we skip directly to the ! 334: system we want to read, a "system" command means we've reached the ! 335: end of it. */ ! 336: ! 337: static int ! 338: iisystem (pglobal, argc, argv, pvar, pinfo) ! 339: pointer pglobal; ! 340: int argc; ! 341: char **argv; ! 342: pointer pvar; ! 343: pointer pinfo; ! 344: { ! 345: return UUCONF_CMDTABRET_EXIT; ! 346: } ! 347: ! 348: /* Handle the "alias" command. */ ! 349: ! 350: /*ARGSUSED*/ ! 351: static int ! 352: iialias (pglobal, argc, argv, pvar, pinfo) ! 353: pointer pglobal; ! 354: int argc; ! 355: char **argv; ! 356: pointer pvar; ! 357: pointer pinfo; ! 358: { ! 359: struct sglobal *qglobal = (struct sglobal *) pglobal; ! 360: struct sinfo *qinfo = (struct sinfo *) pinfo; ! 361: int iret; ! 362: ! 363: iret = _uuconf_iadd_string (qglobal, argv[1], TRUE, FALSE, ! 364: &qinfo->qsys->uuconf_pzalias, ! 365: qinfo->qsys->uuconf_palloc); ! 366: if (iret != UUCONF_SUCCESS) ! 367: iret |= UUCONF_CMDTABRET_EXIT; ! 368: return iret; ! 369: } ! 370: ! 371: /* Handle the "alternate" command. The information just read is in ! 372: sIhold. If this is the first "alternate" command for this system, ! 373: we save off the current information in sIalternate. Otherwise we ! 374: default this information to sIalternate, and then add it to the end ! 375: of the list of alternates in sIalternate. */ ! 376: ! 377: static int ! 378: iialternate (pglobal, argc, argv, pvar, pinfo) ! 379: pointer pglobal; ! 380: int argc; ! 381: char **argv; ! 382: pointer pvar; ! 383: pointer pinfo; ! 384: { ! 385: struct sglobal *qglobal = (struct sglobal *) pglobal; ! 386: struct sinfo *qinfo = (struct sinfo *) pinfo; ! 387: ! 388: uiset_call (qinfo->qsys); ! 389: ! 390: if (! qinfo->falternates) ! 391: { ! 392: qinfo->salternate = *qinfo->qsys; ! 393: qinfo->falternates = TRUE; ! 394: } ! 395: else ! 396: { ! 397: int iret; ! 398: struct uuconf_system *qnew, **pq; ! 399: ! 400: iret = _uuconf_isystem_default (qglobal, qinfo->qsys, ! 401: &qinfo->salternate, FALSE); ! 402: if (iret != UUCONF_SUCCESS) ! 403: return iret | UUCONF_CMDTABRET_EXIT; ! 404: qnew = ((struct uuconf_system *) ! 405: uuconf_malloc (qinfo->qsys->uuconf_palloc, ! 406: sizeof (struct uuconf_system))); ! 407: if (qnew == NULL) ! 408: { ! 409: qglobal->ierrno = errno;; ! 410: return (UUCONF_MALLOC_FAILED ! 411: | UUCONF_ERROR_ERRNO ! 412: | UUCONF_CMDTABRET_EXIT); ! 413: } ! 414: *qnew = *qinfo->qsys; ! 415: for (pq = &qinfo->salternate.uuconf_qalternate; ! 416: *pq != NULL; ! 417: pq = &(*pq)->uuconf_qalternate) ! 418: ; ! 419: *pq = qnew; ! 420: } ! 421: ! 422: /* If this is the last alternate command, move the information back ! 423: to qinfo->qsys. */ ! 424: if (argc == 0) ! 425: *qinfo->qsys = qinfo->salternate; ! 426: else ! 427: { ! 428: _uuconf_uclear_system (qinfo->qsys); ! 429: qinfo->qsys->uuconf_zname = qinfo->salternate.uuconf_zname; ! 430: qinfo->qsys->uuconf_palloc = qinfo->salternate.uuconf_palloc; ! 431: if (argc > 1) ! 432: { ! 433: qinfo->qsys->uuconf_zalternate = argv[1]; ! 434: return UUCONF_CMDTABRET_KEEP; ! 435: } ! 436: } ! 437: ! 438: return UUCONF_CMDTABRET_CONTINUE; ! 439: } ! 440: ! 441: /* Handle the "default-alternates" command. This just takes a boolean ! 442: argument which is used to set the fdefault_alternates field of the ! 443: sinfo structure. */ ! 444: ! 445: /*ARGSUSED*/ ! 446: static int ! 447: iidefault_alternates (pglobal, argc, argv, pvar, pinfo) ! 448: pointer pglobal; ! 449: int argc; ! 450: char **argv; ! 451: pointer pvar; ! 452: pointer pinfo; ! 453: { ! 454: struct sglobal *qglobal = (struct sglobal *) pglobal; ! 455: struct sinfo *qinfo = (struct sinfo *) pinfo; ! 456: ! 457: return _uuconf_iboolean (qglobal, argv[1], &qinfo->fdefault_alternates); ! 458: } ! 459: ! 460: /* Handle the "time" command. We do this by turning it into a ! 461: "timegrade" command with a grade of BGRADE_LOW. The first argument ! 462: is a time string, and the optional second argument is the retry ! 463: time. */ ! 464: ! 465: /*ARGSUSED*/ ! 466: static int ! 467: iitime (pglobal, argc, argv, pvar, pinfo) ! 468: pointer pglobal; ! 469: int argc; ! 470: char **argv; ! 471: pointer pvar; ! 472: pointer pinfo; ! 473: { ! 474: char *aznew[4]; ! 475: char ab[2]; ! 476: ! 477: if (argc != 2 && argc != 3) ! 478: return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT; ! 479: ! 480: aznew[0] = argv[0]; ! 481: ab[0] = UUCONF_GRADE_LOW; ! 482: ab[1] = '\0'; ! 483: aznew[1] = ab; ! 484: aznew[2] = argv[1]; ! 485: if (argc > 2) ! 486: aznew[3] = argv[2]; ! 487: ! 488: return iitimegrade (pglobal, argc + 1, aznew, pvar, pinfo); ! 489: } ! 490: ! 491: /* Handle the "timegrade" command by calling _uuconf_itime_parse with ! 492: appropriate ival (the work grade) and cretry (the retry time) ! 493: arguments. */ ! 494: ! 495: static int ! 496: iitimegrade (pglobal, argc, argv, pvar, pinfo) ! 497: pointer pglobal; ! 498: int argc; ! 499: char **argv; ! 500: pointer pvar; ! 501: pointer pinfo; ! 502: { ! 503: struct sglobal *qglobal = (struct sglobal *) pglobal; ! 504: struct uuconf_timespan **pqspan = (struct uuconf_timespan **) pvar; ! 505: struct sinfo *qinfo = (struct sinfo *) pinfo; ! 506: int cretry; ! 507: int iret; ! 508: ! 509: if (argc < 3 || argc > 4) ! 510: return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT; ! 511: ! 512: if (argv[1][1] != '\0' || ! UUCONF_GRADE_LEGAL (argv[1][0])) ! 513: return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT; ! 514: ! 515: if (argc == 3) ! 516: cretry = 0; ! 517: else ! 518: { ! 519: iret = _uuconf_iint (qglobal, argv[3], (pointer) &cretry, TRUE); ! 520: if (iret != UUCONF_SUCCESS) ! 521: return iret; ! 522: } ! 523: ! 524: iret = _uuconf_itime_parse (qglobal, argv[2], (long) argv[1][0], ! 525: cretry, _uuconf_itime_grade_cmp, pqspan, ! 526: qinfo->qsys->uuconf_palloc); ! 527: if (iret != UUCONF_SUCCESS) ! 528: iret |= UUCONF_CMDTABRET_EXIT; ! 529: return iret; ! 530: } ! 531: ! 532: /* Handle the "baud-range" command, also known as "speed-range". */ ! 533: ! 534: static int ! 535: iibaud_range (pglobal, argc, argv, pvar, pinfo) ! 536: pointer pglobal; ! 537: int argc; ! 538: char **argv; ! 539: pointer pvar; ! 540: pointer pinfo; ! 541: { ! 542: struct sglobal *qglobal = (struct sglobal *) pglobal; ! 543: struct uuconf_system *qsys = (struct uuconf_system *) pvar; ! 544: int iret; ! 545: ! 546: iret = _uuconf_iint (qglobal, argv[1], (pointer) &qsys->uuconf_ibaud, ! 547: FALSE); ! 548: if (iret != UUCONF_SUCCESS) ! 549: return iret; ! 550: return _uuconf_iint (qglobal, argv[2], (pointer) &qsys->uuconf_ihighbaud, ! 551: FALSE); ! 552: } ! 553: ! 554: /* Handle one of the size commands ("call-local-size", etc.). The ! 555: first argument is a number of bytes, and the second argument is a ! 556: time string. The pvar argument points to the string array to which ! 557: we add this new string. */ ! 558: ! 559: /*ARGSUSED*/ ! 560: static int ! 561: iisize (pglobal, argc, argv, pvar, pinfo) ! 562: pointer pglobal; ! 563: int argc; ! 564: char **argv; ! 565: pointer pvar; ! 566: pointer pinfo; ! 567: { ! 568: struct sglobal *qglobal = (struct sglobal *) pglobal; ! 569: struct uuconf_timespan **pqspan = (struct uuconf_timespan **) pvar; ! 570: struct sinfo *qinfo = (struct sinfo *) pinfo; ! 571: long ival; ! 572: int iret; ! 573: ! 574: iret = _uuconf_iint (qglobal, argv[1], (pointer) &ival, FALSE); ! 575: if (iret != UUCONF_SUCCESS) ! 576: return iret; ! 577: ! 578: iret = _uuconf_itime_parse (qglobal, argv[2], ival, 0, iisizecmp, ! 579: pqspan, qinfo->qsys->uuconf_palloc); ! 580: if (iret != UUCONF_SUCCESS) ! 581: iret |= UUCONF_CMDTABRET_EXIT; ! 582: return iret; ! 583: } ! 584: ! 585: /* A comparison function for sizes to pass to _uuconf_itime_parse. */ ! 586: ! 587: static int ! 588: iisizecmp (i1, i2) ! 589: long i1; ! 590: long i2; ! 591: { ! 592: /* We can't just return i1 - i2 because that would be a long. */ ! 593: if (i1 < i2) ! 594: return -1; ! 595: else if (i1 == i2) ! 596: return 0; ! 597: else ! 598: return 1; ! 599: } ! 600: ! 601: /* Handle the "port" command. If there is one argument, this names a ! 602: port. Otherwise, the remaining arguments form a command describing ! 603: the port. */ ! 604: ! 605: /*ARGSUSED*/ ! 606: static int ! 607: iiport (pglobal, argc, argv, pvar, pinfo) ! 608: pointer pglobal; ! 609: int argc; ! 610: char **argv; ! 611: pointer pvar; ! 612: pointer pinfo; ! 613: { ! 614: struct sglobal *qglobal = (struct sglobal *) pglobal; ! 615: struct sinfo *qinfo = (struct sinfo *) pinfo; ! 616: ! 617: if (argc < 2) ! 618: return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT; ! 619: else if (argc == 2) ! 620: { ! 621: qinfo->qsys->uuconf_zport = argv[1]; ! 622: return UUCONF_CMDTABRET_KEEP; ! 623: } ! 624: else ! 625: { ! 626: int iret; ! 627: ! 628: if (qinfo->qsys->uuconf_qport ! 629: == (struct uuconf_port *) &_uuconf_unset) ! 630: { ! 631: struct uuconf_port *qnew; ! 632: ! 633: qnew = ((struct uuconf_port *) ! 634: uuconf_malloc (qinfo->qsys->uuconf_palloc, ! 635: sizeof (struct uuconf_port))); ! 636: if (qnew == NULL) ! 637: { ! 638: qglobal->ierrno = errno; ! 639: return (UUCONF_MALLOC_FAILED ! 640: | UUCONF_ERROR_ERRNO ! 641: | UUCONF_CMDTABRET_EXIT); ! 642: } ! 643: ! 644: _uuconf_uclear_port (qnew); ! 645: ! 646: if (qinfo->qsys->uuconf_zname == NULL) ! 647: qnew->uuconf_zname = (char *) "default system file port"; ! 648: else ! 649: { ! 650: char *zname; ! 651: size_t clen; ! 652: ! 653: clen = strlen (qinfo->qsys->uuconf_zname); ! 654: zname = (char *) uuconf_malloc (qinfo->qsys->uuconf_palloc, ! 655: clen + sizeof "system port"); ! 656: if (zname == NULL) ! 657: { ! 658: qglobal->ierrno = errno; ! 659: return (UUCONF_MALLOC_FAILED ! 660: | UUCONF_ERROR_ERRNO ! 661: | UUCONF_CMDTABRET_EXIT); ! 662: } ! 663: ! 664: memcpy ((pointer) zname, (pointer) "system ", ! 665: sizeof "system " - 1); ! 666: memcpy ((pointer) (zname + sizeof "system " - 1), ! 667: (pointer) qinfo->qsys->uuconf_zname, ! 668: clen); ! 669: memcpy ((pointer) (zname + sizeof "system " - 1 + clen), ! 670: (pointer) " port", sizeof " port"); ! 671: ! 672: qnew->uuconf_zname = zname; ! 673: } ! 674: ! 675: qnew->uuconf_palloc = qinfo->qsys->uuconf_palloc; ! 676: ! 677: qinfo->qsys->uuconf_qport = qnew; ! 678: } ! 679: ! 680: iret = _uuconf_iport_cmd (qglobal, argc - 1, argv + 1, ! 681: qinfo->qsys->uuconf_qport); ! 682: if (UUCONF_ERROR_VALUE (iret) != UUCONF_SUCCESS) ! 683: iret |= UUCONF_CMDTABRET_EXIT; ! 684: return iret; ! 685: } ! 686: } ! 687: ! 688: /* Handle the "chat" and "called-chat" set of commands. These just ! 689: hand off to the generic chat script function. */ ! 690: ! 691: static int ! 692: iichat (pglobal, argc, argv, pvar, pinfo) ! 693: pointer pglobal; ! 694: int argc; ! 695: char **argv; ! 696: pointer pvar; ! 697: pointer pinfo; ! 698: { ! 699: struct sglobal *qglobal = (struct sglobal *) pglobal; ! 700: struct sinfo *qinfo = (struct sinfo *) pinfo; ! 701: struct uuconf_chat *qchat = (struct uuconf_chat *) pvar; ! 702: int iret; ! 703: ! 704: iret = _uuconf_ichat_cmd (qglobal, argc, argv, qchat, ! 705: qinfo->qsys->uuconf_palloc); ! 706: if (UUCONF_ERROR_VALUE (iret) != UUCONF_SUCCESS) ! 707: iret |= UUCONF_CMDTABRET_EXIT; ! 708: return iret; ! 709: } ! 710: ! 711: /* Handle the "called-login" command. This only needs to be in a ! 712: function because there can be additional arguments listing the ! 713: remote systems which are permitted to use this login name. The ! 714: additional arguments are not actually handled here; they are ! 715: handled by uuconf_taylor_system_names, which already has to go ! 716: through all the system files. */ ! 717: ! 718: /*ARGSUSED*/ ! 719: static int ! 720: iicalled_login (pglobal, argc, argv, pvar, pinfo) ! 721: pointer pglobal; ! 722: int argc; ! 723: char **argv; ! 724: pointer pvar; ! 725: pointer pinfo; ! 726: { ! 727: char **pz = (char **) pvar; ! 728: ! 729: if (argc < 2) ! 730: return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT; ! 731: *pz = argv[1]; ! 732: return UUCONF_CMDTABRET_KEEP; ! 733: } ! 734: ! 735: /* Handle the "protocol-parameter" command. This just hands off to ! 736: the generic protocol parameter handler. */ ! 737: ! 738: static int ! 739: iiproto_param (pglobal, argc, argv, pvar, pinfo) ! 740: pointer pglobal; ! 741: int argc; ! 742: char **argv; ! 743: pointer pvar; ! 744: pointer pinfo; ! 745: { ! 746: struct sglobal *qglobal = (struct sglobal *) pglobal; ! 747: struct uuconf_proto_param **pqparam = (struct uuconf_proto_param **) pvar; ! 748: struct sinfo *qinfo = (struct sinfo *) pinfo; ! 749: ! 750: if (*pqparam == (struct uuconf_proto_param *) &_uuconf_unset) ! 751: *pqparam = NULL; ! 752: return _uuconf_iadd_proto_param (qglobal, argc - 1, argv + 1, pqparam, ! 753: qinfo->qsys->uuconf_palloc); ! 754: } ! 755: ! 756: /* Handle the "request" command. This is equivalent to specifying ! 757: both "call-request" and "called-request". */ ! 758: ! 759: /*ARGSUSED*/ ! 760: static int ! 761: iirequest (pglobal, argc, argv, pvar, pinfo) ! 762: pointer pglobal; ! 763: int argc; ! 764: char **argv; ! 765: pointer pvar; ! 766: pointer pinfo; ! 767: { ! 768: struct sglobal *qglobal = (struct sglobal *) pglobal; ! 769: struct sinfo *qinfo = (struct sinfo *) pinfo; ! 770: int iret; ! 771: ! 772: iret = _uuconf_iboolean (qglobal, argv[1], ! 773: &qinfo->qsys->uuconf_fsend_request); ! 774: if (UUCONF_ERROR_VALUE (iret) == UUCONF_SUCCESS) ! 775: qinfo->qsys->uuconf_frec_request = qinfo->qsys->uuconf_fsend_request; ! 776: ! 777: return iret; ! 778: } ! 779: ! 780: /* Handle the "transfer" command. This is equivalent to specifying ! 781: both "call-transfer" and "called-transfer". */ ! 782: ! 783: /*ARGSUSED*/ ! 784: static int ! 785: iitransfer (pglobal, argc, argv, pvar, pinfo) ! 786: pointer pglobal; ! 787: int argc; ! 788: char **argv; ! 789: pointer pvar; ! 790: pointer pinfo; ! 791: { ! 792: struct sglobal *qglobal = (struct sglobal *) pglobal; ! 793: struct sinfo *qinfo = (struct sinfo *) pinfo; ! 794: int iret; ! 795: ! 796: iret = _uuconf_iboolean (qglobal, argv[1], ! 797: &qinfo->qsys->uuconf_fcall_transfer); ! 798: if (UUCONF_ERROR_VALUE (iret) == UUCONF_SUCCESS) ! 799: qinfo->qsys->uuconf_fcalled_transfer = qinfo->qsys->uuconf_fcall_transfer; ! 800: ! 801: return iret; ! 802: } ! 803: ! 804: /* Handle the "forward" command. This is equivalent to specifying ! 805: both "forward-from" and "forward-to". */ ! 806: ! 807: /*ARGSUSED*/ ! 808: static int ! 809: iiforward (pglobal, argc, argv, pvar, pinfo) ! 810: pointer pglobal; ! 811: int argc; ! 812: char **argv; ! 813: pointer pvar; ! 814: pointer pinfo; ! 815: { ! 816: struct sglobal *qglobal = (struct sglobal *) pglobal; ! 817: struct sinfo *qinfo = (struct sinfo *) pinfo; ! 818: struct uuconf_system *qsys; ! 819: int i; ! 820: int iret; ! 821: ! 822: qsys = qinfo->qsys; ! 823: qsys->uuconf_pzforward_from = NULL; ! 824: qsys->uuconf_pzforward_to = NULL; ! 825: for (i = 1; i < argc; i++) ! 826: { ! 827: iret = _uuconf_iadd_string (qglobal, argv[i], FALSE, FALSE, ! 828: &qsys->uuconf_pzforward_to, ! 829: qsys->uuconf_palloc); ! 830: if (iret != UUCONF_SUCCESS) ! 831: return iret | UUCONF_CMDTABRET_KEEP | UUCONF_CMDTABRET_EXIT; ! 832: iret = _uuconf_iadd_string (qglobal, argv[i], FALSE, FALSE, ! 833: &qsys->uuconf_pzforward_from, ! 834: qsys->uuconf_palloc); ! 835: if (iret != UUCONF_SUCCESS) ! 836: return iret | UUCONF_CMDTABRET_KEEP | UUCONF_CMDTABRET_EXIT; ! 837: } ! 838: ! 839: return UUCONF_CMDTABRET_KEEP; ! 840: } ! 841: ! 842: /* Handle an unknown command. This should probably be done more ! 843: intelligently. */ ! 844: ! 845: /*ARGSUSED*/ ! 846: static int ! 847: iiunknown (pglobal, argc, argv, pvar, pinfo) ! 848: pointer pglobal; ! 849: int argc; ! 850: char **argv; ! 851: pointer pvar; ! 852: pointer pinfo; ! 853: { ! 854: return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT; ! 855: } ! 856: ! 857: /* Return information for an unknown system. It would be better to ! 858: put this in a different file, but it would require breaking several ! 859: functions out of this file. Perhaps I will do it sometime. */ ! 860: ! 861: int ! 862: uuconf_taylor_system_unknown (pglobal, qsys) ! 863: pointer pglobal; ! 864: struct uuconf_system *qsys; ! 865: { ! 866: struct sglobal *qglobal = (struct sglobal *) pglobal; ! 867: struct uuconf_cmdtab as[CSYSTEM_CMDS]; ! 868: struct sinfo si; ! 869: struct sunknown *q; ! 870: int iret; ! 871: ! 872: if (qglobal->qprocess->qunknown == NULL) ! 873: return UUCONF_NOT_FOUND; ! 874: ! 875: _uuconf_ucmdtab_base (asIcmds, CSYSTEM_CMDS, (char *) qsys, as); ! 876: ! 877: _uuconf_uclear_system (qsys); ! 878: ! 879: si.qsys = qsys; ! 880: si.falternates = FALSE; ! 881: si.fdefault_alternates = TRUE; ! 882: qsys->uuconf_palloc = uuconf_malloc_block (); ! 883: if (qsys->uuconf_palloc == NULL) ! 884: { ! 885: qglobal->ierrno = errno; ! 886: return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO; ! 887: } ! 888: ! 889: for (q = qglobal->qprocess->qunknown; q != NULL; q = q->qnext) ! 890: { ! 891: iret = uuconf_cmd_args (pglobal, q->cargs, q->pzargs, as, ! 892: (pointer) &si, iiunknown, ! 893: UUCONF_CMDTABFLAG_BACKSLASH, ! 894: qsys->uuconf_palloc); ! 895: iret &=~ UUCONF_CMDTABRET_KEEP; ! 896: if (UUCONF_ERROR_VALUE (iret) != UUCONF_SUCCESS) ! 897: { ! 898: qglobal->zfilename = qglobal->qprocess->zconfigfile; ! 899: qglobal->ilineno = q->ilineno; ! 900: return ((iret &~ UUCONF_CMDTABRET_EXIT) ! 901: | UUCONF_ERROR_FILENAME ! 902: | UUCONF_ERROR_LINENO); ! 903: } ! 904: if ((iret & UUCONF_CMDTABRET_EXIT) != 0) ! 905: break; ! 906: } ! 907: ! 908: if (! si.falternates) ! 909: uiset_call (qsys); ! 910: else ! 911: { ! 912: iret = iialternate (pglobal, 0, (char **) NULL, (pointer) NULL, ! 913: (pointer) &si); ! 914: if (iret != UUCONF_SUCCESS) ! 915: return iret; ! 916: } ! 917: ! 918: /* The first alternate is always available for calling in. */ ! 919: qsys->uuconf_fcalled = TRUE; ! 920: ! 921: return _uuconf_isystem_basic_default (qglobal, qsys); ! 922: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.