From 4f52a7049bbaa0264869b2fe75fc601310b52842 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Thu, 26 May 2016 18:07:37 +0200 Subject: add patch series --- ...-New-library-containing-utils-to-be-used-.patch | 1083 ++++++++++++++++++++ debian/patches/series | 1 + 2 files changed, 1084 insertions(+) create mode 100644 debian/patches/hurdutil0001-libhurdutil-New-library-containing-utils-to-be-used-.patch 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 +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 . ++ ++ 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 ++#include ++#include ++#include ++#include ++ ++#include ++ ++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 ++ Written by Manolis Fragkiskos Ragkousis . ++ ++ 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++ ++#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 ++ Revised by Manolis Fragkiskos Ragkousis . + + 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 + #include + ++#include + + 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 -- cgit v1.2.3