]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/tty.c
Remove the requirement that redistributions in binary form reproduce
[ppp.git] / pppd / tty.c
index 803d8ba02edecad13d30d4cc38517d7731b4f56a..5d65cd2765a485f43a07a3d99dcef81b47ddc851 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * tty.c - code for handling serial ports in pppd.
  *
- * Copyright (C) 2000-2002 Paul Mackerras. All rights reserved.
+ * Copyright (C) 2000-2004 Paul Mackerras. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The name(s) of the authors of this software must not be used to
+ * 2. The name(s) of the authors of this software must not be used to
  *    endorse or promote products derived from this software without
  *    prior written permission.
  *
- * 4. Redistributions of any form whatsoever must retain the following
+ * 3. Redistributions of any form whatsoever must retain the following
  *    acknowledgment:
  *    "This product includes software developed by Paul Mackerras
  *     <paulus@samba.org>".
@@ -73,7 +68,7 @@
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define RCSID  "$Id: tty.c,v 1.8 2002/12/04 23:03:33 paulus Exp $"
+#define RCSID  "$Id: tty.c,v 1.18 2004/11/04 10:02:26 paulus Exp $"
 
 #include <stdio.h>
 #include <ctype.h>
@@ -300,7 +295,7 @@ setdevname(cp, argv, doit)
        if (*cp == 0)
                return 0;
 
-       if (strncmp("/dev/", cp, 5) != 0) {
+       if (*cp != '/') {
                strlcpy(dev, "/dev/", sizeof(dev));
                strlcat(dev, cp, sizeof(dev));
                cp = dev;
@@ -459,7 +454,7 @@ tty_check_options()
        if (using_pty) {
                if (!default_device) {
                        option_error("%s option precludes specifying device name",
-                                    notty? "notty": "pty");
+                                    pty_socket? "socket": notty? "notty": "pty");
                        exit(EXIT_OPTION_ERROR);
                }
                if (ptycommand != NULL && notty) {
@@ -512,7 +507,9 @@ int connect_tty()
 {
        char *connector;
        int fdflags;
+#ifndef __linux__
        struct stat statbuf;
+#endif
        char numbuf[16];
 
        /*
@@ -580,6 +577,11 @@ int connect_tty()
                    || fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0)
                        warn("Couldn't reset non-blocking mode on device: %m");
 
+#ifndef __linux__
+               /*
+                * Linux 2.4 and above blocks normal writes to the tty
+                * when it is in PPP line discipline, so this isn't needed.
+                */
                /*
                 * Do the equivalent of `mesg n' to stop broadcast messages.
                 */
@@ -588,6 +590,7 @@ int connect_tty()
                        warn("Couldn't restrict write permissions to %s: %m", devnam);
                } else
                        tty_mode = statbuf.st_mode;
+#endif /* __linux__ */
 
                /*
                 * Set line speed, flow control, etc.
@@ -614,6 +617,11 @@ int connect_tty()
 
                        if (pipe(ipipe) < 0 || pipe(opipe) < 0)
                                fatal("Couldn't create pipes for record option: %m");
+
+                       /* don't leak these to the ptycommand */
+                       (void) fcntl(ipipe[0], F_SETFD, FD_CLOEXEC);
+                       (void) fcntl(opipe[1], F_SETFD, FD_CLOEXEC);
+
                        ok = device_script(ptycommand, opipe[0], ipipe[1], 1) == 0
                                && start_charshunt(ipipe[0], opipe[1]);
                        close(ipipe[0]);
@@ -643,6 +651,9 @@ int connect_tty()
                        return -1;
        }
 
+       if (using_pty || record_file != NULL)
+               ttyfd = pty_slave;
+
        /* run connection script */
        if ((connector && connector[0]) || initializer) {
                if (real_ttyfd != -1) {
@@ -795,12 +806,12 @@ finish_tty()
 
        restore_tty(real_ttyfd);
 
+#ifndef __linux__
        if (tty_mode != (mode_t) -1) {
-               if (fchmod(real_ttyfd, tty_mode) != 0) {
-                       /* XXX if devnam is a symlink, this will change the link */
-                       chmod(devnam, tty_mode);
-               }
+               if (fchmod(real_ttyfd, tty_mode) != 0)
+                       error("Couldn't restore tty permissions");
        }
+#endif /* __linux__ */
 
        close(real_ttyfd);
        real_ttyfd = -1;
@@ -882,7 +893,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;
@@ -894,7 +905,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);
@@ -904,7 +914,6 @@ start_charshunt(ifd, ofd)
     add_notifier(&sigreceived, stop_charshunt, 0);
     close(pty_master);
     pty_master = -1;
-    ttyfd = pty_slave;
     record_child(cpid, "pppd (charshunt)", charshunt_done, NULL);
     return 1;
 }
@@ -992,6 +1001,13 @@ charshunt(ifd, ofd, record_file)
     signal(SIGXFSZ, SIG_DFL);
 #endif
 
+    /*
+     * Check that the fds won't overrun the fd_sets
+     */
+    if (ifd >= FD_SETSIZE || ofd >= FD_SETSIZE || pty_master >= FD_SETSIZE)
+       fatal("internal error: file descriptor too large (%d, %d, %d)",
+             ifd, ofd, pty_master);
+
     /*
      * Open the record file if required.
      */