697 lines
17 KiB
Diff
697 lines
17 KiB
Diff
|
autofs-5.1.4 - add mount.fedfs.c
|
||
|
|
||
|
From: Ian Kent <raven@themaw.net>
|
||
|
|
||
|
Add build and install of the mount.fedfs binary.
|
||
|
|
||
|
Signed-off-by: Ian Kent <raven@themaw.net>
|
||
|
---
|
||
|
CHANGELOG | 1
|
||
|
Makefile | 3
|
||
|
Makefile.rules | 2
|
||
|
autofs.spec | 1
|
||
|
fedfs/Makefile | 36 +++
|
||
|
fedfs/fedfs-gpl-boiler.h | 40 ++++
|
||
|
fedfs/fedfs-nls.h | 38 ++++
|
||
|
fedfs/mount.fedfs.c | 485 ++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
8 files changed, 605 insertions(+), 1 deletion(-)
|
||
|
create mode 100644 fedfs/Makefile
|
||
|
create mode 100644 fedfs/fedfs-gpl-boiler.h
|
||
|
create mode 100644 fedfs/fedfs-nls.h
|
||
|
create mode 100644 fedfs/mount.fedfs.c
|
||
|
|
||
|
diff --git a/CHANGELOG b/CHANGELOG
|
||
|
index 8d6c737c..88992147 100644
|
||
|
--- a/CHANGELOG
|
||
|
+++ b/CHANGELOG
|
||
|
@@ -15,6 +15,7 @@ xx/xx/2018 autofs-5.1.5
|
||
|
- dont allow trailing slash in master map mount points.
|
||
|
- fix libresolv configure check.
|
||
|
- add fedfs-getsrvinfo.c.
|
||
|
+- add mount.fedfs.c.
|
||
|
|
||
|
19/12/2017 autofs-5.1.4
|
||
|
- fix spec file url.
|
||
|
diff --git a/Makefile b/Makefile
|
||
|
index e560a7cb..99db2c75 100644
|
||
|
--- a/Makefile
|
||
|
+++ b/Makefile
|
||
|
@@ -19,6 +19,9 @@ kernel:
|
||
|
samples:
|
||
|
set -e; if [ -d samples ]; then $(MAKE) -C samples all; fi
|
||
|
|
||
|
+fedfs:
|
||
|
+ set -e; if [ -d fedfs ]; then $(MAKE) -C fedfs all; fi
|
||
|
+
|
||
|
clean:
|
||
|
for i in $(SUBDIRS) samples; do \
|
||
|
if [ -d $$i ]; then $(MAKE) -C $$i clean; fi; done
|
||
|
diff --git a/Makefile.rules b/Makefile.rules
|
||
|
index 4deab3b9..fc9f6019 100644
|
||
|
--- a/Makefile.rules
|
||
|
+++ b/Makefile.rules
|
||
|
@@ -3,7 +3,7 @@
|
||
|
#
|
||
|
|
||
|
# Root directory contents
|
||
|
-SUBDIRS = lib daemon modules man
|
||
|
+SUBDIRS = lib daemon fedfs modules man
|
||
|
INCDIRS = include
|
||
|
INCFILES = COPYING COPYRIGHT NEWS README* TODO Makefile Makefile.rules \
|
||
|
Makefile.conf.in .version .autofs-* configure.in aclocal.m4 \
|
||
|
diff --git a/autofs.spec b/autofs.spec
|
||
|
index 2464e741..2cc0e38f 100644
|
||
|
--- a/autofs.spec
|
||
|
+++ b/autofs.spec
|
||
|
@@ -191,6 +191,7 @@ fi
|
||
|
%config(noreplace) /etc/sysconfig/autofs
|
||
|
%config(noreplace) /etc/autofs_ldap_auth.conf
|
||
|
%{_sbindir}/automount
|
||
|
+%{_sbindir}/mount.fedfs
|
||
|
%dir %{_libdir}/autofs
|
||
|
%{_libdir}/autofs/*
|
||
|
%{_mandir}/*/*
|
||
|
diff --git a/fedfs/Makefile b/fedfs/Makefile
|
||
|
new file mode 100644
|
||
|
index 00000000..cb325bed
|
||
|
--- /dev/null
|
||
|
+++ b/fedfs/Makefile
|
||
|
@@ -0,0 +1,36 @@
|
||
|
+#
|
||
|
+# Makefile for mount.fedfs
|
||
|
+#
|
||
|
+
|
||
|
+-include ../Makefile.conf
|
||
|
+include ../Makefile.rules
|
||
|
+
|
||
|
+SRCS = mount.fedfs.c
|
||
|
+HDRS = fedfs-getsrvinfo.h fedfs-gpl-boiler.h fedfs-nls.h
|
||
|
+
|
||
|
+fedfs-getsrvinfo_OBJ = fedfs-getsrvinfo.o
|
||
|
+
|
||
|
+mount_fedfs_OBJ = mount.fedfs.o
|
||
|
+
|
||
|
+version := $(shell cat ../.version)
|
||
|
+
|
||
|
+CFLAGS += -rdynamic $(DAEMON_CFLAGS) -D_GNU_SOURCE -I../include
|
||
|
+CFLAGS += -DVERSION_STRING=\"$(version)\"
|
||
|
+LDFLAGS += -rdynamic
|
||
|
+
|
||
|
+all: mount.fedfs
|
||
|
+
|
||
|
+mount.fedfs: $(mount_fedfs_OBJ) $(fedfs-getsrvinfo_OBJ) $(HDRS)
|
||
|
+ $(CC) -o mount.fedfs \
|
||
|
+ $(mount_fedfs_OBJ) $(fedfs-getsrvinfo_OBJ) \
|
||
|
+ $(LDFLAGS) $(LIBRESOLV) $(LIBS)
|
||
|
+
|
||
|
+clean:
|
||
|
+ rm -f *.o *.s *~ mount.fedfs
|
||
|
+
|
||
|
+install: all
|
||
|
+ install -d -m 755 $(INSTALLROOT)$(sbindir)
|
||
|
+ if ! test -x $(INSTALLROOT)$(sbindir)/mount.fedfs; \
|
||
|
+ then \
|
||
|
+ install -c mount.fedfs -m 755 $(INSTALLROOT)$(sbindir); \
|
||
|
+ fi
|
||
|
diff --git a/fedfs/fedfs-gpl-boiler.h b/fedfs/fedfs-gpl-boiler.h
|
||
|
new file mode 100644
|
||
|
index 00000000..1353e736
|
||
|
--- /dev/null
|
||
|
+++ b/fedfs/fedfs-gpl-boiler.h
|
||
|
@@ -0,0 +1,40 @@
|
||
|
+/*
|
||
|
+ * Copyright 2011 Oracle. All rights reserved.
|
||
|
+ *
|
||
|
+ * This file is part of fedfs-utils.
|
||
|
+ *
|
||
|
+ * fedfs-utils is free software; you can redistribute it and/or modify
|
||
|
+ * it under the terms of the GNU General Public License version 2.0 as
|
||
|
+ * published by the Free Software Foundation.
|
||
|
+ *
|
||
|
+ * fedfs-utils is distributed in the hope that it will be useful, but
|
||
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
+ * GNU General Public License version 2.0 for more details.
|
||
|
+ *
|
||
|
+ * You should have received a copy of the GNU General Public License
|
||
|
+ * version 2.0 along with fedfs-utils. If not, see:
|
||
|
+ *
|
||
|
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||
|
+ */
|
||
|
+
|
||
|
+#ifndef _GPL_BOILER_H_
|
||
|
+#define _GPL_BOILER_H_
|
||
|
+
|
||
|
+#ifdef HAVE_CONFIG_H
|
||
|
+#include <config.h>
|
||
|
+#endif
|
||
|
+
|
||
|
+/**
|
||
|
+ * GPLv2 boilerplate for usage messages
|
||
|
+ */
|
||
|
+static const char *fedfs_gpl_boilerplate =
|
||
|
+ "\nCopyright 2010, 2011, 2012, 2013 Oracle. "
|
||
|
+ "All rights reserved.\n\n"
|
||
|
+ "License GPLv2: "
|
||
|
+ "<http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>\n"
|
||
|
+ "This is free software. "
|
||
|
+ "You are free to change and redistribute it.\n"
|
||
|
+ "There is NO WARRANTY, to the extent permitted by law.\n";
|
||
|
+
|
||
|
+#endif /* !_GPL_BOILER_H_ */
|
||
|
diff --git a/fedfs/fedfs-nls.h b/fedfs/fedfs-nls.h
|
||
|
new file mode 100644
|
||
|
index 00000000..92f968d3
|
||
|
--- /dev/null
|
||
|
+++ b/fedfs/fedfs-nls.h
|
||
|
@@ -0,0 +1,38 @@
|
||
|
+/*
|
||
|
+ * From util-linux/include/nls.h (GPLv2)
|
||
|
+ */
|
||
|
+
|
||
|
+#ifndef UTIL_LINUX_NLS_H
|
||
|
+#define UTIL_LINUX_NLS_H
|
||
|
+
|
||
|
+int main(int argc, char *argv[]);
|
||
|
+
|
||
|
+#ifndef LOCALEDIR
|
||
|
+#define LOCALEDIR "/usr/share/locale"
|
||
|
+#endif
|
||
|
+
|
||
|
+#ifdef HAVE_LOCALE_H
|
||
|
+# include <locale.h>
|
||
|
+#else
|
||
|
+# undef setlocale
|
||
|
+# define setlocale(Category, Locale) ({}) /* empty */
|
||
|
+#endif
|
||
|
+
|
||
|
+#ifdef ENABLE_NLS
|
||
|
+# include <libintl.h>
|
||
|
+# define _(Text) gettext (Text)
|
||
|
+# ifdef gettext_noop
|
||
|
+# define N_(String) gettext_noop (String)
|
||
|
+# else
|
||
|
+# define N_(String) (String)
|
||
|
+# endif
|
||
|
+#else
|
||
|
+# undef bindtextdomain
|
||
|
+# define bindtextdomain(Domain, Directory) /* empty */
|
||
|
+# undef textdomain
|
||
|
+# define textdomain(Domain) /* empty */
|
||
|
+# define _(Text) (Text)
|
||
|
+# define N_(Text) (Text)
|
||
|
+#endif
|
||
|
+
|
||
|
+#endif /* UTIL_LINUX_NLS_H */
|
||
|
diff --git a/fedfs/mount.fedfs.c b/fedfs/mount.fedfs.c
|
||
|
new file mode 100644
|
||
|
index 00000000..bd434395
|
||
|
--- /dev/null
|
||
|
+++ b/fedfs/mount.fedfs.c
|
||
|
@@ -0,0 +1,485 @@
|
||
|
+/*
|
||
|
+ * Copyright 2011 Oracle. All rights reserved.
|
||
|
+ *
|
||
|
+ * This file is part of fedfs-utils.
|
||
|
+ *
|
||
|
+ * fedfs-utils is free software; you can redistribute it and/or modify
|
||
|
+ * it under the terms of the GNU General Public License version 2.0 as
|
||
|
+ * published by the Free Software Foundation.
|
||
|
+ *
|
||
|
+ * fedfs-utils is distributed in the hope that it will be useful, but
|
||
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
+ * GNU General Public License version 2.0 for more details.
|
||
|
+ *
|
||
|
+ * You should have received a copy of the GNU General Public License
|
||
|
+ * version 2.0 along with fedfs-utils. If not, see:
|
||
|
+ *
|
||
|
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||
|
+ */
|
||
|
+
|
||
|
+#include <sys/types.h>
|
||
|
+#include <sys/stat.h>
|
||
|
+#include <sys/socket.h>
|
||
|
+#include <sys/mount.h>
|
||
|
+#include <sys/wait.h>
|
||
|
+
|
||
|
+#include <stdbool.h>
|
||
|
+#include <string.h>
|
||
|
+#include <stdlib.h>
|
||
|
+#include <unistd.h>
|
||
|
+#include <stdio.h>
|
||
|
+#include <libgen.h>
|
||
|
+#include <errno.h>
|
||
|
+#include <getopt.h>
|
||
|
+#include <locale.h>
|
||
|
+#include <netdb.h>
|
||
|
+#include <langinfo.h>
|
||
|
+
|
||
|
+#include "fedfs-nls.h"
|
||
|
+#include "fedfs-getsrvinfo.h"
|
||
|
+#include "fedfs-gpl-boiler.h"
|
||
|
+
|
||
|
+/**
|
||
|
+ * Top-level directory on client under which we mount NFSv4 domain roots
|
||
|
+ */
|
||
|
+#define FEDFS_NFS4_TLDIR "nfs4"
|
||
|
+
|
||
|
+/**
|
||
|
+ * Name of SRV record containing NFSv4 FedFS root
|
||
|
+ */
|
||
|
+#define FEDFS_NFS_DOMAINROOT "_nfs-domainroot._tcp"
|
||
|
+
|
||
|
+/**
|
||
|
+ * Export path of NFSv4 FedFS root
|
||
|
+ */
|
||
|
+#define FEDFS_NFS_EXPORTPATH "/.domainroot"
|
||
|
+
|
||
|
+/**
|
||
|
+ * Pathname to mount.nfs
|
||
|
+ */
|
||
|
+#define MOUNT_NFS_EXECUTABLE "/sbin/mount.nfs"
|
||
|
+
|
||
|
+/**
|
||
|
+ * Mount status values, lifted from util-linux
|
||
|
+ */
|
||
|
+enum {
|
||
|
+ EX_SUCCESS = 0,
|
||
|
+ EX_USAGE = 1,
|
||
|
+ EX_FAIL = 32,
|
||
|
+};
|
||
|
+
|
||
|
+static char *progname;
|
||
|
+static int nomtab;
|
||
|
+static int verbose;
|
||
|
+static _Bool readonly;
|
||
|
+static _Bool sloppy;
|
||
|
+static _Bool fake;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Short form command line options
|
||
|
+ */
|
||
|
+static const char fedfs_opts[] = "fhno:rsvVw";
|
||
|
+
|
||
|
+/**
|
||
|
+ * Long form command line options
|
||
|
+ */
|
||
|
+static const struct option fedfs_longopts[] =
|
||
|
+{
|
||
|
+ { "fake", 0, NULL, 'f' },
|
||
|
+ { "help", 0, NULL, 'h' },
|
||
|
+ { "no-mtab", 0, NULL, 'n' },
|
||
|
+ { "options", 1, NULL, 'o' },
|
||
|
+ { "read-only", 0, NULL, 'r' },
|
||
|
+ { "read-write", 0, NULL, 'w' },
|
||
|
+ { "ro", 0, NULL, 'r' },
|
||
|
+ { "rw", 0, NULL, 'w' },
|
||
|
+ { "sloppy", 0, NULL, 's' },
|
||
|
+ { "verbose", 0, NULL, 'v' },
|
||
|
+ { "version", 0, NULL, 'V' },
|
||
|
+ { NULL, 0, NULL, 0 }
|
||
|
+};
|
||
|
+
|
||
|
+/**
|
||
|
+ * Display mount.fedfs usage message
|
||
|
+ */
|
||
|
+static void
|
||
|
+mount_usage(void)
|
||
|
+{
|
||
|
+ printf(_("\nUsage: %s remotedir localdir [-fhnrsvVw]\n\n"), progname);
|
||
|
+ printf(_("options:\n"));
|
||
|
+ printf(_("\t-f\t\tFake mount, do not actually mount\n"));
|
||
|
+ printf(_("\t-h\t\tPrint this help\n"));
|
||
|
+ printf(_("\t-n\t\tDo not update /etc/mtab\n"));
|
||
|
+ printf(_("\t-r\t\tMount file system readonly\n"));
|
||
|
+ printf(_("\t-s\t\tTolerate sloppy mount options\n"));
|
||
|
+ printf(_("\t-v\t\tVerbose\n"));
|
||
|
+ printf(_("\t-V\t\tPrint version\n"));
|
||
|
+ printf(_("\t-w\t\tMount file system read-write\n"));
|
||
|
+
|
||
|
+ printf("%s", fedfs_gpl_boilerplate);
|
||
|
+}
|
||
|
+
|
||
|
+/**
|
||
|
+ * Concatenate three strings
|
||
|
+ *
|
||
|
+ * @param s NUL-terminated C string
|
||
|
+ * @param t NUL-terminated C string
|
||
|
+ * @param u NUL-terminated C string
|
||
|
+ * @return pointer to NUL-terminated C string or NULL
|
||
|
+ *
|
||
|
+ * Caller must free the returned string with free(3). Always frees
|
||
|
+ * its first arg - typical use: s = xstrconcat3(s,t,u);
|
||
|
+ *
|
||
|
+ * Lifted from util-linux.
|
||
|
+ */
|
||
|
+static char *
|
||
|
+xstrconcat3(char *s, const char *t, const char *u)
|
||
|
+{
|
||
|
+ _Bool free_s = true;
|
||
|
+ char *result;
|
||
|
+
|
||
|
+ if (s == NULL) {
|
||
|
+ s = "";
|
||
|
+ free_s = false;
|
||
|
+ }
|
||
|
+ if (t == NULL)
|
||
|
+ t = "";
|
||
|
+ if (u == NULL)
|
||
|
+ u = "";
|
||
|
+ result = malloc(strlen(s) + strlen(t) + strlen(u) + 1);
|
||
|
+ if (result == NULL)
|
||
|
+ goto out;
|
||
|
+
|
||
|
+ strcpy(result, s);
|
||
|
+ strcat(result, t);
|
||
|
+ strcat(result, u);
|
||
|
+
|
||
|
+out:
|
||
|
+ if (free_s)
|
||
|
+ free(s);
|
||
|
+ return result;
|
||
|
+}
|
||
|
+
|
||
|
+/**
|
||
|
+ * Exec mount.nfs
|
||
|
+ *
|
||
|
+ * @param server NUL-terminated C string containing name of NFS server
|
||
|
+ * @param port server port to use when mounting
|
||
|
+ * @param domainname NUL-terminated C string containing FedFS domain name
|
||
|
+ * @param export_path NUL-terminated C string containing server export path
|
||
|
+ * @param mounted_on_dir NUL-terminated C string containing local mounted-on directory
|
||
|
+ * @param text_options NUL-terminated C string containing user's mount options
|
||
|
+ *
|
||
|
+ */
|
||
|
+static void
|
||
|
+exec_mount_nfs4(const char *server, unsigned short port,
|
||
|
+ const char *domainname, const char *export_path,
|
||
|
+ const char *mounted_on_dir, const char *text_options)
|
||
|
+{
|
||
|
+ static char special[2048];
|
||
|
+ static char options[2048];
|
||
|
+ char *args[16];
|
||
|
+ int count = 0;
|
||
|
+
|
||
|
+ snprintf(special, sizeof(special), "%s:%s/%s%s", server,
|
||
|
+ FEDFS_NFS_EXPORTPATH, domainname, export_path);
|
||
|
+
|
||
|
+ if (text_options != NULL && strcmp(text_options, "") != 0)
|
||
|
+ snprintf(options, sizeof(options), "%s,vers=4,fg,port=%u",
|
||
|
+ text_options, port);
|
||
|
+ else
|
||
|
+ snprintf(options, sizeof(options), "vers=4,fg,port=%u", port);
|
||
|
+
|
||
|
+ if (verbose) {
|
||
|
+ printf(_("%s: Special device: %s\n"),
|
||
|
+ progname, special);
|
||
|
+ printf(_("%s: Mounted-on directory: %s\n"),
|
||
|
+ progname, mounted_on_dir);
|
||
|
+ printf(_("%s: Mount options: %s\n"),
|
||
|
+ progname, options);
|
||
|
+ }
|
||
|
+
|
||
|
+ args[count++] = MOUNT_NFS_EXECUTABLE;
|
||
|
+ args[count++] = special;
|
||
|
+ args[count++] = (char *)mounted_on_dir;
|
||
|
+ if (verbose)
|
||
|
+ args[count++] = "-v";
|
||
|
+ if (fake)
|
||
|
+ args[count++] = "-f";
|
||
|
+ if (nomtab)
|
||
|
+ args[count++] = "-n";
|
||
|
+ if (readonly)
|
||
|
+ args[count++] = "-r";
|
||
|
+ if (sloppy)
|
||
|
+ args[count++] = "-s";
|
||
|
+ args[count++] = "-o";
|
||
|
+ args[count++] = options;
|
||
|
+
|
||
|
+ args[count] = NULL;
|
||
|
+ execv(args[0], args);
|
||
|
+}
|
||
|
+
|
||
|
+/**
|
||
|
+ * Mount a FedFS domain root via NFSv4
|
||
|
+ *
|
||
|
+ * @param domainname NUL-terminated C string containing FedFS domain name
|
||
|
+ * @param export_path NUL-terminated C string containing server export path
|
||
|
+ * @param mounted_on_dir NUL-terminated C string containing local mounted-on directory
|
||
|
+ * @param text_options NUL-terminated C string containing user's mount options
|
||
|
+ * @return exit status code from the mount.nfs command
|
||
|
+ *
|
||
|
+ * Construct the server:/export string and the mounted-on directory string
|
||
|
+ * based on the DNS SRV query results, then fork and exec mount.nfs to do
|
||
|
+ * the actual mount request.
|
||
|
+ */
|
||
|
+static int
|
||
|
+nfs4_mount(const char *domainname, const char *export_path,
|
||
|
+ const char *mounted_on_dir, const char *text_options)
|
||
|
+{
|
||
|
+ struct srvinfo *tmp, *si = NULL;
|
||
|
+ int error, status;
|
||
|
+
|
||
|
+ status = EX_FAIL;
|
||
|
+
|
||
|
+ error = getsrvinfo(FEDFS_NFS_DOMAINROOT, domainname, &si);
|
||
|
+ switch (error) {
|
||
|
+ case ESI_SUCCESS:
|
||
|
+ break;
|
||
|
+ case ESI_NONAME:
|
||
|
+ fprintf(stderr, _("%s: Domain name %s not found\n"),
|
||
|
+ progname, domainname);
|
||
|
+ goto out;
|
||
|
+ case ESI_SERVICE:
|
||
|
+ fprintf(stderr, _("%s: No FedFS domain root available for %s\n"),
|
||
|
+ progname, domainname);
|
||
|
+ goto out;
|
||
|
+ default:
|
||
|
+ fprintf(stderr, _("%s: Failed to resolve %s: %s\n"),
|
||
|
+ progname, domainname, gsi_strerror(error));
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ /*
|
||
|
+ * The srvinfo list is already in RFC 2782 sorted order. Try each
|
||
|
+ * SRV record once, in the foreground. Go with the first one that
|
||
|
+ * works.
|
||
|
+ */
|
||
|
+ for (tmp = si; tmp != NULL; tmp = tmp->si_next) {
|
||
|
+ pid_t pid;
|
||
|
+
|
||
|
+ pid = fork();
|
||
|
+ switch (pid) {
|
||
|
+ case 0:
|
||
|
+ exec_mount_nfs4(tmp->si_target, tmp->si_port,
|
||
|
+ domainname, export_path, mounted_on_dir,
|
||
|
+ text_options);
|
||
|
+ /*NOTREACHED*/
|
||
|
+ fprintf(stderr, _("%s: Failed to exec: %s\n"),
|
||
|
+ progname, strerror(errno));
|
||
|
+ exit(EX_FAIL);
|
||
|
+ case -1:
|
||
|
+ fprintf(stderr, _("%s: Failed to fork: %s\n"),
|
||
|
+ progname, strerror(errno));
|
||
|
+ goto out;
|
||
|
+ default:
|
||
|
+ waitpid(pid, &status, 0);
|
||
|
+ if (status == EX_SUCCESS)
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+out:
|
||
|
+ freesrvinfo(si);
|
||
|
+ return status;
|
||
|
+}
|
||
|
+
|
||
|
+/**
|
||
|
+ * Try one mount request
|
||
|
+ *
|
||
|
+ * @param source NUL-terminated C string containing name of "special device"
|
||
|
+ * @param target NUL-terminated C string containing local mounted-on directory
|
||
|
+ * @param text_options NUL-terminated C string containing user's mount options
|
||
|
+ * @return an exit status code
|
||
|
+ *
|
||
|
+ * Parse the pathname in "source." It contains the file system protocol
|
||
|
+ * and FedFS domain name. Then pass these arguments to the appropriate
|
||
|
+ * mount helper subcommand.
|
||
|
+ */
|
||
|
+static int
|
||
|
+try_mount(const char *source, const char *target, const char *text_options)
|
||
|
+{
|
||
|
+ char *global_name, *topdir, *domainname, *remaining;
|
||
|
+ int result;
|
||
|
+
|
||
|
+ remaining = NULL;
|
||
|
+ result = EX_FAIL;
|
||
|
+
|
||
|
+ global_name = strdup(source);
|
||
|
+ if (global_name == NULL) {
|
||
|
+ fprintf(stderr, _("%s: Unable to parse globally useful name\n"),
|
||
|
+ progname);
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ topdir = strtok(global_name, "/");
|
||
|
+ if (topdir == NULL) {
|
||
|
+ fprintf(stderr, _("%s: Invalid globally useful name: %s\n"),
|
||
|
+ progname, source);
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+ if (verbose)
|
||
|
+ printf(_("%s: Top-level directory: %s\n"),
|
||
|
+ progname, topdir);
|
||
|
+
|
||
|
+ domainname = strtok(NULL, "/");
|
||
|
+ if (domainname == NULL) {
|
||
|
+ fprintf(stderr, _("%s: Missing domain name in globally "
|
||
|
+ "useful name: %s\n"), progname, source);
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+ if (verbose)
|
||
|
+ printf(_("%s: Domain name: %s\n"),
|
||
|
+ progname, domainname);
|
||
|
+
|
||
|
+ remaining = strtok(NULL, "/");
|
||
|
+ if (remaining == NULL) {
|
||
|
+ remaining = strdup("/");
|
||
|
+ if (remaining == NULL) {
|
||
|
+ fprintf(stderr, _("%s: No memory\n"), progname);
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+ } else {
|
||
|
+ char *tmp;
|
||
|
+
|
||
|
+ tmp = malloc(strlen(remaining) + 1);
|
||
|
+ if (tmp == NULL) {
|
||
|
+ fprintf(stderr, _("%s: No memory\n"), progname);
|
||
|
+ remaining = NULL;
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+ strcpy(tmp, "/");
|
||
|
+ strcat(tmp, remaining);
|
||
|
+ remaining = tmp;
|
||
|
+ }
|
||
|
+ if (verbose)
|
||
|
+ printf(_("%s: Export path: %s\n"),
|
||
|
+ progname, remaining);
|
||
|
+
|
||
|
+ if (strcmp(topdir, FEDFS_NFS4_TLDIR) == 0)
|
||
|
+ result = nfs4_mount(domainname, remaining, target, text_options);
|
||
|
+#if 0
|
||
|
+ /* example: SMB support plugs in here */
|
||
|
+ else if (strcmp(topdir, FEDFS_SMB_TLDIR) == 0)
|
||
|
+ result = smb_mount(domainname, remaining, target, text_options);
|
||
|
+#endif
|
||
|
+ else
|
||
|
+ fprintf(stderr, _("%s: Unrecognized file system protocol\n"), progname);
|
||
|
+
|
||
|
+out:
|
||
|
+ free(global_name);
|
||
|
+ free(remaining);
|
||
|
+
|
||
|
+ return result;
|
||
|
+}
|
||
|
+
|
||
|
+/**
|
||
|
+ * Program entry point
|
||
|
+ *
|
||
|
+ * @param argc count of command line arguments
|
||
|
+ * @param argv array of NUL-terminated C strings containing command line arguments
|
||
|
+ * @return program exit status
|
||
|
+ */
|
||
|
+int main(int argc, char *argv[])
|
||
|
+{
|
||
|
+ char *source, *target, *text_options;
|
||
|
+ int c, mnt_err;
|
||
|
+
|
||
|
+ (void)setlocale(LC_ALL, "");
|
||
|
+
|
||
|
+ progname = basename(argv[0]);
|
||
|
+
|
||
|
+ if (argv[1] && argv[1][0] == '-') {
|
||
|
+ if(argv[1][1] == 'V')
|
||
|
+ printf("%s (VERSION_STRING)\n", progname);
|
||
|
+ else
|
||
|
+ mount_usage();
|
||
|
+ exit(EX_SUCCESS);
|
||
|
+ }
|
||
|
+
|
||
|
+ if (argc < 3) {
|
||
|
+ mount_usage();
|
||
|
+ exit(EX_USAGE);
|
||
|
+ }
|
||
|
+
|
||
|
+ source = argv[1];
|
||
|
+ target = argv[2];
|
||
|
+
|
||
|
+ mnt_err = EX_USAGE;
|
||
|
+ text_options = NULL;
|
||
|
+ readonly = false;
|
||
|
+ sloppy = false;
|
||
|
+ fake = false;
|
||
|
+ argv[2] = argv[0]; /* so that getopt error messages are correct */
|
||
|
+ while ((c = getopt_long(argc - 2, argv + 2, fedfs_opts,
|
||
|
+ fedfs_longopts, NULL)) != -1) {
|
||
|
+ switch (c) {
|
||
|
+ case 'f':
|
||
|
+ fake = true;
|
||
|
+ break;
|
||
|
+ case 'n':
|
||
|
+ ++nomtab;
|
||
|
+ break;
|
||
|
+ case 'o':
|
||
|
+ /* Ugh. */
|
||
|
+ if (text_options != NULL)
|
||
|
+ text_options = xstrconcat3(text_options, ",", optarg);
|
||
|
+ else
|
||
|
+ text_options = strdup(optarg);
|
||
|
+ if (text_options == NULL) {
|
||
|
+ fprintf(stderr, _("%s: No memory\n"), progname);
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ case 'r':
|
||
|
+ readonly = true;
|
||
|
+ break;
|
||
|
+ case 's':
|
||
|
+ sloppy = true;
|
||
|
+ break;
|
||
|
+ case 'v':
|
||
|
+ ++verbose;
|
||
|
+ break;
|
||
|
+ case 'V':
|
||
|
+ printf("%s: (VERSION_STRING)\n", progname);
|
||
|
+ mnt_err = EX_SUCCESS;
|
||
|
+ goto out;
|
||
|
+ case 'w':
|
||
|
+ readonly = false;
|
||
|
+ break;
|
||
|
+ case 'h':
|
||
|
+ default:
|
||
|
+ mount_usage();
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Extra non-option words at the end are bogus... */
|
||
|
+ if (optind != argc - 2) {
|
||
|
+ mount_usage();
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (getuid() != 0 && geteuid() != 0) {
|
||
|
+ fprintf(stderr, _("%s: Not installed setuid - "
|
||
|
+ "\"user\" FedFS mounts are not supported\n"), progname);
|
||
|
+ mnt_err = EX_FAIL;
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ mnt_err = try_mount(source, target, text_options);
|
||
|
+
|
||
|
+out:
|
||
|
+ free(text_options);
|
||
|
+ exit(mnt_err);
|
||
|
+}
|