xref: /original-bsd/sbin/startslip/startslip.c (revision feb5f8e2)
1 /*-
2  * Copyright (c) 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 char copyright[] =
10 "@(#) Copyright (c) 1990 The Regents of the University of California.\n\
11  All rights reserved.\n";
12 #endif /* not lint */
13 
14 #ifndef lint
15 static char sccsid[] = "@(#)startslip.c	5.3 (Berkeley) 11/05/90";
16 #endif /* not lint */
17 
18 #include <sys/param.h>
19 #include <sgtty.h>
20 #include <sys/socket.h>
21 #include <sys/syslog.h>
22 #include <netinet/in.h>
23 #include <net/if.h>
24 #include <net/if_slvar.h>
25 #include <netdb.h>
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <stdio.h>
29 #include <signal.h>
30 
31 #define DEFAULT_BAUD    B9600
32 int     speed = DEFAULT_BAUD;
33 int	hup;
34 #ifdef DEBUG
35 int	debug = 1;
36 #undef LOG_ERR
37 #undef LOG_INFO
38 #define syslog fprintf
39 #define LOG_ERR stderr
40 #define LOG_INFO stderr
41 #else
42 int	debug = 0;
43 #endif
44 #define	printd	if (debug) printf
45 
46 main(argc, argv)
47 	int argc;
48 	char **argv;
49 {
50 	extern char *optarg;
51 	extern int optind;
52 	int ch, disc;
53 	int fd = -1, sighup();
54 	FILE *wfd;
55 	char *dialerstring = 0, buf[BUFSIZ];
56 	struct sgttyb sgtty;
57 	int first = 0;
58 
59 	while ((ch = getopt(argc, argv, "ds:")) != EOF)
60 		switch(ch) {
61 		case 'd':
62 			debug = 1;
63 			break;
64 		case 's':
65 			dialerstring = optarg;
66 			break;
67 		case '?':
68 		default:
69 			usage();
70 		}
71 	argc -= optind;
72 	argv += optind;
73 
74 	if (argc != 3)
75 		usage();
76 
77 	openlog("startslip", LOG_PID, LOG_DAEMON);
78 
79 #if BSD <= 43
80 	if (debug == 0 && (fd = open("/dev/tty", 0)) >= 0) {
81 		ioctl(fd, TIOCNOTTY, 0);
82 		close(fd);
83 	}
84 #endif
85 
86 	signal(SIGHUP, sighup);
87 restart:
88 	hup = 0;
89 	printd("restart\n");
90 	if (fd >= 0)
91 		close(fd);
92 	if (!first) {
93 		if (fork() > 0)
94 			exit(0);
95 		printd("(pid %d)\n", getpid());
96 #ifdef TIOCSCTTY
97 		if (setsid() == -1)
98 			perror("setsid");
99 #endif
100 	} else
101 		sleep(2);
102 	if ((fd = open(argv[0], O_RDWR)) < 0) {
103 		perror(argv[0]);
104 		syslog(LOG_ERR, "startslip: open %s: %m\n", argv[0]);
105 		if (first)
106 			exit(1);
107 		else {
108 			sleep(5*60);
109 			goto restart;
110 		}
111 	}
112 	printd("open %d\n", fd);
113 #ifdef TIOCSCTTY
114 	if (ioctl(fd, TIOCSCTTY, 0) < 0)
115 		perror("ioctl (TIOCSCTTY)");
116 #endif
117 	if (debug) {
118 		if (ioctl(fd, TIOCGETD, &disc) < 0)
119 			perror("ioctl(TIOCSETD)");
120 		printf("disc was %d\n", disc);
121 	}
122 	disc = TTYDISC;
123 	if (ioctl(fd, TIOCSETD, &disc) < 0) {
124 	        perror("ioctl(TIOCSETD)");
125 		syslog(LOG_ERR, "startslip: %s: ioctl (TIOCSETD 0): %m\n",
126 		    argv[0]);
127 	}
128 	if (dialerstring) {
129 		(void) write(fd, dialerstring, strlen(dialerstring));
130 		(void) write(fd, "\n", 1);
131 	}
132 	if (ioctl(fd, TIOCGETP, &sgtty) < 0) {
133 	        perror("ioctl (TIOCGETP)");
134 	        exit(2);
135 	}
136 	sgtty.sg_flags = RAW | ANYP;
137 	sgtty.sg_erase = sgtty.sg_kill = 0377;
138 	sgtty.sg_ispeed = sgtty.sg_ospeed = speed;
139 	if (ioctl(fd, TIOCSETP, &sgtty) < 0) {
140 	        perror("ioctl (TIOCSETP)");
141 		syslog(LOG_ERR, "startslip: %s: ioctl (TIOCSETP): %m\n",
142 		    argv[0]);
143 	        exit(2);
144 	}
145 	printd("ioctl\n");
146 	/*
147 	 * Log in
148 	 */
149 	wfd = fdopen(fd, "w+");
150 	printd("fdopen\n");
151 	if (wfd == NULL) {
152 		syslog(LOG_ERR, "startslip: can't fdopen slip line\n");
153 		exit(10);
154 	}
155 	putc('\n', wfd);
156 	while (fflush(wfd), getline(buf, BUFSIZ, fd) != NULL) {
157 		if (hup != 0)
158 			goto cleanup;
159 	        if (bcmp(&buf[1], "ogin:", 5) == 0) {
160 	                fprintf(wfd, "%s\r", argv[1]);
161 	                continue;
162 	        }
163 	        if (bcmp(&buf[1], "assword:", 8) == 0) {
164 	                fprintf(wfd, "%s\r", argv[2]);
165 	                fflush(wfd);
166 	                break;
167 	        }
168 	}
169 	printd("login\n");
170 	/*
171 	 * Attach
172 	 */
173 	disc = SLIPDISC;
174 	if (ioctl(fd, TIOCSETD, &disc) < 0) {
175 	        perror("ioctl(TIOCSETD)");
176 		syslog(LOG_ERR, "startslip: %s: ioctl (TIOCSETD SLIP): %m\n",
177 		    argv[0]);
178 	        exit(1);
179 	}
180 	printd("setd\n");
181 	disc = SC_COMPRESS;
182 	if (ioctl(fd, SLIOCSFLAGS, (caddr_t)&disc) < 0) {
183 	        perror("ioctl(SLIOCFLAGS)");
184 		syslog(LOG_ERR, "ioctl (SLIOCSFLAGS): %m");
185 		exit(1);
186 	}
187 	if (!first++ && debug == 0) {
188 		close(0);
189 		close(1);
190 		close(2);
191 		(void) open("/dev/null", O_RDWR);
192 		(void) dup2(0, 1);
193 		(void) dup2(0, 2);
194 	}
195 	(void) system("ifconfig sl0 up");
196 	while (hup == 0) {
197 		sigpause(0L);
198 		printd("sigpause return ");
199 	}
200 cleanup:
201 	printd("close\n");
202 	fclose(wfd);
203 	close(fd);
204 #ifdef TIOCSCTTY
205 	if (fork() > 0)
206 		exit(0);
207 	printd("(pid %d)\n", getpid());
208 	if (setsid() == -1)
209 		perror("setsid");
210 	sleep(5);
211 #endif
212 	goto restart;
213 }
214 
215 sighup()
216 {
217 
218 	printd("hup\n");
219 	if (hup == 0)
220 		syslog(LOG_INFO, "startslip: hangup signal\n");
221 	hup = 1;
222 }
223 
224 getline(buf, size, fd)
225 	char *buf;
226 	int size, fd;
227 {
228 	register int i;
229 	int ret;
230 
231 	size--;
232 	for (i = 0; i < size; i++) {
233 		if (hup)
234 			return (0);
235 	        if ((ret = read(fd, &buf[i], 1)) == 1) {
236 	                buf[i] &= 0177;
237 	                if (buf[i] == '\r')
238 	                        buf[i] = '\n';
239 	                if (buf[i] != '\n' && buf[i] != ':')
240 	                        continue;
241 	                buf[i + 1] = '\0';
242 			if (debug)
243 				fprintf(stderr, "Got %d: \"%s\"\n", i + 1, buf);
244 	                return (i+1);
245 	        }
246 		if (ret < 0) {
247 			perror("getline: read (sleeping)");
248 			buf[i] = '\0';
249 			sleep(60);
250 			printd("returning 0 after %d: \"%s\"\n", i, buf);
251 			return (0);
252 		}
253 	}
254 	return (0);
255 }
256 
257 usage()
258 {
259 	fprintf(stderr, "usage: startslip [-d] [-s string] dev user passwd\n");
260 	exit(1);
261 }
262