diff options
author | ache <ache@FreeBSD.org> | 1995-09-14 19:03:20 +0000 |
---|---|---|
committer | ache <ache@FreeBSD.org> | 1995-09-14 19:03:20 +0000 |
commit | 163e4e12ae67e49b387039c555c01e79799b1eec (patch) | |
tree | bb54d3b5e7d5f5098319c651143d173afdaeb34c /sbin/startslip | |
parent | 599a0e919ce0e33a30d3c761b5fd0186530cd7a9 (diff) | |
download | FreeBSD-src-163e4e12ae67e49b387039c555c01e79799b1eec.zip FreeBSD-src-163e4e12ae67e49b387039c555c01e79799b1eec.tar.gz |
Now understand "host!login:" style prompts additionly.
Add -t to specify login script timeout.
Add -w to specify retry wait time.
Describe -p option.
Now understand several -s sections (for several host phone numbers).
Remove -F sw (software flow control), it is impossible with slip.
Change -F hw (hardware flow control) option to -h as in slattach,
we don't need option with argument for only one case.
Call downscript on SIGTERM.
Improve debug diagnostic.
Allow startslip work with several slip lines without killing each other.
Unlink pid file on exit.
Skip \r and \0 in login script parsing instead making them \n.
Use absolute path to default script (/sbin/ifconfig).
Call up/down script in background to prevent hang on them.
Diffstat (limited to 'sbin/startslip')
-rw-r--r-- | sbin/startslip/startslip.1 | 65 | ||||
-rw-r--r-- | sbin/startslip/startslip.c | 188 |
2 files changed, 167 insertions, 86 deletions
diff --git a/sbin/startslip/startslip.1 b/sbin/startslip/startslip.1 index 8a9dd3d..1996ab2 100644 --- a/sbin/startslip/startslip.1 +++ b/sbin/startslip/startslip.1 @@ -41,11 +41,17 @@ .Nm startslip .Op Fl d .Op Fl b Ar speed -.Op Fl s Ar string +[ +.Fl s Ar string1 +.Op Fl s Ar string2 Op Ar ... +] +.Op Fl h .Op Fl A Ar annexname -.Op Fl F Ar flowcontrol .Op Fl U Ar upscript .Op Fl D Ar downscript +.Op Fl p Ar father_pause +.Op Fl t Ar script_timeout +.Op Fl w Ar retry_pause .Ar device user passwd .Sh DESCRIPTION .Nm Startslip @@ -59,11 +65,25 @@ attempts to login as the specified with the given .Ar password . If successful, it puts the device into the slip line discipline. -If carrier drops and a +If carrier drops or a .Dv SIGHUP is sent to .Nm startslip , -it closes the device and attempts to repeat the dialup and login sequence. +it closes the device, calls +.Ar downscript +and attempts to repeat the dialup and login sequence. +If a +.Dv SIGTERM +is send to +.Nm startslip , +it closes the device, calls +.Ar downscript +and exits. +When +.Nm startslip +called twice on the same device, previous copy killed by a +.Dv SIGTERM +before any operation. .Pp Available options: .Bl -tag -width Ar @@ -73,13 +93,26 @@ prints out debugging information about what it is trying to do. .It Fl b Ar speed Determines the baud rate used for .Ar device . -.It Fl s Ar string +Default value is 9600. +.It Fl t Ar script_timeout +Set login script timeout in seconds, default value is 90. +.It Fl w Ar retry_pause +Set retry pause in seconds (increased from one try to another), +default value is 60. +.It Fl p Ar father_pause +Set after fork father pause in seconds, default is no pause there. +.It Fl s Ar string1 The optional .Ar string is written to .Ar device . +Return character is added automatically. For a dialup modem, the string is used to specify a dial sequence. +Default string is return character. +You can specify several +.Fl s Ar stringN +arguments to use with each try, f.e. several host phone numbers. .It Fl A Ar annexname .Nm Startslip assumes it is connecting to a Xylogics Annex box and engages in an @@ -92,25 +125,25 @@ The .Ar annexname argument is a string that is used to match against the Annex prompt to determine when a connection has been established. -.It Fl F Ar flowcontrol -Determines the type of flow control used on +.It Fl h +Use hardware (CTS/RTS) flow control for .Ar device . -Choices for -.Ar flowcontrol -are -``none'' for no flow control (the default), -``hw'' for hardware RTS/CTS flow control and -``sw'' for software XON/XOFF flow control. +Default value is no flow control. .It Fl U Ar upscript Specifies a script to run when a SLIP interface becomes connected. This may contain ifconfig, route, and other appropriate commands. The arguments that -are passed to the script are "slX up". +are passed to the script are "slX up". Default value is "/sbin/ifconfig". .It Fl D Ar downscript Specifies a script to run when a SLIP connection goes away. The arguments that -are passed to the script are "slX down". +are passed to the script are "slX down". Default value is "/sbin/ifconfig". .El +.Sh FILES +.Bl -tag -width /var/run/startslip-<device>.pid -compact +.It Pa /var/run/startslip-<device>.pid +pid stored here .Sh SEE ALSO -.Xr sliplogin 8 +.Xr sliplogin 8 , +.Xr slattach 8 .Sh HISTORY The .Nm startslip diff --git a/sbin/startslip/startslip.c b/sbin/startslip/startslip.c index 0b81897..acd1b16 100644 --- a/sbin/startslip/startslip.c +++ b/sbin/startslip/startslip.c @@ -55,7 +55,7 @@ static char sccsid[] = "@(#)startslip.c 8.1 (Berkeley) 6/5/93"; #include <sys/types.h> #include <sys/time.h> #include <sys/socket.h> -#include <sys/syslog.h> +#include <syslog.h> #include <netinet/in.h> #include <net/if.h> #include <net/if_slvar.h> @@ -71,15 +71,20 @@ static char sccsid[] = "@(#)startslip.c 8.1 (Berkeley) 6/5/93"; #define DEFAULT_BAUD B9600 int speed = DEFAULT_BAUD; #define FC_NONE 0 /* flow control: none */ -#define FC_SW 1 /* flow control: software (XON/XOFF) */ -#define FC_HW 2 /* flow control: hardware (RTS/CTS) */ +#define FC_HW 1 /* flow control: hardware (RTS/CTS) */ int flowcontrol = FC_NONE; char *annex; int hup; +int terminate; int logged_in = 0; int wait_time = 60; /* then back off */ +int script_timeout = 90; /* connect script default timeout */ #define MAXTRIES 6 /* w/60 sec and doubling, takes an hour */ -#define PIDFILE "/var/run/startslip.pid" +#define PIDFILE "/var/run/startslip-%s.pid" + +#define MAXDIALS 20 +char *dials[MAXDIALS]; +int diali, dialc; #ifdef DEBUG int debug = 1; @@ -102,23 +107,24 @@ main(argc, argv) char *cp, **ap; int ch, disc; int fd = -1; - void sighup(); + void sighup(), sigterm(); FILE *wfd = NULL, *pfd; char *dialerstring = 0, buf[BUFSIZ]; + char pidfile[32]; int unitnum; char unitname[32]; char *devicename, *username, *password; char *upscript = NULL, *downscript = NULL; int first = 1, tries = 0; int pausefirst = 0; - int pid; + pid_t pid; #ifdef POSIX struct termios t; #else struct sgttyb sgtty; #endif - while ((ch = getopt(argc, argv, "db:s:p:A:F:U:D:")) != EOF) + while ((ch = getopt(argc, argv, "dhb:s:t:p:w:A:U:D:")) != EOF) switch (ch) { case 'd': debug = 1; @@ -132,7 +138,18 @@ main(argc, argv) pausefirst = atoi(optarg); break; case 's': - dialerstring = strdup(optarg); + if (diali >= MAXDIALS) { + (void)fprintf(stderr, + "max dial strings number (%d) exceeded\n", MAXDIALS); + exit(1); + } + dials[diali++] = strdup(optarg); + break; + case 't': + script_timeout = atoi(optarg); + break; + case 'w': + wait_time = atoi(optarg); break; case 'A': annex = strdup(optarg); @@ -143,19 +160,9 @@ main(argc, argv) case 'D': downscript = strdup(optarg); break; - case 'F': + case 'h': #ifdef POSIX - if (strcmp(optarg, "none") == 0) - flowcontrol = FC_NONE; - else if (strcmp(optarg, "sw") == 0) - flowcontrol = FC_SW; - else if (strcmp(optarg, "hw") == 0) - flowcontrol = FC_HW; - else { - (void)fprintf(stderr, - "flow control: none, sw, hw\n"); - exit(1); - } + flowcontrol = FC_HW; break; #else (void)fprintf(stderr, "flow control not supported\n"); @@ -187,7 +194,7 @@ main(argc, argv) for (cp = *ap; *cp != 0; cp++) *cp = '\0'; - openlog("startslip", LOG_PID, LOG_DAEMON); + openlog("startslip", LOG_PID|LOG_PERROR, LOG_DAEMON); #if BSD <= 43 if (debug == 0 && (fd = open("/dev/tty", 0)) >= 0) { @@ -200,26 +207,44 @@ main(argc, argv) if (debug) setbuf(stdout, NULL); - if (pfd = fopen(PIDFILE, "r")) { + if ((cp = strrchr(devicename, '/')) == NULL) + cp = devicename; + else + cp++; + sprintf(pidfile, PIDFILE, cp); + if ((pfd = fopen(pidfile, "r")) != NULL) { pid = 0; - fscanf(pfd, "%d", &pid); + fscanf(pfd, "%d\n", &pid); if (pid > 0) - kill(pid, SIGUSR1); + kill(pid, SIGTERM); fclose(pfd); - } + pfd = NULL; /* not remove pidfile yet */ + sleep(5); /* allow down script to be completed */ + } else restart: if (logged_in) { - sprintf(buf, "%s %s down", downscript ? downscript : "ifconfig" , unitname); + sprintf(buf, "%s %s down &", downscript ? downscript : "/sbin/ifconfig" , unitname); (void) system(buf); } + if (terminate) { + if (pfd) + unlink(pidfile); + exit(0); + } logged_in = 0; if (++tries > MAXTRIES) { - syslog(LOG_ERR, "exiting after %d tries\n", tries); + syslog(LOG_ERR, "exiting login after %d tries\n", tries); /* ??? if (first) */ + { + if (pfd) + unlink(pidfile); exit(1); + } } + if (diali > 0) + dialerstring = dials[dialc++ % diali]; /* * We may get a HUP below, when the parent (session leader/ @@ -237,11 +262,11 @@ restart: pausefirst = 0; #ifdef POSIX if (setsid() == -1) - perror("setsid"); + syslog(LOG_ERR, "setsid: %m"); #endif pid = getpid(); printd("restart: pid %d: ", pid); - if (pfd = fopen(PIDFILE, "w")) { + if (pfd = fopen(pidfile, "w")) { fprintf(pfd, "%d\n", pid); fclose(pfd); } @@ -257,11 +282,12 @@ restart: } printd("open"); if ((fd = open(devicename, O_RDWR)) < 0) { - perror(devicename); syslog(LOG_ERR, "open %s: %m\n", devicename); - if (first) + if (first) { + if (pfd) + unlink(pidfile); exit(1); - else { + } else { syslog(LOG_INFO, "sleeping %d seconds (%d tries).\n", wait_time * tries, tries); sleep(wait_time * tries); goto restart; @@ -270,25 +296,26 @@ restart: printd(" %d", fd); #ifdef TIOCSCTTY if (ioctl(fd, TIOCSCTTY, 0) < 0) - perror("ioctl (TIOCSCTTY)"); + syslog(LOG_ERR, "ioctl (TIOCSCTTY): %m"); #endif signal(SIGHUP, sighup); + signal(SIGTERM, sigterm); if (debug) { if (ioctl(fd, TIOCGETD, &disc) < 0) - perror("ioctl(TIOCSETD)"); - printf(" (disc was %d)", disc); + syslog(LOG_ERR, "ioctl(TIOCSETD): %m"); + printd(" (disc was %d)", disc); } disc = TTYDISC; if (ioctl(fd, TIOCSETD, &disc) < 0) { - perror("ioctl(TIOCSETD)"); syslog(LOG_ERR, "%s: ioctl (TIOCSETD 0): %m\n", devicename); } printd(", ioctl"); #ifdef POSIX if (tcgetattr(fd, &t) < 0) { - perror("tcgetattr"); syslog(LOG_ERR, "%s: tcgetattr: %m\n", devicename); + if (pfd) + unlink(pidfile); exit(2); } cfmakeraw(&t); @@ -296,21 +323,18 @@ restart: case FC_HW: t.c_cflag |= (CRTS_IFLOW|CCTS_OFLOW); break; - case FC_SW: - t.c_iflag |= (IXON|IXOFF); - break; case FC_NONE: t.c_cflag &= ~(CRTS_IFLOW|CCTS_OFLOW); - t.c_iflag &= ~(IXON|IXOFF); break; } cfsetspeed(&t, speed); if (tcsetattr(fd, TCSAFLUSH, &t) < 0) { - perror("tcsetattr"); syslog(LOG_ERR, "%s: tcsetattr: %m\n", devicename); - if (first) + if (first) { + if (pfd) + unlink(pidfile); exit(2); - else { + } else { syslog(LOG_INFO, "sleeping %d seconds (%d tries).\n", wait_time * tries, tries); sleep(wait_time * tries); goto restart; @@ -318,21 +342,23 @@ restart: } #else if (ioctl(fd, TIOCGETP, &sgtty) < 0) { - perror("ioctl (TIOCGETP)"); syslog(LOG_ERR, "%s: ioctl (TIOCGETP): %m\n", devicename); + if (pfd) + unlink(pidfile); exit(2); } sgtty.sg_flags = RAW | ANYP; sgtty.sg_erase = sgtty.sg_kill = 0377; sgtty.sg_ispeed = sgtty.sg_ospeed = speed; if (ioctl(fd, TIOCSETP, &sgtty) < 0) { - perror("ioctl (TIOCSETP)"); syslog(LOG_ERR, "%s: ioctl (TIOCSETP): %m\n", devicename); - if (first) + if (first) { + if (pfd) + unlink(pidfile); exit(2); - else { + } else { syslog(LOG_INFO, "sleeping %d seconds (%d tries).\n", wait_time * tries, tries); sleep(wait_time * tries); goto restart; @@ -340,20 +366,24 @@ restart: } #endif sleep(2); /* wait for flakey line to settle */ - if (hup) + if (hup || terminate) goto restart; wfd = fdopen(fd, "w+"); if (wfd == NULL) { syslog(LOG_ERR, "can't fdopen slip line\n"); + if (pfd) + unlink(pidfile); exit(10); } setbuf(wfd, (char *)0); if (dialerstring) { - printd(", send dialstring"); + printd(", send dialstring: %s\\r", dialerstring); fprintf(wfd, "%s\r", dialerstring); - } else + } else { + printd(", send \\r"); putc('\r', wfd); + } printd("\n"); /* @@ -361,9 +391,11 @@ restart: */ printd("look for login: "); for (;;) { - if (getline(buf, BUFSIZ, fd, 90) == 0 || hup) { - syslog(LOG_INFO, "sleeping %d seconds (%d tries).\n", wait_time * tries, tries); - sleep(wait_time * tries); + if (getline(buf, BUFSIZ, fd, script_timeout) == 0 || hup || terminate) { + if (!terminate) { + syslog(LOG_INFO, "sleeping %d seconds (%d tries).\n", wait_time * tries, tries); + sleep(wait_time * tries); + } goto restart; } if (annex) { @@ -383,12 +415,12 @@ restart: break; } } else { - if (bcmp(&buf[1], "ogin:", 5) == 0) { + if (strstr(&buf[1], "ogin:") != NULL) { fprintf(wfd, "%s\r", username); printd("Sent login: %s\n", username); continue; } - if (bcmp(&buf[1], "assword:", 8) == 0) { + if (strstr(&buf[1], "assword:") != NULL) { fprintf(wfd, "%s\r", password); printd("Sent password: %s\n", password); break; @@ -402,14 +434,16 @@ restart: printd("setd"); disc = SLIPDISC; if (ioctl(fd, TIOCSETD, &disc) < 0) { - perror("ioctl(TIOCSETD)"); syslog(LOG_ERR, "%s: ioctl (TIOCSETD SLIP): %m\n", devicename); + if (pfd) + unlink(pidfile); exit(1); } if (ioctl(fd, SLIOCGUNIT, (caddr_t)&unitnum) < 0) { - perror("ioctl(SLIOCGUNIT)"); syslog(LOG_ERR, "ioctl(SLIOCGUNIT): %m"); + if (pfd) + unlink(pidfile); exit(1); } sprintf(unitname, "sl%d", unitnum); @@ -422,7 +456,7 @@ restart: (void) dup2(0, 2); } - sprintf(buf, "%s %s up", upscript ? upscript : "ifconfig" , unitname); + sprintf(buf, "%s %s up &", upscript ? upscript : "/sbin/ifconfig" , unitname); (void) system(buf); printd(", ready\n"); @@ -431,7 +465,7 @@ restart: first = 0; tries = 0; logged_in = 1; - while (hup == 0) { + while (hup == 0 && terminate == 0) { sigpause(0L); printd("sigpause return\n"); } @@ -448,6 +482,16 @@ sighup() hup = 1; } +void +sigterm() +{ + + printd("terminate\n"); + if (terminate == 0 && logged_in) + syslog(LOG_INFO, "terminate signal\n"); + terminate = 1; +} + getline(buf, size, fd, timeout) char *buf; int size, fd, timeout; @@ -459,7 +503,7 @@ getline(buf, size, fd, timeout) size--; for (i = 0; i < size; i++) { - if (hup) + if (hup || terminate) return (0); FD_ZERO(&readfds); FD_SET(fd, &readfds); @@ -467,7 +511,7 @@ getline(buf, size, fd, timeout) tv.tv_usec = 0; if ((ret = select(fd + 1, &readfds, NULL, NULL, &tv)) < 0) { if (errno != EINTR) - perror("getline: select"); + syslog(LOG_ERR, "getline: select: %m"); } else { if (! ret) { printd("getline: timed out\n"); @@ -475,21 +519,23 @@ getline(buf, size, fd, timeout) } if ((ret = read(fd, &buf[i], 1)) == 1) { buf[i] &= 0177; - if (buf[i] == '\r' || buf[i] == '\0') - buf[i] = '\n'; + if (buf[i] == '\r' || buf[i] == '\0') { + i--; + continue; + } if (buf[i] != '\n' && buf[i] != ':') continue; buf[i + 1] = '\0'; - printd("Got %d: \"%s\"\n", i + 1, buf); + printd("Got %d: %s", i + 1, buf); return (i+1); } if (ret <= 0) { if (ret < 0) { - perror("getline: read"); + syslog(LOG_ERR, "getline: read: %m"); } else - fprintf(stderr, "read returned 0\n"); + syslog(LOG_ERR, "read returned 0"); buf[i] = '\0'; - printd("returning 0 after %d: \"%s\"\n", i, buf); + printd("returning %d after %d: %s\n", ret, i, buf); return (0); } } @@ -499,7 +545,9 @@ getline(buf, size, fd, timeout) usage() { - (void)fprintf(stderr, - "usage: startslip [-d] [-b speed] [-s string] [-A annexname] [-F flowcontrol] [-U upscript] [-D downscript] dev user passwd\n"); + (void)fprintf(stderr, "\ +usage: startslip [-d] [-b speed] [-s string1 [-s string2 [...]]] [-A annexname]\n\ + [-h] [-U upscript] [-D downscript] [-t script_timeout]\n\ + [-w retry_pause] [-p father_pause] device user passwd\n"); exit(1); } |