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