xref: /csrg-svn/sbin/startslip/startslip.c (revision 45517)
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