xref: /csrg-svn/sbin/startslip/startslip.c (revision 45367)
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*45367Smckusick static char sccsid[] = "@(#)startslip.c	5.2 (Berkeley) 10/20/90";
1645365Smckusick #endif /* not lint */
1745365Smckusick 
1845365Smckusick #include <sys/param.h>
19*45367Smckusick #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>
29*45367Smckusick #include <signal.h>
3045365Smckusick 
3145365Smckusick #define DEFAULT_BAUD    B9600
3245365Smckusick int     speed = DEFAULT_BAUD;
33*45367Smckusick 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;
52*45367Smckusick 	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
80*45367Smckusick 	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:
88*45367Smckusick 	hup = 0;
8945365Smckusick 	printd("restart\n");
9045365Smckusick 	if (fd >= 0)
9145365Smckusick 		close(fd);
9245365Smckusick 	if (first)
9345365Smckusick 		sleep(2);
9445365Smckusick 	if ((fd = open(argv[0], O_RDWR)) < 0) {
9545365Smckusick 		perror(argv[0]);
9645365Smckusick 		syslog(LOG_ERR, "startslip: open %s: %m\n", argv[0]);
9745365Smckusick 		if (first)
9845365Smckusick 			exit(1);
9945365Smckusick 		else {
10045365Smckusick 			sleep(5*60);
10145365Smckusick 			goto restart;
10245365Smckusick 		}
10345365Smckusick 	}
10445365Smckusick 	printd("open %d\n", fd);
105*45367Smckusick 	if (debug) {
106*45367Smckusick 		if (ioctl(fd, TIOCGETD, &disc) < 0)
107*45367Smckusick 			perror("ioctl(TIOCSETD)");
108*45367Smckusick 		printf("disc was %d\n", disc);
109*45367Smckusick 	}
110*45367Smckusick 	disc = TTYDISC;
111*45367Smckusick 	if (ioctl(fd, TIOCSETD, &disc) < 0) {
112*45367Smckusick 	        perror("ioctl(TIOCSETD)");
113*45367Smckusick 		syslog(LOG_ERR, "startslip: %s: ioctl (TIOCSETD 0): %m\n",
114*45367Smckusick 		    argv[0]);
115*45367Smckusick 	}
11645365Smckusick 	if (dialerstring) {
11745365Smckusick 		(void) write(fd, dialerstring, strlen(dialerstring));
11845365Smckusick 		(void) write(fd, "\n", 1);
11945365Smckusick 	}
12045365Smckusick 	if (ioctl(fd, TIOCGETP, &sgtty) < 0) {
12145365Smckusick 	        perror("ioctl (TIOCGETP)");
12245365Smckusick 	        exit(2);
12345365Smckusick 	}
12445365Smckusick 	sgtty.sg_flags = RAW | ANYP;
12545365Smckusick 	sgtty.sg_erase = sgtty.sg_kill = 0377;
12645365Smckusick 	sgtty.sg_ispeed = sgtty.sg_ospeed = speed;
12745365Smckusick 	if (ioctl(fd, TIOCSETP, &sgtty) < 0) {
12845365Smckusick 	        perror("ioctl (TIOCSETP)");
12945365Smckusick 		syslog(LOG_ERR, "startslip: %s: ioctl (TIOCSETP): %m\n",
13045365Smckusick 		    argv[0]);
13145365Smckusick 	        exit(2);
13245365Smckusick 	}
13345365Smckusick 	printd("ioctl\n");
13445365Smckusick 	/*
13545365Smckusick 	 * Log in
13645365Smckusick 	 */
137*45367Smckusick 	wfd = fdopen(fd, "w+");
13845365Smckusick 	printd("fdopen\n");
13945365Smckusick 	if (wfd == NULL) {
14045365Smckusick 		syslog(LOG_ERR, "startslip: can't fdopen slip line\n");
14145365Smckusick 		exit(10);
14245365Smckusick 	}
14345365Smckusick 	putc('\n', wfd);
14445365Smckusick 	while (fflush(wfd), getline(buf, BUFSIZ, fd) != NULL) {
145*45367Smckusick 		if (hup != 0)
146*45367Smckusick 			goto restart;
14745365Smckusick 	        if (bcmp(&buf[1], "ogin:", 5) == 0) {
14845365Smckusick 	                fprintf(wfd, "%s\r", argv[1]);
14945365Smckusick 	                continue;
15045365Smckusick 	        }
15145365Smckusick 	        if (bcmp(&buf[1], "assword:", 8) == 0) {
15245365Smckusick 	                fprintf(wfd, "%s\r", argv[2]);
15345365Smckusick 	                fflush(wfd);
15445365Smckusick 	                break;
15545365Smckusick 	        }
15645365Smckusick 	}
15745365Smckusick 	printd("login\n");
15845365Smckusick 	/*
15945365Smckusick 	 * Attach
16045365Smckusick 	 */
161*45367Smckusick 	disc = SLIPDISC;
162*45367Smckusick 	if (ioctl(fd, TIOCSETD, &disc) < 0) {
16345365Smckusick 	        perror("ioctl(TIOCSETD)");
164*45367Smckusick 		syslog(LOG_ERR, "startslip: %s: ioctl (TIOCSETD SLIP): %m\n",
16545365Smckusick 		    argv[0]);
16645365Smckusick 	        exit(1);
16745365Smckusick 	}
168*45367Smckusick 	printd("setd\n");
169*45367Smckusick 	disc = SC_COMPRESS;
170*45367Smckusick 	if (ioctl(fd, SLIOCSFLAGS, (caddr_t)&disc) < 0) {
17145365Smckusick 	        perror("ioctl(SLIOCFLAGS)");
17245365Smckusick 		syslog(LOG_ERR, "ioctl (SLIOCSFLAGS): %m");
17345365Smckusick 		exit(1);
17445365Smckusick 	}
17545365Smckusick 	if (!first++) {
17645365Smckusick 		if (fork() > 0)
17745365Smckusick 			exit(0);
17845365Smckusick #ifdef TIOCSCTTY
17945365Smckusick 		if (setsid() == -1)
18045365Smckusick 			perror("setsid");
18145365Smckusick #endif
18245365Smckusick 		if (debug == 0) {
18345365Smckusick 			close(0);
18445365Smckusick 			close(1);
18545365Smckusick 			close(2);
186*45367Smckusick 			(void) open("/dev/null", O_RDWR);
187*45367Smckusick 			(void) dup2(0, 1);
188*45367Smckusick 			(void) dup2(0, 2);
18945365Smckusick 		}
19045365Smckusick 	}
191*45367Smckusick #ifdef TIOCSCTTY
192*45367Smckusick 	if (ioctl(fd, TIOCSCTTY, 0) < 0)
193*45367Smckusick 		perror("ioctl (TIOCSCTTY)");
194*45367Smckusick #endif
19545365Smckusick 	(void) system("ifconfig sl0 up");
196*45367Smckusick 	while (hup == 0)
197*45367Smckusick 		sigpause(0L);
19845365Smckusick 	printd("fclose\n");
19945365Smckusick 	fclose(wfd);
200*45367Smckusick #ifdef TIOCSCTTY
201*45367Smckusick 	if (fork() > 0)
202*45367Smckusick 		exit(0);
203*45367Smckusick 	if (setsid() == -1)
204*45367Smckusick 		perror("setsid");
205*45367Smckusick 	sleep(5);
206*45367Smckusick #endif
20745365Smckusick 	goto restart;
20845365Smckusick }
20945365Smckusick 
21045365Smckusick sighup()
21145365Smckusick {
21245365Smckusick 
213*45367Smckusick 	printd("hup\n");
21445365Smckusick 	syslog(LOG_INFO, "startslip: hangup signal\n");
215*45367Smckusick 	hup = 1;
21645365Smckusick }
21745365Smckusick 
21845365Smckusick getline(buf, size, fd)
21945365Smckusick 	char *buf;
22045365Smckusick 	int size, fd;
22145365Smckusick {
22245365Smckusick 	register int i;
22345365Smckusick 
22445365Smckusick 	size--;
22545365Smckusick 	for (i = 0; i < size; i++) {
226*45367Smckusick 		if (hup)
227*45367Smckusick 			return (0);
22845365Smckusick 	        if (read(fd, &buf[i], 1) == 1) {
22945365Smckusick 	                buf[i] &= 0177;
23045365Smckusick 	                if (buf[i] == '\r')
23145365Smckusick 	                        buf[i] = '\n';
23245365Smckusick 	                if (buf[i] != '\n' && buf[i] != ':')
23345365Smckusick 	                        continue;
23445365Smckusick 	                buf[i + 1] = '\0';
23545365Smckusick 			if (debug)
236*45367Smckusick 				fprintf(stderr, "Got %d: \"%s\"\n", i + 1, buf);
23745365Smckusick 	                return (i+1);
23845365Smckusick 	        }
23945365Smckusick 	        perror("read");
240*45367Smckusick 		sleep(5*60);
24145365Smckusick 	        i--;
24245365Smckusick 	}
243*45367Smckusick 	return (0);
24445365Smckusick }
24545365Smckusick 
24645365Smckusick usage()
24745365Smckusick {
24845365Smckusick 	fprintf(stderr, "usage: startslip [-d] [-s string] dev user passwd\n");
24945365Smckusick 	exit(1);
25045365Smckusick }
251