*/
#ifndef lint
-static char rcsid[] = "$Id: main.c,v 1.65 1999/03/23 01:23:46 paulus Exp $";
+static char rcsid[] = "$Id: main.c,v 1.73 1999/04/01 07:19:59 paulus Exp $";
#endif
#include <stdio.h>
u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */
static int n_children; /* # child processes still running */
+static int got_sigchld; /* set if we have received a SIGCHLD */
static int locked; /* lock() has succeeded */
static int start_charshunt __P((int, int));
static void charshunt_done __P((void *));
static void charshunt __P((int, int, char *));
-static int record_write(FILE *, int code, u_char *buf, int nb,
- struct timeval *);
+static int record_write __P((FILE *, int code, u_char *buf, int nb,
+ struct timeval *));
extern char *ttyname __P((int));
extern char *getlogin __P((void));
script_env = NULL;
/* Initialize syslog facilities */
-#ifdef ULTRIX
- openlog("pppd", LOG_PID);
-#else
- openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
- setlogmask(LOG_UPTO(LOG_INFO));
-#endif
+ reopen_log();
if (gethostname(hostname, MAXNAMELEN) < 0 ) {
option_error("Couldn't get hostname: %m");
if (!options_from_file(_PATH_SYSOPTIONS, !privileged, 0, 1)
|| !options_from_user())
exit(1);
+ using_pty = notty || ptycommand != NULL;
scan_args(argc-1, argv+1); /* look for tty name on command line */
+
+ /*
+ * Work out the device name, if it hasn't already been specified.
+ */
+ if (!using_pty) {
+ p = isatty(0)? ttyname(0): NULL;
+ if (p != NULL) {
+ if (default_device)
+ strlcpy(devnam, p, sizeof(devnam));
+ else if (strcmp(devnam, p) == 0)
+ default_device = 1;
+ }
+ }
+
+ /*
+ * Parse the tty options file and the command line.
+ */
if (!options_for_tty()
|| !parse_args(argc-1, argv+1))
exit(1);
exit(1);
}
- if (ptycommand != NULL || notty) {
+ if (using_pty) {
if (!default_device) {
option_error("%s option precludes specifying device name",
notty? "notty": "pty");
lockflag = 0;
modem = 0;
} else {
- /*
- * If the user has specified the default device name explicitly,
- * pretend they hadn't.
- */
- p = isatty(0)? ttyname(0): NULL;
- if (p == NULL) {
- if (default_device) {
- option_error("no device specified and stdin is not a tty");
- exit(1);
- }
- } else {
- if (default_device)
- strlcpy(devnam, p, sizeof(devnam));
- else if (strcmp(devnam, p) == 0)
- default_device = 1;
+ if (devnam[0] == 0) {
+ option_error("no device specified and stdin is not a tty");
+ exit(1);
}
}
if (default_device)
log_to_fd = 1; /* default to stdout */
script_setenv("DEVICE", devnam);
- slprintf(numbuf, sizeof(numbuf), "%d", baud_rate);
- script_setenv("SPEED", numbuf);
/*
* Initialize system-dependent stuff and magic number package.
}
if (get_loop_output())
break;
- reap_kids(0);
+ if (got_sigchld)
+ reap_kids(0);
}
remove_fd(fd_loop);
if (kill_link && !persist)
for (;;) {
/* If the user specified the device name, become the
user before opening it. */
- if (!devnam_info.priv)
+ if (!devnam_info.priv && !default_device)
seteuid(uid);
ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0);
- if (!devnam_info.priv)
+ if (!devnam_info.priv && !default_device)
seteuid(0);
if (ttyfd >= 0)
break;
error("Connect script failed");
goto fail;
}
+ if (kill_link)
+ goto disconnect;
info("Serial connection established.");
close(i);
}
+ slprintf(numbuf, sizeof(numbuf), "%d", baud_rate);
+ script_setenv("SPEED", numbuf);
+
/* run welcome script, if any */
if (welcomer && welcomer[0]) {
if (device_script(welcomer, ttyfd, ttyfd, 0) < 0)
/* set up the serial device as a ppp interface */
fd_ppp = establish_ppp(ttyfd);
if (fd_ppp < 0)
- goto fail;
+ goto disconnect;
if (!demand) {
}
open_ccp_flag = 0;
}
- reap_kids(0); /* Don't leave dead kids lying around */
+ if (got_sigchld)
+ reap_kids(0); /* Don't leave dead kids lying around */
}
/*
restore_loop();
disestablish_ppp(ttyfd);
fd_ppp = -1;
+ if (!hungup)
+ lcp_lowerdown(0);
/*
* Run disconnector script, if requested.
* XXX we may not be able to do this if the line has hung up!
*/
+ disconnect:
if (disconnector && !hungup) {
if (real_ttyfd >= 0)
set_up_tty(real_ttyfd, 1);
info("Serial link disconnected.");
}
}
- if (!hungup)
- lcp_lowerdown(0);
fail:
if (pty_master >= 0)
kill_link = 0;
phase = PHASE_DORMANT; /* allow signal to end holdoff */
}
- reap_kids(0);
+ if (got_sigchld)
+ reap_kids(0);
} while (phase == PHASE_HOLDOFF);
if (!persist)
break;
create_pidfile();
}
+/*
+ * reopen_log - (re)open our connection to syslog.
+ */
+void
+reopen_log()
+{
+#ifdef ULTRIX
+ openlog("pppd", LOG_PID);
+#else
+ openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
+ setlogmask(LOG_UPTO(LOG_INFO));
+#endif
+}
+
/*
* Create a file containing our process ID.
*/
/*
* chld - Catch SIGCHLD signal.
- * Calls reap_kids to get status for any dead kids.
+ * Sets a flag so we will call reap_kids in the mainline.
*/
static void
chld(sig)
int sig;
{
+ got_sigchld = 1;
if (waiting)
siglongjmp(sigjmp, 1);
}
int dont_wait;
{
int pid;
- int status = 0;
+ int status = -1;
int errfd;
++conn_running;
if (out == 0)
out = dup(out);
dup2(in, 0);
- if (in != out)
- close(in);
}
if (out != 1) {
dup2(out, 1);
- close(out);
}
if (real_ttyfd > 2)
close(real_ttyfd);
if (dont_wait) {
record_child(pid, program, NULL, NULL);
+ status = 0;
} else {
while (waitpid(pid, &status, 0) < 0) {
if (errno == EINTR)
if (must_exist || errno != ENOENT) {
/* have to reopen the log, there's nowhere else
for the message to go. */
-#ifdef ULTRIX
- openlog("pppd", LOG_PID);
-#else
- openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
- setlogmask(LOG_UPTO(LOG_INFO));
-#endif
+ reopen_log();
syslog(LOG_ERR, "Can't execute %s: %m", prog);
closelog();
}
int pid, status;
struct subprocess *chp, **prevp;
+ got_sigchld = 0;
if (n_children == 0)
return;
while ((pid = waitpid(-1, &status, (waitfor? 0: WNOHANG))) != -1
warn("Child process %s (pid %d) terminated with signal %d",
(chp? chp->prog: "??"), pid, WTERMSIG(status));
} else if (debug)
- dbglog("process %d (%s) finished, status = 0x%x",
- pid, (chp? chp->prog: "??"), status);
+ dbglog("Script %s finished (pid %d), status = 0x%x",
+ (chp? chp->prog: "??"), pid, status);
if (chp && chp->done)
(*chp->done)(chp->arg);
}
nibuf = nobuf = 0;
ibufp = obufp = NULL;
pty_readable = stdin_readable = 1;
- gettimeofday(&lasttime, NULL);
nfds = (ofd > pty_master? ofd: pty_master) + 1;
+ if (recordf != NULL) {
+ gettimeofday(&lasttime, NULL);
+ putc(7, recordf); /* put start marker */
+ putc(lasttime.tv_sec >> 24, recordf);
+ putc(lasttime.tv_sec >> 16, recordf);
+ putc(lasttime.tv_sec >> 8, recordf);
+ putc(lasttime.tv_sec, recordf);
+ lasttime.tv_usec = 0;
+ }
while (nibuf != 0 || nobuf != 0 || pty_readable || stdin_readable) {
FD_ZERO(&ready);
int diff;
gettimeofday(&now, NULL);
- diff = (now.tv_sec - tp->tv_sec) * 10
- + (now.tv_usec - tp->tv_usec) / 100000;
+ now.tv_usec /= 100000; /* actually 1/10 s, not usec now */
+ diff = (now.tv_sec - tp->tv_sec) * 10 + (now.tv_usec - tp->tv_usec);
if (diff > 0) {
if (diff > 255) {
putc(5, f);