bug-hurd
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]