X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=pppd%2Fmain.c;h=f4913ff28e7798c9b813640d092cfebde21f3a09;hb=79b0b24a753bc3f560ba85893cb51bbbecc429be;hp=38af544d7ae0d261826d6c92381cd53054112164;hpb=8d2b8187352766197e43a8be3f350acc91a65381;p=ppp.git diff --git a/pppd/main.c b/pppd/main.c index 38af544..f4913ff 100644 --- a/pppd/main.c +++ b/pppd/main.c @@ -18,7 +18,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: main.c,v 1.23 1995/05/19 03:26:25 paulus Exp $"; +static char rcsid[] = "$Id: main.c,v 1.27 1995/08/16 01:39:08 paulus Exp $"; #endif #include @@ -87,12 +87,15 @@ static int n_children; /* # child processes still running */ int baud_rate; +char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n"; + /* prototypes */ static void hup __P((int)); static void term __P((int)); static void chld __P((int)); static void toggle_debug __P((int)); static void open_ccp __P((int)); +static void bad_signal __P((int)); static void get_input __P((void)); void establish_ppp __P((void)); @@ -171,7 +174,7 @@ main(argc, argv) uid = getuid(); if (!ppp_available()) { - fprintf(stderr, "Sorry - PPP is not available on this system\n"); + fprintf(stderr, no_ppp_msg); exit(1); } @@ -252,8 +255,47 @@ main(argc, argv) SIGNAL(SIGTERM, term); /* Terminate */ SIGNAL(SIGCHLD, chld); - signal(SIGUSR1, toggle_debug); /* Toggle debug flag */ - signal(SIGUSR2, open_ccp); /* Reopen CCP */ + SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */ + SIGNAL(SIGUSR2, open_ccp); /* Reopen CCP */ + + /* + * Install a handler for other signals which would otherwise + * cause pppd to exit without cleaning up. + */ + SIGNAL(SIGABRT, bad_signal); + SIGNAL(SIGALRM, bad_signal); + SIGNAL(SIGFPE, bad_signal); + SIGNAL(SIGILL, bad_signal); + SIGNAL(SIGPIPE, bad_signal); + SIGNAL(SIGQUIT, bad_signal); + SIGNAL(SIGSEGV, bad_signal); +#ifdef SIGBUS + SIGNAL(SIGBUS, bad_signal); +#endif +#ifdef SIGEMT + SIGNAL(SIGEMT, bad_signal); +#endif +#ifdef SIGPOLL + SIGNAL(SIGPOLL, bad_signal); +#endif +#ifdef SIGPROF + SIGNAL(SIGPROF, bad_signal); +#endif +#ifdef SIGSYS + SIGNAL(SIGSYS, bad_signal); +#endif +#ifdef SIGTRAP + SIGNAL(SIGTRAP, bad_signal); +#endif +#ifdef SIGVTALRM + SIGNAL(SIGVTALRM, bad_signal); +#endif +#ifdef SIGXCPU + SIGNAL(SIGXCPU, bad_signal); +#endif +#ifdef SIGXFSZ + SIGNAL(SIGXFSZ, bad_signal); +#endif /* * Lock the device if we've been asked to. @@ -306,10 +348,10 @@ main(argc, argv) die(1); } - syslog(LOG_INFO, "Connected..."); + syslog(LOG_INFO, "Serial connection established."); sleep(1); /* give it time to set up its terminal */ } - + /* set line speed, flow control, etc.; clear CLOCAL if modem option */ set_up_tty(fd, 0); @@ -347,6 +389,7 @@ main(argc, argv) for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) { wait_input(timeleft(&timo)); calltimeout(); + get_input(); if (kill_link) { lcp_close(0); kill_link = 0; @@ -358,13 +401,13 @@ main(argc, argv) } open_ccp_flag = 0; } - get_input(); reap_kids(); /* Don't leave dead kids lying around */ } /* * Run disconnector script, if requested. * First we need to reset non-blocking mode. + * XXX we may not be able to do this if the line has hung up! */ if (initfdflags != -1 && fcntl(fd, F_SETFL, initfdflags) >= 0) initfdflags = -1; @@ -373,10 +416,9 @@ main(argc, argv) set_up_tty(fd, 1); if (device_script(disconnector, fd, fd) < 0) { syslog(LOG_WARNING, "disconnect script failed"); - die(1); + } else { + syslog(LOG_INFO, "Serial link disconnected."); } - - syslog(LOG_INFO, "Disconnected..."); } close_fd(); @@ -438,21 +480,21 @@ get_input() /* * Upcall the proper protocol input routine. */ - for (i = 0; i < sizeof (prottbl) / sizeof (struct protent); i++) + for (i = 0; i < sizeof (prottbl) / sizeof (struct protent); i++) { if (prottbl[i].protocol == protocol) { (*prottbl[i].input)(0, p, len); - break; - } else if (protocol == (prottbl[i].protocol & ~0x8000) - && prottbl[i].datainput != NULL) { + return; + } + if (protocol == (prottbl[i].protocol & ~0x8000) + && prottbl[i].datainput != NULL) { (*prottbl[i].datainput)(0, p, len); - break; + return; } - - if (i == sizeof (prottbl) / sizeof (struct protent)) { - if (debug) - syslog(LOG_WARNING, "Unknown protocol (0x%x) received", protocol); - lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN); } + + if (debug) + syslog(LOG_WARNING, "Unknown protocol (0x%x) received", protocol); + lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN); } @@ -482,12 +524,23 @@ demuxprotrej(unit, protocol) /* - * quit - Clean up state and exit. + * bad_signal - We've caught a fatal signal. Clean up state and exit. + */ +static void +bad_signal(sig) + int sig; +{ + syslog(LOG_ERR, "Fatal signal %d", sig); + die(1); +} + +/* + * quit - Clean up state and exit (with an error indication). */ void quit() { - die(0); + die(1); } /* @@ -528,6 +581,8 @@ cleanup(status, arg) void close_fd() { + disestablish_ppp(); + /* drop dtr to hang up */ if (modem) setdtr(fd, FALSE); @@ -536,8 +591,6 @@ close_fd() syslog(LOG_WARNING, "Couldn't restore device fd flags: %m"); initfdflags = -1; - disestablish_ppp(); - restore_tty(); close(fd); @@ -760,6 +813,7 @@ device_script(program, in, out) { int pid; int status; + int errfd; pid = fork(); @@ -769,10 +823,13 @@ device_script(program, in, out) } if (pid == 0) { - setuid(getuid()); - setgid(getgid()); dup2(in, 0); dup2(out, 1); + errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0644); + if (errfd >= 0) + dup2(errfd, 2); + setuid(getuid()); + setgid(getgid()); execl("/bin/sh", "sh", "-c", program, (char *)0); syslog(LOG_ERR, "could not exec /bin/sh: %m"); _exit(99);