X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=pppd%2Fmain.c;h=cad0fa3b44a0668ebaadcec1a7d640561eabcfd4;hb=5018cc2da57e555b620750f33dce6b1c964e612a;hp=c69d6c245ed578a848f5c30f96aa66ce6b6dbea6;hpb=408e8824289fa317933d199b0926aff7dc4adcb1;p=ppp.git diff --git a/pppd/main.c b/pppd/main.c index c69d6c2..cad0fa3 100644 --- a/pppd/main.c +++ b/pppd/main.c @@ -18,7 +18,7 @@ */ #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 @@ -110,6 +110,7 @@ u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ 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 */ @@ -152,8 +153,8 @@ static void record_child __P((int, char *, void (*) (void *), void *)); 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)); @@ -213,12 +214,7 @@ main(argc, argv) 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"); @@ -246,7 +242,25 @@ main(argc, argv) 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); @@ -279,7 +293,7 @@ main(argc, argv) exit(1); } - if (ptycommand != NULL || notty) { + if (using_pty) { if (!default_device) { option_error("%s option precludes specifying device name", notty? "notty": "pty"); @@ -293,21 +307,9 @@ main(argc, argv) 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) @@ -316,8 +318,6 @@ main(argc, argv) 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. @@ -476,7 +476,8 @@ main(argc, argv) } if (get_loop_output()) break; - reap_kids(0); + if (got_sigchld) + reap_kids(0); } remove_fd(fd_loop); if (kill_link && !persist) @@ -526,10 +527,10 @@ main(argc, argv) 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; @@ -614,6 +615,8 @@ main(argc, argv) error("Connect script failed"); goto fail; } + if (kill_link) + goto disconnect; info("Serial connection established."); @@ -636,6 +639,9 @@ main(argc, argv) 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) @@ -645,7 +651,7 @@ main(argc, argv) /* set up the serial device as a ppp interface */ fd_ppp = establish_ppp(ttyfd); if (fd_ppp < 0) - goto fail; + goto disconnect; if (!demand) { @@ -704,7 +710,8 @@ main(argc, argv) } 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 */ } /* @@ -731,11 +738,14 @@ main(argc, argv) 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); @@ -745,8 +755,6 @@ main(argc, argv) info("Serial link disconnected."); } } - if (!hungup) - lcp_lowerdown(0); fail: if (pty_master >= 0) @@ -793,7 +801,8 @@ main(argc, argv) 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; @@ -828,6 +837,20 @@ detach() 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. */ @@ -1191,12 +1214,13 @@ term(sig) /* * 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); } @@ -1269,7 +1293,7 @@ device_script(program, in, out, dont_wait) int dont_wait; { int pid; - int status = 0; + int status = -1; int errfd; ++conn_running; @@ -1308,12 +1332,9 @@ device_script(program, in, out, dont_wait) 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); @@ -1335,6 +1356,7 @@ device_script(program, in, out, dont_wait) if (dont_wait) { record_child(pid, program, NULL, NULL); + status = 0; } else { while (waitpid(pid, &status, 0) < 0) { if (errno == EINTR) @@ -1446,12 +1468,7 @@ run_program(prog, args, must_exist, done, arg) 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(); } @@ -1506,6 +1523,7 @@ reap_kids(waitfor) int pid, status; struct subprocess *chp, **prevp; + got_sigchld = 0; if (n_children == 0) return; while ((pid = waitpid(-1, &status, (waitfor? 0: WNOHANG))) != -1 @@ -1518,8 +1536,8 @@ reap_kids(waitfor) 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); } @@ -2373,8 +2391,16 @@ charshunt(ifd, ofd, record_file) 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); @@ -2490,8 +2516,8 @@ record_write(f, code, buf, nb, tp) 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);