summaryrefslogtreecommitdiff
path: root/usermux/leaf.c
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1997-07-23 13:47:31 +0000
committerMiles Bader <miles@gnu.org>1997-07-23 13:47:31 +0000
commit6b9fb1d6104459404b5b7a918530071a02af80c7 (patch)
treea9981acc40ab97b7f9008a31346df4ad07c4684e /usermux/leaf.c
parentfa59e2d6745f93b457f4b984d3d4c331401ec449 (diff)
Initial checkin
Diffstat (limited to 'usermux/leaf.c')
-rw-r--r--usermux/leaf.c151
1 files changed, 151 insertions, 0 deletions
diff --git a/usermux/leaf.c b/usermux/leaf.c
new file mode 100644
index 00000000..bacaee9d
--- /dev/null
+++ b/usermux/leaf.c
@@ -0,0 +1,151 @@
+/* Usermux leaf node functions
+
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ Written by Miles Bader <miles@gnu.ai.mit.edu>
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include <stdio.h>
+#include <string.h>
+#include <pwd.h>
+#include <argz.h>
+#include <hurd/paths.h>
+
+#include "usermux.h"
+
+/* Read the contents of NODE (a symlink), for USER, into BUF. */
+error_t
+netfs_attempt_readlink (struct iouser *user, struct node *node, char *buf)
+{
+ assert (node->nn->name);
+ /* For symlink nodes, the translator spec just contains the link target. */
+ memcpy (buf, node->nn->trans, node->nn->trans_len);
+ fshelp_touch (&node->nn_stat, TOUCH_ATIME, usermux_maptime);
+ return 0;
+}
+
+/* For locked node NODE with S_IPTRANS set in its mode, look up the name of
+ its translator. Store the name into newly malloced storage, and return it
+ in *ARGZ; set *ARGZ_LEN to the total length.
+
+ For usermux, this creates a new translator string by instantiating the
+ global translator template. */
+error_t
+netfs_get_translator (struct node *node, char **trans, size_t *trans_len)
+{
+ if (! node->nn->name)
+ return EINVAL;
+ else
+ {
+ fshelp_touch (&node->nn_stat, TOUCH_ATIME, usermux_maptime);
+ *trans = 0;
+ *trans_len = 0;
+ if (S_ISLNK (node->nn_stat.st_mode))
+ argz_add (trans, trans_len, _HURD_SYMLINK);
+ return
+ argz_append (trans, trans_len, node->nn->trans, node->nn->trans_len);
+ }
+}
+
+/* Create a new leaf node in MUX, with a name NAME, and return the new node
+ with a single reference in NODE. */
+error_t
+create_user_node (struct usermux *mux, struct usermux_name *name,
+ struct passwd *pw, struct node **node)
+{
+ error_t err;
+ struct node *new;
+ struct netnode *nn = malloc (sizeof (struct netnode));
+
+ if (! nn)
+ return ENOMEM;
+
+ nn->mux = mux;
+ nn->name = name;
+
+ new = netfs_make_node (nn);
+ if (! new)
+ {
+ free (nn);
+ return ENOMEM;
+ }
+
+ new->nn_stat = mux->stat_template;
+
+ new->nn_stat.st_ino = pw->pw_uid + USERMUX_FILENO_UID_OFFSET;
+
+ if (strcmp (mux->trans_template, _HURD_SYMLINK) == 0
+ && mux->trans_template_len == sizeof _HURD_SYMLINK)
+ {
+ err = argz_create_sep (pw->pw_dir, 0, &nn->trans, &nn->trans_len);
+ new->nn_stat.st_mode = (S_IFLNK | 0666);
+ new->nn_stat.st_size = nn->trans_len;
+ }
+ else
+ {
+ unsigned replace_count = 0;
+
+ nn->trans = 0; /* Initialize return value. */
+ nn->trans_len = 0;
+
+ err = argz_append (&nn->trans, &nn->trans_len,
+ mux->trans_template, mux->trans_template_len);
+
+ /* Perform any substitutions. */
+ if (!err && mux->user_pat && *mux->user_pat)
+ err = argz_replace (&nn->trans, &nn->trans_len,
+ mux->user_pat, pw->pw_name,
+ &replace_count);
+ if (!err && mux->home_pat && *mux->home_pat)
+ err = argz_replace (&nn->trans, &nn->trans_len,
+ mux->home_pat, pw->pw_dir,
+ &replace_count);
+ if (!err && mux->uid_pat && *mux->uid_pat)
+ {
+ char uid_buf[10];
+ snprintf (uid_buf, sizeof uid_buf, "%d", pw->pw_uid);
+ err = argz_replace (&nn->trans, &nn->trans_len,
+ mux->uid_pat, uid_buf,
+ &replace_count);
+ }
+
+ if (!err && replace_count == 0)
+ /* Default, if no instances of any pattern occur, is to append the
+ user home dir. */
+ err = argz_add (&nn->trans, &nn->trans_len, pw->pw_dir);
+
+ if (err && nn->trans_len > 0)
+ free (nn->trans);
+
+ new->nn_stat.st_mode = (S_IFREG | S_IPTRANS | 0666);
+ new->nn_stat.st_size = 0;
+ }
+
+ if (err)
+ {
+ free (nn);
+ free (new);
+ return err;
+ }
+
+ fshelp_touch (&new->nn_stat, TOUCH_ATIME|TOUCH_MTIME|TOUCH_CTIME,
+ usermux_maptime);
+
+ name->node = new;
+ *node = new;
+
+ return 0;
+}