summaryrefslogtreecommitdiffstats
path: root/utils/exportfs/exportfs.c
diff options
context:
space:
mode:
authorhjl <hjl>1999-10-18 23:21:12 +0000
committerhjl <hjl>1999-10-18 23:21:12 +0000
commit8b7ad01b14df1e7529b9ba8a1ea17df0d6004ef9 (patch)
tree0904ef8554ed680fe3244fa618685e1fb7ea148b /utils/exportfs/exportfs.c
downloadnfs-utils-8b7ad01b14df1e7529b9ba8a1ea17df0d6004ef9.tar.gz
nfs-utils-8b7ad01b14df1e7529b9ba8a1ea17df0d6004ef9.tar.xz
nfs-utils-8b7ad01b14df1e7529b9ba8a1ea17df0d6004ef9.zip
Initial revision
Diffstat (limited to 'utils/exportfs/exportfs.c')
-rw-r--r--utils/exportfs/exportfs.c391
1 files changed, 391 insertions, 0 deletions
diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
new file mode 100644
index 0000000..44761f8
--- /dev/null
+++ b/utils/exportfs/exportfs.c
@@ -0,0 +1,391 @@
+/*
+ * utils/exportfs/exportfs.c
+ *
+ * Export file systems to knfsd
+ *
+ * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
+ *
+ * Extensive changes, 1999, Neil Brown <neilb@cse.unsw.edu.au>
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <getopt.h>
+#include <netdb.h>
+#include <errno.h>
+#include "xmalloc.h"
+#include "misc.h"
+#include "nfslib.h"
+#include "exportfs.h"
+#include "xmalloc.h"
+#include "xlog.h"
+
+static void export_all(int verbose);
+static void unexport_all(int verbose);
+static void exportfs(char *arg, char *options, int verbose);
+static void unexportfs(char *arg, int verbose);
+static void exports_update(int verbose);
+static void dump(int verbose);
+static void error(nfs_export *exp, int err);
+static void usage(void);
+
+
+int
+main(int argc, char **argv)
+{
+ char *options = NULL;
+ int f_export = 1;
+ int f_all = 0;
+ int f_verbose = 0;
+ int f_reexport = 0;
+ int f_ignore = 0;
+ int i, c;
+
+ xlog_open("exportfs");
+
+ while ((c = getopt(argc, argv, "aio:ruv")) != EOF) {
+ switch(c) {
+ case 'a':
+ f_all = 1;
+ break;
+ case 'i':
+ f_ignore = 1;
+ break;
+ case 'o':
+ options = optarg;
+ break;
+ case 'r':
+ f_reexport = 1;
+ f_all = 1;
+ break;
+ case 'u':
+ f_export = 0;
+ break;
+ case 'v':
+ f_verbose = 1;
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if (optind != argc && f_all) {
+ fprintf(stderr,"exportfs: extra arguments are not permitted with -a or -r.\n");
+ return 1;
+ }
+ if (f_ignore && (f_all || ! f_export)) {
+ fprintf(stderr,"exportfs: -i not meaningful with -a, -r or -u.\n");
+ return 1;
+ }
+ if (f_reexport && ! f_export) {
+ fprintf(stderr, "exportfs: -r and -u are incompatible.\n");
+ return 1;
+ }
+ if (optind == argc && ! f_all) {
+ xtab_export_read();
+ dump(f_verbose);
+ return 0;
+ }
+
+ if (f_export && ! f_ignore)
+ export_read(_PATH_EXPORTS);
+ if (f_export) {
+ if (f_all)
+ export_all(f_verbose);
+ else
+ for (i = optind; i < argc ; i++)
+ exportfs(argv[i], options, f_verbose);
+ }
+ /* note: xtab_*_read does not update entries if they already exist,
+ * so this will not lose new options
+ */
+ if (!f_reexport)
+ xtab_export_read();
+ if (!f_export) {
+ if (f_all)
+ unexport_all(f_verbose);
+ else
+ for (i = optind ; i < argc ; i++)
+ unexportfs(argv[i], f_verbose);
+ }
+ rmtab_read();
+ xtab_mount_read();
+ exports_update(f_verbose);
+ xtab_export_write();
+ xtab_mount_write();
+
+ return 0;
+}
+
+/* we synchronise intention with reality.
+ * entries with m_mayexport get exported
+ * entries with m_exported but not m_mayexport get unexported
+ * looking at m_client->m_type == MCL_FQDN only
+ */
+static void
+exports_update(int verbose)
+{
+ nfs_export *exp;
+
+ for (exp = exportlist[MCL_FQDN]; exp; exp=exp->m_next) {
+ if (exp->m_mayexport && (!exp->m_exported || exp->m_changed)) {
+ if (verbose)
+ printf("%sexporting %s:%s to kernel\n",
+ exp->m_exported ?"re":"",
+ exp->m_client->m_hostname,
+ exp->m_export.e_path);
+ if (!export_export(exp))
+ error(exp, errno);
+ }
+ if (exp->m_exported && ! exp->m_mayexport) {
+ if (verbose)
+ printf("unexporting %s:%s from kernel\n",
+ exp->m_client->m_hostname,
+ exp->m_export.e_path);
+ if (!export_unexport(exp))
+ error(exp, errno);
+ }
+ }
+}
+
+/*
+ * export_all finds all entries and
+ * marks them xtabent and mayexport so that they get exported
+ */
+static void
+export_all(int verbose)
+{
+ nfs_export *exp;
+ int i;
+
+ for (i = 0; i < MCL_MAXTYPES; i++) {
+ for (exp = exportlist[i]; exp; exp = exp->m_next) {
+ if (verbose)
+ printf("exporting %s:%s\n",
+ exp->m_client->m_hostname,
+ exp->m_export.e_path);
+ exp->m_xtabent = 1;
+ exp->m_mayexport = 1;
+ exp->m_changed = 1;
+ }
+ }
+}
+/*
+ * unexport_all finds all entries that are mayexport, and
+ * marks them not xtabent and not mayexport
+ */
+static void
+unexport_all(int verbose)
+{
+ nfs_export *exp;
+ int i;
+
+ for (i = 0; i < MCL_MAXTYPES; i++) {
+ for (exp = exportlist[i]; exp; exp = exp->m_next)
+ if (exp->m_mayexport) {
+ if (verbose) {
+ if (exp->m_exported) {
+ printf("unexporting %s:%s from kernel\n",
+ exp->m_client->m_hostname,
+ exp->m_export.e_path);
+ }
+ else {
+ printf("unexporting %s:%s\n",
+ exp->m_client->m_hostname,
+ exp->m_export.e_path);
+ }
+ }
+ if (exp->m_exported && !export_unexport(exp))
+ error(exp, errno);
+ exp->m_xtabent = 0;
+ exp->m_mayexport = 0;
+ }
+ }
+}
+
+
+static void
+exportfs(char *arg, char *options, int verbose)
+{
+ struct exportent *eep;
+ nfs_export *exp;
+ struct hostent *hp = NULL;
+ char *path;
+ char *hname = arg;
+ int htype;
+
+ if ((path = strchr(arg, ':')) != NULL)
+ *path++ = '\0';
+
+ if (!path || *path != '/') {
+ fprintf(stderr, "Invalid exporting option: %s\n", arg);
+ return;
+ }
+
+ if ((htype = client_gettype(hname)) == MCL_FQDN &&
+ (hp = gethostbyname(hname)) != NULL) {
+ hp = hostent_dup (hp);
+ exp = export_find(hp, path);
+ } else {
+ exp = export_lookup(hname, path);
+ }
+
+ if (!exp) {
+ if (!(eep = mkexportent(hname, path, options)) ||
+ !(exp = export_create(eep))) {
+ if (hp) free (hp);
+ return;
+ }
+ } else if (!updateexportent(&exp->m_export, options)) {
+ if (hp) free (hp);
+ return;
+ }
+
+ if (verbose)
+ printf("exporting %s:%s\n", exp->m_client->m_hostname,
+ exp->m_export.e_path);
+ exp->m_xtabent = 1;
+ exp->m_mayexport = 1;
+ exp->m_changed = 1;
+ if (hp) free (hp);
+}
+
+static void
+unexportfs(char *arg, int verbose)
+{
+ nfs_export *exp;
+ struct hostent *hp = NULL;
+ char *path;
+ char *hname = arg;
+ int htype;
+
+ if ((path = strchr(arg, ':')) != NULL)
+ *path++ = '\0';
+
+ if (!path || *path != '/') {
+ fprintf(stderr, "Invalid unexporting option: %s\n",
+ arg);
+ return;
+ }
+
+ if ((htype = client_gettype(hname)) == MCL_FQDN) {
+ if ((hp = gethostbyname(hname)) != 0) {
+ hp = hostent_dup (hp);
+ hname = (char *) hp->h_name;
+ }
+ }
+
+ for (exp = exportlist[htype]; exp; exp = exp->m_next) {
+ if (path && strcmp(path, exp->m_export.e_path))
+ continue;
+ if (htype != exp->m_client->m_type
+ || (htype == MCL_FQDN
+ && !matchhostname(exp->m_export.e_hostname,
+ hname)))
+ continue;
+ if (verbose) {
+ if (exp->m_exported) {
+ printf("unexporting %s:%s from kernel\n",
+ exp->m_client->m_hostname,
+ exp->m_export.e_path);
+ }
+ else {
+ printf("unexporting %s:%s\n",
+ exp->m_client->m_hostname,
+ exp->m_export.e_path);
+ }
+ }
+ if (exp->m_exported && !export_unexport(exp))
+ error(exp, errno);
+ exp->m_xtabent = 0;
+ exp->m_mayexport = 0;
+ }
+
+ if (hp) free (hp);
+}
+
+static char
+dumpopt(char c, char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ printf("%c", c);
+ vprintf(fmt, ap);
+ va_end(ap);
+ return ',';
+}
+
+static void
+dump(int verbose)
+{
+ nfs_export *exp;
+ struct exportent *ep;
+ int htype;
+ char *hname, c;
+
+ for (htype = 0; htype < MCL_MAXTYPES; htype++) {
+ for (exp = exportlist[htype]; exp; exp = exp->m_next) {
+ ep = &exp->m_export;
+ if (!exp->m_xtabent)
+ continue; /* neilb */
+ if (htype == MCL_ANONYMOUS)
+ hname = "<world>";
+ else
+ hname = ep->e_hostname;
+ if (strlen(ep->e_path) > 14)
+ printf("%-14s\n\t\t%s", ep->e_path, hname);
+ else
+ printf("%-14s\t%s", ep->e_path, hname);
+ if (!verbose) {
+ printf("\n");
+ continue;
+ }
+ c = '(';
+ if (ep->e_flags & NFSEXP_READONLY)
+ c = dumpopt(c, "ro");
+ else
+ c = dumpopt(c, "rw");
+ if (ep->e_flags & NFSEXP_ASYNC)
+ c = dumpopt(c, "async");
+ if (ep->e_flags & NFSEXP_GATHERED_WRITES)
+ c = dumpopt(c, "wdelay");
+ if (ep->e_flags & NFSEXP_INSECURE_PORT)
+ c = dumpopt(c, "insecure");
+ if (ep->e_flags & NFSEXP_ROOTSQUASH)
+ c = dumpopt(c, "root_squash");
+ else
+ c = dumpopt(c, "no_root_squash");
+ if (ep->e_flags & NFSEXP_ALLSQUASH)
+ c = dumpopt(c, "all_squash");
+ if (ep->e_maptype == CLE_MAP_UGIDD)
+ c = dumpopt(c, "mapping=ugidd");
+ else if (ep->e_maptype == CLE_MAP_FILE)
+ c = dumpopt(c, "mapping=file");
+ if (ep->e_anonuid != -2)
+ c = dumpopt(c, "anonuid=%d", ep->e_anonuid);
+ if (ep->e_anongid != -2)
+ c = dumpopt(c, "anongid=%d", ep->e_anongid);
+
+ printf("%c\n", (c != '(')? ')' : ' ');
+ }
+ }
+}
+
+static void
+error(nfs_export *exp, int err)
+{
+ fprintf(stderr, "%s:%s: %s\n", exp->m_client->m_hostname,
+ exp->m_export.e_path, strerror(err));
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: exportfs [-aruv] [host:/path]\n");
+ exit(1);
+}