Added -vjccid and vj-max-slots options, and reorganized in
[ppp.git] / pppd / sys-svr4.c
index 68e38cda5d757ab8b2d2f46d97da39e9ae8036f8..cff5851d5f0ae77c9c5cadedb8cf8d16489c8f73 100644 (file)
@@ -26,7 +26,7 @@
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: sys-svr4.c,v 1.2 1995/06/01 01:31:28 paulus Exp $";
+static char rcsid[] = "$Id: sys-svr4.c,v 1.6 1995/08/16 01:40:51 paulus Exp $";
 #endif
 
 #include <stdio.h>
@@ -37,6 +37,8 @@ static char rcsid[] = "$Id: sys-svr4.c,v 1.2 1995/06/01 01:31:28 paulus Exp $";
 #include <fcntl.h>
 #include <unistd.h>
 #include <termios.h>
+#include <signal.h>
+#include <utmpx.h>
 #include <sys/types.h>
 #include <sys/ioccom.h>
 #include <sys/stream.h>
@@ -47,6 +49,7 @@ static char rcsid[] = "$Id: sys-svr4.c,v 1.2 1995/06/01 01:31:28 paulus Exp $";
 #include <sys/systeminfo.h>
 #include <sys/dlpi.h>
 #include <sys/stat.h>
+#include <sys/mkdev.h>
 #include <net/if.h>
 #include <net/if_arp.h>
 #include <net/route.h>
@@ -63,6 +66,8 @@ static int    ipmuxid = -1;
 
 static int     restore_term;
 static struct termios inittermios;
+static struct winsize wsinfo;  /* Initial window size info */
+static pid_t   tty_sid;        /* original session ID for terminal */
 
 static int     link_mtu, link_mru;
 
@@ -143,7 +148,10 @@ ppp_available()
 void
 establish_ppp()
 {
-    int i;
+    int i, ifd;
+
+    if (default_device)
+       tty_sid = getsid((pid_t)0);
 
     pppfd = open("/dev/ppp", O_RDWR | O_NONBLOCK, 0);
     if (pppfd < 0) {
@@ -157,6 +165,28 @@ establish_ppp()
        die(1);
     }
 
+    /*
+     * Open the ppp device again and link it under the ip multiplexor.
+     * IP will assign a unit number which hopefully is the same as ifunit.
+     * I don't know any way to be certain they will be the same. :-(
+     */
+    ifd = open("/dev/ppp", O_RDWR, 0);
+    if (ifd < 0) {
+       syslog(LOG_ERR, "Can't open /dev/ppp (2): %m");
+       die(1);
+    }
+    if (ioctl(ifd, I_PUSH, "ip") < 0) {
+       syslog(LOG_ERR, "Can't push IP module: %m");
+       close(ifd);
+       die(1);
+    }
+    ipmuxid = ioctl(ipfd, I_LINK, ifd);
+    close(ifd);
+    if (ipmuxid < 0) {
+       syslog(LOG_ERR, "Can't link PPP device to IP: %m");
+       die(1);
+    }
+
     /* Pop any existing modules off the tty stream. */
     for (i = 0;; ++i)
        if (ioctl(fd, I_LOOK, tty_modules[i]) < 0
@@ -205,6 +235,16 @@ disestablish_ppp()
                    syslog(LOG_ERR, "Couldn't restore tty module %s: %m",
                           tty_modules[i]);
        }
+       if (hungup && default_device && tty_sid > 0) {
+           /*
+            * If we have received a hangup, we need to send a SIGHUP
+            * to the terminal's controlling process.  The reason is
+            * that the original stream head for the terminal hasn't
+            * seen the M_HANGUP message (it went up through the ppp
+            * driver to the stream head for our fd to /dev/ppp).
+            */
+           kill(tty_sid, SIGHUP);
+       }
     }
 }
 
@@ -334,8 +374,10 @@ set_up_tty(fd, local)
        die(1);
     }
 
-    if (!restore_term)
+    if (!restore_term) {
        inittermios = tios;
+       ioctl(fd, TIOCGWINSZ, &wsinfo);
+    }
 
     tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
     if (crtscts > 0)
@@ -403,6 +445,7 @@ restore_tty()
        if (tcsetattr(fd, TCSAFLUSH, &inittermios) < 0)
            if (!hungup && errno != ENXIO)
                syslog(LOG_WARNING, "tcsetattr: %m");
+       ioctl(fd, TIOCSWINSZ, &wsinfo);
        restore_term = 0;
     }
 }
@@ -659,10 +702,6 @@ sifup(u)
 {
     struct ifreq ifr;
 
-    if (ipmuxid < 0) {
-       syslog(LOG_DEBUG, "sifup: not plumbed!");
-       return 0;
-    }
     strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
     if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) < 0) {
        syslog(LOG_ERR, "Couldn't mark interface up (get): %m");
@@ -710,26 +749,8 @@ sifaddr(u, o, h, m)
     int u;
     u_int32_t o, h, m;
 {
-    int fd;
     struct ifreq ifr;
 
-    fd = open("/dev/ppp", O_RDWR, 0);
-    if (fd < 0) {
-       syslog(LOG_ERR, "Can't open /dev/ppp (2): %m");
-       die(1);
-    }
-    if (ioctl(fd, I_PUSH, "ip") < 0) {
-       syslog(LOG_ERR, "Can't push IP module: %m");
-       close(fd);
-       return 0;
-    }
-    ipmuxid = ioctl(ipfd, I_LINK, fd);
-    close(fd);
-    if (ipmuxid < 0) {
-       syslog(LOG_ERR, "Can't link PPP device to IP: %m");
-       return 0;
-    }
-
     memset(&ifr, 0, sizeof(ifr));
     strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
     ifr.ifr_addr.sa_family = AF_INET;
@@ -764,6 +785,7 @@ cifaddr(u, o, h)
     int u;
     u_int32_t o, h;
 {
+#if 0
     if (ipmuxid >= 0) {
        if (ioctl(ipfd, I_UNLINK, ipmuxid) < 0) {
            syslog(LOG_ERR, "Can't remove ppp interface unit: %m");
@@ -771,6 +793,7 @@ cifaddr(u, o, h)
        }
        ipmuxid = -1;
     }
+#endif
     return 1;
 }
 
@@ -1146,6 +1169,21 @@ int
 logwtmp(line, name, host)
     char *line, *name, *host;
 {
+    static struct utmpx utmpx;
+
+    if (name[0] != 0) {
+       /* logging in */
+       strncpy(utmpx.ut_user, name, sizeof(utmpx.ut_user));
+       strncpy(utmpx.ut_id, ifname, sizeof(utmpx.ut_id));
+       strncpy(utmpx.ut_line, line, sizeof(utmpx.ut_line));
+       utmpx.ut_pid = getpid();
+       utmpx.ut_type = USER_PROCESS;
+    } else {
+       utmpx.ut_type = DEAD_PROCESS;
+    }
+    gettimeofday(&utmpx.ut_tv, NULL);
+    updwtmpx("/var/adm/wtmpx", &utmpx);
+    return 0;
 }
 
 /*
@@ -1160,7 +1198,7 @@ gethostid()
        syslog(LOG_ERR, "sysinfo: %m");
        return 0;
     }
-    return strtol(buf, NULL, 16);
+    return (int) strtoul(buf, NULL, 16);
 }
 
 int
@@ -1182,15 +1220,80 @@ strioctl(fd, cmd, ptr, ilen, olen)
     return 0;
 }
 
+/*
+ * lock - create a lock file for the named lock device
+ *
+ * XXX Does anybody know what the "032" in the lock file name means?
+ */
+
+#define LOCK_PREFIX    "/var/spool/locks/LK.032."
+static char lock_file[40];     /* name of lock file created */
+
 int
 lock(dev)
     char *dev;
 {
+    int n, fd, pid;
+    struct stat sbuf;
+    char ascii_pid[12];
+
+    if (stat(dev, &sbuf) < 0) {
+       syslog(LOG_ERR, "Can't get device number for %s: %m", dev);
+       return -1;
+    }
+    if ((sbuf.st_mode & S_IFMT) != S_IFCHR) {
+       syslog(LOG_ERR, "Can't lock %s: not a character device", dev);
+       return -1;
+    }
+    sprintf(lock_file, "%s%03d.%03d", LOCK_PREFIX, major(sbuf.st_rdev),
+           minor(sbuf.st_rdev));
+
+    while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {
+       if (errno == EEXIST
+           && (fd = open(lock_file, O_RDONLY, 0)) >= 0) {
+           /* Read the lock file to find out who has the device locked */
+           n = read(fd, ascii_pid, 11);
+           if (n <= 0) {
+               syslog(LOG_ERR, "Can't read pid from lock file %s", lock_file);
+               close(fd);
+           } else {
+               ascii_pid[n] = 0;
+               pid = atoi(ascii_pid);
+               if (pid > 0 && kill(pid, 0) == -1 && errno == ESRCH) {
+                   /* pid no longer exists - remove the lock file */
+                   if (unlink(lock_file) == 0) {
+                       close(fd);
+                       syslog(LOG_NOTICE, "Removed stale lock on %s (pid %d)",
+                              dev, pid);
+                       continue;
+                   } else
+                       syslog(LOG_WARNING, "Couldn't remove stale lock on %s",
+                              dev);
+               } else
+                   syslog(LOG_NOTICE, "Device %s is locked by pid %d",
+                          dev, pid);
+           }
+           close(fd);
+       } else
+           syslog(LOG_ERR, "Can't create lock file %s: %m", lock_file);
+       lock_file[0] = 0;
+       return -1;
+    }
+
+    sprintf(ascii_pid, "%10d\n", getpid());
+    write(fd, ascii_pid, 11);
+
+    close(fd);
     return 1;
 }
 
-int
+/*
+ * unlock - remove our lockfile
+ */
 unlock()
 {
-    return 1;
+    if (lock_file[0]) {
+       unlink(lock_file);
+       lock_file[0] = 0;
+    }
 }