summaryrefslogtreecommitdiff
path: root/utils/settrans.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/settrans.c')
-rw-r--r--utils/settrans.c180
1 files changed, 180 insertions, 0 deletions
diff --git a/utils/settrans.c b/utils/settrans.c
new file mode 100644
index 00000000..e5f79847
--- /dev/null
+++ b/utils/settrans.c
@@ -0,0 +1,180 @@
+/* Set a file's translator.
+
+ Copyright (C) 1995 Free Software Foundation, Inc.
+
+ Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+ This program 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.
+
+ This program 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. */
+
+#include <hurd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <error.h>
+#include <argz.h>
+#include <start-trans.h>
+
+/* ---------------------------------------------------------------- */
+
+#define USAGE "Usage: %s [OPTION...] FILE [TRANSLATOR...]\n"
+
+static void
+usage(status)
+ int status;
+{
+ if (status != 0)
+ fprintf(stderr, "Try `%s --help' for more information.\n",
+ program_invocation_name);
+ else
+ {
+ printf(USAGE, program_invocation_name);
+ printf("\
+\n\
+ -a, --active Set FILE's active translator\n\
+ -p, --passive Set FILE's passive translator\n\
+ -c, --create Create FILE if it doesn't exist\n\
+ -f, --force Set the translator even if one already exists\n\
+ -k, --keep-active Keep any currently running active translator\n\
+ when setting the passive translator\n\
+ -L, --dereference If a translator exists, put the new one on top\n\
+ -t, --list Show FILE's passive translator\n\
+ --help Give this help list\n\
+");
+ }
+
+ exit(status);
+}
+
+#define SHORT_OPTIONS "apcfkLt?"
+
+static struct option options[] =
+{
+ {"active", no_argument, 0, 'a'},
+ {"passive", no_argument, 0, 'p'},
+ {"keep-active", no_argument, 0, 'k'},
+ {"create", no_argument, 0, 'c'},
+ {"force", no_argument, 0, 'f'},
+ {"dereference", no_argument, 0, 'L'},
+ {"list", no_argument, 0, 't'},
+ {"help", no_argument, 0, '?'},
+ {0, 0, 0, 0}
+};
+
+/* ---------------------------------------------------------------- */
+
+void
+main(int argc, char *argv[])
+{
+ int opt;
+ error_t err;
+
+ /* The filesystem node we're putting a translator on. */
+ char *node_name;
+ file_t node;
+
+ /* The translator's arg vector, in '\0' separated format. */
+ char *argz = 0;
+ int 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. By default we only set a
+ translator if there's no existing one. */
+ int flags = FS_TRANS_SET | FS_TRANS_EXCL;
+
+ /* Various option flags. */
+ int passive = 0, active = 0, create = 0, force = 0, deref = 0, list = 0;
+ int keep_active = 0;
+
+ /* Parse our options... */
+ while ((opt = getopt_long(argc, argv, "+" SHORT_OPTIONS, options, 0)) != EOF)
+ switch (opt)
+ {
+ case 'a': active = 1; break;
+ case 'p': passive = 1; break;
+ case 'f': force = 1; break;
+ case 'k': keep_active = 1; break;
+ case 'c': create = 1; break;
+ case 'L': deref = 1; break;
+ case 't': list = 1; break;
+ case '?': usage(0);
+ default: usage(1);
+ }
+
+ if (optind == argc)
+ {
+ fprintf(stderr,
+ "%s: Missing filename argument\n", program_invocation_name);
+ usage(1);
+ }
+
+ node_name = argv[optind++];
+
+ if (!active && !passive)
+ passive = 1;
+
+ node =
+ file_name_lookup(node_name,
+ (deref ? 0 : O_NOTRANS) | (create ? O_CREAT : 0),
+ 0666);
+ if (node == MACH_PORT_NULL)
+ error(1, errno, "%s", node_name);
+
+ if (list)
+ /* Print out NODE's translator instead of setting it. */
+ {
+ char buf[1024], *trans = buf;
+ int len = sizeof(buf);
+
+ err = file_get_translator(node, &trans, &len);
+ if (err)
+ error(2, err, "%s", node_name);
+
+ argz_stringify(trans, len);
+ printf("%s\n", trans);
+ }
+ else
+ {
+ err = argz_create(argv + optind, &argz, &argz_len);
+ if (err)
+ error(3, err, "Can't create argz vector");
+
+ if (active && argz_len > 0)
+ err = start_translator(node, argz, argz_len, 60000, &active_control);
+ if (err)
+ error(4, err, "%s", argz);
+
+ if (force)
+ /* Kill any existing translators. */
+ flags &= ~FS_TRANS_EXCL;
+
+ err =
+ file_set_translator(node,
+ passive ? flags : 0,
+ (active || !keep_active) ? flags : 0,
+ 0,
+ argz, argz_len,
+ active_control, MACH_MSG_TYPE_MOVE_SEND);
+ if (err)
+ error(5, err, "%s", node_name);
+ }
+
+ exit(0);
+}