|
|
1.1 ! root 1: /* tli.c ! 2: Code to handle TLI connections. ! 3: ! 4: Copyright (C) 1992 Ian Lance Taylor ! 5: ! 6: This file is part of the Taylor UUCP package. ! 7: ! 8: This program is free software; you can redistribute it and/or ! 9: modify it under the terms of the GNU General Public License as ! 10: published by the Free Software Foundation; either version 2 of the ! 11: License, or (at your option) any later version. ! 12: ! 13: This program 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: General Public License for more details. ! 17: ! 18: You should have received a copy of the GNU General Public License ! 19: along with this program; 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 "uucp.h" ! 27: ! 28: #if USE_RCS_ID ! 29: const char tli_rcsid[] = "$Id: tli.c,v 1.1 93/07/30 07:54:19 bin Exp Locker: bin $"; ! 30: #endif ! 31: ! 32: #if HAVE_TLI ! 33: ! 34: #include "sysdep.h" ! 35: #include "uudefs.h" ! 36: #include "uuconf.h" ! 37: #include "conn.h" ! 38: #include "system.h" ! 39: ! 40: #include <errno.h> ! 41: ! 42: #if HAVE_SYS_IOCTL_H ! 43: #include <sys/ioctl.h> ! 44: #endif ! 45: ! 46: #if HAVE_TIUSER_H ! 47: #include <tiuser.h> ! 48: #else ! 49: #if HAVE_XTI_H ! 50: #include <xti.h> ! 51: #else ! 52: #if HAVE_SYS_TLI_H ! 53: #include <sys/tli.h> ! 54: #endif ! 55: #endif ! 56: #endif ! 57: ! 58: #if HAVE_STROPTS_H ! 59: #include <stropts.h> ! 60: #endif ! 61: ! 62: #if HAVE_FCNTL_H ! 63: #include <fcntl.h> ! 64: #else ! 65: #if HAVE_SYS_FILE_H ! 66: #include <sys/file.h> ! 67: #endif ! 68: #endif ! 69: ! 70: #ifndef O_RDONLY ! 71: #define O_RDONLY 0 ! 72: #define O_WRONLY 1 ! 73: #define O_RDWR 2 ! 74: #endif ! 75: ! 76: #ifndef FD_CLOEXEC ! 77: #define FD_CLOEXEC 1 ! 78: #endif ! 79: ! 80: /* The arguments to t_alloca have two different names. I want the ! 81: SVID ones, not the XPG3 ones. */ ! 82: #ifndef T_BIND ! 83: #define T_BIND T_BIND_STR ! 84: #endif ! 85: #ifndef T_CALL ! 86: #define T_CALL T_CALL_STR ! 87: #endif ! 88: ! 89: /* Hopefully these externs will not cause any trouble. This is how ! 90: they are shown in the SVID. */ ! 91: extern int t_errno; ! 92: extern char *t_errlist[]; ! 93: extern int t_nerr; ! 94: ! 95: #ifndef t_alloc ! 96: extern pointer t_alloc (); ! 97: #endif ! 98: ! 99: /* This code handles TLI connections. It's Unix specific. It's ! 100: largely based on code from Unix Network Programming, by W. Richard ! 101: Stevens. */ ! 102: ! 103: /* Local functions. */ ! 104: static const char *ztlierror P((void)); ! 105: static void utli_free P((struct sconnection *qconn)); ! 106: static boolean ftli_push P((struct sconnection *qconn)); ! 107: static boolean ftli_open P((struct sconnection *qconn, long ibaud, ! 108: boolean fwait)); ! 109: static boolean ftli_close P((struct sconnection *qconn, ! 110: pointer puuconf, ! 111: struct uuconf_dialer *qdialer, ! 112: boolean fsuccess)); ! 113: static boolean ftli_reset P((struct sconnection *qconn)); ! 114: static boolean ftli_dial P((struct sconnection *qconn, pointer puuconf, ! 115: const struct uuconf_system *qsys, ! 116: const char *zphone, ! 117: struct uuconf_dialer *qdialer, ! 118: enum tdialerfound *ptdialer)); ! 119: ! 120: /* The command table for a TLI connection. */ ! 121: static const struct sconncmds stlicmds = ! 122: { ! 123: utli_free, ! 124: NULL, /* pflock */ ! 125: NULL, /* pfunlock */ ! 126: ftli_open, ! 127: ftli_close, ! 128: ftli_reset, ! 129: ftli_dial, ! 130: fsysdep_conn_read, ! 131: fsysdep_conn_write, ! 132: fsysdep_conn_io, ! 133: NULL, /* pfbreak */ ! 134: NULL, /* pfset */ ! 135: NULL, /* pfcarrier */ ! 136: fsysdep_conn_chat, ! 137: NULL /* pibaud */ ! 138: }; ! 139: ! 140: /* Get a TLI error string. */ ! 141: ! 142: static const char * ! 143: ztlierror () ! 144: { ! 145: if (t_errno == TSYSERR) ! 146: return strerror (errno); ! 147: if (t_errno < 0 || t_errno >= t_nerr) ! 148: return "Unknown TLI error"; ! 149: return t_errlist[t_errno]; ! 150: } ! 151: ! 152: /* Initialize a TLI connection. */ ! 153: ! 154: boolean ! 155: fsysdep_tli_init (qconn) ! 156: struct sconnection *qconn; ! 157: { ! 158: struct ssysdep_conn *q; ! 159: ! 160: q = (struct ssysdep_conn *) xmalloc (sizeof (struct ssysdep_conn)); ! 161: q->o = -1; ! 162: q->zdevice = NULL; ! 163: q->iflags = -1; ! 164: q->istdout_flags = -1; ! 165: q->fterminal = FALSE; ! 166: q->ftli = TRUE; ! 167: q->ibaud = 0; ! 168: ! 169: qconn->psysdep = (pointer) q; ! 170: qconn->qcmds = &stlicmds; ! 171: return TRUE; ! 172: } ! 173: ! 174: /* Free a TLI connection. */ ! 175: ! 176: static void ! 177: utli_free (qconn) ! 178: struct sconnection *qconn; ! 179: { ! 180: xfree (qconn->psysdep); ! 181: } ! 182: ! 183: /* Push all desired modules onto a TLI stream. If the user requests a ! 184: STREAMS connection without giving a list of modules, we just push ! 185: tirdwr. If the I_PUSH ioctl is not defined on this system, we just ! 186: ignore any list of modules. */ ! 187: ! 188: static boolean ! 189: ftli_push (qconn) ! 190: struct sconnection *qconn; ! 191: { ! 192: #ifdef I_PUSH ! 193: ! 194: struct ssysdep_conn *qsysdep; ! 195: ! 196: qsysdep = (struct ssysdep_conn *) qconn->psysdep; ! 197: ! 198: if (qconn->qport->uuconf_u.uuconf_stli.uuconf_pzpush != NULL) ! 199: { ! 200: char **pz; ! 201: ! 202: for (pz = qconn->qport->uuconf_u.uuconf_stli.uuconf_pzpush; ! 203: *pz != NULL; ! 204: pz++) ! 205: { ! 206: if (ioctl (qsysdep->o, I_PUSH, *pz) < 0) ! 207: { ! 208: ulog (LOG_ERROR, "ioctl (I_PUSH, %s): %s", *pz, ! 209: strerror (errno)); ! 210: return FALSE; ! 211: } ! 212: } ! 213: } ! 214: else if (qconn->qport->uuconf_u.uuconf_stli.uuconf_fstream) ! 215: { ! 216: if (ioctl (qsysdep->o, I_PUSH, "tirdwr") < 0) ! 217: { ! 218: ulog (LOG_ERROR, "ioctl (I_PUSH, tirdwr): %s", ! 219: strerror (errno)); ! 220: return FALSE; ! 221: } ! 222: } ! 223: ! 224: /* If we have just put the connection into stream mode, we must turn ! 225: off the TLI flag to avoid using TLI calls on it. */ ! 226: if (qconn->qport->uuconf_u.uuconf_stli.uuconf_fstream) ! 227: qsysdep->ftli = FALSE; ! 228: ! 229: #endif /* defined (I_PUSH) */ ! 230: ! 231: return TRUE; ! 232: } ! 233: ! 234: /* Open a TLI connection. If the fwait argument is TRUE, we are ! 235: running as a server. Otherwise we are just trying to reach another ! 236: system. */ ! 237: ! 238: static boolean ! 239: ftli_open (qconn, ibaud, fwait) ! 240: struct sconnection *qconn; ! 241: long ibaud; ! 242: boolean fwait; ! 243: { ! 244: struct ssysdep_conn *qsysdep; ! 245: const char *zdevice; ! 246: char *zfreedev; ! 247: const char *zservaddr; ! 248: char *zfreeaddr; ! 249: struct t_bind *qtbind; ! 250: struct t_call *qtcall; ! 251: ! 252: /* Unlike most other device types, we don't bother to call ! 253: ulog_device here, because fconn_open calls it with the name of ! 254: the port anyhow. */ ! 255: ! 256: qsysdep = (struct ssysdep_conn *) qconn->psysdep; ! 257: ! 258: zdevice = qconn->qport->uuconf_u.uuconf_stli.uuconf_zdevice; ! 259: if (zdevice == NULL) ! 260: zdevice = qconn->qport->uuconf_zname; ! 261: ! 262: zfreedev = NULL; ! 263: if (*zdevice != '/') ! 264: { ! 265: zfreedev = zbufalc (sizeof "/dev/" + strlen (zdevice)); ! 266: sprintf (zfreedev, "/dev/%s", zdevice); ! 267: zdevice = zfreedev; ! 268: } ! 269: ! 270: qsysdep->o = t_open (zdevice, O_RDWR, (struct t_info *) NULL); ! 271: if (qsysdep->o < 0) ! 272: { ! 273: ulog (LOG_ERROR, "t_open (%s): %s", zdevice, ztlierror ()); ! 274: ubuffree (zfreedev); ! 275: return FALSE; ! 276: } ! 277: ! 278: if (fcntl (qsysdep->o, F_SETFD, ! 279: fcntl (qsysdep->o, F_GETFD, 0) | FD_CLOEXEC) < 0) ! 280: { ! 281: ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno)); ! 282: ubuffree (zfreedev); ! 283: (void) t_close (qsysdep->o); ! 284: qsysdep->o = -1; ! 285: return FALSE; ! 286: } ! 287: ! 288: qsysdep->iflags = fcntl (qsysdep->o, F_GETFL, 0); ! 289: if (qsysdep->iflags < 0) ! 290: { ! 291: ulog (LOG_ERROR, "fcntl: %s", strerror (errno)); ! 292: ubuffree (zfreedev); ! 293: (void) t_close (qsysdep->o); ! 294: qsysdep->o = -1; ! 295: return FALSE; ! 296: } ! 297: ! 298: /* If we aren't waiting for a connection, we can bind to any local ! 299: address, and then we're finished. */ ! 300: if (! fwait) ! 301: { ! 302: ubuffree (zfreedev); ! 303: if (t_bind (qsysdep->o, (struct t_bind *) NULL, ! 304: (struct t_bind *) NULL) < 0) ! 305: { ! 306: ulog (LOG_ERROR, "t_bind: %s", ztlierror ()); ! 307: (void) t_close (qsysdep->o); ! 308: qsysdep->o = -1; ! 309: return FALSE; ! 310: } ! 311: return TRUE; ! 312: } ! 313: ! 314: /* Run as a server and wait for a new connection. The code in ! 315: uucico.c has already detached us from our controlling terminal. ! 316: From this point on if the server gets an error we exit; we only ! 317: return if we have received a connection. It would be more robust ! 318: to respawn the server if it fails; someday. */ ! 319: qtbind = (struct t_bind *) t_alloc (qsysdep->o, T_BIND, T_ALL); ! 320: if (qtbind == NULL) ! 321: ulog (LOG_FATAL, "t_alloc (T_BIND): %s", ztlierror ()); ! 322: ! 323: zservaddr = qconn->qport->uuconf_u.uuconf_stli.uuconf_zservaddr; ! 324: if (zservaddr == NULL) ! 325: ulog (LOG_FATAL, "Can't run as TLI server; no server address"); ! 326: ! 327: zfreeaddr = zbufcpy (zservaddr); ! 328: qtbind->addr.len = cescape (zfreeaddr); ! 329: if (qtbind->addr.len > qtbind->addr.maxlen) ! 330: ulog (LOG_FATAL, "%s: TLI server address too long (max %d)", ! 331: zservaddr, qtbind->addr.maxlen); ! 332: memcpy (qtbind->addr.buf, zfreeaddr, qtbind->addr.len); ! 333: ubuffree (zfreeaddr); ! 334: ! 335: qtbind->qlen = 5; ! 336: ! 337: if (t_bind (qsysdep->o, qtbind, (struct t_bind *) NULL) < 0) ! 338: ulog (LOG_FATAL, "t_bind (%s): %s", zservaddr, ztlierror ()); ! 339: ! 340: (void) t_free ((pointer) qtbind, T_BIND); ! 341: ! 342: qtcall = (struct t_call *) t_alloc (qsysdep->o, T_CALL, T_ALL); ! 343: if (qtcall == NULL) ! 344: ulog (LOG_FATAL, "t_alloc (T_CALL): %s", ztlierror ()); ! 345: ! 346: while (! FGOT_SIGNAL ()) ! 347: { ! 348: int onew; ! 349: pid_t ipid; ! 350: ! 351: DEBUG_MESSAGE0 (DEBUG_PORT, ! 352: "ftli_open: Waiting for connections"); ! 353: ! 354: if (t_listen (qsysdep->o, qtcall) < 0) ! 355: ulog (LOG_FATAL, "t_listen: %s", ztlierror ()); ! 356: ! 357: onew = t_open (zdevice, O_RDWR, (struct t_info *) NULL); ! 358: if (onew < 0) ! 359: ulog (LOG_FATAL, "t_open (%s): %s", zdevice, ztlierror ()); ! 360: ! 361: if (fcntl (onew, F_SETFD, ! 362: fcntl (onew, F_GETFD, 0) | FD_CLOEXEC) < 0) ! 363: ulog (LOG_FATAL, "fcntl (FD_CLOEXEC): %s", strerror (errno)); ! 364: ! 365: if (t_bind (onew, (struct t_bind *) NULL, (struct t_bind *) NULL) < 0) ! 366: ulog (LOG_FATAL, "t_bind: %s", ztlierror ()); ! 367: ! 368: if (t_accept (qsysdep->o, onew, qtcall) < 0) ! 369: { ! 370: /* We may have received a disconnect. */ ! 371: if (t_errno != TLOOK) ! 372: ulog (LOG_FATAL, "t_accept: %s", ztlierror ()); ! 373: if (t_rcvdis (qsysdep->o, (struct t_discon *) NULL) < 0) ! 374: ulog (LOG_FATAL, "t_rcvdis: %s", ztlierror ()); ! 375: (void) t_close (onew); ! 376: continue; ! 377: } ! 378: ! 379: DEBUG_MESSAGE0 (DEBUG_PORT, ! 380: "ftli_open: Got connection; forking"); ! 381: ! 382: ipid = ixsfork (); ! 383: if (ipid < 0) ! 384: ulog (LOG_FATAL, "fork: %s", strerror (errno)); ! 385: if (ipid == 0) ! 386: { ! 387: ulog_close (); ! 388: ! 389: (void) t_close (qsysdep->o); ! 390: qsysdep->o = onew; ! 391: ! 392: /* Push any desired modules. */ ! 393: if (! ftli_push (qconn)) ! 394: _exit (EXIT_FAILURE); ! 395: ! 396: /* Now we fork and let our parent die, so that we become ! 397: a child of init. This lets the main server code wait ! 398: for its child and then continue without accumulating ! 399: zombie children. */ ! 400: ipid = ixsfork (); ! 401: if (ipid < 0) ! 402: { ! 403: ulog (LOG_ERROR, "fork: %s", strerror (errno)); ! 404: _exit (EXIT_FAILURE); ! 405: } ! 406: ! 407: if (ipid != 0) ! 408: _exit (EXIT_SUCCESS); ! 409: ! 410: ulog_id (getpid ()); ! 411: ! 412: return TRUE; ! 413: } ! 414: ! 415: (void) t_close (onew); ! 416: ! 417: /* Now wait for the child. */ ! 418: (void) ixswait ((unsigned long) ipid, (const char *) NULL); ! 419: } ! 420: ! 421: /* We got a signal. */ ! 422: usysdep_exit (FALSE); ! 423: ! 424: /* Avoid compiler warnings. */ ! 425: return FALSE; ! 426: } ! 427: ! 428: /* Close the port. */ ! 429: ! 430: /*ARGSUSED*/ ! 431: static boolean ! 432: ftli_close (qconn, puuconf, qdialer, fsuccess) ! 433: struct sconnection *qconn; ! 434: pointer puuconf; ! 435: struct uuconf_dialer *qdialer; ! 436: boolean fsuccess; ! 437: { ! 438: struct ssysdep_conn *qsysdep; ! 439: boolean fret; ! 440: ! 441: qsysdep = (struct ssysdep_conn *) qconn->psysdep; ! 442: ! 443: fret = TRUE; ! 444: if (qsysdep->o >= 0) ! 445: { ! 446: if (qsysdep->ftli) ! 447: { ! 448: if (t_close (qsysdep->o) < 0) ! 449: { ! 450: ulog (LOG_ERROR, "t_close: %s", ztlierror ()); ! 451: fret = FALSE; ! 452: } ! 453: } ! 454: else ! 455: { ! 456: if (close (qsysdep->o) < 0) ! 457: { ! 458: ulog (LOG_ERROR, "close: %s", strerror (errno)); ! 459: fret = FALSE; ! 460: } ! 461: } ! 462: ! 463: qsysdep->o = -1; ! 464: } ! 465: ! 466: return fret; ! 467: } ! 468: ! 469: /* Reset the port. This will be called by a child which was forked ! 470: off in ftli_open, above. We don't want uucico to continue looping ! 471: and giving login prompts, so we pretend that we received a SIGINT ! 472: signal. This should probably be handled more cleanly. The signal ! 473: will not be recorded in the log file because we don't set ! 474: afLog_signal[INDEXSIG_SIGINT]. */ ! 475: ! 476: /*ARGSUSED*/ ! 477: static boolean ! 478: ftli_reset (qconn) ! 479: struct sconnection *qconn; ! 480: { ! 481: afSignal[INDEXSIG_SIGINT] = TRUE; ! 482: return TRUE; ! 483: } ! 484: ! 485: /* Dial out on a TLI port, so to speak: connect to a remote computer. */ ! 486: ! 487: /*ARGSUSED*/ ! 488: static boolean ! 489: ftli_dial (qconn, puuconf, qsys, zphone, qdialer, ptdialerfound) ! 490: struct sconnection *qconn; ! 491: pointer puuconf; ! 492: const struct uuconf_system *qsys; ! 493: const char *zphone; ! 494: struct uuconf_dialer *qdialer; ! 495: enum tdialerfound *ptdialerfound; ! 496: { ! 497: struct ssysdep_conn *qsysdep; ! 498: char **pzdialer; ! 499: const char *zaddr; ! 500: struct t_call *qtcall; ! 501: char *zescape; ! 502: ! 503: qsysdep = (struct ssysdep_conn *) qconn->psysdep; ! 504: ! 505: *ptdialerfound = DIALERFOUND_FALSE; ! 506: ! 507: pzdialer = qconn->qport->uuconf_u.uuconf_stli.uuconf_pzdialer; ! 508: if (*pzdialer == NULL) ! 509: pzdialer = NULL; ! 510: ! 511: /* If the first dialer is "TLI" or "TLIS", we use the first token ! 512: (pzdialer[1]) as the address to connect to. */ ! 513: zaddr = zphone; ! 514: if (pzdialer != NULL ! 515: && (strcmp (pzdialer[0], "TLI") == 0 ! 516: || strcmp (pzdialer[0], "TLIS") == 0)) ! 517: { ! 518: if (pzdialer[1] == NULL) ! 519: ++pzdialer; ! 520: else ! 521: { ! 522: if (strcmp (pzdialer[1], "\\D") != 0 ! 523: && strcmp (pzdialer[1], "\\T") != 0) ! 524: zaddr = pzdialer[1]; ! 525: pzdialer += 2; ! 526: } ! 527: } ! 528: ! 529: if (zaddr == NULL) ! 530: { ! 531: ulog (LOG_ERROR, "No address for TLI connection"); ! 532: return FALSE; ! 533: } ! 534: ! 535: qtcall = (struct t_call *) t_alloc (qsysdep->o, T_CALL, T_ADDR); ! 536: if (qtcall == NULL) ! 537: { ! 538: ulog (LOG_ERROR, "t_alloc (T_CALL): %s", ztlierror ()); ! 539: return FALSE; ! 540: } ! 541: ! 542: zescape = zbufcpy (zaddr); ! 543: qtcall->addr.len = cescape (zescape); ! 544: if (qtcall->addr.len > qtcall->addr.maxlen) ! 545: { ! 546: ulog (LOG_ERROR, "%s: TLI address too long (max %d)", zaddr, ! 547: qtcall->addr.maxlen); ! 548: ubuffree (zescape); ! 549: return FALSE; ! 550: } ! 551: memcpy (qtcall->addr.buf, zescape, qtcall->addr.len); ! 552: ubuffree (zescape); ! 553: ! 554: if (t_connect (qsysdep->o, qtcall, (struct t_call *) NULL) < 0) ! 555: { ! 556: if (t_errno != TLOOK) ! 557: ulog (LOG_ERROR, "t_connect: %s", ztlierror ()); ! 558: else ! 559: { ! 560: if (t_rcvdis (qsysdep->o, (struct t_discon *) NULL) < 0) ! 561: ulog (LOG_ERROR, "t_rcvdis: %s", ztlierror ()); ! 562: else ! 563: ulog (LOG_ERROR, "Connection refused"); ! 564: } ! 565: return FALSE; ! 566: } ! 567: ! 568: /* We've connected to the remote. Push any desired modules. */ ! 569: if (! ftli_push (qconn)) ! 570: return FALSE; ! 571: ! 572: /* Handle the rest of the dialer sequence. This is similar to ! 573: fmodem_dial, and they should, perhaps, be combined somehow. */ ! 574: if (pzdialer != NULL) ! 575: { ! 576: boolean ffirst; ! 577: ! 578: ffirst = TRUE; ! 579: while (*pzdialer != NULL) ! 580: { ! 581: int iuuconf; ! 582: struct uuconf_dialer *q; ! 583: struct uuconf_dialer s; ! 584: const char *ztoken; ! 585: boolean ftranslate; ! 586: ! 587: if (! ffirst) ! 588: q = &s; ! 589: else ! 590: q = qdialer; ! 591: ! 592: iuuconf = uuconf_dialer_info (puuconf, *pzdialer, q); ! 593: if (iuuconf == UUCONF_NOT_FOUND) ! 594: { ! 595: ulog (LOG_ERROR, "%s: Dialer not found", *pzdialer); ! 596: return FALSE; ! 597: } ! 598: else if (iuuconf != UUCONF_SUCCESS) ! 599: { ! 600: ulog_uuconf (LOG_ERROR, puuconf, iuuconf); ! 601: return FALSE; ! 602: } ! 603: ! 604: ++pzdialer; ! 605: ztoken = *pzdialer; ! 606: ! 607: ftranslate = FALSE; ! 608: if (ztoken == NULL ! 609: || strcmp (ztoken, "\\D") == 0) ! 610: ztoken = zphone; ! 611: else if (strcmp (ztoken, "\\T") == 0) ! 612: { ! 613: ztoken = zphone; ! 614: ftranslate = TRUE; ! 615: } ! 616: ! 617: if (! fchat (qconn, puuconf, &q->uuconf_schat, ! 618: (const struct uuconf_system *) NULL, q, ! 619: zphone, ftranslate, qconn->qport->uuconf_zname, ! 620: (long) 0)) ! 621: { ! 622: (void) uuconf_dialer_free (puuconf, q); ! 623: if (! ffirst) ! 624: (void) uuconf_dialer_free (puuconf, qdialer); ! 625: return FALSE; ! 626: } ! 627: ! 628: if (ffirst) ! 629: { ! 630: *ptdialerfound = DIALERFOUND_FREE; ! 631: ffirst = FALSE; ! 632: } ! 633: else ! 634: (void) uuconf_dialer_free (puuconf, q); ! 635: ! 636: if (*pzdialer != NULL) ! 637: ++pzdialer; ! 638: } ! 639: } ! 640: ! 641: return TRUE; ! 642: } ! 643: ! 644: #endif /* HAVE_TLI */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.