date and time created 92/07/05 14:15:17 by bostic
[unix-history] / usr / src / sbin / startslip / startslip.c
CommitLineData
b652be8f 1
61ba62c5
KM
2/*-
3 * Copyright (c) 1990 The Regents of the University of California.
4 * All rights reserved.
5 *
6 * %sccs.include.redist.c%
7 */
8
9#ifndef lint
10char copyright[] =
b652be8f 11"@(#) Copyright (c) 1990, 1991 The Regents of the University of California.\n\
61ba62c5
KM
12 All rights reserved.\n";
13#endif /* not lint */
14
15#ifndef lint
1fedb40b 16static char sccsid[] = "@(#)startslip.c 5.6 (Berkeley) %G%";
61ba62c5
KM
17#endif /* not lint */
18
19#include <sys/param.h>
b652be8f
MK
20#if BSD >= 199006
21#define POSIX
22#endif
23#ifdef POSIX
24#include <sys/termios.h>
25#include <sys/ioctl.h>
26#else
9bdb4436 27#include <sgtty.h>
b652be8f 28#endif
61ba62c5
KM
29#include <sys/socket.h>
30#include <sys/syslog.h>
31#include <netinet/in.h>
32#include <net/if.h>
33#include <net/if_slvar.h>
61ba62c5
KM
34#include <netdb.h>
35#include <errno.h>
36#include <fcntl.h>
37#include <stdio.h>
9bdb4436 38#include <signal.h>
61ba62c5
KM
39
40#define DEFAULT_BAUD B9600
41int speed = DEFAULT_BAUD;
9bdb4436 42int hup;
4f73d838
KM
43int logged_in;
44int wait_time = 60; /* then back off */
45#define MAXTRIES 6 /* w/60 sec and doubling, takes an hour */
46#define PIDFILE "/var/run/startslip.pid"
47
61ba62c5
KM
48#ifdef DEBUG
49int debug = 1;
50#undef LOG_ERR
51#undef LOG_INFO
52#define syslog fprintf
53#define LOG_ERR stderr
54#define LOG_INFO stderr
55#else
56int debug = 0;
57#endif
58#define printd if (debug) printf
59
60main(argc, argv)
61 int argc;
62 char **argv;
63{
64 extern char *optarg;
65 extern int optind;
9bdb4436 66 int ch, disc;
4f73d838
KM
67 int fd = -1;
68 void sighup();
69 FILE *wfd = NULL, *pfd;
61ba62c5 70 char *dialerstring = 0, buf[BUFSIZ];
4f73d838
KM
71 int first = 1, tries = 0;
72 int pausefirst = 0;
73 int pid;
b652be8f
MK
74#ifdef POSIX
75 struct termios t;
76#else
61ba62c5 77 struct sgttyb sgtty;
b652be8f 78#endif
61ba62c5 79
4f73d838 80 while ((ch = getopt(argc, argv, "db:s:p:")) != EOF)
b652be8f 81 switch (ch) {
61ba62c5
KM
82 case 'd':
83 debug = 1;
84 break;
b652be8f
MK
85#ifdef POSIX
86 case 'b':
87 speed = atoi(optarg);
88 break;
89#endif
4f73d838
KM
90 case 'p':
91 pausefirst = atoi(optarg);
92 break;
61ba62c5
KM
93 case 's':
94 dialerstring = optarg;
95 break;
96 case '?':
97 default:
98 usage();
99 }
100 argc -= optind;
101 argv += optind;
102
103 if (argc != 3)
104 usage();
105
106 openlog("startslip", LOG_PID, LOG_DAEMON);
107
108#if BSD <= 43
9bdb4436 109 if (debug == 0 && (fd = open("/dev/tty", 0)) >= 0) {
61ba62c5
KM
110 ioctl(fd, TIOCNOTTY, 0);
111 close(fd);
b652be8f 112 fd = -1;
61ba62c5
KM
113 }
114#endif
115
b652be8f
MK
116 if (debug)
117 setbuf(stdout, NULL);
4f73d838
KM
118
119 if (pfd = fopen(PIDFILE, "r")) {
120 pid = 0;
121 fscanf(pfd, "%d", &pid);
122 if (pid > 0)
123 kill(pid, SIGUSR1);
124 fclose(pfd);
125 }
61ba62c5 126restart:
4f73d838
KM
127 logged_in = 0;
128 if (++tries > MAXTRIES) {
129 syslog(LOG_ERR, "exiting after %d tries\n", tries);
130 /* ???
131 if (first)
132 */
133 exit(1);
134 }
135
b652be8f
MK
136 /*
137 * We may get a HUP below, when the parent (session leader/
138 * controlling process) exits; ignore HUP until into new session.
139 */
140 signal(SIGHUP, SIG_IGN);
9bdb4436 141 hup = 0;
4f73d838
KM
142 if (fork() > 0) {
143 if (pausefirst)
144 sleep(pausefirst);
145 if (first)
146 printd("parent exit\n");
b652be8f 147 exit(0);
4f73d838
KM
148 }
149 pausefirst = 0;
b652be8f
MK
150#ifdef POSIX
151 if (setsid() == -1)
152 perror("setsid");
dc20c96e 153#endif
4f73d838
KM
154 pid = getpid();
155 printd("restart: pid %d: ", pid);
156 if (pfd = fopen(PIDFILE, "w")) {
157 fprintf(pfd, "%d\n", pid);
158 fclose(pfd);
159 }
b652be8f 160 if (wfd) {
4f73d838 161 printd("fclose, ");
b652be8f
MK
162 fclose(wfd);
163 wfd == NULL;
164 }
165 if (fd >= 0) {
4f73d838 166 printd("close, ");
b652be8f
MK
167 close(fd);
168 sleep(5);
169 }
4f73d838 170 printd("open");
61ba62c5
KM
171 if ((fd = open(argv[0], O_RDWR)) < 0) {
172 perror(argv[0]);
4f73d838 173 syslog(LOG_ERR, "open %s: %m\n", argv[0]);
61ba62c5
KM
174 if (first)
175 exit(1);
176 else {
4f73d838 177 sleep(wait_time * tries);
61ba62c5
KM
178 goto restart;
179 }
180 }
b652be8f 181 printd(" %d", fd);
dc20c96e
KM
182#ifdef TIOCSCTTY
183 if (ioctl(fd, TIOCSCTTY, 0) < 0)
184 perror("ioctl (TIOCSCTTY)");
185#endif
b652be8f 186 signal(SIGHUP, sighup);
9bdb4436
KM
187 if (debug) {
188 if (ioctl(fd, TIOCGETD, &disc) < 0)
189 perror("ioctl(TIOCSETD)");
b652be8f 190 printf(" (disc was %d)", disc);
9bdb4436
KM
191 }
192 disc = TTYDISC;
193 if (ioctl(fd, TIOCSETD, &disc) < 0) {
194 perror("ioctl(TIOCSETD)");
4f73d838 195 syslog(LOG_ERR, "%s: ioctl (TIOCSETD 0): %m\n",
9bdb4436
KM
196 argv[0]);
197 }
b652be8f
MK
198 printd(", ioctl");
199#ifdef POSIX
200 if (tcgetattr(fd, &t) < 0) {
201 perror("tcgetattr");
4f73d838 202 syslog(LOG_ERR, "%s: tcgetattr: %m\n", argv[0]);
b652be8f
MK
203 exit(2);
204 }
205 cfmakeraw(&t);
4f73d838 206 t.c_iflag &= ~IMAXBEL;
b652be8f
MK
207 t.c_cflag |= CRTSCTS;
208 cfsetspeed(&t, speed);
4f73d838 209 if (tcsetattr(fd, TCSAFLUSH, &t) < 0) {
b652be8f 210 perror("tcsetattr");
4f73d838 211 syslog(LOG_ERR, "%s: tcsetattr: %m\n", argv[0]);
b652be8f
MK
212 if (first)
213 exit(2);
214 else {
4f73d838 215 sleep(wait_time * tries);
b652be8f
MK
216 goto restart;
217 }
61ba62c5 218 }
b652be8f 219#else
61ba62c5
KM
220 if (ioctl(fd, TIOCGETP, &sgtty) < 0) {
221 perror("ioctl (TIOCGETP)");
4f73d838 222 syslog(LOG_ERR, "%s: ioctl (TIOCGETP): %m\n",
b652be8f 223 argv[0]);
61ba62c5
KM
224 exit(2);
225 }
226 sgtty.sg_flags = RAW | ANYP;
227 sgtty.sg_erase = sgtty.sg_kill = 0377;
228 sgtty.sg_ispeed = sgtty.sg_ospeed = speed;
229 if (ioctl(fd, TIOCSETP, &sgtty) < 0) {
230 perror("ioctl (TIOCSETP)");
4f73d838 231 syslog(LOG_ERR, "%s: ioctl (TIOCSETP): %m\n",
61ba62c5 232 argv[0]);
b652be8f
MK
233 if (first)
234 exit(2);
235 else {
4f73d838 236 sleep(wait_time * tries);
b652be8f
MK
237 goto restart;
238 }
61ba62c5 239 }
b652be8f 240#endif
4f73d838
KM
241 sleep(2); /* wait for flakey line to settle */
242 if (hup)
243 goto restart;
244
245 wfd = fdopen(fd, "w+");
246 if (wfd == NULL) {
247 syslog(LOG_ERR, "can't fdopen slip line\n");
248 exit(10);
249 }
250 setbuf(wfd, (char *)0);
b652be8f
MK
251 if (dialerstring) {
252 printd(", send dialstring");
4f73d838
KM
253 fprintf(wfd, "%s\r", dialerstring);
254 } else
255 putc('\r', wfd);
b652be8f
MK
256 printd("\n");
257
61ba62c5
KM
258 /*
259 * Log in
260 */
b652be8f 261 printd("look for login: ");
4f73d838
KM
262 for (;;) {
263 if (getline(buf, BUFSIZ, fd) == 0 || hup) {
264 sleep(wait_time * tries);
b652be8f 265 goto restart;
4f73d838 266 }
61ba62c5
KM
267 if (bcmp(&buf[1], "ogin:", 5) == 0) {
268 fprintf(wfd, "%s\r", argv[1]);
1fedb40b 269 printd("Sent login: %s\n", argv[1]);
61ba62c5
KM
270 continue;
271 }
272 if (bcmp(&buf[1], "assword:", 8) == 0) {
273 fprintf(wfd, "%s\r", argv[2]);
1fedb40b 274 printd("Sent password: %s\n", argv[2]);
61ba62c5
KM
275 break;
276 }
277 }
4f73d838 278
61ba62c5
KM
279 /*
280 * Attach
281 */
4f73d838 282 printd("setd");
9bdb4436
KM
283 disc = SLIPDISC;
284 if (ioctl(fd, TIOCSETD, &disc) < 0) {
61ba62c5 285 perror("ioctl(TIOCSETD)");
4f73d838 286 syslog(LOG_ERR, "%s: ioctl (TIOCSETD SLIP): %m\n",
61ba62c5
KM
287 argv[0]);
288 exit(1);
289 }
b652be8f 290 if (first && debug == 0) {
dc20c96e
KM
291 close(0);
292 close(1);
293 close(2);
294 (void) open("/dev/null", O_RDWR);
295 (void) dup2(0, 1);
296 (void) dup2(0, 2);
61ba62c5
KM
297 }
298 (void) system("ifconfig sl0 up");
b652be8f 299 printd(", ready\n");
4f73d838
KM
300 if (!first)
301 syslog(LOG_INFO, "reconnected (%d tries).\n", tries);
b652be8f 302 first = 0;
4f73d838
KM
303 tries = 0;
304 logged_in = 1;
dc20c96e 305 while (hup == 0) {
9bdb4436 306 sigpause(0L);
b652be8f 307 printd("sigpause return\n");
dc20c96e 308 }
61ba62c5
KM
309 goto restart;
310}
311
4f73d838 312void
61ba62c5
KM
313sighup()
314{
315
9bdb4436 316 printd("hup\n");
4f73d838
KM
317 if (hup == 0 && logged_in)
318 syslog(LOG_INFO, "hangup signal\n");
9bdb4436 319 hup = 1;
61ba62c5
KM
320}
321
322getline(buf, size, fd)
323 char *buf;
324 int size, fd;
325{
326 register int i;
dc20c96e 327 int ret;
61ba62c5
KM
328
329 size--;
330 for (i = 0; i < size; i++) {
9bdb4436
KM
331 if (hup)
332 return (0);
dc20c96e 333 if ((ret = read(fd, &buf[i], 1)) == 1) {
61ba62c5 334 buf[i] &= 0177;
1fedb40b 335 if (buf[i] == '\r' || buf[i] == '\0')
61ba62c5
KM
336 buf[i] = '\n';
337 if (buf[i] != '\n' && buf[i] != ':')
338 continue;
339 buf[i + 1] = '\0';
1fedb40b 340 printd("Got %d: \"%s\"\n", i + 1, buf);
61ba62c5
KM
341 return (i+1);
342 }
4f73d838
KM
343 if (ret <= 0) {
344 if (ret < 0)
345 perror("getline: read");
346 else
347 fprintf(stderr, "read returned 0\n");
dc20c96e 348 buf[i] = '\0';
dc20c96e
KM
349 printd("returning 0 after %d: \"%s\"\n", i, buf);
350 return (0);
351 }
61ba62c5 352 }
9bdb4436 353 return (0);
61ba62c5
KM
354}
355
356usage()
357{
4f73d838 358 fprintf(stderr, "usage: startslip [-d] [-s string] dev user passwd\n");
61ba62c5
KM
359 exit(1);
360}