[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 1/1] trans/symlink.c: Rewrite on top of trivfs
From: |
Sergey Bugaev |
Subject: |
[PATCH 1/1] trans/symlink.c: Rewrite on top of trivfs |
Date: |
Mon, 21 Jun 2021 16:20:24 +0300 |
---
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