summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lnode.c4
-rw-r--r--lnode.h8
-rw-r--r--node.c229
-rw-r--r--node.h29
-rw-r--r--nsmux.c465
5 files changed, 546 insertions, 189 deletions
diff --git a/lnode.c b/lnode.c
index 406b7b4f5..aed83a0f5 100644
--- a/lnode.c
+++ b/lnode.c
@@ -138,6 +138,10 @@ lnode_destroy
/*Destroy the name of the node*/
free(node->name);
+ /*If there is a list of translators*/
+ if(node->trans)
+ free(node->trans);
+
/*Destroy the node itself*/
free(node);
}/*lnode_destroy*/
diff --git a/lnode.h b/lnode.h
index 9ca1ef2c5..674102523 100644
--- a/lnode.h
+++ b/lnode.h
@@ -32,6 +32,14 @@
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
+/*--------Macros--------------------------------------------------------------*/
+/*The possible flags in an lnode*/
+#define FLAG_LNODE_DIR 0x00000001 /*the lnode is a directory*/
+#define FLAG_LNODE_TRANSLATED 0x00000002 /*all appropriate translators
+ have already been set on this node*/
+/*----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------*/
/*A candy synonym for the fundamental libnetfs node*/
typedef struct node node_t;
/*----------------------------------------------------------------------------*/
diff --git a/node.c b/node.c
index a622db2bd..a37803e15 100644
--- a/node.c
+++ b/node.c
@@ -32,12 +32,14 @@
#include <sys/stat.h>
#include <sys/mman.h>
#include <stdio.h>
+#include <argz.h>
/*----------------------------------------------------------------------------*/
#include "debug.h"
#include "node.h"
#include "options.h"
#include "lib.h"
#include "nsmux.h"
+#include "ncache.h"
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
@@ -111,7 +113,16 @@ node_destroy
assert(!np->nn->ncache_next || !np->nn->ncache_prev);
/*Destroy the port to the underlying filesystem allocated to the node*/
- PORT_DEALLOC(np->nn->port);
+ if(np->nn->port != MACH_PORT_NULL)
+ PORT_DEALLOC(np->nn->port);
+
+ /*If the given node is not the root node and there are translators
+ to kill*/
+ if(np->nn->lnode->dir && np->nn->lnode->trans)
+ {
+ /*kill all translators on the underlying nodes*/
+ node_kill_all_translators(np);
+ }
/*Lock the lnode corresponding to the current node*/
mutex_lock(&np->nn->lnode->lock);
@@ -621,3 +632,219 @@ node_unlink_file
return err;
}/*node_unlink_file*/
/*----------------------------------------------------------------------------*/
+/*Sets the given translator on the supplied node*/
+/*This function will normally be called from netfs_attempt_lookup, therefore
+ it's better that the caller should provide the parent node for `node`.*/
+error_t
+node_set_translator
+ (
+ node_t * dir,
+ node_t * node,
+ const char * trans /*set this on `name`*/
+ )
+ {
+ error_t err;
+
+ /*A port for opened to the file*/
+ mach_port_t p;
+
+ /*A copy (possibly extended) of the name of the translator*/
+ char * ext;
+
+ /*The holders of argz-transformed translator name and arguments*/
+ char * argz = NULL;
+ size_t argz_len = 0;
+
+ /*The control port for the active translator*/
+ mach_port_t active_control;
+
+ /*Opens a port to the file at the request of fshelp_start_translator*/
+ error_t
+ open_port
+ (
+ int flags,
+ mach_port_t * underlying,
+ mach_msg_type_name_t * underlying_type,
+ task_t task,
+ void * cookie /*some additional information, not used here*/
+ )
+ {
+ /*Lookup the file we are working with*/
+ p = file_name_lookup_under
+ (dir->nn->port, node->nn->lnode->name, flags, 0);
+ if(p == MACH_PORT_NULL)
+ return errno;
+
+ /*Store the result in the parameters*/
+ *underlying = p;
+ *underlying_type = MACH_MSG_TYPE_COPY_SEND;
+
+ /*Here everything is OK*/
+ return 0;
+ }/*open_port*/
+
+ /*Adds a "/hurd/" at the beginning of the translator name, if required*/
+ char *
+ put_in_hurd
+ (
+ const char * name
+ )
+ {
+ /*If the path to the translator is absolute, return a copy of the name*/
+ /*TODO: A better decision technique on whether we have to add the prefix*/
+ if(name[0] == '/')
+ return strdup(name);
+
+ /*Compute the length of the name*/
+ size_t len = strlen(name);
+
+ /*Try to allocate new memory*/
+ char * full = malloc(6/*strlen("/hurd/")*/ + len + 1);
+ if(!full)
+ return NULL;
+
+ /*Construct the name*/
+ strcpy(full, "/hurd/");
+ /*LOG_MSG("node_set_translator: %s", full);*/
+ strcpy(full + 6, name);
+ /*LOG_MSG("node_set_translator: %s", full);*/
+ full[6 + len] = 0;
+ /*LOG_MSG("node_set_translator: %s", full);*/
+
+ /*Return the full path*/
+ return full;
+ }/*put_in_hurd*/
+
+ /*Obtain a copy (possibly extended) of the name*/
+ ext = put_in_hurd(trans);
+ if(!ext)
+ return ENOMEM;
+
+ /*TODO: Better argument-parsing?*/
+
+ /*Obtain the argz version of str*/
+ err = argz_create_sep(ext, ' ', &argz, &argz_len);
+ if(err)
+ return err;
+
+ /*Start the translator*/
+ err = fshelp_start_translator
+ (
+ open_port, NULL, argz, argz, argz_len,
+ 60000,/*this is the default in settrans*/
+ &active_control
+ );
+ if(err)
+ return err;
+
+ /*Attempt to set a translator on the port opened by the previous call*/
+ err = file_set_translator
+ (
+ p, 0, FS_TRANS_SET, 0, argz, argz_len,
+ active_control, MACH_MSG_TYPE_COPY_SEND
+ );
+ if(err)
+ return err;
+
+ /*Deallocate the port we have just opened*/
+ PORT_DEALLOC(p);
+
+ /*Everything is OK here*/
+ return 0;
+ }/*node_set_translator*/
+/*----------------------------------------------------------------------------*/
+/*Kill the topmost translator for this node*/
+/*This function will normally be called from netfs_attempt_lookup, therefore
+ it's better that the caller should provide the parent node for `node`.*/
+error_t
+node_kill_translator
+ (
+ node_t * dir,
+ node_t * node
+ )
+ {
+ /*Lookup the file*/
+ mach_port_t p =
+ file_name_lookup_under(dir->nn->port, node->nn->lnode->name, O_NOTRANS, 0);
+
+ /*Remove a translator from the node*/
+ error_t err = file_set_translator
+ (
+ p, FS_TRANS_SET, FS_TRANS_SET, 0, NULL, 0,
+ MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND
+ );
+
+ /*Close the port*/
+ PORT_DEALLOC(p);
+
+ /*Return the result of removing the translator*/
+ return err;
+ }/*node_kill_translator*/
+/*----------------------------------------------------------------------------*/
+/*Kills all translators on the nodes belonging to the given directory*/
+void
+node_kill_all_translators
+ (
+ node_t * node
+ )
+ {
+ /*Goes through all children of the given node recursively*/
+ void
+ traverse_children_r
+ (
+ node_t * dir,
+ node_t * np,
+ size_t ntrans /*the number of translators to remove from all nodes*/
+ )
+ {
+ int i;
+
+ /*A child of the current node*/
+ lnode_t * ln = np->nn->lnode;
+
+ /*If the current node is not a directory*/
+ if(!(ln->flags & FLAG_LNODE_DIR))
+ {
+ /*remove the required number of translators from the current node*/
+ for(i = 0; i < ntrans + ln->ntrans; ++i)
+ node_kill_translator(dir, np);
+ }
+ else
+ /*Go through the list of entries belonging to this directory*/
+ for(ln = ln->entries; ln; ln = ln->next)
+ {
+ /*die, if there is no node corresponding to the current child*/
+ /*This is abnormal, because lnodes should normally go away shortly
+ after the destruction of correpsonding nodes*/
+ assert(ln->node);
+
+ /*kill translators for this node*/
+ traverse_children_r(np, ln->node, ntrans + ln->ntrans);
+ }
+
+ /*Obtain a pointer to the lnode corresponding to np*/
+ ln = np->nn->lnode;
+
+ /*Destroy the list of translators*/
+ if(ln->trans)
+ free(ln->trans);
+
+ /*No more translators on this node*/
+ ln->trans = NULL;
+ ln->ntrans = ln->translen = 0;
+
+ /*There are no translators on this node*/
+ ln->flags &= ~FLAG_LNODE_TRANSLATED;
+ }/*traverse_children_r*/
+
+ /*Obtain the pointer to the parent node of the current node*/
+ node_t * dnp;
+ ncache_node_lookup(node->nn->lnode->dir, &dnp);
+
+ /*Kill all translators on the current node*/
+ traverse_children_r(dnp, node, node->nn->lnode->ntrans);
+
+ /*Unlock the parent node*/
+ mutex_unlock(&dnp->lock);
+ }/*node_kill_all_translators*/
+/*----------------------------------------------------------------------------*/
diff --git a/node.h b/node.h
index 584aa9f3d..72c244e8c 100644
--- a/node.h
+++ b/node.h
@@ -165,4 +165,33 @@ node_unlink_file
char * name
);
/*----------------------------------------------------------------------------*/
+/*Sets the given translator on the supplied node*/
+/*This function will normally be called from netfs_attempt_lookup, therefore
+ it's better that the caller should provide the parent node for `node`.*/
+error_t
+node_set_translator
+ (
+ node_t * dir,
+ node_t * node,
+ const char * trans /*set this on `name`*/
+ );
+/*----------------------------------------------------------------------------*/
+/*Kill the topmost translator for this node*/
+/*This function will normally be called from netfs_attempt_lookup, therefore
+ it's better that the caller should provide the parent node for `node`.*/
+error_t
+node_kill_translator
+ (
+ node_t * dir,
+ node_t * node
+ );
+/*----------------------------------------------------------------------------*/
+/*Kills all translators on the current node or on all underlying nodes it the
+ current node is a directory*/
+void
+node_kill_all_translators
+ (
+ node_t * node
+ );
+/*----------------------------------------------------------------------------*/
#endif /*__NODE_H__*/
diff --git a/nsmux.c b/nsmux.c
index d7f89002c..d512d7722 100644
--- a/nsmux.c
+++ b/nsmux.c
@@ -31,7 +31,6 @@
/*----------------------------------------------------------------------------*/
#include <error.h>
#include <argp.h>
-#include <argz.h>
#include <hurd/netfs.h>
#include <fcntl.h>
/*----------------------------------------------------------------------------*/
@@ -41,13 +40,6 @@
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
-/*--------Macros--------------------------------------------------------------*/
-/*The state modes use in open*/
-#define OPENONLY_STATE_MODES (O_CREAT | O_EXCL | O_NOLINK | O_NOTRANS \
- | O_NONBLOCK)
-/*----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------*/
/*--------Global Variables----------------------------------------------------*/
/*The name of the server*/
char * netfs_server_name = "nsmux";
@@ -520,6 +512,7 @@ netfs_attempt_lookup
LOG_MSG("netfs_attempt_lookup: '%s'", name);
error_t err = 0;
+ int i = 0;
/*If we are asked to fetch the current directory*/
if(strcmp(name, ".") == 0)
@@ -564,10 +557,32 @@ netfs_attempt_lookup
/*The lnode corresponding to the entry we are supposed to fetch*/
lnode_t * lnode;
+ /*The position of ',,' in the name*/
+ char * sep;
+
+ /*A pointer for various operations on strings*/
+ char * str;
+
+ /*A list of translators*/
+ char * trans = NULL;
+
+ /*The number of translators in the list*/
+ size_t ntrans;
+
+ /*The length of the list of translators*/
+ size_t translen;
+
+ /*Is the looked up file a directory*/
+ int isdir;
+
/*Finalizes the execution of this function*/
void
finalize(void)
{
+ /*Free the list of translators, if it has been allocated*/
+ if(trans)
+ free(trans);
+
/*If some errors have occurred*/
if(err)
{
@@ -625,6 +640,9 @@ netfs_attempt_lookup
{
/*do not set the port*/
p = MACH_PORT_NULL;
+
+ /*remember we do not have a directory*/
+ isdir = 0;
}
else
{
@@ -634,6 +652,9 @@ netfs_attempt_lookup
{
return EBADF; /*not enough rights?*/
}
+
+ /*we have a directory here*/
+ isdir = 1;
}
/*Try to find an lnode called `name` under the lnode corresponding to `dir`*/
@@ -653,28 +674,13 @@ netfs_attempt_lookup
/*install the new lnode into the directory*/
lnode_install(dir->nn->lnode, lnode);
}
- else
- {
- /*TODO: Remove the code from here and put it into the caller block,
- so that we can decide there whether to remove translators and
- *which* ones to remove*/
-
- /*free the list of translators associated with this node, if
- such a list exists*/
- if(lnode->trans)
- {
- free(lnode->trans);
- lnode->trans = NULL;
- lnode->ntrans = lnode->translen = 0;
- }
- }
-
+
/*Obtain the node corresponding to this lnode*/
err = ncache_node_lookup(lnode, node);
/*Remove an extra reference from the lnode*/
lnode_ref_remove(lnode);
-
+
/*If the lookup in the cache failed*/
if(err)
{
@@ -686,6 +692,12 @@ netfs_attempt_lookup
/*Store the port in the node*/
(*node)->nn->port = p;
+ /*Fill in the flag about the node being a directory*/
+ if(isdir)
+ lnode->flags |= FLAG_LNODE_DIR;
+ else
+ lnode->flags &= ~FLAG_LNODE_DIR;
+
/*Construct the full path to the node*/
err = lnode_path_construct(lnode, NULL);
if(err)
@@ -701,12 +713,6 @@ netfs_attempt_lookup
return 0;
}/*lookup*/
- /*The position of ',,' in the name*/
- char * sep;
-
- /*A pointer for various operations on strings*/
- char * str;
-
/*While pairs of commas can still be found in the name*/
for(sep = strstr(name, ",,"); sep; sep = strstr(sep, ",,"))
{
@@ -760,58 +766,219 @@ netfs_attempt_lookup
/*duplicate the part of the name containing the list of translators
and store the copy in the lnode*/
- lnode->trans = strdup(sep);
- if(!lnode->trans)
+ trans = strdup(sep);
+ if(!trans)
{
finalize();
return err;
}
- /*free the copy of the name*/
- /*we've just copied the pointer, so don't free it*/
- /*free(name_cpy);*/
-
/*obtain a pointer to the beginning of the list of translators*/
- str = lnode->trans;
+ str = trans;
- /*used to process escaped commas*/
- /*char * p;*/
+ /*a pointer for removal of extra commas*/
+ char * p;
/*Go through the list of translators*/
- for(lnode->ntrans = 0; *str; ++str)
+ for(translen = ntrans = 0; *str; ++str)
{
- /*Commas are not allowed in translator names*/
-#if 0
- /*If we are now situated at an escaped comma*/
- if((*str == '\\') && (str[1] == ','))
- {
- /*shift everything left in the string to remove the escaping backslash*/
- for(p = str; *p; *p = p[1], ++p);
-
- /*count a single character and step forward*/
- ++lnode->translen;
- continue;
- }
-#endif
-
/*If the current character is a comma*/
if(*str == ',')
{
+ /*While the next characters are commas, too*/
+ for(; str[1] == ',';)
+ {
+ /*shift the string leftwards*/
+ for(p = str + 1; *p; p[-1] = *p, ++p);
+ p[-1] = 0;
+ }
+
+ /*If the next character is the terminal 0*/
+ if(!str[1])
+ {
+ /*this comma is extra*/
+ *str = 0;
+ break;
+ }
+
/*make it a separator zero*/
*str = 0;
/*we have just finished going through a new component*/
- ++lnode->ntrans;
+ ++ntrans;
}
/*take the current character into account*/
- ++lnode->translen;
+ ++translen;
}
/*take into consideration the last element in the list,
which does not end in a comma and the corresponding terminal 0*/
- ++lnode->ntrans;
- ++lnode->translen;
+ ++ntrans;
+ ++translen;
+
+ /*If there are no translators set upon the current node*/
+ if(!lnode->trans)
+ {
+ /*copy the list of translators we have just built in the lnode*/
+ lnode->trans = trans;
+ lnode->ntrans = ntrans;
+ lnode->translen = translen;
+
+ /*If the node has already been fully translated before and it's
+ not a directory*/
+ /*We don't need to set the whole collection of translators,
+ both inherited and the ones in lnode->trans. The latter
+ are only necessary. Directories, on the other hand, cannot
+ bear translators on them.*/
+ if
+ (
+ (lnode->flags & FLAG_LNODE_TRANSLATED)
+ && !(lnode->flags & FLAG_LNODE_DIR)
+ )
+ {
+ /*Go through the list of translators*/
+ for(str = trans, i = 0; i < ntrans; ++i)
+ {
+ /*set the translator specified in the current component*/
+ err = node_set_translator(dir, *node, str);
+ if(err)
+ {
+ finalize();
+ return 0; /*TODO: A better way to fight errors here*/
+ }
+
+ /*skip the current component*/
+ str += strlen(str) + 1;
+ }
+
+ /*we don't own the list of translators any more*/
+ trans = NULL;
+ ntrans = 0;
+ translen = 0;
+
+ /*here the lookup is successful*/
+ err = 0;
+ finalize();
+ return err;
+ }
+
+ /*we don't own the list of translators any more*/
+ trans = NULL;
+ ntrans = 0;
+ translen = 0;
+ }
+ else
+ {
+ /*If the current node is not a directory*/
+ if(!isdir)
+ {
+ /*obtain the minimal of the lengths of the lists of translators*/
+ size_t minlen =
+ (translen < lnode->translen) ? (translen) : (lnode->translen);
+
+ /*the number of similar translators*/
+ size_t similar = 0;
+
+ /*the current position in the list*/
+ size_t i;
+
+ /*Go through the lists of translators*/
+ for(i = 0; i < minlen; ++i)
+ {
+ /*If the current characters are different, stop here*/
+ if(trans[i] != lnode->trans[i])
+ break;
+
+ /*If the current character marks the end of a translator name*/
+ if(trans[i] == 0)
+ /*one more matching translator*/
+ ++similar;
+ }
+
+ /*While all not matching translators have not been removed*/
+ size_t j;
+ for(j = 0; j < lnode->ntrans - similar; ++j)
+ {
+ /*remove one more translator*/
+ err = node_kill_translator(dir, *node);
+ if(err)
+ {
+ finalize();
+ return err;
+ }
+ }
+
+ /*obtain the pointer to the first not matching position*/
+ str = trans + i;
+
+ /*seek to the beginning of the current translator name*/
+ for(; (str > trans) && *str; --str);
+
+ /*While the required new translators have not been set*/
+ for(i = 0; i < ntrans - similar; ++i)
+ {
+ /*set the current translator on the file*/
+ err = node_set_translator(dir, *node, str);
+ if(err)
+ {
+ finalize();
+ return err;
+ }
+
+ /*skip the current translator*/
+ str += strlen(str) + 1;
+ }
+ }
+ /*We have looked up a directory*/
+ else
+ {
+ /*If the length of the lists of translators are the same*/
+ if((lnode->translen = translen) && (lnode->ntrans == ntrans))
+ {
+ /*check each character of the list of translators*/
+ int i;
+ for(i = 0; (i < translen) && (lnode->trans[i] == trans[i]); ++i);
+
+ /*If the lists coincide*/
+ if(i == translen)
+ {
+ /*the lookup has finished successfully here*/
+ err = 0;
+ finalize();
+ return err;
+ }
+ }
+
+ /*unlock the directory in which we are at the moment*/
+ mutex_unlock(&dir->lock);
+
+ /*kill all translators on all children of this node*/
+ node_kill_all_translators(*node);
+
+ /*lock the directory back*/
+ mutex_lock(&dir->lock);
+ }
+
+ /*destroy the list of translators in the current node*/
+ free(lnode->trans);
+
+ /*put the new list in the node*/
+ lnode->trans = trans;
+ lnode->ntrans = ntrans;
+ lnode->translen = translen;
+
+ /*all required translators have been already applied on this node*/
+ /*lnode->flags |= FLAG_LNODE_TRANSLATED;*/
+
+ /*we don't own the list of translators any more*/
+ trans = NULL;
+
+ /*the lookup is already finished here*/
+ err = 0;
+ finalize();
+ return err;
+ }
}
/*The control sequence ',,' has not been found*/
else
@@ -823,14 +990,51 @@ netfs_attempt_lookup
finalize();
return err;
}
+
+ /*If there are some translators set on this file*/
+ if(lnode->trans)
+ {
+ /*unlock the directory*/
+ mutex_unlock(&dir->lock);
+
+ /*kill all translators on this node*/
+ node_kill_all_translators(*node);
+
+ /*lock the directory again*/
+ mutex_lock(&dir->lock);
+
+ /*all translators have been succesfully set here*/
+ /*lnode->flags |= FLAG_LNODE_TRANSLATED;*/
+
+ /*the lookup has finished successfully here*/
+ /*The translators inherited from parents survive throughout
+ the previous loop*/
+ err = 0;
+ finalize();
+ return err;
+ }
}
- /*The list of translators inherited from its ancestors*/
- char * trans;
-
- /*the number of translators*/
- size_t ntrans;
-
+ /*If we have a directory*/
+ if(isdir)
+ {
+ /*FIXME: It means we've got a directory, and no translators are set on
+ directories. The point is that nsmux should mainly handle libtrivs-based
+ translators, which should not operate on directories.*/
+ err = 0;
+ finalize();
+ return err;
+ }
+
+ /*If the current node has already been successfully translated*/
+ if(lnode->flags & FLAG_LNODE_TRANSLATED)
+ {
+ /*no additional translators must set on this file*/
+ err = 0;
+ finalize();
+ return err;
+ }
+
/*Obtain the list of inherited translators*/
err = lnode_list_translators(lnode, &trans, &ntrans);
if(err)
@@ -847,139 +1051,24 @@ netfs_attempt_lookup
return 0;
}
- int i;
-
- /*If there is a port open for the current node*/
- if((*node)->nn->port != MACH_PORT_NULL)
- {
- /*close the port, since we will open it when starting translators*/
- PORT_DEALLOC((*node)->nn->port);
- }
-
- /*Opens a port to the file at the request of fshelp_start_translator*/
- error_t
- open_port
- (
- int flags,
- mach_port_t * underlying,
- mach_msg_type_name_t * underlying_type,
- task_t task,
- void * cookie /*some additional information, not used here*/
- )
- {
- /*Lookup the file we are working with*/
- p = file_name_lookup_under
- (dir->nn->port, (*node)->nn->lnode->name, flags, 0);
- if(p == MACH_PORT_NULL)
- return errno;
-
- /*Store the result in the parameters*/
- *underlying = p;
- *underlying_type = MACH_MSG_TYPE_COPY_SEND;
-
- /*Here everything is OK*/
- return 0;
- }/*open_port*/
-
- /*Adds a "/hurd/" at the beginning of the translator name, if required*/
- char *
- put_in_hurd
- (
- char * name
- )
- {
- /*If the path to the translator is absolute, return a copy of the name*/
- /*TODO: A better decision technique on whether we have to add the prefix*/
- if(name[0] == '/')
- return strdup(name);
-
- /*Compute the length of the name*/
- size_t len = strlen(name);
-
- /*Try to allocate new memory*/
- char * full = malloc(6/*strlen("/hurd/")*/ + len + 1);
- if(!full)
- return NULL;
-
- /*Construct the name*/
- strcpy(full, "/hurd/");
- strcpy(full + 6, name);
- full[6 + len] = 0;
-
- /*Return the full path*/
- return full;
- }/*put_in_hurd*/
-
- /*A copy (possibly extended) of the name of the translator*/
- char * ext;
-
- /*The length of the current component in the list of translators*/
- size_t complen;
-
- /*The holders of argz-transformed translator name and arguments*/
- char * argz = NULL;
- size_t argz_len = 0;
-
- /*The control port for the active translator*/
- mach_port_t active_control;
-
/*Go through the list of translators*/
for(str = trans, i = 0; i < ntrans; ++i)
{
- /*obtain the length of the current component*/
- complen = strlen(str);
-
- /*obtain a copy (possibly extended) of the name*/
- ext = put_in_hurd(str);
- if(!ext)
- {
- err = ENOMEM;
- finalize();
- return err;
- }
-
- /*TODO: Better argument-parsing?*/
-
- /*obtain the argz version of str*/
- err = argz_create_sep(ext, ' ', &argz, &argz_len);
+ /*set the translator specified in the current component*/
+ err = node_set_translator(dir, *node, str);
if(err)
{
finalize();
- return err;
+ return 0; /*TODO: A better way to fight errors here*/
}
-
- /*start the translator*/
- err = fshelp_start_translator
- (
- open_port, NULL, argz, argz, argz_len,
- 60000,/*this is the default in settrans*/
- &active_control
- );
- if(err)
- {
- finalize();
- return err;
- }
-
- /*attempt to set a translator on the port opened by the previous call*/
- err = file_set_translator
- (
- p, 0, FS_TRANS_SET, 0, argz, argz_len,
- active_control, MACH_MSG_TYPE_COPY_SEND
- );
- if(err)
- {
- finalize();
- return err;
- }
-
- /*deallocate the port we have just opened*/
- PORT_DEALLOC(p);
-
+
/*skip the current component*/
- str += complen + 1;
+ str += strlen(str) + 1;
}
+ /*All translators have been succesfully set on this node*/
+ lnode->flags |= FLAG_LNODE_TRANSLATED;
+
/*Everything OK here*/
finalize();
return err;