]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/sys-sunos4.c
use strlcpy, strlcat, slprintf everywhere
[ppp.git] / pppd / sys-sunos4.c
index 730e0a78017e145e0fe18144edb0d1184fa55f94..9e84b7e6260917397951e6ae525476eadccdb812 100644 (file)
@@ -26,7 +26,7 @@
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: sys-sunos4.c,v 1.2 1995/12/19 02:04:40 paulus Exp $";
+static char rcsid[] = "$Id: sys-sunos4.c,v 1.13 1999/03/12 06:07:23 paulus Exp $";
 #endif
 
 #include <stdio.h>
@@ -63,6 +63,9 @@ static char rcsid[] = "$Id: sys-sunos4.c,v 1.2 1995/12/19 02:04:40 paulus Exp $"
 
 #if defined(sun) && defined(sparc)
 #include <alloca.h>
+#ifndef __GNUC__
+extern void *alloca();
+#endif
 #endif /*sparc*/
 
 static int     pppfd;
@@ -75,6 +78,8 @@ static struct termios inittermios;
 static struct winsize wsinfo;  /* Initial window size info */
 static pid_t   parent_pid;     /* PID of our parent */
 
+extern u_char  inpacket_buf[]; /* borrowed from main.c */
+
 static int     link_mtu, link_mru;
 
 #define NMODULES       32
@@ -82,6 +87,7 @@ static int    tty_nmodules;
 static char    tty_modules[NMODULES][FMNAMESZ+1];
 
 static int     if_is_up;       /* Interface has been marked up */
+static u_int32_t ifaddrs[2];   /* local and remote addresses */
 static u_int32_t default_route_gateway;        /* Gateway for default route added */
 static u_int32_t proxy_arp_addr;       /* Addr for proxy arp entry added */
 
@@ -98,10 +104,7 @@ static int strioctl __P((int, int, void *, int, int));
 void
 sys_init()
 {
-    openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
-    setlogmask(LOG_UPTO(LOG_INFO));
-    if (debug)
-       setlogmask(LOG_UPTO(LOG_DEBUG));
+    int x;
 
     /* Get an internet socket for doing socket ioctl's on. */
     if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
@@ -116,26 +119,100 @@ sys_init()
      * parent process.
      */
     parent_pid = getppid();
+
+    /*
+     * Open the ppp device.
+     */
+    pppfd = open("/dev/ppp", O_RDWR | O_NONBLOCK, 0);
+    if (pppfd < 0) {
+       syslog(LOG_ERR, "Can't open /dev/ppp: %m");
+       die(1);
+    }
+    if (kdebugflag) {
+       x = PPPDBG_LOG + PPPDBG_DRIVER;
+       strioctl(pppfd, PPPIO_DEBUG, &x, sizeof(int), 0);
+    }
+
+    /* Assign a new PPA and get its unit number. */
+    if (strioctl(pppfd, PPPIO_NEWPPA, &ifunit, 0, sizeof(int)) < 0) {
+       syslog(LOG_ERR, "Can't create new PPP interface: %m");
+       die(1);
+    }
+
+    /*
+     * Open the ppp device again and push the if_ppp module on it.
+     */
+    iffd = open("/dev/ppp", O_RDWR, 0);
+    if (iffd < 0) {
+       syslog(LOG_ERR, "Can't open /dev/ppp (2): %m");
+       die(1);
+    }
+    if (kdebugflag) {
+       x = PPPDBG_LOG + PPPDBG_DRIVER;
+       strioctl(iffd, PPPIO_DEBUG, &x, sizeof(int), 0);
+    }
+    if (strioctl(iffd, PPPIO_ATTACH, &ifunit, sizeof(int), 0) < 0) {
+       syslog(LOG_ERR, "Couldn't attach ppp interface to device: %m");
+       die(1);
+    }
+    if (ioctl(iffd, I_PUSH, "if_ppp") < 0) {
+       syslog(LOG_ERR, "Can't push ppp interface module: %m");
+       die(1);
+    }
+    if (kdebugflag) {
+       x = PPPDBG_LOG + PPPDBG_IF;
+       strioctl(iffd, PPPIO_DEBUG, &x, sizeof(int), 0);
+    }
+    if (strioctl(iffd, PPPIO_NEWPPA, &ifunit, sizeof(int), 0) < 0) {
+       syslog(LOG_ERR, "Couldn't create ppp interface unit: %m");
+       die(1);
+    }
+    x = PPP_IP;
+    if (strioctl(iffd, PPPIO_BIND, &x, sizeof(int), 0) < 0) {
+       syslog(LOG_ERR, "Couldn't bind ppp interface to IP SAP: %m");
+       die(1);
+    }
 }
 
 /*
  * sys_cleanup - restore any system state we modified before exiting:
  * mark the interface down, delete default route and/or proxy arp entry.
- * This should call die() because it's called from die().
+ * This shouldn't call die() because it's called from die().
  */
 void
 sys_cleanup()
 {
-    struct ifreq ifr;
-
     if (if_is_up)
        sifdown(0);
+    if (ifaddrs[0])
+       cifaddr(0, ifaddrs[0], ifaddrs[1]);
     if (default_route_gateway)
-       cifdefaultroute(0, default_route_gateway);
+       cifdefaultroute(0, 0, default_route_gateway);
     if (proxy_arp_addr)
        cifproxyarp(0, proxy_arp_addr);
 }
 
+/*
+ * sys_close - Clean up in a child process before execing.
+ */
+void
+sys_close()
+{
+    close(iffd);
+    close(pppfd);
+    close(sockfd);
+}
+
+/*
+ * sys_check_options - check the options that the user specified
+ */
+int
+sys_check_options()
+{
+    return 1;
+}
+
+
 /*
  * daemon - Detach us from controlling terminal session.
  */
@@ -160,20 +237,6 @@ daemon(nochdir, noclose)
     return 0;
 }
 
-/*
- * note_debug_level - note a change in the debug level.
- */
-void
-note_debug_level()
-{
-    if (debug) {
-       syslog(LOG_INFO, "Debug turned ON, Level %d", debug);
-       setlogmask(LOG_UPTO(LOG_DEBUG));
-    } else {
-       setlogmask(LOG_UPTO(LOG_WARNING));
-    }
-}
-
 /*
  * ppp_available - check whether the system has any ppp interfaces
  */
@@ -189,60 +252,10 @@ ppp_available()
  * establish_ppp - Turn the serial port into a ppp interface.
  */
 void
-establish_ppp()
+establish_ppp(fd)
+    int fd;
 {
-    int i, x;
-    struct ifreq ifr;
-
-    pppfd = open("/dev/ppp", O_RDWR | O_NONBLOCK, 0);
-    if (pppfd < 0) {
-       syslog(LOG_ERR, "Can't open /dev/ppp: %m");
-       die(1);
-    }
-    if (kdebugflag) {
-       x = PPPDBG_LOG + PPPDBG_DRIVER;
-       strioctl(pppfd, PPPIO_DEBUG, &x, sizeof(int), 0);
-    }
-
-    /* Assign a new PPA and get its unit number. */
-    if (strioctl(pppfd, PPPIO_NEWPPA, &ifunit, 0, sizeof(int)) < 0) {
-       syslog(LOG_ERR, "Can't create new PPP interface: %m");
-       die(1);
-    }
-
-    /*
-     * Open the ppp device again and push the if_ppp module on it.
-     */
-    iffd = open("/dev/ppp", O_RDWR, 0);
-    if (iffd < 0) {
-       syslog(LOG_ERR, "Can't open /dev/ppp (2): %m");
-       die(1);
-    }
-    if (kdebugflag) {
-       x = PPPDBG_LOG + PPPDBG_DRIVER;
-       strioctl(iffd, PPPIO_DEBUG, &x, sizeof(int), 0);
-    }
-    if (strioctl(iffd, PPPIO_ATTACH, &ifunit, sizeof(int), 0) < 0) {
-       syslog(LOG_ERR, "Couldn't attach ppp interface to device: %m");
-       die(1);
-    }
-    if (ioctl(iffd, I_PUSH, "if_ppp") < 0) {
-       syslog(LOG_ERR, "Can't push ppp interface module: %m");
-       die(1);
-    }
-    if (kdebugflag) {
-       x = PPPDBG_LOG + PPPDBG_IF;
-       strioctl(iffd, PPPIO_DEBUG, &x, sizeof(int), 0);
-    }
-    if (strioctl(iffd, PPPIO_NEWPPA, &ifunit, sizeof(int), 0) < 0) {
-       syslog(LOG_ERR, "Couldn't create ppp interface unit: %m");
-       die(1);
-    }
-    x = PPP_IP;
-    if (strioctl(iffd, PPPIO_BIND, &x, sizeof(int), 0) < 0) {
-       syslog(LOG_ERR, "Couldn't bind ppp interface to IP SAP: %m");
-       die(1);
-    }
+    int i;
 
     /* Pop any existing modules off the tty stream. */
     for (i = 0;; ++i)
@@ -266,21 +279,25 @@ establish_ppp()
        syslog(LOG_ERR, "Can't link tty to PPP mux: %m");
        die(1);
     }
+}
 
-    do {
-       char buf[PPP_MRU];
-
-       i = read(fd, buf, PPP_MRU);
-       syslog(LOG_DEBUG, "read %d bytes from fd", i);
-    } while (i > 0);
+/*
+ * restore_loop - reattach the ppp unit to the loopback.
+ * This doesn't need to do anything because disestablish_ppp does it.
+ */
+void
+restore_loop()
+{
 }
 
 /*
  * disestablish_ppp - Restore the serial port to normal operation.
- * This shouldn't call die() because it's called from die().
+ * It attempts to reconstruct the stream with the previously popped
+ * modules.  This shouldn't call die() because it's called from die().
  */
 void
-disestablish_ppp()
+disestablish_ppp(fd)
+    int fd;
 {
     int i;
 
@@ -314,6 +331,38 @@ disestablish_ppp()
     }
 }
 
+/*
+ * Check whether the link seems not to be 8-bit clean.
+ */
+void
+clean_check()
+{
+    int x;
+    char *s;
+
+    if (strioctl(pppfd, PPPIO_GCLEAN, &x, 0, sizeof(x)) < 0)
+       return;
+    s = NULL;
+    switch (~x) {
+    case RCV_B7_0:
+       s = "bit 7 set to 1";
+       break;
+    case RCV_B7_1:
+       s = "bit 7 set to 0";
+       break;
+    case RCV_EVNP:
+       s = "odd parity";
+       break;
+    case RCV_ODDP:
+       s = "even parity";
+       break;
+    }
+    if (s != NULL) {
+       syslog(LOG_WARNING, "Serial link is not 8-bit clean:");
+       syslog(LOG_WARNING, "All received characters had %s", s);
+    }
+}
+
 /*
  * List of valid speeds.
  */
@@ -497,7 +546,8 @@ set_up_tty(fd, local)
  * restore_tty - restore the terminal to the saved settings.
  */
 void
-restore_tty()
+restore_tty(fd)
+    int fd;
 {
     if (restore_term) {
        if (!default_device) {
@@ -530,6 +580,16 @@ int fd, on;
     ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits);
 }
 
+/*
+ * open_loopback - open the device we use for getting packets
+ * in demand mode.  Under Solaris 2, we use our existing fd
+ * to the ppp driver.
+ */
+void
+open_ppp_loopback()
+{
+}
+
 /*
  * output - Output PPP packet.
  */
@@ -544,22 +604,24 @@ output(unit, p, len)
     struct pollfd pfd;
 
     if (debug)
-       log_packet(p, len, "sent ");
+       log_packet(p, len, "sent ", LOG_DEBUG);
 
     data.len = len;
     data.buf = (caddr_t) p;
+    retries = 4;
     while (putmsg(pppfd, NULL, &data, 0) < 0) {
        if (--retries < 0 || (errno != EWOULDBLOCK && errno != EAGAIN)) {
            if (errno != ENXIO)
                syslog(LOG_ERR, "Couldn't send packet: %m");
            break;
        }
-       pfd.fd = fd;
+       pfd.fd = pppfd;
        pfd.events = POLLOUT;
        poll(&pfd, 1, 250);     /* wait for up to 0.25 seconds */
     }
 }
 
+
 /*
  * wait_input - wait until there is data available on fd,
  * for the length of time specified by *timo (indefinite
@@ -581,6 +643,36 @@ wait_input(timo)
     }
 }
 
+/*
+ * wait_loop_output - wait until there is data available on the
+ * loopback, for the length of time specified by *timo (indefinite
+ * if timo is NULL).
+ */
+void
+wait_loop_output(timo)
+    struct timeval *timo;
+{
+    wait_input(timo);
+}
+
+/*
+ * wait_time - wait for a given length of time or until a
+ * signal is received.
+ */
+void
+wait_time(timo)
+    struct timeval *timo;
+{
+    int n;
+
+    n = select(0, NULL, NULL, NULL, timo);
+    if (n < 0 && errno != EINTR) {
+       syslog(LOG_ERR, "select: %m");
+       die(1);
+    }
+}
+
+
 /*
  * read_packet - get a PPP packet from the serial device.
  */
@@ -618,6 +710,24 @@ read_packet(buf)
     }
 }
 
+/*
+ * get_loop_output - get outgoing packets from the ppp device,
+ * and detect when we want to bring the real link up.
+ * Return value is 1 if we need to bring up the link, 0 otherwise.
+ */
+int
+get_loop_output()
+{
+    int len;
+    int rv = 0;
+
+    while ((len = read_packet(inpacket_buf)) > 0) {
+       if (loop_frame(inpacket_buf, len))
+           rv = 1;
+    }
+    return rv;
+}
+
 /*
  * ppp_send_config - configure the transmit characteristics of
  * the ppp interface.
@@ -629,6 +739,7 @@ ppp_send_config(unit, mtu, asyncmap, pcomp, accomp)
     int pcomp, accomp;
 {
     int cf[2];
+    struct ifreq ifr;
 
     link_mtu = mtu;
     if (strioctl(pppfd, PPPIO_MTU, &mtu, sizeof(mtu), 0) < 0) {
@@ -644,6 +755,14 @@ ppp_send_config(unit, mtu, asyncmap, pcomp, accomp)
     if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
        syslog(LOG_ERR, "Couldn't set prot/AC compression: %m");
     }
+
+    /* set mtu for ip as well */
+    memset(&ifr, 0, sizeof(ifr));
+    strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
+    ifr.ifr_metric = link_mtu;
+    if (ioctl(sockfd, SIOCSIFMTU, &ifr) < 0) {
+       syslog(LOG_ERR, "Couldn't set IP MTU: %m");
+    }
 }
 
 /*
@@ -720,6 +839,18 @@ ccp_flags_set(unit, isopen, isup)
     }
 }
 
+/*
+ * get_idle_time - return how long the link has been idle.
+ */
+int
+get_idle_time(u, ip)
+    int u;
+    struct ppp_idle *ip;
+{
+    return strioctl(pppfd, PPPIO_GIDLE, ip, 0, sizeof(struct ppp_idle)) >= 0;
+}
+
+
 /*
  * ccp_fatal_error - returns 1 if decompression was disabled as a
  * result of an error detected after decompression of a packet,
@@ -778,7 +909,7 @@ sifup(u)
 {
     struct ifreq ifr;
 
-    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+    strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
     if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
        syslog(LOG_ERR, "Couldn't mark interface up (get): %m");
        return 0;
@@ -801,7 +932,7 @@ sifdown(u)
 {
     struct ifreq ifr;
 
-    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+    strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
     if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
        syslog(LOG_ERR, "Couldn't mark interface down (get): %m");
        return 0;
@@ -817,6 +948,26 @@ sifdown(u)
     return 1;
 }
 
+/*
+ * sifnpmode - Set the mode for handling packets for a given NP.
+ */
+int
+sifnpmode(u, proto, mode)
+    int u;
+    int proto;
+    enum NPmode mode;
+{
+    int npi[2];
+
+    npi[0] = proto;
+    npi[1] = (int) mode;
+    if (strioctl(pppfd, PPPIO_NPMODE, npi, 2 * sizeof(int), 0) < 0) {
+       syslog(LOG_ERR, "ioctl(set NP %d mode to %d): %m", proto, mode);
+       return 0;
+    }
+    return 1;
+}
+
 #define INET_ADDR(x)   (((struct sockaddr_in *) &(x))->sin_addr.s_addr)
 
 /*
@@ -830,7 +981,12 @@ sifaddr(u, o, h, m)
     struct ifreq ifr;
 
     memset(&ifr, 0, sizeof(ifr));
-    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+    strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
+    ifr.ifr_addr.sa_family = AF_INET;
+    INET_ADDR(ifr.ifr_addr) = m;
+    if (ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0) {
+       syslog(LOG_ERR, "Couldn't set IP netmask: %m");
+    }
     ifr.ifr_addr.sa_family = AF_INET;
     INET_ADDR(ifr.ifr_addr) = o;
     if (ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) {
@@ -841,15 +997,14 @@ sifaddr(u, o, h, m)
     if (ioctl(sockfd, SIOCSIFDSTADDR, &ifr) < 0) {
        syslog(LOG_ERR, "Couldn't set remote IP address: %m");
     }
-    ifr.ifr_addr.sa_family = AF_INET;
-    INET_ADDR(ifr.ifr_addr) = m;
-    if (ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0) {
-       syslog(LOG_ERR, "Couldn't set IP netmask: %m");
-    }
+#if 0  /* now done in ppp_send_config */
     ifr.ifr_metric = link_mtu;
     if (ioctl(sockfd, SIOCSIFMTU, &ifr) < 0) {
        syslog(LOG_ERR, "Couldn't set IP MTU: %m");
     }
+#endif
+    ifaddrs[0] = o;
+    ifaddrs[1] = h;
 
     return 1;
 }
@@ -865,12 +1020,15 @@ cifaddr(u, o, h)
 {
     struct rtentry rt;
 
+    bzero(&rt, sizeof(rt));
     rt.rt_dst.sa_family = AF_INET;
     INET_ADDR(rt.rt_dst) = h;
     rt.rt_gateway.sa_family = AF_INET;
     INET_ADDR(rt.rt_gateway) = o;
     rt.rt_flags = RTF_HOST;
-    ioctl(sockfd, SIOCDELRT, &rt);
+    if (ioctl(sockfd, SIOCDELRT, &rt) < 0)
+       syslog(LOG_ERR, "Couldn't delete route through interface: %m");
+    ifaddrs[0] = 0;
     return 1;
 }
 
@@ -878,12 +1036,13 @@ cifaddr(u, o, h)
  * sifdefaultroute - assign a default route through the address given.
  */
 int
-sifdefaultroute(u, g)
+sifdefaultroute(u, l, g)
     int u;
-    u_int32_t g;
+    u_int32_t l, g;
 {
     struct rtentry rt;
 
+    bzero(&rt, sizeof(rt));
     rt.rt_dst.sa_family = AF_INET;
     INET_ADDR(rt.rt_dst) = 0;
     rt.rt_gateway.sa_family = AF_INET;
@@ -903,12 +1062,13 @@ sifdefaultroute(u, g)
  * cifdefaultroute - delete a default route through the address given.
  */
 int
-cifdefaultroute(u, g)
+cifdefaultroute(u, l, g)
     int u;
-    u_int32_t g;
+    u_int32_t l, g;
 {
     struct rtentry rt;
 
+    bzero(&rt, sizeof(rt));
     rt.rt_dst.sa_family = AF_INET;
     INET_ADDR(rt.rt_dst) = 0;
     rt.rt_gateway.sa_family = AF_INET;
@@ -1010,7 +1170,7 @@ get_ether_addr(ipaddr, hwaddr)
              * Check that the interface is up, and not point-to-point
              * or loopback.
              */
-            strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
+            strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name);
             if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0)
                 continue;
             if ((ifreq.ifr_flags &
@@ -1043,7 +1203,7 @@ get_ether_addr(ipaddr, hwaddr)
        syslog(LOG_ERR, "Couldn't open /dev/nit: %m");
        return 0;
     }
-    strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
+    strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name);
     if (ioctl(nit_fd, NIOCBIND, &ifreq) < 0
        || ioctl(nit_fd, SIOCGIFADDR, &ifreq) < 0) {
        syslog(LOG_ERR, "Couldn't get hardware address for %s: %m",
@@ -1058,11 +1218,23 @@ get_ether_addr(ipaddr, hwaddr)
     return 1;
 }
 
+/*
+ * have_route_to - determine if the system has any route to
+ * a given IP address.
+ * For demand mode to work properly, we have to ignore routes
+ * through our own interface.
+ */
+int have_route_to(addr)
+    u_int32_t addr;
+{
+    return -1;
+}
+
 #define        WTMPFILE        "/usr/adm/wtmp"
 
-int
+void
 logwtmp(line, name, host)
-    char *line, *name, *host;
+    const char *line, *name, *host;
 {
     int fd;
     struct stat buf;
@@ -1071,9 +1243,9 @@ logwtmp(line, name, host)
     if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0)
        return;
     if (!fstat(fd, &buf)) {
-       (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
-       (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
-       (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
+       strlcpy(ut.ut_line, sizeof(ut.ut_line), line);
+       strlcpy(ut.ut_name, sizeof(ut.ut_name), name);
+       strlcpy(ut.ut_host, sizeof(ut.ut_host), host);
        (void)time(&ut.ut_time);
        if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp))
            (void)ftruncate(fd, buf.st_size);
@@ -1131,7 +1303,7 @@ GetMask(addr)
        /*
         * Check that the interface is up, and not point-to-point or loopback.
         */
-       strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
+       strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name);
        if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0)
            continue;
        if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK))
@@ -1167,6 +1339,15 @@ strioctl(fd, cmd, ptr, ilen, olen)
     return 0;
 }
 
+/*
+ * Use the hostid as part of the random number seed.
+ */
+int
+get_host_seed()
+{
+    return gethostid();
+}
+
 /*
  * Code for locking/unlocking the serial device.
  * This code is derived from chat.c.
@@ -1197,13 +1378,15 @@ lock(dev)
     char hdb_lock_buffer[12];
     int fd, pid, n;
     char *p;
+    size_t l;
 
     if ((p = strrchr(dev, '/')) != NULL)
        dev = p + 1;
-    lock_file = malloc(strlen(LOCK_PREFIX) + strlen(dev) + 1);
+    l = strlen(LOCK_PREFIX) + strlen(dev) + 1;
+    lock_file = malloc(l);
     if (lock_file == NULL)
        novm("lock file name");
-    strcat(strcpy(lock_file, LOCK_PREFIX), dev);
+    slprintf(lock_file, l, "%s%s", LOCK_PREFIX, dev);
 
     while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {
        if (errno == EEXIST
@@ -1279,3 +1462,21 @@ strtoul(str, ptr, base)
 {
     return (unsigned long) strtol(str, ptr, base);
 }
+
+/*
+ * Or strerror :-(
+ */
+extern char *sys_errlist[];
+extern int sys_nerr;
+
+char *
+strerror(n)
+    int n;
+{
+    static char unknown[32];
+
+    if (n > 0 && n < sys_nerr)
+       return sys_errlist[n];
+    sprintf(unknown, "Error %d", n);
+    return unknown;
+}