X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=pppd%2Fmain.c;h=e5d2977fc2363d99bccf9b98d5cf01dc804d2d15;hb=44cd25b6c5a886f3cb615f2f0d8d78c6a52a2030;hp=4da0b9af4bc73b2eaf9dea34abcea2ec18368938;hpb=a3630de20e34796f434a728bfd9cf1a961380c82;p=ppp.git diff --git a/pppd/main.c b/pppd/main.c index 4da0b9a..e5d2977 100644 --- a/pppd/main.c +++ b/pppd/main.c @@ -17,7 +17,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define RCSID "$Id: main.c,v 1.83 1999/08/13 06:46:15 paulus Exp $" +#define RCSID "$Id: main.c,v 1.86 1999/09/11 12:08:57 paulus Exp $" #include #include @@ -46,6 +46,9 @@ #include "fsm.h" #include "lcp.h" #include "ipcp.h" +#ifdef INET6 +#include "ipv6cp.h" +#endif #include "upap.h" #include "chap.h" #include "ccp.h" @@ -89,6 +92,8 @@ int prepass = 0; /* doing prepass to find device name */ int devnam_fixed; /* set while in options.ttyxx file */ volatile int status; /* exit status for pppd */ int unsuccess; /* # unsuccessful connection attempts */ +int (*holdoff_hook) __P((void)) = NULL; +int (*new_phase_hook) __P((int)) = NULL; static int fd_ppp = -1; /* fd for talking PPP */ static int fd_loop; /* fd for getting demand-dial packets */ @@ -160,7 +165,7 @@ static void open_ccp __P((int)); static void bad_signal __P((int)); static void holdoff_end __P((void *)); static int device_script __P((char *, int, int, int)); -static void reap_kids __P((int waitfor)); +static int reap_kids __P((int waitfor)); static void record_child __P((int, char *, void (*) (void *), void *)); static int start_charshunt __P((int, int)); static void charshunt_done __P((void *)); @@ -194,6 +199,9 @@ struct protent *protocols[] = { &cbcp_protent, #endif &ipcp_protent, +#ifdef INET6 + &ipv6cp_protent, +#endif &ccp_protent, #ifdef IPX_CHANGE &ipxcp_protent, @@ -209,7 +217,7 @@ main(argc, argv) int argc; char *argv[]; { - int i, fdflags; + int i, fdflags, t; struct sigaction sa; char *p; struct passwd *pw; @@ -219,7 +227,7 @@ main(argc, argv) struct stat statbuf; char numbuf[16]; - phase = PHASE_INITIALIZE; + new_phase(PHASE_INITIALIZE); /* * Ensure that fds 0, 1, 2 are open, to /dev/null if nowhere else. @@ -251,6 +259,12 @@ main(argc, argv) ngroups = getgroups(NGROUPS_MAX, groups); + /* + * Initialize magic number generator now so that protocols may + * use magic numbers in initialization. + */ + magic_init(); + /* * Initialize to the standard option set, then parse, in order, * the system options file, the user's options file, @@ -328,6 +342,9 @@ main(argc, argv) option_error("connect script is required for demand-dialling\n"); exit(EXIT_OPTION_ERROR); } + /* default holdoff to 0 if no connect script has been given */ + if (connector == 0 && !holdoff_specified) + holdoff = 0; if (using_pty) { if (!default_device) { @@ -373,10 +390,9 @@ main(argc, argv) script_setenv("DEVICE", devnam); /* - * Initialize system-dependent stuff and magic number package. + * Initialize system-dependent stuff. */ sys_init(); - magic_init(); if (debug) setlogmask(LOG_UPTO(LOG_DEBUG)); @@ -510,7 +526,7 @@ main(argc, argv) * Don't do anything until we see some activity. */ kill_link = 0; - phase = PHASE_DORMANT; + new_phase(PHASE_DORMANT); demand_unblock(); add_fd(fd_loop); for (;;) { @@ -547,7 +563,7 @@ main(argc, argv) info("Starting link"); } - phase = PHASE_SERIALCONN; + new_phase(PHASE_SERIALCONN); /* * Get a pty master/slave pair if the pty, notty, or record @@ -775,7 +791,8 @@ main(argc, argv) open_ccp_flag = 0; add_fd(fd_ppp); status = EXIT_NEGOTIATION_FAILED; - for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) { + new_phase(PHASE_ESTABLISH); + while (phase != PHASE_DEAD) { if (sigsetjmp(sigjmp, 1) == 0) { sigprocmask(SIG_BLOCK, &mask, NULL); if (kill_link || open_ccp_flag || got_sigchld) { @@ -794,7 +811,7 @@ main(argc, argv) kill_link = 0; } if (open_ccp_flag) { - if (phase == PHASE_NETWORK) { + if (phase == PHASE_NETWORK || phase == PHASE_RUNNING) { ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */ (*ccp_protent.open)(0); } @@ -814,6 +831,18 @@ main(argc, argv) link_stats.bytes_out, link_stats.bytes_in); } + /* + * Delete pid file before disestablishing ppp. Otherwise it + * can happen that another pppd gets the same unit and then + * we delete its pid file. + */ + if (!demand) { + if (pidfilename[0] != 0 + && unlink(pidfilename) < 0 && errno != ENOENT) + warn("unable to delete pid file %s: %m", pidfilename); + pidfilename[0] = 0; + } + /* * If we may want to bring the link up again, transfer * the ppp unit back to the loopback. Set the @@ -834,6 +863,7 @@ main(argc, argv) */ disconnect: if (disconnector && !hungup) { + new_phase(PHASE_DISCONNECT); if (real_ttyfd >= 0) set_up_tty(real_ttyfd, 1); if (device_script(disconnector, ttyfd, ttyfd, 0) < 0) { @@ -868,9 +898,12 @@ main(argc, argv) kill_link = 0; if (demand) demand_discard(); - if (holdoff > 0 && need_holdoff) { - phase = PHASE_HOLDOFF; - TIMEOUT(holdoff_end, NULL, holdoff); + t = need_holdoff? holdoff: 0; + if (holdoff_hook) + t = (*holdoff_hook)(); + if (t > 0) { + new_phase(PHASE_HOLDOFF); + TIMEOUT(holdoff_end, NULL, t); do { if (sigsetjmp(sigjmp, 1) == 0) { sigprocmask(SIG_BLOCK, &mask, NULL); @@ -886,7 +919,7 @@ main(argc, argv) calltimeout(); if (kill_link) { kill_link = 0; - phase = PHASE_DORMANT; /* allow signal to end holdoff */ + new_phase(PHASE_DORMANT); /* allow signal to end holdoff */ } if (got_sigchld) reap_kids(0); @@ -905,7 +938,8 @@ main(argc, argv) for (chp = children; chp != NULL; chp = chp->next) dbglog(" script %s, pid %d", chp->prog, chp->pid); } - reap_kids(1); + if (reap_kids(1) < 0) + break; } die(status); @@ -1012,7 +1046,7 @@ static void holdoff_end(arg) void *arg; { - phase = PHASE_DORMANT; + new_phase(PHASE_DORMANT); } /* @@ -1093,6 +1127,17 @@ get_input() lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN); } +/* + * new_phase - signal the start of a new phase of pppd's operation. + */ +void +new_phase(p) + int p; +{ + phase = p; + if (new_phase_hook) + (*new_phase_hook)(p); +} /* * die - clean up state and exit with the specified status. @@ -1253,7 +1298,7 @@ untimeout(func, arg) for (copp = &callout; (freep = *copp); copp = &freep->c_next) if (freep->c_func == func && freep->c_arg == arg) { *copp = freep->c_next; - (void) free((char *) freep); + free((char *) freep); break; } } @@ -1665,7 +1710,7 @@ record_child(pid, prog, done, arg) * reap_kids - get status from any dead child processes, * and log a message for abnormal terminations. */ -static void +static int reap_kids(waitfor) int waitfor; { @@ -1674,7 +1719,7 @@ reap_kids(waitfor) got_sigchld = 0; if (n_children == 0) - return; + return 0; while ((pid = waitpid(-1, &status, (waitfor? 0: WNOHANG))) != -1 && pid != 0) { --n_children; @@ -1695,8 +1740,13 @@ reap_kids(waitfor) if (chp) free(chp); } - if (pid == -1 && errno != ECHILD && errno != EINTR) - error("Error waiting for child process: %m"); + if (pid == -1) { + if (errno == ECHILD) + return -1; + if (errno != EINTR) + error("Error waiting for child process: %m"); + } + return 0; } @@ -1737,6 +1787,7 @@ script_setenv(var, value) } } } else { + /* no space allocated for script env. ptrs. yet */ i = 0; script_env = (char **) malloc(16 * sizeof(char *)); if (script_env == 0)