diff options
Diffstat (limited to 'lib.c')
-rw-r--r-- | lib.c | 371 |
1 files changed, 184 insertions, 187 deletions
@@ -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 */ + +/*---------------------------------------------------------------------------*/ |