int main(int argc, char **argv) { char *cp, **ap; int ch, disc; FILE *wfd = NULL; char *dialerstring = 0, buf[BUFSIZ]; int unitnum, keepal = 0, outfill = 0; char unitname[32]; char *password; char *upscript = NULL, *downscript = NULL; int first = 1, tries = 0; time_t fintimeout; long lpid; pid_t pid; struct termios t; int result; while ((ch = getopt(argc, argv, "dhlb:s:t:w:A:U:D:W:K:O:S:L")) != -1) switch (ch) { case 'd': debug = 1; break; case 'b': speed = atoi(optarg); break; case 's': if (diali >= MAXDIALS) errx(1, "max dial strings number (%d) exceeded", MAXDIALS); dials[diali++] = strdup(optarg); break; case 't': script_timeout = atoi(optarg); break; case 'w': wait_time = atoi(optarg); break; case 'W': MAXTRIES = atoi(optarg); break; case 'A': annex = strdup(optarg); break; case 'U': upscript = strdup(optarg); break; case 'D': downscript = strdup(optarg); break; case 'L': uucp_lock = 1; break; case 'l': modem_control = 0; break; case 'h': flowcontrol = FC_HW; break; case 'K': keepal = atoi(optarg); break; case 'O': outfill = atoi(optarg); break; case 'S': sl_unit = atoi(optarg); break; case '?': default: usage(); } argc -= optind; argv += optind; if (argc != 3) usage(); /* * Copy these so they exist after we clobber them. */ devicename = strdup(argv[0]); username = strdup(argv[1]); password = strdup(argv[2]); /* * Security hack. Do not want private information such as the * password and possible phone number to be left around. * So we clobber the arguments. */ for (ap = argv - optind + 1; ap < argv + 3; ap++) for (cp = *ap; *cp != 0; cp++) *cp = '\0'; openlog("startslip", LOG_PID|LOG_PERROR, LOG_DAEMON); if (debug) setbuf(stdout, NULL); signal(SIGTERM, sigterm); if ((dvname = strrchr(devicename, '/')) == NULL) dvname = devicename; else dvname++; result = snprintf(my_pidfile, sizeof(my_pidfile), PIDFILE, _PATH_VARRUN, dvname); if (result < 0 || (unsigned int)result >= sizeof(my_pidfile)) usage(); if ((pfd = fopen(my_pidfile, "r")) != NULL) { if (fscanf(pfd, "%ld\n", &lpid) == 1) { pid = lpid; if (pid == lpid && pid > 0) kill(pid, SIGTERM); } fclose(pfd); pfd = NULL; /* not remove pidfile yet */ sleep(5); /* allow down script to be completed */ } else restart: signal(SIGHUP, SIG_IGN); signal(SIGURG, SIG_IGN); hup = 0; if (wfd) { printd("fclose, "); fclose(wfd); conn_time = time(NULL) - start_time; if (uucp_lock) uu_unlock(dvname); locked = 0; wfd = NULL; fd = -1; sleep(5); } else if (fd >= 0) { printd("close, "); close(fd); conn_time = time(NULL) - start_time; if (uucp_lock) uu_unlock(dvname); locked = 0; fd = -1; sleep(5); } if (logged_in) { syslog(LOG_INFO, "%s: connection time elapsed: %ld secs", username, (long)conn_time); sprintf(buf, "LINE=%d %s %s down", diali ? (dialc - 1) % diali : 0, downscript ? downscript : "/sbin/ifconfig" , unitname); system(buf); logged_in = 0; } if (terminate) down(0); tries++; if (MAXTRIES > 0 && tries > MAXTRIES) { syslog(LOG_ERR, "%s: exiting login after %d tries", username, tries); /* ??? if (first) */ down(3); } if (tries > 1) { syslog(LOG_INFO, "%s: sleeping %d seconds (%d tries)", username, wait_time * (tries - 1), tries); sleep(wait_time * (tries - 1)); if (terminate) goto restart; } if (daemon(1, debug) < 0) { syslog(LOG_ERR, "%s: daemon: %m", username); down(2); } pid = getpid(); printd("restart: pid %ld: ", (long)pid); if ((pfd = fopen(my_pidfile, "w")) != NULL) { fprintf(pfd, "%ld\n", (long)pid); fclose(pfd); } printd("open"); if (uucp_lock) { int res; if ((res = uu_lock(dvname)) != UU_LOCK_OK) { if (res != UU_LOCK_INUSE) syslog(LOG_ERR, "uu_lock: %s", uu_lockerr(res)); syslog(LOG_ERR, "%s: can't lock %s", username, devicename); goto restart; } locked = 1; } if ((fd = open(devicename, O_RDWR | O_NONBLOCK)) < 0) { syslog(LOG_ERR, "%s: open %s: %m", username, devicename); if (first) down(1); else { if (uucp_lock) uu_unlock(dvname); locked = 0; goto restart; } } printd(" %d", fd); signal(SIGHUP, sighup); if (ioctl(fd, TIOCSCTTY, 0) < 0) { syslog(LOG_ERR, "%s: ioctl (TIOCSCTTY): %m", username); down(2); } if (tcsetpgrp(fd, getpid()) < 0) { syslog(LOG_ERR, "%s: tcsetpgrp failed: %m", username); down(2); } printd(", ioctl\n"); if (tcgetattr(fd, &t) < 0) { syslog(LOG_ERR, "%s: tcgetattr(%s): %m", username, devicename); down(2); } cfmakeraw(&t); switch (flowcontrol) { case FC_HW: t.c_cflag |= (CRTS_IFLOW|CCTS_OFLOW); break; case FC_NONE: t.c_cflag &= ~(CRTS_IFLOW|CCTS_OFLOW); break; } if (modem_control) t.c_cflag |= HUPCL; else t.c_cflag &= ~(HUPCL); t.c_cflag |= CLOCAL; /* until modem commands passes */ cfsetispeed(&t, speed); cfsetospeed(&t, speed); if (tcsetattr(fd, TCSAFLUSH, &t) < 0) { syslog(LOG_ERR, "%s: tcsetattr(%s): %m", username, devicename); down(2); } sleep(2); /* wait for flakey line to settle */ if (hup || terminate) goto restart; wfd = fdopen(fd, "w+"); if (wfd == NULL) { syslog(LOG_ERR, "%s: can't fdopen %s: %m", username, devicename); down(2); } setbuf(wfd, NULL); if (diali > 0) dialerstring = dials[dialc++ % diali]; if (dialerstring) { syslog(LOG_INFO, "%s: dialer string: %s\\r", username, dialerstring); fprintf(wfd, "%s\r", dialerstring); } printd("\n"); fintimeout = time(NULL) + script_timeout; if (modem_control) { printd("waiting for carrier\n"); while (time(NULL) < fintimeout && !carrier()) { sleep(1); if (hup || terminate) goto restart; } if (!carrier()) goto restart; t.c_cflag &= ~(CLOCAL); if (tcsetattr(fd, TCSANOW, &t) < 0) { syslog(LOG_ERR, "%s: tcsetattr(%s): %m", username, devicename); down(2); } /* Only now we able to receive HUP on carrier drop! */ } /* * Log in */ printd("look for login: "******"slip\r"); printd("Sent \"slip\"\n"); continue; } if (bcmp(&buf[1], "sername:", 8) == 0) { fprintf(wfd, "%s\r", username); printd("Sent login: %s\n", username); continue; } if (bcmp(&buf[1], "assword:", 8) == 0) { fprintf(wfd, "%s\r", password); printd("Sent password: %s\n", password); break; } } else { if (strstr(&buf[1], "ogin:") != NULL) { fprintf(wfd, "%s\r", username); printd("Sent login: %s\n", username); continue; } if (strstr(&buf[1], "assword:") != NULL) { fprintf(wfd, "%s\r", password); printd("Sent password: %s\n", password); break; } } } sleep(5); /* Wait until login completed */ if (hup || terminate) goto restart; start_time = time(NULL); /* * Attach */ printd("setd"); disc = SLIPDISC; if (ioctl(fd, TIOCSETD, &disc) < 0) { syslog(LOG_ERR, "%s: ioctl (%s, TIOCSETD): %m", username, devicename); down(2); } if (sl_unit >= 0 && ioctl(fd, SLIOCSUNIT, &sl_unit) < 0) { syslog(LOG_ERR, "%s: ioctl(SLIOCSUNIT): %m", username); down(2); } if (ioctl(fd, SLIOCGUNIT, &unitnum) < 0) { syslog(LOG_ERR, "%s: ioctl(SLIOCGUNIT): %m", username); down(2); } sprintf(unitname, "sl%d", unitnum); if (keepal > 0) { signal(SIGURG, sigurg); if (ioctl(fd, SLIOCSKEEPAL, &keepal) < 0) { syslog(LOG_ERR, "%s: ioctl(SLIOCSKEEPAL): %m", username); down(2); } } if (outfill > 0 && ioctl(fd, SLIOCSOUTFILL, &outfill) < 0) { syslog(LOG_ERR, "%s: ioctl(SLIOCSOUTFILL): %m", username); down(2); } sprintf(buf, "LINE=%d %s %s up", diali ? (dialc - 1) % diali : 0, upscript ? upscript : "/sbin/ifconfig" , unitname); system(buf); printd(", ready\n"); if (!first) syslog(LOG_INFO, "%s: reconnected on %s (%d tries)", username, unitname, tries); else syslog(LOG_INFO, "%s: connected on %s", username, unitname); first = 0; tries = 0; logged_in = 1; while (hup == 0 && terminate == 0) { sigpause(0L); printd("sigpause return\n"); } goto restart; return(0); /* not reached */ }
/* * Botch the interface to look like cu's */ void cumain(int argc, char *argv[]) { int i; static char sbuf[12]; if (argc < 2) { printf("usage: cu telno [-t] [-s speed] [-a acu] [-l line] [-#]\n"); exit(8); } CU = DV = NULL; BR = DEFBR; for (; argc > 1; argv++, argc--) { if (argv[1][0] != '-') PN = argv[1]; else switch (argv[1][1]) { case 't': HW = 1, DU = -1; --argc; continue; case 'a': CU = argv[2]; ++argv; --argc; break; case 's': if (argc < 3 || speed(atoi(argv[2])) == 0) { fprintf(stderr, "cu: unsupported speed %s\n", argv[2]); exit(3); } BR = atoi(argv[2]); ++argv; --argc; break; case 'l': DV = argv[2]; ++argv; --argc; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (CU) CU[strlen(CU)-1] = argv[1][1]; if (DV) DV[strlen(DV)-1] = argv[1][1]; break; default: printf("Bad flag %s", argv[1]); break; } } signal(SIGINT, cleanup); signal(SIGQUIT, cleanup); signal(SIGHUP, cleanup); signal(SIGTERM, cleanup); /* * The "cu" host name is used to define the * attributes of the generic dialer. */ (void)snprintf(sbuf, sizeof(sbuf), "cu%ld", BR); if ((i = hunt(sbuf)) == 0) { printf("all ports busy\n"); exit(3); } if (i == -1) { printf("link down\n"); (void)uu_unlock(uucplock); exit(3); } setbuf(stdout, NULL); loginit(); user_uid(); vinit(); setparity("none"); boolean(value(VERBOSE)) = 0; if (HW) ttysetup(speed(BR)); if (connect()) { printf("Connect failed\n"); daemon_uid(); (void)uu_unlock(uucplock); exit(1); } if (!HW) ttysetup(speed(BR)); exit(0); }
/* sighup_handler() is invoked when carrier drops, eg. before redial. */ static void sighup_handler(int signo __unused) { if(exiting) return; if (redial_cmd == NULL) { syslog(LOG_NOTICE,"SIGHUP on %s (sl%d); exiting", dev, unit); exit_handler(1); } again: /* invoke a shell for redial_cmd or punt. */ if (*redial_cmd) { /* Non-empty redial command */ syslog(LOG_NOTICE,"SIGHUP on %s (sl%d); running '%s'", dev, unit, redial_cmd); acquire_line(); /* reopen dead line */ setup_line(CLOCAL); if (locked) { if (uucp_lock) uu_unlock(dvname); /* for redial */ locked = 0; } if (system(redial_cmd)) goto again; if (uucp_lock) { int res; if ((res = uu_lock(dvname)) != UU_LOCK_OK) { if (res != UU_LOCK_INUSE) syslog(LOG_ERR, "uu_lock: %s", uu_lockerr(res)); syslog(LOG_ERR, "can't relock %s after %s, aborting", dev, redial_cmd); exit_handler(1); } locked = 1; } /* Now check again for carrier (dial command is done): */ if (!(modem_control & CLOCAL)) { tty.c_cflag &= ~CLOCAL; if (tcsetattr(fd, TCSAFLUSH, &tty) < 0) { syslog(LOG_ERR, "tcsetattr(TCSAFLUSH): %m"); exit_handler(1); } ioctl(fd, TIOCMGET, &comstate); if (!(comstate & TIOCM_CD)) { /* check for carrier */ /* force a redial if no carrier */ goto again; } } else setup_line(0); } else { /* Empty redial command */ syslog(LOG_NOTICE,"SIGHUP on %s (sl%d); reestablish connection", dev, unit); acquire_line(); /* reopen dead line */ setup_line(0); /* restore ospeed from hangup (B0) */ /* If modem control, just wait for carrier before attaching. If no modem control, just fall through immediately. */ if (!(modem_control & CLOCAL)) { int carrier = 0; syslog(LOG_NOTICE, "waiting for carrier on %s (sl%d)", dev, unit); /* Now wait for carrier before attaching line. */ /* We must poll since CLOCAL prevents signal. */ while (! carrier) { sleep(2); ioctl(fd, TIOCMGET, &comstate); if (comstate & TIOCM_CD) carrier = 1; } syslog(LOG_NOTICE, "carrier now present on %s (sl%d)", dev, unit); } } slip_discipline(); configure_network(); }
int main(int argc, char *argv[]) { char *sys = NOSTR, sbuf[12], *p; int i; /* XXX preserve previous braindamaged behavior */ setboolean(value(DC), TRUE); gid = getgid(); egid = getegid(); uid = getuid(); euid = geteuid(); if (equal(__progname, "cu")) { cumode = 1; cumain(argc, argv); goto cucommon; } if (argc > 4) { fprintf(stderr, "usage: tip [-v] [-speed] [system-name]\n"); exit(1); } if (!isatty(0)) { fprintf(stderr, "%s: must be interactive\n", __progname); exit(1); } for (; argc > 1; argv++, argc--) { if (argv[1][0] != '-') sys = argv[1]; else switch (argv[1][1]) { case 'v': vflag++; break; case 'n': noesc++; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': BR = atoi(&argv[1][1]); break; default: fprintf(stderr, "%s: %s, unknown option\n", __progname, argv[1]); break; } } if (sys == NOSTR) goto notnumber; if (isalpha(*sys)) goto notnumber; /* * System name is really a phone number... * Copy the number then stomp on the original (in case the number * is private, we don't want 'ps' or 'w' to find it). */ if (strlen(sys) > sizeof PNbuf - 1) { fprintf(stderr, "%s: phone number too long (max = %d bytes)\n", __progname, (int)sizeof(PNbuf) - 1); exit(1); } strlcpy(PNbuf, sys, sizeof PNbuf - 1); for (p = sys; *p; p++) *p = '\0'; PN = PNbuf; (void)snprintf(sbuf, sizeof(sbuf), "tip%ld", BR); sys = sbuf; notnumber: (void)signal(SIGINT, cleanup); (void)signal(SIGQUIT, cleanup); (void)signal(SIGHUP, cleanup); (void)signal(SIGTERM, cleanup); (void)signal(SIGCHLD, SIG_DFL); if ((i = hunt(sys)) == 0) { printf("all ports busy\n"); exit(3); } if (i == -1) { printf("link down\n"); (void)uu_unlock(uucplock); exit(3); } setbuf(stdout, NULL); loginit(); /* * Now that we have the logfile and the ACU open * return to the real uid and gid. These things will * be closed on exit. Swap real and effective uid's * so we can get the original permissions back * for removing the uucp lock. */ user_uid(); /* * Kludge, their's no easy way to get the initialization * in the right order, so force it here */ if ((PH = getenv("PHONES")) == NOSTR) PH = _PATH_PHONES; vinit(); /* init variables */ setparity("none"); /* set the parity table */ /* * Hardwired connections require the * line speed set before they make any transmissions * (this is particularly true of things like a DF03-AC) */ if (HW && ttysetup(number(value(BAUDRATE)))) { fprintf(stderr, "%s: bad baud rate %ld\n", __progname, number(value(BAUDRATE))); daemon_uid(); (void)uu_unlock(uucplock); exit(3); } if ((p = con())) { printf("\07%s\n[EOT]\n", p); daemon_uid(); (void)uu_unlock(uucplock); exit(1); } if (!HW && ttysetup(number(value(BAUDRATE)))) { fprintf(stderr, "%s: bad baud rate %ld\n", __progname, number(value(BAUDRATE))); daemon_uid(); (void)uu_unlock(uucplock); exit(3); } cucommon: /* * From here down the code is shared with * the "cu" version of tip. */ i = fcntl(FD, F_GETFL); if (i == -1) { perror("fcntl"); cleanup(0); } i = fcntl(FD, F_SETFL, i & ~O_NONBLOCK); if (i == -1) { perror("fcntl"); cleanup(0); } tcgetattr(0, &defterm); gotdefterm = 1; term = defterm; term.c_lflag &= ~(ICANON|IEXTEN|ECHO); term.c_iflag &= ~(INPCK|ICRNL); term.c_oflag &= ~OPOST; term.c_cc[VMIN] = 1; term.c_cc[VTIME] = 0; defchars = term; term.c_cc[VINTR] = term.c_cc[VQUIT] = term.c_cc[VSUSP] = term.c_cc[VDSUSP] = term.c_cc[VDISCARD] = term.c_cc[VLNEXT] = _POSIX_VDISABLE; raw(); pipe(fildes); pipe(repdes); (void)signal(SIGALRM, timeout); if (value(LINEDISC) != TTYDISC) { int ld = (int)(intptr_t)value(LINEDISC); ioctl(FD, TIOCSETD, &ld); } /* * Everything's set up now: * connection established (hardwired or dialup) * line conditioned (baud rate, mode, etc.) * internal data structures (variables) * so, fork one process for local side and one for remote. */ printf(cumode ? "Connected\r\n" : "\07connected\r\n"); tipin_pid = getpid(); if ((tipout_pid = fork())) tipin(); else tipout(); /*NOTREACHED*/ exit(0); }
/* * Botch the interface to look like cu's */ void cumain(int argc, char *argv[]) { int ch, i, parity; long l; char *cp; static char sbuf[12]; if (argc < 2) cuusage(); CU = DV = NOSTR; BR = DEFBR; parity = 0; /* none */ /* * We want to accept -# as a speed. It's easiest to look through * the arguments, replace -# with -s#, and let getopt() handle it. */ for (i = 1; i < argc; i++) { if (argv[i][0] == '-' && argv[i][1] >= '0' && argv[i][1] <= '9') { asprintf(&cp, "-s%s", argv[i] + 1); if (cp == NULL) { fprintf(stderr, "%s: cannot convert -# to -s#\n", __progname); exit(3); } argv[i] = cp; } } while ((ch = getopt(argc, argv, "a:l:s:htoe")) != -1) { switch (ch) { case 'a': CU = optarg; break; case 'l': if (DV != NULL) { fprintf(stderr, "%s: cannot specificy multiple -l options\n", __progname); exit(3); } if (strchr(optarg, '/')) DV = optarg; else asprintf(&DV, "/dev/%s", optarg); break; case 's': l = strtol(optarg, &cp, 10); if (*cp != '\0' || l < 0 || l >= INT_MAX) { fprintf(stderr, "%s: unsupported speed %s\n", __progname, optarg); exit(3); } BR = (int)l; break; case 'h': setboolean(value(LECHO), TRUE); HD = TRUE; break; case 't': HW = 1, DU = -1; break; case 'o': if (parity != 0) parity = 0; /* -e -o */ else parity = 1; /* odd */ break; case 'e': if (parity != 0) parity = 0; /* -o -e */ else parity = -1; /* even */ break; default: cuusage(); break; } } argc -= optind; argv += optind; switch (argc) { case 1: PN = argv[0]; break; case 0: break; default: cuusage(); break; } signal(SIGINT, cleanup); signal(SIGQUIT, cleanup); signal(SIGHUP, cleanup); signal(SIGTERM, cleanup); signal(SIGCHLD, SIG_DFL); /* * The "cu" host name is used to define the * attributes of the generic dialer. */ (void)snprintf(sbuf, sizeof(sbuf), "cu%ld", BR); if ((i = hunt(sbuf)) == 0) { printf("all ports busy\n"); exit(3); } if (i == -1) { printf("link down\n"); (void)uu_unlock(uucplock); exit(3); } setbuf(stdout, NULL); loginit(); user_uid(); vinit(); switch (parity) { case -1: setparity("even"); break; case 1: setparity("odd"); break; default: setparity("none"); break; } setboolean(value(VERBOSE), FALSE); if (HW && ttysetup(BR)) { fprintf(stderr, "%s: unsupported speed %ld\n", __progname, BR); daemon_uid(); (void)uu_unlock(uucplock); exit(3); } if (con()) { printf("Connect failed\n"); daemon_uid(); (void)uu_unlock(uucplock); exit(1); } if (!HW && ttysetup(BR)) { fprintf(stderr, "%s: unsupported speed %ld\n", __progname, BR); daemon_uid(); (void)uu_unlock(uucplock); exit(3); } }
int main(int argc, char *argv[]) { char *system = NULL; int i; char *p; char sbuf[12]; gid = getgid(); egid = getegid(); uid = getuid(); euid = geteuid(); #if INCLUDE_CU_INTERFACE if (equal(sname(argv[0]), "cu")) { cumode = 1; cumain(argc, argv); goto cucommon; } #endif /* INCLUDE_CU_INTERFACE */ if (argc > 4) usage(); if (!isatty(0)) errx(1, "must be interactive"); for (; argc > 1; argv++, argc--) { if (argv[1][0] != '-') system = argv[1]; else switch (argv[1][1]) { case 'v': vflag++; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': BR = atoi(&argv[1][1]); break; default: warnx("%s, unknown option", argv[1]); break; } } if (system == NULL) goto notnumber; if (isalpha(*system)) goto notnumber; /* * System name is really a phone number... * Copy the number then stomp on the original (in case the number * is private, we don't want 'ps' or 'w' to find it). */ if (strlen(system) > sizeof(PNbuf) - 1) errx(1, "phone number too long (max = %zd bytes)", sizeof PNbuf - 1); strncpy(PNbuf, system, sizeof(PNbuf) - 1); for (p = system; *p; p++) *p = '\0'; PN = PNbuf; (void)snprintf(sbuf, sizeof(sbuf), "tip%ld", BR); system = sbuf; notnumber: (void)signal(SIGINT, cleanup); (void)signal(SIGQUIT, cleanup); (void)signal(SIGHUP, cleanup); (void)signal(SIGTERM, cleanup); (void)signal(SIGUSR1, tipdone); if ((i = hunt(system)) == 0) { printf("all ports busy\n"); exit(3); } if (i == -1) { printf("link down\n"); (void)uu_unlock(uucplock); exit(3); } setbuf(stdout, NULL); loginit(); /* * Kludge, their's no easy way to get the initialization * in the right order, so force it here */ if ((PH = getenv("PHONES")) == NULL) PH = _PATH_PHONES; vinit(); /* init variables */ setparity("even"); /* set the parity table */ if ((i = speed(number(value(BAUDRATE)))) == 0) { printf("tip: bad baud rate %d\n", number(value(BAUDRATE))); (void)uu_unlock(uucplock); exit(3); } /* * Now that we have the logfile and the ACU open * return to the real uid and gid. These things will * be closed on exit. Swap real and effective uid's * so we can get the original permissions back * for removing the uucp lock. */ user_uid(); /* * Hardwired connections require the * line speed set before they make any transmissions * (this is particularly true of things like a DF03-AC) */ if (HW) ttysetup(i); if ((p = connect())) { printf("\07%s\n[EOT]\n", p); daemon_uid(); (void)uu_unlock(uucplock); exit(1); } if (!HW) ttysetup(i); cucommon: /* * From here down the code is shared with * the "cu" version of tip. */ #if HAVE_TERMIOS tcgetattr (0, &otermios); ctermios = otermios; #ifndef _POSIX_SOURCE ctermios.c_iflag = (IMAXBEL|IXANY|ISTRIP|IXON|BRKINT); ctermios.c_lflag = (PENDIN|IEXTEN|ISIG|ECHOCTL|ECHOE|ECHOKE); #else ctermios.c_iflag = (ISTRIP|IXON|BRKINT); ctermios.c_lflag = (PENDIN|IEXTEN|ISIG|ECHOE); #endif ctermios.c_cflag = (CLOCAL|HUPCL|CREAD|CS8); ctermios.c_cc[VINTR] = ctermios.c_cc[VQUIT] = -1; ctermios.c_cc[VSUSP] = ctermios.c_cc[VDSUSP] = ctermios.c_cc[VDISCARD] = ctermios.c_cc[VLNEXT] = -1; #else /* HAVE_TERMIOS */ ioctl(0, TIOCGETP, (char *)&defarg); ioctl(0, TIOCGETC, (char *)&defchars); ioctl(0, TIOCGLTC, (char *)&deflchars); ioctl(0, TIOCGETD, (char *)&odisc); arg = defarg; arg.sg_flags = ANYP | CBREAK; tchars = defchars; tchars.t_intrc = tchars.t_quitc = -1; ltchars = deflchars; ltchars.t_suspc = ltchars.t_dsuspc = ltchars.t_flushc = ltchars.t_lnextc = -1; #endif /* HAVE_TERMIOS */ raw(); pipe(fildes); pipe(repdes); (void)signal(SIGALRM, timeoutfunc); /* * Everything's set up now: * connection established (hardwired or dialup) * line conditioned (baud rate, mode, etc.) * internal data structures (variables) * so, fork one process for local side and one for remote. */ printf(cumode ? "Connected\r\n" : "\07connected\r\n"); if (LI != NULL && tiplink (LI, 0) != 0) { tipabort ("login failed"); } if ((pid = fork())) tipin(); else tipout(); /*NOTREACHED*/ }