* Copyright (c) 1990, 1991, 1993
* The Regents of the University of California. All rights reserved.
* %sccs.include.redist.c%
static char copyright
[] =
"@(#) Copyright (c) 1990, 1991, 1993\n\
The Regents of the University of California. All rights reserved.\n";
static char sccsid
[] = "@(#)startslip.c 8.1 (Berkeley) %G%";
#include <net/if_slvar.h>
#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) */
int flowcontrol
= FC_NONE
;
int wait_time
= 60; /* then back off */
#define MAXTRIES 6 /* w/60 sec and doubling, takes an hour */
#define PIDFILE "/var/run/startslip.pid"
#define printd if (debug) printf
char *dialerstring
= 0, buf
[BUFSIZ
];
int first
= 1, tries
= 0;
while ((ch
= getopt(argc
, argv
, "db:s:p:A:F:")) != EOF
)
pausefirst
= atoi(optarg
);
if (strcmp(optarg
, "none") == 0)
else if (strcmp(optarg
, "sw") == 0)
else if (strcmp(optarg
, "hw") == 0)
"flow control: none, sw, hw\n");
(void)fprintf(stderr
, "flow control not supported\n");
openlog("startslip", LOG_PID
, LOG_DAEMON
);
if (debug
== 0 && (fd
= open("/dev/tty", 0)) >= 0) {
if (pfd
= fopen(PIDFILE
, "r")) {
if (++tries
> MAXTRIES
) {
syslog(LOG_ERR
, "exiting after %d tries\n", tries
);
* We may get a HUP below, when the parent (session leader/
* controlling process) exits; ignore HUP until into new session.
printd("restart: pid %d: ", pid
);
if (pfd
= fopen(PIDFILE
, "w")) {
fprintf(pfd
, "%d\n", pid
);
if ((fd
= open(argv
[0], O_RDWR
)) < 0) {
syslog(LOG_ERR
, "open %s: %m\n", argv
[0]);
sleep(wait_time
* tries
);
if (ioctl(fd
, TIOCSCTTY
, 0) < 0)
perror("ioctl (TIOCSCTTY)");
if (ioctl(fd
, TIOCGETD
, &disc
) < 0)
perror("ioctl(TIOCSETD)");
printf(" (disc was %d)", disc
);
if (ioctl(fd
, TIOCSETD
, &disc
) < 0) {
perror("ioctl(TIOCSETD)");
syslog(LOG_ERR
, "%s: ioctl (TIOCSETD 0): %m\n",
if (tcgetattr(fd
, &t
) < 0) {
syslog(LOG_ERR
, "%s: tcgetattr: %m\n", argv
[0]);
t
.c_cflag
|= (CRTS_IFLOW
|CCTS_OFLOW
);
t
.c_iflag
|= (IXON
|IXOFF
);
t
.c_cflag
&= ~(CRTS_IFLOW
|CCTS_OFLOW
);
t
.c_iflag
&= ~(IXON
|IXOFF
);
if (tcsetattr(fd
, TCSAFLUSH
, &t
) < 0) {
syslog(LOG_ERR
, "%s: tcsetattr: %m\n", argv
[0]);
sleep(wait_time
* tries
);
if (ioctl(fd
, TIOCGETP
, &sgtty
) < 0) {
perror("ioctl (TIOCGETP)");
syslog(LOG_ERR
, "%s: ioctl (TIOCGETP): %m\n",
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",
sleep(wait_time
* tries
);
sleep(2); /* wait for flakey line to settle */
syslog(LOG_ERR
, "can't fdopen slip line\n");
printd(", send dialstring");
fprintf(wfd
, "%s\r", dialerstring
);
printd("look for login: ");
if (getline(buf
, BUFSIZ
, fd
) == 0 || hup
) {
sleep(wait_time
* tries
);
if (bcmp(buf
, annex
, strlen(annex
)) == 0) {
printd("Sent \"slip\"\n");
if (bcmp(&buf
[1], "sername:", 8) == 0) {
fprintf(wfd
, "%s\r", argv
[1]);
printd("Sent login: %s\n", argv
[1]);
if (bcmp(&buf
[1], "assword:", 8) == 0) {
fprintf(wfd
, "%s\r", argv
[2]);
printd("Sent password: %s\n", argv
[2]);
if (bcmp(&buf
[1], "ogin:", 5) == 0) {
fprintf(wfd
, "%s\r", argv
[1]);
printd("Sent login: %s\n", argv
[1]);
if (bcmp(&buf
[1], "assword:", 8) == 0) {
fprintf(wfd
, "%s\r", argv
[2]);
printd("Sent password: %s\n", argv
[2]);
* Security hack. Do not want private information such as the
* password and possible phone number to be left around.
* So we clobber the arguments.
for (ap
= argv
- optind
+ 1; ap
< argv
+ 3; ap
++)
for (cp
= *ap
; *cp
!= 0; cp
++)
if (ioctl(fd
, TIOCSETD
, &disc
) < 0) {
perror("ioctl(TIOCSETD)");
syslog(LOG_ERR
, "%s: ioctl (TIOCSETD SLIP): %m\n",
if (first
&& debug
== 0) {
(void) open("/dev/null", O_RDWR
);
(void) system("ifconfig sl0 up");
syslog(LOG_INFO
, "reconnected (%d tries).\n", tries
);
printd("sigpause return\n");
if (hup
== 0 && logged_in
)
syslog(LOG_INFO
, "hangup signal\n");
for (i
= 0; i
< size
; i
++) {
if ((ret
= read(fd
, &buf
[i
], 1)) == 1) {
if (buf
[i
] == '\r' || buf
[i
] == '\0')
if (buf
[i
] != '\n' && buf
[i
] != ':')
printd("Got %d: \"%s\"\n", i
+ 1, buf
);
fprintf(stderr
, "read returned 0\n");
printd("returning 0 after %d: \"%s\"\n", i
, buf
);
"usage: startslip [-d] [-b speed] [-s string] [-A annexname] [-F flowcontrol] dev user passwd\n");