Use the correct buffer when calling dirname, improve an error message, and
[oweals/busybox.git] / nfsmount.c
index 628772b1bdd6b233e5a31675a22191a7eead7878..cd722acc34f2c6eb895e429edc642dca45b3f84c 100644 (file)
  * nfsmount.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp
  */
 
-#include "internal.h"
-#undef FALSE
-#undef TRUE
 #include <unistd.h>
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
 #include <netdb.h>
-#include <rpc/rpc.h>
-#include <rpc/pmap_prot.h>
-#include <rpc/pmap_clnt.h>
 #include <sys/socket.h>
-#include <sys/time.h>
+#include <time.h>
 #include <sys/utsname.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
-
-#include "nfsmount.h"
+#include <stdlib.h>
+#include "busybox.h"
+#undef TRUE
+#undef FALSE
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
 #include <linux/nfs.h>  /* For the kernels nfs stuff */
+#include "nfsmount.h"
 
+#ifndef NFS_FHSIZE
+static const int NFS_FHSIZE = 32;
+#endif
+#ifndef NFS_PORT
+static const int NFS_PORT = 2049;
+#endif
 
 /* Disable the nls stuff */
 # undef bindtextdomain
 # define _(Text) (Text)
 # define N_(Text) (Text)
 
-#define MS_MGC_VAL             0xc0ed0000 /* Magic number indicatng "new" flags */
-#define MS_RDONLY        1      /* Mount read-only */
-#define MS_NOSUID        2      /* Ignore suid and sgid bits */
-#define MS_NODEV         4      /* Disallow access to device special files */
-#define MS_NOEXEC        8      /* Disallow program execution */
-#define MS_SYNCHRONOUS  16      /* Writes are synced at once */
-#define MS_REMOUNT      32      /* Alter flags of a mounted FS */
-#define MS_MANDLOCK     64      /* Allow mandatory locks on an FS */
-#define S_QUOTA         128     /* Quota initialized for file/directory/symlink */
-#define S_APPEND        256     /* Append-only file */
-#define S_IMMUTABLE     512     /* Immutable file */
-#define MS_NOATIME      1024    /* Do not update access times. */
-#define MS_NODIRATIME   2048    /* Do not update directory access times */
+static const int MS_MGC_VAL = 0xc0ed0000; /* Magic number indicatng "new" flags */
+static const int MS_RDONLY = 1;      /* Mount read-only */
+static const int MS_NOSUID = 2;      /* Ignore suid and sgid bits */
+static const int MS_NODEV = 4;      /* Disallow access to device special files */
+static const int MS_NOEXEC = 8;      /* Disallow program execution */
+static const int MS_SYNCHRONOUS = 16;      /* Writes are synced at once */
+static const int MS_REMOUNT = 32;      /* Alter flags of a mounted FS */
+static const int MS_MANDLOCK = 64;      /* Allow mandatory locks on an FS */
+static const int S_QUOTA = 128;     /* Quota initialized for file/directory/symlink */
+static const int S_APPEND = 256;     /* Append-only file */
+static const int S_IMMUTABLE = 512;     /* Immutable file */
+static const int MS_NOATIME = 1024;    /* Do not update access times. */
+static const int MS_NODIRATIME = 2048;    /* Do not update directory access times */
 
 
 /*
@@ -87,7 +93,9 @@
  * so it is easiest to ignore the kernel altogether (at compile time).
  */
 
-#define NFS_MOUNT_VERSION      4
+/* NOTE: Do not make this into a 'static const int' because the pre-processor
+ * needs to test this value in some #if statements. */
+#define NFS_MOUNT_VERSION 4
 
 struct nfs2_fh {
         char                    data[32];
@@ -119,16 +127,16 @@ struct nfs_mount_data {
 
 /* bits in the flags field */
 
-#define NFS_MOUNT_SOFT         0x0001  /* 1 */
-#define NFS_MOUNT_INTR         0x0002  /* 1 */
-#define NFS_MOUNT_SECURE       0x0004  /* 1 */
-#define NFS_MOUNT_POSIX                0x0008  /* 1 */
-#define NFS_MOUNT_NOCTO                0x0010  /* 1 */
-#define NFS_MOUNT_NOAC         0x0020  /* 1 */
-#define NFS_MOUNT_TCP          0x0040  /* 2 */
-#define NFS_MOUNT_VER3         0x0080  /* 3 */
-#define NFS_MOUNT_KERBEROS     0x0100  /* 3 */
-#define NFS_MOUNT_NONLM                0x0200  /* 3 */
+static const int NFS_MOUNT_SOFT = 0x0001;      /* 1 */
+static const int NFS_MOUNT_INTR = 0x0002;      /* 1 */
+static const int NFS_MOUNT_SECURE = 0x0004;    /* 1 */
+static const int NFS_MOUNT_POSIX = 0x0008;     /* 1 */
+static const int NFS_MOUNT_NOCTO = 0x0010;     /* 1 */
+static const int NFS_MOUNT_NOAC = 0x0020;      /* 1 */
+static const int NFS_MOUNT_TCP = 0x0040;       /* 2 */
+static const int NFS_MOUNT_VER3 = 0x0080;      /* 3 */
+static const int NFS_MOUNT_KERBEROS = 0x0100;  /* 3 */
+static const int NFS_MOUNT_NONLM = 0x0200;     /* 3 */
 
 
 #define UTIL_LINUX_VERSION "2.10m"
@@ -149,35 +157,19 @@ struct nfs_mount_data {
 #define HAVE_personality
 #define HAVE_tm_gmtoff
 
-extern char *xstrdup (const char *s);
-extern char *xstrndup (const char *s, int n);
-static char *nfs_strerror(int stat);
+static char *nfs_strerror(int status);
 
 #define MAKE_VERSION(p,q,r)    (65536*(p) + 256*(q) + (r))
 #define MAX_NFSPROT ((nfs_mount_version >= 4) ? 3 : 2)
 
-#define EX_FAIL                        32       /* mount failure */
-#define EX_BG                  256       /* retry in background (internal only) */
+static const int EX_FAIL = 32;       /* mount failure */
+static const int EX_BG = 256;       /* retry in background (internal only) */
 
 
-static int
-linux_version_code(void) {
-       struct utsname my_utsname;
-       int p, q, r;
-
-       if (uname(&my_utsname) == 0) {
-               p = atoi(strtok(my_utsname.release, "."));
-               q = atoi(strtok(NULL, "."));
-               r = atoi(strtok(NULL, "."));
-               return MAKE_VERSION(p,q,r);
-       }
-       return 0;
-}
-
 /*
  * nfs_mount_version according to the sources seen at compile time.
  */
-int nfs_mount_version = NFS_MOUNT_VERSION;
+static int nfs_mount_version;
 
 /*
  * Unfortunately, the kernel prints annoying console messages
@@ -191,24 +183,28 @@ int nfs_mount_version = NFS_MOUNT_VERSION;
  *     nfs_mount_version: version this source and running kernel can handle
  */
 static void
-find_kernel_nfs_mount_version(void) {
+find_kernel_nfs_mount_version(void)
+{
        static int kernel_version = 0;
 
        if (kernel_version)
                return;
 
-       kernel_version = linux_version_code();
+       nfs_mount_version = NFS_MOUNT_VERSION; /* default */
 
+       kernel_version = get_kernel_revision();
        if (kernel_version) {
-            if (kernel_version < MAKE_VERSION(2,1,32))
-                 nfs_mount_version = 1;
-            else if (kernel_version < MAKE_VERSION(2,3,99))
-                 nfs_mount_version = 3;
-            else
-                 nfs_mount_version = 4; /* since 2.3.99pre4 */
+               if (kernel_version < MAKE_VERSION(2,1,32))
+                       nfs_mount_version = 1;
+               else if (kernel_version < MAKE_VERSION(2,2,18) ||
+                               (kernel_version >=   MAKE_VERSION(2,3,0) &&
+                                kernel_version < MAKE_VERSION(2,3,99)))
+                       nfs_mount_version = 3;
+               else
+                       nfs_mount_version = 4; /* since 2.3.99pre4 */
        }
        if (nfs_mount_version > NFS_MOUNT_VERSION)
-            nfs_mount_version = NFS_MOUNT_VERSION;
+               nfs_mount_version = NFS_MOUNT_VERSION;
 }
 
 static struct pmap *
@@ -266,7 +262,7 @@ int nfsmount(const char *spec, const char *node, int *flags,
        char hostdir[1024];
        CLIENT *mclient;
        char *hostname;
-       char *dirname;
+       char *pathname;
        char *old_opts;
        char *mounthost=NULL;
        char new_opts[1024];
@@ -314,22 +310,22 @@ int nfsmount(const char *spec, const char *node, int *flags,
        msock = fsock = -1;
        mclient = NULL;
        if (strlen(spec) >= sizeof(hostdir)) {
-               errorMsg("excessively long host:dir argument\n");
+               error_msg("excessively long host:dir argument");
                goto fail;
        }
        strcpy(hostdir, spec);
        if ((s = strchr(hostdir, ':'))) {
                hostname = hostdir;
-               dirname = s + 1;
+               pathname = s + 1;
                *s = '\0';
                /* Ignore all but first hostname in replicated mounts
                   until they can be fully supported. (mack@sgi.com) */
                if ((s = strchr(hostdir, ','))) {
                        *s = '\0';
-                       errorMsg("warning: multiple hostnames not supported\n");
+                       error_msg("warning: multiple hostnames not supported");
                }
        } else {
-               errorMsg("directory to mount not in host:dir format\n");
+               error_msg("directory to mount not in host:dir format");
                goto fail;
        }
 
@@ -339,11 +335,11 @@ int nfsmount(const char *spec, const char *node, int *flags,
 #endif
        {
                if ((hp = gethostbyname(hostname)) == NULL) {
-                       errorMsg("can't get address for %s\n", hostname);
+                       herror_msg("%s", hostname);
                        goto fail;
                } else {
                        if (hp->h_length > sizeof(struct in_addr)) {
-                               errorMsg("got bad hp->h_length\n");
+                               error_msg("got bad hp->h_length");
                                hp->h_length = sizeof(struct in_addr);
                        }
                        memcpy(&server_addr.sin_addr,
@@ -360,7 +356,7 @@ int nfsmount(const char *spec, const char *node, int *flags,
        if (!old_opts)
                old_opts = "";
        if (strlen(old_opts) + strlen(s) + 10 >= sizeof(new_opts)) {
-               errorMsg("excessively long option argument\n");
+               error_msg("excessively long option argument");
                goto fail;
        }
        sprintf(new_opts, "%s%saddr=%s",
@@ -520,11 +516,11 @@ int nfsmount(const char *spec, const char *node, int *flags,
                data.flags |= (nolock ? NFS_MOUNT_NONLM : 0);
 #endif
        if (nfsvers > MAX_NFSPROT) {
-               errorMsg("NFSv%d not supported!\n", nfsvers);
+               error_msg("NFSv%d not supported!", nfsvers);
                return 0;
        }
        if (mountvers > MAX_NFSPROT) {
-               errorMsg("NFSv%d not supported!\n", nfsvers);
+               error_msg("NFSv%d not supported!", nfsvers);
                return 0;
        }
        if (nfsvers && !mountvers)
@@ -584,11 +580,11 @@ int nfsmount(const char *spec, const char *node, int *flags,
            mount_server_addr.sin_addr.s_addr = inet_addr(hostname);
          } else {
                  if ((hp = gethostbyname(mounthost)) == NULL) {
-                         errorMsg("can't get address for %s\n", hostname);
+                         herror_msg("%s", mounthost);
                          goto fail;
                  } else {
                          if (hp->h_length > sizeof(struct in_addr)) {
-                                 errorMsg("got bad hp->h_length?\n");
+                                 error_msg("got bad hp->h_length?");
                                  hp->h_length = sizeof(struct in_addr);
                          }
                          mount_server_addr.sin_family = AF_INET;
@@ -666,7 +662,7 @@ int nfsmount(const char *spec, const char *node, int *flags,
                        mclient = 0;
                        }
                        if (mclient) {
-                               /* try to mount hostname:dirname */
+                               /* try to mount hostname:pathname */
                                mclient->cl_auth = authunix_create_default();
 
                        /* make pointers in xdr_mountres3 NULL so
@@ -677,14 +673,14 @@ int nfsmount(const char *spec, const char *node, int *flags,
                        if (pm_mnt->pm_vers == 3)
                                clnt_stat = clnt_call(mclient, MOUNTPROC3_MNT,
                                                      (xdrproc_t) xdr_dirpath,
-                                                     (caddr_t) &dirname,
+                                                     (caddr_t) &pathname,
                                                      (xdrproc_t) xdr_mountres3,
                                                      (caddr_t) &status,
                                        total_timeout);
                        else
                                clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
                                                      (xdrproc_t) xdr_dirpath,
-                                                     (caddr_t) &dirname,
+                                                     (caddr_t) &pathname,
                                                      (xdrproc_t) xdr_fhstatus,
                                                      (caddr_t) &status,
                                                      total_timeout);
@@ -723,8 +719,8 @@ int nfsmount(const char *spec, const char *node, int *flags,
 
        if (nfsvers == 2) {
                if (status.nfsv2.fhs_status != 0) {
-                       errorMsg("%s:%s failed, reason given by server: %s\n",
-                               hostname, dirname,
+                       error_msg("%s:%s failed, reason given by server: %s",
+                               hostname, pathname,
                                nfs_strerror(status.nfsv2.fhs_status));
                        goto fail;
                }
@@ -739,20 +735,20 @@ int nfsmount(const char *spec, const char *node, int *flags,
 #endif
        } else {
 #if NFS_MOUNT_VERSION >= 4
-               fhandle3 *fhandle;
+               fhandle3 *my_fhandle;
                if (status.nfsv3.fhs_status != 0) {
-                       errorMsg("%s:%s failed, reason given by server: %s\n",
-                               hostname, dirname,
+                       error_msg("%s:%s failed, reason given by server: %s",
+                               hostname, pathname,
                                nfs_strerror(status.nfsv3.fhs_status));
                        goto fail;
                }
-               fhandle = &status.nfsv3.mountres3_u.mountinfo.fhandle;
+               my_fhandle = &status.nfsv3.mountres3_u.mountinfo.fhandle;
                memset(data.old_root.data, 0, NFS_FHSIZE);
                memset(&data.root, 0, sizeof(data.root));
-               data.root.size = fhandle->fhandle3_len;
+               data.root.size = my_fhandle->fhandle3_len;
                memcpy(data.root.data,
-                      (char *) fhandle->fhandle3_val,
-                      fhandle->fhandle3_len);
+                      (char *) my_fhandle->fhandle3_val,
+                      my_fhandle->fhandle3_len);
 
                data.flags |= NFS_MOUNT_VER3;
 #endif
@@ -796,7 +792,7 @@ int nfsmount(const char *spec, const char *node, int *flags,
          * to avoid problems with multihomed hosts.
          * --Swen
          */
-       if (linux_version_code() <= 66314
+       if (get_kernel_revision() <= 66314
            && connect(fsock, (struct sockaddr *) &server_addr,
                       sizeof (server_addr)) < 0) {
                perror(_("nfs connect"));
@@ -877,20 +873,20 @@ static struct {
        { -1,                   EIO             }
 };
 
-static char *nfs_strerror(int stat)
+static char *nfs_strerror(int status)
 {
        int i;
        static char buf[256];
 
        for (i = 0; nfs_errtbl[i].stat != -1; i++) {
-               if (nfs_errtbl[i].stat == stat)
+               if (nfs_errtbl[i].stat == status)
                        return strerror(nfs_errtbl[i].errnum);
        }
-       sprintf(buf, _("unknown nfs status return value: %d"), stat);
+       sprintf(buf, _("unknown nfs status return value: %d"), status);
        return buf;
 }
 
-bool_t
+static bool_t
 xdr_fhandle (XDR *xdrs, fhandle objp)
 {
        //register int32_t *buf;