summaryrefslogtreecommitdiff
path: root/console-client/trans.c
diff options
context:
space:
mode:
authorMarcus Brinkmann <marcus@gnu.org>2005-07-11 13:59:24 +0000
committerMarcus Brinkmann <marcus@gnu.org>2005-07-11 13:59:24 +0000
commit94414efd38f6a555ac97d013bd0aced76803142d (patch)
tree39a3a126bf24edc3a0e1658fc0863f0da9453909 /console-client/trans.c
parent2f745c154065dfeae33c864b4e61cfca7a3d4974 (diff)
2005-07-11 Samuel Thibault <samuel.thibault@ens-lyon.org>
* Makefile (modules): Add `current-vcs' and its rules. * console.c (console_current_id): New function. * input.h (console_current_id): New prototype. * trans.c (struct netnode): New member `symlink_path'. (console_demuxer): Handle case when node it anonymous. (netfs_S_io_select): Likewise. (netfs_S_io_read): Likewise. (netfs_S_io_write): Likewise. (netfs_report_access): Likewise. (netfs_attempt_mksymlink): Implement symlinks. (netfs_attempt_lookup): Likewise. (netfs_attempt_unlink): Likewise. (netfs_attempt_link): Likewise. (netfs_attempt_mkfile): Likewise. (netfs_attempt_readlink): Likewise. (netfs_get_dirents): Likewise. (netfs_create_consnode): Likewise. * trans.h (struct consnode): New members `readlink' and `mksymlink'. * current-vcs.c: New file.
Diffstat (limited to 'console-client/trans.c')
-rw-r--r--console-client/trans.c110
1 files changed, 100 insertions, 10 deletions
diff --git a/console-client/trans.c b/console-client/trans.c
index 83342bcc..ee7581b4 100644
--- a/console-client/trans.c
+++ b/console-client/trans.c
@@ -41,6 +41,7 @@ static consnode_t node_list = 0;
struct netnode
{
consnode_t node;
+ char *symlink_path;
};
typedef mach_msg_header_t request_t;
@@ -69,7 +70,7 @@ console_demuxer (mach_msg_header_t *inp,
return 0;
}
- if (!ret && user->po->np->nn->node->demuxer)
+ if (!ret && user->po->np->nn->node && user->po->np->nn->node->demuxer)
ret = user->po->np->nn->node->demuxer (inp, outp);
ports_port_deref (user);
@@ -125,6 +126,15 @@ error_t
netfs_attempt_mksymlink (struct iouser *cred, struct node *np,
char *name)
{
+ if (!np->nn->node)
+ {
+ if (np->nn->symlink_path)
+ free (np->nn->symlink_path);
+ np->nn->symlink_path = strdup (name);
+ return 0;
+ }
+ else if (np->nn->node->mksymlink)
+ return np->nn->node->mksymlink (cred, np, name);
return EOPNOTSUPP;
}
@@ -272,8 +282,18 @@ netfs_attempt_lookup (struct iouser *user, struct node *dir,
nn->node = cn;
(*node)->nn_stat = netfs_root_node->nn_stat;
- (*node)->nn_stat.st_mode = S_IFCHR | (netfs_root_node->nn_stat.st_mode & ~S_IFMT & ~S_ITRANS);
+ (*node)->nn_stat.st_mode = (netfs_root_node->nn_stat.st_mode & ~S_IFMT & ~S_ITRANS);
(*node)->nn_stat.st_ino = 5;
+ if (cn->readlink)
+ {
+ (*node)->nn_stat.st_mode |= S_IFLNK;
+ (*node)->nn_stat.st_size = cn->readlink (user, NULL, NULL);
+ }
+ else
+ {
+ (*node)->nn_stat.st_mode |= S_IFCHR;
+ (*node)->nn_stat.st_size = 0;
+ }
cn->node = *node;
goto out;
}
@@ -325,7 +345,7 @@ netfs_S_io_select (struct protid *user, mach_port_t reply,
np = user->po->np;
- if (np->nn->node->select)
+ if (np->nn->node && np->nn->node->select)
return np->nn->node->select (user, reply, replytype, type);
return EOPNOTSUPP;
}
@@ -336,6 +356,21 @@ error_t
netfs_attempt_unlink (struct iouser *user, struct node *dir,
char *name)
{
+ error_t err;
+ consnode_t cn;
+
+ err = fshelp_access (&dir->nn_stat, S_IWRITE, user);
+ if (err)
+ return err;
+
+ for (cn = node_list; cn; cn = cn->next)
+ if (!strcmp (name, cn->name))
+ {
+ if (cn->mksymlink)
+ return 0;
+ else
+ break;
+ }
return EOPNOTSUPP;
}
@@ -378,6 +413,30 @@ error_t
netfs_attempt_link (struct iouser *user, struct node *dir,
struct node *file, char *name, int excl)
{
+ error_t err;
+ consnode_t cn;
+
+ err = fshelp_access (&dir->nn_stat, S_IWRITE, user);
+ if (err)
+ return err;
+
+ if (!file->nn->node && file->nn->symlink_path)
+ {
+ for (cn = node_list; cn; cn = cn->next)
+ if (!strcmp (name, cn->name))
+ {
+ if (cn->mksymlink)
+ {
+ file->nn->node = cn;
+ cn->mksymlink (user, file, file->nn->symlink_path);
+ free (file->nn->symlink_path);
+ file->nn->symlink_path = NULL;
+ return 0;
+ }
+ else
+ break;
+ }
+ }
return EOPNOTSUPP;
}
@@ -389,7 +448,27 @@ error_t
netfs_attempt_mkfile (struct iouser *user, struct node *dir,
mode_t mode, struct node **np)
{
- return EOPNOTSUPP;
+ error_t err;
+ struct netnode *nn;
+
+ err = fshelp_access (&dir->nn_stat, S_IWRITE, user);
+ if (err)
+ {
+ *np = 0;
+ return err;
+ }
+
+ mutex_unlock (&dir->lock);
+
+ nn = calloc (1, sizeof (*nn));
+ if (!nn)
+ return ENOMEM;
+
+ *np = netfs_make_node (nn);
+ mutex_lock (&(*np)->lock);
+ spin_unlock (&netfs_node_refcnt_lock);
+
+ return 0;
}
@@ -413,6 +492,8 @@ error_t
netfs_attempt_readlink (struct iouser *user, struct node *np,
char *buf)
{
+ if (np->nn->node && np->nn->node->readlink)
+ return np->nn->node->readlink (user, np, buf);
return EOPNOTSUPP;
}
@@ -471,7 +552,7 @@ netfs_S_io_read (struct protid *user,
return EOPNOTSUPP;
np = user->po->np;
- if (np->nn->node->read)
+ if (np->nn->node && np->nn->node->read)
return np->nn->node->read (user, data, datalen, offset, amount);
return EOPNOTSUPP;
}
@@ -490,7 +571,7 @@ netfs_S_io_write (struct protid *user,
return EOPNOTSUPP;
np = user->po->np;
- if (np->nn->node->read)
+ if (np->nn->node && np->nn->node->write)
return np->nn->node->write (user, data, datalen, offset, amount);
return EOPNOTSUPP;
}
@@ -517,9 +598,15 @@ netfs_report_access (struct iouser *cred, struct node *np,
void netfs_node_norefs (struct node *np)
{
- if (np->nn->node->close)
- np->nn->node->close ();
- np->nn->node->node = 0;
+ if (np->nn->node)
+ {
+ if (np->nn->node->close)
+ np->nn->node->close ();
+ np->nn->node->node = 0;
+ }
+
+ if (np->nn->symlink_path)
+ free (np->nn->symlink_path);
spin_unlock (&netfs_node_refcnt_lock);
free (np->nn);
@@ -645,7 +732,7 @@ netfs_get_dirents (struct iouser *cred, struct node *dir,
/* Fill in the real directory entries. */
for (cn = first_node; cn; cn = cn->next)
- if (!add_dir_entry (cn->name, cn->id, DT_CHR))
+ if (!add_dir_entry (cn->name, cn->id, cn->readlink ? DT_LNK : DT_CHR))
break;
}
@@ -689,6 +776,9 @@ console_create_consnode (const char *name, consnode_t *cn)
return ENOMEM;
}
+ (*cn)->readlink = NULL;
+ (*cn)->mksymlink = NULL;
+
return 0;
}