summaryrefslogtreecommitdiff
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
parent59f4d4d2b67028c01f41ea0de0f12934b4fad07b (diff)
Moved the code to GCS
Now the code is (hopefully) compliant with GNU Coding Standards.
-rw-r--r--debug.h51
-rw-r--r--lib.c371
-rw-r--r--lib.h95
-rw-r--r--lnode.c759
-rw-r--r--lnode.h242
-rw-r--r--ncache.c364
-rw-r--r--ncache.h122
-rw-r--r--node.c1860
-rw-r--r--node.h280
-rw-r--r--nsmux.c2792
-rw-r--r--nsmux.h414
-rw-r--r--options.c346
-rw-r--r--options.h34
13 files changed, 3569 insertions, 4161 deletions
diff --git a/debug.h b/debug.h
index d4e79cea7..453e559e2 100644
--- a/debug.h
+++ b/debug.h
@@ -1,10 +1,10 @@
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*debug.h*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Simple facilities for debugging messages*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*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,39 +22,38 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#ifndef __DEBUG_H__
#define __DEBUG_H__
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#include <stdio.h>
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Macros--------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Macros-------------------------------------------------------------*/
/*Print debug messages here*/
#define DEBUG_OUTPUT "/var/log/nsmux.dbg"
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#ifdef DEBUG
- /*Initializes the log*/
-# define INIT_LOG() nsmux_dbg = fopen(DEBUG_OUTPUT, "wt")
- /*Closes the log*/
+/*Initializes the log */
+# define INIT_LOG() nsmux_dbg = fopen(DEBUG_OUTPUT, "wt")
+/*Closes the log */
# define CLOSE_LOG() fclose(nsmux_dbg)
- /*Prints a debug message and flushes the debug output*/
-# define LOG_MSG(fmt, args...) {fprintf(nsmux_dbg, fmt"\n", ##args);\
- fflush(nsmux_dbg);}
+/*Prints a debug message and flushes the debug output */
+# define LOG_MSG(fmt, args...) {fprintf(nsmux_dbg, fmt"\n", ##args);\
+ fflush(nsmux_dbg);}
#else
- /*Remove requests for debugging output*/
-# define INIT_LOG()
-# define CLOSE_LOG()
-# define LOG_MSG(fmt, args...)
+/*Remove requests for debugging output */
+# define INIT_LOG()
+# define CLOSE_LOG()
+# define LOG_MSG(fmt, args...)
#endif /*DEBUG*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Global Variables----------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Global Variables---------------------------------------------------*/
/*The file to write debugging info to*/
-extern FILE * nsmux_dbg;
-/*----------------------------------------------------------------------------*/
-
+extern FILE *nsmux_dbg;
+/*---------------------------------------------------------------------------*/
#endif /*__DEBUG_H__*/
diff --git a/lib.c b/lib.c
index c05e08eae..e8cb3a0d9 100644
--- a/lib.c
+++ b/lib.c
@@ -1,10 +1,10 @@
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*lib.h*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Basic routines for filesystem manipulations*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*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,198 +22,195 @@
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 <sys/mman.h>
#include <fcntl.h>
#include <hurd/fshelp.h>
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#include "lib.h"
#include "debug.h"
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Functions-----------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Functions----------------------------------------------------------*/
/*Fetches directory entries for `dir`*/
-error_t
-dir_entries_get
- (
- file_t dir,
- char ** dirent_data, /*the list of directory entries as returned
- by dir_readdir*/
- size_t * dirent_data_size, /*the size of `dirent_data`*/
- struct dirent *** dirent_list /*the array of pointers to beginnings of
- dirents in dirent_data*/
- )
- {
- error_t err = 0;
-
- /*The data (array of dirents(?)) returned by dir_readdir*/
- char * data;
-
- /*The size of `data`*/
- size_t data_size;
-
- /*The number of entries in `data`*/
- int entries_num;
-
- /*Try to read the contents of the specified directory*/
- err = dir_readdir(dir, &data, &data_size, 0, -1, 0, &entries_num);
- if(err)
- return err;
-
- /*Create a new list of dirents*/
- struct dirent ** list;
-
- /*Allocate the memory for the list of dirents and for the
- finalizing element*/
- list = malloc(sizeof(struct dirent *) * (entries_num + 1));
-
- /*If memory allocation has failed*/
- if(!list)
- {
- /*free the result of dir_readdir*/
- munmap(data, data_size);
-
- /*return the corresponding error*/
- return ENOMEM;
- }
-
- /*The current directory entry*/
- struct dirent * dp;
-
- int i;
-
- /*Go through every element of the list of dirents*/
- for
- (
- i = 0, dp = (struct dirent *)data;
- i < entries_num;
- ++i, dp = (struct dirent *)((char *)dp + dp->d_reclen))
- /*copy the current value into the list*/
- *(list + i) = dp;
-
- /*Nullify the last element of the list*/
- *(list + i) = NULL;
-
- /*Copy the required values in the parameters*/
- *dirent_data = data;
- *dirent_data_size = data_size;
- *dirent_list = list;
-
- /*Return success*/
- return err;
- }/*dir_entries_get*/
-/*----------------------------------------------------------------------------*/
+error_t dir_entries_get (file_t dir,
+ char **dirent_data, /*the list of directory
+ entries as returned by
+ dir_readdir */
+ size_t * dirent_data_size,/*the size of
+ `dirent_data` */
+ struct dirent ***dirent_list/*the array of
+ pointers to
+ beginnings of
+ dirents in
+ dirent_data */
+ )
+{
+ error_t err = 0;
+
+ /*The data (array of dirents(?)) returned by dir_readdir */
+ char *data;
+
+ /*The size of `data` */
+ size_t data_size;
+
+ /*The number of entries in `data` */
+ int entries_num;
+
+ /*Try to read the contents of the specified directory */
+ err = dir_readdir (dir, &data, &data_size, 0, -1, 0, &entries_num);
+ if (err)
+ return err;
+
+ /*Create a new list of dirents */
+ struct dirent **list;
+
+ /*Allocate the memory for the list of dirents and for the
+ finalizing element */
+ list = malloc (sizeof (struct dirent *) * (entries_num + 1));
+
+ /*If memory allocation has failed */
+ if (!list)
+ {
+ /*free the result of dir_readdir */
+ munmap (data, data_size);
+
+ /*return the corresponding error */
+ return ENOMEM;
+ }
+
+ /*The current directory entry */
+ struct dirent *dp;
+
+ int i;
+
+ /*Go through every element of the list of dirents */
+ for
+ (i = 0, dp = (struct dirent *) data;
+ i < entries_num;
+ ++i, dp = (struct dirent *) ((char *) dp + dp->d_reclen))
+ /*copy the current value into the list */
+ *(list + i) = dp;
+
+ /*Nullify the last element of the list */
+ *(list + i) = NULL;
+
+ /*Copy the required values in the parameters */
+ *dirent_data = data;
+ *dirent_data_size = data_size;
+ *dirent_list = list;
+
+ /*Return success */
+ return err;
+} /*dir_entries_get */
+
+/*---------------------------------------------------------------------------*/
/*Lookup `name` under `dir` (or cwd, if `dir` is invalid)*/
-error_t
-file_lookup
- (
- file_t dir,
- char * name,
- int flags0, /*try to open with these flags first*/
- int flags1, /*try to open with these flags, if `flags0` fail*/
- int mode, /*if the file is to be created, create it with this mode*/
- file_t * port, /*store the port to the looked up file here*/
- io_statbuf_t * stat /*store the stat information here*/
- )
+error_t file_lookup (file_t dir, char *name,
+ int flags0, /*try to open with these flags first */
+ int flags1, /*try to open with these flags, if
+ `flags0` fail */
+ int mode, /*if the file is to be created, create
+ it with this mode */
+ file_t * port, /*store the port to the looked up
+ file here */
+ io_statbuf_t * stat /*store the stat information here */
+ )
+{
+ error_t err = 0;
+
+ /*The port to the looked up file */
+ file_t p;
+
+ /*The stat information about the looked up file */
+ io_statbuf_t s;
+
+ /*Performs a lookup under 'dir' or in cwd, if `dir` is invalid */
+ file_t do_file_lookup (file_t dir, char *name, /*lookup this file */
+ int flags, /*lookup the file with these flags */
+ int mode /*if a new file is to be
+ created, create it with this
+ mode */
+ )
+ {
+ /*The result of lookup */
+ file_t p;
+
+ /*If `dir` is a valid port */
+ if (dir != MACH_PORT_NULL)
+ /*try to lookup `name` under `dir` */
+ p = file_name_lookup_under (dir, name, flags, mode);
+ else
+ /*lookup `name` under current cwd */
+ p = file_name_lookup (name, flags, mode);
+
+ /*Return the result of the lookup */
+ return p;
+ } /*do_file_lookup */
+
+ /*Lookup `name` under the suggested `dir` */
+ p = do_file_lookup (dir, name, flags0, mode);
+
+ /*If the lookup failed */
+ if (p == MACH_PORT_NULL)
+ /*try to lookup for `name` using alternative flags `flags1` */
+ p = do_file_lookup (dir, name, flags1, mode);
+
+ /*If the port is valid */
+ if (p != MACH_PORT_NULL)
+ {
+ /*If stat information is required */
+ if (stat)
{
- error_t err = 0;
-
- /*The port to the looked up file*/
- file_t p;
-
- /*The stat information about the looked up file*/
- io_statbuf_t s;
-
- /*Performs a lookup under 'dir' or in cwd, if `dir` is invalid*/
- file_t
- do_file_lookup
- (
- file_t dir,
- char * name, /*lookup this file*/
- int flags, /*lookup the file with these flags*/
- int mode /*if a new file is to be created, create it with this mode*/
- )
- {
- /*The result of lookup*/
- file_t p;
-
- /*If `dir` is a valid port*/
- if(dir != MACH_PORT_NULL)
- /*try to lookup `name` under `dir`*/
- p = file_name_lookup_under(dir, name, flags, mode);
- else
- /*lookup `name` under current cwd*/
- p = file_name_lookup(name, flags, mode);
-
- /*Return the result of the lookup*/
- return p;
- }/*do_file_lookup*/
-
- /*Lookup `name` under the suggested `dir`*/
- p = do_file_lookup(dir, name, flags0, mode);
-
- /*If the lookup failed*/
- if(p == MACH_PORT_NULL)
- /*try to lookup for `name` using alternative flags `flags1`*/
- p = do_file_lookup(dir, name, flags1, mode);
-
- /*If the port is valid*/
- if(p != MACH_PORT_NULL)
- {
- /*If stat information is required*/
- if(stat)
- {
- /*obtain stat information for `p`*/
- err = io_stat(p, &s);
- if(err)
- PORT_DEALLOC(p);
- }
- }
- else
- /*copy `errno` into `err`*/
- err = errno;
-
- /*If no errors have happened during lookup*/
- if(!err)
- {
- /*copy the resulting port into *`port`*/
- *port = p;
-
- /*fill in the receiver for stat information, if requried*/
- if(stat)
- *stat = s;
- }
-
- /*Return the result of performing operations*/
- return err;
- }/*file_lookup*/
-/*----------------------------------------------------------------------------*/
-/*Checks whether `user` has the right to open the node described by `stat` with
- `flags`*/
+ /*obtain stat information for `p` */
+ err = io_stat (p, &s);
+ if (err)
+ PORT_DEALLOC (p);
+ }
+ }
+ else
+ /*copy `errno` into `err` */
+ err = errno;
+
+ /*If no errors have happened during lookup */
+ if (!err)
+ {
+ /*copy the resulting port into *`port` */
+ *port = p;
+
+ /*fill in the receiver for stat information, if requried */
+ if (stat)
+ *stat = s;
+ }
+
+ /*Return the result of performing operations */
+ return err;
+} /*file_lookup */
+
+/*---------------------------------------------------------------------------*/
+/*Checks whether `user` has the right to open the node described by
+ `stat` with `flags`*/
error_t
-check_open_permissions
- (
- struct iouser * user,
- io_statbuf_t * stat,
- int flags
- )
- {
- error_t err = 0;
-
- /*Cheks user's permissions*/
- if(flags & O_READ)
- err = fshelp_access(stat, S_IREAD, user);
- if(!err && (flags & O_WRITE))
- err = fshelp_access(stat, S_IWRITE, user);
- if(!err && (flags & O_EXEC))
- err = fshelp_access(stat, S_IEXEC, user);
-
- /*Return the result of the check*/
- return err;
- }/*check_open_permissions*/
-/*----------------------------------------------------------------------------*/
+ check_open_permissions
+ (struct iouser * user, io_statbuf_t * stat, int flags)
+{
+ error_t err = 0;
+
+ /*Cheks user's permissions */
+ if (flags & O_READ)
+ err = fshelp_access (stat, S_IREAD, user);
+ if (!err && (flags & O_WRITE))
+ err = fshelp_access (stat, S_IWRITE, user);
+ if (!err && (flags & O_EXEC))
+ err = fshelp_access (stat, S_IEXEC, user);
+
+ /*Return the result of the check */
+ return err;
+} /*check_open_permissions */
+
+/*---------------------------------------------------------------------------*/
diff --git a/lib.h b/lib.h
index 776d475e2..2b7f49a90 100644
--- a/lib.h
+++ b/lib.h
@@ -1,10 +1,10 @@
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*lib.h*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Declarations of basic routines for filesystem manipulations*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*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,72 +22,69 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#ifndef __LIB_H__
#define __LIB_H__
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#define __USE_FILE_OFFSET64
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#include <hurd.h>
#include <dirent.h>
#include <stddef.h>
#include <hurd/iohelp.h>
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Macros--------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Macros-------------------------------------------------------------*/
/*Alignment of directory entries*/
#define DIRENT_ALIGN 4
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*The offset of the directory name in the directory entry structure*/
#define DIRENT_NAME_OFFS offsetof(struct dirent, d_name)
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Computes the length of the structure before the name + the name + 0,
- all padded to DIRENT_ALIGN*/
+ all padded to DIRENT_ALIGN*/
#define DIRENT_LEN(name_len)\
((DIRENT_NAME_OFFS + (name_len) + 1 + DIRENT_ALIGN - 1) &\
~(DIRENT_ALIGN - 1))
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Deallocate the given port for the current task*/
#define PORT_DEALLOC(p) (mach_port_deallocate(mach_task_self(), (p)))
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Functions-----------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Functions----------------------------------------------------------*/
/*Fetches directory entries for `dir`*/
-error_t
-dir_entries_get
- (
- file_t dir,
- char ** dirent_data, /*the list of directory entries as returned
- by dir_readdir*/
- size_t * dirent_data_size, /*the size of `dirent_data`*/
- struct dirent *** dirent_list /*the array of pointers to beginnings of
- dirents in dirent_data*/
- );
-/*----------------------------------------------------------------------------*/
+error_t dir_entries_get (file_t dir,
+ char **dirent_data, /*the list of directory
+ entries as returned by
+ dir_readdir */
+ size_t * dirent_data_size,/*the size of
+ `dirent_data` */
+ struct dirent ***dirent_list/*the array of
+ pointers to
+ beginnings of
+ dirents in
+ dirent_data */
+ );
+/*---------------------------------------------------------------------------*/
/*Lookup `name` under `dir` (or cwd, if `dir` is invalid)*/
+error_t file_lookup (file_t dir, char *name,
+ int flags0, /*try to open with these flags first */
+ int flags1, /*try to open with these flags, if
+ `flags0` fail */
+ int mode, /*if the file is to be created, create
+ it with this mode */
+ file_t * port, /*store the port to the looked up
+ file here */
+ io_statbuf_t * stat /*store the stat information here */
+ );
+/*---------------------------------------------------------------------------*/
+/*Checks whether `user` has the right to open the node described by
+ `stat` with `flags`*/
error_t
-file_lookup
- (
- file_t dir,
- char * name,
- int flags0, /*try to open with these flags first*/
- int flags1, /*try to open with these flags, if `flags0` fail*/
- int mode, /*if the file is to be created, create it with this mode*/
- file_t * port, /*store the port to the looked up file here*/
- io_statbuf_t * stat /*store the stat information here*/
- );
-/*----------------------------------------------------------------------------*/
-/*Checks whether `user` has the right to open the node described by `stat` with
- `flags`*/
-error_t
-check_open_permissions
- (
- struct iouser * user,
- io_statbuf_t * stat,
- int flags
- );
-/*----------------------------------------------------------------------------*/
+ check_open_permissions
+ (struct iouser *user, io_statbuf_t * stat, int flags);
+/*---------------------------------------------------------------------------*/
#endif /*__LIB_H__*/
diff --git a/lnode.c b/lnode.c
index 2e6d34eb5..2d1f058c3 100644
--- a/lnode.c
+++ b/lnode.c
@@ -1,10 +1,10 @@
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*lnode.c*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Implementation of policies of management of 'light nodes'*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*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,407 +22,376 @@
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
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#include "lnode.h"
#include "debug.h"
#include "node.h"
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Functions-----------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Functions----------------------------------------------------------*/
/*Adds a reference to the `lnode` (which must be locked)*/
-void
-lnode_ref_add
- (
- lnode_t * node
- )
- {
- /*Increment the number of references*/
- ++node->references;
- }/*lnode_ref_add*/
-/*----------------------------------------------------------------------------*/
-/*Removes a reference from `node` (which must be locked). If that was the last
- reference, destroy the node*/
-void
-lnode_ref_remove
- (
- lnode_t * node
- )
- {
- /*Fail if the node is not referenced by anybody*/
- assert(node->references);
-
- /*Decrement the number of references to `node`*/
- --node->references;
-
- /*If there are no references remaining*/
- if(node->references == 0)
- {
- /*uninstall the node from the directory it is in and destroy it*/
- lnode_uninstall(node);
- lnode_destroy(node);
- }
- else
- /*simply unlock the node*/
- mutex_unlock(&node->lock);
- }/*lnode_ref_remove*/
-/*----------------------------------------------------------------------------*/
+void lnode_ref_add (lnode_t * node)
+{
+ /*Increment the number of references */
+ ++node->references;
+} /*lnode_ref_add */
+
+/*---------------------------------------------------------------------------*/
+/*Removes a reference from `node` (which must be locked). If that was
+ the last reference, destroy the node*/
+void lnode_ref_remove (lnode_t * node)
+{
+ /*Fail if the node is not referenced by anybody */
+ assert (node->references);
+
+ /*Decrement the number of references to `node` */
+ --node->references;
+
+ /*If there are no references remaining */
+ if (node->references == 0)
+ {
+ /*uninstall the node from the directory it is in and destroy it */
+ lnode_uninstall (node);
+ lnode_destroy (node);
+ }
+ else
+ /*simply unlock the node */
+ mutex_unlock (&node->lock);
+} /*lnode_ref_remove */
+
+/*---------------------------------------------------------------------------*/
/*Creates a new lnode with `name`; the new node is locked and contains
- a single reference*/
-error_t
-lnode_create
- (
- char * name,
- lnode_t ** node /*put the result here*/
- )
+ a single reference*/
+error_t lnode_create (char *name, lnode_t ** node)
+{
+ /*Allocate the memory for the node */
+ lnode_t *node_new = malloc (sizeof (lnode_t));
+
+ /*If the memory has not been allocated */
+ if (!node_new)
+ {
+ /*stop */
+ return ENOMEM;
+ }
+
+ /*The copy of the name */
+ char *name_cp = NULL;
+
+ /*If the name exists */
+ if (name)
+ {
+ /*duplicate it */
+ name_cp = strdup (name);
+
+ /*If the name has not been duplicated */
+ if (!name_cp)
{
- /*Allocate the memory for the node*/
- lnode_t * node_new = malloc(sizeof(lnode_t));
-
- /*If the memory has not been allocated*/
- if(!node_new)
- {
- /*stop*/
- return ENOMEM;
- }
-
- /*The copy of the name*/
- char * name_cp = NULL;
-
- /*If the name exists*/
- if(name)
- {
- /*duplicate it*/
- name_cp = strdup(name);
-
- /*If the name has not been duplicated*/
- if(!name_cp)
- {
- /*free the node*/
- free(node_new);
-
- /*stop*/
- return ENOMEM;
- }
- }
-
- /*Setup the new node*/
- memset(node_new, 0, sizeof(lnode_t));
- node_new->name = name_cp;
- node_new->name_len = (name_cp) ? (strlen(name_cp)) : (0);
-
- /*Setup one reference to this lnode*/
- node_new->references = 1;
-
- /*Initialize the mutex and acquire a lock on this lnode*/
- mutex_init(&node_new->lock);
- mutex_lock(&node_new->lock);
-
- /*Store the result in the second parameter*/
- *node = node_new;
-
- /*Return success*/
- return 0;
- }/*lnode_create*/
-/*----------------------------------------------------------------------------*/
+ /*free the node */
+ free (node_new);
+
+ /*stop */
+ return ENOMEM;
+ }
+ }
+
+ /*Setup the new node */
+ memset (node_new, 0, sizeof (lnode_t));
+ node_new->name = name_cp;
+ node_new->name_len = (name_cp) ? (strlen (name_cp)) : (0);
+
+ /*Setup one reference to this lnode */
+ node_new->references = 1;
+
+ /*Initialize the mutex and acquire a lock on this lnode */
+ mutex_init (&node_new->lock);
+ mutex_lock (&node_new->lock);
+
+ /*Store the result in the second parameter */
+ *node = node_new;
+
+ /*Return success */
+ return 0;
+} /*lnode_create */
+
+/*---------------------------------------------------------------------------*/
/*Destroys the given lnode*/
-void
-lnode_destroy
- (
- lnode_t * node /*destroy this*/
- )
- {
- /*Destroy the name of the node*/
- free(node->name);
-
- /*While the list of proxies has not been freed*/
- node_list_t p;
- for(p = node->proxies; p;)
- {
- /*shift the pointer to the head of the list forward*/
- node->proxies = node->proxies->next;
-
- /*drop the current cell in the list*/
- free(p);
-
- /*store the current proxy*/
- p = node->proxies;
- }
-
- /*Destroy the node itself*/
- free(node);
- }/*lnode_destroy*/
-/*----------------------------------------------------------------------------*/
-/*Constructs the full path for the given lnode and stores the result both in
- the parameter and inside the lnode (the same string, actually)*/
-error_t
-lnode_path_construct
- (
- lnode_t * node,
- char ** path /*store the path here*/
- )
+void lnode_destroy (lnode_t * node)
+{
+ /*Destroy the name of the node */
+ free (node->name);
+
+ /*While the list of proxies has not been freed */
+ node_list_t p;
+ for (p = node->proxies; p;)
+ {
+ /*shift the pointer to the head of the list forward */
+ node->proxies = node->proxies->next;
+
+ /*drop the current cell in the list */
+ free (p);
+
+ /*store the current proxy */
+ p = node->proxies;
+ }
+
+ /*Destroy the node itself */
+ free (node);
+} /*lnode_destroy */
+
+/*---------------------------------------------------------------------------*/
+/*Constructs the full path for the given lnode and stores the result
+ both in the parameter and inside the lnode (the same string,
+ actually)*/
+error_t lnode_path_construct (lnode_t * node, char **path)
+{
+ error_t err = 0;
+
+ /*The final path */
+ char *p;
+
+ /*The final length of the path */
+ int p_len = 0;
+
+ /*A temporary pointer to an lnode */
+ lnode_t *n;
+
+ /*While the root node of the proxy filesystem has not been reached */
+ for (n = node; n && n->dir; n = n->dir)
+ /*add the length of the name of `n` to `p_len` make some space for
+ the delimiter '/', if we are not approaching the root node */
+ /*p_len += n->name_len + ((n->dir->dir) ? (1) : (0)); */
+ /*There is some path to our root node, so we will anyway have to
+ add a '/' */
+ p_len += n->name_len + 1;
+
+ /*Include the space for the path to the root node of the proxy
+ (n is now the root of the filesystem) */
+ p_len += strlen (n->path) + 1;
+
+ /*Try to allocate the space for the string */
+ p = malloc (p_len * sizeof (char));
+ if (!p)
+ err = ENOMEM;
+ /*If memory allocation has been successful */
+ else
+ {
+ /*put a terminal 0 at the end of the path */
+ p[--p_len] = 0;
+
+ /*While the root node of the proxy filesystem has not been reached */
+ for (n = node; n && n->dir; n = n->dir)
{
- error_t err = 0;
-
- /*The final path*/
- char * p;
-
- /*The final length of the path*/
- int p_len = 0;
-
- /*A temporary pointer to an lnode*/
- lnode_t * n;
-
- /*While the root node of the proxy filesystem has not been reached*/
- for(n = node; n && n->dir; n = n->dir)
- /*add the length of the name of `n` to `p_len` make some space for
- the delimiter '/', if we are not approaching the root node*/
- /*p_len += n->name_len + ((n->dir->dir) ? (1) : (0));*/
- /*There is some path to our root node, so we will anyway have to
- add a '/'*/
- p_len += n->name_len + 1;
-
- /*Include the space for the path to the root node of the proxy
- (n is now the root of the filesystem)*/
- p_len += strlen(n->path) + 1;
-
- /*Try to allocate the space for the string*/
- p = malloc(p_len * sizeof(char));
- if(!p)
- err = ENOMEM;
- /*If memory allocation has been successful*/
- else
- {
- /*put a terminal 0 at the end of the path*/
- p[--p_len] = 0;
-
- /*While the root node of the proxy filesystem has not been reached*/
- for(n = node; n && n->dir; n = n->dir)
- {
- /*compute the position where the name of `n` is to be inserted*/
- p_len -= n->name_len;
-
- /*copy the name of the node into the path (omit the terminal 0)*/
- strncpy(p + p_len, n->name, n->name_len);
-
- /*If we are not at the root node of the proxy filesystem, add the
- separator*/
- /*if(n->dir->dir)
- p[--p_len] = '/';*/
- /*we anyway have to add the separator slash*/
- p[--p_len] = '/';
- }
-
- /*put the path to the root node at the beginning of the first path
- (n is at the root now)*/
- strncpy(p, n->path, strlen(n->path));
-
- /*destroy the former path in lnode, if it exists*/
- if(node->path)
- free(node->path);
-
- /*store the new path inside the lnode*/
- node->path = p;
-
- /*store the path in the parameter*/
- if(path)
- *path = p;
- }
-
- /*Return the result of operations*/
- return err;
- }/*lnode_path_construct*/
-/*----------------------------------------------------------------------------*/
+ /*compute the position where the name of `n` is to be inserted */
+ p_len -= n->name_len;
+
+ /*copy the name of the node into the path (omit the terminal 0) */
+ strncpy (p + p_len, n->name, n->name_len);
+
+ /*If we are not at the root node of the proxy filesystem, add the
+ separator */
+ /*if(n->dir->dir)
+ p[--p_len] = '/'; */
+ /*we anyway have to add the separator slash */
+ p[--p_len] = '/';
+ }
+
+ /*put the path to the root node at the beginning of the first path
+ (n is at the root now) */
+ strncpy (p, n->path, strlen (n->path));
+
+ /*destroy the former path in lnode, if it exists */
+ if (node->path)
+ free (node->path);
+
+ /*store the new path inside the lnode */
+ node->path = p;
+
+ /*store the path in the parameter */
+ if (path)
+ *path = p;
+ }
+
+ /*Return the result of operations */
+ return err;
+} /*lnode_path_construct */
+
+/*---------------------------------------------------------------------------*/
/*Gets a light node by its name, locks it and increments its refcount*/
-error_t
-lnode_get
- (
- lnode_t * dir, /*search here*/
- char * name, /*search for this name*/
- lnode_t ** node /*put the result here*/
- )
- {
- error_t err = 0;
-
- /*The pointer to the required lnode*/
- lnode_t * n;
-
- /*Find `name` among the names of entries in `dir`*/
- for(n = dir->entries; n && (strcmp(n->name, name) != 0); n = n->next);
-
- /*If the search has been successful*/
- if(n)
- {
- /*lock the node*/
- mutex_lock(&n->lock);
-
- /*increment the refcount of the found lnode*/
- lnode_ref_add(n);
-
- /*put a pointer to `n` into the parameter*/
- *node = n;
- }
- else
- err = ENOENT;
-
- /*Return the result of operations*/
- return err;
- }/*lnode_get*/
-/*----------------------------------------------------------------------------*/
-/*Install the lnode into the lnode tree: add a reference to `dir` (which must
- be locked)*/
-void
-lnode_install
- (
- lnode_t * dir, /*install here*/
- lnode_t * node /*install this*/
- )
- {
- /*Install `node` into the list of entries in `dir`*/
- node->next = dir->entries;
- node->prevp = &dir->entries; /*this node is the first on the list*/
- if(dir->entries)
- dir->entries->prevp = &node->next; /*here `prevp` gets the value
- corresponding to its meaning*/
- dir->entries = node;
-
- /*Add a new reference to dir*/
- lnode_ref_add(dir);
-
- /*Setup the `dir` link in node*/
- node->dir = dir;
- }/*lnode_install*/
-/*----------------------------------------------------------------------------*/
-/*Unistall the node from the node tree; remove a reference from the lnode
- containing `node`*/
-void
-lnode_uninstall
- (
- lnode_t * node
- )
- {
- /*Remove a reference from the parent*/
- lnode_ref_remove(node->dir);
-
- /*Make the next pointer in the previous element point to the element,
- which follows `node`*/
- *node->prevp = node->next;
-
- /*If the current node is not the last one, connect the list after removal
- of the current node*/
- if(node->next)
- node->next->prevp = &node->next;
- }/*lnode_uninstall*/
-/*----------------------------------------------------------------------------*/
-/*Makes the specified lnode aware of another proxy. Both `node` and `proxy`
- must be locked*/
-error_t
-lnode_add_proxy
- (
- lnode_t * node,
- node_t * proxy
- )
- {
- /*TODO: Make the list of proxies finite*/
-
- /*Create an new cell in the list of proxies*/
- node_list_t p = malloc(sizeof(node_list_t));
- if(!p)
- return ENOMEM;
-
- /*If the supplied node references an lnode already
- (this should always happen, though)*/
- if(proxy->nn->lnode)
- /*remove the reference held by the node to that lnode*/
- lnode_ref_remove(proxy->nn->lnode);
-
- /*Connect the proxy to the lnode*/
- proxy->nn->lnode = node;
-
- /*Store the pointer to the proxy in the new cell*/
- p->node = proxy;
-
- /*Add the new cell to the list of proxies*/
- p->next = node->proxies;
- node->proxies = p;
-
- /*Count a new reference to this lnode*/
- lnode_ref_add(node);
-
- /*Everything is OK here*/
- return 0;
- }/*lnode_add_proxy*/
-/*----------------------------------------------------------------------------*/
+error_t lnode_get (lnode_t * dir, /*search here */
+ char *name, /*search for this name */
+ lnode_t ** node /*put the result here */
+ )
+{
+ error_t err = 0;
+
+ /*The pointer to the required lnode */
+ lnode_t *n;
+
+ /*Find `name` among the names of entries in `dir` */
+ for (n = dir->entries; n && (strcmp (n->name, name) != 0); n = n->next);
+
+ /*If the search has been successful */
+ if (n)
+ {
+ /*lock the node */
+ mutex_lock (&n->lock);
+
+ /*increment the refcount of the found lnode */
+ lnode_ref_add (n);
+
+ /*put a pointer to `n` into the parameter */
+ *node = n;
+ }
+ else
+ err = ENOENT;
+
+ /*Return the result of operations */
+ return err;
+} /*lnode_get */
+
+/*---------------------------------------------------------------------------*/
+/*Install the lnode into the lnode tree: add a reference to `dir`
+ (which must be locked)*/
+void lnode_install (lnode_t * dir, /*install here */
+ lnode_t * node /*install this */
+ )
+{
+ /*Install `node` into the list of entries in `dir` */
+ node->next = dir->entries;
+ node->prevp = &dir->entries; /*this node is the first on the list */
+ if (dir->entries)
+ dir->entries->prevp = &node->next; /*here `prevp` gets the value
+ corresponding to its meaning */
+ dir->entries = node;
+
+ /*Add a new reference to dir */
+ lnode_ref_add (dir);
+
+ /*Setup the `dir` link in node */
+ node->dir = dir;
+} /*lnode_install */
+
+/*---------------------------------------------------------------------------*/
+/*Unistall the node from the node tree; remove a reference from the
+ lnode containing `node`*/
+void lnode_uninstall (lnode_t * node)
+{
+ /*Remove a reference from the parent */
+ lnode_ref_remove (node->dir);
+
+ /*Make the next pointer in the previous element point to the element,
+ which follows `node` */
+ *node->prevp = node->next;
+
+ /*If the current node is not the last one, connect the list after removal
+ of the current node */
+ if (node->next)
+ node->next->prevp = &node->next;
+} /*lnode_uninstall */
+
+/*---------------------------------------------------------------------------*/
+/*Makes the specified lnode aware of another proxy. Both `node` and
+ `proxy` must be locked*/
+error_t lnode_add_proxy (lnode_t * node, node_t * proxy)
+{
+ /*TODO: Make the list of proxies finite */
+
+ /*Create an new cell in the list of proxies */
+ node_list_t p = malloc (sizeof (node_list_t));
+ if (!p)
+ return ENOMEM;
+
+ /*If the supplied node references an lnode already
+ (this should always happen, though) */
+ if (proxy->nn->lnode)
+ /*remove the reference held by the node to that lnode */
+ lnode_ref_remove (proxy->nn->lnode);
+
+ /*Connect the proxy to the lnode */
+ proxy->nn->lnode = node;
+
+ /*Store the pointer to the proxy in the new cell */
+ p->node = proxy;
+
+ /*Add the new cell to the list of proxies */
+ p->next = node->proxies;
+ node->proxies = p;
+
+ /*Count a new reference to this lnode */
+ lnode_ref_add (node);
+
+ /*Everything is OK here */
+ return 0;
+} /*lnode_add_proxy */
+
+/*---------------------------------------------------------------------------*/
/*Removes the specified proxy from the list of proxies of the supplied lnode.
- `proxy` must not be locked*/
-void
-lnode_remove_proxy
- (
- lnode_t * node,
- node_t * proxy
- )
- {
- /*A pointer to a cell in the list of proxies*/
- node_list_t p;
-
- /*Lock the lnode*/
- mutex_lock(&node->lock);
-
- /*If the first cell in the list contains a reference to `proxy`*/
- if(node->proxies->node == proxy)
- {
- /*store a pointer to the head of the list*/
- p = node->proxies;
-
- /*shift the head of the list forward*/
- node->proxies = node->proxies->next;
-
- /*destroy the former head*/
- free(p);
-
- /*remove a reference from the supplied lnode*/
- lnode_ref_remove(node);
-
- /*stop right here*/
- mutex_unlock(&node->lock);
- return;
- }
-
- /*Another pointer to a cell in the list*/
- node_list_t q;
-
- /*Go through the list of proxy nodes of the given lnode*/
- for(p = node->proxies; p->next; p = p->next)
- {
- /*If the next cell does not contain a reference to the same node,
- as specified in the parameter, skip this entry*/
- if(p->next->node != proxy)
- continue;
-
- /*store a copy of the next element*/
- q = p->next;
-
- /*unregister the next element from the list*/
- p->next = q->next;
-
- /*remove the unregistered element*/
- free(q);
-
- /*stop looping*/
- break;
- }
-
- /*Remove a reference from the supplied lnode*/
- lnode_ref_remove(node);
-
-
- /*Unlock the node*/
- mutex_unlock(&node->lock);
-
- return;
- }/*lnode_remove_proxy*/
-/*----------------------------------------------------------------------------*/
+ `proxy` must not be locked*/
+void lnode_remove_proxy (lnode_t * node, node_t * proxy)
+{
+ /*A pointer to a cell in the list of proxies */
+ node_list_t p;
+
+ /*Lock the lnode */
+ mutex_lock (&node->lock);
+
+ /*If the first cell in the list contains a reference to `proxy` */
+ if (node->proxies->node == proxy)
+ {
+ /*store a pointer to the head of the list */
+ p = node->proxies;
+
+ /*shift the head of the list forward */
+ node->proxies = node->proxies->next;
+
+ /*destroy the former head */
+ free (p);
+
+ /*remove a reference from the supplied lnode */
+ lnode_ref_remove (node);
+
+ /*stop right here */
+ mutex_unlock (&node->lock);
+ return;
+ }
+
+ /*Another pointer to a cell in the list */
+ node_list_t q;
+
+ /*Go through the list of proxy nodes of the given lnode */
+ for (p = node->proxies; p->next; p = p->next)
+ {
+ /*If the next cell does not contain a reference to the same node,
+ as specified in the parameter, skip this entry */
+ if (p->next->node != proxy)
+ continue;
+
+ /*store a copy of the next element */
+ q = p->next;
+
+ /*unregister the next element from the list */
+ p->next = q->next;
+
+ /*remove the unregistered element */
+ free (q);
+
+ /*stop looping */
+ break;
+ }
+
+ /*Remove a reference from the supplied lnode */
+ lnode_ref_remove (node);
+
+
+ /*Unlock the node */
+ mutex_unlock (&node->lock);
+
+ return;
+} /*lnode_remove_proxy */
+
+/*---------------------------------------------------------------------------*/
diff --git a/lnode.h b/lnode.h
index 08a70adef..efeed7123 100644
--- a/lnode.h
+++ b/lnode.h
@@ -1,10 +1,10 @@
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*lnode.h*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Management of cheap 'light nodes'*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*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,164 +22,122 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#ifndef __LNODE_H__
#define __LNODE_H__
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#include <error.h>
#include <hurd/netfs.h>
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Macros--------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Macros-------------------------------------------------------------*/
/*The possible flags in an lnode*/
-#define FLAG_LNODE_DIR 0x00000001 /*the lnode is a directory*/
-/*----------------------------------------------------------------------------*/
+#define FLAG_LNODE_DIR 0x00000001 /*the lnode is a directory */
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Types---------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Types--------------------------------------------------------------*/
/*A candy synonym for the fundamental libnetfs node*/
typedef struct node node_t;
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*A list of lnodes*/
struct node_element
- {
- /*the node associated with the current entry*/
- node_t * node;
-
- /*the next element in the list*/
- struct node_element * next;
- };/*struct node_element*/
-/*----------------------------------------------------------------------------*/
-typedef struct node_element * node_list_t;
-/*----------------------------------------------------------------------------*/
+{
+ /*the node associated with the current entry */
+ node_t *node;
+
+ /*the next element in the list */
+ struct node_element *next;
+}; /*struct node_element */
+/*---------------------------------------------------------------------------*/
+typedef struct node_element *node_list_t;
+/*---------------------------------------------------------------------------*/
/*The light node*/
struct lnode
- {
- /*the name of the lnode*/
- char * name;
-
- /*the length of the name; `name` does not change, and this value is used
- quite often, therefore calculate it just once*/
- size_t name_len;
-
- /*the full path to the lnode*/
- char * path;
-
- /*the associated flags*/
- int flags;
-
- /*the number of references to this lnode*/
- int references;
-
- /*the reference to the real netfs node*/
- node_t * node;
-
- /*the references to the proxy nodes of this lnode;
- lnodes do not hold references to */
- node_list_t proxies;
-
- /*the next lnode and the pointer to this lnode from the previous one*/
- struct lnode * next, **prevp;
-
- /*the lnode (directory) in which this node is contained*/
- struct lnode * dir;
-
- /*the beginning of the list of entries contained in this lnode (directory)*/
- struct lnode * entries;
-
- /*the lock, protecting this lnode*/
- struct mutex lock;
- };/*struct lnode*/
-/*----------------------------------------------------------------------------*/
+{
+ /*the name of the lnode */
+ char *name;
+
+ /*the length of the name; `name` does not change, and this value is used
+ quite often, therefore calculate it just once */
+ size_t name_len;
+
+ /*the full path to the lnode */
+ char *path;
+
+ /*the associated flags */
+ int flags;
+
+ /*the number of references to this lnode */
+ int references;
+
+ /*the reference to the real netfs node */
+ node_t *node;
+
+ /*the references to the proxy nodes of this lnode;
+ lnodes do not hold references to */
+ node_list_t proxies;
+
+ /*the next lnode and the pointer to this lnode from the previous one */
+ struct lnode *next, **prevp;
+
+ /*the lnode (directory) in which this node is contained */
+ struct lnode *dir;
+
+ /*the beginning of the list of entries contained in this lnode (directory) */
+ struct lnode *entries;
+
+ /*the lock, protecting this lnode */
+ struct mutex lock;
+}; /*struct lnode */
+/*---------------------------------------------------------------------------*/
typedef struct lnode lnode_t;
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
-/*--------Functions-----------------------------------------------------------*/
+/*--------Functions----------------------------------------------------------*/
/*Adds a reference to the `lnode` (which must be locked)*/
-void
-lnode_ref_add
- (
- lnode_t * node
- );
-/*----------------------------------------------------------------------------*/
-/*Removes a reference from `node` (which must be locked). If that was the last
- reference, destroy the node*/
-void
-lnode_ref_remove
- (
- lnode_t * node
- );
-/*----------------------------------------------------------------------------*/
+void lnode_ref_add (lnode_t * node);
+/*---------------------------------------------------------------------------*/
+/*Removes a reference from `node` (which must be locked). If that was
+ the last reference, destroy the node*/
+void lnode_ref_remove (lnode_t * node);
+/*---------------------------------------------------------------------------*/
/*Creates a new lnode with `name`; the new node is locked and contains
- a single reference*/
-error_t
-lnode_create
- (
- char * name,
- lnode_t ** node /*put the result here*/
- );
-/*----------------------------------------------------------------------------*/
+ a single reference*/
+error_t lnode_create (char *name, lnode_t ** node);
+/*---------------------------------------------------------------------------*/
/*Destroys the given lnode*/
-void
-lnode_destroy
- (
- lnode_t * node /*destroy this*/
- );
-/*----------------------------------------------------------------------------*/
-/*Constructs the full path for the given lnode and stores the result both in
- the parameter and inside the lnode (the same string, actually)*/
-error_t
-lnode_path_construct
- (
- lnode_t * node,
- char ** path /*store the path here*/
- );
-/*----------------------------------------------------------------------------*/
+void lnode_destroy (lnode_t * node);
+/*---------------------------------------------------------------------------*/
+/*Constructs the full path for the given lnode and stores the result
+ both in the parameter and inside the lnode (the same string,
+ actually)*/
+error_t lnode_path_construct (lnode_t * node, char **path);
+/*---------------------------------------------------------------------------*/
/*Gets a light node by its name, locks it and increments its refcount*/
-error_t
-lnode_get
- (
- lnode_t * dir, /*search here*/
- char * name, /*search for this name*/
- lnode_t ** node /*put the result here*/
- );
-/*----------------------------------------------------------------------------*/
-/*Install the lnode into the lnode tree: add a reference to `dir` (which must
- be locked)*/
-void
-lnode_install
- (
- lnode_t * dir, /*install here*/
- lnode_t * node /*install this*/
- );
-/*----------------------------------------------------------------------------*/
+error_t lnode_get (lnode_t * dir, /*search here */
+ char *name, /*search for this name */
+ lnode_t ** node /*put the result here */
+ );
+/*---------------------------------------------------------------------------*/
+/*Install the lnode into the lnode tree: add a reference to `dir`
+ (which must be locked)*/
+void lnode_install (lnode_t * dir, /*install here */
+ lnode_t * node /*install this */
+ );
+/*---------------------------------------------------------------------------*/
/*Unistall the node from the node tree; remove a reference from the lnode*/
-void
-lnode_uninstall
- (
- lnode_t * node
- );
-/*----------------------------------------------------------------------------*/
-/*Makes the specified lnode aware of another proxy. Both `node` and `proxy`
- must be locked*/
-error_t
-lnode_add_proxy
- (
- lnode_t * node,
- node_t * proxy
- );
-/*----------------------------------------------------------------------------*/
-/*Removes the specified proxy from the list of proxies of the supplied lnode.
- `proxy` must not be locked*/
-void
-lnode_remove_proxy
- (
- lnode_t * node,
- node_t * proxy
- );
-/*----------------------------------------------------------------------------*/
+void lnode_uninstall (lnode_t * node);
+/*---------------------------------------------------------------------------*/
+/*Makes the specified lnode aware of another proxy. Both `node` and
+ `proxy` must be locked*/
+error_t lnode_add_proxy (lnode_t * node, node_t * proxy);
+/*---------------------------------------------------------------------------*/
+/*Removes the specified proxy from the list of proxies of the supplied
+ lnode. `proxy` must not be locked*/
+void lnode_remove_proxy (lnode_t * node, node_t * proxy);
+/*---------------------------------------------------------------------------*/
#endif /*__LNODE_H__*/
-
diff --git a/ncache.c b/ncache.c
index f54331554..e1bcff7f0 100644
--- a/ncache.c
+++ b/ncache.c
@@ -1,10 +1,10 @@
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*ncache.h*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*The implementation of the cache of nodes*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*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,191 +22,184 @@
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 "ncache.h"
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Global Variables----------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Global Variables---------------------------------------------------*/
/*The global cache chain*/
ncache_t ncache;
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Cache size (may be overwritten by the user)*/
/*int ncache_size = NCACHE_SIZE;*/
-/*Our cache is not really a cache now (actually, it has never been one). Its
- main task now will be to maintain additional references to shadow nodes,
- which are still in use by some clients and which could possibly go away if
- nobody maintained references to them explicitly.*/
-/*----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------*/
-/*--------Functions-----------------------------------------------------------*/
+/*Our cache is not really a cache now (actually, it has never been
+ one). Its main task now will be to maintain additional references to
+ shadow nodes, which are still in use by some clients and which could
+ possibly go away if nobody maintained references to them
+ explicitly.*/
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/*--------Functions----------------------------------------------------------*/
/*Initializes the node cache*/
-void
-ncache_init
- (
- /*int size_max*/
- void
- )
- {
- /*Reset the LRU and MRU ends of the list*/
- ncache.mru = ncache.lru = NULL;
-
- /*Set the maximal size according to the parameter*/
- /*ncache.size_max = size_max;*/
-
- /*The cache is empty so far; remark that*/
- ncache.size_current = 0;
-
- /*Init the lock*/
- mutex_init(&ncache.lock);
- }/*ncache_init*/
-/*----------------------------------------------------------------------------*/
-/*Looks up the lnode and stores the result in `node`; creates a new entry
- in the cache if the lookup fails*/
-error_t
-ncache_node_lookup
- (
- lnode_t * lnode, /*search for this*/
- node_t ** node /*put the result here*/
- )
- {
- error_t err = 0;
-
- /*Obtain the pointer to the node corresponding to `lnode`*/
- node_t * n = lnode->node;
-
- /*If a node has already been created for the given lnode*/
- if(n != NULL)
- {
- /*count a new reference to 'n'*/
- netfs_nref(n);
- }
- else
- {
- /*create a new node for the given lnode and store the result in `n`*/
- err = node_create(lnode, &n);
- }
-
- /*If no errors have occurred during the previous operations*/
- if(!err)
- {
- /*lock the mutex in the looked up node*/
- mutex_lock(&n->lock);
-
- /*store the lookup result in `node`*/
- *node = n;
- }
-
- /*Return the result of operations*/
- return err;
- }/*ncache_node_lookup*/
-/*----------------------------------------------------------------------------*/
-/*Removes the given node from the cache. Does not release the reference held
- by the cache (for some further finalization actions on the node)*/
+void ncache_init (void)
+{
+ /*Reset the LRU and MRU ends of the list */
+ ncache.mru = ncache.lru = NULL;
+
+ /*Set the maximal size according to the parameter */
+ /*ncache.size_max = size_max; */
+
+ /*The cache is empty so far; remark that */
+ ncache.size_current = 0;
+
+ /*Init the lock */
+ mutex_init (&ncache.lock);
+} /*ncache_init */
+
+/*---------------------------------------------------------------------------*/
+/*Looks up the lnode and stores the result in `node`; creates a new
+ entry in the cache if the lookup fails*/
+error_t ncache_node_lookup (lnode_t * lnode, /*search for this */
+ node_t ** node /*put the result here */
+ )
+{
+ error_t err = 0;
+
+ /*Obtain the pointer to the node corresponding to `lnode` */
+ node_t *n = lnode->node;
+
+ /*If a node has already been created for the given lnode */
+ if (n != NULL)
+ {
+ /*count a new reference to 'n' */
+ netfs_nref (n);
+ }
+ else
+ {
+ /*create a new node for the given lnode and store the result in `n` */
+ err = node_create (lnode, &n);
+ }
+
+ /*If no errors have occurred during the previous operations */
+ if (!err)
+ {
+ /*lock the mutex in the looked up node */
+ mutex_lock (&n->lock);
+
+ /*store the lookup result in `node` */
+ *node = n;
+ }
+
+ /*Return the result of operations */
+ return err;
+} /*ncache_node_lookup */
+
+/*---------------------------------------------------------------------------*/
+/*Removes the given node from the cache. Does not release the
+ reference held by the cache (for some further finalization actions
+ on the node)*/
/*Nodes will NOT be removed from the cache automatically*/
-void
-ncache_node_remove
- (
- node_t * node
- )
- {
- /*Obtain the pointer to the netnode (this contains the information
- specific of us)*/
- struct netnode * nn = node->nn;
-
- /*If there exists a successor of this node in the cache chain*/
- if(nn->ncache_next)
- /*remove the reference in the successor*/
- nn->ncache_next->nn->ncache_prev = nn->ncache_prev;
- /*If there exists a predecessor of this node in the cache chain*/
- if(nn->ncache_prev)
- /*remove the reference in the predecessor*/
- nn->ncache_prev->nn->ncache_next = nn->ncache_next;
-
- /*If the node was located at the MRU end of the list*/
- if(ncache.mru == node)
- /*shift the MRU end to the next node*/
- ncache.mru = nn->ncache_next;
- /*If the node was located at the LRU end of the list*/
- if(ncache.lru == node)
- /*shift the LRU end to the previous node*/
- ncache.lru = nn->ncache_prev;
-
- /*Invalidate the references inside the node*/
- nn->ncache_next = nn->ncache_prev = NULL;
-
- /*Count the removal of a node*/
- --ncache.size_current;
- }/*ncache_node_remove*/
-/*----------------------------------------------------------------------------*/
+void ncache_node_remove (node_t * node)
+{
+ /*Obtain the pointer to the netnode (this contains the information
+ specific of us) */
+ struct netnode *nn = node->nn;
+
+ /*If there exists a successor of this node in the cache chain */
+ if (nn->ncache_next)
+ /*remove the reference in the successor */
+ nn->ncache_next->nn->ncache_prev = nn->ncache_prev;
+ /*If there exists a predecessor of this node in the cache chain */
+ if (nn->ncache_prev)
+ /*remove the reference in the predecessor */
+ nn->ncache_prev->nn->ncache_next = nn->ncache_next;
+
+ /*If the node was located at the MRU end of the list */
+ if (ncache.mru == node)
+ /*shift the MRU end to the next node */
+ ncache.mru = nn->ncache_next;
+ /*If the node was located at the LRU end of the list */
+ if (ncache.lru == node)
+ /*shift the LRU end to the previous node */
+ ncache.lru = nn->ncache_prev;
+
+ /*Invalidate the references inside the node */
+ nn->ncache_next = nn->ncache_prev = NULL;
+
+ /*Count the removal of a node */
+ --ncache.size_current;
+} /*ncache_node_remove */
+
+/*---------------------------------------------------------------------------*/
/*Resets the node cache*/
/*No references to nodes are released*/
void
-ncache_reset(void)
- {
- /*The node being currently removed from the cache*/
- node_t * node;
-
- /*Acquire a lock on the cache*/
- mutex_lock(&ncache.lock);
-
- /*Release the whole cache chain*/
- for(node = ncache.mru; node != NULL; ncache_node_remove(node), node = ncache.mru);
-
- /*Release the lock*/
- mutex_unlock(&ncache.lock);
- }/*ncache_reset*/
-/*----------------------------------------------------------------------------*/
+ncache_reset (void)
+{
+ /*The node being currently removed from the cache */
+ node_t *node;
+
+ /*Acquire a lock on the cache */
+ mutex_lock (&ncache.lock);
+
+ /*Release the whole cache chain */
+ for (node = ncache.mru; node != NULL;
+ ncache_node_remove (node), node = ncache.mru);
+
+ /*Release the lock */
+ mutex_unlock (&ncache.lock);
+} /*ncache_reset */
+
+/*---------------------------------------------------------------------------*/
/*Adds the given node to the cache*/
-void
-ncache_node_add
- (
- node_t * node /*the node to add*/
- )
+void ncache_node_add (node_t * node)
+{
+ /*Acquire a lock on the cache */
+ mutex_lock (&ncache.lock);
+
+ /*If there already are some nodes in the cache already */
+ if (ncache.size_current > 0)
+ {
+ /*If the node to be added is not at the MRU end already */
+ if (ncache.mru != node)
{
- /*Acquire a lock on the cache*/
- mutex_lock(&ncache.lock);
-
- /*If there already are some nodes in the cache already*/
- if(ncache.size_current > 0)
- {
- /*If the node to be added is not at the MRU end already*/
- if(ncache.mru != node)
- {
- /*If the node is correctly integrated in the cache*/
- if((node->nn->ncache_next != NULL) && (node->nn->ncache_prev != NULL))
- /*remove the old entry*/
- ncache_node_remove(node);
- else
- /*add a new reference to the node*/
- netfs_nref(node);
-
- /*put the node at the MRU end of the cache chain*/
- node->nn->ncache_next = ncache.mru;
- node->nn->ncache_prev = NULL;
-
- /*setup the pointer in the old MRU end, if it exists*/
- if(ncache.mru != NULL)
- ncache.mru->nn->ncache_prev = node;
-
- /*setup the LRU end of the cache chain, if it did not exist previously*/
- if(ncache.lru == NULL)
- ncache.lru = node;
-
- /*shift the MRU end to the new node*/
- ncache.mru = node;
-
- /*count the addition*/
- ++ncache.size_current;
- }
- }
-
- /*While the size of the cache is exceeding the maximal size*/
+ /*If the node is correctly integrated in the cache */
+ if ((node->nn->ncache_next != NULL)
+ && (node->nn->ncache_prev != NULL))
+ /*remove the old entry */
+ ncache_node_remove (node);
+ else
+ /*add a new reference to the node */
+ netfs_nref (node);
+
+ /*put the node at the MRU end of the cache chain */
+ node->nn->ncache_next = ncache.mru;
+ node->nn->ncache_prev = NULL;
+
+ /*setup the pointer in the old MRU end, if it exists */
+ if (ncache.mru != NULL)
+ ncache.mru->nn->ncache_prev = node;
+
+ /*setup the LRU end of the cache chain, if it did not exist
+ previously */
+ if (ncache.lru == NULL)
+ ncache.lru = node;
+
+ /*shift the MRU end to the new node */
+ ncache.mru = node;
+
+ /*count the addition */
+ ++ncache.size_current;
+ }
+ }
+
+ /*While the size of the cache is exceeding the maximal size */
/* node_t * old_lru;
for
(
@@ -215,14 +208,15 @@ ncache_node_add
old_lru = ncache.lru
)
{*/
- /*remove the current LRU end of the list from the cache*/
- /*ncache_node_remove(old_lru);*/
-
- /*release the reference to the node owned by this thread*/
- /*netfs_nrele(old_lru);
- }*/
-
- /*Release the lock on the cache*/
- mutex_unlock(&ncache.lock);
- }/*ncache_node_add*/
-/*----------------------------------------------------------------------------*/
+ /*remove the current LRU end of the list from the cache */
+ /*ncache_node_remove(old_lru); */
+
+ /*release the reference to the node owned by this thread */
+ /*netfs_nrele(old_lru);
+ } */
+
+ /*Release the lock on the cache */
+ mutex_unlock (&ncache.lock);
+} /*ncache_node_add */
+
+/*---------------------------------------------------------------------------*/
diff --git a/ncache.h b/ncache.h
index 15688ba19..e0235657b 100644
--- a/ncache.h
+++ b/ncache.h
@@ -1,10 +1,10 @@
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*ncache.h*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*The cache of nodes*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*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,94 +22,78 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#ifndef __NCACHE_H__
#define __NCACHE_H__
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#include <error.h>
#include <hurd/netfs.h>
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#include "node.h"
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Macros--------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Macros-------------------------------------------------------------*/
/*The default maximal cache size*/
/*#define NCACHE_SIZE 256*/
/*SEE ALSO the comment in ncache.c*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Types---------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Types--------------------------------------------------------------*/
/*A cache chain*/
struct ncache
- {
- /*the MRU end of the cache chain*/
- node_t * mru;
-
- /*the LRU end of the cache chain*/
- node_t * lru;
-
- /*the maximal number of nodes to cache*/
- /*int size_max;*/
- /*SEE ALSO the comment in ncache.c*/
-
- /*the current length of the cache chain*/
- int size_current;
-
- /*a lock*/
- struct mutex lock;
- };/*struct ncache*/
-/*----------------------------------------------------------------------------*/
+{
+ /*the MRU end of the cache chain */
+ node_t *mru;
+
+ /*the LRU end of the cache chain */
+ node_t *lru;
+
+ /*the maximal number of nodes to cache */
+ /*int size_max; */
+ /*SEE ALSO the comment in ncache.c */
+
+ /*the current length of the cache chain */
+ int size_current;
+
+ /*a lock */
+ struct mutex lock;
+}; /*struct ncache */
+/*---------------------------------------------------------------------------*/
typedef struct ncache ncache_t;
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Global Variables----------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Global Variables---------------------------------------------------*/
/*The cache size (may be overwritten by the user)*/
/*extern int cache_size;*/
/*SEE ALSO the comment in ncache.c*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
-/*--------Functions-----------------------------------------------------------*/
+/*--------Functions----------------------------------------------------------*/
/*Initializes the node cache*/
-void
-ncache_init
- (
- /*int size_max*/
- void
- );
-/*----------------------------------------------------------------------------*/
-/*Looks up the lnode and stores the result in `node`; creates a new entry
- in the cache if the lookup fails*/
-error_t
-ncache_node_lookup
- (
- lnode_t * lnode, /*search for this*/
- node_t ** node /*put the result here*/
- );
-/*----------------------------------------------------------------------------*/
-/*Removes the given node from the cache. Does not release the reference held
- by the cache (for some further finalization actions on the node)*/
+void ncache_init (void);
+/*---------------------------------------------------------------------------*/
+/*Looks up the lnode and stores the result in `node`; creates a new
+ entry in the cache if the lookup fails*/
+error_t ncache_node_lookup (lnode_t * lnode, /*search for this */
+ node_t ** node /*put the result here */
+ );
+/*---------------------------------------------------------------------------*/
+/*Removes the given node from the cache. Does not release the
+ reference held by the cache (for some further finalization actions
+ on the node)*/
/*Nodes will NOT be removed from the cache automatically*/
-void
-ncache_node_remove
- (
- node_t * node
- );
-/*----------------------------------------------------------------------------*/
+void ncache_node_remove (node_t * node);
+/*---------------------------------------------------------------------------*/
/*Resets the node cache*/
/*No references to nodes are released*/
-void
-ncache_reset(void);
-/*----------------------------------------------------------------------------*/
+void ncache_reset (void);
+/*---------------------------------------------------------------------------*/
/*Adds the given node to the cache*/
-void
-ncache_node_add
- (
- node_t * node /*the node to add*/
- );
-/*----------------------------------------------------------------------------*/
+void ncache_node_add (node_t * node);
+/*---------------------------------------------------------------------------*/
#endif /*__NCACHE_H__*/
diff --git a/node.c b/node.c
index a452571ff..866bd1977 100644
--- a/node.c
+++ b/node.c
@@ -1,10 +1,10 @@
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*node.c*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Implementation of node management strategies*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*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,11 +22,11 @@
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 <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
@@ -34,1018 +34,888 @@
#include <stdio.h>
#include <argz.h>
#include <hurd/fsys.h>
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#include "debug.h"
#include "node.h"
#include "options.h"
#include "lib.h"
#include "nsmux.h"
#include "ncache.h"
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Global Variables----------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Global Variables---------------------------------------------------*/
/*The lock protecting the underlying filesystem*/
struct mutex ulfs_lock = MUTEX_INITIALIZER;
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Functions-----------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Functions----------------------------------------------------------*/
/*Derives a new node from `lnode` and adds a reference to `lnode`*/
-error_t
-node_create
- (
- lnode_t * lnode,
- node_t ** node /*store the result here*/
- )
+error_t node_create (lnode_t * lnode, node_t ** node)
+{
+ error_t err = 0;
+
+ /*Create a new netnode */
+ netnode_t *netnode_new = malloc (sizeof (netnode_t));
+
+ /*Reset the memory allocated for the new netnode (just in case :-) ) */
+ memset (netnode_new, 0, sizeof (netnode_t));
+
+ /*If the memory could not be allocated */
+ if (netnode_new == NULL)
+ err = ENOMEM;
+ else
+ {
+ /*create a new node from the netnode */
+ node_t *node_new = netfs_make_node (netnode_new);
+
+ /*If the creation failed */
+ if (node_new == NULL)
{
- error_t err = 0;
-
- /*Create a new netnode*/
- netnode_t * netnode_new = malloc(sizeof(netnode_t));
-
- /*Reset the memory allocated for the new netnode (just in case :-) )*/
- memset(netnode_new, 0, sizeof(netnode_t));
-
- /*If the memory could not be allocated*/
- if(netnode_new == NULL)
- err = ENOMEM;
- else
- {
- /*create a new node from the netnode*/
- node_t * node_new = netfs_make_node(netnode_new);
-
- /*If the creation failed*/
- if(node_new == NULL)
- {
- /*set the error code*/
- err = ENOMEM;
-
- /*destroy the netnode created above*/
- free(netnode_new);
-
- /*stop*/
- return err;
- }
-
- /*link the lnode to the new node*/
- lnode->node = node_new;
-
- /*setup the references in the newly created node*/
- node_new->nn->lnode = lnode;
- lnode_ref_add(lnode);
-
- /*setup the information in the netnode*/
- node_new->nn->flags = 0;
- node_new->nn->ncache_next = node_new->nn->ncache_prev = NULL;
-
- /*initialize the list of translators*/
- node_new->nn->trans = NULL;
- node_new->nn->ntrans = node_new->nn->translen = 0;
-
- /*store the result of creation in the second parameter*/
- *node = node_new;
- }
-
- /*Return the result of operations*/
- return err;
- }/*node_create*/
-/*----------------------------------------------------------------------------*/
+ /*set the error code */
+ err = ENOMEM;
+
+ /*destroy the netnode created above */
+ free (netnode_new);
+
+ /*stop */
+ return err;
+ }
+
+ /*link the lnode to the new node */
+ lnode->node = node_new;
+
+ /*setup the references in the newly created node */
+ node_new->nn->lnode = lnode;
+ lnode_ref_add (lnode);
+
+ /*setup the information in the netnode */
+ node_new->nn->flags = 0;
+ node_new->nn->ncache_next = node_new->nn->ncache_prev = NULL;
+
+ /*initialize the list of translators */
+ node_new->nn->trans = NULL;
+ node_new->nn->ntrans = node_new->nn->translen = 0;
+
+ /*store the result of creation in the second parameter */
+ *node = node_new;
+ }
+
+ /*Return the result of operations */
+ return err;
+} /*node_create */
+
+/*---------------------------------------------------------------------------*/
/*Derives a new proxy from `lnode`*/
-error_t
-node_create_proxy
- (
- lnode_t * lnode,
- node_t ** node /*store the result here*/
- )
+error_t node_create_proxy (lnode_t * lnode, node_t ** node)
+{
+ error_t err = 0;
+
+ /*Create a new netnode */
+ netnode_t *netnode_new = malloc (sizeof (netnode_t));
+
+ /*Reset the memory allocated for the new netnode. We do this here
+ since lnode_add_proxy will try to reference the `lnode` in this
+ netnode and will do bad writes to memory. */
+ memset (netnode_new, 0, sizeof (netnode_t));
+
+ /*If the memory could not be allocated */
+ if (netnode_new == NULL)
+ err = ENOMEM;
+ else
+ {
+ /*create a new node from the netnode */
+ node_t *node_new = netfs_make_node (netnode_new);
+
+ /*If the creation failed */
+ if (node_new == NULL)
{
- error_t err = 0;
-
- /*Create a new netnode*/
- netnode_t * netnode_new = malloc(sizeof(netnode_t));
-
- /*Reset the memory allocated for the new netnode. We do this here
- since lnode_add_proxy will try to reference the `lnode` in this netnode
- and will do bad writes to memory.*/
- memset(netnode_new, 0, sizeof(netnode_t));
-
- /*If the memory could not be allocated*/
- if(netnode_new == NULL)
- err = ENOMEM;
- else
- {
- /*create a new node from the netnode*/
- node_t * node_new = netfs_make_node(netnode_new);
-
- /*If the creation failed*/
- if(node_new == NULL)
- {
- /*set the error code*/
- err = ENOMEM;
-
- /*destroy the netnode created above*/
- free(netnode_new);
-
- /*stop*/
- return err;
- }
-
- /*add this new node to the list of proxies of `lnode`*/
- lnode_add_proxy(lnode, node_new);
-
- /*setup the information in the netnode*/
- node_new->nn->flags = 0;
- node_new->nn->ncache_next = node_new->nn->ncache_prev = NULL;
-
- /*initialize the list of translators*/
- node_new->nn->trans = NULL;
- node_new->nn->ntrans = node_new->nn->translen = 0;
-
- /*store the result of creation in the second parameter*/
- *node = node_new;
- }
-
- /*Return the result of operations*/
- return err;
- }/*node_create_proxy*/
-/*----------------------------------------------------------------------------*/
+ /*set the error code */
+ err = ENOMEM;
+
+ /*destroy the netnode created above */
+ free (netnode_new);
+
+ /*stop */
+ return err;
+ }
+
+ /*add this new node to the list of proxies of `lnode` */
+ lnode_add_proxy (lnode, node_new);
+
+ /*setup the information in the netnode */
+ node_new->nn->flags = 0;
+ node_new->nn->ncache_next = node_new->nn->ncache_prev = NULL;
+
+ /*initialize the list of translators */
+ node_new->nn->trans = NULL;
+ node_new->nn->ntrans = node_new->nn->translen = 0;
+
+ /*store the result of creation in the second parameter */
+ *node = node_new;
+ }
+
+ /*Return the result of operations */
+ return err;
+} /*node_create_proxy */
+
+/*---------------------------------------------------------------------------*/
/*Destroys the specified node and removes a light reference from the
- associated light node*/
-void
-node_destroy
- (
- node_t * np
- )
- {
- /*Die if the node does not belong to node cache*/
- assert(!np->nn->ncache_next || !np->nn->ncache_prev);
-
- /*Destroy the port to the underlying filesystem allocated to the node*/
- if(np->nn->port != MACH_PORT_NULL)
- PORT_DEALLOC(np->nn->port);
-
- /*If there are translators to kill*/
- if(np->nn->lnode->dir && np->nn->trans)
- {
- /*kill all translators on the underlying nodes*/
- node_kill_translators(np);
- }
-
- /*Lock the lnode corresponding to the current node*/
- mutex_lock(&np->nn->lnode->lock);
-
- /*If the node to be destroyed is a real netfs node*/
- if(np->nn->lnode->node == np)
- /*orphan the light node*/
- np->nn->lnode->node = NULL;
- else
- /*remove a reference to this node from the list of proxies*/
- lnode_remove_proxy(np->nn->lnode, np);
-
- /*Remove a reference from the lnode*/
- lnode_ref_remove(np->nn->lnode);
-
- /*Free the netnode and the node itself*/
- free(np->nn);
- free(np);
- }/*node_destroy*/
-/*----------------------------------------------------------------------------*/
+ associated light node*/
+void node_destroy (node_t * np)
+{
+ /*Die if the node does not belong to node cache */
+ assert (!np->nn->ncache_next || !np->nn->ncache_prev);
+
+ /*Destroy the port to the underlying filesystem allocated to the node */
+ if (np->nn->port != MACH_PORT_NULL)
+ PORT_DEALLOC (np->nn->port);
+
+ /*If there are translators to kill */
+ if (np->nn->lnode->dir && np->nn->trans)
+ {
+ /*kill all translators on the underlying nodes */
+ node_kill_translators (np);
+ }
+
+ /*Lock the lnode corresponding to the current node */
+ mutex_lock (&np->nn->lnode->lock);
+
+ /*If the node to be destroyed is a real netfs node */
+ if (np->nn->lnode->node == np)
+ /*orphan the light node */
+ np->nn->lnode->node = NULL;
+ else
+ /*remove a reference to this node from the list of proxies */
+ lnode_remove_proxy (np->nn->lnode, np);
+
+ /*Remove a reference from the lnode */
+ lnode_ref_remove (np->nn->lnode);
+
+ /*Free the netnode and the node itself */
+ free (np->nn);
+ free (np);
+} /*node_destroy */
+
+/*---------------------------------------------------------------------------*/
/*Creates the root node and the corresponding lnode*/
-error_t
-node_create_root
- (
- node_t ** root_node /*store the result here*/
- )
- {
- /*Try to create a new lnode*/
- lnode_t * lnode;
- error_t err = lnode_create(NULL, &lnode);
-
- /*Stop, if the creation failed*/
- if(err)
- return err;
-
- /*Try to derive the node corresponding to `lnode`*/
- node_t * node;
- err = node_create(lnode, &node);
-
- /*If the operation failed*/
- if(err)
- {
- /*destroy the created lnode*/
- lnode_destroy(lnode);
-
- /*stop*/
- return err;
- }
-
- /*Release the lock on the lnode*/
- mutex_unlock(&lnode->lock);
-
- /*Store the result in the parameter*/
- *root_node = node;
-
- /*Return the result*/
- return err;
- }/*node_create_root*/
-/*----------------------------------------------------------------------------*/
+error_t node_create_root (node_t ** root_node)
+{
+ /*Try to create a new lnode */
+ lnode_t *lnode;
+ error_t err = lnode_create (NULL, &lnode);
+
+ /*Stop, if the creation failed */
+ if (err)
+ return err;
+
+ /*Try to derive the node corresponding to `lnode` */
+ node_t *node;
+ err = node_create (lnode, &node);
+
+ /*If the operation failed */
+ if (err)
+ {
+ /*destroy the created lnode */
+ lnode_destroy (lnode);
+
+ /*stop */
+ return err;
+ }
+
+ /*Release the lock on the lnode */
+ mutex_unlock (&lnode->lock);
+
+ /*Store the result in the parameter */
+ *root_node = node;
+
+ /*Return the result */
+ return err;
+} /*node_create_root */
+
+/*---------------------------------------------------------------------------*/
/*Initializes the port to the underlying filesystem for the root node*/
-error_t
-node_init_root
- (
- node_t * node /*the root node*/
- )
+error_t node_init_root (node_t * node /*the root node */
+ )
+{
+ error_t err = 0;
+
+ /*Acquire a lock for operations on the underlying filesystem */
+ mutex_lock (&ulfs_lock);
+
+ /*Open the port to the directory specified in `dir` */
+ node->nn->port = file_name_lookup (dir, O_READ | O_DIRECTORY, 0);
+
+ /*If the directory could not be opened */
+ if (node->nn->port == MACH_PORT_NULL)
+ {
+ /*set the error code accordingly */
+ err = errno;
+ LOG_MSG ("node_init_root: Could not open the port for %s.", dir);
+
+ /*release the lock and stop */
+ mutex_unlock (&ulfs_lock);
+ return err;
+ }
+
+ LOG_MSG ("node_init_root: Port for %s opened successfully.", dir);
+ LOG_MSG ("\tPort: 0x%lX", (unsigned long) node->nn->port);
+
+ /*Stat the root node */
+ err = io_stat (node->nn->port, &node->nn_stat);
+ if (err)
+ {
+ /*deallocate the port */
+ PORT_DEALLOC (node->nn->port);
+
+ LOG_MSG ("node_init_root: Could not stat the root node.");
+
+ /*unlock the mutex and exit */
+ mutex_unlock (&ulfs_lock);
+ return err;
+ }
+
+ /*Set the path to the corresponding lnode to `dir` */
+ node->nn->lnode->path = strdup (dir);
+ if (!node->nn->lnode->path)
+ {
+ /*deallocate the port */
+ PORT_DEALLOC (node->nn->port);
+
+ /*unlock the mutex */
+ mutex_unlock (&ulfs_lock);
+
+ LOG_MSG ("node_init_root: Could not strdup the directory.");
+ return ENOMEM;
+ }
+
+ /*The current position in dir */
+ char *p = dir + strlen (dir);
+
+ /*Go through the path from end to beginning */
+ for (; p >= dir; --p)
+ {
+ /*If the current character is a '/' */
+ if (*p == '/')
{
- error_t err = 0;
-
- /*Acquire a lock for operations on the underlying filesystem*/
- mutex_lock(&ulfs_lock);
-
- /*Open the port to the directory specified in `dir`*/
- node->nn->port = file_name_lookup(dir, O_READ | O_DIRECTORY, 0);
-
- /*If the directory could not be opened*/
- if(node->nn->port == MACH_PORT_NULL)
- {
- /*set the error code accordingly*/
- err = errno;
- LOG_MSG("node_init_root: Could not open the port for %s.", dir);
-
- /*release the lock and stop*/
- mutex_unlock(&ulfs_lock);
- return err;
- }
-
- LOG_MSG("node_init_root: Port for %s opened successfully.", dir);
- LOG_MSG("\tPort: 0x%lX", (unsigned long)node->nn->port);
-
- /*Stat the root node*/
- err = io_stat(node->nn->port, &node->nn_stat);
- if(err)
- {
- /*deallocate the port*/
- PORT_DEALLOC(node->nn->port);
-
- LOG_MSG("node_init_root: Could not stat the root node.");
-
- /*unlock the mutex and exit*/
- mutex_unlock(&ulfs_lock);
- return err;
- }
-
- /*Set the path to the corresponding lnode to `dir`*/
- node->nn->lnode->path = strdup(dir);
- if(!node->nn->lnode->path)
- {
- /*deallocate the port*/
- PORT_DEALLOC(node->nn->port);
-
- /*unlock the mutex*/
- mutex_unlock(&ulfs_lock);
-
- LOG_MSG("node_init_root: Could not strdup the directory.");
- return ENOMEM;
- }
-
- /*The current position in dir*/
- char * p = dir + strlen(dir);
-
- /*Go through the path from end to beginning*/
- for(; p >= dir; --p)
- {
- /*If the current character is a '/'*/
- if(*p == '/')
- {
- /*If p is not the first character*/
- if(p > dir)
- {
- /*if this slash is escaped, skip it*/
- if(*(p - 1) == '\\')
- continue;
- }
-
- /*advance the pointer to the first character after the slash*/
- ++p;
-
- /*stop*/
- break;
- }
- }
-
- LOG_MSG("node_init_root: The name of root node is %s.", p);
-
- /*Set the name of the lnode to the last element in the path to dir*/
- node->nn->lnode->name = strdup(p);
- /*If the name of the node could not be duplicated*/
- if(!node->nn->lnode->name)
- {
- /*free the name of the path to the node and deallocate teh port*/
- free(node->nn->lnode->path);
- PORT_DEALLOC(node->nn->port);
-
- /*unlock the mutex*/
- mutex_unlock(&ulfs_lock);
-
- LOG_MSG("node_init_root: Could not strdup the name of the root node.");
- return ENOMEM;
- }
-
- /*Compute the length of the name of the root node*/
- node->nn->lnode->name_len = strlen(p);
-
- /*Release the lock for operations on the undelying filesystem*/
- mutex_unlock(&ulfs_lock);
-
- /*Return the result of operations*/
- return err;
- }/*node_init_root*/
-/*----------------------------------------------------------------------------*/
+ /*If p is not the first character */
+ if (p > dir)
+ {
+ /*if this slash is escaped, skip it */
+ if (*(p - 1) == '\\')
+ continue;
+ }
+
+ /*advance the pointer to the first character after the slash */
+ ++p;
+
+ /*stop */
+ break;
+ }
+ }
+
+ LOG_MSG ("node_init_root: The name of root node is %s.", p);
+
+ /*Set the name of the lnode to the last element in the path to dir */
+ node->nn->lnode->name = strdup (p);
+ /*If the name of the node could not be duplicated */
+ if (!node->nn->lnode->name)
+ {
+ /*free the name of the path to the node and deallocate teh port */
+ free (node->nn->lnode->path);
+ PORT_DEALLOC (node->nn->port);
+
+ /*unlock the mutex */
+ mutex_unlock (&ulfs_lock);
+
+ LOG_MSG ("node_init_root: Could not strdup the name of the root node.");
+ return ENOMEM;
+ }
+
+ /*Compute the length of the name of the root node */
+ node->nn->lnode->name_len = strlen (p);
+
+ /*Release the lock for operations on the undelying filesystem */
+ mutex_unlock (&ulfs_lock);
+
+ /*Return the result of operations */
+ return err;
+} /*node_init_root */
+
+/*---------------------------------------------------------------------------*/
/*Frees a list of dirents*/
-void
-node_entries_free
- (
- node_dirent_t * dirents /*free this*/
- )
- {
- /*The current and the next elements*/
- node_dirent_t * dirent, * dirent_next;
-
- /*Go through all elements of the list*/
- for(dirent = dirents; dirent; dirent = dirent_next)
- {
- /*store the next element*/
- dirent_next = dirent->next;
-
- /*free the dirent stored in the current element of the list*/
- free(dirent->dirent);
-
- /*free the current element*/
- free(dirent);
- }
- }/*node_entries_free*/
-/*----------------------------------------------------------------------------*/
+void node_entries_free (node_dirent_t * dirents)
+{
+ /*The current and the next elements */
+ node_dirent_t *dirent, *dirent_next;
+
+ /*Go through all elements of the list */
+ for (dirent = dirents; dirent; dirent = dirent_next)
+ {
+ /*store the next element */
+ dirent_next = dirent->next;
+
+ /*free the dirent stored in the current element of the list */
+ free (dirent->dirent);
+
+ /*free the current element */
+ free (dirent);
+ }
+} /*node_entries_free */
+
+/*---------------------------------------------------------------------------*/
/*Reads the directory entries from `node`, which must be locked*/
-error_t
-node_entries_get
- (
- node_t * node,
- node_dirent_t ** dirents /*store the result here*/
- )
+error_t node_entries_get (node_t * node, node_dirent_t ** dirents)
+{
+ error_t err = 0;
+
+ /*The list of dirents */
+ struct dirent **dirent_list, **dirent;
+
+ /*The head of the list of dirents */
+ node_dirent_t *node_dirent_list = NULL;
+
+ /*The size of the array of pointers to dirent */
+ size_t dirent_data_size;
+
+ /*The array of dirents */
+ char *dirent_data;
+
+ /*Obtain the directory entries for the given node */
+ err = dir_entries_get
+ (node->nn->port, &dirent_data, &dirent_data_size, &dirent_list);
+ if (err)
+ {
+ return err;
+ }
+
+ /*The new entry in the list */
+ node_dirent_t *node_dirent_new;
+
+ /*The new dirent */
+ struct dirent *dirent_new;
+
+ /*LOG_MSG("node_entries_get: Getting entries for %p", node); */
+
+ /*The name of the current dirent */
+ char *name;
+
+ /*The length of the current name */
+ size_t name_len;
+
+ /*The size of the current dirent */
+ size_t size;
+
+ /*Go through all elements of the list of pointers to dirent */
+ for (dirent = dirent_list; *dirent; ++dirent)
+ {
+ /*obtain the name of the current dirent */
+ name = &((*dirent)->d_name[0]);
+
+ /*If the current dirent is either '.' or '..', skip it */
+ if ((strcmp (name, ".") == 0) || (strcmp (name, "..") == 0))
+ continue;
+
+ /*obtain the length of the current name */
+ name_len = strlen (name);
+
+ /*obtain the length of the current dirent */
+ size = DIRENT_LEN (name_len);
+
+ /*create a new list element */
+ node_dirent_new = malloc (sizeof (node_dirent_t));
+ if (!node_dirent_new)
{
- error_t err = 0;
-
- /*The list of dirents*/
- struct dirent ** dirent_list, **dirent;
-
- /*The head of the list of dirents*/
- node_dirent_t * node_dirent_list = NULL;
-
- /*The size of the array of pointers to dirent*/
- size_t dirent_data_size;
-
- /*The array of dirents*/
- char * dirent_data;
-
- /*Obtain the directory entries for the given node*/
- err = dir_entries_get
- (node->nn->port, &dirent_data, &dirent_data_size, &dirent_list);
- if(err)
- {
- return err;
- }
-
- /*The new entry in the list*/
- node_dirent_t * node_dirent_new;
-
- /*The new dirent*/
- struct dirent * dirent_new;
-
- /*LOG_MSG("node_entries_get: Getting entries for %p", node);*/
-
- /*The name of the current dirent*/
- char * name;
-
- /*The length of the current name*/
- size_t name_len;
-
- /*The size of the current dirent*/
- size_t size;
-
- /*Go through all elements of the list of pointers to dirent*/
- for(dirent = dirent_list; *dirent; ++dirent)
- {
- /*obtain the name of the current dirent*/
- name = &((*dirent)->d_name[0]);
-
- /*If the current dirent is either '.' or '..', skip it*/
- if((strcmp(name, ".") == 0) || (strcmp(name, "..") == 0))
- continue;
-
- /*obtain the length of the current name*/
- name_len = strlen(name);
-
- /*obtain the length of the current dirent*/
- size = DIRENT_LEN(name_len);
-
- /*create a new list element*/
- node_dirent_new = malloc(sizeof(node_dirent_t));
- if(!node_dirent_new)
- {
- err = ENOMEM;
- break;
- }
-
- /*create a new dirent*/
- dirent_new = malloc(size);
- if(!dirent_new)
- {
- free(node_dirent_new);
- err = ENOMEM;
- break;
- }
-
- /*fill the dirent with information*/
- dirent_new->d_ino = (*dirent)->d_ino;
- dirent_new->d_type = (*dirent)->d_type;
- dirent_new->d_reclen = size;
- strcpy((char *)dirent_new + DIRENT_NAME_OFFS, name);
-
- /*add the dirent to the list*/
- node_dirent_new->dirent = dirent_new;
- node_dirent_new->next = node_dirent_list;
- node_dirent_list = node_dirent_new;
- }
-
- /*If something went wrong in the loop*/
- if(err)
- /*free the list of dirents*/
- node_entries_free(node_dirent_list);
- else
- /*store the list of dirents in the second parameter*/
- *dirents = node_dirent_list;
-
- /*Free the list of pointers to dirent*/
- free(dirent_list);
-
- /*Free the results of listing the dirents*/
- munmap(dirent_data, dirent_data_size);
-
- /*Return the result of operations*/
- return err;
- }/*node_entries_get*/
-/*----------------------------------------------------------------------------*/
-/*Makes sure that all ports to the underlying filesystem of `node` are up to
- date*/
-error_t
-node_update
- (
- node_t * node
- )
+ err = ENOMEM;
+ break;
+ }
+
+ /*create a new dirent */
+ dirent_new = malloc (size);
+ if (!dirent_new)
{
- error_t err = 0;
-
- /*The full path to this node*/
- char * path;
-
- /*Stat information for `node`*/
- io_statbuf_t stat;
-
- /*The port to the file corresponding to `node`*/
- file_t port;
-
- /*If the specified node is the root node or if it must not be updated*/
- if(NODE_IS_ROOT(node) || (node->nn->flags & FLAG_NODE_ULFS_FIXED))
- /*do nothing*/
- return err; /*return 0; actually*/
-
- /*Gain exclusive access to the root node of the filesystem*/
- mutex_lock(&netfs_root_node->lock);
-
- /*Construct the full path to `node`*/
- err = lnode_path_construct(node->nn->lnode, &path);
- if(err)
- {
- mutex_unlock(&netfs_root_node->lock);
- return err;
- }
-
- /*Deallocate `node`'s port to the underlying filesystem*/
- if(node->nn->port)
- PORT_DEALLOC(node->nn->port);
-
- /*Try to lookup the file for `node` in its untranslated version*/
- err = file_lookup
- (
- netfs_root_node->nn->port, path, O_READ | O_NOTRANS, O_NOTRANS,
- 0, &port, &stat
- );
- if(err)
- {
- node->nn->port = MACH_PORT_NULL;
- err = 0; /*failure (?)*/
- return err;
- }
-
- /*If the node looked up is actually the root node of the proxy filesystem*/
- if
- (
- (stat.st_ino == underlying_node_stat.st_ino)
- && (stat.st_fsid == underlying_node_stat.st_fsid)
- )
- /*set `err` accordingly*/
- err = ELOOP;
- else
- {
- /*deallocate the obtained port*/
- PORT_DEALLOC(port);
-
- /*obtain the translated version of the required node*/
- err = file_lookup
- (netfs_root_node->nn->port, path, O_READ, 0, 0, &port, &stat);
- }
-
- /*If there have been errors*/
- if(err)
- /*reset the port*/
- port = MACH_PORT_NULL;
-
- /*Store the port in the node*/
- node->nn->port = port;
-
- /*Remove the flag about the invalidity of the current node and set the
- flag that the node is up-to-date*/
- node->nn->flags &= ~FLAG_NODE_INVALIDATE;
- node->nn->flags |= FLAG_NODE_ULFS_UPTODATE;
-
- /*Release the lock on the root node of proxy filesystem*/
- mutex_unlock(&netfs_root_node->lock);
-
- /*Return the result of operations*/
- return err;
- }/*node_update*/
-/*----------------------------------------------------------------------------*/
+ free (node_dirent_new);
+ err = ENOMEM;
+ break;
+ }
+
+ /*fill the dirent with information */
+ dirent_new->d_ino = (*dirent)->d_ino;
+ dirent_new->d_type = (*dirent)->d_type;
+ dirent_new->d_reclen = size;
+ strcpy ((char *) dirent_new + DIRENT_NAME_OFFS, name);
+
+ /*add the dirent to the list */
+ node_dirent_new->dirent = dirent_new;
+ node_dirent_new->next = node_dirent_list;
+ node_dirent_list = node_dirent_new;
+ }
+
+ /*If something went wrong in the loop */
+ if (err)
+ /*free the list of dirents */
+ node_entries_free (node_dirent_list);
+ else
+ /*store the list of dirents in the second parameter */
+ *dirents = node_dirent_list;
+
+ /*Free the list of pointers to dirent */
+ free (dirent_list);
+
+ /*Free the results of listing the dirents */
+ munmap (dirent_data, dirent_data_size);
+
+ /*Return the result of operations */
+ return err;
+} /*node_entries_get */
+
+/*---------------------------------------------------------------------------*/
+/*Makes sure that all ports to the underlying filesystem of `node` are
+ up to date*/
+error_t node_update (node_t * node)
+{
+ error_t err = 0;
+
+ /*The full path to this node */
+ char *path;
+
+ /*Stat information for `node` */
+ io_statbuf_t stat;
+
+ /*The port to the file corresponding to `node` */
+ file_t port;
+
+ /*If the specified node is the root node or if it must not be updated */
+ if (NODE_IS_ROOT (node) || (node->nn->flags & FLAG_NODE_ULFS_FIXED))
+ /*do nothing */
+ return err; /*return 0; actually */
+
+ /*Gain exclusive access to the root node of the filesystem */
+ mutex_lock (&netfs_root_node->lock);
+
+ /*Construct the full path to `node` */
+ err = lnode_path_construct (node->nn->lnode, &path);
+ if (err)
+ {
+ mutex_unlock (&netfs_root_node->lock);
+ return err;
+ }
+
+ /*Deallocate `node`'s port to the underlying filesystem */
+ if (node->nn->port)
+ PORT_DEALLOC (node->nn->port);
+
+ /*Try to lookup the file for `node` in its untranslated version */
+ err = file_lookup
+ (netfs_root_node->nn->port, path, O_READ | O_NOTRANS, O_NOTRANS,
+ 0, &port, &stat);
+ if (err)
+ {
+ node->nn->port = MACH_PORT_NULL;
+ err = 0; /*failure (?) */
+ return err;
+ }
+
+ /*If the node looked up is actually the root node of the proxy filesystem */
+ if ((stat.st_ino == underlying_node_stat.st_ino)
+ && (stat.st_fsid == underlying_node_stat.st_fsid))
+ /*set `err` accordingly */
+ err = ELOOP;
+ else
+ {
+ /*deallocate the obtained port */
+ PORT_DEALLOC (port);
+
+ /*obtain the translated version of the required node */
+ err = file_lookup
+ (netfs_root_node->nn->port, path, O_READ, 0, 0, &port, &stat);
+ }
+
+ /*If there have been errors */
+ if (err)
+ /*reset the port */
+ port = MACH_PORT_NULL;
+
+ /*Store the port in the node */
+ node->nn->port = port;
+
+ /*Remove the flag about the invalidity of the current node and set the
+ flag that the node is up-to-date */
+ node->nn->flags &= ~FLAG_NODE_INVALIDATE;
+ node->nn->flags |= FLAG_NODE_ULFS_UPTODATE;
+
+ /*Release the lock on the root node of proxy filesystem */
+ mutex_unlock (&netfs_root_node->lock);
+
+ /*Return the result of operations */
+ return err;
+} /*node_update */
+
+/*---------------------------------------------------------------------------*/
/*Computes the size of the given directory*/
-error_t
-node_get_size
- (
- node_t * dir,
- OFFSET_T * off
- )
- {
- error_t err = 0;
-
- /*The final size*/
- size_t size = 0;
-
- /*The number of directory entries*/
- /*int count = 0;*/
-
- /*The the node in the directory entries list from which we start counting*/
- /*node_dirent_t * dirent_start = NULL;*/
-
- /*The currently analyzed dirent*/
- node_dirent_t * dirent_current = NULL;
-
- /*The pointer to the beginning of the list of dirents*/
- node_dirent_t * dirent_list = NULL;
-
- /*The first entry we have to analyze*/
- /*int first_entry = 2;*/
-
- /*Takes into consideration the name of the current dirent*/
- void
- bump_size
- (
- const char * name
- )
- {
- /*Increment the current size by the size of the current dirent*/
- size += DIRENT_LEN(strlen(name));
-
- /*Count the current dirent*/
- /*++count;*/
- }/*bump_size*/
-
- /*Obtain the list of entries in the current directory*/
- err = node_entries_get(dir, &dirent_list);
- if(err)
- return err;
-
- /*Obtain the pointer to the dirent which has the number first_entry*/
- /*Actually, the first element of the list*/
- /*This code is included in unionfs, but it's completely useless here*/
- /*for
- (
- dirent_start = dirent_list, count = 2;
- dirent_start && count < first_entry;
- dirent_start = dirent_start->next, ++count
- );*/
-
- /*Reset the count*/
- /*count = 0;*/
-
- /*Make space for '.' and '..' entries*/
- /*This code is included in unionfs, but it's completely useless here*/
- /*if(first_entry == 0)
- bump_size(".");
- if(first_entry <= 1)
- bump_size("..");*/
-
- /*See how much space is required for the node*/
- for
- (
- dirent_current = dirent_list/*dirent_start*/; dirent_current;
- dirent_current = dirent_current->next
- )
- bump_size(dirent_current->dirent->d_name);
-
- /*Free the list of dirents*/
- node_entries_free(dirent_list);
-
- /*Return the size*/
- *off = size;
- return 0;
- }/*node_get_size*/
-/*----------------------------------------------------------------------------*/
+error_t node_get_size (node_t * dir, OFFSET_T * off)
+{
+ error_t err = 0;
+
+ /*The final size */
+ size_t size = 0;
+
+ /*The number of directory entries */
+ /*int count = 0; */
+
+ /*The the node in the directory entries list from which we start counting */
+ /*node_dirent_t * dirent_start = NULL; */
+
+ /*The currently analyzed dirent */
+ node_dirent_t *dirent_current = NULL;
+
+ /*The pointer to the beginning of the list of dirents */
+ node_dirent_t *dirent_list = NULL;
+
+ /*The first entry we have to analyze */
+ /*int first_entry = 2; */
+
+ /*Takes into consideration the name of the current dirent */
+ void bump_size (const char *name)
+ {
+ /*Increment the current size by the size of the current dirent */
+ size += DIRENT_LEN (strlen (name));
+
+ /*Count the current dirent */
+ /*++count; */
+ } /*bump_size */
+
+ /*Obtain the list of entries in the current directory */
+ err = node_entries_get (dir, &dirent_list);
+ if (err)
+ return err;
+
+ /*Obtain the pointer to the dirent which has the number first_entry */
+ /*Actually, the first element of the list */
+ /*This code is included in unionfs, but it's completely useless here */
+ /*for
+ (
+ dirent_start = dirent_list, count = 2;
+ dirent_start && count < first_entry;
+ dirent_start = dirent_start->next, ++count
+ ); */
+
+ /*Reset the count */
+ /*count = 0; */
+
+ /*Make space for '.' and '..' entries */
+ /*This code is included in unionfs, but it's completely useless here */
+ /*if(first_entry == 0)
+ bump_size(".");
+ if(first_entry <= 1)
+ bump_size(".."); */
+
+ /*See how much space is required for the node */
+ for (dirent_current = dirent_list /*dirent_start */ ; dirent_current;
+ dirent_current = dirent_current->next)
+ bump_size (dirent_current->dirent->d_name);
+
+ /*Free the list of dirents */
+ node_entries_free (dirent_list);
+
+ /*Return the size */
+ *off = size;
+ return 0;
+} /*node_get_size */
+
+/*---------------------------------------------------------------------------*/
/*Remove the file called `name` under `dir`*/
-error_t
-node_unlink_file
- (
- node_t * dir,
- char * name
- )
- {
- error_t err = 0;
-
- /*The port to the file which will be unlinked*/
- mach_port_t p;
-
- /*Stat information about the file which will be unlinked*/
- io_statbuf_t stat;
-
- /*If port corresponding to `dir` is invalid*/
- if(dir->nn->port == MACH_PORT_NULL)
- /*stop with an error*/
- return ENOENT; /*FIXME: Is the return value indeed meaningful here?*/
-
- /*Attempt to lookup the specified file*/
- err = file_lookup(dir->nn->port, name, O_NOTRANS, O_NOTRANS, 0, &p, &stat);
- if(err)
- return err;
-
- /*Deallocate the obtained port*/
- PORT_DEALLOC(p);
-
- /*Unlink file `name` under `dir`*/
- err = dir_unlink(dir->nn->port, name);
- if(err)
- return err;
-
- return err;
- }/*node_unlink_file*/
-/*----------------------------------------------------------------------------*/
+error_t node_unlink_file (node_t * dir, char *name)
+{
+ error_t err = 0;
+
+ /*The port to the file which will be unlinked */
+ mach_port_t p;
+
+ /*Stat information about the file which will be unlinked */
+ io_statbuf_t stat;
+
+ /*If port corresponding to `dir` is invalid */
+ if (dir->nn->port == MACH_PORT_NULL)
+ /*stop with an error */
+ return ENOENT; /*FIXME: Is the return value indeed meaningful here? */
+
+ /*Attempt to lookup the specified file */
+ err = file_lookup (dir->nn->port, name, O_NOTRANS, O_NOTRANS, 0, &p, &stat);
+ if (err)
+ return err;
+
+ /*Deallocate the obtained port */
+ PORT_DEALLOC (p);
+
+ /*Unlink file `name` under `dir` */
+ err = dir_unlink (dir->nn->port, name);
+ if (err)
+ return err;
+
+ return err;
+} /*node_unlink_file */
+
+/*---------------------------------------------------------------------------*/
/*Sets the given translators on the specified node*/
-error_t
-node_set_translators
- (
- struct protid * diruser,
- node_t * np,
- char * trans, /*set these on `node`*/
- size_t ntrans,
- int flags,
- mach_port_t * port
- )
- {
- error_t err;
- mach_port_t p;
-
- /*An unauthenticated port to the directory containing `np`*/
- mach_port_t unauth_dir;
-
- /*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 pointer to the name of the translator we are going to start now*/
- char * str;
-
- /*The index of the translator in the list of strings*/
- size_t idx;
-
- /*The control port for the active translator*/
- mach_port_t active_control;
-
- /*A new element in the list of control ports*/
- port_el_t * p_el;
-
- /*A copy of the user information, supplied in `user`*/
- struct iouser * user;
-
- /*A protid for the supplied node*/
- struct protid * newpi;
-
- /*Identity information about the current process (for fsys_getroot)*/
- uid_t * uids;
- size_t nuids;
-
- gid_t * gids;
- size_t ngids;
-
- /*The retry information returned by fsys_getroot*/
- string_t retry_name;
- mach_port_t retry_port;
-
- /*Try to get the number of effective UIDs*/
- nuids = geteuids(0, 0);
- if(nuids < 0)
- return EPERM;
-
- /*Allocate some memory for the UIDs on the stack*/
- uids = alloca(nuids * sizeof(uid_t));
-
- /*Fetch the UIDs themselves*/
- nuids = geteuids(nuids, uids);
- if(nuids < 0)
- return EPERM;
-
- /*Try to get the number of effective GIDs*/
- ngids = getgroups(0, 0);
- if(ngids < 0)
- return EPERM;
-
- /*Allocate some memory for the GIDs on the stack*/
- gids = alloca(ngids * sizeof(gid_t));
-
- /*Fetch the GIDs themselves*/
- ngids = getgroups(ngids, gids);
- if(ngids < 0)
- return EPERM;
-
- /*Opens the port on which to set the new translator*/
- error_t
- open_port
- (
- int flags,
- mach_port_t * underlying,
- mach_msg_type_name_t * underlying_type,
- task_t task,
- void * cookie /*if 0, open the port to the node; otherwise get the port
- of the topmost translator on the node*/
- )
- {
- /*No errors at first*/
- err = 0;
-
- /*If a port to the node is wanted*/
- if((int)cookie == 0)
- {
- /*check, whether the user has the permissions to open this node*/
- err = check_open_permissions(diruser->user, &np->nn_stat, flags);
- if(err)
- return err;
-
- /*duplicate the supplied user*/
- err = iohelp_dup_iouser(&user, diruser->user);
- if(err)
- return err;
-
- /*create a protid for this node*/
- newpi = netfs_make_protid
- (netfs_make_peropen(np, flags, diruser->po), user);
- if(!newpi)
- {
- iohelp_free_iouser(user);
- return errno;
- }
- LOG_MSG("node_set_translators.open_port: PASSED");
-
- /*obtain the resulting port right and set its type appropriately*/
- *underlying = p = ports_get_send_right(newpi);
- *underlying_type = MACH_MSG_TYPE_COPY_SEND;
-
- LOG_MSG("node_set_translators.open_port: %ld", (long)*underlying);
-
- /*drop our reference to the port*/
- ports_port_deref(newpi);
- }
- /*We are not setting the first translator, this one is not required
- to sit on the node itself*/
- else
- /*in the previous iteration of the loop fsys_getroot gave us the port
- to the toplevel translator on the current node, namely `p`; this is
- what is required of us now*/
- {
- *underlying = p;
- *underlying_type = MACH_MSG_TYPE_COPY_SEND;
- }
-
- /*Return the result of operations (everything should be okay here)*/
- return err;
- }/*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 the unauthenticated port to the directory*/
- err = io_restrict_auth(diruser->po->np->nn->port, &unauth_dir, 0, 0, 0, 0);
- if(err)
- return err;
-
- /*While all translators have not been looked through*/
- for(str = trans, idx = 0; idx < ntrans; ++idx)
- {
- /*obtain a copy (possibly extended) of the name*/
- ext = put_in_hurd(str);
- if(!ext)
- return ENOMEM;
-
- /*move str to the next translator in the list*/
- str += strlen(str) + 1;
-
- /*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, (void *)((idx == 0) ? 0 : 1), 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
- );
- /*close the port we have just opened*/
- PORT_DEALLOC(p);
-
- /*stop, if the attempt to set the translator failed*/
- if(err)
- return err;
-
- /*allocate a new element for the current control port*/
- p_el = malloc(sizeof(struct port_el));
- if(!p_el)
- return ENOMEM;
-
- /*store the current control port in the new cell*/
- p_el->p = active_control;
-
- /*add the new control port to the list*/
- p_el->next = np->nn->cntl_ports;
- np->nn->cntl_ports = p_el;
-
- /*obtain the port to the top of the newly-set translator*/
- err = fsys_getroot
- (
- active_control, unauth_dir, MACH_MSG_TYPE_COPY_SEND,
- uids, nuids, gids, ngids,
- flags, &retry_port, retry_name, &p
- );
- if(err)
- return err;
- }
-
- /*Return the port*/
- *port = p;
-
- /*Everything is OK here*/
- return 0;
- }/*node_set_translators*/
-/*----------------------------------------------------------------------------*/
-/*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`.*/
-/*This is the code for the wrong version of nsmux.*/
-error_t
-node_kill_translator
- (
- node_t * dir,
- node_t * node
- )
- {
- error_t err = 0;
-
- /*Lookup the file*/
- mach_port_t p =
- file_name_lookup_under
- (dir->nn->port, node->nn->lnode->name, /*O_NOTRANS*/0, 0);
- if(!p)
- return errno;
-
- /*Remove a translator from the node*/
-/*This code was taken from the code of settrans and works only when there is
- only one translator in the stack (not including the ext2fs, for example).
- For this code to work the O_NOTRANS is required in the lookup.*/
- /*error_t err = file_set_translator
- (
- p, FS_TRANS_SET, FS_TRANS_SET, 0, NULL, 0,
- MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND
- );*/
-
- /*Obtain the control port of the filesystem to which file `name` belongs*/
- fsys_t fsys;
- err = file_getcontrol(p, &fsys);
-
- char * argz = NULL;
- size_t argz_len = 0;
- err = file_get_fs_options(p, &argz, &argz_len);
-
- /*Close the port*/
- PORT_DEALLOC(p);
-
- /*If the control port of the filesystem could not be fetched, stop*/
- if(err)
- return err;
-
- /*Ask the translator to go away*/
- err = fsys_goaway(fsys, 0);
-
- /*If the translator is busy*/
- if(err)
- /*force the translator to go away*/
- err = fsys_goaway(fsys, FSYS_GOAWAY_FORCE);
-
- /*Deallocate the control port*/
- PORT_DEALLOC(fsys);
-
- /*Return the result of removing the translator*/
+error_t node_set_translators (struct protid * diruser, node_t * np,
+ char *trans, /*set these on `node` */
+ size_t ntrans, int flags, mach_port_t * port)
+{
+ error_t err;
+ mach_port_t p;
+
+ /*An unauthenticated port to the directory containing `np` */
+ mach_port_t unauth_dir;
+
+ /*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 pointer to the name of the translator we are going to start now */
+ char *str;
+
+ /*The index of the translator in the list of strings */
+ size_t idx;
+
+ /*The control port for the active translator */
+ mach_port_t active_control;
+
+ /*A new element in the list of control ports */
+ port_el_t *p_el;
+
+ /*A copy of the user information, supplied in `user` */
+ struct iouser *user;
+
+ /*A protid for the supplied node */
+ struct protid *newpi;
+
+ /*Identity information about the current process (for fsys_getroot) */
+ uid_t *uids;
+ size_t nuids;
+
+ gid_t *gids;
+ size_t ngids;
+
+ /*The retry information returned by fsys_getroot */
+ string_t retry_name;
+ mach_port_t retry_port;
+
+ /*Try to get the number of effective UIDs */
+ nuids = geteuids (0, 0);
+ if (nuids < 0)
+ return EPERM;
+
+ /*Allocate some memory for the UIDs on the stack */
+ uids = alloca (nuids * sizeof (uid_t));
+
+ /*Fetch the UIDs themselves */
+ nuids = geteuids (nuids, uids);
+ if (nuids < 0)
+ return EPERM;
+
+ /*Try to get the number of effective GIDs */
+ ngids = getgroups (0, 0);
+ if (ngids < 0)
+ return EPERM;
+
+ /*Allocate some memory for the GIDs on the stack */
+ gids = alloca (ngids * sizeof (gid_t));
+
+ /*Fetch the GIDs themselves */
+ ngids = getgroups (ngids, gids);
+ if (ngids < 0)
+ return EPERM;
+
+ /*Opens the port on which to set the new translator */
+ error_t open_port (int flags, mach_port_t * underlying,
+ mach_msg_type_name_t * underlying_type, task_t task,
+ void *cookie /*if 0, open the port to the node;
+ otherwise get the port of the
+ topmost translator on the node */
+ )
+ {
+ /*No errors at first */
+ err = 0;
+
+ /*If a port to the node is wanted */
+ if ((int) cookie == 0)
+ {
+ /*check, whether the user has the permissions to open this node */
+ err = check_open_permissions (diruser->user, &np->nn_stat, flags);
+ if (err)
+ return err;
+
+ /*duplicate the supplied user */
+ err = iohelp_dup_iouser (&user, diruser->user);
+ if (err)
+ return err;
+
+ /*create a protid for this node */
+ newpi = netfs_make_protid
+ (netfs_make_peropen (np, flags, diruser->po), user);
+ if (!newpi)
+ {
+ iohelp_free_iouser (user);
+ return errno;
+ }
+ LOG_MSG ("node_set_translators.open_port: PASSED");
+
+ /*obtain the resulting port right and set its type appropriately */
+ *underlying = p = ports_get_send_right (newpi);
+ *underlying_type = MACH_MSG_TYPE_COPY_SEND;
+
+ LOG_MSG ("node_set_translators.open_port: %ld", (long) *underlying);
+
+ /*drop our reference to the port */
+ ports_port_deref (newpi);
+ }
+ /*We are not setting the first translator, this one is not required
+ to sit on the node itself */
+ else
+ /*in the previous iteration of the loop fsys_getroot gave us the port
+ to the toplevel translator on the current node, namely `p`; this is
+ what is required of us now */
+ {
+ *underlying = p;
+ *underlying_type = MACH_MSG_TYPE_COPY_SEND;
+ }
+
+ /*Return the result of operations (everything should be okay here) */
+ return err;
+ } /*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 the unauthenticated port to the directory */
+ err = io_restrict_auth (diruser->po->np->nn->port, &unauth_dir, 0, 0, 0, 0);
+ if (err)
+ return err;
+
+ /*While all translators have not been looked through */
+ for (str = trans, idx = 0; idx < ntrans; ++idx)
+ {
+ /*obtain a copy (possibly extended) of the name */
+ ext = put_in_hurd (str);
+ if (!ext)
+ return ENOMEM;
+
+ /*move str to the next translator in the list */
+ str += strlen (str) + 1;
+
+ /*TODO: Better argument-parsing? */
+
+ /*obtain the argz version of str */
+ err = argz_create_sep (ext, ' ', &argz, &argz_len);
+ if (err)
return err;
- }/*node_kill_translator*/
-/*----------------------------------------------------------------------------*/
+
+ /*start the translator */
+ err = fshelp_start_translator (open_port, (void *) ((idx == 0) ? 0 : 1),
+ 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);
+ /*close the port we have just opened */
+ PORT_DEALLOC (p);
+
+ /*stop, if the attempt to set the translator failed */
+ if (err)
+ return err;
+
+ /*allocate a new element for the current control port */
+ p_el = malloc (sizeof (struct port_el));
+ if (!p_el)
+ return ENOMEM;
+
+ /*store the current control port in the new cell */
+ p_el->p = active_control;
+
+ /*add the new control port to the list */
+ p_el->next = np->nn->cntl_ports;
+ np->nn->cntl_ports = p_el;
+
+ /*obtain the port to the top of the newly-set translator */
+ err = fsys_getroot
+ (active_control, unauth_dir, MACH_MSG_TYPE_COPY_SEND,
+ uids, nuids, gids, ngids, flags, &retry_port, retry_name, &p);
+ if (err)
+ return err;
+ }
+
+ /*Return the port */
+ *port = p;
+
+ /*Everything is OK here */
+ return 0;
+} /*node_set_translators */
+
+/*---------------------------------------------------------------------------*/
/*Kills all translators on the nodes belonging to the given directory*/
-void
-node_kill_translators
- (
- node_t * node
- )
- {
- /*If the node has no translators*/
- if(node->nn->trans == NULL)
- /*nothing to do*/
- return;
-
- error_t err = 0;
-
- /*The current element in the port list*/
- port_el_t * p_el;
-
- /*While the list of control ports is not empty*/
- for(p_el = node->nn->cntl_ports; p_el; p_el = node->nn->cntl_ports)
- {
- /*kill the current translator*/
- err = fsys_goaway(p_el->p, 0);
-
- /*If the translator says it is busy, force it to go away*/
- if(err == EBUSY)
- err = fsys_goaway(p_el->p, FSYS_GOAWAY_FORCE);
-
- /*move the beginning of the list of control ports forward*/
- node->nn->cntl_ports = p_el->next;
-
- /*destroy the current cell in the list of ports*/
- free(p_el);
- }
- }/*node_kill_translators*/
-/*----------------------------------------------------------------------------*/
+void node_kill_translators (node_t * node)
+{
+ /*If the node has no translators */
+ if (node->nn->trans == NULL)
+ /*nothing to do */
+ return;
+
+ error_t err = 0;
+
+ /*The current element in the port list */
+ port_el_t *p_el;
+
+ /*While the list of control ports is not empty */
+ for (p_el = node->nn->cntl_ports; p_el; p_el = node->nn->cntl_ports)
+ {
+ /*kill the current translator */
+ err = fsys_goaway (p_el->p, 0);
+
+ /*If the translator says it is busy, force it to go away */
+ if (err == EBUSY)
+ err = fsys_goaway (p_el->p, FSYS_GOAWAY_FORCE);
+
+ /*move the beginning of the list of control ports forward */
+ node->nn->cntl_ports = p_el->next;
+
+ /*destroy the current cell in the list of ports */
+ free (p_el);
+ }
+} /*node_kill_translators */
+
+/*---------------------------------------------------------------------------*/
diff --git a/node.h b/node.h
index 99096daf6..0ab636680 100644
--- a/node.h
+++ b/node.h
@@ -1,10 +1,10 @@
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*node.h*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Node management. Also see lnode.h*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*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,212 +22,152 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#ifndef __NODE_H__
#define __NODE_H__
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#include <error.h>
#include <sys/stat.h>
#include <hurd/netfs.h>
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#include "lnode.h"
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Macros--------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Macros-------------------------------------------------------------*/
/*Checks whether the give node is the root of the proxy filesystem*/
#define NODE_IS_ROOT(n) (((n)->nn->lnode->dir) ? (0) : (1))
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Node flags*/
-#define FLAG_NODE_ULFS_FIXED 0x00000001 /*this node should not be updated*/
-#define FLAG_NODE_INVALIDATE 0x00000002 /*this node must be updated*/
-#define FLAG_NODE_ULFS_UPTODATE 0x00000004 /*this node has just been updated*/
-/*----------------------------------------------------------------------------*/
+#define FLAG_NODE_ULFS_FIXED 0x00000001 /*this node should not be updated */
+#define FLAG_NODE_INVALIDATE 0x00000002 /*this node must be updated */
+#define FLAG_NODE_ULFS_UPTODATE 0x00000004 /*this node has just been updated */
+/*---------------------------------------------------------------------------*/
/*The type of offset corresponding to the current platform*/
#ifdef __USE_FILE_OFFSET64
# define OFFSET_T __off64_t
#else
# define OFFSET_T __off_t
#endif /*__USE_FILE_OFFSET64*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Types---------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Types--------------------------------------------------------------*/
/*A list element containing a port*/
struct port_el
- {
- /*the port*/
- mach_port_t p;
-
- /*the next element in the list*/
- struct port_el * next;
- };/*struct port_el*/
-/*----------------------------------------------------------------------------*/
+{
+ /*the port */
+ mach_port_t p;
+
+ /*the next element in the list */
+ struct port_el *next;
+}; /*struct port_el */
+/*---------------------------------------------------------------------------*/
typedef struct port_el port_el_t;
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*The user-defined node for libnetfs*/
struct netnode
- {
- /*the reference to the corresponding light node*/
- lnode_t * lnode;
-
- /*the flags associated with this node*/
- int flags;
-
- /*a port to the underlying filesystem*/
- file_t port;
-
- /*the port to the untranslated version of the node*/
- file_t port_notrans;
-
- /*the malloced set of translators which have to be stacked upon this node
- and upon its children; the corresponding translators will have to decide
- on their own whether to accept directories or not*/
- char * trans;
-
- /*the number of translators listed in `translators`*/
- size_t ntrans;
-
- /*the length of the list of translators (in bytes)*/
- size_t translen;
-
- /*the list of control ports to the translators being set on this node*/
- port_el_t * cntl_ports;
-
- /*the neighbouring entries in the cache*/
- node_t * ncache_prev, * ncache_next;
- };/*struct netnode*/
-/*----------------------------------------------------------------------------*/
+{
+ /*the reference to the corresponding light node */
+ lnode_t *lnode;
+
+ /*the flags associated with this node */
+ int flags;
+
+ /*a port to the underlying filesystem */
+ file_t port;
+
+ /*the port to the untranslated version of the node */
+ file_t port_notrans;
+
+ /*the malloced set of translators which have to be stacked upon this node
+ and upon its children; the corresponding translators will have to decide
+ on their own whether to accept directories or not */
+ char *trans;
+
+ /*the number of translators listed in `translators` */
+ size_t ntrans;
+
+ /*the length of the list of translators (in bytes) */
+ size_t translen;
+
+ /*the list of control ports to the translators being set on this node */
+ port_el_t *cntl_ports;
+
+ /*the neighbouring entries in the cache */
+ node_t *ncache_prev, *ncache_next;
+}; /*struct netnode */
+/*---------------------------------------------------------------------------*/
typedef struct netnode netnode_t;
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*A list element containing directory entry*/
struct node_dirent
- {
- /*the directory entry*/
- struct dirent * dirent;
-
- /*the next element*/
- struct node_dirent * next;
- };/*struct node_dirent*/
-/*----------------------------------------------------------------------------*/
+{
+ /*the directory entry */
+ struct dirent *dirent;
+
+ /*the next element */
+ struct node_dirent *next;
+}; /*struct node_dirent */
+/*---------------------------------------------------------------------------*/
typedef struct node_dirent node_dirent_t;
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Global Variables----------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Global Variables---------------------------------------------------*/
/*The lock protecting the underlying filesystem*/
extern struct mutex ulfs_lock;
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
-/*--------Functions-----------------------------------------------------------*/
+/*--------Functions----------------------------------------------------------*/
/*Derives a new node from `lnode` and adds a reference to `lnode`*/
-error_t
-node_create
- (
- lnode_t * lnode,
- node_t ** node /*store the result here*/
- );
-/*----------------------------------------------------------------------------*/
+error_t node_create (lnode_t * lnode, node_t ** node);
+/*---------------------------------------------------------------------------*/
/*Derives a new proxy from `lnode`*/
-error_t
-node_create_proxy
- (
- lnode_t * lnode,
- node_t ** node /*store the result here*/
- );
-/*----------------------------------------------------------------------------*/
+error_t node_create_proxy (lnode_t * lnode, node_t ** node);
+/*---------------------------------------------------------------------------*/
/*Destroys the specified node and removes a light reference from the
- associated light node*/
-void
-node_destroy
- (
- node_t * np
- );
-/*----------------------------------------------------------------------------*/
+ associated light node*/
+void node_destroy (node_t * np);
+/*---------------------------------------------------------------------------*/
/*Creates the root node and the corresponding lnode*/
-error_t
-node_create_root
- (
- node_t ** root_node /*store the result here*/
- );
-/*----------------------------------------------------------------------------*/
+error_t node_create_root (node_t ** root_node);
+/*---------------------------------------------------------------------------*/
/*Initializes the port to the underlying filesystem for the root node*/
-error_t
-node_init_root
- (
- node_t * node /*the root node*/
- );
-/*----------------------------------------------------------------------------*/
+error_t node_init_root (node_t * node);
+/*---------------------------------------------------------------------------*/
/*Frees a list of dirents*/
-void
-node_entries_free
- (
- node_dirent_t * dirents /*free this*/
- );
-/*----------------------------------------------------------------------------*/
+void node_entries_free (node_dirent_t * dirents);
+/*---------------------------------------------------------------------------*/
/*Reads the directory entries from `node`, which must be locked*/
-error_t
-node_entries_get
- (
- node_t * node,
- node_dirent_t ** dirents /*store the result here*/
- );
-/*----------------------------------------------------------------------------*/
-/*Makes sure that all ports to the underlying filesystem of `node` are up to
- date*/
-error_t
-node_update
- (
- node_t * node
- );
-/*----------------------------------------------------------------------------*/
+error_t node_entries_get (node_t * node, node_dirent_t ** dirents);
+/*---------------------------------------------------------------------------*/
+/*Makes sure that all ports to the underlying filesystem of `node` are
+ up to date*/
+error_t node_update (node_t * node);
+/*---------------------------------------------------------------------------*/
/*Computes the size of the given directory*/
-error_t
-node_get_size
- (
- node_t * dir,
- OFFSET_T * off
- );
-/*----------------------------------------------------------------------------*/
+error_t node_get_size (node_t * dir, OFFSET_T * off);
+/*---------------------------------------------------------------------------*/
/*Remove the file called `name` under `dir`*/
-error_t
-node_unlink_file
- (
- node_t * dir,
- char * name
- );
-/*----------------------------------------------------------------------------*/
-/*Sets the given translators on the specified node and returns the port to
- the topmost one opened as `flags` require*/
-error_t
-node_set_translators
- (
- struct protid * diruser,
- node_t * np,
- char * trans, /*set these on `node`*/
- size_t ntrans,
- int flags,
- mach_port_t * port
- );
-/*----------------------------------------------------------------------------*/
+error_t node_unlink_file (node_t * dir, char *name);
+/*---------------------------------------------------------------------------*/
+/*Sets the given translators on the specified node and returns the
+ port to the topmost one opened as `flags` require*/
+error_t node_set_translators (struct protid *diruser, node_t * np,
+ char *trans, /*set these on `node` */
+ size_t ntrans, int flags, mach_port_t * port);
+/*---------------------------------------------------------------------------*/
/*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_translators
- (
- node_t * 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_translators (node_t * node);
+/*---------------------------------------------------------------------------*/
#endif /*__NODE_H__*/
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 */
+
+/*---------------------------------------------------------------------------*/
diff --git a/nsmux.h b/nsmux.h
index 48b6a5b7b..b4c7f3ff9 100644
--- a/nsmux.h
+++ b/nsmux.h
@@ -1,10 +1,10 @@
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*nsmux.h*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Definitions for 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,10 +22,10 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#ifndef __NSMUX_H__
#define __NSMUX_H__
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#include <stddef.h>
#include <stdlib.h>
#include <cthreads.h>
@@ -37,354 +37,206 @@
#include <sys/time.h>
#include <hurd/ihash.h>
#include <hurd/iohelp.h>
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#include "lib.h"
#include "node.h"
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Macros--------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Macros-------------------------------------------------------------*/
/*The inode number for the root node*/
#define NSMUX_ROOT_INODE 1
-/*----------------------------------------------------------------------------*/
-/*The special flag character for creating proxy nodes*/
-#define LOOKUP_MAGIC_CHAR '\33'
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Bits that are turned off after open*/
#define OPENONLY_STATE_MODES (O_CREAT | O_EXCL | O_NOLINK | O_NOTRANS)
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Global Variables----------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Global Variables---------------------------------------------------*/
/*A mapped time value*/
/*Required for a very fast access to time*/
-extern volatile struct mapped_time_value * maptime;
-/*----------------------------------------------------------------------------*/
+extern volatile struct mapped_time_value *maptime;
+/*---------------------------------------------------------------------------*/
/*A port to the underlying node*/
extern mach_port_t underlying_node;
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*The stat information about the underlying node*/
extern io_statbuf_t underlying_node_stat;
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*The translator callbacks required by netfs_S_dir_lookup*/
fshelp_fetch_root_callback1_t _netfs_translator_callback1;
fshelp_fetch_root_callback2_t _netfs_translator_callback2;
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------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
- );
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_create_file
+ (struct iouser *user,
+ struct node *dir, char *name, mode_t mode, struct node **node);
+/*---------------------------------------------------------------------------*/
/*Returns 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
- );
-/*----------------------------------------------------------------------------*/
+ netfs_check_open_permissions
+ (struct iouser *user, struct node *np, int flags, int newnode);
+/*---------------------------------------------------------------------------*/
/*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
- );
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_utimes
+ (struct iouser *cred,
+ struct node *node, struct timespec *atime, struct timespec *mtime);
+/*---------------------------------------------------------------------------*/
/*Returns the valid access types for file `node` and user `cred`*/
error_t
-netfs_report_access
- (
- struct iouser * cred,
- struct node * np,
- int * types
- );
-/*----------------------------------------------------------------------------*/
+ netfs_report_access (struct iouser *cred, struct node *np, int *types);
+/*---------------------------------------------------------------------------*/
/*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);
+/*---------------------------------------------------------------------------*/
/*Syncs `node` completely to disk*/
-error_t
-netfs_attempt_sync
- (
- struct iouser * cred,
- struct node * node,
- int wait
- );
-/*----------------------------------------------------------------------------*/
+error_t netfs_attempt_sync (struct iouser *cred, struct node *node, int wait);
+/*---------------------------------------------------------------------------*/
/*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
- );
-/*----------------------------------------------------------------------------*/
+ 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);
+/*---------------------------------------------------------------------------*/
/*Looks up `name` under `dir` for `user`*/
error_t
-netfs_attempt_lookup
- (
- struct iouser * user,
- struct node * dir,
- char * name,
- struct node ** node
- );
-/*----------------------------------------------------------------------------*/
-/*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
+ (struct iouser *user, struct node *dir, char *name, struct node **node);
+/*---------------------------------------------------------------------------*/
+/*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);
+/*---------------------------------------------------------------------------*/
/*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
- );
-/*----------------------------------------------------------------------------*/
+ 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);
+/*---------------------------------------------------------------------------*/
/*Deletes `name` in `dir` for `user`*/
error_t
-netfs_attempt_unlink
- (
- struct iouser * user,
- struct node * dir,
- char * name
- );
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_unlink (struct iouser *user, struct node *dir, char *name);
+/*---------------------------------------------------------------------------*/
/*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
- );
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_rename
+ (struct iouser *user,
+ struct node *fromdir,
+ char *fromname, struct node *todir, char *toname, int excl);
+/*---------------------------------------------------------------------------*/
/*Attempts to create a new directory*/
error_t
-netfs_attempt_mkdir
- (
- struct iouser * user,
- struct node * dir,
- char * name,
- mode_t mode
- );
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_mkdir
+ (struct iouser *user, struct node *dir, char *name, mode_t mode);
+/*---------------------------------------------------------------------------*/
/*Attempts to remove directory `name` in `dir` for `user`*/
error_t
-netfs_attempt_rmdir
- (
- struct iouser * user,
- struct node * dir,
- char * name
- );
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_rmdir (struct iouser *user, struct node *dir, char *name);
+/*---------------------------------------------------------------------------*/
/*Attempts to change the owner 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
- );
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_chown
+ (struct iouser *cred, struct node *node, uid_t uid, uid_t gid);
+/*---------------------------------------------------------------------------*/
/*Attempts to change the author of `node` to `author`*/
error_t
-netfs_attempt_chauthor
- (
- struct iouser * cred,
- struct node * node,
- uid_t author
- );
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_chauthor
+ (struct iouser *cred, struct node *node, uid_t author);
+/*---------------------------------------------------------------------------*/
/*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
- );
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_chmod (struct iouser *user, struct node *node, mode_t mode);
+/*---------------------------------------------------------------------------*/
/*Attempts to turn `node` into a symlink targetting `name`*/
error_t
-netfs_attempt_mksymlink
- (
- struct iouser * cred,
- struct node * node,
- char * name
- );
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_mksymlink
+ (struct iouser *cred, struct node *node, char *name);
+/*---------------------------------------------------------------------------*/
/*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
- );
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_mkdev
+ (struct iouser *cred, struct node *node, mode_t type, dev_t indexes);
+/*---------------------------------------------------------------------------*/
/*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
- );
-/*----------------------------------------------------------------------------*/
+ netfs_set_translator
+ (struct iouser *cred, struct node *node, char *argz, size_t arglen);
+/*---------------------------------------------------------------------------*/
/*Attempts to call chflags for `node`*/
error_t
-netfs_attempt_chflags
- (
- struct iouser * cred,
- struct node * node,
- int flags
- );
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_chflags (struct iouser *cred, struct node *node, int flags);
+/*---------------------------------------------------------------------------*/
/*Attempts to set the size of file `node`*/
error_t
-netfs_attempt_set_size
- (
- struct iouser * cred,
- struct node * node,
- loff_t size
- );
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_set_size
+ (struct iouser *cred, struct node *node, loff_t size);
+/*---------------------------------------------------------------------------*/
/*Fetches the filesystem status information*/
error_t
-netfs_attempt_statfs
- (
- struct iouser * cred,
- struct node * node,
- fsys_statfsbuf_t * st
- );
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_statfs
+ (struct iouser *cred, struct node *node, fsys_statfsbuf_t * st);
+/*---------------------------------------------------------------------------*/
/*Syncs the filesystem*/
-error_t
-netfs_attempt_syncfs
- (
- struct iouser * cred,
- int wait
- );
-/*----------------------------------------------------------------------------*/
+error_t netfs_attempt_syncfs (struct iouser *cred, int wait);
+/*---------------------------------------------------------------------------*/
/*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
- );
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_link
+ (struct iouser *user,
+ struct node *dir, struct node *file, char *name, int excl);
+/*---------------------------------------------------------------------------*/
/*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
- );
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_mkfile
+ (struct iouser *user, struct node *dir, mode_t mode, struct node **node);
+/*---------------------------------------------------------------------------*/
/*Reads the contents of symlink `node` into `buf`*/
error_t
-netfs_attempt_readlink
- (
- struct iouser * user,
- struct node * node,
- char * buf
- );
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_readlink (struct iouser *user, struct node *node, char *buf);
+/*---------------------------------------------------------------------------*/
/*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
- );
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_read
+ (struct iouser *cred,
+ struct node *np, loff_t offset, size_t * len, void *data);
+/*---------------------------------------------------------------------------*/
/*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
- );
-/*----------------------------------------------------------------------------*/
+ netfs_attempt_write
+ (struct iouser *cred,
+ struct node *node, loff_t offset, size_t * len, void *data);
+/*---------------------------------------------------------------------------*/
/*Frees all storage associated with the node*/
-void
-netfs_node_norefs
- (
- struct node * np
- );
-/*----------------------------------------------------------------------------*/
+void netfs_node_norefs (struct node *np);
+/*---------------------------------------------------------------------------*/
/*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
- );
-/*----------------------------------------------------------------------------*/
+ netfs_S_file_get_translator_cntl
+ (struct protid *user, mach_port_t * cntl, mach_msg_type_name_t * cntltype);
+/*---------------------------------------------------------------------------*/
#endif /*__NSMUX_H__*/
diff --git a/options.c b/options.c
index 1117766a9..20c9e7b42 100644
--- a/options.c
+++ b/options.c
@@ -1,10 +1,10 @@
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*options.h*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Definitions for parsing the command line switches*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*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,222 +22,206 @@
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 <argp.h>
#include <error.h>
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#include "debug.h"
#include "options.h"
#include "ncache.h"
#include "node.h"
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Macros--------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Macros-------------------------------------------------------------*/
/*Short documentation for argp*/
#define ARGS_DOC "DIR"
-#define DOC "Provides namespace-based translator selection."\
+#define DOC "Provides namespace-based translator selection."\
" You can dynamically obtain the file 'file' translated by translator"\
" 'x' using the syntax: 'file,,x'."
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Forward Declarations------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Forward Declarations-----------------------------------------------*/
/*Argp parser function for the common options*/
static
-error_t
-argp_parse_common_options
- (
- int key,
- char * arg,
- struct argp_state * state
- );
-/*----------------------------------------------------------------------------*/
+ error_t
+ argp_parse_common_options (int key, char *arg, struct argp_state *state);
+/*---------------------------------------------------------------------------*/
/*Argp parser function for the startup options*/
static
-error_t
-argp_parse_startup_options
- (
- int key,
- char * arg,
- struct argp_state * state
- );
-/*----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------*/
-/*--------Global Variables----------------------------------------------------*/
+ error_t
+ argp_parse_startup_options (int key, char *arg, struct argp_state *state);
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/*--------Global Variables---------------------------------------------------*/
/*This variable is set to a non-zero value after the parsing of starup options
is finished*/
/*Whenever the argument parser is later called to modify the
options of the root node will be initialized accordingly directly
by the parser*/
static int parsing_startup_options_finished;
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Argp options common to both the runtime and the startup parser*/
-static const struct argp_option argp_common_options[] =
- {
- /*{OPT_LONG_CACHE_SIZE, OPT_CACHE_SIZE, "SIZE", 0,
- "The maximal number of nodes in the node cache"}*/
- {0}
- };
-/*----------------------------------------------------------------------------*/
+static const struct argp_option argp_common_options[] = {
+ /*{OPT_LONG_CACHE_SIZE, OPT_CACHE_SIZE, "SIZE", 0,
+ "The maximal number of nodes in the node cache"} */
+ {0}
+};
+
+/*---------------------------------------------------------------------------*/
/*Argp options only meaningful for startup parsing*/
-static const struct argp_option argp_startup_options[] =
- {
- {0}
- };
-/*----------------------------------------------------------------------------*/
+static const struct argp_option argp_startup_options[] = {
+ {0}
+};
+
+/*---------------------------------------------------------------------------*/
/*Argp parser for only the common options*/
static const struct argp argp_parser_common_options =
- {argp_common_options, argp_parse_common_options, 0, 0, 0};
-/*----------------------------------------------------------------------------*/
+ { argp_common_options, argp_parse_common_options, 0, 0, 0 };
+/*---------------------------------------------------------------------------*/
/*Argp parser for only the startup options*/
static const struct argp argp_parser_startup_options =
- {argp_startup_options, argp_parse_startup_options, 0, 0, 0};
-/*----------------------------------------------------------------------------*/
+ { argp_startup_options, argp_parse_startup_options, 0, 0, 0 };
+/*---------------------------------------------------------------------------*/
/*The list of children parsers for runtime arguments*/
-static const struct argp_child argp_children_runtime[] =
- {
- {&argp_parser_common_options},
- {&netfs_std_runtime_argp},
- {0}
- };
-/*----------------------------------------------------------------------------*/
+static const struct argp_child argp_children_runtime[] = {
+ {&argp_parser_common_options},
+ {&netfs_std_runtime_argp},
+ {0}
+};
+
+/*---------------------------------------------------------------------------*/
/*The list of children parsers for startup arguments*/
-static const struct argp_child argp_children_startup[] =
- {
- {&argp_parser_startup_options},
- {&argp_parser_common_options},
- {&netfs_std_startup_argp},
- {0}
- };
-/*----------------------------------------------------------------------------*/
+static const struct argp_child argp_children_startup[] = {
+ {&argp_parser_startup_options},
+ {&argp_parser_common_options},
+ {&netfs_std_startup_argp},
+ {0}
+};
+
+/*---------------------------------------------------------------------------*/
/*The version of the server for argp*/
-const char * argp_program_version = "0.0";
-/*----------------------------------------------------------------------------*/
+const char *argp_program_version = "0.0";
+/*---------------------------------------------------------------------------*/
/*The arpg parser for runtime arguments*/
-struct argp argp_runtime =
- {0, 0, 0, 0, argp_children_runtime};
-/*----------------------------------------------------------------------------*/
+struct argp argp_runtime = { 0, 0, 0, 0, argp_children_runtime };
+
+/*---------------------------------------------------------------------------*/
/*The argp parser for startup arguments*/
-struct argp argp_startup =
- {0, 0, ARGS_DOC, DOC, argp_children_startup};
-/*----------------------------------------------------------------------------*/
+struct argp argp_startup = { 0, 0, ARGS_DOC, DOC, argp_children_startup };
+
+/*---------------------------------------------------------------------------*/
/*The directory to mirror*/
-char * dir = NULL;
-/*----------------------------------------------------------------------------*/
+char *dir = NULL;
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Functions-----------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Functions----------------------------------------------------------*/
/*Argp parser function for the common options*/
static
-error_t
-argp_parse_common_options
- (
- int key,
- char * arg,
- struct argp_state * state
- )
- {
- error_t err = 0;
-
- /*Go through the possible options*/
- switch(key)
- {
- /*case OPT_CACHE_SIZE:
- {*/
- /*store the new cache-size*/
- /*ncache_size = strtol(arg, NULL, 10);
-
- break;
- }*/
- case ARGP_KEY_ARG: /*the directory to mirror*/
- {
- /*try to duplicate the directory name*/
- dir = strdup(arg);
- if(!dir)
- error(EXIT_FAILURE, ENOMEM, "argp_parse_common_options: "
- "Could not strdup the directory");
-
- /*fill all trailing spaces with 0*/
- int i = strlen(dir) - 1;
- /*for(i = strlen(dir) - 1; (i >= 0) && (dir[i] == ' '); dir[i--] = 0);*/
- /*the original filename may contain spaces*/
-
- /*If the last non blank symbol is a '/' and it's not the only one*/
- if((dir[i] == '/') && (i != 0))
- /*put 0 instead*/
- dir[i] = 0;
-
- LOG_MSG("argp_parse_common_options: Mirroring the directory %s.", dir);
-
- break;
- }
- case ARGP_KEY_END:
- {
- /*If parsing of startup options has not finished*/
- if(!parsing_startup_options_finished)
- {
- /*reset the cache*/
- ncache_reset();
-
- /*If the directory has not been specified*/
- if(!dir)
- {
- /*assume the directory to be the home directory*/
- ;
-
- /*FIXME: The default directory is /var/tmp*/
- dir = "/var/tmp";
- }
-
- /*set the flag that the startup options have already been parsed*/
- parsing_startup_options_finished = 1;
- }
- else
- {
+ error_t
+ argp_parse_common_options (int key, char *arg, struct argp_state *state)
+{
+ error_t err = 0;
+
+ /*Go through the possible options */
+ switch (key)
+ {
+ /*case OPT_CACHE_SIZE:
+ { */
+ /*store the new cache-size */
+ /*ncache_size = strtol(arg, NULL, 10);
+
+ break;
+ } */
+ case ARGP_KEY_ARG: /*the directory to mirror */
+ {
+ /*try to duplicate the directory name */
+ dir = strdup (arg);
+ if (!dir)
+ error (EXIT_FAILURE, ENOMEM, "argp_parse_common_options: "
+ "Could not strdup the directory");
+
+ /*fill all trailing spaces with 0 */
+ int i = strlen (dir) - 1;
+ /*for(i = strlen(dir) - 1; (i >= 0) && (dir[i] == ' ');
+ dir[i--] = 0); */
+ /*the original filename may contain spaces */
+
+ /*If the last non blank symbol is a '/' and it's not the only one */
+ if ((dir[i] == '/') && (i != 0))
+ /*put 0 instead */
+ dir[i] = 0;
+
+ LOG_MSG ("argp_parse_common_options: Mirroring the directory %s.",
+ dir);
+
+ break;
+ }
+ case ARGP_KEY_END:
+ {
+ /*If parsing of startup options has not finished */
+ if (!parsing_startup_options_finished)
+ {
+ /*reset the cache */
+ ncache_reset ();
+
+ /*If the directory has not been specified */
+ if (!dir)
+ {
+ /*assume the directory to be the home directory */
+ ;
+
+ /*FIXME: The default directory is /var/tmp */
+ dir = "/var/tmp";
+ }
+
+ /*set the flag that the startup options have already been parsed */
+ parsing_startup_options_finished = 1;
+ }
+ else
+ {
/*TODO: Take care of runtime calls modifying the property*/
- }
- }
- /*If the option could not be recognized*/
- default:
- {
- /*set the error code*/
- err = ARGP_ERR_UNKNOWN;
- }
- }
-
- /*Return the result*/
- return err;
- }/*argp_parse_common_options*/
-/*----------------------------------------------------------------------------*/
+ }
+ }
+ /*If the option could not be recognized */
+ default:
+ {
+ /*set the error code */
+ err = ARGP_ERR_UNKNOWN;
+ }
+ }
+
+ /*Return the result */
+ return err;
+} /*argp_parse_common_options */
+
+/*---------------------------------------------------------------------------*/
/*Argp parser function for the startup options*/
static
-error_t
-argp_parse_startup_options
- (
- int key,
- char * arg,
- struct argp_state * state
- )
- {
- /*Do nothing in a beautiful way*/
- error_t err = 0;
-
- switch(key)
- {
- default:
- {
- err = ARGP_ERR_UNKNOWN;
-
- break;
- }
- }
-
- return err;
- }/*argp_parse_startup_options*/
-/*----------------------------------------------------------------------------*/
+ error_t
+ argp_parse_startup_options (int key, char *arg, struct argp_state *state)
+{
+ /*Do nothing in a beautiful way */
+ error_t err = 0;
+
+ switch (key)
+ {
+ default:
+ {
+ err = ARGP_ERR_UNKNOWN;
+
+ break;
+ }
+ }
+
+ return err;
+} /*argp_parse_startup_options */
+
+/*---------------------------------------------------------------------------*/
diff --git a/options.h b/options.h
index cbedb3db6..daa23b4c2 100644
--- a/options.h
+++ b/options.h
@@ -1,10 +1,10 @@
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*options.h*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Declarations for parsing the command line switches*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*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,34 +22,34 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.*/
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
#ifndef __OPTIONS_H__
#define __OPTIONS_H__
-/*----------------------------------------------------------------------------*/
-/*--------Macros--------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Macros-------------------------------------------------------------*/
/*The possible short options*/
#define OPT_CACHE_SIZE 'c'
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*The corresponding long options*/
#define OPT_LONG_CACHE_SIZE "cache-size"
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*Makes a long option out of option name*/
#define OPT_LONG(o) "--"o
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-/*--------Global Variables----------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*--------Global Variables---------------------------------------------------*/
/*The argp parser for startup arguments*/
extern struct argp argp_startup;
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*The argp parser for rutime arguments*/
extern struct argp argp_runtime;
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*The number of nodes in cache (see ncache.{c,h})*/
extern int ncache_size;
-/*----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*The directory to mirror*/
-extern char * dir;
-/*----------------------------------------------------------------------------*/
+extern char *dir;
+/*---------------------------------------------------------------------------*/
#endif /*__OPTIONS_H__*/