--- trans/Makefile | 10 +- trans/symlink.c | 243 +++++++++++++++++++++++++++--------------------- 2 files changed, 137 insertions(+), 116 deletions(-)
diff --git a/trans/Makefile b/trans/Makefile index 6cf50e7a..c04220a2 100644 --- a/trans/Makefile +++ b/trans/Makefile @@ -25,7 +25,7 @@ targets = symlink firmlink ifsock magic null fifo new-fifo fwd crash \ SRCS = ifsock.c symlink.c magic.c null.c fifo.c new-fifo.c fwd.c \ crash.c firmlink.c password.c hello.c hello-mt.c streamio.c \ fakeroot.c proxy-defpager.c remap.c mtab.c -OBJS = $(SRCS:.c=.o) fsysServer.o ifsockServer.o passwordServer.o \ +OBJS = $(SRCS:.c=.o) ifsockServer.o passwordServer.o \ crashServer.o crash_replyUser.o msgServer.o \ default_pagerServer.o default_pagerUser.o \ device_replyServer.o elfcore.o startup_notifyServer.o @@ -48,11 +48,6 @@ device_reply-MIGSFLAGS=\ "-DMACH_PAYLOAD_TO_PORT=ports_payload_get_name" \ "-DDEVICE_IMPORTS=import \"$(srcdir)/../libports/ports.h\";" -# fsysServer is only used by the symlink translator which does not use -# libports. Disable the default payload to port conversion. -fsys-MIGSFLAGS = "-DHURD_DEFAULT_PAYLOAD_TO_PORT=1" -fsysServer-CFLAGS = "-DMIG_EOPNOTSUPP=EOPNOTSUPP" - # If we have a configured tree, include the configuration so that we # can conditionally build translators. ifneq (,$(wildcard ../config.make)) @@ -76,11 +71,10 @@ mtab: fsysUser.o password: passwordServer.o proxy-defpager: default_pagerServer.o default_pagerUser.o streamio: device_replyServer.o -symlink: fsysServer.o fakeroot: ../libnetfs/libnetfs.a fifo new-fifo: ../libpipe/libpipe.a -crash fifo firmlink hello hello-mt ifsock magic mtab new-fifo null password proxy-defpager remap streamio: ../libtrivfs/libtrivfs.a +crash fifo firmlink hello hello-mt ifsock magic mtab new-fifo null password proxy-defpager remap streamio symlink: ../libtrivfs/libtrivfs.a $(targets): ../libfshelp/libfshelp.a \ ../libihash/libihash.a \ ../libiohelp/libiohelp.a \ diff --git a/trans/symlink.c b/trans/symlink.c index 80d60f64..63c94048 100644 --- a/trans/symlink.c +++ b/trans/symlink.c @@ -1,5 +1,5 @@ /* Translator for S_IFLNK nodes - Copyright (C) 1994, 2000, 2001, 2002 Free Software Foundation + Copyright (C) 1994, 2000, 2001, 2002, 2021 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -15,30 +15,137 @@ 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 <hurd/fsys.h> -#include <fcntl.h> +#include <argz.h> #include <errno.h> #include <error.h> +#include <fcntl.h> +#include <hurd/trivfs.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mman.h> #include <version.h> -#include "fsys_S.h" -mach_port_t realnode; - -/* We return this for O_NOLINK lookups */ -mach_port_t realnodenoauth; - -/* We return this for non O_NOLINK lookups */ -char *linktarget; - -extern int fsys_server (mach_msg_header_t *, mach_msg_header_t *); +char *link_target; +size_t link_target_len; const char *argp_program_version = STANDARD_HURD_VERSION (symlink); +int trivfs_fsid = 0; +int trivfs_fstype = FSTYPE_MISC; + +int trivfs_support_read = 1; +int trivfs_support_write = 0; +int trivfs_support_exec = 0; + +int trivfs_allow_open = O_READ; + +void +trivfs_modify_stat (struct trivfs_protid *cred, io_statbuf_t *st) +{ + st->st_size = link_target_len; + st->st_blocks = 0; + st->st_mode = S_IFLNK | 0777; +} + +kern_return_t +trivfs_S_io_read (struct trivfs_protid *cred, + mach_port_t reply, + mach_msg_type_name_t reply_type, + data_t *data, + mach_msg_type_number_t *data_len, + loff_t offset, + vm_size_t amount) +{ + if (!cred) + return EOPNOTSUPP; + else if (!(cred->po->openmodes & O_READ)) + return EBADF; + + if (amount > link_target_len) + amount = link_target_len; + + if (amount > *data_len) + { + /* Try to make more space. */ + void *buffer; + + buffer = mmap (0, amount, PROT_READ | PROT_WRITE, MAP_ANON, 0, 0); + if (buffer == MAP_FAILED) + amount = *data_len; + else + { + *data = buffer; + *data_len = amount; + } + } + else + *data_len = amount; + + memcpy (*data, link_target, amount); + return 0; +} + +error_t +get_root (struct trivfs_control *fsys, + mach_port_t reply_port, + mach_msg_type_name_t reply_port_type, + mach_port_t dotdot, + uid_t *uids, size_t nuids, + uid_t *gids, size_t ngids, + int flags, + retry_type *do_retry, + char *retry_name, + mach_port_t *retry_node, + mach_msg_type_name_t *retry_node_type) +{ + /* If O_NOLINK is specified, proceed + with opening the link itself. */ + if (flags & O_NOLINK) + return EAGAIN; + + strncpy (retry_name, link_target, sizeof (string_t)); + + if (link_target[0] == '/') + { + /* Tell the user to retry from their root. */ + *do_retry = FS_RETRY_MAGICAL; + *retry_node = MACH_PORT_NULL; + *retry_node_type = MACH_MSG_TYPE_COPY_SEND; + + if (dotdot != MACH_PORT_NULL) + mach_port_deallocate (mach_task_self (), dotdot); + } + else + { + /* Tell the user to retry relative to dotdot. Since dotdot + is unauthenticated, they should reauth it first. */ + *do_retry = FS_RETRY_REAUTH; + *retry_node = dotdot; + *retry_node_type = MACH_MSG_TYPE_MOVE_SEND; + } + + return 0; +} + +error_t (*trivfs_getroot_hook)() = get_root; + +error_t +trivfs_append_args (struct trivfs_control *fsys, + char **argz, size_t *argz_len) +{ + return argz_add (argz, argz_len, link_target); +} + +error_t +trivfs_goaway (struct trivfs_control *cntl, int flags) +{ + exit (0); +} + + + static const struct argp_option options[] = { { 0 } @@ -57,7 +164,10 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) { if (key == ARGP_KEY_ARG && state->arg_num == 0) - linktarget = arg; + { + link_target = arg; + link_target_len = strlen (link_target); + } else if (key == ARGP_KEY_ARG || key == ARGP_KEY_NO_ARGS) argp_usage (state); else @@ -71,107 +181,24 @@ static struct argp argp = { options, parse_opt, args_doc, doc }; int main (int argc, char **argv) { - mach_port_t bootstrap; - mach_port_t control; error_t err; + mach_port_t bootstrap; + struct trivfs_control *fsys; /* Parse our options... */ argp_parse (&argp, argc, argv, 0, 0, 0); - task_get_bootstrap_port (mach_task_self (), &bootstrap); + err = task_get_bootstrap_port (mach_task_self (), &bootstrap); + assert_perror_backtrace (err); if (bootstrap == MACH_PORT_NULL) error (1, 0, "Must be started as a translator"); - linktarget = argv[1]; - - /* Reply to our parent */ - mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &control); - mach_port_insert_right (mach_task_self (), control, control, - MACH_MSG_TYPE_MAKE_SEND); - err = - fsys_startup (bootstrap, 0, control, MACH_MSG_TYPE_COPY_SEND, &realnode); - mach_port_deallocate (mach_task_self (), control); + err = trivfs_startup (bootstrap, 0, 0, 0, 0, 0, &fsys); mach_port_deallocate (mach_task_self (), bootstrap); if (err) - error (1, err, "Starting up translator"); + error(3, err, "trivfs_startup"); - io_restrict_auth (realnode, &realnodenoauth, 0, 0, 0, 0); - mach_port_deallocate (mach_task_self (), realnode); + ports_manage_port_operations_one_thread (fsys->pi.bucket, trivfs_demuxer, 0); - /* Mark us as important. */ - mach_port_t proc = getproc (); - if (proc == MACH_PORT_NULL) - error (2, err, "cannot get a handle to our process"); - - err = proc_mark_important (proc); - /* This might fail due to permissions or because the old proc server - is still running, ignore any such errors. */ - if (err && err != EPERM && err != EMIG_BAD_ID) - error (2, err, "Cannot mark us as important"); - - mach_port_deallocate (mach_task_self (), proc); - - /* Launch */ - while (1) - { - /* The timeout here is 10 minutes */ - err = mach_msg_server_timeout (fsys_server, 0, control, - MACH_RCV_TIMEOUT, 1000 * 60 * 10); - if (err == MACH_RCV_TIMED_OUT) - exit (0); - } -} - -error_t -S_fsys_getroot (mach_port_t fsys_t, - mach_port_t dotdotnode, - uid_t *uids, size_t nuids, - uid_t *gids, size_t ngids, - int flags, - retry_type *do_retry, - char *retry_name, - mach_port_t *ret, - mach_msg_type_name_t *rettype) -{ - if (flags & O_NOLINK) - { - /* Return our underlying node. */ - *ret = realnodenoauth; - *rettype = MACH_MSG_TYPE_COPY_SEND; - *do_retry = FS_RETRY_REAUTH; - retry_name[0] = '\0'; - return 0; - } - else - { - /* Return telling the user to follow the link */ - strcpy (retry_name, linktarget); - if (linktarget[0] == '/') - { - *do_retry = FS_RETRY_MAGICAL; - *ret = MACH_PORT_NULL; - *rettype = MACH_MSG_TYPE_COPY_SEND; - } - else - { - *do_retry = FS_RETRY_REAUTH; - *ret = dotdotnode; - *rettype = MACH_MSG_TYPE_MOVE_SEND; - } - } - return 0; -} - -error_t -S_fsys_goaway (mach_port_t control, int flags) -{ - exit (0); -} - -error_t -S_fsys_syncfs (mach_port_t control, - int wait, - int recurse) -{ return 0; } -- 2.31.1