]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/sys-linux.c
add stuff to use /dev/ptmx etc.
[ppp.git] / pppd / sys-linux.c
index 94c31ddc441f25b8d45d9052c39297f86fa86fb8..d494c847e4e689eecf32fadb6093e03c1e24804b 100644 (file)
@@ -1024,7 +1024,7 @@ static int read_route_table (struct rtentry *rt);
  * path_to_procfs - find the path to the proc file system mount point
  */
 
-static int path_to_procfs (void)
+static int path_to_procfs (const char *tail)
 {
     struct mntent *mntent;
     FILE *fp;
@@ -1033,6 +1033,7 @@ static int path_to_procfs (void)
     if (fp == NULL) {
        /* Default the mount location of /proc */
        strlcpy (route_buffer, "/proc", sizeof (route_buffer));
+       strlcat (route_buffer, tail, sizeof(route_buffer));
        return 1;
     }
 
@@ -1047,6 +1048,7 @@ static int path_to_procfs (void)
        return 0;
 
     strlcpy(route_buffer, mntent->mnt_dir, sizeof (route_buffer));
+    strlcat (route_buffer, tail, sizeof(route_buffer));
     return 1;
 }
 
@@ -1057,11 +1059,10 @@ static int path_to_procfs (void)
 
 static char *path_to_route (void)
 {
-    if (!path_to_procfs()) {
+    if (!path_to_procfs("/net/route")) {
        error("proc file system not mounted");
        return 0;
     }
-    strlcat (route_buffer, "/net/route", sizeof(route_buffer));
     return (route_buffer);
 }
 
@@ -2116,7 +2117,7 @@ int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
 
 /*
  * get_pty - get a pty master/slave pair and chown the slave side
- * to the uid given.  Assumes slave_name points to >= 12 bytes of space.
+ * to the uid given.  Assumes slave_name points to >= 16 bytes of space.
  */
 int
 get_pty(master_fdp, slave_fdp, slave_name, uid)
@@ -2125,31 +2126,56 @@ get_pty(master_fdp, slave_fdp, slave_name, uid)
     char *slave_name;
     int uid;
 {
-    int i, mfd, sfd;
-    char pty_name[12];
+    int i, mfd, sfd = -1;
+    char pty_name[16];
     struct termios tios;
 
-    sfd = -1;
-    for (i = 0; i < 64; ++i) {
-       slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
-                'p' + i / 16, i % 16);
-       mfd = open(pty_name, O_RDWR, 0);
-       if (mfd >= 0) {
-           pty_name[5] = 't';
-           sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
-           if (sfd >= 0)
-               break;
-           close(mfd);
+#ifdef TIOCGPTN
+    /*
+     * Try the unix98 way first.
+     */
+    mfd = open("/dev/ptmx", O_RDWR);
+    if (mfd >= 0) {
+       int ptn;
+       if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
+           slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
+           chmod(pty_name, S_IRUSR | S_IWUSR);
+#ifdef TIOCSPTLCK
+           ptn = 0;
+           if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
+               warn("Couldn't unlock pty slave %s: %m", pty_name);
+#endif
+           if ((sfd = open(pty_name, O_RDWR)) < 0)
+               warn("Couldn't open pty slave %s: %m", pty_name);
        }
     }
+#endif /* TIOCGPTN */
+
+    if (sfd < 0) {
+       /* the old way - scan through the pty name space */
+       for (i = 0; i < 64; ++i) {
+           slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
+                    'p' + i / 16, i % 16);
+           mfd = open(pty_name, O_RDWR, 0);
+           if (mfd >= 0) {
+               pty_name[5] = 't';
+               sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
+               if (sfd >= 0) {
+                   fchown(sfd, uid, -1);
+                   fchmod(sfd, S_IRUSR | S_IWUSR);
+                   break;
+               }
+               close(mfd);
+           }
+       }
+    }
+
     if (sfd < 0)
        return 0;
 
-    strlcpy(slave_name, pty_name, 12);
+    strlcpy(slave_name, pty_name, 16);
     *master_fdp = mfd;
     *slave_fdp = sfd;
-    fchown(sfd, uid, -1);
-    fchmod(sfd, S_IRUSR | S_IWUSR);
     if (tcgetattr(sfd, &tios) == 0) {
        tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
        tios.c_cflag |= CS8 | CREAD;
@@ -2396,21 +2422,16 @@ int
 sys_check_options(void)
 {
 #ifdef IPX_CHANGE
-    struct stat stat_buf;
 /*
  * Disable the IPX protocol if the support is not present in the kernel.
- * If we disable it then ensure that IP support is enabled.
  */
-    while (ipxcp_protent.enabled_flag) {
-        if (path_to_procfs()) {
-           strlcat (route_buffer, "/net/ipx_interface", sizeof(route_buffer));
-           if (lstat (route_buffer, &stat_buf) >= 0)
-               break;
+    if (ipxcp_protent.enabled_flag) {
+       struct stat stat_buf;
+        if (!path_to_procfs("/net/ipx_interface")
+           || lstat (route_buffer, &stat_buf) < 0) {
+           error("IPX support is not present in the kernel\n");
+           ipxcp_protent.enabled_flag = 0;
        }
-       error("IPX support is not present in the kernel\n");
-       ipxcp_protent.enabled_flag = 0;
-       ipcp_protent.enabled_flag  = 1;
-       break;
     }
 #endif
     if (demand && driver_is_old) {