summaryrefslogtreecommitdiff
path: root/nsmux.c
diff options
context:
space:
mode:
authorSergiu Ivanov <unlimitedscolobb@gmail.com>2008-11-21 23:54:40 +0200
committerSergiu Ivanov <unlimitedscolobb@gmail.com>2008-11-21 23:54:40 +0200
commita54273639f6afd659c15326cb997922fcecfe89a (patch)
tree3f240fed8fcfd7f14cbc5b7d059f48f6eb9707cb /nsmux.c
parent59f4d4d2b67028c01f41ea0de0f12934b4fad07b (diff)
Moved the code to GCS
Now the code is (hopefully) compliant with GNU Coding Standards.
Diffstat (limited to 'nsmux.c')
-rw-r--r--nsmux.c2792
1 files changed, 1328 insertions, 1464 deletions
diff --git a/nsmux.c b/nsmux.c
index e5247b39a..5ac3c0fdf 100644
--- a/nsmux.c
+++ b/nsmux.c
@@ -1,10 +1,10 @@
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*nsmux.c*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*The filesystem proxy for namespace-based translator selection.*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Based on the code of unionfs translator.*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Copyright (C) 2001, 2002, 2005, 2008 Free Software Foundation, Inc.
Written by Sergiu Ivanov <unlimitedscolobb@gmail.com>.
@@ -22,938 +22,882 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#define _GNU_SOURCE 1
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#include "nsmux.h"
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#include <error.h>
#include <argp.h>
#include <hurd/netfs.h>
#include <fcntl.h>
#include <hurd/paths.h>
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#include "debug.h"
#include "options.h"
#include "ncache.h"
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Global Variables----------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Global Variables---------------------------------------------------*/
/*The name of the server*/
-char * netfs_server_name = "nsmux";
-/*----------------------------------------------------------------------------*/
+char *netfs_server_name = "nsmux";
+/*---------------------------------------------------------------------------*/
/*The version of the server*/
-char * netfs_server_version = "0.0";
-/*----------------------------------------------------------------------------*/
+char *netfs_server_version = "0.0";
+/*---------------------------------------------------------------------------*/
/*The maximal length of a chain of symbolic links*/
int netfs_maxsymlinks = 12;
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*A port to the underlying node*/
mach_port_t underlying_node;
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Status information for the underlying node*/
io_statbuf_t underlying_node_stat;
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Mapped time used for updating node information*/
-volatile struct mapped_time_value * maptime;
-/*----------------------------------------------------------------------------*/
+volatile struct mapped_time_value *maptime;
+/*---------------------------------------------------------------------------*/
/*The filesystem ID*/
pid_t fsid;
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*The file to print debug messages to*/
-FILE * nsmux_dbg;
-/*----------------------------------------------------------------------------*/
+FILE *nsmux_dbg;
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Functions-----------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Functions----------------------------------------------------------*/
/*Attempts to create a file named `name` in `dir` for `user` with mode `mode`*/
error_t
-netfs_attempt_create_file
- (
- struct iouser * user,
- struct node * dir,
- char * name,
- mode_t mode,
- struct node ** node
- )
- {
- LOG_MSG("netfs_attempt_create_file");
-
- /*Unlock `dir` and say that we can do nothing else here*/
- mutex_unlock(&dir->lock);
- return EOPNOTSUPP;
- }/*netfs_attempt_create_file*/
-/*----------------------------------------------------------------------------*/
-/*Return an error if the process of opening a file should not be allowed
- to complete because of insufficient permissions*/
+ netfs_attempt_create_file
+ (struct iouser *user,
+ struct node *dir, char *name, mode_t mode, struct node **node)
+{
+ LOG_MSG ("netfs_attempt_create_file");
+
+ /*Unlock `dir` and say that we can do nothing else here */
+ mutex_unlock (&dir->lock);
+ return EOPNOTSUPP;
+} /*netfs_attempt_create_file */
+
+/*---------------------------------------------------------------------------*/
+/*Return an error if the process of opening a file should not be
+ allowed to complete because of insufficient permissions*/
error_t
-netfs_check_open_permissions
- (
- struct iouser * user,
- struct node * np,
- int flags,
- int newnode
- )
- {
- LOG_MSG("netfs_check_open_permissions: '%s'", np->nn->lnode->name);
+ netfs_check_open_permissions
+ (struct iouser * user, struct node * np, int flags, int newnode)
+{
+ LOG_MSG ("netfs_check_open_permissions: '%s'", np->nn->lnode->name);
+
+ /*Cheks user's permissions and return the result */
+ return check_open_permissions (user, &np->nn_stat, flags);
+} /*netfs_check_open_permissions */
- /*Cheks user's permissions and return the result*/
- return check_open_permissions(user, &np->nn_stat, flags);
- }/*netfs_check_open_permissions*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Attempts an utimes call for the user `cred` on node `node`*/
error_t
-netfs_attempt_utimes
- (
- struct iouser * cred,
- struct node * node,
- struct timespec * atime,
- struct timespec * mtime
- )
- {
- LOG_MSG("netfs_attempt_utimes");
-
- error_t err = 0;
-
- /*See what information is to be updated*/
- int flags = TOUCH_CTIME;
-
- /*Check if the user is indeed the owner of the node*/
- err = fshelp_isowner(&node->nn_stat, cred);
-
- /*If the user is allowed to do utimes*/
- if(!err)
- {
- /*If atime is to be updated*/
- if(atime)
- /*update the atime*/
- node->nn_stat.st_atim = *atime;
- else
- /*the current time will be set as the atime*/
- flags |= TOUCH_ATIME;
-
- /*If mtime is to be updated*/
- if(mtime)
- /*update the mtime*/
- node->nn_stat.st_mtim = *mtime;
- else
- /*the current time will be set as mtime*/
- flags |= TOUCH_MTIME;
-
- /*touch the file*/
- fshelp_touch(&node->nn_stat, flags, maptime);
- }
-
- /*Return the result of operations*/
- return err;
- }/*netfs_attempt_utimes*/
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_utimes
+ (struct iouser * cred,
+ struct node * node, struct timespec * atime, struct timespec * mtime)
+{
+ LOG_MSG ("netfs_attempt_utimes");
+
+ error_t err = 0;
+
+ /*See what information is to be updated */
+ int flags = TOUCH_CTIME;
+
+ /*Check if the user is indeed the owner of the node */
+ err = fshelp_isowner (&node->nn_stat, cred);
+
+ /*If the user is allowed to do utimes */
+ if (!err)
+ {
+ /*If atime is to be updated */
+ if (atime)
+ /*update the atime */
+ node->nn_stat.st_atim = *atime;
+ else
+ /*the current time will be set as the atime */
+ flags |= TOUCH_ATIME;
+
+ /*If mtime is to be updated */
+ if (mtime)
+ /*update the mtime */
+ node->nn_stat.st_mtim = *mtime;
+ else
+ /*the current time will be set as mtime */
+ flags |= TOUCH_MTIME;
+
+ /*touch the file */
+ fshelp_touch (&node->nn_stat, flags, maptime);
+ }
+
+ /*Return the result of operations */
+ return err;
+} /*netfs_attempt_utimes */
+
+/*---------------------------------------------------------------------------*/
/*Returns the valid access types for file `node` and user `cred`*/
error_t
-netfs_report_access
- (
- struct iouser * cred,
- struct node * np,
- int * types
- )
- {
- LOG_MSG("netfs_report_access");
-
- /*No access at first*/
- *types = 0;
-
- /*Check the access and set the required bits*/
- if(fshelp_access(&np->nn_stat, S_IREAD, cred) == 0)
- *types |= O_READ;
- if(fshelp_access(&np->nn_stat, S_IWRITE, cred) == 0)
- *types |= O_WRITE;
- if(fshelp_access(&np->nn_stat, S_IEXEC, cred) == 0)
- *types |= O_EXEC;
-
- /*Everything OK*/
- return 0;
- }/*netfs_report_access*/
-/*----------------------------------------------------------------------------*/
+ netfs_report_access (struct iouser * cred, struct node * np, int *types)
+{
+ LOG_MSG ("netfs_report_access");
+
+ /*No access at first */
+ *types = 0;
+
+ /*Check the access and set the required bits */
+ if (fshelp_access (&np->nn_stat, S_IREAD, cred) == 0)
+ *types |= O_READ;
+ if (fshelp_access (&np->nn_stat, S_IWRITE, cred) == 0)
+ *types |= O_WRITE;
+ if (fshelp_access (&np->nn_stat, S_IEXEC, cred) == 0)
+ *types |= O_EXEC;
+
+ /*Everything OK */
+ return 0;
+} /*netfs_report_access */
+
+/*---------------------------------------------------------------------------*/
/*Validates the stat data for the node*/
-error_t
-netfs_validate_stat
- (
- struct node * np,
- struct iouser * cred
- )
+error_t netfs_validate_stat (struct node * np, struct iouser * cred)
+{
+ LOG_MSG ("netfs_validate_stat: '%s'", (np ? np->nn->lnode->name : ""));
+
+ error_t err = 0;
+
+ /*If we are not at the root */
+ if (np != netfs_root_node)
+ {
+ /*If the node is not surely up-to-date */
+ if (!(np->nn->flags & FLAG_NODE_ULFS_UPTODATE))
{
- LOG_MSG("netfs_validate_stat: '%s'", (np ? np->nn->lnode->name : ""));
+ /*update it */
+ err = node_update (np);
+ }
- error_t err = 0;
-
- /*If we are not at the root*/
- if(np != netfs_root_node)
- {
- /*If the node is not surely up-to-date*/
- if(!(np->nn->flags & FLAG_NODE_ULFS_UPTODATE))
- {
- /*update it*/
- err = node_update(np);
- }
-
- /*If no errors have yet occurred*/
- if(!err)
- {
- /*If the port to the file corresponding to `np` is valid*/
- if(np->nn->port != MACH_PORT_NULL)
- {
- /*We have a directory here (normally, only they maintain an open port).
- Generally, our only concern is to maintain an open port in this case*/
-
- /*attempt to stat this file*/
- err = io_stat(np->nn->port, &np->nn_stat);
-
- if(S_ISDIR(np->nn_stat.st_mode))
- LOG_MSG("\tIs a directory");
-
- /*If stat information has been successfully obtained for the file*/
- if(!err)
- /*duplicate the st_mode field of stat structure*/
- np->nn_translated = np->nn_stat.st_mode;
- }
- else
- {
- /*We, most probably, have something which is not a directory. Therefore
- we will open the port and close it after the stat, so that additional
- resources are not consumed.*/
-
- /*the parent node of the current node*/
- node_t * dnp;
-
- /*obtain the parent node of the the current node*/
- err = ncache_node_lookup(np->nn->lnode->dir, &dnp);
-
- /*the lookup should never fail here*/
- assert(!err);
-
- /*open a port to the file we are interested in*/
- mach_port_t p = file_name_lookup_under
- (dnp->nn->port, np->nn->lnode->name, 0, 0);
-
- /*put `dnp` back, since we don't need it any more*/
- netfs_nput(dnp);
-
- if(!p)
- return EBADF;
-
- /*try to stat the node*/
- err = io_stat(p, &np->nn_stat);
-
- /*deallocate the port*/
- PORT_DEALLOC(p);
- }
- }
- }
- /*If we are at the root*/
- else
- /*put the size of the node into the stat structure belonging to `np`*/
- node_get_size(np, (OFFSET_T *)&np->nn_stat.st_size);
+ /*If no errors have yet occurred */
+ if (!err)
+ {
+ /*If the port to the file corresponding to `np` is valid */
+ if (np->nn->port != MACH_PORT_NULL)
+ {
+ /*We have a directory here (normally, only they maintain an open port).
+ Generally, our only concern is to maintain an open port in this case */
- /*Return the result of operations*/
- return err;
- }/*netfs_validate_stat*/
-/*----------------------------------------------------------------------------*/
+ /*attempt to stat this file */
+ err = io_stat (np->nn->port, &np->nn_stat);
+
+ if (S_ISDIR (np->nn_stat.st_mode))
+ LOG_MSG ("\tIs a directory");
+
+ /*If stat information has been successfully obtained for the file */
+ if (!err)
+ /*duplicate the st_mode field of stat structure */
+ np->nn_translated = np->nn_stat.st_mode;
+ }
+ else
+ {
+ /*We, most probably, have something which is not a directory. Therefore
+ we will open the port and close it after the stat, so that additional
+ resources are not consumed. */
+
+ /*the parent node of the current node */
+ node_t *dnp;
+
+ /*obtain the parent node of the the current node */
+ err = ncache_node_lookup (np->nn->lnode->dir, &dnp);
+
+ /*the lookup should never fail here */
+ assert (!err);
+
+ /*open a port to the file we are interested in */
+ mach_port_t p = file_name_lookup_under
+ (dnp->nn->port, np->nn->lnode->name, 0, 0);
+
+ /*put `dnp` back, since we don't need it any more */
+ netfs_nput (dnp);
+
+ if (!p)
+ return EBADF;
+
+ /*try to stat the node */
+ err = io_stat (p, &np->nn_stat);
+
+ /*deallocate the port */
+ PORT_DEALLOC (p);
+ }
+ }
+ }
+ /*If we are at the root */
+ else
+ /*put the size of the node into the stat structure belonging to `np` */
+ node_get_size (np, (OFFSET_T *) & np->nn_stat.st_size);
+
+ /*Return the result of operations */
+ return err;
+} /*netfs_validate_stat */
+
+/*---------------------------------------------------------------------------*/
/*Syncs `node` completely to disk*/
error_t
-netfs_attempt_sync
- (
- struct iouser * cred,
- struct node * node,
- int wait
- )
- {
- LOG_MSG("netfs_attempt_sync");
+ netfs_attempt_sync (struct iouser * cred, struct node * node, int wait)
+{
+ LOG_MSG ("netfs_attempt_sync");
+
+ /*Operation is not supported */
+ return EOPNOTSUPP;
+} /*netfs_attempt_sync */
- /*Operation is not supported*/
- return EOPNOTSUPP;
- }/*netfs_attempt_sync*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Fetches a directory*/
error_t
-netfs_get_dirents
- (
- struct iouser * cred,
- struct node * dir,
- int first_entry,
- int num_entries,
- char ** data,
- mach_msg_type_number_t * data_len,
- vm_size_t max_data_len,
- int * data_entries
- )
- {
- LOG_MSG("netfs_get_dirents: '%s'", dir->nn->lnode->name);
-
- error_t err;
-
- /*Two pointers required for processing the list of dirents*/
- node_dirent_t * dirent_start, * dirent_current;
-
- /*The pointer to the beginning of the list of dirents*/
- node_dirent_t * dirent_list = NULL;
-
- /*The size of the current dirent*/
- size_t size = 0;
-
- /*The number of dirents added*/
- int count = 0;
-
- /*The dereferenced value of parameter `data`*/
- char * data_p;
-
- /*Takes into account the size of the given dirent*/
- int
- bump_size
- (
- const char * name
- )
- {
- /*If the required number of entries has not been listed yet*/
- if((num_entries == -1) || (count < num_entries))
- {
- /*take the current size and take into account the length of the name*/
- size_t new_size = size + DIRENT_LEN(strlen(name));
-
- /*If there is a limit for the received size and it has been exceeded*/
- if((max_data_len > 0) && (new_size > max_data_len))
- /*a new dirent cannot be added*/
- return 0;
-
- /*memorize the new size*/
- size = new_size;
-
- /*increase the number of dirents added*/
- ++count;
-
- /*everything is OK*/
- return 1;
- }
- else
- {
- /*dirents cannot be added*/
- return 0;
- }
- }/*bump_size*/
-
- /*Adds a dirent to the list of dirents*/
- int
- add_dirent
- (
- const char * name,
- ino_t ino,
- int type
- )
- {
- /*If the required number of dirents has not been listed yet*/
- if((num_entries == -1) || (count < num_entries))
- {
- /*create a new dirent*/
- struct dirent hdr;
-
- /*obtain the length of the name*/
- size_t name_len = strlen(name);
-
- /*compute the full size of the dirent*/
- size_t sz = DIRENT_LEN(name_len);
-
- /*If there is no room for this dirent*/
- if(sz > size)
- /*stop*/
- return 0;
- else
- /*take into account the fact that a new dirent has just been added*/
- size -= sz;
-
- /*setup the dirent*/
- hdr.d_ino = ino;
- hdr.d_reclen = sz;
- hdr.d_type = type;
- hdr.d_namlen = name_len;
-
- /*The following two lines of code reflect the old layout of
- dirents in the memory. Now libnetfs expects the layout
- identical to the layout provided by dir_readdir (see dir_entries_get)*/
-
- /*copy the header of the dirent into the final block of dirents*/
- memcpy(data_p, &hdr, DIRENT_NAME_OFFS);
-
- /*copy the name of the dirent into the block of dirents*/
- strcpy(data_p + DIRENT_NAME_OFFS, name);
-
- /*This line is commented for the same reason as the two specifically
- commented lines above.*/
- /*move the current pointer in the block of dirents*/
- data_p += sz;
-
- /*count the new dirent*/
- ++count;
-
- /*everything was OK, so say it*/
- return 1;
- }
- else
- /*no [new] dirents allowed*/
- return 0;
- }/*add_dirent*/
-
- /*List the dirents for node `dir`*/
- err = node_entries_get(dir, &dirent_list);
-
- /*If listing was successful*/
- if(!err)
- {
- /*find the entry whose number is `first_entry`*/
- for
- (
- dirent_start = dirent_list, count = 2;
- dirent_start && (count < first_entry);
- dirent_start = dirent_start->next, ++count
- );
-
- /*reset number of dirents added so far*/
- count = 0;
-
- /*make space for entries '.' and '..', if required*/
- if(first_entry == 0)
- bump_size(".");
- if(first_entry <= 1)
- bump_size("..");
-
- /*Go through all dirents*/
- for
- (
- dirent_current = dirent_start;
- dirent_current;
- dirent_current = dirent_current->next
- )
- /*If another dirent cannot be added succesfully*/
- if(bump_size(dirent_current->dirent->d_name) == 0)
- /*stop here*/
- break;
-
- /*allocate the required space for dirents*/
- *data = mmap(0, size, PROT_READ | PROT_WRITE, MAP_ANON, 0, 0);
-
- /*check if any error occurred*/
- err = ((void *)*data == MAP_FAILED) ? (errno) : (0);
- }
-
- /*If no errors have occurred so far*/
- if(!err)
- {
- /*obtain the pointer to the beginning of the block of dirents*/
- data_p = *data;
-
- /*fill the parameters with useful values*/
- *data_len = size;
- *data_entries = count;
-
- /*reset the number of dirents added*/
- count = 0;
-
- /*add entries '.' and '..', if required*/
- if(first_entry == 0)
- add_dirent(".", 2, DT_DIR);
- if(first_entry <= 1)
- add_dirent("..", 2, DT_DIR);
-
- /*Follow the list of dirents beginning with dirents_start*/
- for
- (
- dirent_current = dirent_start; dirent_current;
- dirent_current = dirent_current->next
- )
- /*If the addition of the current dirent fails*/
- if
- (
- add_dirent
- (dirent_current->dirent->d_name, dirent_current->dirent->d_fileno,
- dirent_current->dirent->d_type) == 0
- )
- /*stop adding dirents*/
- break;
- }
-
- /*If the list of dirents has been allocated, free it*/
- if(dirent_list)
- node_entries_free(dirent_list);
-
- /*The directory has been read right now, modify the access time*/
- fshelp_touch(&dir->nn_stat, TOUCH_ATIME, maptime);
-
- /*Return the result of listing the dirents*/
- return err;
- }/*netfs_get_dirents*/
-/*----------------------------------------------------------------------------*/
+ netfs_get_dirents
+ (struct iouser * cred,
+ struct node * dir,
+ int first_entry,
+ int num_entries,
+ char **data,
+ mach_msg_type_number_t * data_len,
+ vm_size_t max_data_len, int *data_entries)
+{
+ LOG_MSG ("netfs_get_dirents: '%s'", dir->nn->lnode->name);
+
+ error_t err;
+
+ /*Two pointers required for processing the list of dirents */
+ node_dirent_t *dirent_start, *dirent_current;
+
+ /*The pointer to the beginning of the list of dirents */
+ node_dirent_t *dirent_list = NULL;
+
+ /*The size of the current dirent */
+ size_t size = 0;
+
+ /*The number of dirents added */
+ int count = 0;
+
+ /*The dereferenced value of parameter `data` */
+ char *data_p;
+
+ /*Takes into account the size of the given dirent */
+ int bump_size (const char *name)
+ {
+ /*If the required number of entries has not been listed yet */
+ if ((num_entries == -1) || (count < num_entries))
+ {
+ /*take the current size and take into account the length of the name */
+ size_t new_size = size + DIRENT_LEN (strlen (name));
+
+ /*If there is a limit for the received size and it has been exceeded */
+ if ((max_data_len > 0) && (new_size > max_data_len))
+ /*a new dirent cannot be added */
+ return 0;
+
+ /*memorize the new size */
+ size = new_size;
+
+ /*increase the number of dirents added */
+ ++count;
+
+ /*everything is OK */
+ return 1;
+ }
+ else
+ {
+ /*dirents cannot be added */
+ return 0;
+ }
+ } /*bump_size */
+
+ /*Adds a dirent to the list of dirents */
+ int add_dirent (const char *name, ino_t ino, int type)
+ {
+ /*If the required number of dirents has not been listed yet */
+ if ((num_entries == -1) || (count < num_entries))
+ {
+ /*create a new dirent */
+ struct dirent hdr;
+
+ /*obtain the length of the name */
+ size_t name_len = strlen (name);
+
+ /*compute the full size of the dirent */
+ size_t sz = DIRENT_LEN (name_len);
+
+ /*If there is no room for this dirent */
+ if (sz > size)
+ /*stop */
+ return 0;
+ else
+ /*take into account the fact that a new dirent has just been added */
+ size -= sz;
+
+ /*setup the dirent */
+ hdr.d_ino = ino;
+ hdr.d_reclen = sz;
+ hdr.d_type = type;
+ hdr.d_namlen = name_len;
+
+ /*The following two lines of code reflect the old layout of
+ dirents in the memory. Now libnetfs expects the layout
+ identical to the layout provided by dir_readdir
+ see dir_entries_get) */
+
+ /*copy the header of the dirent into the final block of dirents */
+ memcpy (data_p, &hdr, DIRENT_NAME_OFFS);
+
+ /*copy the name of the dirent into the block of dirents */
+ strcpy (data_p + DIRENT_NAME_OFFS, name);
+
+ /*This line is commented for the same reason as the two specifically
+ commented lines above. */
+ /*move the current pointer in the block of dirents */
+ data_p += sz;
+
+ /*count the new dirent */
+ ++count;
+
+ /*everything was OK, so say it */
+ return 1;
+ }
+ else
+ /*no [new] dirents allowed */
+ return 0;
+ } /*add_dirent */
+
+ /*List the dirents for node `dir` */
+ err = node_entries_get (dir, &dirent_list);
+
+ /*If listing was successful */
+ if (!err)
+ {
+ /*find the entry whose number is `first_entry` */
+ for
+ (dirent_start = dirent_list, count = 2;
+ dirent_start && (count < first_entry);
+ dirent_start = dirent_start->next, ++count);
+
+ /*reset number of dirents added so far */
+ count = 0;
+
+ /*make space for entries '.' and '..', if required */
+ if (first_entry == 0)
+ bump_size (".");
+ if (first_entry <= 1)
+ bump_size ("..");
+
+ /*Go through all dirents */
+ for
+ (dirent_current = dirent_start;
+ dirent_current; dirent_current = dirent_current->next)
+ /*If another dirent cannot be added succesfully */
+ if (bump_size (dirent_current->dirent->d_name) == 0)
+ /*stop here */
+ break;
+
+ /*allocate the required space for dirents */
+ *data = mmap (0, size, PROT_READ | PROT_WRITE, MAP_ANON, 0, 0);
+
+ /*check if any error occurred */
+ err = ((void *) *data == MAP_FAILED) ? (errno) : (0);
+ }
+
+ /*If no errors have occurred so far */
+ if (!err)
+ {
+ /*obtain the pointer to the beginning of the block of dirents */
+ data_p = *data;
+
+ /*fill the parameters with useful values */
+ *data_len = size;
+ *data_entries = count;
+
+ /*reset the number of dirents added */
+ count = 0;
+
+ /*add entries '.' and '..', if required */
+ if (first_entry == 0)
+ add_dirent (".", 2, DT_DIR);
+ if (first_entry <= 1)
+ add_dirent ("..", 2, DT_DIR);
+
+ /*Follow the list of dirents beginning with dirents_start */
+ for
+ (dirent_current = dirent_start; dirent_current;
+ dirent_current = dirent_current->next)
+ /*If the addition of the current dirent fails */
+ if (add_dirent
+ (dirent_current->dirent->d_name, dirent_current->dirent->d_fileno,
+ dirent_current->dirent->d_type) == 0)
+ /*stop adding dirents */
+ break;
+ }
+
+ /*If the list of dirents has been allocated, free it */
+ if (dirent_list)
+ node_entries_free (dirent_list);
+
+ /*The directory has been read right now, modify the access time */
+ fshelp_touch (&dir->nn_stat, TOUCH_ATIME, maptime);
+
+ /*Return the result of listing the dirents */
+ return err;
+} /*netfs_get_dirents */
+
+/*---------------------------------------------------------------------------*/
/*Looks up `name` under `dir` for `user`*/
error_t
-netfs_attempt_lookup
- (
- struct iouser * user,
- struct node * dir,
- char * name,
- struct node ** node
- )
- {
- LOG_MSG("netfs_attempt_lookup");
-
- /*We should never get here. In any case, we do not want to do this type
- of lookup, netfs_attempt_lookup_improved is what we want*/
- return EOPNOTSUPP;
- }/*netfs_attempt_lookup*/
-/*----------------------------------------------------------------------------*/
-/*Performs an advanced lookup of file `name` under `dir`. If the lookup of the
- last component of the path is requested (`lastcomp` is 1), it is not a
- directory and no translators are required (`name` does not contain ',,'), the
- function will simply open the required file and return the port in `file`. In
- other cases it will create a proxy node and return it in `node`.*/
+ netfs_attempt_lookup
+ (struct iouser * user, struct node * dir, char *name, struct node ** node)
+{
+ LOG_MSG ("netfs_attempt_lookup");
+
+ /*We should never get here. In any case, we do not want to do this type
+ of lookup, netfs_attempt_lookup_improved is what we want */
+ return EOPNOTSUPP;
+} /*netfs_attempt_lookup */
+
+/*---------------------------------------------------------------------------*/
+/*Performs an advanced lookup of file `name` under `dir`. If the
+ lookup of the last component of the path is requested (`lastcomp` is
+ 1), it is not a directory and no translators are required (`name`
+ does not contain ',,' ), the function will simply open the required
+ file and return the port in `file`. In other cases it will create a
+ proxy node and return it in `node`.*/
error_t
-netfs_attempt_lookup_improved
- (
- struct iouser * user,
- struct node * dir,
- char * name,
- int flags,
- int lastcomp,
- node_t ** node,
- file_t * file
- )
+ netfs_attempt_lookup_improved
+ (struct iouser * user,
+ struct node * dir,
+ char *name, int flags, int lastcomp, node_t ** node, file_t * file)
+{
+ LOG_MSG ("netfs_attempt_lookup_improved: '%s'", name);
+
+ error_t err = 0;
+
+ /*If we are asked to fetch the current directory */
+ if (strcmp (name, ".") == 0)
+ {
+ /*validate the stat information for `dir` */
+ err = netfs_validate_stat (dir, user);
+ if (err)
{
- LOG_MSG("netfs_attempt_lookup_improved: '%s'", name);
+ mutex_unlock (&dir->lock);
+ return err;
+ }
- error_t err = 0;
-
- /*If we are asked to fetch the current directory*/
- if(strcmp(name, ".") == 0)
- {
- /*validate the stat information for `dir`*/
- err = netfs_validate_stat(dir, user);
- if(err)
- {
- mutex_unlock(&dir->lock);
- return err;
- }
-
- /*If `dir` is not a directory, actually*/
- if(!S_ISDIR(dir->nn_stat.st_mode))
- {
- /*unlock the directory and stop right here*/
- mutex_unlock(&dir->lock);
- return ENOTDIR;
- }
-
- /*add a reference to `dir` and put it into `node`*/
- netfs_nref(dir);
- *node = dir;
-
- /*everything is OK*/
- return 0;
- }
- /*If we are asked to fetch the parent directory*/
- else if(strcmp(name, "..") == 0)
- {
- /*validate the stat information for `dir`*/
- err = netfs_validate_stat(dir, user);
- if(err)
- {
- mutex_unlock(&dir->lock);
- return err;
- }
-
- /*If `dir` is not a directory, actually*/
- if(!S_ISDIR(dir->nn_stat.st_mode))
- {
- /*unlock the directory and stop right here*/
- mutex_unlock(&dir->lock);
- return ENOTDIR;
- }
-
- /*If the supplied node is not root*/
- if(dir->nn->lnode->dir)
- {
- /*The node corresponding to the parent directory must exist here*/
- assert(dir->nn->lnode->dir->node);
-
- /*put the parent node of `dir` into the result*/
- err = ncache_node_lookup(dir->nn->lnode->dir, node);
- }
- /*The supplied node is root*/
- else
- {
- /*this node is not included into our filesystem*/
- err = ENOENT;
- *node = NULL;
- }
-
- /*unlock the directory*/
- mutex_unlock(&dir->lock);
-
- /*stop here*/
- return err;
- }
+ /*If `dir` is not a directory, actually */
+ if (!S_ISDIR (dir->nn_stat.st_mode))
+ {
+ /*unlock the directory and stop right here */
+ mutex_unlock (&dir->lock);
+ return ENOTDIR;
+ }
- /*The port to the requested file*/
- mach_port_t p;
-
- /*The port to the untranslated version of the requested file*/
- mach_port_t p_notrans;
-
- /*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)
- {
- /*the user should receive nothing*/
- *node = NULL;
-
- /*If there is some port, free it*/
- if(p != MACH_PORT_NULL)
- PORT_DEALLOC(p);
- if(p_notrans != MACH_PORT_NULL)
- PORT_DEALLOC(p_notrans);
- }
- /*If there is a node to return*/
- if(*node)
- {
- /*unlock the node*/
- mutex_unlock(&(*node)->lock);
-
- /*add the node to the cache*/
- ncache_node_add(*node);
- }
-
- /*Unlock the mutexes in `dir`*/
- mutex_unlock(&dir->nn->lnode->lock);
- mutex_unlock(&dir->lock);
- }/*finalize*/
-
- /*Performs a usual lookup*/
- error_t
- lookup
- (
- char * name, /*lookup this*/
- int flags, /*lookup `name` in the this way*/
- int proxy /*should a proxy node be created*/
- )
- {
- /*Try to lookup the given file in the underlying directory*/
- p = file_name_lookup_under(dir->nn->port, name, 0, 0);
-
- /*If the lookup failed*/
- if(p == MACH_PORT_NULL)
- /*no such entry*/
- return ENOENT;
-
- /*Obtain the stat information about the file*/
- io_statbuf_t stat;
- err = io_stat(p, &stat);
-
- /*Deallocate the obtained port*/
- PORT_DEALLOC(p);
-
- /*If this file is not a directory*/
- if(err || !S_ISDIR(stat.st_mode))
- {
- /*lookup the required file with the supplied flags*/
- p = file_name_lookup_under(dir->nn->port, name, flags, 0);
- if(p == MACH_PORT_NULL)
- return EBADF;
-
- /*obtain the untranslated version of the file, too (for filters)*/
- p_notrans = file_name_lookup_under
- (dir->nn->port, name, O_NOTRANS, 0);
- if(p_notrans == MACH_PORT_NULL)
- return EBADF;
-
- /*remember we do not have a directory*/
- isdir = 0;
-
- /*If a proxy node is not required*/
- if(!proxy)
- /*stop here, we want only the port to the file*/
- return 0;
- }
- else
- {
- /*lookup the port with the right to read the contents of the directory*/
- p = file_name_lookup_under
- (dir->nn->port, name, flags | O_READ | O_DIRECTORY, 0);
- if(p == MACH_PORT_NULL)
- return EBADF; /*not enough rights?*/
-
- /*obtain the untranslated version of the file, too (for filters)*/
- p_notrans = file_name_lookup_under
- (dir->nn->port, name, O_NOTRANS, 0);
- if(p_notrans == MACH_PORT_NULL)
- return EBADF;
-
- /*we have a directory here*/
- isdir = 1;
- }
-
- /*Try to find an lnode called `name` under the lnode corresponding to `dir`*/
- err = lnode_get(dir->nn->lnode, name, &lnode);
-
- /*If such an entry does not exist*/
- if(err == ENOENT)
- {
- /*create a new lnode with the supplied name*/
- err = lnode_create(name, &lnode);
- if(err)
- {
- finalize();
- return err;
- }
-
- /*install the new lnode into the directory*/
- lnode_install(dir->nn->lnode, lnode);
- }
-
- /*If we are to create a proxy node*/
- if(proxy)
- /*create a proxy node from the given lnode*/
- err = node_create_proxy(lnode, node);
- /*If we don't need proxy nodes in this lookup*/
- else
- {
- /*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 either the lookup in the cache or the creation of a proxy failed*/
- if(err)
- {
- /*stop*/
- mutex_unlock(&lnode->lock);
- finalize();
- return err;
- }
-
- /*Store the ports in the node*/
- (*node)->nn->port = p;
- (*node)->nn->port_notrans = p_notrans;
-
- /*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)
- {
- mutex_unlock(&lnode->lock);
- finalize();
- return err;
- }
-
- /*Unlock the lnode*/
- mutex_unlock(&lnode->lock);
-
- /*Now the node is up-to-date*/
- (*node)->nn->flags = FLAG_NODE_ULFS_UPTODATE;
-
- /*Everything OK here*/
- return 0;
- }/*lookup*/
-
- /*While pairs of commas can still be found in the name*/
- for(sep = strstr(name, ",,"); sep; sep = strstr(sep, ",,"))
- {
- /*If the separator is situated at the beginning, it is an error*/
- if(sep == name)
- {
- finalize();
- return ENOENT;
- }
-
- /*If current pair of commas is not escaped*/
- if(*(sep + 2) != ',')
- /*stop here, we've found what we needed*/
- break;
-
- /*remove the escaping ',' from the string*/
- for(str = ++sep; *str; str[-1] = *str, ++str);
- str[-1] = 0;
-
- /*skip the current pair of commas*/
- ++sep;
- }
-
- /*If the control sequence has been found*/
- if(sep)
+ /*add a reference to `dir` and put it into `node` */
+ netfs_nref (dir);
+ *node = dir;
+
+ /*everything is OK */
+ return 0;
+ }
+ /*If we are asked to fetch the parent directory */
+ else if (strcmp (name, "..") == 0)
+ {
+ /*validate the stat information for `dir` */
+ err = netfs_validate_stat (dir, user);
+ if (err)
+ {
+ mutex_unlock (&dir->lock);
+ return err;
+ }
+
+ /*If `dir` is not a directory, actually */
+ if (!S_ISDIR (dir->nn_stat.st_mode))
+ {
+ /*unlock the directory and stop right here */
+ mutex_unlock (&dir->lock);
+ return ENOTDIR;
+ }
+
+ /*If the supplied node is not root */
+ if (dir->nn->lnode->dir)
+ {
+ /*The node corresponding to the parent directory must exist here */
+ assert (dir->nn->lnode->dir->node);
+
+ /*put the parent node of `dir` into the result */
+ err = ncache_node_lookup (dir->nn->lnode->dir, node);
+ }
+ /*The supplied node is root */
+ else
+ {
+ /*this node is not included into our filesystem */
+ err = ENOENT;
+ *node = NULL;
+ }
+
+ /*unlock the directory */
+ mutex_unlock (&dir->lock);
+
+ /*stop here */
+ return err;
+ }
+
+ /*The port to the requested file */
+ mach_port_t p;
+
+ /*The port to the untranslated version of the requested file */
+ mach_port_t p_notrans;
+
+ /*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)
+ {
+ /*the user should receive nothing */
+ *node = NULL;
+
+ /*If there is some port, free it */
+ if (p != MACH_PORT_NULL)
+ PORT_DEALLOC (p);
+ if (p_notrans != MACH_PORT_NULL)
+ PORT_DEALLOC (p_notrans);
+ }
+ /*If there is a node to return */
+ if (*node)
+ {
+ /*unlock the node */
+ mutex_unlock (&(*node)->lock);
+
+ /*add the node to the cache */
+ ncache_node_add (*node);
+ }
+
+ /*Unlock the mutexes in `dir` */
+ mutex_unlock (&dir->nn->lnode->lock);
+ mutex_unlock (&dir->lock);
+ } /*finalize */
+
+ /*Performs a usual lookup */
+ error_t lookup (char *name, /*lookup this */
+ int flags, /*lookup `name` in the this way */
+ int proxy /*should a proxy node be created */
+ )
+ {
+ /*Try to lookup the given file in the underlying directory */
+ p = file_name_lookup_under (dir->nn->port, name, 0, 0);
+
+ /*If the lookup failed */
+ if (p == MACH_PORT_NULL)
+ /*no such entry */
+ return ENOENT;
+
+ /*Obtain the stat information about the file */
+ io_statbuf_t stat;
+ err = io_stat (p, &stat);
+
+ /*Deallocate the obtained port */
+ PORT_DEALLOC (p);
+
+ /*If this file is not a directory */
+ if (err || !S_ISDIR (stat.st_mode))
+ {
+ /*lookup the required file with the supplied flags */
+ p = file_name_lookup_under (dir->nn->port, name, flags, 0);
+ if (p == MACH_PORT_NULL)
+ return EBADF;
+
+ /*obtain the untranslated version of the file, too (for filters) */
+ p_notrans = file_name_lookup_under
+ (dir->nn->port, name, O_NOTRANS, 0);
+ if (p_notrans == MACH_PORT_NULL)
+ return EBADF;
+
+ /*remember we do not have a directory */
+ isdir = 0;
+
+ /*If a proxy node is not required */
+ if (!proxy)
+ /*stop here, we want only the port to the file */
+ return 0;
+ }
+ else
+ {
+ /*lookup the port with the right to read the contents of the
+ directory */
+ p = file_name_lookup_under
+ (dir->nn->port, name, flags | O_READ | O_DIRECTORY, 0);
+ if (p == MACH_PORT_NULL)
+ return EBADF; /*not enough rights? */
+
+ /*obtain the untranslated version of the file, too (for filters) */
+ p_notrans = file_name_lookup_under
+ (dir->nn->port, name, O_NOTRANS, 0);
+ if (p_notrans == MACH_PORT_NULL)
+ return EBADF;
+
+ /*we have a directory here */
+ isdir = 1;
+ }
+
+ /*Try to find an lnode called `name` under the lnode corresponding
+ to `dir` */
+ err = lnode_get (dir->nn->lnode, name, &lnode);
+
+ /*If such an entry does not exist */
+ if (err == ENOENT)
+ {
+ /*create a new lnode with the supplied name */
+ err = lnode_create (name, &lnode);
+ if (err)
+ {
+ finalize ();
+ return err;
+ }
+
+ /*install the new lnode into the directory */
+ lnode_install (dir->nn->lnode, lnode);
+ }
+
+ /*If we are to create a proxy node */
+ if (proxy)
+ /*create a proxy node from the given lnode */
+ err = node_create_proxy (lnode, node);
+ /*If we don't need proxy nodes in this lookup */
+ else
+ {
+ /*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 either the lookup in the cache or the creation of a proxy failed */
+ if (err)
+ {
+ /*stop */
+ mutex_unlock (&lnode->lock);
+ finalize ();
+ return err;
+ }
+
+ /*Store the ports in the node */
+ (*node)->nn->port = p;
+ (*node)->nn->port_notrans = p_notrans;
+
+ /*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)
+ {
+ mutex_unlock (&lnode->lock);
+ finalize ();
+ return err;
+ }
+
+ /*Unlock the lnode */
+ mutex_unlock (&lnode->lock);
+
+ /*Now the node is up-to-date */
+ (*node)->nn->flags = FLAG_NODE_ULFS_UPTODATE;
+
+ /*Everything OK here */
+ return 0;
+ } /*lookup */
+
+ /*While pairs of commas can still be found in the name */
+ for (sep = strstr (name, ",,"); sep; sep = strstr (sep, ",,"))
+ {
+ /*If the separator is situated at the beginning, it is an error */
+ if (sep == name)
+ {
+ finalize ();
+ return ENOENT;
+ }
+
+ /*If current pair of commas is not escaped */
+ if (*(sep + 2) != ',')
+ /*stop here, we've found what we needed */
+ break;
+
+ /*remove the escaping ',' from the string */
+ for (str = ++sep; *str; str[-1] = *str, ++str);
+ str[-1] = 0;
+
+ /*skip the current pair of commas */
+ ++sep;
+ }
+
+ /*If the control sequence has been found */
+ if (sep)
+ {
+ /*the name of the file to lookup */
+ char *name_cpy;
+
+ /*copy the name */
+ /*just copy the pointer */
+ name_cpy = /*strdup */ (name);
+ if (!name_cpy)
+ {
+ err = ENOMEM;
+ finalize ();
+ return err;
+ }
+
+ /*move sep to name_cpy */
+ sep = name_cpy + (sep - name);
+
+ /*remove the separator from the string */
+ *(sep++) = 0;
+ *(sep++) = 0;
+
+ /*try to lookup the file with the specified name and create a proxy
+ node for it (since we need to start translators) */
+ err = lookup (name_cpy, flags, 1);
+
+ /*If the lookup failed */
+ if (err)
+ {
+ /*say that the file has not been found */
+ finalize ();
+ return ENOENT;
+ }
+
+ /*duplicate the part of the name containing the list of translators
+ and store the copy in the lnode */
+ trans = strdup (sep);
+ if (!trans)
+ {
+ finalize ();
+ return err;
+ }
+
+ /*obtain a pointer to the beginning of the list of translators */
+ str = trans;
+
+ /*a pointer for removal of extra commas */
+ char *p;
+
+ /*Go through the list of translators */
+ for (translen = ntrans = 0; *str; ++str)
+ {
+ /*If the current character is a comma */
+ if (*str == ',')
+ {
+ /*While the next characters are commas, too */
+ for (; str[1] == ',';)
{
- /*the name of the file to lookup*/
- char * name_cpy;
-
- /*copy the name*/
- /*just copy the pointer*/
- name_cpy = /*strdup*/(name);
- if(!name_cpy)
- {
- err = ENOMEM;
- finalize();
- return err;
- }
-
- /*move sep to name_cpy*/
- sep = name_cpy + (sep - name);
-
- /*remove the separator from the string*/
- *(sep++) = 0;
- *(sep++) = 0;
-
- /*try to lookup the file with the specified name and create a proxy
- node for it (since we need to start translators)*/
- err = lookup(name_cpy, flags, 1);
-
- /*If the lookup failed*/
- if(err)
- {
- /*say that the file has not been found*/
- finalize();
- return ENOENT;
- }
-
- /*duplicate the part of the name containing the list of translators
- and store the copy in the lnode*/
- trans = strdup(sep);
- if(!trans)
- {
- finalize();
- return err;
- }
-
- /*obtain a pointer to the beginning of the list of translators*/
- str = trans;
-
- /*a pointer for removal of extra commas*/
- char * p;
-
- /*Go through the list of translators*/
- for(translen = ntrans = 0; *str; ++str)
- {
- /*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*/
- ++ntrans;
- }
-
- /*take the current character into account*/
- ++translen;
- }
-
- /*take into consideration the last element in the list,
- which does not end in a comma and the corresponding terminal 0*/
- ++ntrans;
- ++translen;
-
- /*copy the list of translators we have just built in the new proxy node*/
- (*node)->nn->trans = trans;
- (*node)->nn->ntrans = ntrans;
- (*node)->nn->translen = translen;
-
- /*we don't own the list of translators any more*/
- trans = NULL;
- ntrans = 0;
- translen = 0;
+ /*shift the string leftwards */
+ for (p = str + 1; *p; p[-1] = *p, ++p);
+ p[-1] = 0;
}
- /*The control sequence ',,' has not been found*/
- else
+
+ /*If the next character is the terminal 0 */
+ if (!str[1])
{
- /*simply lookup the provided name, without creating the proxy, if not
- necessary (i.e. when the file is not a directory)*/
- err = lookup(name, flags, 0);
- if(err)
- {
- finalize();
- return err;
- }
-
- /*if we have looked up a regular file, store the port to it in *`file`*/
- if(!isdir)
- *file = p;
+ /*this comma is extra */
+ *str = 0;
+ break;
}
-
- /*Everything OK here*/
- finalize();
- return err;
- }/*netfs_attempt_lookup_improved*/
-/*----------------------------------------------------------------------------*/
+
+ /*make it a separator zero */
+ *str = 0;
+
+ /*we have just finished going through a new component */
+ ++ntrans;
+ }
+
+ /*take the current character into account */
+ ++translen;
+ }
+
+ /*take into consideration the last element in the list,
+ which does not end in a comma and the corresponding terminal 0 */
+ ++ntrans;
+ ++translen;
+
+ /*copy the list of translators we have just built in the new
+ proxy node */
+ (*node)->nn->trans = trans;
+ (*node)->nn->ntrans = ntrans;
+ (*node)->nn->translen = translen;
+
+ /*we don't own the list of translators any more */
+ trans = NULL;
+ ntrans = 0;
+ translen = 0;
+ }
+ /*The control sequence ',,' has not been found */
+ else
+ {
+ /*simply lookup the provided name, without creating the proxy, if not
+ necessary (i.e. when the file is not a directory) */
+ err = lookup (name, flags, 0);
+ if (err)
+ {
+ finalize ();
+ return err;
+ }
+
+ /*if we have looked up a regular file, store the port to it in *`file` */
+ if (!isdir)
+ *file = p;
+ }
+
+ /*Everything OK here */
+ finalize ();
+ return err;
+} /*netfs_attempt_lookup_improved */
+
+/*---------------------------------------------------------------------------*/
/*Responds to the RPC dir_lookup*/
error_t
-netfs_S_dir_lookup
- (
- struct protid * diruser,
- char * filename,
- int flags,
- mode_t mode,
- retry_type * do_retry,
- char * retry_name,
- mach_port_t * retry_port,
- mach_msg_type_number_t * retry_port_type
- )
- {
- LOG_MSG("netfs_S_dir_lookup: '%s'", filename);
+ netfs_S_dir_lookup
+ (struct protid * diruser,
+ char *filename,
+ int flags,
+ mode_t mode,
+ retry_type * do_retry,
+ char *retry_name,
+ mach_port_t * retry_port, mach_msg_type_number_t * retry_port_type)
+{
+ LOG_MSG ("netfs_S_dir_lookup: '%s'", filename);
int create; /* true if O_CREAT flag set */
int excl; /* true if O_EXCL flag set */
@@ -967,15 +911,15 @@ netfs_S_dir_lookup
struct protid *newpi;
struct iouser *user;
- /*The port to the file for the case when we don't need proxy nodes*/
- file_t file = MACH_PORT_NULL;
-
- /*The port to the same file with restricted rights*/
- file_t file_restricted = MACH_PORT_NULL;
+ /*The port to the file for the case when we don't need proxy nodes */
+ file_t file = MACH_PORT_NULL;
- /*The stat information about the node pointed at by `file` (for the case
- when not proxy nodes are to be created)*/
- io_statbuf_t stat;
+ /*The port to the same file with restricted rights */
+ file_t file_restricted = MACH_PORT_NULL;
+
+ /*The stat information about the node pointed at by `file` (for the case
+ when not proxy nodes are to be created) */
+ io_statbuf_t stat;
if (!diruser)
return EOPNOTSUPP;
@@ -1044,7 +988,7 @@ netfs_S_dir_lookup
*do_retry = FS_RETRY_REAUTH;
*retry_port = diruser->po->shadow_root_parent;
*retry_port_type = MACH_MSG_TYPE_COPY_SEND;
- if (! lastcomp)
+ if (!lastcomp)
strcpy (retry_name, nextname);
error = 0;
mutex_unlock (&dnp->lock);
@@ -1072,38 +1016,40 @@ netfs_S_dir_lookup
netfs_nref (np);
}
else
+ {
+ /* Attempt a lookup on the next pathname component. */
+ /*error = netfs_attempt_lookup (diruser->user, dnp, filename, &np); */
+
+ /*attempt an improved lookup on the next pathname component */
+ error = netfs_attempt_lookup_improved
+ (diruser->user, dnp, filename, flags, lastcomp, &np, &file);
+
+ /*If no problems have occurred during the lookup and we do
+ not have O_EXCL */
+ if (!error && !excl)
+ {
+ /*If a simple file has been looked up */
+ if (file)
+ /*just return the port */
+ goto justport;
+
+ /*If a proxy for setting up translators has just been created */
+ if (np->nn->trans)
{
- /* Attempt a lookup on the next pathname component. */
- /*error = netfs_attempt_lookup (diruser->user, dnp, filename, &np);*/
-
- /*attempt an improved lookup on the next pathname component*/
- error = netfs_attempt_lookup_improved
- (diruser->user, dnp, filename, flags, lastcomp, &np, &file);
-
- /*If no problems have occurred during the lookup and we do not have O_EXCL*/
- if(!error && !excl)
- {
- /*If a simple file has been looked up*/
- if(file)
- /*just return the port*/
- goto justport;
-
- /*If a proxy for setting up translators has just been created*/
- if(np->nn->trans)
- {
- /*set the list of translators on this node*/
- node_set_translators
- (diruser, np, np->nn->trans, np->nn->ntrans, flags, &file);
-
- /*lock the the node and add a new reference*/
- mutex_lock(&np->lock);
- netfs_nref(np);
-
- /*return `file` as the resulting port*/
- goto justport;
- }
- }
+ /*set the list of translators on this node */
+ node_set_translators
+ (diruser, np, np->nn->trans, np->nn->ntrans, flags,
+ &file);
+
+ /*lock the the node and add a new reference */
+ mutex_lock (&np->lock);
+ netfs_nref (np);
+
+ /*return `file` as the resulting port */
+ goto justport;
}
+ }
+ }
/* At this point, DNP is unlocked */
@@ -1152,61 +1098,61 @@ netfs_S_dir_lookup
/* A callback function for short-circuited translators.
S_ISLNK and S_IFSOCK are handled elsewhere. */
error_t short_circuited_callback1 (void *cookie1, void *cookie2,
- uid_t *uid, gid_t *gid,
- char **argz, size_t *argz_len)
- {
- struct node *np = cookie1;
- error_t err;
-
- err = netfs_validate_stat (np, diruser->user);
- if (err)
- return err;
-
- switch (np->nn_translated & S_IFMT)
- {
- case S_IFCHR:
- case S_IFBLK:
- if (asprintf (argz, "%s%c%d%c%d",
- (S_ISCHR (np->nn_translated)
- ? _HURD_CHRDEV : _HURD_BLKDEV),
- 0, major (np->nn_stat.st_rdev),
- 0, minor (np->nn_stat.st_rdev)) < 0)
- return ENOMEM;
- *argz_len = strlen (*argz) + 1;
- *argz_len += strlen (*argz + *argz_len) + 1;
- *argz_len += strlen (*argz + *argz_len) + 1;
- break;
- case S_IFIFO:
- if (asprintf (argz, "%s", _HURD_FIFO) < 0)
- return ENOMEM;
- *argz_len = strlen (*argz) + 1;
- break;
- default:
- return ENOENT;
- }
-
- *uid = np->nn_stat.st_uid;
- *gid = np->nn_stat.st_gid;
-
- return 0;
- }
+ uid_t * uid, gid_t * gid,
+ char **argz, size_t * argz_len)
+ {
+ struct node *np = cookie1;
+ error_t err;
+
+ err = netfs_validate_stat (np, diruser->user);
+ if (err)
+ return err;
+
+ switch (np->nn_translated & S_IFMT)
+ {
+ case S_IFCHR:
+ case S_IFBLK:
+ if (asprintf (argz, "%s%c%d%c%d",
+ (S_ISCHR (np->nn_translated)
+ ? _HURD_CHRDEV : _HURD_BLKDEV),
+ 0, major (np->nn_stat.st_rdev),
+ 0, minor (np->nn_stat.st_rdev)) < 0)
+ return ENOMEM;
+ *argz_len = strlen (*argz) + 1;
+ *argz_len += strlen (*argz + *argz_len) + 1;
+ *argz_len += strlen (*argz + *argz_len) + 1;
+ break;
+ case S_IFIFO:
+ if (asprintf (argz, "%s", _HURD_FIFO) < 0)
+ return ENOMEM;
+ *argz_len = strlen (*argz) + 1;
+ break;
+ default:
+ return ENOENT;
+ }
+
+ *uid = np->nn_stat.st_uid;
+ *gid = np->nn_stat.st_gid;
+
+ return 0;
+ }
/* Create an unauthenticated port for DNP, and then
unlock it. */
error = iohelp_create_empty_iouser (&user);
- if (! error)
+ if (!error)
{
newpi = netfs_make_protid (netfs_make_peropen (dnp, 0,
diruser->po),
user);
- if (! newpi)
- {
+ if (!newpi)
+ {
error = errno;
iohelp_free_iouser (user);
}
}
- if (! error)
+ if (!error)
{
dirport = ports_get_send_right (newpi);
ports_port_deref (newpi);
@@ -1216,12 +1162,12 @@ netfs_S_dir_lookup
diruser->user,
lastcomp ? flags : 0,
((np->nn_translated & S_IPTRANS)
- ? _netfs_translator_callback1
- : short_circuited_callback1),
+ ? _netfs_translator_callback1
+ : short_circuited_callback1),
_netfs_translator_callback2,
do_retry, retry_name, retry_port);
/* fetch_root copies DIRPORT for success, so we always should
- deallocate our send right. */
+ deallocate our send right. */
mach_port_deallocate (mach_task_self (), dirport);
}
@@ -1238,15 +1184,16 @@ netfs_S_dir_lookup
return error;
}
- /* ENOENT means there was a hiccup, and the translator vanished
- while NP was unlocked inside fshelp_fetch_root; continue as normal. */
+ /* ENOENT means there was a hiccup, and the translator
+ vanished while NP was unlocked inside fshelp_fetch_root;
+ continue as normal. */
error = 0;
}
- if (S_ISLNK (np->nn_translated)
- && (!lastcomp
- || mustbedir /* "foo/" must see that foo points to a dir */
- || !(flags & (O_NOLINK|O_NOTRANS))))
+ /* "foo/" must see that foo points to a dir */
+ if (S_ISLNK (np->nn_translated) && (!lastcomp || mustbedir
+ || !(flags &
+ (O_NOLINK | O_NOTRANS))))
{
size_t nextnamelen, newnamelen, linklen;
char *linkbuf;
@@ -1271,8 +1218,7 @@ netfs_S_dir_lookup
if (nextname)
{
linkbuf[linklen] = '/';
- memcpy (linkbuf + linklen + 1, nextname,
- nextnamelen - 1);
+ memcpy (linkbuf + linklen + 1, nextname, nextnamelen - 1);
}
linkbuf[nextnamelen + linklen] = '\0';
@@ -1291,7 +1237,7 @@ netfs_S_dir_lookup
lastcomp = 0;
/* Symlinks to nonexistent files aren't allowed to cause
- creation, so clear the flag here. */
+ creation, so clear the flag here. */
create = 0;
}
netfs_nput (np);
@@ -1316,7 +1262,7 @@ netfs_S_dir_lookup
while (filename && *filename);
/* At this point, NP is the node to return. */
- gotit:
+gotit:
if (mustbedir)
{
@@ -1327,8 +1273,7 @@ netfs_S_dir_lookup
goto out;
}
}
- error = netfs_check_open_permissions (diruser->user, np,
- flags, newnode);
+ error = netfs_check_open_permissions (diruser->user, np, flags, newnode);
if (error)
goto out;
@@ -1340,7 +1285,7 @@ netfs_S_dir_lookup
newpi = netfs_make_protid (netfs_make_peropen (np, flags, diruser->po),
user);
- if (! newpi)
+ if (!newpi)
{
iohelp_free_iouser (user);
error = errno;
@@ -1350,553 +1295,472 @@ netfs_S_dir_lookup
*retry_port = ports_get_right (newpi);
ports_port_deref (newpi);
+ goto out;
+
+ /*At this point, we have to return `file` as the resulting port */
+justport:
+ /*If a directory is definitely wanted */
+ if (mustbedir)
+ {
+ /*stat the looked up file */
+ error = io_stat (file, &stat);
+ if (error)
goto out;
- /*At this point, we have to return `file` as the resulting port*/
- justport:
- /*If a directory is definitely wanted*/
- if(mustbedir)
- {
- /*stat the looked up file*/
- error = io_stat(file, &stat);
- if(error)
- goto out;
-
- /*If the file is not a directory*/
- if(!S_ISDIR(stat.st_mode))
- {
- /*this is an error; stop here*/
- error = ENOTDIR;
- goto out;
- }
-
- }
-
- /*Check the user's open permissions for the specified port*/
- error = check_open_permissions(diruser->user, &stat, file);
- if(error)
- goto out;
-
- /*Restrict the port to the rights of the user*/
- error = io_restrict_auth
- (
- file, &file_restricted,
- diruser->user->uids->ids, diruser->user->uids->num,
- diruser->user->gids->ids, diruser->user->gids->num
- );
- if(error)
- goto out;
-
- /*Put the resulting port in the corresponding receiver parameter*/
- *retry_port = file_restricted;
- *retry_port_type = MACH_MSG_TYPE_MOVE_SEND;
-
- out:
- if(error && (file != MACH_PORT_NULL))
- PORT_DEALLOC(file);
+ /*If the file is not a directory */
+ if (!S_ISDIR (stat.st_mode))
+ {
+ /*this is an error; stop here */
+ error = ENOTDIR;
+ goto out;
+ }
+
+ }
+
+ /*Check the user's open permissions for the specified port */
+ error = check_open_permissions (diruser->user, &stat, file);
+ if (error)
+ goto out;
+
+ /*Restrict the port to the rights of the user */
+ error = io_restrict_auth
+ (file, &file_restricted,
+ diruser->user->uids->ids, diruser->user->uids->num,
+ diruser->user->gids->ids, diruser->user->gids->num);
+ if (error)
+ goto out;
+
+ /*Put the resulting port in the corresponding receiver parameter */
+ *retry_port = file_restricted;
+ *retry_port_type = MACH_MSG_TYPE_MOVE_SEND;
+
+out:
+ if (error && (file != MACH_PORT_NULL))
+ PORT_DEALLOC (file);
if (np)
netfs_nput (np);
if (dnp)
netfs_nrele (dnp);
return error;
- }/*netfs_S_dir_lookup*/
-/*----------------------------------------------------------------------------*/
+} /*netfs_S_dir_lookup */
+
+/*---------------------------------------------------------------------------*/
/*Deletes `name` in `dir` for `user`*/
error_t
-netfs_attempt_unlink
- (
- struct iouser * user,
- struct node * dir,
- char * name
- )
- {
- LOG_MSG("netfs_attempt_unlink");
+ netfs_attempt_unlink (struct iouser * user, struct node * dir, char *name)
+{
+ LOG_MSG ("netfs_attempt_unlink");
- return 0;
- }/*netfs_attempt_unlink*/
-/*----------------------------------------------------------------------------*/
+ return 0;
+} /*netfs_attempt_unlink */
+
+/*---------------------------------------------------------------------------*/
/*Attempts to rename `fromdir`/`fromname` to `todir`/`toname`*/
error_t
-netfs_attempt_rename
- (
- struct iouser * user,
- struct node * fromdir,
- char * fromname,
- struct node * todir,
- char * toname,
- int excl
- )
- {
- LOG_MSG("netfs_attempt_rename");
-
- /*Operation not supported*/
- return EOPNOTSUPP;
- }/*netfs_attempt_rename*/
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_rename
+ (struct iouser * user,
+ struct node * fromdir,
+ char *fromname, struct node * todir, char *toname, int excl)
+{
+ LOG_MSG ("netfs_attempt_rename");
+
+ /*Operation not supported */
+ return EOPNOTSUPP;
+} /*netfs_attempt_rename */
+
+/*---------------------------------------------------------------------------*/
/*Attempts to create a new directory*/
error_t
-netfs_attempt_mkdir
- (
- struct iouser * user,
- struct node * dir,
- char * name,
- mode_t mode
- )
- {
- LOG_MSG("netfs_attempt_mkdir");
+ netfs_attempt_mkdir
+ (struct iouser * user, struct node * dir, char *name, mode_t mode)
+{
+ LOG_MSG ("netfs_attempt_mkdir");
- return 0;
- }/*netfs_attempt_mkdir*/
-/*----------------------------------------------------------------------------*/
+ return 0;
+} /*netfs_attempt_mkdir */
+
+/*---------------------------------------------------------------------------*/
/*Attempts to remove directory `name` in `dir` for `user`*/
error_t
-netfs_attempt_rmdir
- (
- struct iouser * user,
- struct node * dir,
- char * name
- )
- {
- LOG_MSG("netfs_attempt_rmdir");
+ netfs_attempt_rmdir (struct iouser * user, struct node * dir, char *name)
+{
+ LOG_MSG ("netfs_attempt_rmdir");
- return 0;
- }/*netfs_attempt_rmdir*/
-/*----------------------------------------------------------------------------*/
+ return 0;
+} /*netfs_attempt_rmdir */
+
+/*---------------------------------------------------------------------------*/
/*Attempts to change the mode of `node` for user `cred` to `uid`:`gid`*/
error_t
-netfs_attempt_chown
- (
- struct iouser * cred,
- struct node * node,
- uid_t uid,
- uid_t gid
- )
- {
- LOG_MSG("netfs_attempt_chown");
+ netfs_attempt_chown
+ (struct iouser * cred, struct node * node, uid_t uid, uid_t gid)
+{
+ LOG_MSG ("netfs_attempt_chown");
+
+ /*Operation is not supported */
+ return EOPNOTSUPP;
+} /*netfs_attempt_chown */
- /*Operation is not supported*/
- return EOPNOTSUPP;
- }/*netfs_attempt_chown*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Attempts to change the author of `node` to `author`*/
error_t
-netfs_attempt_chauthor
- (
- struct iouser * cred,
- struct node * node,
- uid_t author
- )
- {
- LOG_MSG("netfs_attempt_chauthor");
+ netfs_attempt_chauthor
+ (struct iouser * cred, struct node * node, uid_t author)
+{
+ LOG_MSG ("netfs_attempt_chauthor");
- /*Operation is not supported*/
- return EOPNOTSUPP;
- }/*netfs_attempt_chauthor*/
-/*----------------------------------------------------------------------------*/
+ /*Operation is not supported */
+ return EOPNOTSUPP;
+} /*netfs_attempt_chauthor */
+
+/*---------------------------------------------------------------------------*/
/*Attempts to change the mode of `node` to `mode` for `cred`*/
error_t
-netfs_attempt_chmod
- (
- struct iouser * user,
- struct node * node,
- mode_t mode
- )
- {
- LOG_MSG("netfs_attempt_chmod");
+ netfs_attempt_chmod (struct iouser * user, struct node * node, mode_t mode)
+{
+ LOG_MSG ("netfs_attempt_chmod");
- /*Operation is not supported*/
- return EOPNOTSUPP;
- }/*netfs_attempt_chmod*/
-/*----------------------------------------------------------------------------*/
+ /*Operation is not supported */
+ return EOPNOTSUPP;
+} /*netfs_attempt_chmod */
+
+/*---------------------------------------------------------------------------*/
/*Attempts to turn `node` into a symlink targetting `name`*/
error_t
-netfs_attempt_mksymlink
- (
- struct iouser * cred,
- struct node * node,
- char * name
- )
- {
- LOG_MSG("netfs_attempt_mksymlink");
-
- /*Operation is not supported*/
- return EOPNOTSUPP;
- }/*netfs_attempt_mksymlink*/
-/*----------------------------------------------------------------------------*/
-/*Attempts to turn `node` into a device; type can be either S_IFBLK or S_IFCHR*/
+ netfs_attempt_mksymlink
+ (struct iouser * cred, struct node * node, char *name)
+{
+ LOG_MSG ("netfs_attempt_mksymlink");
+
+ /*Operation is not supported */
+ return EOPNOTSUPP;
+} /*netfs_attempt_mksymlink */
+
+/*---------------------------------------------------------------------------*/
+/*Attempts to turn `node` into a device; type can be either S_IFBLK or
+ S_IFCHR*/
error_t
-netfs_attempt_mkdev
- (
- struct iouser * cred,
- struct node * node,
- mode_t type,
- dev_t indexes
- )
- {
- LOG_MSG("netfs_attempt_mkdev");
+ netfs_attempt_mkdev
+ (struct iouser * cred, struct node * node, mode_t type, dev_t indexes)
+{
+ LOG_MSG ("netfs_attempt_mkdev");
- /*Operation is not supported*/
- return EOPNOTSUPP;
- }/*netfs_attempt_mkdev*/
-/*----------------------------------------------------------------------------*/
+ /*Operation is not supported */
+ return EOPNOTSUPP;
+} /*netfs_attempt_mkdev */
+
+/*---------------------------------------------------------------------------*/
/*Attempts to set the passive translator record for `file` passing `argz`*/
error_t
-netfs_set_translator
- (
- struct iouser * cred,
- struct node * node,
- char * argz,
- size_t arglen
- )
- {
- LOG_MSG("netfs_set_translator");
+ netfs_set_translator
+ (struct iouser * cred, struct node * node, char *argz, size_t arglen)
+{
+ LOG_MSG ("netfs_set_translator");
+
+ /*Operation is not supported */
+ return EOPNOTSUPP;
+} /*netfs_set_translator */
- /*Operation is not supported*/
- return EOPNOTSUPP;
- }/*netfs_set_translator */
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Attempts to call chflags for `node`*/
error_t
-netfs_attempt_chflags
- (
- struct iouser * cred,
- struct node * node,
- int flags
- )
- {
- LOG_MSG("netfs_attempt_chflags");
+ netfs_attempt_chflags (struct iouser * cred, struct node * node, int flags)
+{
+ LOG_MSG ("netfs_attempt_chflags");
+
+ /*Operation is not supported */
+ return EOPNOTSUPP;
+} /*netfs_attempt_chflags */
- /*Operation is not supported*/
- return EOPNOTSUPP;
- }/*netfs_attempt_chflags*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Attempts to set the size of file `node`*/
error_t
-netfs_attempt_set_size
- (
- struct iouser * cred,
- struct node * node,
- loff_t size
- )
- {
- LOG_MSG("netfs_attempt_set_size");
+ netfs_attempt_set_size
+ (struct iouser * cred, struct node * node, loff_t size)
+{
+ LOG_MSG ("netfs_attempt_set_size");
+
+ /*Operation is not supported */
+ return EOPNOTSUPP;
+} /*netfs_attempt_set_size */
- /*Operation is not supported*/
- return EOPNOTSUPP;
- }/*netfs_attempt_set_size*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Fetches the filesystem status information*/
error_t
-netfs_attempt_statfs
- (
- struct iouser * cred,
- struct node * node,
- fsys_statfsbuf_t * st
- )
- {
- LOG_MSG("netfs_attempt_statfs");
+ netfs_attempt_statfs
+ (struct iouser * cred, struct node * node, fsys_statfsbuf_t * st)
+{
+ LOG_MSG ("netfs_attempt_statfs");
+
+ /*Operation is not supported */
+ return EOPNOTSUPP;
+} /*netfs_attempt_statfs */
- /*Operation is not supported*/
- return EOPNOTSUPP;
- }/*netfs_attempt_statfs*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Syncs the filesystem*/
-error_t
-netfs_attempt_syncfs
- (
- struct iouser * cred,
- int wait
- )
- {
- LOG_MSG("netfs_attempt_syncfs");
+error_t netfs_attempt_syncfs (struct iouser * cred, int wait)
+{
+ LOG_MSG ("netfs_attempt_syncfs");
- /*Everythin OK*/
- return 0;
- }/*netfs_attempt_syncfs*/
-/*----------------------------------------------------------------------------*/
+ /*Everythin OK */
+ return 0;
+} /*netfs_attempt_syncfs */
+
+/*---------------------------------------------------------------------------*/
/*Creates a link in `dir` with `name` to `file`*/
error_t
-netfs_attempt_link
- (
- struct iouser * user,
- struct node * dir,
- struct node * file,
- char * name,
- int excl
- )
- {
- LOG_MSG("netfs_attempt_link");
+ netfs_attempt_link
+ (struct iouser * user,
+ struct node * dir, struct node * file, char *name, int excl)
+{
+ LOG_MSG ("netfs_attempt_link");
- /*Operation not supported*/
- return EOPNOTSUPP;
- }/*netfs_attempt_link*/
-/*----------------------------------------------------------------------------*/
+ /*Operation not supported */
+ return EOPNOTSUPP;
+} /*netfs_attempt_link */
+
+/*---------------------------------------------------------------------------*/
/*Attempts to create an anonymous file related to `dir` with `mode`*/
error_t
-netfs_attempt_mkfile
- (
- struct iouser * user,
- struct node * dir,
- mode_t mode,
- struct node ** node
- )
- {
- LOG_MSG("netfs_attempt_mkfile");
+ netfs_attempt_mkfile
+ (struct iouser * user, struct node * dir, mode_t mode, struct node ** node)
+{
+ LOG_MSG ("netfs_attempt_mkfile");
- /*Unlock the directory*/
- mutex_unlock(&dir->lock);
+ /*Unlock the directory */
+ mutex_unlock (&dir->lock);
- /*Operation not supported*/
- return EOPNOTSUPP;
- }/*netfs_attempt_mkfile*/
-/*----------------------------------------------------------------------------*/
+ /*Operation not supported */
+ return EOPNOTSUPP;
+} /*netfs_attempt_mkfile */
+
+/*---------------------------------------------------------------------------*/
/*Reads the contents of symlink `node` into `buf`*/
error_t
-netfs_attempt_readlink
- (
- struct iouser * user,
- struct node * node,
- char * buf
- )
- {
- LOG_MSG("netfs_attempt_readlink");
+ netfs_attempt_readlink (struct iouser * user, struct node * node, char *buf)
+{
+ LOG_MSG ("netfs_attempt_readlink");
- /*Operation not supported (why?..)*/
- return EOPNOTSUPP;
- }/*netfs_attempt_readlink*/
-/*----------------------------------------------------------------------------*/
+ /*Operation not supported (why?..) */
+ return EOPNOTSUPP;
+} /*netfs_attempt_readlink */
+
+/*---------------------------------------------------------------------------*/
/*Reads from file `node` up to `len` bytes from `offset` into `data`*/
error_t
-netfs_attempt_read
- (
- struct iouser * cred,
- struct node * np,
- loff_t offset,
- size_t * len,
- void * data
- )
- {
- LOG_MSG("netfs_attempt_read");
-
- error_t err = 0;
-
- /*Obtain a pointer to the first byte of the supplied buffer*/
- char * buf = data;
-
- /*Try to read the requested information from the file*/
- err = io_read(np->nn->port, &buf, len, offset, *len);
-
- /*If some data has been read successfully*/
- if(!err && (buf != data))
- {
- /*copy the data from the buffer into which is has been read into the
- supplied receiver*/
- memcpy(data, buf, *len);
-
- /*unmap the new buffer*/
- munmap(buf, *len);
- }
+ netfs_attempt_read
+ (struct iouser * cred,
+ struct node * np, loff_t offset, size_t * len, void *data)
+{
+ LOG_MSG ("netfs_attempt_read");
- /*Return the result of reading*/
- return err;
- }/*netfs_attempt_read*/
-/*----------------------------------------------------------------------------*/
+ error_t err = 0;
+
+ /*Obtain a pointer to the first byte of the supplied buffer */
+ char *buf = data;
+
+ /*Try to read the requested information from the file */
+ err = io_read (np->nn->port, &buf, len, offset, *len);
+
+ /*If some data has been read successfully */
+ if (!err && (buf != data))
+ {
+ /*copy the data from the buffer into which is has been read into the
+ supplied receiver */
+ memcpy (data, buf, *len);
+
+ /*unmap the new buffer */
+ munmap (buf, *len);
+ }
+
+ /*Return the result of reading */
+ return err;
+} /*netfs_attempt_read */
+
+/*---------------------------------------------------------------------------*/
/*Writes to file `node` up to `len` bytes from offset from `data`*/
error_t
-netfs_attempt_write
- (
- struct iouser * cred,
- struct node * node,
- loff_t offset,
- size_t * len,
- void * data
- )
- {
- /*Write the supplied data into the file and return the result*/
- return io_write(node->nn->port, data, *len, offset, len);
- }/*netfs_attempt_write*/
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_write
+ (struct iouser * cred,
+ struct node * node, loff_t offset, size_t * len, void *data)
+{
+ /*Write the supplied data into the file and return the result */
+ return io_write (node->nn->port, data, *len, offset, len);
+} /*netfs_attempt_write */
+
+/*---------------------------------------------------------------------------*/
/*Frees all storage associated with the node*/
-void
-netfs_node_norefs
- (
- struct node * np
- )
- {
- /*Destroy the node*/
- node_destroy(np);
- }/*netfs_node_norefs*/
-/*----------------------------------------------------------------------------*/
+void netfs_node_norefs (struct node *np)
+{
+ /*Destroy the node */
+ node_destroy (np);
+} /*netfs_node_norefs */
+
+/*---------------------------------------------------------------------------*/
/*Implements file_get_translator_cntl as described in <hurd/fs.defs>
- (according to diskfs_S_file_get_translator_cntl)*/
+ (according to diskfs_S_file_get_translator_cntl)*/
kern_return_t
-netfs_S_file_get_translator_cntl
- (
- struct protid * user,
- mach_port_t * cntl,
- mach_msg_type_name_t * cntltype
- )
- {
- /*If the information about the user is missing*/
- if(!user)
- return EOPNOTSUPP;
-
- error_t err = 0;
-
- /*Obtain the node for which we are called*/
- node_t * np = user->po->np;
-
- /*If the node is not the root node of nsmux*/
- if(np != netfs_root_node)
- {
- /*the control port to the translator sitting on the real node*/
- mach_port_t p;
-
- /*obtain the control port for the translator sitting on the real node;
- provide the bottommost translator, so that the filter (and this is
- most probably a request of such a translator) should be able to trace
- the real translator stack*/
- err = file_get_translator_cntl(np->nn->port_notrans, &p);
- if(err)
- return err;
-
- /*set the parameters accordingly*/
- *cntltype = MACH_MSG_TYPE_MOVE_SEND;
- *cntl = p;
-
- /*return the result of operations*/
- return err;
- }
-
- /*Lock the node*/
- mutex_lock(&np->lock);
-
- /*Check if the user is the owner of this node*/
- err = fshelp_isowner(&np->nn_stat, user->user);
-
- /*If no errors have happened*/
- if(!err)
- /*try to fetch the control port*/
- err = fshelp_fetch_control(&np->transbox, cntl);
-
- /*If no errors have occurred, but no port has been returned*/
- if(!err && (cntl == MACH_PORT_NULL))
- /*set the error accordingly*/
- err = ENXIO;
-
- /*If no errors have occurred so far*/
- if(!err)
- /*set the control port type*/
- *cntltype = MACH_MSG_TYPE_MOVE_SEND;
-
- /*Unlock the node*/
- mutex_unlock(&np->lock);
-
- /*Return the result of operations*/
+ netfs_S_file_get_translator_cntl
+ (struct protid *user, mach_port_t * cntl, mach_msg_type_name_t * cntltype)
+{
+ /*If the information about the user is missing */
+ if (!user)
+ return EOPNOTSUPP;
+
+ error_t err = 0;
+
+ /*Obtain the node for which we are called */
+ node_t *np = user->po->np;
+
+ /*If the node is not the root node of nsmux */
+ if (np != netfs_root_node)
+ {
+ /*the control port to the translator sitting on the real node */
+ mach_port_t p;
+
+ /*obtain the control port for the translator sitting on the real node;
+ provide the bottommost translator, so that the filter (and this is
+ most probably a request of such a translator) should be able to trace
+ the real translator stack */
+ err = file_get_translator_cntl (np->nn->port_notrans, &p);
+ if (err)
return err;
- }/*netfs_S_file_get_translator_cntl*/
-/*----------------------------------------------------------------------------*/
+
+ /*set the parameters accordingly */
+ *cntltype = MACH_MSG_TYPE_MOVE_SEND;
+ *cntl = p;
+
+ /*return the result of operations */
+ return err;
+ }
+
+ /*Lock the node */
+ mutex_lock (&np->lock);
+
+ /*Check if the user is the owner of this node */
+ err = fshelp_isowner (&np->nn_stat, user->user);
+
+ /*If no errors have happened */
+ if (!err)
+ /*try to fetch the control port */
+ err = fshelp_fetch_control (&np->transbox, cntl);
+
+ /*If no errors have occurred, but no port has been returned */
+ if (!err && (cntl == MACH_PORT_NULL))
+ /*set the error accordingly */
+ err = ENXIO;
+
+ /*If no errors have occurred so far */
+ if (!err)
+ /*set the control port type */
+ *cntltype = MACH_MSG_TYPE_MOVE_SEND;
+
+ /*Unlock the node */
+ mutex_unlock (&np->lock);
+
+ /*Return the result of operations */
+ return err;
+} /*netfs_S_file_get_translator_cntl */
+
+/*---------------------------------------------------------------------------*/
/*Entry point*/
-int
-main
- (
- int argc,
- char ** argv
- )
- {
- /*Start logging*/
- INIT_LOG();
- LOG_MSG(">> Starting initialization...");
-
- /*The port on which this translator will be set upon*/
- mach_port_t bootstrap_port;
-
- error_t err = 0;
-
- /*Parse the command line arguments*/
- argp_parse(&argp_startup, argc, argv, ARGP_IN_ORDER, 0, 0);
- LOG_MSG("Command line arguments parsed.");
-
- /*Try to create the root node*/
- err = node_create_root(&netfs_root_node);
- if(err)
- error(EXIT_FAILURE, err, "Failed to create the root node");
- LOG_MSG("Root node created.");
-
- /*Obtain the bootstrap port*/
- task_get_bootstrap_port(mach_task_self(), &bootstrap_port);
-
- /*Initialize the translator*/
- netfs_init();
-
- /*Obtain a port to the underlying node*/
- underlying_node = netfs_startup(bootstrap_port, O_READ);
- LOG_MSG("netfs initialization complete.");
-
- /*Initialize the root node*/
- err = node_init_root(netfs_root_node);
- if(err)
- error(EXIT_FAILURE, err, "Failed to initialize the root node");
- LOG_MSG("Root node initialized.");
- LOG_MSG("\tRoot node address: 0x%lX", (unsigned long)netfs_root_node);
-
- /*Map the time for updating node information*/
- err = maptime_map(0, 0, &maptime);
- if(err)
- error(EXIT_FAILURE, err, "Failed to map the time");
- LOG_MSG("Time mapped.");
-
- /*Initialize the cache with the required number of nodes*/
- ncache_init(/*ncache_size*/);
- LOG_MSG("Cache initialized.");
-
- /*Obtain stat information about the underlying node*/
- err = io_stat(underlying_node, &underlying_node_stat);
- if(err)
- error(EXIT_FAILURE, err,
- "Cannot obtain stat information about the underlying node");
- LOG_MSG("Stat information for undelying node obtained.");
-
- /*Obtain the ID of the current process*/
- fsid = getpid();
-
- /*Setup the stat information for the root node*/
- netfs_root_node->nn_stat = underlying_node_stat;
-
- netfs_root_node->nn_stat.st_ino = NSMUX_ROOT_INODE;
- netfs_root_node->nn_stat.st_fsid = fsid;
- netfs_root_node->nn_stat.st_mode = S_IFDIR | (underlying_node_stat.st_mode
- & ~S_IFMT & ~S_ITRANS); /*we are providing a translated directory*/
-
- netfs_root_node->nn_translated = netfs_root_node->nn_stat.st_mode;
-
- /*If the underlying node is not a directory, enhance the permissions
- of the root node of the proxy filesystem*/
- if(!S_ISDIR(underlying_node_stat.st_mode))
- {
- /*can be read by owner*/
- if(underlying_node_stat.st_mode & S_IRUSR)
- /*allow execution by the owner*/
- netfs_root_node->nn_stat.st_mode |= S_IXUSR;
- /*can be read by group*/
- if(underlying_node_stat.st_mode & S_IRGRP)
- /*allow execution by the group*/
- netfs_root_node->nn_stat.st_mode |= S_IXGRP;
- /*can be read by others*/
- if(underlying_node_stat.st_mode & S_IROTH)
- /*allow execution by the others*/
- netfs_root_node->nn_stat.st_mode |= S_IXOTH;
- }
-
- /*Update the timestamps of the root node*/
- fshelp_touch
- (&netfs_root_node->nn_stat, TOUCH_ATIME | TOUCH_MTIME | TOUCH_CTIME,
- maptime);
-
- LOG_MSG(">> Initialization complete. Entering netfs server loop...");
-
- /*Start serving clients*/
- for(;;)
- netfs_server_loop();
- }/*main*/
-/*----------------------------------------------------------------------------*/
+int main (int argc, char **argv)
+{
+ /*Start logging */
+ INIT_LOG ();
+ LOG_MSG (">> Starting initialization...");
+
+ /*The port on which this translator will be set upon */
+ mach_port_t bootstrap_port;
+
+ error_t err = 0;
+
+ /*Parse the command line arguments */
+ argp_parse (&argp_startup, argc, argv, ARGP_IN_ORDER, 0, 0);
+ LOG_MSG ("Command line arguments parsed.");
+
+ /*Try to create the root node */
+ err = node_create_root (&netfs_root_node);
+ if (err)
+ error (EXIT_FAILURE, err, "Failed to create the root node");
+ LOG_MSG ("Root node created.");
+
+ /*Obtain the bootstrap port */
+ task_get_bootstrap_port (mach_task_self (), &bootstrap_port);
+
+ /*Initialize the translator */
+ netfs_init ();
+
+ /*Obtain a port to the underlying node */
+ underlying_node = netfs_startup (bootstrap_port, O_READ);
+ LOG_MSG ("netfs initialization complete.");
+
+ /*Initialize the root node */
+ err = node_init_root (netfs_root_node);
+ if (err)
+ error (EXIT_FAILURE, err, "Failed to initialize the root node");
+ LOG_MSG ("Root node initialized.");
+ LOG_MSG ("\tRoot node address: 0x%lX", (unsigned long) netfs_root_node);
+
+ /*Map the time for updating node information */
+ err = maptime_map (0, 0, &maptime);
+ if (err)
+ error (EXIT_FAILURE, err, "Failed to map the time");
+ LOG_MSG ("Time mapped.");
+
+ /*Initialize the cache with the required number of nodes */
+ ncache_init ( /*ncache_size */ );
+ LOG_MSG ("Cache initialized.");
+
+ /*Obtain stat information about the underlying node */
+ err = io_stat (underlying_node, &underlying_node_stat);
+ if (err)
+ error (EXIT_FAILURE, err,
+ "Cannot obtain stat information about the underlying node");
+ LOG_MSG ("Stat information for undelying node obtained.");
+
+ /*Obtain the ID of the current process */
+ fsid = getpid ();
+
+ /*Setup the stat information for the root node */
+ netfs_root_node->nn_stat = underlying_node_stat;
+
+ netfs_root_node->nn_stat.st_ino = NSMUX_ROOT_INODE;
+ netfs_root_node->nn_stat.st_fsid = fsid;
+ /*we are providing a translated directory */
+ netfs_root_node->nn_stat.st_mode =
+ S_IFDIR | (underlying_node_stat.st_mode & ~S_IFMT & ~S_ITRANS);
+
+ netfs_root_node->nn_translated = netfs_root_node->nn_stat.st_mode;
+
+ /*If the underlying node is not a directory, enhance the permissions
+ of the root node of the proxy filesystem */
+ if (!S_ISDIR (underlying_node_stat.st_mode))
+ {
+ /*can be read by owner */
+ if (underlying_node_stat.st_mode & S_IRUSR)
+ /*allow execution by the owner */
+ netfs_root_node->nn_stat.st_mode |= S_IXUSR;
+ /*can be read by group */
+ if (underlying_node_stat.st_mode & S_IRGRP)
+ /*allow execution by the group */
+ netfs_root_node->nn_stat.st_mode |= S_IXGRP;
+ /*can be read by others */
+ if (underlying_node_stat.st_mode & S_IROTH)
+ /*allow execution by the others */
+ netfs_root_node->nn_stat.st_mode |= S_IXOTH;
+ }
+
+ /*Update the timestamps of the root node */
+ fshelp_touch
+ (&netfs_root_node->nn_stat, TOUCH_ATIME | TOUCH_MTIME | TOUCH_CTIME,
+ maptime);
+
+ LOG_MSG (">> Initialization complete. Entering netfs server loop...");
+
+ /*Start serving clients */
+ for (;;)
+ netfs_server_loop ();
+} /*main */
+
+/*---------------------------------------------------------------------------*/