From 97073441e6ec6320580cda4d315a0fec506568eb Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Mon, 10 Jan 2011 14:31:23 +0100 Subject: [PATCH] libmount: add mount(8) sample This code is going to be used as mount(8) replacement in the next major release (2.20). For now this mount(8) implementation does not support loopdevs initialization. Signed-off-by: Karel Zak --- configure.ac | 1 + shlibs/mount/Makefile.am | 2 +- shlibs/mount/samples/.gitignore | 1 + shlibs/mount/samples/Makefile.am | 7 + shlibs/mount/samples/mount.c | 422 +++++++++++++++++++++++++++++++ shlibs/mount/src/context_mount.c | 1 + 6 files changed, 433 insertions(+), 1 deletion(-) create mode 100644 shlibs/mount/samples/.gitignore create mode 100644 shlibs/mount/samples/Makefile.am create mode 100644 shlibs/mount/samples/mount.c diff --git a/configure.ac b/configure.ac index b537d812..f68d7907 100644 --- a/configure.ac +++ b/configure.ac @@ -1185,6 +1185,7 @@ shlibs/mount/src/Makefile shlibs/mount/src/mount.h shlibs/mount/docs/Makefile shlibs/mount/docs/version.xml +shlibs/mount/samples/Makefile shlibs/uuid/uuid.pc shlibs/uuid/Makefile shlibs/uuid/man/Makefile diff --git a/shlibs/mount/Makefile.am b/shlibs/mount/Makefile.am index 3fefce6e..26111c66 100644 --- a/shlibs/mount/Makefile.am +++ b/shlibs/mount/Makefile.am @@ -1,6 +1,6 @@ include $(top_srcdir)/config/include-Makefile.am -SUBDIRS = src +SUBDIRS = src samples if ENABLE_GTK_DOC SUBDIRS += docs diff --git a/shlibs/mount/samples/.gitignore b/shlibs/mount/samples/.gitignore new file mode 100644 index 00000000..fde64773 --- /dev/null +++ b/shlibs/mount/samples/.gitignore @@ -0,0 +1 @@ +mount diff --git a/shlibs/mount/samples/Makefile.am b/shlibs/mount/samples/Makefile.am new file mode 100644 index 00000000..b0c655f1 --- /dev/null +++ b/shlibs/mount/samples/Makefile.am @@ -0,0 +1,7 @@ +include $(top_srcdir)/config/include-Makefile.am + +AM_CPPFLAGS += -I$(ul_libmount_incdir) +AM_LDFLAGS += $(ul_libmount_la) + +noinst_PROGRAMS = mount + diff --git a/shlibs/mount/samples/mount.c b/shlibs/mount/samples/mount.c new file mode 100644 index 00000000..1d032a62 --- /dev/null +++ b/shlibs/mount/samples/mount.c @@ -0,0 +1,422 @@ +/* + * mount(8) -- mount a filesystem + * + * Copyright (C) 2011 Red Hat, Inc. All rights reserved. + * Written by Karel Zak + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it would 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mount.h" +#include "nls.h" +#include "c.h" + +/*** TODO: DOCS: + * + * -p, --pass-fd is unsupported + * --guess-fstype is unsupported + * -c = --no-canonicalize + */ + +/* exit status */ +#define EX_SUCCESS 0 +#define EX_USAGE 1 /* incorrect invocation or permission */ +#define EX_SYSERR 2 /* out of memory, cannot fork, ... */ +#define EX_SOFTWARE 4 /* internal mount bug or wrong version */ +#define EX_USER 8 /* user interrupt */ +#define EX_FILEIO 16 /* problems writing, locking, ... mtab/fstab */ +#define EX_FAIL 32 /* mount failure */ +#define EX_SOMEOK 64 /* some mount succeeded */ + +static mnt_lock *lock; + +static void lock_atexit_cleanup(void) +{ + if (lock) + mnt_unlock_file(lock); +} + +static void __attribute__((__noreturn__)) exit_non_root(const char *option) +{ + const uid_t ruid = getuid(); + const uid_t euid = geteuid(); + + if (ruid == 0 && euid != 0) { + /* user is root, but setuid to non-root */ + if (option) + errx(EX_USAGE, _("only root can use \"--%s\" option " + "(effective UID is %u)"), + option, euid); + errx(EX_USAGE, _("only root can do that " + "(effective UID is %u)"), euid); + } + if (option) + errx(EX_USAGE, _("only root can use \"--%s\" option"), option); + errx(EX_USAGE, _("only root can do that")); +} + +static void __attribute__((__noreturn__)) print_version(void) +{ + const char *ver = NULL; + + mnt_get_library_version(&ver); + + printf("%s from %s (libmount %s)\n", + program_invocation_short_name, PACKAGE_STRING, ver); + exit(EX_SUCCESS); +} + +static const char *opt_to_longopt(int c, const struct option *opts) +{ + const struct option *o; + + for (o = opts; o->name; o++) + if (o->val == c) + return o->name; + return NULL; +} + +static int print_all(mnt_context *cxt, char *pattern, int show_label) +{ + int rc = 0; + mnt_tab *tb; + mnt_iter *itr; + mnt_fs *fs; + mnt_cache *cache = NULL; + + rc = mnt_context_get_mtab(cxt, &tb); + if (rc) + goto done; + + itr = mnt_new_iter(MNT_ITER_FORWARD); + if (!itr) + goto done; + + if (show_label) + cache = mnt_new_cache(); + + while(mnt_tab_next_fs(tb, itr, &fs) == 0) { + const char *type = mnt_fs_get_fstype(fs); + const char *src = mnt_fs_get_source(fs); + char *optstr = mnt_fs_strdup_options(fs); + + if (type && pattern && !mnt_match_fstype(type, pattern)) + continue; + + /* TODO: print loop backing file instead of device name */ + + printf ("%s on %s", src ? : "none", mnt_fs_get_target(fs)); + if (type) + printf (" type %s", type); + if (optstr) + printf (" (%s)", optstr); + if (show_label && src) { + char *lb = mnt_cache_find_tag_value(cache, src, "LABEL"); + if (lb) + printf (" [%s]", lb); + } + fputc('\n', stdout); + } +done: + mnt_free_cache(cache); + return rc; +} + +static void __attribute__((__noreturn__)) usage(FILE *out) +{ + fprintf(out, _("Usage:\n" + " %1$s [-lhV]\n" + " %1$s -a [options]\n" + " %1$s [options] | \n" + " %1$s [options] \n" + " %1$s []\n"), + program_invocation_short_name); + + fprintf(out, _( + "\nOptions:\n" + " -a, --all mount all filesystems mentioned in fstab\n" + " -f, --fake dry run, skip mount(2) syscall\n" + " -F, --fork fork off for each device (use with -a)\n" + " -h, --help this help\n" + " -n, --no-mtab don't write to /etc/mtab\n" + " -r, --read-only mount the filesystem read-only (same as -o ro)\n" + " -v, --verbose verbose mode\n" + " -V, --version print version string\n" + " -w, --read-write mount the filesystem read-write (default)\n" + " -o, --options comma separated string of mount options\n" + " -O, --test-opts limit the set of filesystems (use with -a)\n" + " -t, --types indicate the filesystem type\n" + " -c, --no-canonicalize don't canonicalize paths\n" + " -i, --internal-only don't call the mount. helpers\n" + " -l, --show-labels lists all mounts with LABELs\n" + + "\nSource:\n" + " -L, --label