A bunch of fixes mostly aimed at fixing the problems we have been
authorPaul Mackerras <paulus@samba.org>
Mon, 3 Mar 2003 05:11:46 +0000 (05:11 +0000)
committerPaul Mackerras <paulus@samba.org>
Mon, 3 Mar 2003 05:11:46 +0000 (05:11 +0000)
having with leaking fds and with fatal errors occurring when the link
goes down.
Updated patchlevel.h to 2.4.2b2.
Moved open of /dev/ppp to generic_establish_ppp; we now close the
ppp_dev_fd in generic_disestablish_ppp rather than trying to use
PPPIOCDETACH.
*_send_config and *_recv_config now return 0 for success or -1 for
error, rather than calling fatal() when an error occurs.
Added a notifier for when we fork so plugins can close their fds in
the child.
Added a safe_fork() which does a fork and then closes stuff in the
child; the parent waits until the child has done that.
On detach, the parent rewrites the pid files rather than the child,
and the child waits for the parent to die.
Fixed some potential FILE * leaks.
Also moved auth_number() check into auth_check_options.

pppd/auth.c
pppd/demand.c
pppd/lcp.c
pppd/main.c
pppd/options.c
pppd/patchlevel.h
pppd/pppd.h
pppd/sys-linux.c
pppd/sys-solaris.c
pppd/sys-sunos4.c
pppd/tty.c

index a4f7775adb6a5ff69ff090e590b7008bf01eb1cd..d554bfd0f7e6aecb5cfa921f903a160fd45cc92f 100644 (file)
@@ -73,7 +73,7 @@
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define RCSID  "$Id: auth.c,v 1.92 2003/02/16 22:29:50 paulus Exp $"
+#define RCSID  "$Id: auth.c,v 1.93 2003/03/03 05:11:45 paulus Exp $"
 
 #include <stdio.h>
 #include <stddef.h>
@@ -428,7 +428,8 @@ setupapfile(argv)
 
     /* get username */
     if (fgets(u, MAXNAMELEN - 1, ufile) == NULL
-       || fgets(p, MAXSECRETLEN - 1, ufile) == NULL){
+       || fgets(p, MAXSECRETLEN - 1, ufile) == NULL) {
+       fclose(ufile);
        option_error("unable to read user login data file %s", fname);
        return 0;
     }
@@ -1149,6 +1150,14 @@ auth_check_options()
 
        exit(1);
     }
+
+    /*
+     * Early check for remote number authorization.
+     */
+    if (!auth_number()) {
+       warn("calling number %q is not authorized", remote_number);
+       exit(EXIT_CNID_AUTH_FAILED);
+    }
 }
 
 /*
index db5dd90e8d5d9194283dd80ad6385185efa3ddb7..395a598a9ea56b8c95d256d47eeacafc6081d920 100644 (file)
@@ -33,7 +33,7 @@
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define RCSID  "$Id: demand.c,v 1.16 2002/12/04 23:03:32 paulus Exp $"
+#define RCSID  "$Id: demand.c,v 1.17 2003/03/03 05:11:45 paulus Exp $"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -102,8 +102,9 @@ demand_conf()
     fcs = PPP_INITFCS;
 
     netif_set_mtu(0, MIN(lcp_allowoptions[0].mru, PPP_MRU));
-    ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0);
-    ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0);
+    if (ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0) < 0
+       || ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0) < 0)
+           fatal("Couldn't set up demand-dialled PPP interface: %m");
 
 #ifdef PPP_FILTER
     set_filters(&pass_filter, &active_filter);
index 442ae227a5143215a863130bc138bc22c4225f17..e44a78125dde573b62bad33c87b966dfcfdca78a 100644 (file)
@@ -40,7 +40,7 @@
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define RCSID  "$Id: lcp.c,v 1.64 2002/12/04 23:03:32 paulus Exp $"
+#define RCSID  "$Id: lcp.c,v 1.65 2003/03/03 05:11:46 paulus Exp $"
 
 /*
  * TODO:
@@ -433,9 +433,10 @@ lcp_lowerup(unit)
      * but accept A/C and protocol compressed packets
      * if we are going to ask for A/C and protocol compression.
      */
-    ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0);
-    ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff),
-                   wo->neg_pcompression, wo->neg_accompression);
+    if (ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0) < 0
+       || ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff),
+                          wo->neg_pcompression, wo->neg_accompression) < 0)
+           return;
     peer_mru[unit] = PPP_MRU;
 
     if (listen_time != 0) {
index 5f30dd1867cbfd530a5786cfa4970b85e76e7247..a01b852cc26c1dad05dabd37dcdecb5694694aa3 100644 (file)
@@ -40,7 +40,7 @@
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define RCSID  "$Id: main.c,v 1.122 2003/02/24 12:46:37 fcusack Exp $"
+#define RCSID  "$Id: main.c,v 1.123 2003/03/03 05:11:46 paulus Exp $"
 
 #include <stdio.h>
 #include <ctype.h>
@@ -113,6 +113,7 @@ struct notifier *pidchange = NULL;
 struct notifier *phasechange = NULL;
 struct notifier *exitnotify = NULL;
 struct notifier *sigreceived = NULL;
+struct notifier *fork_notifier = NULL;
 
 int hungup;                    /* terminal has been hung up */
 int privileged;                        /* we're running as real uid root */
@@ -139,6 +140,7 @@ static int conn_running;    /* we have a [dis]connector running */
 static int devfd;              /* fd of underlying device */
 static int fd_ppp = -1;                /* fd for talking PPP */
 static int fd_loop;            /* fd for getting demand-dial packets */
+static int fd_devnull;         /* fd for /dev/null */
 
 int phase;                     /* where the link is at */
 int kill_link;
@@ -190,8 +192,8 @@ static struct subprocess *children;
 /* Prototypes for procedures local to this file. */
 
 static void setup_signals __P((void));
-static void create_pidfile __P((void));
-static void create_linkpidfile __P((void));
+static void create_pidfile __P((int pid));
+static void create_linkpidfile __P((int pid));
 static void cleanup __P((void));
 static void get_input __P((void));
 static void calltimeout __P((void));
@@ -278,18 +280,6 @@ main(argc, argv)
     link_stats_valid = 0;
     new_phase(PHASE_INITIALIZE);
 
-    /*
-     * Ensure that fds 0, 1, 2 are open, to /dev/null if nowhere else.
-     * This way we can close 0, 1, 2 in detach() without clobbering
-     * a fd that we are using.
-     */
-    if ((i = open("/dev/null", O_RDWR)) >= 0) {
-       while (0 <= i && i <= 2)
-           i = dup(i);
-       if (i >= 0)
-           close(i);
-    }
-
     script_env = NULL;
 
     /* Initialize syslog facilities */
@@ -387,14 +377,6 @@ main(argc, argv)
        end_pr_log();
     }
 
-    /*
-     * Early check for remote number authorization.
-     */
-    if (!auth_number()) {
-       warn("calling number %q is not authorized", remote_number);
-       exit(EXIT_CNID_AUTH_FAILED);
-    }
-
     if (dryrun)
        die(0);
 
@@ -403,6 +385,17 @@ main(argc, argv)
      */
     sys_init();
 
+    /* Make sure fds 0, 1, 2 are open to somewhere. */
+    fd_devnull = open(_PATH_DEVNULL, O_RDWR);
+    if (fd_devnull < 0)
+       fatal("Couldn't open %s: %m", _PATH_DEVNULL);
+    while (fd_devnull <= 2) {
+       i = dup(fd_devnull);
+       if (i < 0)
+           fatal("Critical shortage of file descriptors: dup failed: %m");
+       fd_devnull = i;
+    }
+
 #ifdef USE_TDB
     pppdb = tdb_open(_PATH_PPPDB, 0, 0, O_RDWR|O_CREAT, 0644);
     if (pppdb != NULL) {
@@ -443,7 +436,7 @@ main(argc, argv)
 
     waiting = 0;
 
-    create_linkpidfile();
+    create_linkpidfile(getpid());
 
     /*
      * If we're doing dial-on-demand, set up the interface now.
@@ -783,8 +776,8 @@ set_ifunit(iskey)
     slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit);
     script_setenv("IFNAME", ifname, iskey);
     if (iskey) {
-       create_pidfile();       /* write pid to file */
-       create_linkpidfile();
+       create_pidfile(getpid());       /* write pid to file */
+       create_linkpidfile(getpid());
     }
 }
 
@@ -796,9 +789,12 @@ detach()
 {
     int pid;
     char numbuf[16];
+    int pipefd[2];
 
     if (detached)
        return;
+    if (pipe(pipefd) == -1)
+       pipefd[0] = pipefd[1] = -1;
     if ((pid = fork()) < 0) {
        error("Couldn't detach (fork failed: %m)");
        die(1);                 /* or just return? */
@@ -806,23 +802,28 @@ detach()
     if (pid != 0) {
        /* parent */
        notify(pidchange, pid);
+       /* update pid files if they have been written already */
+       if (pidfilename[0])
+           create_pidfile(pid);
+       if (linkpidfile[0])
+           create_linkpidfile(pid);
        exit(0);                /* parent dies */
     }
     setsid();
     chdir("/");
-    close(0);
-    close(1);
-    close(2);
+    dup2(fd_devnull, 0);
+    dup2(fd_devnull, 1);
+    dup2(fd_devnull, 2);
     detached = 1;
     if (log_default)
        log_to_fd = -1;
-    /* update pid files if they have been written already */
-    if (pidfilename[0])
-       create_pidfile();
-    if (linkpidfile[0])
-       create_linkpidfile();
     slprintf(numbuf, sizeof(numbuf), "%d", getpid());
     script_setenv("PPPD_PID", numbuf, 1);
+
+    /* wait for parent to finish updating pid & lock files and die */
+    close(pipefd[1]);
+    read(pipefd[0], numbuf, 1);
+    close(pipefd[0]);
 }
 
 /*
@@ -843,7 +844,8 @@ reopen_log()
  * Create a file containing our process ID.
  */
 static void
-create_pidfile()
+create_pidfile(pid)
+    int pid;
 {
     FILE *pidfile;
 
@@ -859,7 +861,8 @@ create_pidfile()
 }
 
 static void
-create_linkpidfile()
+create_linkpidfile(pid)
+    int pid;
 {
     FILE *pidfile;
 
@@ -1405,6 +1408,40 @@ bad_signal(sig)
     die(127);
 }
 
+/*
+ * safe_fork - Create a child process.  The child closes all the
+ * file descriptors that we don't want to leak to a script.
+ * The parent waits for the child to do this before returning.
+ */
+pid_t
+safe_fork()
+{
+       pid_t pid;
+       int pipefd[2];
+       char buf[1];
+
+       if (pipe(pipefd) == -1)
+               pipefd[0] = pipefd[1] = -1;
+       pid = fork();
+       if (pid < 0)
+               return -1;
+       if (pid > 0) {
+               close(pipefd[1]);
+               /* this read() blocks until the close(pipefd[1]) below */
+               read(pipefd[0], buf, 1);
+               close(pipefd[0]);
+               return pid;
+       }
+       sys_close();
+#ifdef USE_TDB
+       tdb_close(pppdb);
+#endif
+       notify(fork_notifier, 0);
+       close(pipefd[0]);
+       /* this close unblocks the read() call above in the parent */
+       close(pipefd[1]);
+       return 0;
+}
 
 /*
  * device_script - run a program to talk to the specified fds
@@ -1417,12 +1454,12 @@ device_script(program, in, out, dont_wait)
     int in, out;
     int dont_wait;
 {
-    int pid, fd;
+    int pid;
     int status = -1;
     int errfd;
 
     ++conn_running;
-    pid = fork();
+    pid = safe_fork();
 
     if (pid < 0) {
        --conn_running;
@@ -1446,13 +1483,6 @@ device_script(program, in, out, dont_wait)
     }
 
     /* here we are executing in the child */
-    /* make sure fds 0, 1, 2 are occupied */
-    while ((fd = dup(in)) >= 0) {
-       if (fd > 2) {
-           close(fd);
-           break;
-       }
-    }
 
     /* dup in and out to fds > 2 */
     {
@@ -1474,10 +1504,10 @@ device_script(program, in, out, dont_wait)
     close(0);
     close(1);
     close(2);
-    sys_close();
     if (the_channel->close)
        (*the_channel->close)();
     closelog();
+    close(fd_devnull);
 
     /* dup the in, out, err fds to 0, 1, 2 */
     dup2(in, 0);
@@ -1537,66 +1567,54 @@ run_program(prog, args, must_exist, done, arg)
        return 0;
     }
 
-    pid = fork();
+    pid = safe_fork();
     if (pid == -1) {
        error("Failed to create child process for %s: %m", prog);
        return -1;
     }
-    if (pid == 0) {
-       int new_fd;
+    if (pid != 0) {
+       if (debug)
+           dbglog("Script %s started (pid %d)", prog, pid);
+       record_child(pid, prog, done, arg);
+       return pid;
+    }
 
-       /* Leave the current location */
-       (void) setsid();        /* No controlling tty. */
-       (void) umask (S_IRWXG|S_IRWXO);
-       (void) chdir ("/");     /* no current directory. */
-       setuid(0);              /* set real UID = root */
-       setgid(getegid());
+    /* Leave the current location */
+    (void) setsid();   /* No controlling tty. */
+    (void) umask (S_IRWXG|S_IRWXO);
+    (void) chdir ("/");        /* no current directory. */
+    setuid(0);         /* set real UID = root */
+    setgid(getegid());
 
-       /* Ensure that nothing of our device environment is inherited. */
-       sys_close();
-       closelog();
-       close (0);
-       close (1);
-       close (2);
-       if (the_channel->close)
-           (*the_channel->close)();
-
-        /* Don't pass handles to the PPP device, even by accident. */
-       new_fd = open (_PATH_DEVNULL, O_RDWR);
-       if (new_fd >= 0) {
-           if (new_fd != 0) {
-               dup2  (new_fd, 0); /* stdin <- /dev/null */
-               close (new_fd);
-           }
-           dup2 (0, 1); /* stdout -> /dev/null */
-           dup2 (0, 2); /* stderr -> /dev/null */
-       }
+    /* Ensure that nothing of our device environment is inherited. */
+    closelog();
+    if (the_channel->close)
+       (*the_channel->close)();
+
+    /* Don't pass handles to the PPP device, even by accident. */
+    dup2(fd_devnull, 0);
+    dup2(fd_devnull, 1);
+    dup2(fd_devnull, 2);
+    close(fd_devnull);
 
 #ifdef BSD
-       /* Force the priority back to zero if pppd is running higher. */
-       if (setpriority (PRIO_PROCESS, 0, 0) < 0)
-           warn("can't reset priority to 0: %m");
+    /* Force the priority back to zero if pppd is running higher. */
+    if (setpriority (PRIO_PROCESS, 0, 0) < 0)
+       warn("can't reset priority to 0: %m");
 #endif
 
-       /* SysV recommends a second fork at this point. */
+    /* SysV recommends a second fork at this point. */
 
-       /* run the program */
-       execve(prog, args, script_env);
-       if (must_exist || errno != ENOENT) {
-           /* have to reopen the log, there's nowhere else
-              for the message to go. */
-           reopen_log();
-           syslog(LOG_ERR, "Can't execute %s: %m", prog);
-           closelog();
-       }
-       _exit(-1);
+    /* run the program */
+    execve(prog, args, script_env);
+    if (must_exist || errno != ENOENT) {
+       /* have to reopen the log, there's nowhere else
+          for the message to go. */
+       reopen_log();
+       syslog(LOG_ERR, "Can't execute %s: %m", prog);
+       closelog();
     }
-
-    if (debug)
-       dbglog("Script %s started (pid %d)", prog, pid);
-    record_child(pid, prog, done, arg);
-
-    return pid;
+    _exit(-1);
 }
 
 
index 7f4f5eb80af4d68004811a868b4f11e9c7651119..b8a2103ac8a264e7c683801539471a366e94a2d7 100644 (file)
@@ -40,7 +40,7 @@
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define RCSID  "$Id: options.c,v 1.90 2002/12/04 23:03:32 paulus Exp $"
+#define RCSID  "$Id: options.c,v 1.91 2003/03/03 05:11:46 paulus Exp $"
 
 #include <ctype.h>
 #include <stdio.h>
@@ -1483,7 +1483,6 @@ setdomain(argv)
     return (1);
 }
 
-
 static int
 setlogfile(argv)
     char **argv;
@@ -1511,6 +1510,7 @@ setlogfile(argv)
     log_default = 0;
     return 1;
 }
+
 #ifdef MAXOCTETS
 static int
 setmodir(argv)
index d22c191a598879f1fdbb3acaed3eb390ba30e012..9b143e3be354ddb1e5482b5439ad64b010e0c94c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: patchlevel.h,v 1.55 2003/02/16 22:31:41 paulus Exp $ */
+/* $Id: patchlevel.h,v 1.56 2003/03/03 05:11:46 paulus Exp $ */
 
-#define VERSION                "2.4.2b1"
-#define DATE           "17 February 2003"
+#define VERSION                "2.4.2b2"
+#define DATE           "3 March 2003"
index f6ad3181e9544da6a7ccbc722861224619608891..60ca8b54f230f56992e08ce1704042234fb758e3 100644 (file)
@@ -39,7 +39,7 @@
  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * $Id: pppd.h,v 1.79 2003/02/16 22:26:27 paulus Exp $
+ * $Id: pppd.h,v 1.80 2003/03/03 05:11:46 paulus Exp $
  */
 
 /*
@@ -252,6 +252,7 @@ extern struct notifier *ip_up_notifier; /* IPCP has come up */
 extern struct notifier *ip_down_notifier; /* IPCP has gone down */
 extern struct notifier *auth_up_notifier; /* peer has authenticated */
 extern struct notifier *link_down_notifier; /* link has gone down */
+extern struct notifier *fork_notifier; /* we are a new child process */
 
 /* Values for do_callback and doing_callback */
 #define CALLBACK_DIALIN                1       /* we are expecting the call back */
@@ -438,9 +439,9 @@ struct channel {
        /* take the channel out of PPP `mode', restore loopback if demand */
        void (*disestablish_ppp) __P((int));
        /* set the transmit-side PPP parameters of the channel */
-       void (*send_config) __P((int, u_int32_t, int, int));
+       int (*send_config) __P((int, u_int32_t, int, int));
        /* set the receive-side PPP parameters of the channel */
-       void (*recv_config) __P((int, u_int32_t, int, int));
+       int (*recv_config) __P((int, u_int32_t, int, int));
        /* cleanup on error or normal exit */
        void (*cleanup) __P((void));
        /* close the device, called in children after fork */
@@ -450,16 +451,12 @@ struct channel {
 extern struct channel *the_channel;
 
 #define ppp_send_config(unit, mtu, accm, pc, acc)                       \
-do {                                                                    \
-       if (the_channel->send_config)                                    \
-               (*the_channel->send_config)((mtu), (accm), (pc), (acc)); \
-} while (0)
+       (the_channel->send_config?                                       \
+        (*the_channel->send_config)((mtu), (accm), (pc), (acc)): 0)
 
 #define ppp_recv_config(unit, mtu, accm, pc, acc)                       \
-do {                                                                    \
-       if (the_channel->send_config)                                    \
-               (*the_channel->recv_config)((mtu), (accm), (pc), (acc)); \
-} while (0)
+       (the_channel->recv_config?                                       \
+        (*the_channel->recv_config)((mtu), (accm), (pc), (acc)): 0)
 
 /*
  * Prototypes.
@@ -476,6 +473,7 @@ void timeout __P((void (*func)(void *), void *arg, int s, int us));
 void untimeout __P((void (*func)(void *), void *arg));
                                /* Cancel call to func(arg) */
 void record_child __P((int, char *, void (*) (void *), void *));
+pid_t safe_fork __P((void));   /* Fork & close stuff in child */
 int  device_script __P((char *cmd, int in, int out, int dont_wait));
                                /* Run `cmd' with given stdin and stdout */
 pid_t run_program __P((char *prog, char **args, int must_exist,
@@ -588,11 +586,11 @@ void add_fd __P((int));           /* Add fd to set to wait for */
 void remove_fd __P((int));     /* Remove fd from set to wait for */
 int  read_packet __P((u_char *)); /* Read PPP packet */
 int  get_loop_output __P((void)); /* Read pkts from loopback */
-void tty_send_config __P((int, u_int32_t, int, int));
+int  tty_send_config __P((int, u_int32_t, int, int));
                                /* Configure i/f transmit parameters */
 void tty_set_xaccm __P((ext_accm));
                                /* Set extended transmit ACCM */
-void tty_recv_config __P((int, u_int32_t, int, int));
+int  tty_recv_config __P((int, u_int32_t, int, int));
                                /* Configure i/f receive parameters */
 int  ccp_test __P((int, u_char *, int, int));
                                /* Test support for compression scheme */
index 099db535357fb8211928fd545143a4e2d68e1476..0b6db1c8f91d0b6a1d13f73f12b4875555a7f335 100644 (file)
@@ -183,7 +183,7 @@ static int master_fd = -1;
 #ifdef INET6
 static int sock6_fd = -1;
 #endif /* INET6 */
-int ppp_dev_fd = -1;   /* fd for /dev/ppp (new style driver) */
+int ppp_dev_fd = -1;           /* fd for /dev/ppp (new style driver) */
 static int chindex;            /* channel index (new style driver) */
 
 static fd_set in_fds;          /* set of fds that wait_input waits for */
@@ -225,7 +225,7 @@ static int kernel_version;
 
 /* Prototypes for procedures local to this file. */
 static int get_flags (int fd);
-static void set_flags (int fd, int flags);
+static int set_flags (int fd, int flags);
 static int translate_speed (int bps);
 static int baud_rate_of (int speed);
 static void close_route_table (void);
@@ -300,14 +300,16 @@ static int get_flags (int fd)
 
 /********************************************************************/
 
-static void set_flags (int fd, int flags)
+static int set_flags (int fd, int flags)
 {
     SYSDEBUG ((LOG_DEBUG, "set flags = %x\n", flags));
 
     if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &flags) < 0) {
        if (! ok_error (errno) )
-           fatal("ioctl(PPPIOCSFLAGS, %x): %m (line %d)", flags, errno, __LINE__);
+           error("Failed to set PPP kernel option flags: %m", flags);
+       return -1;
     }
+    return 0;
 }
 
 /********************************************************************
@@ -317,18 +319,6 @@ static void set_flags (int fd, int flags)
 
 void sys_init(void)
 {
-    int flags;
-
-    if (new_style_driver) {
-       ppp_dev_fd = open("/dev/ppp", O_RDWR);
-       if (ppp_dev_fd < 0)
-           fatal("Couldn't open /dev/ppp: %m");
-       flags = fcntl(ppp_dev_fd, F_GETFL);
-       if (flags == -1
-           || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
-           warn("Couldn't set /dev/ppp to nonblock: %m");
-    }
-
     /* Get an internet socket for doing socket ioctls. */
     sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
     if (sock_fd < 0)
@@ -381,11 +371,14 @@ sys_close(void)
        close(ppp_dev_fd);
     if (sock_fd >= 0)
        close(sock_fd);
+#ifdef INET6
+    if (sock6_fd >= 0)
+       close(sock6_fd);
+#endif
     if (slave_fd >= 0)
        close(slave_fd);
     if (master_fd >= 0)
        close(master_fd);
-    closelog();
 }
 
 /********************************************************************
@@ -472,9 +465,9 @@ int generic_establish_ppp (int fd)
     int x;
 
     if (new_style_driver) {
-       /* Open another instance of /dev/ppp and connect the channel to it */
        int flags;
 
+       /* Open an instance of /dev/ppp and connect the channel to it */
        if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
            error("Couldn't get channel number: %m");
            goto err;
@@ -617,10 +610,11 @@ void generic_disestablish_ppp(int dev_fd)
        if (demand) {
            set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_LOOP_TRAFFIC);
            looped = 1;
-       } else if (ifunit >= 0 && ioctl(ppp_dev_fd, PPPIOCDETACH) < 0)
-           error("Couldn't release PPP unit: %m");
-       if (!multilink)
+       } else if (ifunit >= 0) {
+           close(ppp_dev_fd);
            remove_fd(ppp_dev_fd);
+           ppp_dev_fd = -1;
+       }
     } else {
        /* old-style driver */
        if (demand)
@@ -634,7 +628,19 @@ void generic_disestablish_ppp(int dev_fd)
  */
 static int make_ppp_unit()
 {
-       int x;
+       int x, flags;
+
+       if (ppp_dev_fd >= 0) {
+               dbglog("in make_ppp_unit, already had /dev/ppp open?");
+               close(ppp_dev_fd);
+       }
+       ppp_dev_fd = open("/dev/ppp", O_RDWR);
+       if (ppp_dev_fd < 0)
+               fatal("Couldn't open /dev/ppp: %m");
+       flags = fcntl(ppp_dev_fd, F_GETFL);
+       if (flags == -1
+           || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
+               warn("Couldn't set /dev/ppp to nonblock: %m");
 
        ifunit = req_unit;
        x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
@@ -701,17 +707,25 @@ void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
  */
 int bundle_attach(int ifnum)
 {
+       int master_fd;
+
        if (!new_style_driver)
                return -1;
 
-       if (ioctl(ppp_dev_fd, PPPIOCATTACH, &ifnum) < 0) {
-               if (errno == ENXIO)
+       master_fd = open("/dev/ppp", O_RDWR);
+       if (master_fd < 0)
+               fatal("Couldn't open /dev/ppp: %m");
+       if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
+               if (errno == ENXIO) {
+                       close(master_fd);
                        return 0;       /* doesn't still exist */
+               }
                fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
        }
        if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
                fatal("Couldn't connect to interface unit %d: %m", ifnum);
-       set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_MULTILINK);
+       set_flags(master_fd, get_flags(master_fd) | SC_MULTILINK);
+       close(master_fd);
 
        ifunit = ifnum;
        return 1;
@@ -1175,7 +1189,7 @@ netif_get_mtu(int unit)
  * the ppp interface.
  */
 
-void tty_send_config (int mtu,u_int32_t asyncmap,int pcomp,int accomp)
+int tty_send_config (int mtu,u_int32_t asyncmap,int pcomp,int accomp)
 {
     u_int x;
 
@@ -1183,20 +1197,22 @@ void tty_send_config (int mtu,u_int32_t asyncmap,int pcomp,int accomp)
  * Set the asyncmap and other parameters for the ppp device
  */
     if (!still_ppp())
-       return;
+       return 0;
     link_mtu = mtu;
     SYSDEBUG ((LOG_DEBUG, "send_config: asyncmap = %lx\n", asyncmap));
     if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
-       if (!ok_error(errno))
-           fatal("ioctl(PPPIOCSASYNCMAP): %m (line %d)", __LINE__);
-       return;
+       if (errno != EIO && errno != ENOTTY)
+           error("Couldn't set transmit async character map: %m");
+       else if (debug)
+           dbglog("PPPIOCSASYNCMAP: %m");
+       return -1;
     }
 
     x = get_flags(ppp_fd);
     x = pcomp  ? x | SC_COMP_PROT : x & ~SC_COMP_PROT;
     x = accomp ? x | SC_COMP_AC   : x & ~SC_COMP_AC;
     x = sync_serial ? x | SC_SYNC : x & ~SC_SYNC;
-    set_flags(ppp_fd, x);
+    return set_flags(ppp_fd, x);
 }
 
 /********************************************************************
@@ -1223,31 +1239,42 @@ void tty_set_xaccm (ext_accm accm)
  * the ppp interface.
  */
 
-void tty_recv_config (int mru,u_int32_t asyncmap,int pcomp,int accomp)
+int tty_recv_config (int mru,u_int32_t asyncmap,int pcomp,int accomp)
 {
+    int ret = 0;
+
     SYSDEBUG ((LOG_DEBUG, "recv_config: mru = %d\n", mru));
 /*
  * If we were called because the link has gone down then there is nothing
  * which may be done. Just return without incident.
  */
     if (!still_ppp())
-       return;
+       return 0;
 /*
  * Set the receiver parameters
  */
     if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
-       if ( ! ok_error (errno))
-           error("ioctl(PPPIOCSMRU): %m (line %d)", __LINE__);
+       if (errno != EIO && errno != ENOTTY)
+           error("Couldn't set channel receive MRU: %m");
+       else if (debug)
+           dbglog("PPPIOCSMRU: %m");
+       ret = -1;
     }
     if (new_style_driver && ifunit >= 0
-       && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
+       && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
        error("Couldn't set MRU in generic PPP layer: %m");
+       ret = -1;
+    }
 
     SYSDEBUG ((LOG_DEBUG, "recv_config: asyncmap = %lx\n", asyncmap));
     if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
-       if (!ok_error(errno))
-           error("ioctl(PPPIOCSRASYNCMAP): %m (line %d)", __LINE__);
+       if (errno != EIO && errno != ENOTTY)
+           error("Couldn't set channel receive asyncmap: %m");
+       else if (debug)
+           dbglog("PPPIOCSRASYNCMAP: %m");
+       ret = -1;
     }
+    return ret;
 }
 
 /********************************************************************
index 10803e2209de67b0a5d59112fdf71ec454853b74..d3675f6296ea7e34aa209e0d01a24042dba0d01a 100644 (file)
@@ -90,7 +90,7 @@
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define RCSID  "$Id: sys-solaris.c,v 1.9 2002/12/04 23:03:33 paulus Exp $"
+#define RCSID  "$Id: sys-solaris.c,v 1.10 2003/03/03 05:11:46 paulus Exp $"
 
 #include <limits.h>
 #include <stdio.h>
@@ -1539,24 +1539,27 @@ netif_set_mtu(unit, mtu)
  * tty_send_config - configure the transmit characteristics of
  * the ppp interface.
  */
-void
+int
 tty_send_config(mtu, asyncmap, pcomp, accomp)
     int mtu;
     u_int32_t asyncmap;
     int pcomp, accomp;
 {
     int cf[2];
+    int ret = 0;
 
     link_mtu = mtu;
     if (strioctl(pppfd, PPPIO_MTU, &mtu, sizeof(mtu), 0) < 0) {
        if (hungup && errno == ENXIO)
-           return;
+           return -1;
        error("Couldn't set MTU: %m");
+       ret = -1;
     }
     if (fdmuxid >= 0) {
        if (!sync_serial) {
            if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0) {
                error("Couldn't set transmit ACCM: %m");
+               ret = -1;
            }
        }
        cf[0] = (pcomp? COMP_PROT: 0) + (accomp? COMP_AC: 0);
@@ -1564,8 +1567,10 @@ tty_send_config(mtu, asyncmap, pcomp, accomp)
        if (any_compressions() &&
            strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
            error("Couldn't set prot/AC compression: %m");
+           ret = -1;
        }
     }
+    return ret;
 }
 
 /*
@@ -1589,24 +1594,27 @@ tty_set_xaccm(accm)
  * tty_recv_config - configure the receive-side characteristics of
  * the ppp interface.
  */
-void
+int
 tty_recv_config(mru, asyncmap, pcomp, accomp)
     int mru;
     u_int32_t asyncmap;
     int pcomp, accomp;
 {
     int cf[2];
+    int ret = 0;
 
     link_mru = mru;
     if (strioctl(pppfd, PPPIO_MRU, &mru, sizeof(mru), 0) < 0) {
        if (hungup && errno == ENXIO)
-           return;
+           return -1;
        error("Couldn't set MRU: %m");
+       ret = -1;
     }
     if (fdmuxid >= 0) {
        if (!sync_serial) {
            if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0) {
                error("Couldn't set receive ACCM: %m");
+               ret = -1;
            }
        }
        cf[0] = (pcomp? DECOMP_PROT: 0) + (accomp? DECOMP_AC: 0);
@@ -1614,8 +1622,10 @@ tty_recv_config(mru, asyncmap, pcomp, accomp)
        if (any_compressions() &&
            strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
            error("Couldn't set prot/AC decompression: %m");
+           ret = -1;
        }
     }
+    return ret;
 }
 
 /*
index 26e2ba15a4506b15ab712c0d085bec6ea566a8eb..cb1b2485adaebb6b00905723c852f17e47f5b721 100644 (file)
@@ -73,7 +73,7 @@
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define RCSID  "$Id: sys-sunos4.c,v 1.30 2002/12/04 23:03:33 paulus Exp $"
+#define RCSID  "$Id: sys-sunos4.c,v 1.31 2003/03/03 05:11:46 paulus Exp $"
 
 #include <stdio.h>
 #include <stddef.h>
@@ -803,28 +803,33 @@ netif_set_mtu(unit, mtu)
  * tty_send_config - configure the transmit characteristics of
  * the ppp interface.
  */
-void
+int
 tty_send_config(mtu, asyncmap, pcomp, accomp)
     int mtu;
     u_int32_t asyncmap;
     int pcomp, accomp;
 {
     int cf[2];
+    int ret = 0;
 
     link_mtu = mtu;
     if (strioctl(pppfd, PPPIO_MTU, &mtu, sizeof(mtu), 0) < 0) {
        if (hungup && errno == ENXIO)
-           return;
+           return -1;
        error("Couldn't set MTU: %m");
+       ret = -1;
     }
     if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0) {
        error("Couldn't set transmit ACCM: %m");
+       ret = -1;
     }
     cf[0] = (pcomp? COMP_PROT: 0) + (accomp? COMP_AC: 0);
     cf[1] = COMP_PROT | COMP_AC;
     if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
        error("Couldn't set prot/AC compression: %m");
+       ret = -1;
     }
+    return ret;
 }
 
 /*
@@ -845,28 +850,33 @@ tty_set_xaccm(unit, accm)
  * tty_recv_config - configure the receive-side characteristics of
  * the ppp interface.
  */
-void
+int
 tty_recv_config(mru, asyncmap, pcomp, accomp)
     int mru;
     u_int32_t asyncmap;
     int pcomp, accomp;
 {
     int cf[2];
+    int ret = 0;
 
     link_mru = mru;
     if (strioctl(pppfd, PPPIO_MRU, &mru, sizeof(mru), 0) < 0) {
        if (hungup && errno == ENXIO)
-           return;
+           return -1;
        error("Couldn't set MRU: %m");
+       ret = -1;
     }
     if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0) {
        error("Couldn't set receive ACCM: %m");
+       ret = -1;
     }
     cf[0] = (pcomp? DECOMP_PROT: 0) + (accomp? DECOMP_AC: 0);
     cf[1] = DECOMP_PROT | DECOMP_AC;
     if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
        error("Couldn't set prot/AC decompression: %m");
+       ret = -1;
     }
+    return ret;
 }
 
 /*
index a7ebe6ff0151055cfab29c706260d51bd3c126f9..9fa0326cb0ca2d438eb181289d8cd3b0849b3d1b 100644 (file)
@@ -73,7 +73,7 @@
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define RCSID  "$Id: tty.c,v 1.10 2003/02/24 11:29:53 fcusack Exp $"
+#define RCSID  "$Id: tty.c,v 1.11 2003/03/03 05:11:46 paulus Exp $"
 
 #include <stdio.h>
 #include <ctype.h>
@@ -108,7 +108,7 @@ int  connect_tty __P((void));
 void disconnect_tty __P((void));
 void tty_close_fds __P((void));
 void cleanup_tty __P((void));
-void tty_do_send_config __P((int, u_int32_t, int, int));
+int  tty_do_send_config __P((int, u_int32_t, int, int));
 
 static int setdevname __P((char *, char **, int));
 static int setspeed __P((char *, char **, int));
@@ -772,14 +772,14 @@ void cleanup_tty()
  * tty_do_send_config - set transmit-side PPP configuration.
  * We set the extended transmit ACCM here as well.
  */
-void
+int
 tty_do_send_config(mtu, accm, pcomp, accomp)
     int mtu;
     u_int32_t accm;
     int pcomp, accomp;
 {
        tty_set_xaccm(xmit_accm);
-       tty_send_config(mtu, accm, pcomp, accomp);
+       return tty_send_config(mtu, accm, pcomp, accomp);
 }
 
 /*
@@ -887,7 +887,7 @@ start_charshunt(ifd, ofd)
 {
     int cpid;
 
-    cpid = fork();
+    cpid = safe_fork();
     if (cpid == -1) {
        error("Can't fork process for character shunt: %m");
        return 0;
@@ -899,7 +899,6 @@ start_charshunt(ifd, ofd)
        if (getuid() != uid)
            fatal("setuid failed");
        setgid(getgid());
-       sys_close();
        if (!nodetach)
            log_to_fd = -1;
        charshunt(ifd, ofd, record_file);