guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

56/62: DRAFT gnu: hurd: Add `libhurdutil' patch.


From: guix-commits
Subject: 56/62: DRAFT gnu: hurd: Add `libhurdutil' patch.
Date: Sat, 11 Apr 2020 11:35:57 -0400 (EDT)

janneke pushed a commit to branch wip-hurd-vm
in repository guix.

commit 3234621a957b39f9646c5b5778fbdba31c080a03
Author: Jan (janneke) Nieuwenhuizen <address@hidden>
AuthorDate: Tue Apr 7 08:23:53 2020 +0200

    DRAFT gnu: hurd: Add `libhurdutil' patch.
    
    * gnu/packages/patches/hurd-libhurdutil.patch: New file.
    * gnu/local.mk (dist_patch_DATA): Add it.
    * gnu/packages/hurd.scm (hurd)[source]: Use it.
---
 gnu/local.mk                                |    1 +
 gnu/packages/hurd.scm                       |    3 +-
 gnu/packages/patches/hurd-libhurdutil.patch | 1111 +++++++++++++++++++++++++++
 3 files changed, 1114 insertions(+), 1 deletion(-)

diff --git a/gnu/local.mk b/gnu/local.mk
index c163d12..2100393 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1054,6 +1054,7 @@ dist_patch_DATA =                                         
\
   %D%/packages/patches/hdf-eos5-fortrantests.patch             \
   %D%/packages/patches/hubbub-sort-entities.patch              \
   %D%/packages/patches/hurd-cross.patch                                \
+  %D%/packages/patches/hurd-libhurdutil.patch                  \
   %D%/packages/patches/hplip-remove-imageprocessor.patch       \
   %D%/packages/patches/hydra-disable-darcs-test.patch          \
   %D%/packages/patches/icecat-makeicecat.patch                 \
diff --git a/gnu/packages/hurd.scm b/gnu/packages/hurd.scm
index 90e39a2..5a56714 100644
--- a/gnu/packages/hurd.scm
+++ b/gnu/packages/hurd.scm
@@ -358,7 +358,8 @@ boot, since this cannot be done from GNU/Linux."
     (name "hurd")
     (version (package-version hurd-headers))
     (source (origin (inherit (package-source hurd-headers))
-                    (patches (search-patches "hurd-cross.patch"))))
+                    (patches (search-patches "hurd-cross.patch"
+                                             "hurd-libhurdutil.patch"))))
     (arguments
      `(#:phases
        (modify-phases %standard-phases
diff --git a/gnu/packages/patches/hurd-libhurdutil.patch 
b/gnu/packages/patches/hurd-libhurdutil.patch
new file mode 100644
index 0000000..f4788c8
--- /dev/null
+++ b/gnu/packages/patches/hurd-libhurdutil.patch
@@ -0,0 +1,1111 @@
+This patch is from Manolis' GSoC work, not upstreamed yet.
+
+Forward ported from:
+
+    
https://github.com/Phant0mas/Hurd/commit/3501ee22ad4150b3b2cf9a386d2350b9a68aecd8.patch
+
+See also:
+    https://lists.gnu.org/archive/html/guix-devel/2020-03/msg00174.html
+
+From 1a6ba95e260c044bf4f84c8c8887fbdcd6c4fce5 Mon Sep 17 00:00:00 2001
+From: Manolis Ragkousis <address@hidden>
+Date: Wed, 25 May 2016 17:45:28 +0300
+Subject: [PATCH] libhurdutil: New library containing utils to be used by Guix.
+
+* libhurdutil/hurdutil.h: New file.
+* libhurdutil/settrans.c: New file.
+* libhurdutil/Makefile: New file.
+* utils/Makefile (HURDLIBS, settrans): Use the new library.
+* utils/settrans.c: Update to use the new library.
+* Makefile: (lib-subdirs): Add library.
+---
+ Makefile               |   2 +-
+ libhurdutil/Makefile   |  28 +++
+ libhurdutil/hurdutil.h |  84 +++++++
+ libhurdutil/settrans.c | 377 ++++++++++++++++++++++++++++++++
+ utils/Makefile         |   4 +-
+ utils/settrans.c       | 482 ++++++++++-------------------------------
+ 6 files changed, 604 insertions(+), 373 deletions(-)
+ create mode 100644 libhurdutil/Makefile
+ create mode 100644 libhurdutil/hurdutil.h
+ create mode 100644 libhurdutil/settrans.c
+
+diff --git a/Makefile b/Makefile
+index 6b1e8066..f7a8224d 100644
+--- a/Makefile
++++ b/Makefile
+@@ -29,7 +29,7 @@ include ./Makeconf
+ lib-subdirs = libshouldbeinlibc libihash libiohelp libports libthreads \
+             libpager libfshelp libdiskfs libtrivfs libps \
+             libnetfs libpipe libstore libhurdbugaddr libftpconn libcons \
+-            libhurd-slab \
++            libhurd-slab libhurdutil \
+             libbpf \
+             libmachdev \
+ 
+diff --git a/libhurdutil/Makefile b/libhurdutil/Makefile
+new file mode 100644
+index 00000000..6d2dc7f8
+--- /dev/null
++++ b/libhurdutil/Makefile
+@@ -0,0 +1,28 @@
++#   Copyright (C) 2016 Free Software Foundation, Inc.
++#
++#   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.  If not, see <http://www.gnu.org/licenses/>.
++
++dir := libhurdutil
++makemode := library
++
++libname := libhurdutil
++SRCS = settrans.c
++installhdrs = hurdutil.h
++
++HURDLIBS= fshelp
++OBJS = $(SRCS:.c=.o)
++
++include ../Makeconf
+diff --git a/libhurdutil/hurdutil.h b/libhurdutil/hurdutil.h
+new file mode 100644
+index 00000000..2ff1e985
+--- /dev/null
++++ b/libhurdutil/hurdutil.h
+@@ -0,0 +1,84 @@
++/* hurdutil.h - Hurd utils interface.
++   Copyright (C) 2016 Free Software Foundation, Inc.
++   Written by Manolis Fragkiskos Ragkousis <address@hidden>.
++
++   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.  If not, see <http://www.gnu.org/licenses/>.*/
++
++#ifndef _HURD_UTIL_H
++#define _HURD_UTIL_H
++
++#include <errno.h>
++#include <sys/types.h>
++#include <limits.h>
++#include <stdint.h>
++#include <stddef.h>
++
++#include <hurd/fsys.h>
++
++struct settrans_context
++{
++  /* The name of the node we're putting the translator on. */
++  char *node_name;
++
++  /* Flags to pass to file_set_translator.  */
++  int lookup_flags;
++  int goaway_flags;
++
++  /* Various option flags.  */
++  int passive : 1;
++  int active : 1;
++  int keep_active : 1;
++  int pause : 1;
++  int kill_active : 1;
++  int orphan : 1;
++  int start : 1;
++  int stack : 1;
++  int excl : 1;
++  int timeout;
++  char *pid_file;
++  char *underlying_node_name;
++  int underlying_lookup_flags;
++  char **chroot_command;
++  char *chroot_chdir;
++
++  /* The translator's arg vector, in '\0' separated format.  */
++  char *argz;
++  size_t argz_len;
++};
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++/* Initialize the flags to be used. */
++void settrans_context_init (struct settrans_context *context);
++
++/* Release the memory allocated. */
++void settrans_context_cleanup (struct settrans_context *context);
++
++/* Create the struct containing the flags and initialize them.
++   If a memory allocation error occurs, ENOMEM is returned,
++   otherwise 0.*/
++error_t settrans_context_create (struct settrans_context **context);
++
++/* Set a translator according to the flags passed. On success return 0. */
++error_t settrans(struct settrans_context *context);
++
++#ifdef __cplusplus
++}   /* extern "C" */
++#endif
++
++#endif /* _HURD_UTIL_H */
+diff --git a/libhurdutil/settrans.c b/libhurdutil/settrans.c
+new file mode 100644
+index 00000000..245fae76
+--- /dev/null
++++ b/libhurdutil/settrans.c
+@@ -0,0 +1,377 @@
++/* settrans.c - Set a file's translator.
++
++   Copyright (C) 1995,96,97,98,2001,02,13,14,16
++   Free Software Foundation, Inc.
++   Written by Miles Bader <address@hidden>
++   Written by Manolis Fragkiskos Ragkousis <address@hidden>.
++
++   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.  If not, see <http://www.gnu.org/licenses/>.*/
++
++#include <errno.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <stdint.h>
++#include <assert-backtrace.h>
++#include <fcntl.h>
++#include <argp.h>
++#include <unistd.h>
++#include <sys/wait.h>
++
++#include <hurd.h>
++#include <error.h>
++#include <argz.h>
++#include <hurd/fshelp.h>
++#include <hurd/lookup.h>
++
++
++#include "hurdutil.h"
++
++#define DEFAULT_TIMEOUT 60
++
++/* Authentication of the current process.  */
++uid_t *uids;
++gid_t *gids;
++size_t uids_len, gids_len;
++
++/* Initialize and populate the uids and gids vectors.  */
++error_t
++get_credentials (void)
++{
++  /* Fetch uids...  */
++  uids_len = geteuids (0, 0);
++  if (uids_len < 0)
++    return errno;
++
++  uids = malloc (uids_len * sizeof (uid_t));
++  if (! uids)
++    return ENOMEM;
++
++  uids_len = geteuids (uids_len, uids);
++  if (uids_len < 0)
++    return errno;
++
++  /* ... and gids.  */
++  gids_len = getgroups (0, 0);
++  if (gids_len < 0)
++    return errno;
++
++  gids = malloc (gids_len * sizeof (gid_t));
++  if (! uids)
++    return ENOMEM;
++
++  gids_len = getgroups (gids_len, gids);
++  if (gids_len < 0)
++    return errno;
++
++  return 0;
++}
++
++/* ---------------------------------------------------------------- */
++
++void
++settrans_context_init (struct settrans_context *context)
++{
++  context->node_name = 0;
++
++  context->lookup_flags = O_NOTRANS;
++  context->goaway_flags = 0;
++
++  context->passive = 0;
++  context->active = 0;
++  context->keep_active = 0;
++  context->pause = 0;
++  context->kill_active = 0;
++  context->orphan = 0;
++  context->start = 0;
++  context->stack = 0;
++  context->excl = 0;
++  context->timeout = DEFAULT_TIMEOUT * 1000; /* ms */
++  context->pid_file = 0;
++  context->underlying_node_name = NULL;
++  context->chroot_command = 0;
++  context->chroot_chdir = "/";
++
++  context->argz;
++  context->argz_len;
++}
++
++void
++settrans_context_cleanup (struct settrans_context *context)
++{
++  free(context);
++}
++
++error_t
++settrans_context_create (struct settrans_context **context)
++{
++  *context = malloc (sizeof (struct settrans_context));
++  if (*context == NULL)
++    return ENOMEM;
++
++  settrans_context_init(*context);
++
++  return 0;
++}
++
++error_t
++settrans(struct settrans_context *context)
++{
++  error_t err;
++
++  /* The filesystem node we're putting a translator on.  */
++  char *node_name = context->node_name;
++  file_t node;
++
++  /* The translator's arg vector, in '\0' separated format.  */
++  char *argz = context->argz;
++  size_t argz_len = context->argz_len;
++
++  /* The control port for any active translator we start up.  */
++  fsys_t active_control = MACH_PORT_NULL;
++
++  /* Flags to pass to file_set_translator.  */
++  int active_flags = 0;
++  int passive_flags = 0;
++  int lookup_flags = context->lookup_flags;
++  int goaway_flags = context->goaway_flags;
++
++  /* Various option flags.  */
++  int passive = context->passive;
++  int active = context->active;
++  int keep_active = context->keep_active;
++  int pause = context->pause;
++  int kill_active = context->kill_active;
++  int orphan = context->orphan;
++  int start = context->start;
++  int stack = context->stack;
++  char *pid_file = context->pid_file;
++  unsigned int excl = context->excl;
++  int timeout = context->timeout; /* ms */
++  char *underlying_node_name = context->underlying_node_name;
++  int underlying_lookup_flags = context->underlying_lookup_flags;
++  char **chroot_command = context->chroot_command;
++  char *chroot_chdir = context->chroot_chdir;
++
++  if (stack)
++    {
++      underlying_node_name = node_name;
++      underlying_lookup_flags = lookup_flags && ~O_NOTRANS;
++    }
++  else
++    underlying_lookup_flags = lookup_flags;
++
++
++  if (!active && !passive && !chroot_command)
++    passive = 1;              /* By default, set the passive translator.  */
++
++  if (passive)
++    passive_flags = FS_TRANS_SET | (excl ? FS_TRANS_EXCL : 0);
++  if (active)
++    active_flags = FS_TRANS_SET | (excl ? FS_TRANS_EXCL : 0)
++      | (orphan ? FS_TRANS_ORPHAN : 0);
++
++  if (passive && !active)
++    {
++      /* When setting just the passive, decide what to do with any active.  */
++      if (kill_active)
++        /* Make it go away.  */
++        active_flags = FS_TRANS_SET;
++      else if (! keep_active)
++        /* Ensure that there isn't one.  */
++        active_flags = FS_TRANS_SET | FS_TRANS_EXCL;
++    }
++
++  if (start)
++    {
++      /* Retrieve the passive translator record in argz.  */
++      mach_port_t node = file_name_lookup (node_name, lookup_flags, 0);
++      if (node == MACH_PORT_NULL)
++        error (4, errno, "%s", node_name);
++
++      char buf[1024];
++      argz = buf;
++      argz_len = sizeof (buf);
++
++      err = file_get_translator (node, &argz, &argz_len);
++      if (err == EINVAL)
++        error (4, 0, "%s: no passive translator record found", node_name);
++      if (err)
++        error (4, err, "%s", node_name);
++
++      mach_port_deallocate (mach_task_self (), node);
++    }
++
++  if ((active || chroot_command) && argz_len > 0)
++    {
++      /* Error during file lookup; we use this to avoid duplicating error
++         messages.  */
++      error_t open_err = 0;
++
++      /* The callback to start_translator opens NODE as a side effect.  */
++      error_t open_node (int flags,
++                         mach_port_t *underlying,
++                         mach_msg_type_name_t *underlying_type,
++                         task_t task, void *cookie)
++      {
++        if (pause)
++          {
++            fprintf (stderr, "Translator pid: %d\nPausing...",
++                     task2pid (task));
++            getchar ();
++          }
++
++        if (pid_file != NULL)
++          {
++            FILE *h;
++            h = fopen (pid_file, "w");
++            if (h == NULL)
++              error (4, errno, "Failed to open pid file");
++
++            fprintf (h, "%i\n", task2pid (task));
++            fclose (h);
++          }
++
++        node = file_name_lookup (node_name, flags | lookup_flags, 0666);
++        if (node == MACH_PORT_NULL)
++          {
++            open_err = errno;
++            return open_err;
++          }
++
++        if (underlying_node_name)
++          {
++            *underlying = file_name_lookup (underlying_node_name,
++                                            flags | underlying_lookup_flags,
++                                            0666);
++            if (! MACH_PORT_VALID (*underlying))
++              {
++                /* For the error message.  */
++                node_name = underlying_node_name;
++                open_err = errno;
++                return open_err;
++              }
++          }
++        else
++          *underlying = node;
++        *underlying_type = MACH_MSG_TYPE_COPY_SEND;
++
++        return 0;
++      }
++      err = fshelp_start_translator (open_node, NULL, argz, argz, argz_len,
++                                     timeout, &active_control);
++      if (err)
++        /* If ERR is due to a problem opening the translated node, we print
++           that name, otherwise, the name of the translator.  */
++        error(4, err, "%s", (err == open_err) ? node_name : argz);
++    }
++  else
++    {
++      node = file_name_lookup(node_name, lookup_flags, 0666);
++      if (node == MACH_PORT_NULL)
++        error(1, errno, "%s", node_name);
++    }
++
++  if (active || passive)
++    {
++      err = file_set_translator (node,
++                                 passive_flags, active_flags, goaway_flags,
++                                 argz, argz_len,
++                                 active_control, MACH_MSG_TYPE_COPY_SEND);
++      if (err)
++        {
++          error (5, err, "%s", node_name);
++        }
++
++    }
++
++  if (chroot_command)
++    {
++      pid_t child;
++      int status;
++      switch ((child = fork ()))
++        {
++        case -1:
++          error (6, errno, "fork");
++
++        case 0:; /* Child.  */
++          /* We will act as the parent filesystem would for a lookup
++             of the active translator's root node, then use this port
++             as our root directory while we exec the command.  */
++
++          char retry_name[1024];      /* XXX */
++          retry_type do_retry;
++          mach_port_t root;
++          file_t executable;
++          char *prefixed_name;
++
++          err = get_credentials ();
++          if (err)
++            error (6, err, "getting credentials");
++
++          err = fsys_getroot (active_control,
++                              MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND,
++                              uids, uids_len, gids, gids_len, 0,
++                              &do_retry, retry_name, &root);
++          mach_port_deallocate (mach_task_self (), active_control);
++          if (err)
++            error (6, err, "fsys_getroot");
++          err = hurd_file_name_lookup_retry (&_hurd_ports_use, &getdport, 0,
++                                             do_retry, retry_name, 0, 0,
++                                             &root);
++          if (err)
++            error (6, err, "cannot resolve root port");
++
++          if (setcrdir (root))
++            error (7, errno, "cannot install root port");
++          mach_port_deallocate (mach_task_self (), root);
++          if (chdir (chroot_chdir))
++            error (8, errno, "%s", chroot_chdir);
++
++          /* Lookup executable in PATH.  */
++          executable = file_name_path_lookup (chroot_command[0],
++                                              getenv ("PATH"),
++                                              O_EXEC, 0,
++                                              &prefixed_name);
++          if (MACH_PORT_VALID (executable))
++            {
++              err = mach_port_deallocate (mach_task_self (), executable);
++              assert_perror_backtrace (err);
++              if (prefixed_name)
++                chroot_command[0] = prefixed_name;
++            }
++
++          execvp (chroot_command[0], chroot_command);
++          error (8, errno, "cannot execute %s", chroot_command[0]);
++          break;
++
++        default: /* Parent.  */
++          if (waitpid (child, &status, 0) != child)
++            error (8, errno, "waitpid on %d", child);
++
++          err = fsys_goaway (active_control, goaway_flags);
++          if (err && err != EBUSY)
++            error (9, err, "fsys_goaway");
++
++          if (WIFSIGNALED (status))
++            error (WTERMSIG (status) + 128, 0,
++                   "%s for child %d", strsignal (WTERMSIG (status)), child);
++          if (WEXITSTATUS (status) != 0)
++            error (WEXITSTATUS (status), 0,
++                   "Error %d for child %d", WEXITSTATUS (status), child);
++        }
++    }
++  return 0;
++}
+diff --git a/utils/Makefile b/utils/Makefile
+index 0cefd27b..f81472f1 100644
+--- a/utils/Makefile
++++ b/utils/Makefile
+@@ -34,7 +34,7 @@ SRCS = shd.c ps.c settrans.c syncfs.c showtrans.c addauth.c 
rmauth.c \
+       nullauth.c match-options.c msgids.c rpcscan.c
+ 
+ OBJS = $(filter-out %.sh,$(SRCS:.c=.o))
+-HURDLIBS = ps ihash store fshelp ports ftpconn shouldbeinlibc
++HURDLIBS = ps ihash store fshelp ports ftpconn shouldbeinlibc hurdutil
+ LDLIBS += -lpthread
+ login-LDLIBS = -lutil $(and $(HAVE_LIBCRYPT),-lcrypt)
+ addauth-LDLIBS = $(and $(HAVE_LIBCRYPT),-lcrypt)
+@@ -60,7 +60,7 @@ storeinfo storecat storeread: ../libstore/libstore.a
+ ftpcp ftpdir: ../libftpconn/libftpconn.a
+ mount umount: ../libihash/libihash.a
+ settrans: ../libfshelp/libfshelp.a ../libihash/libihash.a \
+-      ../libports/libports.a
++      ../libports/libports.a ../libhurdutil/libhurdutil.a
+ ps w ids settrans syncfs showtrans fsysopts storeinfo login vmstat portinfo \
+   devprobe vminfo addauth rmauth setauth unsu ftpcp ftpdir storeread \
+   storecat msgport mount umount nullauth rpctrace: \
+diff --git a/utils/settrans.c b/utils/settrans.c
+index 9c9f087e..0b580392 100644
+--- a/utils/settrans.c
++++ b/utils/settrans.c
+@@ -3,6 +3,7 @@
+    Copyright (C) 1995,96,97,98,2001,02,13,14
+      Free Software Foundation, Inc.
+    Written by Miles Bader <address@hidden>
++   Revised by Manolis Fragkiskos Ragkousis <address@hidden>.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+@@ -15,8 +16,8 @@
+    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. */
++   along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.*/
++
+ 
+ #include <assert-backtrace.h>
+ #include <hurd.h>
+@@ -38,11 +39,10 @@
+ #include <hurd/lookup.h>
+ #include <hurd/fsys.h>
+ 
++#include <hurd/hurdutil.h>
+ 
+ const char *argp_program_version = STANDARD_HURD_VERSION (settrans);
+ 
+-#define DEFAULT_TIMEOUT 60
+-
+ #define _STRINGIFY(arg) #arg
+ #define STRINGIFY(arg) _STRINGIFY (arg)
+ 
+@@ -92,389 +92,131 @@ static struct argp_option options[] =
+ static char *args_doc = "NODE [TRANSLATOR ARG...]";
+ static char *doc = "Set the passive/active translator on NODE."
+ "\vBy default the passive translator is set.";
+-
+-/* Authentication of the current process.  */
+-uid_t *uids;
+-gid_t *gids;
+-size_t uids_len, gids_len;
+-
+-/* Initialize and populate the uids and gids vectors.  */
+-error_t
+-get_credentials (void)
+-{
+-  /* Fetch uids...  */
+-  uids_len = geteuids (0, 0);
+-  if (uids_len < 0)
+-    return errno;
+-
+-  uids = malloc (uids_len * sizeof (uid_t));
+-  if (! uids)
+-    return ENOMEM;
+ 
+-  uids_len = geteuids (uids_len, uids);
+-  if (uids_len < 0)
+-    return errno;
+-
+-  /* ... and gids.  */
+-  gids_len = getgroups (0, 0);
+-  if (gids_len < 0)
+-    return errno;
+-
+-  gids = malloc (gids_len * sizeof (gid_t));
+-  if (! uids)
+-    return ENOMEM;
+-
+-  gids_len = getgroups (gids_len, gids);
+-  if (gids_len < 0)
+-    return errno;
++/* The context to be used to create the translator. */
++struct settrans_context *context;
++
++/* ---------------------------------------------------------------- */
+ 
++/* Parse our options...  */
++error_t parse_opt (int key, char *arg, struct argp_state *state)
++{
++  switch (key)
++    {
++    case ARGP_KEY_ARG:
++      if (state->arg_num == 0)
++        context->node_name = arg;
++      else                    /* command */
++        {
++          if (context->start)
++            argp_error (state, "both --start and TRANSLATOR given");
++
++          error_t err =
++            argz_create (state->argv + state->next - 1, &context->argz, 
&context->argz_len);
++          if (err)
++            error(3, err, "Can't create options vector");
++          state->next = state->argc; /* stop parsing */
++        }
++      break;
++
++    case ARGP_KEY_NO_ARGS:
++      argp_usage (state);
++      return EINVAL;
++
++    case 'a': context->active = 1; break;
++    case 's':
++      context->start = 1;
++      context->active = 1;    /* start implies active */
++      break;
++    case OPT_STACK:
++      context->stack = 1;
++      context->active = 1;   /* stack implies active */
++      context->orphan = 1;   /* stack implies orphan */
++      break;
++    case 'p': context->passive = 1; break;
++    case 'k': context->keep_active = 1; break;
++    case 'g': context->kill_active = 1; break;
++    case 'x': context->excl = 1; break;
++    case 'P': context->pause = 1; break;
++    case 'F':
++      context->pid_file = strdup (arg);
++      if (context->pid_file == NULL)
++        error(3, ENOMEM, "Failed to duplicate argument");
++      break;
++
++    case 'o': context->orphan = 1; break;
++    case 'U':
++      context->underlying_node_name = strdup (arg);
++      if (context->underlying_node_name == NULL)
++        error(3, ENOMEM, "Failed to duplicate argument");
++      break;
++
++    case 'C':
++      if (context->chroot_command)
++        {
++          argp_error (state, "--chroot given twice");
++          return EINVAL;
++        }
++      context->chroot_command = &state->argv[state->next];
++      while (state->next < state->argc)
++        {
++          if (!strcmp (state->argv[state->next], "--"))
++            {
++              state->argv[state->next++] = 0;
++              if (context->chroot_command[0] == 0)
++                {
++                  argp_error (state,
++                              "--chroot must be followed by a command");
++                  return EINVAL;
++                }
++              return 0;
++            }
++          ++state->next;
++        }
++      argp_error (state, "--chroot command must be terminated with `--'");
++      return EINVAL;
++
++    case OPT_CHROOT_CHDIR:
++      if (arg[0] != '/')
++        argp_error (state, "--chroot-chdir must be absolute");
++      context->chroot_chdir = arg;
++      break;
++
++    case 'c': context->lookup_flags |= O_CREAT; break;
++    case 'L': context->lookup_flags &= ~O_NOTRANS; break;
++
++    case 'R': context->goaway_flags |= FSYS_GOAWAY_RECURSE; break;
++    case 'S': context->goaway_flags |= FSYS_GOAWAY_NOSYNC; break;
++    case 'f': context->goaway_flags |= FSYS_GOAWAY_FORCE; break;
++
++      /* Use atof so the user can specifiy fractional timeouts.  */
++    case 't': context->timeout = atof (arg) * 1000.0; break;
++
++    default:
++      return ARGP_ERR_UNKNOWN;
++    }
+   return 0;
+ }
+-
+-/* ---------------------------------------------------------------- */
+ 
+ int
+ main(int argc, char *argv[])
+ {
+   error_t err;
+ 
+-  /* The filesystem node we're putting a translator on.  */
+-  char *node_name = 0;
+-  file_t node;
+-
+-  /* The translator's arg vector, in '\0' separated format.  */
+-  char *argz = 0;
+-  size_t argz_len = 0;
+-
+-  /* The control port for any active translator we start up.  */
+-  fsys_t active_control = MACH_PORT_NULL;
+-
+-  /* Flags to pass to file_set_translator.  */
+-  int active_flags = 0;
+-  int passive_flags = 0;
+-  int lookup_flags = O_NOTRANS;
+-  int goaway_flags = 0;
+-
+-  /* Various option flags.  */
+-  int passive = 0, active = 0, keep_active = 0, pause = 0, kill_active = 0,
+-      orphan = 0;
+-  int start = 0;
+-  int stack = 0;
+-  char *pid_file = NULL;
+-  int excl = 0;
+-  int timeout = DEFAULT_TIMEOUT * 1000; /* ms */
+-  char *underlying_node_name = NULL;
+-  int underlying_lookup_flags;
+-  char **chroot_command = 0;
+-  char *chroot_chdir = "/";
+-
+-  /* Parse our options...  */
+-  error_t parse_opt (int key, char *arg, struct argp_state *state)
+-    {
+-      switch (key)
+-      {
+-      case ARGP_KEY_ARG:
+-        if (state->arg_num == 0)
+-          node_name = arg;
+-        else                  /* command */
+-          {
+-            if (start)
+-              argp_error (state, "both --start and TRANSLATOR given");
+-
+-            error_t err =
+-              argz_create (state->argv + state->next - 1, &argz, &argz_len);
+-            if (err)
+-              error(3, err, "Can't create options vector");
+-            state->next = state->argc; /* stop parsing */
+-          }
+-        break;
+-
+-      case ARGP_KEY_NO_ARGS:
+-        argp_usage (state);
+-        return EINVAL;
+-
+-      case 'a': active = 1; break;
+-      case 's':
+-        start = 1;
+-        active = 1;   /* start implies active */
+-        break;
+-      case OPT_STACK:
+-        stack = 1;
+-        active = 1;   /* stack implies active */
+-        orphan = 1;   /* stack implies orphan */
+-        break;
+-      case 'p': passive = 1; break;
+-      case 'k': keep_active = 1; break;
+-      case 'g': kill_active = 1; break;
+-      case 'x': excl = 1; break;
+-      case 'P': pause = 1; break;
+-      case 'F':
+-        pid_file = strdup (arg);
+-        if (pid_file == NULL)
+-          error(3, ENOMEM, "Failed to duplicate argument");
+-        break;
+-
+-      case 'o': orphan = 1; break;
+-      case 'U':
+-        underlying_node_name = strdup (arg);
+-        if (underlying_node_name == NULL)
+-          error(3, ENOMEM, "Failed to duplicate argument");
+-        break;
+-
+-      case 'C':
+-        if (chroot_command)
+-          {
+-            argp_error (state, "--chroot given twice");
+-            return EINVAL;
+-          }
+-        chroot_command = &state->argv[state->next];
+-        while (state->next < state->argc)
+-          {
+-            if (!strcmp (state->argv[state->next], "--"))
+-              {
+-                state->argv[state->next++] = 0;
+-                if (chroot_command[0] == 0)
+-                  {
+-                    argp_error (state,
+-                                "--chroot must be followed by a command");
+-                    return EINVAL;
+-                  }
+-                return 0;
+-              }
+-            ++state->next;
+-          }
+-        argp_error (state, "--chroot command must be terminated with `--'");
+-        return EINVAL;
+-
+-      case OPT_CHROOT_CHDIR:
+-        if (arg[0] != '/')
+-          argp_error (state, "--chroot-chdir must be absolute");
+-        chroot_chdir = arg;
+-        break;
+-
+-      case 'c': lookup_flags |= O_CREAT; break;
+-      case 'L': lookup_flags &= ~O_NOTRANS; break;
+-
+-      case 'R': goaway_flags |= FSYS_GOAWAY_RECURSE; break;
+-      case 'S': goaway_flags |= FSYS_GOAWAY_NOSYNC; break;
+-      case 'f': goaway_flags |= FSYS_GOAWAY_FORCE; break;
+-
+-        /* Use atof so the user can specifiy fractional timeouts.  */
+-      case 't': timeout = atof (arg) * 1000.0; break;
+-
+-      default:
+-        return ARGP_ERR_UNKNOWN;
+-      }
+-      return 0;
+-    }
++  settrans_context_create(&context);
++
+   struct argp argp = {options, parse_opt, args_doc, doc};
+ 
+   argp_parse (&argp, argc, argv, ARGP_IN_ORDER, 0, 0);
+ 
+-  if (stack)
++  err = settrans(context);
++  if (err)
+     {
+-      underlying_node_name = node_name;
+-      underlying_lookup_flags = lookup_flags && ~O_NOTRANS;
++      settrans_context_cleanup(context);
++      error(1, err, "Could not set translator");
+     }
+-  else
+-    underlying_lookup_flags = lookup_flags;
+ 
+-  if (!active && !passive && !chroot_command)
+-    passive = 1;              /* By default, set the passive translator.  */
+-
+-  if (passive)
+-    passive_flags = FS_TRANS_SET | (excl ? FS_TRANS_EXCL : 0);
+-  if (active)
+-    active_flags = FS_TRANS_SET | (excl ? FS_TRANS_EXCL : 0)
+-                 | (orphan ? FS_TRANS_ORPHAN : 0);
+-
+-  if (passive && !active)
+-    {
+-      /* When setting just the passive, decide what to do with any active.  */
+-      if (kill_active)
+-      /* Make it go away.  */
+-      active_flags = FS_TRANS_SET;
+-      else if (! keep_active)
+-      /* Ensure that there isn't one.  */
+-      active_flags = FS_TRANS_SET | FS_TRANS_EXCL;
+-    }
+-
+-  if (start)
+-    {
+-      /* Retrieve the passive translator record in argz.  */
+-      mach_port_t node = file_name_lookup (node_name, lookup_flags, 0);
+-      if (node == MACH_PORT_NULL)
+-      error (4, errno, "%s", node_name);
+-
+-      char buf[1024];
+-      argz = buf;
+-      argz_len = sizeof (buf);
+-
+-      err = file_get_translator (node, &argz, &argz_len);
+-      if (err == EINVAL)
+-      error (4, 0, "%s: no passive translator record found", node_name);
+-      if (err)
+-      error (4, err, "%s", node_name);
+-
+-      mach_port_deallocate (mach_task_self (), node);
+-    }
+-
+-  if ((active || chroot_command) && argz_len > 0)
+-    {
+-      /* Error during file lookup; we use this to avoid duplicating error
+-       messages.  */
+-      error_t open_err = 0;
+-
+-      /* The callback to start_translator opens NODE as a side effect.  */
+-      error_t open_node (int flags,
+-                       mach_port_t *underlying,
+-                       mach_msg_type_name_t *underlying_type,
+-                       task_t task, void *cookie)
+-      {
+-        if (pause)
+-          {
+-            fprintf (stderr, "Translator pid: %d\nPausing...",
+-                     task2pid (task));
+-            getchar ();
+-          }
+-
+-        if (pid_file != NULL)
+-          {
+-            FILE *h;
+-            h = fopen (pid_file, "w");
+-            if (h == NULL)
+-              error (4, errno, "Failed to open pid file");
+-
+-            fprintf (h, "%i\n", task2pid (task));
+-            fclose (h);
+-          }
+-
+-        node = file_name_lookup (node_name, flags | lookup_flags, 0666);
+-        if (node == MACH_PORT_NULL)
+-          {
+-            open_err = errno;
+-            return open_err;
+-          }
+-
+-        if (underlying_node_name)
+-          {
+-            *underlying = file_name_lookup (underlying_node_name,
+-                                            flags | underlying_lookup_flags,
+-                                            0666);
+-            if (! MACH_PORT_VALID (*underlying))
+-              {
+-                /* For the error message.  */
+-                node_name = underlying_node_name;
+-                open_err = errno;
+-                return open_err;
+-              }
+-          }
+-        else
+-          *underlying = node;
+-        *underlying_type = MACH_MSG_TYPE_COPY_SEND;
+-
+-        return 0;
+-      }
+-      err = fshelp_start_translator (open_node, NULL, argz, argz, argz_len,
+-                                   timeout, &active_control);
+-      if (err)
+-      /* If ERR is due to a problem opening the translated node, we print
+-         that name, otherwise, the name of the translator.  */
+-      error(4, err, "%s", (err == open_err) ? node_name : argz);
+-    }
+-  else
+-    {
+-      node = file_name_lookup(node_name, lookup_flags, 0666);
+-      if (node == MACH_PORT_NULL)
+-      error(1, errno, "%s", node_name);
+-    }
+-
+-  if (active || passive)
+-    {
+-      err = file_set_translator (node,
+-                               passive_flags, active_flags, goaway_flags,
+-                               argz, argz_len,
+-                               active_control, MACH_MSG_TYPE_COPY_SEND);
+-      if (err)
+-      error (5, err, "%s", node_name);
+-    }
+-
+-  if (chroot_command)
+-    {
+-      pid_t child;
+-      int status;
+-      switch ((child = fork ()))
+-      {
+-      case -1:
+-        error (6, errno, "fork");
+-
+-      case 0:; /* Child.  */
+-        /* We will act as the parent filesystem would for a lookup
+-           of the active translator's root node, then use this port
+-           as our root directory while we exec the command.  */
+-
+-        char retry_name[1024];        /* XXX */
+-        retry_type do_retry;
+-        mach_port_t root;
+-        file_t executable;
+-        char *prefixed_name;
+-
+-        err = get_credentials ();
+-        if (err)
+-          error (6, err, "getting credentials");
+-
+-        err = fsys_getroot (active_control,
+-                            MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND,
+-                            uids, uids_len, gids, gids_len, 0,
+-                            &do_retry, retry_name, &root);
+-        mach_port_deallocate (mach_task_self (), active_control);
+-        if (err)
+-          error (6, err, "fsys_getroot");
+-        err = hurd_file_name_lookup_retry (&_hurd_ports_use, &getdport, 0,
+-                                           do_retry, retry_name, 0, 0,
+-                                           &root);
+-        if (err)
+-          error (6, err, "cannot resolve root port");
+-
+-        if (setcrdir (root))
+-          error (7, errno, "cannot install root port");
+-        mach_port_deallocate (mach_task_self (), root);
+-        if (chdir (chroot_chdir))
+-          error (8, errno, "%s", chroot_chdir);
+-
+-        /* Lookup executable in PATH.  */
+-        executable = file_name_path_lookup (chroot_command[0],
+-                                            getenv ("PATH"),
+-                                            O_EXEC, 0,
+-                                            &prefixed_name);
+-        if (MACH_PORT_VALID (executable))
+-          {
+-            err = mach_port_deallocate (mach_task_self (), executable);
+-            assert_perror_backtrace (err);
+-            if (prefixed_name)
+-              chroot_command[0] = prefixed_name;
+-          }
+-
+-        execvp (chroot_command[0], chroot_command);
+-        error (8, errno, "cannot execute %s", chroot_command[0]);
+-        break;
+-
+-      default: /* Parent.  */
+-        if (waitpid (child, &status, 0) != child)
+-          error (8, errno, "waitpid on %d", child);
+-
+-        err = fsys_goaway (active_control, goaway_flags);
+-        if (err && err != EBUSY)
+-          error (9, err, "fsys_goaway");
+-
+-        if (WIFSIGNALED (status))
+-          error (WTERMSIG (status) + 128, 0,
+-                 "%s for child %d", strsignal (WTERMSIG (status)), child);
+-        if (WEXITSTATUS (status) != 0)
+-          error (WEXITSTATUS (status), 0,
+-                 "Error %d for child %d", WEXITSTATUS (status), child);
+-      }
+-    }
++  settrans_context_cleanup(context);
+ 
+   return 0;
+ }
+-- 
+2.26.0
+



reply via email to

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