summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustus Winter <justus@gnupg.org>2016-05-26 18:07:37 +0200
committerJustus Winter <justus@gnupg.org>2016-05-26 18:07:37 +0200
commit4f52a7049bbaa0264869b2fe75fc601310b52842 (patch)
tree219d6d34588949388d8f8447ef7ebb87893a0442
parent4fd1aa9fe936ce03e47cd6d2cb11010360817138 (diff)
add patch series
-rw-r--r--debian/patches/hurdutil0001-libhurdutil-New-library-containing-utils-to-be-used-.patch1083
-rw-r--r--debian/patches/series1
2 files changed, 1084 insertions, 0 deletions
diff --git a/debian/patches/hurdutil0001-libhurdutil-New-library-containing-utils-to-be-used-.patch b/debian/patches/hurdutil0001-libhurdutil-New-library-containing-utils-to-be-used-.patch
new file mode 100644
index 00000000..72fbd872
--- /dev/null
+++ b/debian/patches/hurdutil0001-libhurdutil-New-library-containing-utils-to-be-used-.patch
@@ -0,0 +1,1083 @@
+From 0b6a25b392abb6f2028cfd2eb348df0e6482708a Mon Sep 17 00:00:00 2001
+From: Manolis Ragkousis <manolis837@gmail.com>
+Date: Wed, 25 May 2016 18:05:57 +0300
+Subject: [PATCH hurd] 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 | 78 ++++++++
+ libhurdutil/settrans.c | 377 +++++++++++++++++++++++++++++++++++++++
+ utils/Makefile | 4 +-
+ utils/settrans.c | 475 +++++++++++--------------------------------------
+ 6 files changed, 594 insertions(+), 370 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 d48baaa..e712767 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
+
+ # Hurd programs
+ prog-subdirs = auth proc exec term \
+diff --git a/libhurdutil/Makefile b/libhurdutil/Makefile
+new file mode 100644
+index 0000000..2e0e642
+--- /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 this program; if not, write to the Free Software
++# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++
++dir := libhurdutil
++makemode := library
++
++libname := libhurdutil
++SRCS = settrans.c
++installhdrs = hurdutil.h
++
++OBJS = $(SRCS:.c=.o)
++
++include ../Makeconf
+diff --git a/libhurdutil/hurdutil.h b/libhurdutil/hurdutil.h
+new file mode 100644
+index 0000000..5786cff
+--- /dev/null
++++ b/libhurdutil/hurdutil.h
+@@ -0,0 +1,78 @@
++/* hurdutil.h - Hurd utils interface.
++ Copyright (C) 2016 Free Software Foundation, Inc.
++ Written by Manolis Fragkiskos Ragkousis <manolis837@gmail.com>.
++
++ 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, write to the Free Software
++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
++
++#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_flags
++{
++ /* 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;
++ int active;
++ int keep_active;
++ int pause;
++ int kill_active;
++ int orphan;
++ int start;
++ int stack;
++ int excl;
++ 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;
++};
++typedef struct settrans_flags *settrans_flags_t;
++
++/* Initialize the flags to be used. */
++void settrans_flags_init (settrans_flags_t flags);
++
++/* Release the memory allocated. */
++void settrans_flags_cleanup (settrans_flags_t flags);
++
++/* Create the struct containing the flags and initialize them.
++ If a memory allocation error occurs, ENOMEM is returned,
++ otherwise 0.*/
++error_t settrans_flags_create (settrans_flags_t *flags);
++
++/* Set a translator according to the flags passed. On success return 0. */
++error_t settrans(settrans_flags_t flags);
++
++#endif /* _HURD_UTIL_H */
+diff --git a/libhurdutil/settrans.c b/libhurdutil/settrans.c
+new file mode 100644
+index 0000000..eeaa964
+--- /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 <miles@gnu.org>
++ Written by Manolis Fragkiskos Ragkousis <manolis837@gmail.com>.
++
++ 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, write to the Free Software
++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
++
++#include <errno.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <stdint.h>
++#include <assert.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_flags_init (settrans_flags_t flags)
++{
++ flags->node_name = 0;
++
++ flags->lookup_flags = O_NOTRANS;
++ flags->goaway_flags = 0;
++
++ flags->passive = 0;
++ flags->active = 0;
++ flags->keep_active = 0;
++ flags->pause = 0;
++ flags->kill_active = 0;
++ flags->orphan = 0;
++ flags->start = 0;
++ flags->stack = 0;
++ flags->excl = 0;
++ flags->timeout = DEFAULT_TIMEOUT * 1000; /* ms */
++ flags->pid_file = 0;
++ flags->underlying_node_name = NULL;
++ flags->chroot_command = 0;
++ flags->chroot_chdir = "/";
++
++ flags->argz;
++ flags->argz_len;
++}
++
++void
++settrans_flags_cleanup (settrans_flags_t flags)
++{
++ free(flags);
++}
++
++error_t
++settrans_flags_create (settrans_flags_t *flags)
++{
++ *flags = malloc (sizeof (struct settrans_flags));
++ if (*flags == NULL)
++ return ENOMEM;
++
++ settrans_flags_init(*flags);
++
++ return 0;
++}
++
++error_t settrans(settrans_flags_t flags)
++{
++ error_t err;
++
++ /* The filesystem node we're putting a translator on. */
++ char *node_name = flags->node_name;
++ file_t node;
++
++ /* The translator's arg vector, in '\0' separated format. */
++ char *argz = flags->argz;
++ size_t argz_len = flags->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 = flags->lookup_flags;
++ int goaway_flags = flags->goaway_flags;
++
++ /* Various option flags. */
++ int passive = flags->passive;
++ int active = flags->active;
++ int keep_active = flags->keep_active;
++ int pause = flags->pause;
++ int kill_active = flags->kill_active;
++ int orphan = flags->orphan;
++ int start = flags->start;
++ int stack = flags->stack;
++ char *pid_file = flags->pid_file;
++ int excl = flags->excl;
++ int timeout = flags->timeout; /* ms */
++ char *underlying_node_name = flags->underlying_node_name;
++ int underlying_lookup_flags = flags->underlying_lookup_flags;
++ char **chroot_command = flags->chroot_command;
++ char *chroot_chdir = flags->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 (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 d2ef9e8..be10cf6 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 -lcrypt
+ addauth-LDLIBS = -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 ee7cba5..14dd520 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 <miles@gnu.org>
++ Revised by Manolis Fragkiskos Ragkousis <manolis837@gmail.com>.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+@@ -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)
+
+@@ -93,44 +93,6 @@ 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;
+-
+- return 0;
+-}
+-
+ /* ---------------------------------------------------------------- */
+
+ int
+@@ -138,343 +100,122 @@ 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 = "/";
++ /* The flags to be used to create the translator. */
++ settrans_flags_t flags;
++
++ settrans_flags_create(&flags);
+
+ /* 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;
+- }
++ {
++ switch (key)
++ {
++ case ARGP_KEY_ARG:
++ if (state->arg_num == 0)
++ flags->node_name = arg;
++ else /* command */
++ {
++ if (flags->start)
++ argp_error (state, "both --start and TRANSLATOR given");
++
++ error_t err =
++ argz_create (state->argv + state->next - 1, &flags->argz, &flags->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': flags->active = 1; break;
++ case 's':
++ flags->start = 1;
++ flags->active = 1; /* start implies active */
++ break;
++ case OPT_STACK:
++ flags->stack = 1;
++ flags->active = 1; /* stack implies active */
++ flags->orphan = 1; /* stack implies orphan */
++ break;
++ case 'p': flags->passive = 1; break;
++ case 'k': flags->keep_active = 1; break;
++ case 'g': flags->kill_active = 1; break;
++ case 'x': flags->excl = 1; break;
++ case 'P': flags->pause = 1; break;
++ case 'F':
++ flags->pid_file = strdup (arg);
++ if (flags->pid_file == NULL)
++ error(3, ENOMEM, "Failed to duplicate argument");
++ break;
++
++ case 'o': flags->orphan = 1; break;
++ case 'U':
++ flags->underlying_node_name = strdup (arg);
++ if (flags->underlying_node_name == NULL)
++ error(3, ENOMEM, "Failed to duplicate argument");
++ break;
++
++ case 'C':
++ if (flags->chroot_command)
++ {
++ argp_error (state, "--chroot given twice");
++ return EINVAL;
++ }
++ flags->chroot_command = &state->argv[state->next];
++ while (state->next < state->argc)
++ {
++ if (!strcmp (state->argv[state->next], "--"))
++ {
++ state->argv[state->next++] = 0;
++ if (flags->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");
++ flags->chroot_chdir = arg;
++ break;
++
++ case 'c': flags->lookup_flags |= O_CREAT; break;
++ case 'L': flags->lookup_flags &= ~O_NOTRANS; break;
++
++ case 'R': flags->goaway_flags |= FSYS_GOAWAY_RECURSE; break;
++ case 'S': flags->goaway_flags |= FSYS_GOAWAY_NOSYNC; break;
++ case 'f': flags->goaway_flags |= FSYS_GOAWAY_FORCE; break;
++
++ /* Use atof so the user can specifiy fractional timeouts. */
++ case 't': flags->timeout = atof (arg) * 1000.0; break;
++
++ 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);
+
+- 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 = settrans(flags);
++ if (err)
+ {
+- 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);
++ settrans_flags_cleanup(flags);
++ error(1, err, "Could not set translator");
+ }
+
+- 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 (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_flags_cleanup(flags);
+
+ return 0;
+ }
+--
+2.1.4
+
diff --git a/debian/patches/series b/debian/patches/series
index 246db96e..322912f7 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -38,3 +38,4 @@ exec_filename0004-This-patch-is-an-amendment-of-exec_filename_exec.pat.patch
crash0001-xxx-crash-logging-works.patch
pager-alloc0001-libpager-provide-pager_create_alloc.patch
+hurdutil0001-libhurdutil-New-library-containing-utils-to-be-used-.patch