145365Smckusick /*- 245365Smckusick * Copyright (c) 1990 The Regents of the University of California. 345365Smckusick * All rights reserved. 445365Smckusick * 545365Smckusick * %sccs.include.redist.c% 645365Smckusick */ 745365Smckusick 845365Smckusick #ifndef lint 945365Smckusick char copyright[] = 1045365Smckusick "@(#) Copyright (c) 1990 The Regents of the University of California.\n\ 1145365Smckusick All rights reserved.\n"; 1245365Smckusick #endif /* not lint */ 1345365Smckusick 1445365Smckusick #ifndef lint 15*45517Smckusick static char sccsid[] = "@(#)startslip.c 5.3 (Berkeley) 11/05/90"; 1645365Smckusick #endif /* not lint */ 1745365Smckusick 1845365Smckusick #include <sys/param.h> 1945367Smckusick #include <sgtty.h> 2045365Smckusick #include <sys/socket.h> 2145365Smckusick #include <sys/syslog.h> 2245365Smckusick #include <netinet/in.h> 2345365Smckusick #include <net/if.h> 2445365Smckusick #include <net/if_slvar.h> 2545365Smckusick #include <netdb.h> 2645365Smckusick #include <errno.h> 2745365Smckusick #include <fcntl.h> 2845365Smckusick #include <stdio.h> 2945367Smckusick #include <signal.h> 3045365Smckusick 3145365Smckusick #define DEFAULT_BAUD B9600 3245365Smckusick int speed = DEFAULT_BAUD; 3345367Smckusick int hup; 3445365Smckusick #ifdef DEBUG 3545365Smckusick int debug = 1; 3645365Smckusick #undef LOG_ERR 3745365Smckusick #undef LOG_INFO 3845365Smckusick #define syslog fprintf 3945365Smckusick #define LOG_ERR stderr 4045365Smckusick #define LOG_INFO stderr 4145365Smckusick #else 4245365Smckusick int debug = 0; 4345365Smckusick #endif 4445365Smckusick #define printd if (debug) printf 4545365Smckusick 4645365Smckusick main(argc, argv) 4745365Smckusick int argc; 4845365Smckusick char **argv; 4945365Smckusick { 5045365Smckusick extern char *optarg; 5145365Smckusick extern int optind; 5245367Smckusick int ch, disc; 5345365Smckusick int fd = -1, sighup(); 5445365Smckusick FILE *wfd; 5545365Smckusick char *dialerstring = 0, buf[BUFSIZ]; 5645365Smckusick struct sgttyb sgtty; 5745365Smckusick int first = 0; 5845365Smckusick 5945365Smckusick while ((ch = getopt(argc, argv, "ds:")) != EOF) 6045365Smckusick switch(ch) { 6145365Smckusick case 'd': 6245365Smckusick debug = 1; 6345365Smckusick break; 6445365Smckusick case 's': 6545365Smckusick dialerstring = optarg; 6645365Smckusick break; 6745365Smckusick case '?': 6845365Smckusick default: 6945365Smckusick usage(); 7045365Smckusick } 7145365Smckusick argc -= optind; 7245365Smckusick argv += optind; 7345365Smckusick 7445365Smckusick if (argc != 3) 7545365Smckusick usage(); 7645365Smckusick 7745365Smckusick openlog("startslip", LOG_PID, LOG_DAEMON); 7845365Smckusick 7945365Smckusick #if BSD <= 43 8045367Smckusick if (debug == 0 && (fd = open("/dev/tty", 0)) >= 0) { 8145365Smckusick ioctl(fd, TIOCNOTTY, 0); 8245365Smckusick close(fd); 8345365Smckusick } 8445365Smckusick #endif 8545365Smckusick 8645365Smckusick signal(SIGHUP, sighup); 8745365Smckusick restart: 8845367Smckusick hup = 0; 8945365Smckusick printd("restart\n"); 9045365Smckusick if (fd >= 0) 9145365Smckusick close(fd); 92*45517Smckusick if (!first) { 93*45517Smckusick if (fork() > 0) 94*45517Smckusick exit(0); 95*45517Smckusick printd("(pid %d)\n", getpid()); 96*45517Smckusick #ifdef TIOCSCTTY 97*45517Smckusick if (setsid() == -1) 98*45517Smckusick perror("setsid"); 99*45517Smckusick #endif 100*45517Smckusick } else 10145365Smckusick sleep(2); 10245365Smckusick if ((fd = open(argv[0], O_RDWR)) < 0) { 10345365Smckusick perror(argv[0]); 10445365Smckusick syslog(LOG_ERR, "startslip: open %s: %m\n", argv[0]); 10545365Smckusick if (first) 10645365Smckusick exit(1); 10745365Smckusick else { 10845365Smckusick sleep(5*60); 10945365Smckusick goto restart; 11045365Smckusick } 11145365Smckusick } 11245365Smckusick printd("open %d\n", fd); 113*45517Smckusick #ifdef TIOCSCTTY 114*45517Smckusick if (ioctl(fd, TIOCSCTTY, 0) < 0) 115*45517Smckusick perror("ioctl (TIOCSCTTY)"); 116*45517Smckusick #endif 11745367Smckusick if (debug) { 11845367Smckusick if (ioctl(fd, TIOCGETD, &disc) < 0) 11945367Smckusick perror("ioctl(TIOCSETD)"); 12045367Smckusick printf("disc was %d\n", disc); 12145367Smckusick } 12245367Smckusick disc = TTYDISC; 12345367Smckusick if (ioctl(fd, TIOCSETD, &disc) < 0) { 12445367Smckusick perror("ioctl(TIOCSETD)"); 12545367Smckusick syslog(LOG_ERR, "startslip: %s: ioctl (TIOCSETD 0): %m\n", 12645367Smckusick argv[0]); 12745367Smckusick } 12845365Smckusick if (dialerstring) { 12945365Smckusick (void) write(fd, dialerstring, strlen(dialerstring)); 13045365Smckusick (void) write(fd, "\n", 1); 13145365Smckusick } 13245365Smckusick if (ioctl(fd, TIOCGETP, &sgtty) < 0) { 13345365Smckusick perror("ioctl (TIOCGETP)"); 13445365Smckusick exit(2); 13545365Smckusick } 13645365Smckusick sgtty.sg_flags = RAW | ANYP; 13745365Smckusick sgtty.sg_erase = sgtty.sg_kill = 0377; 13845365Smckusick sgtty.sg_ispeed = sgtty.sg_ospeed = speed; 13945365Smckusick if (ioctl(fd, TIOCSETP, &sgtty) < 0) { 14045365Smckusick perror("ioctl (TIOCSETP)"); 14145365Smckusick syslog(LOG_ERR, "startslip: %s: ioctl (TIOCSETP): %m\n", 14245365Smckusick argv[0]); 14345365Smckusick exit(2); 14445365Smckusick } 14545365Smckusick printd("ioctl\n"); 14645365Smckusick /* 14745365Smckusick * Log in 14845365Smckusick */ 14945367Smckusick wfd = fdopen(fd, "w+"); 15045365Smckusick printd("fdopen\n"); 15145365Smckusick if (wfd == NULL) { 15245365Smckusick syslog(LOG_ERR, "startslip: can't fdopen slip line\n"); 15345365Smckusick exit(10); 15445365Smckusick } 15545365Smckusick putc('\n', wfd); 15645365Smckusick while (fflush(wfd), getline(buf, BUFSIZ, fd) != NULL) { 15745367Smckusick if (hup != 0) 158*45517Smckusick goto cleanup; 15945365Smckusick if (bcmp(&buf[1], "ogin:", 5) == 0) { 16045365Smckusick fprintf(wfd, "%s\r", argv[1]); 16145365Smckusick continue; 16245365Smckusick } 16345365Smckusick if (bcmp(&buf[1], "assword:", 8) == 0) { 16445365Smckusick fprintf(wfd, "%s\r", argv[2]); 16545365Smckusick fflush(wfd); 16645365Smckusick break; 16745365Smckusick } 16845365Smckusick } 16945365Smckusick printd("login\n"); 17045365Smckusick /* 17145365Smckusick * Attach 17245365Smckusick */ 17345367Smckusick disc = SLIPDISC; 17445367Smckusick if (ioctl(fd, TIOCSETD, &disc) < 0) { 17545365Smckusick perror("ioctl(TIOCSETD)"); 17645367Smckusick syslog(LOG_ERR, "startslip: %s: ioctl (TIOCSETD SLIP): %m\n", 17745365Smckusick argv[0]); 17845365Smckusick exit(1); 17945365Smckusick } 18045367Smckusick printd("setd\n"); 18145367Smckusick disc = SC_COMPRESS; 18245367Smckusick if (ioctl(fd, SLIOCSFLAGS, (caddr_t)&disc) < 0) { 18345365Smckusick perror("ioctl(SLIOCFLAGS)"); 18445365Smckusick syslog(LOG_ERR, "ioctl (SLIOCSFLAGS): %m"); 18545365Smckusick exit(1); 18645365Smckusick } 187*45517Smckusick if (!first++ && debug == 0) { 188*45517Smckusick close(0); 189*45517Smckusick close(1); 190*45517Smckusick close(2); 191*45517Smckusick (void) open("/dev/null", O_RDWR); 192*45517Smckusick (void) dup2(0, 1); 193*45517Smckusick (void) dup2(0, 2); 19445365Smckusick } 19545365Smckusick (void) system("ifconfig sl0 up"); 196*45517Smckusick while (hup == 0) { 19745367Smckusick sigpause(0L); 198*45517Smckusick printd("sigpause return "); 199*45517Smckusick } 200*45517Smckusick cleanup: 201*45517Smckusick printd("close\n"); 20245365Smckusick fclose(wfd); 203*45517Smckusick close(fd); 20445367Smckusick #ifdef TIOCSCTTY 20545367Smckusick if (fork() > 0) 20645367Smckusick exit(0); 207*45517Smckusick printd("(pid %d)\n", getpid()); 20845367Smckusick if (setsid() == -1) 20945367Smckusick perror("setsid"); 21045367Smckusick sleep(5); 21145367Smckusick #endif 21245365Smckusick goto restart; 21345365Smckusick } 21445365Smckusick 21545365Smckusick sighup() 21645365Smckusick { 21745365Smckusick 21845367Smckusick printd("hup\n"); 219*45517Smckusick if (hup == 0) 220*45517Smckusick syslog(LOG_INFO, "startslip: hangup signal\n"); 22145367Smckusick hup = 1; 22245365Smckusick } 22345365Smckusick 22445365Smckusick getline(buf, size, fd) 22545365Smckusick char *buf; 22645365Smckusick int size, fd; 22745365Smckusick { 22845365Smckusick register int i; 229*45517Smckusick int ret; 23045365Smckusick 23145365Smckusick size--; 23245365Smckusick for (i = 0; i < size; i++) { 23345367Smckusick if (hup) 23445367Smckusick return (0); 235*45517Smckusick if ((ret = read(fd, &buf[i], 1)) == 1) { 23645365Smckusick buf[i] &= 0177; 23745365Smckusick if (buf[i] == '\r') 23845365Smckusick buf[i] = '\n'; 23945365Smckusick if (buf[i] != '\n' && buf[i] != ':') 24045365Smckusick continue; 24145365Smckusick buf[i + 1] = '\0'; 24245365Smckusick if (debug) 24345367Smckusick fprintf(stderr, "Got %d: \"%s\"\n", i + 1, buf); 24445365Smckusick return (i+1); 24545365Smckusick } 246*45517Smckusick if (ret < 0) { 247*45517Smckusick perror("getline: read (sleeping)"); 248*45517Smckusick buf[i] = '\0'; 249*45517Smckusick sleep(60); 250*45517Smckusick printd("returning 0 after %d: \"%s\"\n", i, buf); 251*45517Smckusick return (0); 252*45517Smckusick } 25345365Smckusick } 25445367Smckusick return (0); 25545365Smckusick } 25645365Smckusick 25745365Smckusick usage() 25845365Smckusick { 25945365Smckusick fprintf(stderr, "usage: startslip [-d] [-s string] dev user passwd\n"); 26045365Smckusick exit(1); 26145365Smckusick } 262