X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=pppd%2Fmain.c;h=a84fd4251f90ed71f231e58a697cbc334be3fd35;hb=a6b37e93378a72f1dd8f14ccf62a8dcbb8326c87;hp=a33a5e242188bfc6f0437ce0f448f58853e9750b;hpb=a4efaa63e68e25e712af030a138a272dfe0d2180;p=ppp.git diff --git a/pppd/main.c b/pppd/main.c index a33a5e2..a84fd42 100644 --- a/pppd/main.c +++ b/pppd/main.c @@ -17,9 +17,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#ifndef lint -static char rcsid[] = "$Id: main.c,v 1.80 1999/07/21 00:24:31 paulus Exp $"; -#endif +#define RCSID "$Id: main.c,v 1.85 1999/08/24 05:59:15 paulus Exp $" #include #include @@ -48,6 +46,9 @@ static char rcsid[] = "$Id: main.c,v 1.80 1999/07/21 00:24:31 paulus Exp $"; #include "fsm.h" #include "lcp.h" #include "ipcp.h" +#ifdef INET6 +#include "ipv6cp.h" +#endif #include "upap.h" #include "chap.h" #include "ccp.h" @@ -65,6 +66,8 @@ static char rcsid[] = "$Id: main.c,v 1.80 1999/07/21 00:24:31 paulus Exp $"; #include "atcp.h" #endif +static const char rcsid[] = RCSID; + /* interface vars */ char ifname[32]; /* Interface name */ int ifunit; /* Interface unit number */ @@ -72,6 +75,7 @@ int ifunit; /* Interface unit number */ char *progname; /* Name of this program */ char hostname[MAXNAMELEN]; /* Our hostname */ static char pidfilename[MAXPATHLEN]; /* name of pid file */ +static char linkpidfile[MAXPATHLEN]; /* name of linkname pid file */ static char ppp_devnam[MAXPATHLEN]; /* name of PPP tty (maybe ttypx) */ static uid_t uid; /* Our real user-id */ static int conn_running; /* we have a [dis]connector running */ @@ -87,6 +91,7 @@ struct stat devstat; /* result of stat() on devnam */ 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 */ static int fd_ppp = -1; /* fd for talking PPP */ static int fd_loop; /* fd for getting demand-dial packets */ @@ -143,6 +148,7 @@ static struct subprocess *children; /* Prototypes for procedures local to this file. */ static void create_pidfile __P((void)); +static void create_linkpidfile __P((void)); static void cleanup __P((void)); static void close_tty __P((void)); static void get_input __P((void)); @@ -157,7 +163,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 *)); @@ -191,6 +197,9 @@ struct protent *protocols[] = { &cbcp_protent, #endif &ipcp_protent, +#ifdef INET6 + &ipv6cp_protent, +#endif &ccp_protent, #ifdef IPX_CHANGE &ipxcp_protent, @@ -248,6 +257,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, @@ -370,10 +385,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)); @@ -471,6 +485,8 @@ main(argc, argv) waiting = 0; + create_linkpidfile(); + /* * If we're doing dial-on-demand, set up the interface now. */ @@ -498,6 +514,7 @@ main(argc, argv) ttyfd = -1; real_ttyfd = -1; status = EXIT_OK; + ++unsuccess; if (demand) { /* @@ -808,6 +825,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 @@ -852,11 +881,11 @@ main(argc, argv) if (!demand) { if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT) - warn("unable to delete pid file: %m"); + warn("unable to delete pid file %s: %m", pidfilename); pidfilename[0] = 0; } - if (!persist) + if (!persist || (maxfail > 0 && unsuccess >= maxfail)) break; kill_link = 0; @@ -899,7 +928,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); @@ -933,9 +963,11 @@ detach() close(2); detached = 1; log_to_fd = -1; - /* update pid file if it has been written already */ + /* update pid files if they have been written already */ if (pidfilename[0]) create_pidfile(); + if (linkpidfile[0]) + create_linkpidfile(); } /* @@ -972,6 +1004,29 @@ create_pidfile() } slprintf(numbuf, sizeof(numbuf), "%d", getpid()); script_setenv("PPPD_PID", numbuf); + if (linkpidfile[0]) + create_linkpidfile(); +} + +static void +create_linkpidfile() +{ + FILE *pidfile; + + if (linkname[0] == 0) + return; + slprintf(linkpidfile, sizeof(linkpidfile), "%sppp-%s.pid", + _PATH_VARRUN, linkname); + if ((pidfile = fopen(linkpidfile, "w")) != NULL) { + fprintf(pidfile, "%d\n", getpid()); + if (pidfilename[0]) + fprintf(pidfile, "%s\n", ifname); + (void) fclose(pidfile); + } else { + error("Failed to create pid file %s: %m", linkpidfile); + linkpidfile[0] = 0; + } + script_setenv("LINKNAME", linkname); } /* @@ -1090,8 +1145,11 @@ cleanup() close_tty(); if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT) - warn("unable to delete pid file: %m"); + warn("unable to delete pid file %s: %m", pidfilename); pidfilename[0] = 0; + if (linkpidfile[0] != 0 && unlink(linkpidfile) < 0 && errno != ENOENT) + warn("unable to delete pid file %s: %m", linkpidfile); + linkpidfile[0] = 0; if (locked) unlock(); @@ -1631,7 +1689,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; { @@ -1640,7 +1698,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; @@ -1661,8 +1719,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; }