--- hurd/fsys.defs | 8 ++ libdiskfs/Makefile | 3 +- libdiskfs/dir-lookup.c | 5 + libdiskfs/diskfs.h | 3 + libdiskfs/file-set-trans.c | 4 + libdiskfs/fsys-get-translator-info.c | 61 +++++++++++ libdiskfs/fsys-getroot.c | 3 +- libdiskfs/peropen-make.c | 8 ++ libdiskfs/peropen-rele.c | 1 + libfshelp/Makefile | 3 +- libfshelp/fshelp.h | 12 +++ libfshelp/translator-list.c | 87 ++++++++++++++++ utils/Makefile | 8 +- utils/mtab.c | 187 ++++++++++++++++++++++++++++++++++ 14 files changed, 388 insertions(+), 5 deletions(-) create mode 100644 libdiskfs/fsys-get-translator-info.c create mode 100644 libfshelp/translator-list.c create mode 100644 utils/mtab.c
diff --git a/hurd/fsys.defs b/hurd/fsys.defs index 979a6cf..f816da0 100644 --- a/hurd/fsys.defs +++ b/hurd/fsys.defs @@ -127,3 +127,11 @@ routine fsys_get_options ( server: fsys_t; RPT out options: data_t, dealloc); + +/* Return the options describing the operation of the receiving + filesystem (sutiable for fsys_set_options). */ +routine fsys_get_translator_info ( + server: fsys_t; + RPT + out source: string_t; + out children: data_t); diff --git a/libdiskfs/Makefile b/libdiskfs/Makefile index c6b5c3f..2bfb1bf 100644 --- a/libdiskfs/Makefile +++ b/libdiskfs/Makefile @@ -34,7 +34,8 @@ IOSRCS= io-async-icky.c io-async.c io-duplicate.c io-get-conch.c io-revoke.c \ io-reauthenticate.c io-rel-conch.c io-restrict-auth.c io-seek.c \ io-select.c io-stat.c io-stubs.c io-write.c io-version.c io-sigio.c FSYSSRCS=fsys-getroot.c fsys-goaway.c fsys-startup.c fsys-getfile.c \ - fsys-options.c fsys-syncfs.c fsys-forward.c + fsys-options.c fsys-syncfs.c fsys-forward.c \ + fsys-get-translator-info.c IFSOCKSRCS=ifsock.c OTHERSRCS = conch-fetch.c conch-set.c dir-clear.c dir-init.c dir-renamed.c \ extern-inline.c \ diff --git a/libdiskfs/dir-lookup.c b/libdiskfs/dir-lookup.c index 923be03..31142ef 100644 --- a/libdiskfs/dir-lookup.c +++ b/libdiskfs/dir-lookup.c @@ -82,6 +82,11 @@ diskfs_S_dir_lookup (struct protid *dircred, goto gotit; } + free (dircred->po->path); + dircred->po->path = strdup(path); /* XXX is this the right place? */ + if (! dircred->po->path) + return ENOMEM; + dnp = dircred->po->np; pthread_mutex_lock (&dnp->lock); diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h index 0f9c1d3..2489517 100644 --- a/libdiskfs/diskfs.h +++ b/libdiskfs/diskfs.h @@ -69,6 +69,9 @@ struct peropen mach_port_t shadow_root_parent; /* If in a shadow tree, its root node in this translator. */ struct node *shadow_root; + + /* Path relative to the root of the translator. */ + char *path; }; /* A unique one of these exists for each node currently in use (and diff --git a/libdiskfs/file-set-trans.c b/libdiskfs/file-set-trans.c index 3798001..acd47bb 100644 --- a/libdiskfs/file-set-trans.c +++ b/libdiskfs/file-set-trans.c @@ -206,5 +206,9 @@ diskfs_S_file_set_translator (struct protid *cred, } pthread_mutex_unlock (&np->lock); + + if (! error && cred->po->path) + error = fshelp_add_translator (cred->po->path); + return error; } diff --git a/libdiskfs/fsys-get-translator-info.c b/libdiskfs/fsys-get-translator-info.c new file mode 100644 index 0000000..d882397 --- /dev/null +++ b/libdiskfs/fsys-get-translator-info.c @@ -0,0 +1,61 @@ +/* fsys_get_translator_info + + Copyright (C) 2013 Free Software Foundation, Inc. + + Written by Justus Winter <4win...@informatik.uni-hamburg.de> + + This file is part of the GNU Hurd. + + The GNU Hurd 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, or (at your option) + any later version. + + The GNU Hurd 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 for more details. + + You should have received a copy of the GNU General Public License + along with the GNU Hurd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "priv.h" +#include "fsys_S.h" + +/* Ask SERVER to provide fsys translation service for us. REQUESTOR is + the bootstrap port supplied to the original translator, and ARGV are + the command line arguments. If the recipient accepts the request, he + (or some delegate) should send fsys_startup to REQUESTOR to start the + filesystem up. */ +error_t +diskfs_S_fsys_get_translator_info (mach_port_t server, + mach_port_t reply, + mach_msg_type_name_t replyPoly, + string_t source, + char **children, + mach_msg_type_number_t *children_len) +{ + error_t err; + + source[0] = 0; + /* Let the translator provide a more accurate device. */ + /* sth along the lines of: + if (diskfs_get_device) + source = diskfs_get_device(); + */ + + char *c = NULL; + size_t c_len = 0; + + err = fshelp_get_translators (&c, &c_len); + if (err) + goto errout; + + err = iohelp_return_malloced_buffer (c, c_len, children, children_len); + c = NULL; /* c was freed by iohelp_return_malloced_buffer. */ + + errout: + free (c); + return err; +} diff --git a/libdiskfs/fsys-getroot.c b/libdiskfs/fsys-getroot.c index 2e11da4..39973a8 100644 --- a/libdiskfs/fsys-getroot.c +++ b/libdiskfs/fsys-getroot.c @@ -51,7 +51,8 @@ diskfs_S_fsys_getroot (fsys_t controlport, { root_parent: dotdot, shadow_root_parent: MACH_PORT_NULL, - shadow_root: _diskfs_chroot_directory ? diskfs_root_node : NULL /* XXX */ + shadow_root: _diskfs_chroot_directory ? diskfs_root_node : NULL, /* XXX */ + path: NULL, }; if (!pt) diff --git a/libdiskfs/peropen-make.c b/libdiskfs/peropen-make.c index d37516c..d0ac698 100644 --- a/libdiskfs/peropen-make.c +++ b/libdiskfs/peropen-make.c @@ -34,6 +34,7 @@ diskfs_make_peropen (struct node *np, int flags, struct peropen *context, po->refcnt = 0; po->openstat = flags; po->np = np; + po->path = NULL; if (context) { @@ -50,6 +51,13 @@ diskfs_make_peropen (struct node *np, int flags, struct peropen *context, if (po->shadow_root_parent != MACH_PORT_NULL) mach_port_mod_refs (mach_task_self (), po->shadow_root_parent, MACH_PORT_RIGHT_SEND, 1); + + if (context->path) + { + po->path = strdup (context->path); + if (! po->path) + return ENOMEM; + } } else { diff --git a/libdiskfs/peropen-rele.c b/libdiskfs/peropen-rele.c index 08276ec..d3f7492 100644 --- a/libdiskfs/peropen-rele.c +++ b/libdiskfs/peropen-rele.c @@ -45,5 +45,6 @@ diskfs_release_peropen (struct peropen *po) diskfs_nput (po->np); + free (po->path); free (po); } diff --git a/libfshelp/Makefile b/libfshelp/Makefile index 4de3837..6ba6a14 100644 --- a/libfshelp/Makefile +++ b/libfshelp/Makefile @@ -20,6 +20,7 @@ makemode := library libname = libfshelp SRCS = lock-acquire.c lock-init.c \ + translator-list.c \ start-translator-long.c start-translator.c \ fetch-root.c transbox-init.c set-active.c fetch-control.c \ drop-transbox.c translated.c \ @@ -32,7 +33,7 @@ SRCS = lock-acquire.c lock-init.c \ touch.c installhdrs = fshelp.h -HURDLIBS = shouldbeinlibc iohelp ports +HURDLIBS = shouldbeinlibc iohelp ports ihash LDLIBS += -lpthread OBJS = $(subst .c,.o,$(SRCS)) diff --git a/libfshelp/fshelp.h b/libfshelp/fshelp.h index cf39fbc..ce9b0ae 100644 --- a/libfshelp/fshelp.h +++ b/libfshelp/fshelp.h @@ -32,6 +32,18 @@ #include <maptime.h> +/* XXX */ +/* XXX */ + +/* XXX */ +error_t +fshelp_add_translator (const char *name); + +/* XXX */ +error_t +fshelp_get_translators (char **translators, size_t *translators_len); + + /* Passive translator linkage */ /* These routines are self-contained and start passive translators, returning the control port. They do not require multi threading diff --git a/libfshelp/translator-list.c b/libfshelp/translator-list.c new file mode 100644 index 0000000..4a4524c --- /dev/null +++ b/libfshelp/translator-list.c @@ -0,0 +1,87 @@ +/* + Copyright (C) 2013 Free Software Foundation + Written by Justus Winter <4win...@informatik.uni-hamburg.de> + + This file is part of the GNU Hurd. + + 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, or (at + your option) any later version. + + This program 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 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <stdlib.h> +#include <string.h> +#include <argz.h> +#include <pthread.h> +#include <hurd/ihash.h> + +/* XXX */ +//typedef char * translator_ihash_entry; + +/* XXX */ +static struct hurd_ihash translator_ihash + = HURD_IHASH_INITIALIZER (HURD_IHASH_NO_LOCP); + +static pthread_mutex_t translator_ihash_lock = PTHREAD_MUTEX_INITIALIZER; + +/* XXX */ +static void +translator_ihash_cleanup (void *element, void *arg) +{ + free (element); +} + +error_t +fshelp_add_translator (const char *name) +{ + error_t err = 0; + pthread_mutex_lock (&translator_ihash_lock); + + if (! translator_ihash.cleanup) + hurd_ihash_set_cleanup (&translator_ihash, translator_ihash_cleanup, NULL); + + HURD_IHASH_ITERATE (&translator_ihash, value) + if (strcmp (name, (char *) value) == 0) + goto out; /* Entry exists, do nothing. */ + + name = strdup (name); + if (! name) + { + err = errno; + goto out; + } + + err = hurd_ihash_add (&translator_ihash, (hurd_ihash_key_t) name, name); + if (err) + free (name); + + out: + pthread_mutex_unlock (&translator_ihash_lock); + return err; +} + +error_t +fshelp_get_translators (char **translators, size_t *translators_len) +{ + error_t err = 0; + pthread_mutex_lock (&translator_ihash_lock); + + HURD_IHASH_ITERATE (&translator_ihash, value) + { + err = argz_add (translators, translators_len, (char *) value); + if (err) + break; + } + + pthread_mutex_unlock (&translator_ihash_lock); + return err; +} diff --git a/utils/Makefile b/utils/Makefile index e3bed0b..8a998f3 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -21,14 +21,16 @@ makemode := utilities targets = shd ps settrans showtrans syncfs fsysopts \ storeinfo login w uptime ids loginpr sush vmstat portinfo \ devprobe vminfo addauth rmauth unsu setauth ftpcp ftpdir storecat \ - storeread msgport rpctrace mount gcore fakeauth fakeroot remap + storeread msgport rpctrace mount gcore fakeauth fakeroot remap \ + mtab special-targets = loginpr sush uptime fakeroot remap SRCS = shd.c ps.c settrans.c syncfs.c showtrans.c addauth.c rmauth.c \ fsysopts.c storeinfo.c login.c loginpr.sh sush.sh w.c \ uptime.sh psout.c ids.c vmstat.c portinfo.c devprobe.c vminfo.c \ parse.c frobauth.c frobauth-mod.c setauth.c pids.c nonsugid.c \ unsu.c ftpcp.c ftpdir.c storeread.c storecat.c msgport.c \ - rpctrace.c mount.c gcore.c fakeauth.c fakeroot.sh remap.sh + rpctrace.c mount.c gcore.c fakeauth.c fakeroot.sh remap.sh \ + mtab.c OBJS = $(filter-out %.sh,$(SRCS:.c=.o)) HURDLIBS = ps ihash store fshelp ports ftpconn shouldbeinlibc @@ -77,3 +79,5 @@ mount: ../sutils/fstab.o ../sutils/clookup.o \ ../sutils/fstab.o ../sutils/clookup.o: FORCE $(MAKE) -C $(@D) $(@F) FORCE: + +mtab: fsysUser.o diff --git a/utils/mtab.c b/utils/mtab.c new file mode 100644 index 0000000..0c91168 --- /dev/null +++ b/utils/mtab.c @@ -0,0 +1,187 @@ +/* XXX + + Copyright (C) 2013 Free Software Foundation, Inc. + + Written by Justus Winter <4win...@informatik.uni-hamburg.de> + + 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, or (at + your option) any later version. + + This program 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 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <argp.h> +#include <fcntl.h> +#include <unistd.h> + +#include <error.h> +#include <argz.h> +#include <version.h> + +#include <hurd/fsys.h> + +#include "fsys_U.h" + +const char *argp_program_version = STANDARD_HURD_VERSION (fsysopts); + +static struct argp_option options[] = +{ + {"insecure", 'I', 0, 0, "Follow translators not started by root"}, + {} +}; +static char *args_doc = "PATH"; +static char *doc = "XXX"; + + +error_t +print_translator_info (const char *path, int insecure); + +error_t +map_device_to_path (const char *device, char **path); + +int +main (int argc, char *argv[]) +{ + error_t err; + char *path = NULL; + int insecure = 0; + + /* Parse a command line option. */ + error_t parse_opt (int key, char *arg, struct argp_state *state) + { + switch (key) + { + case 'I': + insecure = 1; + break; + + case ARGP_KEY_ARG: + path = arg; + break; + + case ARGP_KEY_NO_ARGS: + argp_usage (state); + return EINVAL; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; + } + + struct argp argp = {options, parse_opt, args_doc, doc}; + + argp_parse (&argp, argc, argv, ARGP_IN_ORDER, 0, 0); + + err = print_translator_info (path, insecure); + if (err) + error (5, err, "%s", path); + + return 0; +} + +/* XXX */ +error_t +print_translator_info (const char *path, int insecure) +{ + if (! insecure) + { + /* XXX check who owns the translator */ + } + + file_t node = file_name_lookup (path, 0, 0666); + if (node == MACH_PORT_NULL) + error (1, errno, "%s", path); + + error_t err; + char *argz = 0; + size_t argz_len = 0; + err = file_get_fs_options (node, &argz, &argz_len); + if (err) + error (5, err, "%s", path); + + size_t count = argz_count (argz, argz_len); + char **argv = malloc ((count + 1) * sizeof (char *)); + if (! argv) + return ENOMEM; + + argz_extract (argz, argz_len, argv); + + char *type = strdup (argv[0]); + if (! type) + return ENOMEM; + + char *options = NULL; + size_t options_len = 0; + + for (int i = 1; i < count - 1; i++) + { + char *v = argv[i]; + + if (*v == '-') + v++; + if (*v == '-') + v++; + + err = argz_add (&options, &options_len, v); + if (err) + return err; + } + + argz_stringify (options, options_len, ','); + + string_t source; + char *children = NULL; + size_t childrenCnt = 0; + err = fsys_get_translator_info (node, source, &children, &childrenCnt); + if (err) + error (5, err, "get_translator_info"); + + char *src = NULL; + if (*source != '\0') + src = source; + else + map_device_to_path (argv[count - 1], &src); + + printf ("%s %s %s %s 0 0\n", src, path, type, options); + + if (childrenCnt) + for (char *c = children; c; c = argz_next (children, childrenCnt, c)) + { + char *p; + asprintf (&p, "%s/%s", path, c); + if (! p) + return ENOMEM; + + print_translator_info (p, insecure); + } + + return 0; +} + +/* XXX */ +error_t +map_device_to_path (const char *device, char **path) +{ + if (strcmp (device, "device:") == 0) + asprintf (path, "/dev/%s", &device[7]); + else + *path = strdup ("none"); + + if (! *path) + return ENOMEM; + + return 0; +} -- 1.7.10.4