summaryrefslogtreecommitdiff
path: root/netfs-sample/lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'netfs-sample/lib.c')
-rw-r--r--netfs-sample/lib.c193
1 files changed, 193 insertions, 0 deletions
diff --git a/netfs-sample/lib.c b/netfs-sample/lib.c
new file mode 100644
index 00000000..aa0ff0be
--- /dev/null
+++ b/netfs-sample/lib.c
@@ -0,0 +1,193 @@
+/*----------------------------------------------------------------------------*/
+/*lib.h*/
+/*----------------------------------------------------------------------------*/
+/*Basic routines for filesystem manipulations*/
+/*----------------------------------------------------------------------------*/
+/*Based on the code of unionfs translator.*/
+/*----------------------------------------------------------------------------*/
+/*Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
+ Written by Sergiu Ivanov <unlimitedscolobb@gmail.com>.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or * (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ 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 "lib.h"
+#include "debug.h"
+/*----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------*/
+/*--------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*/
+/*----------------------------------------------------------------------------*/
+/*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 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*/
+/*----------------------------------------------------------------------------*/