summaryrefslogtreecommitdiff
path: root/unionfs
diff options
context:
space:
mode:
Diffstat (limited to 'unionfs')
-rw-r--r--unionfs/AUTHORS2
-rw-r--r--unionfs/BUGS5
-rw-r--r--unionfs/CAVEAT25
-rw-r--r--unionfs/COPYING2
-rw-r--r--unionfs/ChangeLog229
-rw-r--r--unionfs/Makefile81
-rw-r--r--unionfs/README92
-rw-r--r--unionfs/TODO7
-rw-r--r--unionfs/lib.c280
-rw-r--r--unionfs/lib.h82
-rw-r--r--unionfs/lnode.c184
-rw-r--r--unionfs/lnode.h77
-rw-r--r--unionfs/main.c134
-rw-r--r--unionfs/ncache.c151
-rw-r--r--unionfs/ncache.h59
-rw-r--r--unionfs/netfs.c1170
-rw-r--r--unionfs/node.c555
-rw-r--r--unionfs/node.h135
-rw-r--r--unionfs/options.c225
-rw-r--r--unionfs/options.h53
-rw-r--r--unionfs/pattern.c131
-rw-r--r--unionfs/pattern.h53
-rw-r--r--unionfs/stow-mutations.h27
-rw-r--r--unionfs/stow-priv.h45
-rw-r--r--unionfs/stow.c328
-rw-r--r--unionfs/stow.h30
-rw-r--r--unionfs/ulfs.c321
-rw-r--r--unionfs/ulfs.h75
-rw-r--r--unionfs/unionfs.h90
-rw-r--r--unionfs/update.c97
-rw-r--r--unionfs/update.h28
-rw-r--r--unionfs/version.h29
32 files changed, 0 insertions, 4802 deletions
diff --git a/unionfs/AUTHORS b/unionfs/AUTHORS
deleted file mode 100644
index 1cc95387..00000000
--- a/unionfs/AUTHORS
+++ /dev/null
@@ -1,2 +0,0 @@
-* Moritz Schulte <moritz@duesseldorf.ccc.de>
-* Gianluca Guida <glguida@gmail.com>
diff --git a/unionfs/BUGS b/unionfs/BUGS
deleted file mode 100644
index 56209654..00000000
--- a/unionfs/BUGS
+++ /dev/null
@@ -1,5 +0,0 @@
-Known bugs:
-
- * unionfs hangs when looking up recursive links, which point into the
- unionfs
- * emacs hangs when trying to save files in unionfs
diff --git a/unionfs/CAVEAT b/unionfs/CAVEAT
deleted file mode 100644
index dbb88136..00000000
--- a/unionfs/CAVEAT
+++ /dev/null
@@ -1,25 +0,0 @@
-While using unionfs, you could experience more permission errors or
-difficult or impossible file or directory deletion. This is a list of
-things that can happen.
-
-WARNINGS:
-
-- If the translator is run as by an unpriviledged user, other users will fail
-to create files or directory, since the translator won't be able to change
-the ownership of the file.
-
-
-PROBLEMS:
-
-- If there's a name conflict in underlying filesystems between directories
-and files -- say that "foo" is a directory in underlying filesystem "a" while
-is a file in the underlying filesystem "b" -- then unionfs will be unable to
-delete this entry. This is a structural BUG (there's no clean way to solve it),
-and should be fixed.
-
-- If there's a name conflict in underlying filesystems between directories
-(or between files), and the user has not permission to delete _ALL_ the
-entries -- e.g. one hidden entry is read-only -- then he will get an EPERM
-even if permissions seems ok. This is a structural BUG (there's no clean way
-to solve it), and should be fixed.
-
diff --git a/unionfs/COPYING b/unionfs/COPYING
deleted file mode 100644
index 5cc9607b..00000000
--- a/unionfs/COPYING
+++ /dev/null
@@ -1,2 +0,0 @@
-This program is licensed under the terms of the GNU General Public
-License.
diff --git a/unionfs/ChangeLog b/unionfs/ChangeLog
deleted file mode 100644
index d8a29618..00000000
--- a/unionfs/ChangeLog
+++ /dev/null
@@ -1,229 +0,0 @@
-2006-06-21 Alfred M. Szmidt <ams@gnu.org>
-
- * lib.c (for_each_subdir): Revert previous change. Reported by
- Aanjhan Ranganathan <aanjhan@tuxmaniac.com>.
-
-2006-04-13 Ben Asselstine <benasselstine@gmail.com>
-
- * options.c (argp_parse_common_options)
- (argp_parse_startup_options, parsing_startup_options_finished)
- (argp_common_options, argp_startup_options)
- (argp_parser_common_options, argp_parser_startup_options)
- (argp_children_runtime): Make these static.
- * ulfs.c (ulfs_create, ulfs_destroy, ulfs_install)
- (ulfs_uninstall, ulfs_get_path): Likewise.
-
- * ulfs.h (ulfs_get_path): Remove declaration.
-
- * lib.c (for_each_subdir): Remove unused variables.
-
-2005-06-27 Ben Asselstine <benasselstine@gmail.com>
-
- * ulfs.c (ulfs_install): Rewrote to allow insertions of
- filesystems based on priority.
- (ulfs_register): Added new argument 'priority'. Set the priority
- value in ulfs structure.
- * ulfs.h (ulfs): Added 'priority' field to struct.
- Updated ulfs_register declaration.
- * netfs.c (netfs_append_args): Appending new priority option.
- * stow.c (stow_privdata): Added 'priority' field to struct.
- (stow_diradd): Added new 'priority' argument. Fill priority field
- of 'mypriv'.
- (_stow_scanstowentry): Changed caller to ulfs_register.
- (_stow_registermatchingdirs): Likewise.
- * options.c (arg_common_options): Added entries for OPT_PRIORITY
- and OPT_ADD.
- (arg_parse_common_options): Handle OPT_PRIORITY and OPT_ADD
- case. Renamed 'ulfs_removed' to 'ulfs_mode'. New variable
- 'ulfs_priority'. Changed caller to 'stow_diradd'. Changed caller
- to 'ulfs_register'.
- * options.h (OPT_ADD, OPT_PRIORITY, OPT_LONG_ADD)
- (OPT_LONG_PRIORITY, ULFS_MODE_ADD, ULFS_MODE_REMOVE): New
- declarations.
-
-2005-06-13 Gianluca Guida <glguida@gmail.com>
-
- * main.c (main): Set properly netfs_root_node permissions when
- underlying node is not a file
- Reported by Alfred M. Szmidt.
-
-2005-05-31 Gianluca Guida <glguida@gmail.com>
-
- * node.c (node_unlink_file): Use lookup to figure out whether a file
- exists or not, or it will fail on read-only filesystems.
- Reported by Ben Asselstine.
-
-2005-05-30 Gianluca Guida <glguida@gmail.com>
-
- * AUTHORS: Added myself in the list.
- * README: Added sections "Introduction" and "Stowing Feature".
- * options.c (argp_program_bug_address): Changed address.
-
- * lib.c (for_each_subdir): When call to stat() fails free "name"
- and continue the loop, instead of returning error. Return 0 at the
- end of the loop.
- (for_each_subdir_priv): Likewise.
-
- * stow.c (_stow_registermatchingdirs): Don't return error when
- patternlist_match returns false. Free filepath before returning
- error when ulfs_register fails.
-
- * ulfs.c (ulfs_register): Removed bogus fprintf.
-
-2005-05-29 Gianluca Guida <glguida@gmail.com>
-
- * Makefile: Added support for building mig stubs for stow feature.
- (OBJS): Added update.o
- (unionfs): Added fs_notifyServer.o to final linking.
- (unionfs.static): Likewise.
- (fs_notifyServer.o): New rule.
- (clean): Remove fs_notifyServer.c and fs_notify_S.h when cleaning.
-
- * netfs.c (OFFSET_T): New macro.
- (_get_node_size): New function.
- (netfs_validate_stat): Call _get_node_size for root node.
-
- * node.c (node_unlink_file): New variable "removed". Return ENOENT
- if no files unlinked.
-
- * ulfs.c: Include "unionfs", fcntl.h and "lib.h".
- (ulfs_install, ulfs_uninstall): Rewritten.
- (ulfs_for_each_under_priv, ulfs_check): New function.
- (ulfs_register): Check that argument is a directory.
- * ulfs.h: Removed field "prevp" from struct ulfs.
- (ulfs_check): New declaration.
- (ulfs_iterate, ulfs_iterate_unlocked): Don't use ulfs_chain_end.
- * lib.c (check_dir): New function.
- * lib.h: Added declaration of check_dir.
-
- * stow.c: Include "update.h", cthreads.h, hurd/port.h,
- "stow-priv.h" and "ncache.h".
- (stow_privdata) Added "lock" to struct. Removed "remove" to
- struct.
- (_stow_registermatchingdirs): Removed call to
- debug_msg_send. Removed call to ulfs_unregister when
- privdata->remove is set. Return error on ulfs_register failure
- instead of exiting the program.
- (_stow_scanstowentry): Removed call to ulfs_unregister when
- privdata->remove is set. Lock privdata->lock and unlock at end.
- (stow_port_bucket, stow_port_class): New variables.
- (_stow_notify_init, begin_using_notify_ports)
- (end_using_notify_ports, stow_S_file_changed, stow_S_dir_changed)
- (_stow_notify_thread, stow_init): New functions.
- (stow_diradd): Allocate "mypriv" instead of using stack. Call
- _stow_notify_init.
- * stow.h: Include "pattern.h". Declare
- stow_init.
-
- * stow-priv.h: New file.
- * stow-mutations.h: Likewise.
- * update.c: Likewise.
- * update.h: Likewise.
-
- * options.c: Include "update.h".
- (argp_parse_common_options): Check stow_diradd return. Call
- root_update_schedule instead of node_init_root and ncache_reset
- when parsing_startup_options_finished is set.
-
- * main.c: Include "stow.h". Include "update.h".
- (main): Call stow_init. Call root_update_init.
-
-2005-05-25 Gianluca Guida <glguida@gmail.com>
-
- * CAVEAT: New file.
- * README: Rewritten.
-
- * netfs.c (netfs_attempt_unlink): Use fshelp_checkdirmod
- instead of fshelp_access.
- (netfs_attempt_mkdir): Implemented.
- (netfs_attempt_rmdir): Likewise.
- (netfs_attempt_create_file_reduced): Likewise.
- Fixed typo in a comment.
- * node.c (node_dir_remove): New function.
- (node_dir_create): Likewise.
- * node.h (node_dir_create): New declaration.
- (node_dir_remove): Likewise.
-
- * lib.c (for_each_file_priv): Removed unused variables
- "name" and "filestat".
-
-2005-05-24 Gianluca Guida <glguida@gmail.com>
-
- * netfs.c (netfs_attempt_unlink): Implemented.
- (netfs_attempt_create_file_reduced): New function.
- (netfs_S_dir_lookup): Initialized variable "error".
- Added support for file creation.
- (netfs_attempt_lookup_improved): Changed instruction flow,
- return on error not continue on non-error.
- Check user permission to open file before returning port.
- * node.c (node_create, node_update, node_lookup_file, node_ulfs_free)
- (node_ulfs_init, node_entries_get, node_create_root, node_init_root):
- Changed instruction flow, return on error not continue on non-error.
- (node_unlink_file): New function.
- * node.h (node_unlink_file): New declaration.
- (node_ulfs_iterate_reverse_unlocked): New macro.
-
- * options.c (argp_parse_common_options): Removed debugging fprintf.
-
-2005-01-31 Gianluca Guida <glguida@gmail.com>
-
- * stow.c (stow_diradd): Handle --stow argument with missing /
- correctly.
-
-2005-01-31 Gianluca Guida <glguida@gmail.com>
-
- * pattern.c: New file.
- * stow.c: Likewise.
- * pattern.h: Likewise.
- * stow.h: Likewise.
- * Makefile (OBJS): Added pattern.o and stow.o
-
- * node.c: Initialize variable err.
- * lib.c (file_lookup): Initialize variable err.
- Include <fcntl.h>.
- (make_filepath, for_each_subdir, for_each_subdir_priv)
- (for_each_file_priv): New function.
- * lib.h (make_filepath, for_each_subdir, for_each_subdir_priv): New
- declaration.
- * options.c: Include "pattern.h".
- Include "stow.h".
- (arg_common_options): Added entries for OPT_STOW and OPT_PATTERN.
- (argp_parse_common_options): Handle OPT_STOW and OPT_PATTERN case.
- * options.h (OPT_PATTERN, OPT_STOW, OPT_LONG_PATTERN, OPT_LONG_STOW):
- New declarations.
-
-2003-07-05 Jeroen Dekkers <jeroen@dekkers.cx>
-
- * Makefile: Rewrite.
-
- * netfs.c (netfs_attempt_create_file): Unlock DIR.
- (netfs_attempt_mkfile): Likewise.
-
-2002-12-09 Moritz Schulte <moritz@duesseldorf.ccc.de>
-
- * lib.h: Fix pointer arg.
- * lib.c (dir_entries_get): Likewise.
- * lib.c (dir_entries_get): Fix typo.
- (dir_entries_get): Change type of data_size to size_t.
- * node.c (node_entries_get): Change type of dirent_data_size to
- size_t.
-
-2002-12-08 Moritz Schulte <moritz@duesseldorf.ccc.de>
-
- * BUGS: Remove the memory-leak bug.
- * lib.c: Include <sys/mman.h>.
- * node.c: Include <sys/mman.h>.
- (node_entries_get): munmap dirent_data as returned by
- dir_entries_get.
- (node_entries_get): New variable: int dirent_data_size.
- * lib.c (dir_entries_get): New argument: int *dirent_data_size.
- (dir_entries_get): Do not forget to munmap DATA if something goes
- wrong.
- * lib.h: Update dir_entries_get declaration.
-
- * node.c (node_create_root): call lnode_destroy, if node_create
- failed, not if lnode_create failed. Reported by Richard Smith.
-
- Copyright 2002, 2003, 2005 Free Software Foundation, Inc.
- Copying and distribution of this file, with or without modification, are
- permitted provided the copyright notice and this notice are preserved.
diff --git a/unionfs/Makefile b/unionfs/Makefile
deleted file mode 100644
index b1800722..00000000
--- a/unionfs/Makefile
+++ /dev/null
@@ -1,81 +0,0 @@
-# Hurd unionfs
-# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
-# Written by Jeroen Dekkers <jeroen@dekkers.cx>.
-#
-# 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.
-
-CPP = gcc -E -x c
-MIGCOM = mig -cc cat - /dev/null
-
-CFLAGS += -Wall -g -O2 -D_FILE_OFFSET_BITS=64 -std=gnu99 \
- -DDEBUG
-LDFLAGS += -lnetfs -lfshelp -liohelp -lthreads \
- -lports -lihash -lshouldbeinlibc
-OBJS = main.o node.o lnode.o ulfs.o ncache.o netfs.o \
- lib.o options.o pattern.o stow.o update.o
-
-MIGCOMSFLAGS = -prefix stow_
-fs_notify-MIGSFLAGS = -imacros ./stow-mutations.h
-
-
-# How to build RPC stubs
-
-# We always need this setting, because libc does not include the bogus names.
-MIGCOMFLAGS := -subrprefix __
-
-# User settable variables:
-# mig-sheader-prefix prepend to foo_S.h for name of foo.defs stub header
-# MIGSFLAGS flags to CPP when building server stubs and headers
-# foo-MIGSFLAGS same, but only for interface `foo'
-# MIGCOMSFLAGS flags to MiG when building server stubs and headers
-# foo-MIGCOMSFLAGS same, but only for interface `foo'
-# MIGUFLAGS flags to CPP when building user stubs and headers
-# foo-MIGUFLAGS same, but only for interface `foo'
-# MIGCOMUFLAGS flags to MiG when building user stubs and headers
-# foo-MIGCOMUFLAGS same, but only for interface `foo'
-# CPPFLAGS flags to CPP
-
-# Implicit rules for building server and user stubs from mig .defs files.
-
-# These chained rules could be (and used to be) single rules using pipes.
-# But it's convenient to be able to explicitly make the intermediate
-# files when you want to deal with a problem in the MiG stub generator.
-$(mig-sheader-prefix)%_S.h %Server.c: %.sdefsi
- $(MIGCOM) $(MIGCOMFLAGS) $(MIGCOMSFLAGS) $($*-MIGCOMSFLAGS) \
- -sheader $(mig-sheader-prefix)$*_S.h -server $*Server.c \
- -user /dev/null -header /dev/null < $<
-
-%.sdefsi: %.defs
- $(CPP) $(CPPFLAGS) $(MIGSFLAGS) $($*-MIGSFLAGS) -DSERVERPREFIX=S_ $< -o $@
-
-vpath %.defs $(prefix)/include/hurd
-
-
-
-all: unionfs
-
-unionfs: $(OBJS) fs_notifyServer.o
- $(CC) -o $@ $(OBJS) fs_notifyServer.o $(LDFLAGS)
-
-unionfs.static: $(OBJS) fs_notifyServer.o
- $(CC) -static -o $@ $(OBJS) fs_notifyServer.o $(LDFLAGS)
-
-fs_notifyServer.o: fs_notifyServer.c
-
-.PHONY: clean
-
-clean:
- rm -rf *.o fs_notifyServer.c fs_notify_S.h unionfs
diff --git a/unionfs/README b/unionfs/README
deleted file mode 100644
index 1849f4d9..00000000
--- a/unionfs/README
+++ /dev/null
@@ -1,92 +0,0 @@
-This is the unionfs translator for the GNU Hurd.
-
-The unionfs translator was originally written by Moritz Schulte
-<moritz@duesseldorf.ccc.de> and currently mantained by Gianluca Guida
-<glguida@gmail.com>.
-
-
-
-Introduction.
-
-An unionfs is a filesystems that joins many filesystems into one, meaning
-that you can see into an "unionfs" all files contained in the filesystems
-that are part of the union.
-
-When two or more directories with the same path are found in different
-filesystems, their content is joined.
-When two or more files with the same path are found in different filesystems,
-unionfs has to solve this conflict. See below (Internals section) for
-information on what this implementation does in such case.
-
-Example:
-To join "foo/" "bar/" and "baz/" in the directory "quux/", just do:
-
- settrans -capfg quux/ /hurd/unionfs foo/ bar/ baz/
-
-If you want to join even quux/ contents in the union itself, add -u as a
-translator argument.
-You can add filesystems at run-time with the fsysopts command.
-
-
-
-Stowing feature.
-
-This unionfs implements stowing feature, i.e. the translator will watch a
-directory, called 'stow', that contains the directories to unite.
-When a directory is added or removed in the stow, it will be added to or
-removed from the unionfs.
-
-Example:
-To use "/stow" as the stow for the directory "foo/", do:
-
- settrans -capfg foo/ /hurd/unionfs --stow=/stow
-
-All directories contained in /stow/ will then be joined together in foo/;
-you can delete or add directory at run-time and you will see unionfs adding
-or removing files in foo/ automatically.
-
-Another interesting feature of stow support of unionfs is the pattern matching
-option.
-For example, by using:
-
- settrans -capfg foo/ /hurd/unionfs -m bar --stow=/stow
-
-You will get joined in foo/ all sub-sub-directories of /stow matching "bar",
-i.e. /stow/*/bar/; pattern matching will be done too in run-time added stow
-subdirectories.
-Furthermore, you can specify more complex matching pattern to the option,
-like -m bar\* (to get all stow's sub-sub-directories beginning with "bar")
-or specify multiple -m options.
-
-Example:
-This command
-
- settrans -capfg /myfaketree/bin -m bin -m sbin --stow=/stow
-
-will join in /myfaketree/bin all files that are in /stow/*/bin and
-/stow/*/sbin. It is equivalent to:
-
- settrans -capfg /myfaketree/bin -m [s]bin --stow=/stow
-
-
-
-Internals.
-
-This `unionfs' translator is simple, but it is definitely not a joke.
-
-It works by keeping in memory a dynamically updated tree of nodes, each
-node representing a directory in the unionfs. A node contains an array
-of ports that give access to the corrisponding directory in the underlying
-filesystems.
-
-On lookup, the first entry found is chosen. Thus, it is very important the
-underlying filesystems ordering, since the first underlying filesystem will
-be the first one to be searched during lookups, and it is the filesystem
-where new files and directories are written into.
-
-At the moment, underlying filesystem ordering is set by option ordering.
-
-See CAVEAT for other unexpected behaviour that could happen.
-
-
-Please send all bug reports to Gianluca Guida <glguida@gmail.com>.
diff --git a/unionfs/TODO b/unionfs/TODO
deleted file mode 100644
index 790221f2..00000000
--- a/unionfs/TODO
+++ /dev/null
@@ -1,7 +0,0 @@
-Todo list for unionfs:
-
- * implement filesystem notification support;
- only update nodes when needed
- * cache dirents (?)
- * verify that the locking is correct
- * increase performance
diff --git a/unionfs/lib.c b/unionfs/lib.c
deleted file mode 100644
index 0423c1bc..00000000
--- a/unionfs/lib.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
- Written by Moritz Schulte <moritz@duesseldorf.ccc.de>.
-
- 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
-
-#include <hurd/netfs.h>
-#include <error.h>
-#include <dirent.h>
-#include <errno.h>
-#include <sys/mman.h>
-#include <stddef.h>
-
-#include "lib.h"
-
-/* Lock, which must be held, during printing of debugging
- messages. */
-struct mutex debug_msg_lock = MUTEX_INITIALIZER;
-
-/* Returns no error if PATH points to a directory. */
-error_t check_dir (char *path)
-{
- struct stat filestat;
- error_t err = 0;
-
- err = stat (path, &filestat);
- if (err)
- return err;
-
- if (!S_ISDIR (filestat.st_mode))
- return ENOTDIR;
-
- return 0;
-}
-
-/* Fetch directory entries for DIR; store the raw data as returned by
- the dir_readdir RPC in *DIRENT_DATA, the size of *DIRENT_DATA in
- *DIRENT_DATA_SIZE and a list of pointers to the dirent structures
- in *DIRENT_LIST. */
-error_t
-dir_entries_get (file_t dir, char **dirent_data,
- size_t *dirent_data_size, struct dirent ***dirent_list)
-{
- error_t err;
- size_t data_size;
- int entries_num;
- char *data;
-
- err = dir_readdir (dir, &data, &data_size, 0, -1, 0, &entries_num);
- if (! err)
- {
- struct dirent **list;
-
- list = malloc (sizeof (struct dirent *) * (entries_num + 1));
- if (list)
- {
- struct dirent *dp;
- int i;
-
- for (i = 0, dp = (struct dirent *) data;
- i < entries_num;
- i++, dp = (struct dirent *) ((char *) dp + dp->d_reclen))
- *(list + i) = dp;
- *(list + i) = NULL;
-
- *dirent_data = data;
- *dirent_data_size = data_size;
- *dirent_list = list;
- }
- else
- {
- munmap (data, data_size);
- err = ENOMEM;
- }
- }
- return err;
-}
-
-/* Lookup the file named NAME beneath DIR (or the cwd, if DIR is not a
- valid port. Try to open with FLAGS0 first, and if that fails with
- FLAGS1; MODE is the mode to user for newly created files. On
- success, stat the looked up port and store it in *PORT, the
- according stat information are stored in *STAT. */
-error_t
-file_lookup (file_t dir, char *name, int flags0, int flags1,
- int mode, file_t *port, struct stat *stat)
-{
- error_t err = 0;
- file_t p;
- struct stat s;
-
- file_t do_file_lookup (file_t d, char *n, int f, int m)
- {
- if (port_valid (d))
- p = file_name_lookup_under (d, n, f, m);
- else if (errno == EACCES)
- p = file_name_lookup (n, f, m);
- return p;
- }
-
- p = do_file_lookup (dir, name, flags0, mode);
- if (! port_valid (p))
- p = do_file_lookup (dir, name, flags1, mode);
-
- if (port_valid (p))
- {
- if (stat)
- {
- err = io_stat (p, &s);
- if (err)
- port_dealloc (p);
- }
- }
- else
- err = errno;
-
- if (! err)
- {
- *port = p;
- if (stat)
- *stat = s;
- }
- return err;
-}
-
-#include <fcntl.h>
-
-char *
-make_filepath (char *path, char *filename)
-{
- int length;
- char *filepath;
-
- length = strlen (path) + strlen (filename) + 2;
- filepath = malloc (length);
- if (filepath == NULL)
- return NULL;
-
- strncpy (filepath, path, length);
- strncat (filepath, filename, strlen (filename));
-
- return filepath;
-}
-
-error_t
-for_each_subdir (char *path, error_t (*func) (char *, char *))
-{
- struct dirent **dirent, **dirent_list;
- char *dirent_data;
- size_t dirent_data_size;
- file_t dir;
- error_t err;
-
- dir = file_name_lookup (path, O_READ, 0);
-
- err = dir_entries_get (dir, &dirent_data, &dirent_data_size, &dirent_list);
- if (err)
- return err;
-
- for (dirent = dirent_list; (! err) && (*dirent); dirent++)
- {
- char *name;
- struct stat filestat;
-
- if ((!strcmp ((*dirent)->d_name, "."))
- || (!strcmp ((*dirent)->d_name, "..")))
- continue;
-
- name = make_filepath (path, (*dirent)->d_name);
-
- err = stat (name, &filestat);
-
- free (name);
-
- if (err)
- {
- fprintf (stderr, "unionfs: couldn't stat %s%s\n",
- path, (*dirent)->d_name);
- continue;
- }
-
- if (!S_ISDIR(filestat.st_mode))
- continue;
-
- func ((*dirent)->d_name, path);
- }
-
- return 0;
-}
-
-error_t
-for_each_subdir_priv (char *path, error_t (*func) (char *, char *, void *),
- void *priv)
-{
- struct dirent **dirent, **dirent_list;
- char *dirent_data;
- size_t dirent_data_size;
- file_t dir;
- error_t err;
-
- dir = file_name_lookup (path, O_READ, 0);
-
- err = dir_entries_get (dir, &dirent_data, &dirent_data_size, &dirent_list);
- if (err)
- return err;
-
- for (dirent = dirent_list; (!err) && (*dirent); dirent++)
- {
- char *name;
- struct stat filestat;
-
- if ((!strcmp ((*dirent)->d_name, "."))
- || (!strcmp ((*dirent)->d_name, "..")))
- continue;
-
- name = make_filepath (path, (*dirent)->d_name);
-
- err = stat (name, &filestat);
-
- free (name);
-
- if (err)
- {
- fprintf (stderr, "unionfs: couldn't stat %s%s\n",
- path, (*dirent)->d_name);
- continue;
- }
-
- if (!S_ISDIR(filestat.st_mode))
- continue;
-
- func ((*dirent)->d_name, path, priv);
- }
-
- return 0;
-}
-
-error_t
-for_each_file_priv (char *path, error_t (*func) (char *, char *, void *),
- void *priv)
-{
- struct dirent **dirent, **dirent_list;
- char *dirent_data;
- size_t dirent_data_size;
- file_t dir;
- error_t err;
-
- dir = file_name_lookup (path, O_READ, 0);
-
- err = dir_entries_get (dir, &dirent_data, &dirent_data_size, &dirent_list);
- if (err)
- return err;
-
- for (dirent = dirent_list; (!err) && (*dirent); dirent++)
- {
-
- if ((!strcmp ((*dirent)->d_name, "."))
- || (!strcmp ((*dirent)->d_name, "..")))
- continue;
-
- func ((*dirent)->d_name, path, priv);
- }
-
- return err;
-}
diff --git a/unionfs/lib.h b/unionfs/lib.h
deleted file mode 100644
index be9a2192..00000000
--- a/unionfs/lib.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
- Written by Moritz Schulte <moritz@duesseldorf.ccc.de>.
-
- 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. */
-
-#ifndef INCLUDED_LIB_H
-#define INCLUDED_LIB_H
-
-#include <hurd.h>
-#include <dirent.h>
-#include <stddef.h>
-
-/* Returned directory entries are aligned to blocks this many bytes
- long. Must be a power of two. */
-#define DIRENT_ALIGN 4
-#define DIRENT_NAME_OFFS offsetof (struct dirent, d_name)
-
-/* Length is structure before the name + the name + '\0', all padded
- to a four-byte alignment. */
-#define DIRENT_LEN(name_len) \
- ((DIRENT_NAME_OFFS + (name_len) + 1 + (DIRENT_ALIGN - 1)) \
- & ~(DIRENT_ALIGN - 1))
-
-/* These macros remove some Mach specific code from the server
- itself. */
-#define port_null MACH_PORT_NULL
-#define port_dealloc(p) mach_port_deallocate (mach_task_self (), (p))
-#define port_valid(p) ((p) != port_null)
-
-/* Fetch directory entries for DIR; store the raw data as returned by
- the dir_readdir RPC in *DIRENT_DATA, the size of *DIRENT_DATA in
- *DIRENT_DATA_SIZE and a list of pointers to the dirent structures
- in *DIRENT_LIST. */
-error_t dir_entries_get (file_t dir, char **dirent_data,
- size_t *dirent_data_size,
- struct dirent ***dirent_list);
-
-char *make_filepath (char *, char *);
-error_t for_each_subdir (char *, error_t (*) (char *, char *));
-error_t for_each_subdir_priv (char *, error_t (*) (char *, char *, void *),
- void *);
-
-/* Lookup the file named NAME beneath DIR (or the cwd, if DIR is not a
- valid port. Try to open with FLAGS0 first, and if that fails with
- FLAGS1; MODE is the mode to user for newly created files. On
- success, stat the looked up port and store it in *PORT, the
- according stat information are stored in *STAT. */
-error_t file_lookup (file_t dir, char *name, int flags0, int flags1, int mode,
- file_t *port, struct stat *stat);
-
-/* Returns no error if directory. */
-error_t check_dir (char *path);
-
-extern struct mutex debug_msg_lock;
-
-/* Support for debugging messages. */
-#define debug_msg_send(fmt, args...) \
- do \
- { \
- mutex_lock (&debug_msg_lock); \
- fprintf (stderr, "%s:%i: ", __FILE__, __LINE__); \
- fprintf (stderr, fmt , ## args); \
- putc ('\n', stderr); \
- mutex_unlock (&debug_msg_lock); \
- } \
- while (0)
-
-#endif
diff --git a/unionfs/lnode.c b/unionfs/lnode.c
deleted file mode 100644
index 9b242bba..00000000
--- a/unionfs/lnode.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
- Written by Moritz Schulte <moritz@duesseldorf.ccc.de>.
-
- 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. */
-
-/* `light node' management. See unionfs.h for an explanation of light
- nodes. */
-
-#define _GNU_SOURCE
-
-#include <hurd/netfs.h>
-#include <error.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "lnode.h"
-#include "lib.h"
-#include "unionfs.h"
-
-/* Create a new light node as an entry with the name NAME and store it
- in *NODE. The new node is not locked and contains a single
- reference. */
-error_t
-lnode_create (char *name, lnode_t **node)
-{
- lnode_t *node_new = malloc (sizeof (lnode_t));
- error_t err = 0;
-
- debug_msg ("lnode_create for name: %s", name);
-
- if (! node_new)
- err = ENOMEM;
- else
- {
- char *name_cp = NULL;
-
- if (name)
- name_cp = strdup (name);
- if (name && (! name_cp))
- {
- err = ENOMEM;
- free (node_new);
- }
- else
- {
- node_new->name = name_cp;
- node_new->name_len = name_cp ? strlen (name_cp) : 0;
- node_new->flags = 0;
- node_new->node = NULL;
- node_new->next = NULL;
- node_new->prevp = NULL;
- node_new->dir = NULL;
- node_new->entries = NULL;
- node_new->references = 1;
- mutex_init (&node_new->lock);
- mutex_lock (&node_new->lock);
- *node = node_new;
- }
- }
- return err;
-}
-
-/* Destroy a light node. */
-void
-lnode_destroy (lnode_t *node)
-{
- debug_msg ("lnode_destroy for name: %s", node->name);
- free (node->name);
- free (node);
-}
-
-/* Install the node in the node tree; add a reference to DIR, which
- must be locked. */
-void
-lnode_install (lnode_t *dir, lnode_t *node)
-{
- lnode_ref_add (dir);
- node->next = dir->entries;
- node->prevp = &dir->entries;
- if (dir->entries)
- dir->entries->prevp = &node->next;
- dir->entries = node;
- node->dir = dir;
-}
-
-/* Uninstall the node from the node tree; remove a reference from the
- lnode containing NODE. */
-void
-lnode_uninstall (lnode_t *node)
-{
- lnode_ref_remove (node->dir);
- *node->prevp = node->next;
- if (node->next)
- node->next->prevp = &node->next;
-}
-
-/* Add a reference to NODE, which must be locked. */
-void
-lnode_ref_add (lnode_t *node)
-{
- node->references++;
-}
-
-/* Remove a reference to NODE, which must be locked. If that was the
- last reference, destroy the node, otherwise simply unlock NODE. */
-void
-lnode_ref_remove (lnode_t *node)
-{
- assert (node->references);
- if (! --node->references)
- {
- lnode_uninstall (node);
- lnode_destroy (node);
- }
- else
- mutex_unlock (&node->lock);
-}
-
-/* Get a light node by it's name. The looked up node is locked and
- got one reference added. */
-error_t
-lnode_get (lnode_t *dir, char *name,
- lnode_t **node)
-{
- error_t err = 0;
- lnode_t *n;
-
- for (n = dir->entries; n && strcmp (n->name, name); n = n->next);
- if (n)
- {
- mutex_lock (&n->lock);
- lnode_ref_add (n);
- *node = n;
- }
- else
- err = ENOENT;
-
- return err;
-}
-
-/* Construct the full path for a given light node. */
-error_t
-lnode_path_construct (lnode_t *node,
- char **path)
-{
- error_t err = 0;
- int p_len = 1;
- lnode_t *n;
- char *p;
-
- for (n = node; n && n->dir; n = n->dir)
- p_len += n->name_len + (n->dir->dir ? 1 : 0);
-
- p = malloc (p_len);
- if (! p)
- err = ENOMEM;
- else
- {
- *(p + --p_len) = 0;
- for (n = node; n && n->dir; n = n->dir)
- {
- p_len -= n->name_len;
- strncpy (p + p_len, n->name, n->name_len);
- if (n->dir->dir)
- *(p + --p_len) = '/';
- }
- *path = p;
- }
- return err;
-}
diff --git a/unionfs/lnode.h b/unionfs/lnode.h
deleted file mode 100644
index b43b7b26..00000000
--- a/unionfs/lnode.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
- Written by Moritz Schulte <moritz@duesseldorf.ccc.de>.
-
- 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. */
-
-/* `light node' management. */
-
-#ifndef INCLUDED_LNODE_H
-#define INCLUDED_LNODE_H
-
-#include <hurd/netfs.h>
-#include <error.h>
-
-struct lnode
-{
- char *name; /* The name of this light node. */
- int name_len; /* This is used quite often and since
- NAME does not change, just
- calculate it once. */
- int flags; /* Associated flags. */
- int references; /* References to this light node. */
- struct node *node; /* Reference to the real node. */
- struct lnode *next, **prevp; /* Light nodes are connected in a
- linked list. */
- struct lnode *dir; /* The light node this light node is
- contained int. */
- struct lnode *entries; /* A reference to the list containing
- the entries of this light node. */
- struct mutex lock; /* A lock. */
-};
-typedef struct lnode lnode_t;
-
-/* Create a new light node as an entry with the name NAME and store it
- in *NODE. The new node is not locked and contains a single
- reference. */
-error_t lnode_create (char *name, lnode_t **node);
-
-/* Destroy a light node. */
-void lnode_destroy (lnode_t *node);
-
-/* Install the node in the node tree; add a reference to DIR. */
-void lnode_install (lnode_t *dir, lnode_t *node);
-
-/* Uninstall the node from the node tree; remove a reference from the
- lnode containing NODE. */
-void lnode_uninstall (lnode_t *node);
-
-/* Add a reference to NODE, which must be locked. */
-void lnode_ref_add (lnode_t *node);
-
-/* Remove a reference to NODE, which must be locked. If that was the
- last reference, destroy the node, otherwise simply unlock NODE. */
-void lnode_ref_remove (lnode_t *node);
-
-/* Get a light node by it's name. The looked up node is locked and
- got one reference added. */
-error_t lnode_get (lnode_t *dir, char *name,
- lnode_t **node);
-
-/* Construct the full path for a given light node. */
-error_t lnode_path_construct (lnode_t *node, char **path);
-
-#endif
diff --git a/unionfs/main.c b/unionfs/main.c
deleted file mode 100644
index c33b0654..00000000
--- a/unionfs/main.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
- Written by Moritz Schulte <moritz@duesseldorf.ccc.de>.
-
- 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
-
-#include <hurd/netfs.h>
-#include <argp.h>
-#include <argz.h>
-#include <error.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "version.h"
-#include "unionfs.h"
-#include "ncache.h"
-#include "ulfs.h"
-#include "lnode.h"
-#include "node.h"
-#include "options.h"
-#include "stow.h"
-#include "update.h"
-
-char *netfs_server_name = "unionfs";
-char *netfs_server_version = HURD_VERSION;
-
-/* Not really needed, since unionfs doesn't manage symlinks. */
-int netfs_maxsymlinks = 0;
-
-/* Flags describing certain properties of the unionfs. */
-int unionfs_flags;
-
-/* The filesystem id (the pid). */
-pid_t fsid;
-
-/* A port to the underlying node. */
-mach_port_t underlying_node;
-
-/* stat information for the underlying node. */
-struct stat underlying_node_stat;
-
-/* Mapped time, used for updating node information. */
-volatile struct mapped_time_value *maptime;
-
-/* Used by netfs_set_options to handle runtime option parsing. */
-struct argp *netfs_runtime_argp = &argp_runtime;
-
-/* Main entry point. */
-int
-main (int argc, char **argv)
-{
- mach_port_t bootstrap_port;
- error_t err = 0;
-
- root_update_init ();
-
- err = stow_init();
- if (err)
- error (EXIT_FAILURE, err, "failed to initialize stow support");
-
- /* Argument parsing. */
- argp_parse (&argp_startup, argc, argv, ARGP_IN_ORDER, 0, 0);
-
- err = node_create_root (&netfs_root_node);
- if (err)
- error (EXIT_FAILURE, err, "failed to create root node");
-
- /* netfs initialization. */
- task_get_bootstrap_port (mach_task_self (), &bootstrap_port);
- netfs_init ();
- underlying_node = netfs_startup (bootstrap_port, O_READ);
-
- err = node_init_root (netfs_root_node);
- if (err)
- error (EXIT_FAILURE, err, "failed to initialize root node");
-
- /* Map the time, used for updating node information. */
- err = maptime_map (0, 0, &maptime);
- if (err)
- error (EXIT_FAILURE, err, "maptime_map");
-
- /* More initialiazation. */
- ncache_init (ncache_size);
-
- /* Here we adjust the root node permissions. */
- err = io_stat (underlying_node, &underlying_node_stat);
-
- if (err)
- error (EXIT_FAILURE, err, "io_stat");
-
- fsid = getpid ();
- netfs_root_node->nn_stat = underlying_node_stat;
- netfs_root_node->nn_stat.st_ino = UNIONFS_ROOT_INODE; /* FIXME. */
- 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);
- netfs_root_node->nn_translated = netfs_root_node->nn_stat.st_mode;
-
- /* If the underlying node isn't a directory, enhance the stat
- information. */
- if (! S_ISDIR (underlying_node_stat.st_mode))
- {
- if (underlying_node_stat.st_mode & S_IRUSR)
- netfs_root_node->nn_stat.st_mode |= S_IXUSR;
- if (underlying_node_stat.st_mode & S_IRGRP)
- netfs_root_node->nn_stat.st_mode |= S_IXGRP;
- if (underlying_node_stat.st_mode & S_IROTH)
- 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);
-
- /* Start serving clients. */
- for (;;)
- netfs_server_loop ();
-}
diff --git a/unionfs/ncache.c b/unionfs/ncache.c
deleted file mode 100644
index 4c83ac0e..00000000
--- a/unionfs/ncache.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
- Written by Moritz Schulte <moritz@duesseldorf.ccc.de>.
-
- 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
-
-#include <hurd/netfs.h>
-#include <error.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#include "ncache.h"
-#include "lib.h"
-#include "unionfs.h"
-
-/* The node cache. */
-ncache_t ncache;
-
-/* Cache size, may be overwritten by the user. */
-int ncache_size = NCACHE_SIZE;
-
-/* Initialize the node cache, set the maximum number of allowed nodes
- in the cache to SIZE_MAX. */
-void
-ncache_init (int size_max)
-{
- ncache.mru = NULL;
- ncache.lru = NULL;
- ncache.size_max = size_max;
- ncache.size_current = 0;
- mutex_init (&ncache.lock);
-}
-
-/* Remove the given node NODE from the cache. */
-static void
-ncache_node_remove (node_t *node)
-{
- struct netnode *nn = node->nn;
-
- if (nn->ncache_next)
- nn->ncache_next->nn->ncache_prev = nn->ncache_prev;
- if (nn->ncache_prev)
- nn->ncache_prev->nn->ncache_next = nn->ncache_next;
- if (ncache.mru == node)
- ncache.mru = nn->ncache_next;
- if (ncache.lru == node)
- ncache.lru = nn->ncache_prev;
- nn->ncache_next = NULL;
- nn->ncache_prev = NULL;
- ncache.size_current--;
-}
-
-void
-ncache_reset (void)
-{
- node_t *node;
-
- mutex_lock (&ncache.lock);
- while ((node = ncache.mru))
- ncache_node_remove (node);
- mutex_unlock (&ncache.lock);
-}
-
-/* Lookup the node for the light node LNODE. If it does not exist
- anymore in the cache, create a new node. Store the looked up node
- in *NODE. */
-error_t
-ncache_node_lookup (lnode_t *lnode, node_t **node)
-{
- error_t err = 0;
- node_t *n;
-
- if (lnode->node)
- {
- debug_msg ("ncache_node_lookup for lnode: %s (found in cache)",
- lnode->name);
- n = lnode->node;
- netfs_nref (n);
- }
- else
- {
- debug_msg ("ncache_node_lookup for lnode: %s (newly created)",
- lnode->name);
- err = node_create (lnode, &n);
- }
-
- if (! err)
- {
- mutex_lock (&n->lock);
- *node = n;
- }
- return err;
-}
-
-/* Add the given node NODE to the node cache; remove
- least-recently-used nodes, if needed. */
-void
-ncache_node_add (node_t *node)
-{
- mutex_lock (&ncache.lock);
-
- debug_msg ("adding node to cache: %s", node->nn->lnode->name);
-
- if (ncache.size_max > 0 || ncache.size_current > 0)
- {
- if (ncache.mru != node)
- {
- if (node->nn->ncache_next || node->nn->ncache_prev)
- /* Node is already in the cache. */
- ncache_node_remove (node);
- else
- /* Add a reference from the cache. */
- netfs_nref (node);
-
- node->nn->ncache_next = ncache.mru;
- node->nn->ncache_prev = NULL;
- if (ncache.mru)
- ncache.mru->nn->ncache_prev = node;
- if (! ncache.lru)
- ncache.lru = node;
- ncache.mru = node;
- ncache.size_current++;
- }
- }
-
- /* Forget the least used nodes. */
- while (ncache.size_current > ncache.size_max)
- {
- struct node *lru = ncache.lru;
- debug_msg ("removing cached node: %s", lru->nn->lnode->name);
- ncache_node_remove (lru);
- netfs_nrele (lru);
- }
-
- mutex_unlock (&ncache.lock);
-}
diff --git a/unionfs/ncache.h b/unionfs/ncache.h
deleted file mode 100644
index 8fa7d107..00000000
--- a/unionfs/ncache.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
- Written by Moritz Schulte <moritz@duesseldorf.ccc.de>.
-
- 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. */
-
-#ifndef INCLUDED_NCACHE_H
-#define INCLUDED_NCACHE_H
-
-#include <error.h>
-#include <hurd/netfs.h>
-
-#include "node.h"
-
-typedef struct ncache
-{
- node_t *mru; /* Reference to the mru end of the
- cache chain. */
- node_t *lru; /* Reference to the lru end of the
- cache chain. */
- int size_max; /* Maximal number of nodes to
- cache. */
- int size_current; /* Current number of nodes in the
- cache. */
- struct mutex lock; /* A lock. */
-} ncache_t;
-
-/* Cache size, may be overwritten by the user. */
-extern int ncache_size;
-
-/* Initialize the node cache, set the maximum number of allowed nodes
- in the cache to SIZE_MAX. */
-void ncache_init (int size_max);
-
-/* Lookup the node for the light node LNODE. If it does not exist
- anymore in the cache, create a new node. Store the looked up node
- in *NODE. */
-error_t ncache_node_lookup (lnode_t *lnode, node_t **node);
-
-void ncache_reset (void);
-
-/* Add the given node NODE to the node cache; remove
- least-recently-used nodes, if needed. */
-void ncache_node_add (node_t *node);
-
-#endif
diff --git a/unionfs/netfs.c b/unionfs/netfs.c
deleted file mode 100644
index 89d1bf67..00000000
--- a/unionfs/netfs.c
+++ /dev/null
@@ -1,1170 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
- Written by Moritz Schulte <moritz@duesseldorf.ccc.de>.
-
- 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
-
-#include <hurd/netfs.h>
-#include <error.h>
-#include <argz.h>
-#include <stddef.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <string.h>
-#include <stdio.h>
-#include <hurd/paths.h>
-#include <sys/mman.h>
-
-#include "unionfs.h"
-#include "ulfs.h"
-#include "node.h"
-#include "lib.h"
-#include "ncache.h"
-#include "options.h"
-
-/* Return an argz string describing the current options. Fill *ARGZ
- with a pointer to newly malloced storage holding the list and *LEN
- to the length of that storage. */
-error_t
-netfs_append_args (char **argz, size_t *argz_len)
-{
- error_t err = 0;
-
- ulfs_iterate
- {
- if (! err)
- if (unionfs_flags & FLAG_UNIONFS_MODE_DEBUG)
- err = argz_add (argz, argz_len,
- OPT_LONG (OPT_LONG_DEBUG));
- if (! err)
- if (ulfs->flags & FLAG_ULFS_WRITABLE)
- err = argz_add (argz, argz_len,
- OPT_LONG (OPT_LONG_WRITABLE));
- if (! err)
- if (ulfs->priority)
- {
- char *buf = NULL;
- if ((err = asprintf (&buf, "%s=%s", OPT_LONG (OPT_LONG_PRIORITY),
- ulfs->priority)) != -1)
- {
- err = argz_add (argz, argz_len, buf);
- free (buf);
- }
- }
-
- if (! err)
- {
- if (ulfs->path)
- err = argz_add (argz, argz_len, ulfs->path);
- else
- err = argz_add (argz, argz_len,
- OPT_LONG (OPT_LONG_UNDERLYING));
- }
- }
-
- return err;
-}
-
-#ifndef __USE_FILE_OFFSET64
-#define OFFSET_T __off_t /* Size in bytes. */
-#else
-#define OFFSET_T __off64_t /* Size in bytes. */
-#endif
-
-static error_t
-_get_node_size (struct node *dir, OFFSET_T *off)
-{
- size_t size = 0;
- error_t err;
- int count = 0;
- node_dirent_t *dirent_start, *dirent_current;
- node_dirent_t *dirent_list = NULL;
- int first_entry = 2;
-
- int bump_size (const char *name)
- {
- size_t new_size = size + DIRENT_LEN (strlen (name));
-
- size = new_size;
- count ++;
- return 1;
- }
-
- err = node_entries_get (dir, &dirent_list);
- if (err)
- return err;
-
- for (dirent_start = dirent_list, count = 2;
- dirent_start && first_entry > count;
- dirent_start = dirent_start->next, count++);
-
- count = 0;
-
- /* Make space for the `.' and `..' entries. */
- if (first_entry == 0)
- bump_size (".");
- if (first_entry <= 1)
- bump_size ("..");
-
- /* See how much space we need for the result. */
- for (dirent_current = dirent_start;
- dirent_current;
- dirent_current = dirent_current->next)
- if (! bump_size (dirent_current->dirent->d_name))
- break;
-
- free (dirent_list);
-
- *off = size;
-
- return 0;
-}
-
-
-/* Make sure that NP->nn_stat is filled with current information.
- CRED identifies the user responsible for the operation. */
-error_t
-netfs_validate_stat (struct node *np, struct iouser *cred)
-{
- error_t err = 0;
-
- if (np != netfs_root_node)
- {
- if (! (np->nn->flags & FLAG_NODE_ULFS_UPTODATE))
- err = node_update (np);
- if (! err)
- {
- int done = 0;
-
- node_ulfs_iterate_unlocked (np)
- if ((! done) && port_valid (node_ulfs->port))
- {
- err = io_stat (node_ulfs->port, &np->nn_stat);
- if (! err)
- np->nn_translated = np->nn_stat.st_mode;
- done = 1;
- }
- if (! done)
- err = ENOENT; /* FIXME? */
- }
- }
- else
- {
- _get_node_size (np, &np->nn_stat.st_size);
- }
-
- return err;
-}
-
-/* This should attempt a chmod call for the user specified by CRED on
- locked node NP, to change the owner to UID and the group to GID. */
-error_t
-netfs_attempt_chown (struct iouser *cred, struct node *np,
- uid_t uid, uid_t gid)
-{
- return EOPNOTSUPP;
-}
-
-/* This should attempt a chauthor call for the user specified by CRED
- on locked node NP, thereby changing the author to AUTHOR. */
-error_t
-netfs_attempt_chauthor (struct iouser *cred, struct node *np,
- uid_t author)
-{
- return EOPNOTSUPP;
-}
-
-/* This should attempt a chmod call for the user specified by CRED on
- locked node NODE, to change the mode to MODE. Unlike the normal
- Unix and Hurd meaning of chmod, this function is also used to
- attempt to change files into other types. If such a transition is
- attempted which is impossible, then return EOPNOTSUPP. */
-error_t
-netfs_attempt_chmod (struct iouser *cred, struct node *np,
- mode_t mode)
-{
- return EOPNOTSUPP;
-}
-
-/* Attempt to turn locked node NP (user CRED) into a symlink with
- target NAME. */
-error_t
-netfs_attempt_mksymlink (struct iouser *cred, struct node *np,
- char *name)
-{
- return EOPNOTSUPP;
-}
-
-/* Attempt to turn NODE (user CRED) into a device. TYPE is either
- S_IFBLK or S_IFCHR. NP is locked. */
-error_t
-netfs_attempt_mkdev (struct iouser *cred, struct node *np,
- mode_t type, dev_t indexes)
-{
- return EOPNOTSUPP;
-}
-
-/* Attempt to set the passive translator record for FILE to ARGZ (of
- length ARGZLEN) for user CRED. NP is locked. */
-error_t
-netfs_set_translator (struct iouser *cred, struct node *np,
- char *argz, size_t argzlen)
-{
- return EOPNOTSUPP;
-}
-
-/* For locked node NODE with S_IPTRANS set in its mode, look up the
- name of its translator. Store the name into newly malloced
- storage, and return it in *ARGZ; set *ARGZ_LEN to the total length. */
-error_t
-netfs_get_translator (struct node *node, char **argz,
- size_t *argz_len)
-{
- return EOPNOTSUPP;
-}
-
-/* This should attempt a chflags call for the user specified by CRED
- on locked node NP, to change the flags to FLAGS. */
-error_t
-netfs_attempt_chflags (struct iouser *cred, struct node *np,
- int flags)
-{
- return EOPNOTSUPP;
-}
-
-/* This should attempt a utimes call for the user specified by CRED on
- locked node NP, to change the atime to ATIME and the mtime to
- MTIME. If ATIME or MTIME is null, then set to the current time. */
-error_t
-netfs_attempt_utimes (struct iouser *cred, struct node *np,
- struct timespec *atime, struct timespec *mtime)
-{
- return 0;
-}
-
-/* This should attempt to set the size of the locked file NP (for user
- CRED) to SIZE bytes long. */
-error_t
-netfs_attempt_set_size (struct iouser *cred, struct node *np,
- off_t size)
-{
- return EOPNOTSUPP;
-}
-
-/* This should attempt to fetch filesystem status information for the
- remote filesystem, for the user CRED. NP is locked. */
-error_t
-netfs_attempt_statfs (struct iouser *cred, struct node *np,
- struct statfs *st)
-{
- return EOPNOTSUPP;
-}
-
-/* This should sync the locked file NP completely to disk, for the
- user CRED. If WAIT is set, return only after the sync is
- completely finished. */
-error_t
-netfs_attempt_sync (struct iouser *cred, struct node *np,
- int wait)
-{
- return EOPNOTSUPP;
-}
-
-/* This should sync the entire remote filesystem. If WAIT is set,
- return only after the sync is completely finished. */
-error_t
-netfs_attempt_syncfs (struct iouser *cred, int wait)
-{
- return 0;
-}
-
-/* lookup */
-
-/* We don't use this functions, but it has to be defined. */
-error_t
-netfs_attempt_lookup (struct iouser *user, struct node *dir,
- char *name, struct node **node)
-{
- return EOPNOTSUPP;
-}
-
-/* Delete NAME in DIR (which is locked) for USER. */
-error_t
-netfs_attempt_unlink (struct iouser *user, struct node *dir,
- char *name)
-{
- error_t err = 0;
- mach_port_t p;
- struct stat statbuf;
-
- node_update (dir);
-
- err = node_lookup_file (dir, name, 0, &p, &statbuf);
- if (err)
- return err;
-
- port_dealloc (p);
-
- err = fshelp_checkdirmod (&dir->nn_stat, &statbuf, user);
- if (err)
- return err;
-
- err = node_unlink_file (dir, name);
-
- return err;
-}
-
-/* Attempt to rename the directory FROMDIR to TODIR. Note that neither
- of the specific nodes are locked. */
-error_t
-netfs_attempt_rename (struct iouser *user, struct node *fromdir,
- char *fromname, struct node *todir,
- char *toname, int excl)
-{
- return EOPNOTSUPP;
-}
-
-/* Attempt to create a new directory named NAME in DIR (which is
- locked) for USER with mode MODE. */
-error_t
-netfs_attempt_mkdir (struct iouser *user, struct node *dir,
- char *name, mode_t mode)
-{
- error_t err = 0;
- mach_port_t p;
- struct stat statbuf;
-
- node_update (dir);
-
- err = fshelp_checkdirmod (&dir->nn_stat, 0, user);
- if (err)
- goto exit;
-
- /* Special case for no UID processes (like login shell). */
- if ((!user->uids->ids) || (!user->uids->ids))
- {
- err = EACCES;
- goto exit;
- }
-
- err = node_dir_create (dir, name, mode);
- if (err)
- goto exit;
-
- err = node_lookup_file (dir, name, 0, &p, &statbuf);
- if (err)
- {
- node_dir_remove (dir, name);
- goto exit;
- }
-
- err = file_chown (p, user->uids->ids[0], user->gids->ids[0]);
- if (err)
- {
- port_dealloc (p);
- node_dir_remove (dir, name);
- goto exit;
- }
-
- port_dealloc (p);
-
- exit:
-
- return err;
-}
-
-/* Attempt to remove directory named NAME in DIR (which is locked) for
- USER. */
-error_t
-netfs_attempt_rmdir (struct iouser *user,
- struct node *dir, char *name)
-{
- error_t err = 0;
- mach_port_t p;
- struct stat statbuf;
-
- node_update (dir);
-
- err = node_lookup_file (dir, name, 0, &p, &statbuf);
- if (err)
- return err;
-
- port_dealloc (p);
-
- err = fshelp_checkdirmod (&dir->nn_stat, &statbuf, user);
- if (err)
- return err;
-
- err = node_dir_remove (dir, name);
-
- return err;
-}
-
-/* Create a link in DIR with name NAME to FILE for USER. Note that
- neither DIR nor FILE are locked. If EXCL is set, do not delete the
- target. Return EEXIST if NAME is already found in DIR. */
-error_t
-netfs_attempt_link (struct iouser *user, struct node *dir,
- struct node *file, char *name, int excl)
-{
- return EOPNOTSUPP;
-}
-
-/* Attempt to create an anonymous file related to DIR (which is
- locked) for USER with MODE. Set *NP to the returned file upon
- success. No matter what, unlock DIR. */
-error_t
-netfs_attempt_mkfile (struct iouser *user, struct node *dir,
- mode_t mode, struct node **np)
-{
- mutex_unlock (&dir->lock);
- return EOPNOTSUPP;
-}
-
-/* (We don't use this function!) Attempt to create a file named NAME
- in DIR (which is locked) for USER with MODE. Set *NP to the new
- node upon return. On any error, clear *NP. *NP should be locked
- on success; no matter what, unlock DIR before returning. */
-error_t
-netfs_attempt_create_file (struct iouser *user, struct node *dir,
- char *name, mode_t mode, struct node **np)
-{
- mutex_unlock (&dir->lock);
- return EOPNOTSUPP;
-}
-
-/* We use this local interface to attempt_create file since we are
- using our own netfs_S_dir_lookup. */
-error_t
-netfs_attempt_create_file_reduced (struct iouser *user, struct node *dir,
- char *name, mode_t mode, int flags)
-{
- mach_port_t p;
- error_t err;
- struct stat statbuf;
-
- node_update (dir);
-
- err = fshelp_checkdirmod (&dir->nn_stat, 0, user);
- if (err)
- goto exit;
-
- /* Special case for no UID processes (like login shell). */
- if ((!user->uids->ids) || (!user->uids->ids))
- {
- err = EACCES;
- goto exit;
- }
-
- mutex_unlock (&dir->lock);
- err = node_lookup_file (dir, name, flags | O_CREAT,
- &p, &statbuf);
- mutex_lock (&dir->lock);
-
- if (err)
- goto exit;
-
- err = file_chmod (p, mode);
- if (err)
- {
- port_dealloc (p);
- node_unlink_file (dir, name);
- goto exit;
- }
-
- err = file_chown (p, user->uids->ids[0], user->gids->ids[0]);
- if (err)
- {
- port_dealloc (p);
- node_unlink_file (dir, name);
- goto exit;
- }
-
- err = io_stat (p, &statbuf);
-
- /* Check file permissions. */
- if (! err && (flags & O_READ))
- err = fshelp_access (&statbuf, S_IREAD, user);
- if (! err && (flags & O_WRITE))
- err = fshelp_access (&statbuf, S_IWRITE, user);
- if (! err && (flags & O_EXEC))
- err = fshelp_access (&statbuf, S_IEXEC, user);
-
- if (err)
- {
- port_dealloc (p);
- node_unlink_file (dir, name);
- goto exit;
- }
-
- port_dealloc (p);
-
- exit:
- mutex_unlock (&dir->lock);
- return err;
-}
-
-/* Read the contents of locked node NP (a symlink), for USER, into
- BUF. */
-error_t
-netfs_attempt_readlink (struct iouser *user, struct node *np,
- char *buf)
-{
- return EOPNOTSUPP;
-}
-
-/* libnetfs uses this functions once. */
-error_t
-netfs_check_open_permissions (struct iouser *user, struct node *np,
- int flags, int newnode)
-{
- error_t err = 0;
-
- if (! err && (flags & O_READ))
- err = fshelp_access (&np->nn_stat, S_IREAD, user);
- if (! err && (flags & O_WRITE))
- err = fshelp_access (&np->nn_stat, S_IWRITE, user);
- if (! err && (flags & O_EXEC))
- err = fshelp_access (&np->nn_stat, S_IEXEC, user);
-
- return err;
-}
-
-/* Read from the locked file NP for user CRED starting at OFFSET and
- continuing for up to *LEN bytes. Put the data at DATA. Set *LEN
- to the amount successfully read upon return. */
-error_t
-netfs_attempt_read (struct iouser *cred, struct node *np,
- off_t offset, size_t *len, void *data)
-{
- *len = 0;
- return 0;
-}
-
-/* Write to the locked file NP for user CRED starting at OFSET and
- continuing for up to *LEN bytes from DATA. Set *LEN to the amount
- successfully written upon return. */
-error_t
-netfs_attempt_write (struct iouser *cred, struct node *np,
- off_t offset, size_t *len, void *data)
-{
- /* Since unionfs only manages directories... */
- return EISDIR;
-}
-
-/* Return the valid access types (bitwise OR of O_READ, O_WRITE, and
- O_EXEC) in *TYPES for locked file NP and user CRED. */
-error_t
-netfs_report_access (struct iouser *cred, struct node *np,
- int *types)
-{
- *types = 0;
- 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;
- return 0;
-}
-
-/* Create a new user from the specified UID and GID arrays. */
-struct iouser *
-netfs_make_user (uid_t *uids, int nuids, uid_t *gids, int ngids)
-{
- return NULL;
-}
-
-/* Node NP has no more references; free all its associated storage. */
-void
-netfs_node_norefs (struct node *np)
-{
- node_destroy (np);
-}
-
-error_t
-netfs_attempt_lookup_improved (struct iouser *user, struct node *dir,
- char *name, struct node **np,
- int flags, int lastcomp,
- mach_port_t *port,
- mach_msg_type_name_t *port_type)
-{
- mach_port_t p;
- error_t err;
-
- mutex_lock (&dir->nn->lnode->lock);
-
- err = fshelp_access (&dir->nn_stat, S_IEXEC, user);
- if (err)
- goto exit;
-
-
- if (! *name || ! strcmp (name, "."))
- {
-
- /* The same node is wanted. */
- *np = dir;
- netfs_nref (*np);
-
- }
- else if (! strcmp (name, ".."))
- {
-
- /* We have to get the according light node first. */
- lnode_t *lnode = dir->nn->lnode;
- node_t *node;
-
- err = ncache_node_lookup (lnode->dir, &node);
- if (err)
- goto exit;
-
- *np = node;
-
- }
- else
- {
-
- lnode_t *dir_lnode = dir->nn->lnode;
- struct stat statbuf;
- lnode_t *lnode = NULL;
-
- /* Lookup the node by it's name on the underlying
- filesystems. */
-
- err = node_update (dir);
-
- /* We have to unlock this node while doing lookups. */
- mutex_unlock (&dir_lnode->lock);
- mutex_unlock (&dir->lock);
-
- err = node_lookup_file (dir, name, flags & ~(O_NOLINK|O_CREAT),
- &p, &statbuf);
-
- mutex_lock (&dir->lock);
- mutex_lock (&dir_lnode->lock);
-
-
- if (err)
- goto exit;
-
- if (S_ISDIR (statbuf.st_mode))
- {
- node_t *node;
-
- /* We don't need this port directly. */
- port_dealloc (p);
-
- /* The found node is a directory, so we have to manage the
- node. First we need the light node. */
-
- err = lnode_get (dir_lnode, name, &lnode);
- if (err == ENOENT)
- {
- /* It does not exist, we have to create it. */
- err = lnode_create (name, &lnode);
- if (err)
- goto exit;
-
- lnode_install (dir_lnode, lnode);
- }
-
- /* Now we have a light node. */
- err = ncache_node_lookup (lnode, &node);
-
- /* This unlocks the node for us. */
- lnode_ref_remove (lnode);
-
- if (err)
- goto exit;
-
- /* Got the node. */
- *np = node;
-
- }
- else
- {
- /* The found node is not a directory. */
- mach_port_t p_restricted;
-
- if (! lastcomp)
- {
- /* We have not reached the last path component yet. */
- port_dealloc (p);
- err = ENOTDIR;
- goto exit;
- }
-
- /* Check file permissions. */
- if (! err && (flags & O_READ))
- err = fshelp_access (&statbuf, S_IREAD, user);
- if (! err && (flags & O_WRITE))
- err = fshelp_access (&statbuf, S_IWRITE, user);
- if (! err && (flags & O_EXEC))
- err = fshelp_access (&statbuf, S_IEXEC, user);
-
- if (err)
- {
- port_dealloc (p);
- goto exit;
- }
-
-
- /* A file node is successfully looked up. */
- err = io_restrict_auth (p, &p_restricted,
- user->uids->ids, user->uids->num,
- user->gids->ids, user->gids->num);
- port_dealloc (p);
-
- if (err)
- goto exit;
-
- /* Successfully restricted. */
- *port = p_restricted;
- *port_type = MACH_MSG_TYPE_MOVE_SEND;
- }
- }
-
- exit:
-
- if (err)
- *np = NULL;
- else if (*np)
- {
- mutex_unlock (&(*np)->lock);
- ncache_node_add (*np);
- }
-
- mutex_unlock (&dir->nn->lnode->lock);
- mutex_unlock (&dir->lock);
- return err;
-}
-
-/* We need our own, special implementation of netfs_S_dir_lookup,
- because libnetfs does not (yet?) know about cases, in which the
- servers wants to return (foreign) ports directly to the user,
- instead of usual node structures. */
-
-#define OPENONLY_STATE_MODES (O_CREAT|O_EXCL|O_NOLINK|O_NOTRANS|O_NONBLOCK)
-
-fshelp_fetch_root_callback1_t _netfs_translator_callback1;
-fshelp_fetch_root_callback2_t _netfs_translator_callback2;
-
-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_name_t *retry_port_type)
-{
- int create; /* true if O_CREAT flag set */
- int excl; /* true if O_EXCL flag set */
- int mustbedir = 0; /* true if the result must be S_IFDIR */
- int lastcomp = 0; /* true if we are at the last component */
- int newnode = 0; /* true if this node is newly created */
- int nsymlinks = 0;
- struct node *dnp, *np;
- char *nextname;
- error_t error = 0;
- struct protid *newpi;
- struct iouser *user;
-
- if (!diruser)
- return EOPNOTSUPP;
-
- create = (flags & O_CREAT);
- excl = (flags & O_EXCL);
-
- /* Skip leading slashes */
- while (*filename == '/')
- filename++;
-
- *retry_port_type = MACH_MSG_TYPE_MAKE_SEND;
- *do_retry = FS_RETRY_NORMAL;
- *retry_name = '\0';
-
- if (*filename == '\0')
- {
- /* Set things up in the state expected by the code from gotit: on. */
- dnp = 0;
- np = diruser->po->np;
- mutex_lock (&np->lock);
- netfs_nref (np);
- goto gotit;
- }
-
- dnp = diruser->po->np;
-
- mutex_lock (&dnp->lock);
-
- netfs_nref (dnp); /* acquire a reference for later netfs_nput */
-
- do
- {
- assert (!lastcomp);
-
- /* Find the name of the next pathname component */
- nextname = index (filename, '/');
-
- if (nextname)
- {
- *nextname++ = '\0';
- while (*nextname == '/')
- nextname++;
- if (*nextname == '\0')
- {
- /* These are the rules for filenames ending in /. */
- nextname = 0;
- lastcomp = 1;
- mustbedir = 1;
- create = 0;
- }
- else
- lastcomp = 0;
- }
- else
- lastcomp = 1;
-
- np = 0;
-
- retry_lookup:
-
- if ((dnp == netfs_root_node || dnp == diruser->po->shadow_root)
- && filename[0] == '.' && filename[1] == '.' && filename[2] == '\0')
- if (dnp == diruser->po->shadow_root)
- /* We're at the root of a shadow tree. */
- {
- *do_retry = FS_RETRY_REAUTH;
- *retry_port = diruser->po->shadow_root_parent;
- *retry_port_type = MACH_MSG_TYPE_COPY_SEND;
- if (! lastcomp)
- strcpy (retry_name, nextname);
- error = 0;
- mutex_unlock (&dnp->lock);
- goto out;
- }
- else if (diruser->po->root_parent != MACH_PORT_NULL)
- /* We're at a real translator root; even if DIRUSER->po has a
- shadow root, we can get here if its in a directory that was
- renamed out from under it... */
- {
- *do_retry = FS_RETRY_REAUTH;
- *retry_port = diruser->po->root_parent;
- *retry_port_type = MACH_MSG_TYPE_COPY_SEND;
- if (!lastcomp)
- strcpy (retry_name, nextname);
- error = 0;
- mutex_unlock (&dnp->lock);
- goto out;
- }
- else
- /* We are global root */
- {
- error = 0;
- np = dnp;
- netfs_nref (np);
- }
- else
- /* Attempt a lookup on the next pathname component. */
- error = netfs_attempt_lookup_improved (diruser->user, dnp,
- filename, &np,
- flags, lastcomp,
- retry_port, retry_port_type);
-
- /* At this point, DNP is unlocked */
-
- /* Implement O_EXCL flag here */
- if (lastcomp && create && excl && !error && np)
- error = EEXIST;
-
- /* Create the new node if necessary */
- if (lastcomp && create && error == ENOENT)
- {
- mode &= ~(S_IFMT | S_ISPARE | S_ISVTX);
- mode |= S_IFREG;
- mutex_lock (&dnp->lock);
-
- error = netfs_attempt_create_file_reduced (diruser->user, dnp,
- filename, mode, flags);
-
- /* We retry lookup in two cases:
- - we created the file and we have to get a valid port;
- - someone has already created the file (between our lookup
- and this create) then we just got EEXIST. If we are EXCL,
- that's fine; otherwise, we have to retry the lookup. */
- if ((!error) || (error == EEXIST && !excl))
- {
- mutex_lock (&dnp->lock);
- goto retry_lookup;
- }
-
- newnode = 1;
- }
-
- /* All remaining errors get returned to the user */
- if (error)
- goto out;
-
- if (np)
- {
- mutex_lock (&np->lock);
- error = netfs_validate_stat (np, diruser->user);
- mutex_unlock (&np->lock);
- if (error)
- goto out;
- }
-
- if (np
- && S_ISLNK (np->nn_translated)
- && (!lastcomp
- || mustbedir /* "foo/" must see that foo points to a dir */
- || !(flags & (O_NOLINK|O_NOTRANS))))
- {
- size_t nextnamelen, newnamelen, linklen;
- char *linkbuf;
-
- /* Handle symlink interpretation */
- if (nsymlinks++ > netfs_maxsymlinks)
- {
- error = ELOOP;
- goto out;
- }
-
- linklen = np->nn_stat.st_size;
-
- nextnamelen = nextname ? strlen (nextname) + 1 : 0;
- newnamelen = nextnamelen + linklen + 1;
- linkbuf = alloca (newnamelen);
-
- error = netfs_attempt_readlink (diruser->user, np, linkbuf);
- if (error)
- goto out;
-
- if (nextname)
- {
- linkbuf[linklen] = '/';
- memcpy (linkbuf + linklen + 1, nextname,
- nextnamelen - 1);
- }
- linkbuf[nextnamelen + linklen] = '\0';
-
- if (linkbuf[0] == '/')
- {
- /* Punt to the caller */
- *do_retry = FS_RETRY_MAGICAL;
- *retry_port = MACH_PORT_NULL;
- strcpy (retry_name, linkbuf);
- goto out;
- }
-
- filename = linkbuf;
- if (lastcomp)
- {
- lastcomp = 0;
-
- /* Symlinks to nonexistent files aren't allowed to cause
- creation, so clear the flag here. */
- create = 0;
- }
- netfs_nput (np);
- mutex_lock (&dnp->lock);
- np = 0;
- }
- else
- {
- /* Normal nodes here for next filename component */
- filename = nextname;
- netfs_nrele (dnp);
-
- if (lastcomp)
- dnp = 0;
- else
- {
- dnp = np;
- np = 0;
- }
- }
- }
- while (filename && *filename);
-
- /* At this point, NP is the node to return. */
- gotit:
-
- if (mustbedir && ! np)
- {
- error = ENOTDIR;
- goto out;
- }
-
- if (np)
- error = netfs_check_open_permissions (diruser->user, np,
- flags, newnode);
-
- if (error)
- goto out;
-
- flags &= ~OPENONLY_STATE_MODES;
-
- if (np)
- {
- error = iohelp_dup_iouser (&user, diruser->user);
- if (error)
- goto out;
-
- newpi = netfs_make_protid (netfs_make_peropen (np, flags, diruser->po),
- user);
- if (! newpi)
- {
- iohelp_free_iouser (user);
- error = errno;
- goto out;
- }
-
- *retry_port = ports_get_right (newpi);
- ports_port_deref (newpi);
- }
-
- out:
- if (np)
- netfs_nput (np);
- if (dnp)
- netfs_nrele (dnp);
- return error;
-}
-
-/* Fill the array *DATA of size BUFSIZE with up to NENTRIES dirents
- from DIR (which is locked) starting with entry ENTRY for user CRED.
- The number of entries in the array is stored in *AMT and the number
- of bytes in *DATACNT. If the supplied buffer is not large enough
- to hold the data, it should be grown. */
-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)
-{
- node_dirent_t *dirent_start, *dirent_current;
- node_dirent_t *dirent_list = NULL;
- size_t size = 0;
- int count = 0;
- char *data_p;
- error_t err;
-
- int bump_size (const char *name)
- {
- if (num_entries == -1 || count < num_entries)
- {
- size_t new_size = size + DIRENT_LEN (strlen (name));
-
- if (max_data_len > 0 && new_size > max_data_len)
- return 0;
- size = new_size;
- count++;
- return 1;
- }
- else
- return 0;
- }
-
- int add_dirent (const char *name, ino_t fileno, int type)
- {
- if (num_entries == -1 || count < num_entries)
- {
- struct dirent hdr;
- size_t name_len = strlen (name);
- size_t sz = DIRENT_LEN (name_len);
-
- if (sz > size)
- return 0;
- else
- size -= sz;
-
- hdr.d_fileno = fileno;
- hdr.d_reclen = sz;
- hdr.d_type = type;
- hdr.d_namlen = name_len;
-
- memcpy (data_p, &hdr, DIRENT_NAME_OFFS);
- strcpy (data_p + DIRENT_NAME_OFFS, name);
- data_p += sz;
- count++;
-
- return 1;
- }
- else
- return 0;
- }
-
- err = node_entries_get (dir, &dirent_list);
-
- if (! err)
- {
- for (dirent_start = dirent_list, count = 2;
- dirent_start && first_entry > count;
- dirent_start = dirent_start->next, count++);
-
- count = 0;
-
- /* Make space for the `.' and `..' entries. */
- if (first_entry == 0)
- bump_size (".");
- if (first_entry <= 1)
- bump_size ("..");
-
- /* See how much space we need for the result. */
- for (dirent_current = dirent_start;
- dirent_current;
- dirent_current = dirent_current->next)
- if (! bump_size (dirent_current->dirent->d_name))
- break;
-
- *data = mmap (0, size, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
- err = ((void *) *data == (void *) -1) ? errno : 0;
- }
-
- if (! err)
- {
- data_p = *data;
- *data_len = size;
- *data_entries = count;
- count = 0;
-
- /* Add `.' and `..' entries. */
- if (first_entry == 0)
- add_dirent (".", 2, DT_DIR);
- if (first_entry <= 1)
- add_dirent ("..", 2, DT_DIR);
-
- for (dirent_current = dirent_start;
- dirent_current;
- dirent_current = dirent_current->next)
- if (! add_dirent (dirent_current->dirent->d_name,
- 2 /* FIXME */,
- dirent_current->dirent->d_type))
- break;
- }
-
- if (dirent_list)
- node_entries_free (dirent_list);
-
- fshelp_touch (&dir->nn_stat, TOUCH_ATIME, maptime);
-
- return err;
-}
diff --git a/unionfs/node.c b/unionfs/node.c
deleted file mode 100644
index cf9a8b47..00000000
--- a/unionfs/node.c
+++ /dev/null
@@ -1,555 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
- Written by Moritz Schulte <moritz@duesseldorf.ccc.de>.
-
- 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. */
-
-/* node management. */
-
-#define _GNU_SOURCE
-
-#include <hurd/netfs.h>
-#include <stdlib.h>
-#include <error.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <stdio.h>
-
-#include "unionfs.h"
-#include "node.h"
-#include "ulfs.h"
-#include "lib.h"
-
-/* Declarations for functions only used in this file. */
-
-/* Deallocate all ports contained in NODE and free per-ulfs data
- structures. */
-void node_ulfs_free (node_t *node);
-
-/* Create a new node, derived from a light node, add a reference to
- the light node. */
-error_t
-node_create (lnode_t *lnode, node_t **node)
-{
- netnode_t *netnode_new = malloc (sizeof (netnode_t));
- error_t err = 0;
- node_t *node_new;
-
- debug_msg ("node_create for lnode: %s", lnode->name);
-
- if (! netnode_new)
- {
- err = ENOMEM;
- return err;
- }
-
- node_new = netfs_make_node (netnode_new);
- if (! node_new)
- {
- err = ENOMEM;
- free (netnode_new);
- return err;
- }
-
- node_new->nn->ulfs = NULL;
-
- err = node_ulfs_init (node_new);
- if (err)
- {
- node_destroy (node_new);
- return err;
- }
-
- lnode->node = node_new;
- lnode_ref_add (lnode);
- node_new->nn->lnode = lnode;
- node_new->nn->flags = 0;
- node_new->nn->ncache_next = NULL;
- node_new->nn->ncache_prev = NULL;
- *node = node_new;
-
- return err;
-}
-
-/* Destroy a node, remove one reference from the associated light
- node. */
-void
-node_destroy (node_t *node)
-{
- debug_msg ("node destroy: %s", node->nn->lnode->name);
- assert (! (node->nn->ncache_next || node->nn->ncache_prev));
- node_ulfs_free (node);
- mutex_lock (&node->nn->lnode->lock);
- node->nn->lnode->node = NULL;
- lnode_ref_remove (node->nn->lnode);
- free (node->nn);
- free (node);
-}
-
-/* Make sure that all ports to the underlying filesystems of NODE,
- which must be locked, are uptodate. */
-error_t
-node_update (node_t *node)
-{
- error_t err = 0;
- char *path;
-
- node_ulfs_t *root_ulfs;
- struct stat stat;
- file_t port;
- int i = 0;
-
- debug_msg ("node_update for lnode: %s", node->nn->lnode->name);
-
- if (node_is_root (node))
- return err;
-
- mutex_lock (&netfs_root_node->lock);
-
- err = lnode_path_construct (node->nn->lnode, &path);
- if (err)
- {
- mutex_unlock (&netfs_root_node->lock);
- return err;
- }
-
- root_ulfs = netfs_root_node->nn->ulfs;
-
- node_ulfs_iterate_unlocked (node)
- {
-
- if (node_ulfs->flags & FLAG_NODE_ULFS_FIXED)
- {
- i++;
- continue;
- }
-
- /* We really have to update the port. */
- if (port_valid (node_ulfs->port))
- port_dealloc (node_ulfs->port);
-
- err = file_lookup ((root_ulfs + i)->port, path,
- O_READ | O_NOTRANS, O_NOTRANS,
- 0, &port, &stat);
-
- if (err)
- {
- node_ulfs->port = MACH_PORT_NULL;
- err = 0;
- i++;
- continue;
- }
-
- if (stat.st_ino == underlying_node_stat.st_ino
- && stat.st_fsid == underlying_node_stat.st_fsid)
- /* It's OUR root node. */
- err = ELOOP;
- else
- {
- port_dealloc (port);
- err = file_lookup ((root_ulfs + i)->port, path,
- O_READ, 0, 0, &port, &stat);
- }
-
- if (err)
- {
- port = MACH_PORT_NULL;
- err = 0;
- }
- node_ulfs->port = port;
-
- i++;
- }
-
- free (path);
- node->nn->flags |= FLAG_NODE_ULFS_UPTODATE;
-
- mutex_unlock (&netfs_root_node->lock);
-
- return err;
-}
-
-/* Remove all directory named NAME beneath DIR on all underlying filesystems.
- Fails if we cannot remove all the directories. */
-error_t
-node_dir_remove (node_t *dir, char *name)
-{
- error_t err = 0;
-
- node_ulfs_iterate_reverse_unlocked (dir)
- {
- if (!port_valid (node_ulfs->port))
- continue;
-
- err = dir_rmdir (node_ulfs->port, name);
- if ((err) && (err != ENOENT))
- break;
- }
-
- return err;
-}
-
-/* Create a directory named NAME beneath DIR on the first (writable) underlying
- filesystem. */
-error_t
-node_dir_create (node_t *dir, char *name, mode_t mode)
-{
- error_t err = 0;
-
- node_ulfs_iterate_unlocked (dir)
- {
- if (!port_valid (node_ulfs->port))
- continue;
-
- err = dir_mkdir (node_ulfs->port, name, mode);
-
- if ((!err) || (err == EEXIST) || (err == ENOTDIR))
- break;
- }
-
- return err;
-}
-
-/* Remove all files named NAME beneath DIR on the underlying filesystems
- with FLAGS as openflags. */
-error_t
-node_unlink_file (node_t *dir, char *name)
-{
- mach_port_t p;
- struct stat stat;
- error_t err = 0;
- int removed = 0;
-
- /* Using reverse iteration still have issues. Infact, we could be
- deleting a file in some underlying filesystem, and keeping those
- after the first occurring error.
- FIXME: Check BEFORE starting deletion. */
-
- node_ulfs_iterate_reverse_unlocked (dir)
- {
-
- if (!port_valid (node_ulfs->port))
- continue;
-
- err = file_lookup (node_ulfs->port, name,
- O_NOTRANS, O_NOTRANS,
- 0, &p, &stat);
-
- port_dealloc (p);
-
- if (err == ENOENT)
- {
- err = 0;
- continue;
- }
-
- if (err)
- break;
-
- err = dir_unlink (node_ulfs->port, name);
- if ((err) && (err != ENOENT))
- break;
-
- if (!err)
- removed++;
-
- }
-
- if ((!err) && (!removed))
- err = ENOENT;
-
- return err;
-}
-
-/* Lookup a file named NAME beneath DIR on the underlying filesystems
- with FLAGS as openflags. Return the first port successfully looked
- up in *PORT and according stat information in *STAT. */
-error_t
-node_lookup_file (node_t *dir, char *name, int flags,
- file_t *port, struct stat *s)
-{
- error_t err = ENOENT;
- struct stat stat;
- file_t p;
-
- node_ulfs_iterate_unlocked (dir)
- {
-
- if (err != ENOENT)
- break;
-
- if (!port_valid (node_ulfs->port))
- continue;
-
- err = file_lookup (node_ulfs->port, name,
- flags | O_NOTRANS, O_NOTRANS,
- 0, &p, &stat);
- if (err)
- continue;
-
- if (stat.st_ino == underlying_node_stat.st_ino
- && stat.st_fsid == underlying_node_stat.st_fsid)
- /* It's OUR root node. */
- err = ELOOP;
- else
- /* stat.st_mode & S_ITRANS */
- {
- port_dealloc (p);
- err = file_lookup (node_ulfs->port, name,
- flags, 0, 0, &p, &stat);
- }
- }
-
- if (! err)
- {
- *s = stat;
- *port = p;
- }
-
- return err;
-}
-
-/* Deallocate all ports contained in NODE and free per-ulfs data
- structures. */
-void
-node_ulfs_free (node_t *node)
-{
-
- node_ulfs_iterate_unlocked (node)
- {
- if (port_valid (node_ulfs->port)
- && node_ulfs->port != underlying_node)
- port_dealloc (node_ulfs->port);
- }
-
- free (node->nn->ulfs);
-}
-
-/* Initialize per-ulfs data structures for NODE. The ulfs_lock must
- be held by the caller. */
-error_t
-node_ulfs_init (node_t *node)
-{
- node_ulfs_t *ulfs_new;
- error_t err = 0;
-
- ulfs_new = malloc (ulfs_num * sizeof (node_ulfs_t));
- if (! ulfs_new)
- {
- err = ENOMEM;
- return err;
- }
-
- if (node->nn->ulfs)
- node_ulfs_free (node);
-
- node->nn->ulfs = ulfs_new;
- node->nn->ulfs_num = ulfs_num;
-
- node_ulfs_iterate_unlocked (node)
- {
- node_ulfs->flags = 0;
- node_ulfs->port = port_null;
- }
-
- return err;
-}
-
-/* Read the merged directory entries from NODE, which must be
- locked, into *DIRENTS. */
-error_t
-node_entries_get (node_t *node, node_dirent_t **dirents)
-{
- struct dirent **dirent_list, **dirent;
- node_dirent_t *node_dirent_list = NULL;
- size_t dirent_data_size;
- char *dirent_data;
- error_t err = 0;
-
- /* Add a dirent to the list. If an entry with the specified name
- already exists, reuse that entry. Otherwise create a new
- one. */
- error_t node_dirent_add (char *name, ino_t fileno, int type)
- {
- error_t e = 0;
- node_dirent_t *node_dirent;
- node_dirent_t *node_dirent_new;
- struct dirent *dirent_new;
- int name_len = strlen (name);
- int size = DIRENT_LEN (name_len);
-
-
- for (node_dirent = node_dirent_list;
- node_dirent && strcmp (node_dirent->dirent->d_name, name);
- node_dirent = node_dirent->next);
-
- if (node_dirent)
- {
- /* Reuse existing entry. */
-
- node_dirent->dirent->d_fileno = fileno;
- node_dirent->dirent->d_type = type;
- return e;
- }
-
- /* Create new entry. */
-
- node_dirent_new = malloc (sizeof (node_dirent_t));
- if (!node_dirent_new)
- {
- e = ENOMEM;
- return e;
- }
-
- dirent_new = malloc (size);
- if (!dirent_new)
- {
- free (node_dirent_new);
- e = ENOMEM;
- return e;
- }
-
- /* Fill dirent. */
- dirent_new->d_fileno = fileno;
- dirent_new->d_type = type;
- dirent_new->d_reclen = size;
- strcpy ((char *) dirent_new + DIRENT_NAME_OFFS, name);
-
- /* Add dirent to the list. */
- node_dirent_new->dirent = dirent_new;
- node_dirent_new->next = node_dirent_list;
- node_dirent_list = node_dirent_new;
-
- return e;
- }
-
- node_ulfs_iterate_unlocked(node)
- {
- if (!port_valid (node_ulfs->port))
- continue;
-
- err = dir_entries_get (node_ulfs->port, &dirent_data,
- &dirent_data_size, &dirent_list);
- if (err)
- continue;
-
- for (dirent = dirent_list; (! err) && *dirent; dirent++)
- if (strcmp ((*dirent)->d_name, ".")
- && strcmp ((*dirent)->d_name, ".."))
- err = node_dirent_add ((*dirent)->d_name,
- (*dirent)->d_fileno,
- (*dirent)->d_type);
-
- free (dirent_list);
- munmap (dirent_data, dirent_data_size);
- }
-
- if (err)
- node_entries_free (node_dirent_list);
- else
- *dirents = node_dirent_list;
-
- return err;
-}
-
-/* Free DIRENTS. */
-void
-node_entries_free (node_dirent_t *dirents)
-{
- node_dirent_t *dirent, *dirent_next;
-
- for (dirent = dirents; dirent; dirent = dirent_next)
- {
- dirent_next = dirent->next;
- free (dirent->dirent);
- free (dirent);
- }
-}
-
-/* Create the root node (and it's according lnode) and store it in
- *ROOT_NODE. */
-error_t
-node_create_root (node_t **root_node)
-{
- lnode_t *lnode;
- node_t *node;
- error_t err = 0;
-
- err = lnode_create (NULL, &lnode);
- if (err)
- return err;
-
- err = node_create (lnode, &node);
- if (err)
- {
- lnode_destroy (lnode);
- return err;
- }
-
- mutex_unlock (&lnode->lock);
- *root_node = node;
- return err;
-}
-
-/* Initialize the ports to the underlying filesystems for the root
- node. */
-
-error_t
-node_init_root (node_t *node)
-{
- error_t err;
- ulfs_t *ulfs;
- int i = 0;
-
- mutex_lock (&ulfs_lock);
-
- err = node_ulfs_init (node);
- if (err)
- {
- mutex_unlock (&ulfs_lock);
- return err;
- }
-
- node_ulfs_iterate_unlocked (node)
- {
-
- if (err)
- break;
-
- err = ulfs_get_num (i, &ulfs);
- if (err)
- break;
-
- if (ulfs->path)
- node_ulfs->port = file_name_lookup (ulfs->path,
- O_READ | O_DIRECTORY, 0);
- else
- node_ulfs->port = underlying_node;
-
- if (! port_valid (node_ulfs->port))
- {
- err = errno;
- break;
- }
-
- node_ulfs->flags |= FLAG_NODE_ULFS_FIXED;
- i++;
- }
-
- mutex_unlock (&ulfs_lock);
- return err;
-}
diff --git a/unionfs/node.h b/unionfs/node.h
deleted file mode 100644
index 41ae43ad..00000000
--- a/unionfs/node.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
- Written by Moritz Schulte <moritz@duesseldorf.ccc.de>.
-
- 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. */
-
-/* node management. */
-
-#ifndef INCLUDED_NODE_H
-#define INCLUDED_NODE_H
-
-#include <error.h>
-#include <sys/stat.h>
-#include <hurd/netfs.h>
-
-typedef struct node node_t;
-
-#include "lnode.h"
-
-/* per-ulfs data for each node. */
-struct node_ulfs
-{
- int flags; /* Flags associated for this
- underlying filesystem. */
- file_t port; /* A port to the underlying
- filesystem. */
-};
-typedef struct node_ulfs node_ulfs_t;
-
-/* Flags. */
-
-/* The according port should not be updated. */
-#define FLAG_NODE_ULFS_FIXED 0x00000001
-
-struct netnode
-{
- lnode_t *lnode; /* A reference to the according light
- node. */
- int flags; /* Associated flags. */
- node_ulfs_t *ulfs; /* Array holding data for each
- underlying filesystem. */
- int ulfs_num; /* Number of entries in ULFS. */
- node_t *ncache_next;
- node_t *ncache_prev;
-};
-typedef struct netnode netnode_t;
-
-/* Flags. */
-#define FLAG_NODE_INVALIDATE 0x00000001
-#define FLAG_NODE_ULFS_UPTODATE 0x00000002
-
-typedef struct node_dirent
-{
- struct dirent *dirent;
- struct node_dirent *next;
-} node_dirent_t;
-
-/* Create a new node, derived from a light node, add a reference to
- the light node. */
-error_t node_create (lnode_t *lnode, node_t **node);
-
-/* Destroy a node, remove one reference from the associated light
- node. */
-void node_destroy (node_t *node);
-
-/* Make sure that all ports to the underlying filesystems of NODE,
- which must be locked, are uptodate. */
-error_t node_update (node_t *node);
-
-/* Create a directory named NAME beneath DIR on all the (writable) underlying
- filesystems. */
-error_t node_dir_create (node_t *dir, char *name, mode_t mode);
-
-/* Remove all directory named NAME beneath DIR on all underlying filesystems.
- Fails if we cannot remove all the directories. */
-error_t node_dir_remove (node_t *dir, char *name);
-
-/* Remove all files named NAME beneath DIR on the underlying filesystems
- with FLAGS as openflags. */
-error_t node_unlink_file (node_t *dir, char *name);
-
-/* Lookup a file named NAME beneath DIR on the underlying filesystems
- with FLAGS as openflags. Return the first port successfully looked
- up in *PORT and according stat information in *STAT. */
-error_t node_lookup_file (node_t *dir, char *name, int flags,
- file_t *port, struct stat *stat);
-
-/* Initialize per-ulfs data structures for NODE. The ulfs_lock must
- be held by the caller. */
-error_t node_ulfs_init (node_t *node);
-
-/* Read the merged directory entries from NODE, which must be
- locked, into *DIRENTS. */
-error_t node_entries_get (node_t *node, node_dirent_t **dirents);
-
-/* Free DIRENTS. */
-void node_entries_free (node_dirent_t *dirents);
-
-/* Create the root node (and it's according lnode) and store it in
- *ROOT_NODE. */
-error_t node_create_root (node_t **root_node);
-
-/* Initialize the ports to the underlying filesystems for the root
- node. */
-error_t node_init_root (node_t *node);
-
-/* Return non-zero, if NODE is the root node. */
-#define node_is_root(node) (node)->nn->lnode->dir ? 0 : 1
-
-/* Iterate over the per-ulfs data in NODE, which must be locked by the
- caller. */
-#define node_ulfs_iterate_unlocked(node) \
- for (node_ulfs_t *node_ulfs = (node)->nn->ulfs; \
- node_ulfs < (node)->nn->ulfs + (node)->nn->ulfs_num; \
- node_ulfs++)
-
-#define node_ulfs_iterate_reverse_unlocked(node) \
- for (node_ulfs_t *node_ulfs = (node)->nn->ulfs + (node)->nn->ulfs_num - 1;\
- node_ulfs >= (node)->nn->ulfs; \
- node_ulfs--)
-
-#endif
diff --git a/unionfs/options.c b/unionfs/options.c
deleted file mode 100644
index ef29a020..00000000
--- a/unionfs/options.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
- Written by Moritz Schulte <moritz@duesseldorf.ccc.de>.
-
- 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. */
-
-/* Argument parsing. */
-
-#define _GNU_SOURCE
-
-#include <argp.h>
-#include <error.h>
-
-#include "options.h"
-#include "ulfs.h"
-#include "ncache.h"
-#include "unionfs.h"
-#include "node.h"
-#include "version.h"
-#include "pattern.h"
-#include "stow.h"
-#include "update.h"
-
-/* This variable is set to a non-zero value after parsing of the
- startup options. Whenever the argument parser is later called to
- modify the underlying filesystems of the root node, the root node
- is initialized accordingly directly by the parser. */
-static int parsing_startup_options_finished;
-
-/* Argp options common to the runtime and startup parser. */
-static const struct argp_option argp_common_options[] =
- {
- { OPT_LONG_UNDERLYING, OPT_UNDERLYING, 0, 0,
- "add the underlying node to the unionfs" },
- { OPT_LONG_WRITABLE, OPT_WRITABLE, 0, 0,
- "specify the following filesystem as writable" },
- { OPT_LONG_DEBUG, OPT_DEBUG, 0, OPTION_HIDDEN,
- "send debugging messages to stderr" },
- { OPT_LONG_CACHE_SIZE, OPT_CACHE_SIZE, "SIZE", 0,
- "specify the maximum number of nodes in the cache" },
- { 0, 0, 0, 0, "Runtime options:", 1 },
- { OPT_LONG_STOW, OPT_STOW, "STOWDIR", 0,
- "stow given directory", 1},
- { OPT_LONG_PRIORITY, OPT_PRIORITY, "VALUE", 0,
- "Set the priority for the following filesystem to VALUE", 1},
- { OPT_LONG_PATTERN, OPT_PATTERN, "PATTERN", 0,
- "add only nodes of the underlying filesystem matching pattern", 1},
- { OPT_LONG_REMOVE, OPT_REMOVE, 0, 0,
- "remove the following filesystem", 1 },
- { OPT_LONG_ADD, OPT_ADD, 0, 0,
- "add the following filesystem (Default)", 1 },
- { 0 }
- };
-
-/* Argp options only meaningful for startup parsing. */
-static const struct argp_option argp_startup_options[] =
- {
- { 0 }
- };
-
-/* Argp parser function for the common options. */
-static error_t
-argp_parse_common_options (int key, char *arg, struct argp_state *state)
-{
- static int ulfs_flags = 0, ulfs_mode = 0, ulfs_modified = 0,
- ulfs_match = 0, ulfs_priority = 0;
- static struct patternlist ulfs_patternlist =
- {
- .lock = MUTEX_INITIALIZER,
- .head = NULL
- };
- error_t err = 0;
-
- switch (key)
- {
- case OPT_WRITABLE: /* --writable */
- ulfs_flags |= FLAG_ULFS_WRITABLE;
- break;
-
- case OPT_PRIORITY: /* --priority */
- ulfs_priority = strtol (arg, NULL, 10);
- break;
-
- case OPT_DEBUG: /* --debug */
- unionfs_flags |= FLAG_UNIONFS_MODE_DEBUG;
- break;
-
- case OPT_CACHE_SIZE: /* --cache-size */
- ncache_size = strtol (arg, NULL, 10);
- break;
-
- case OPT_ADD: /* --add */
- ulfs_mode = ULFS_MODE_ADD;
- break;
-
- case OPT_REMOVE: /* --remove */
- ulfs_mode = ULFS_MODE_REMOVE;
- break;
-
- case OPT_PATTERN: /* --match */
- ulfs_match = 1;
- patternlist_add (&ulfs_patternlist, arg);
- break;
-
- case OPT_STOW: /* --stow */
- err = stow_diradd (arg, ulfs_flags, &ulfs_patternlist, ulfs_priority);
- if (err)
- error (EXIT_FAILURE, err, "stow_diradd");
- ulfs_modified = 1;
- ulfs_flags = ulfs_mode = ulfs_priority = 0;
- ulfs_match = 0;
- break;
-
- case OPT_UNDERLYING: /* --underlying */
- case ARGP_KEY_ARG:
-
- if (ulfs_mode == ULFS_MODE_REMOVE)
- {
- err = ulfs_unregister (arg);
- if (err == ENOENT)
- /* It is not a fatal error, when the user tries to remove
- a filesystem, which is not used by unionfs. */
- err = 0;
- }
- else
- err = ulfs_register (arg, ulfs_flags, ulfs_priority);
- if (err)
- error (EXIT_FAILURE, err, "ulfs_register");
- ulfs_modified = 1;
- ulfs_flags = ulfs_mode = ulfs_priority = 0;
- ulfs_match = 0;
- break;
-
- case ARGP_KEY_END:
- ulfs_flags = ulfs_mode = 0;
- if (ulfs_modified && parsing_startup_options_finished)
- {
- root_update_schedule ();
- }
- else
- {
- ncache_reset ();
- }
- ulfs_modified = 0;
-
- if (! parsing_startup_options_finished)
- parsing_startup_options_finished = 1;
- break;
-
- default:
- err = ARGP_ERR_UNKNOWN;
- break;
- }
-
- return err;
-}
-
-/* Argp parser function for the startup oprtions. */
-static error_t
-argp_parse_startup_options (int key, char *arg, struct argp_state *state)
-{
- error_t err = 0;
-
- switch (key)
- {
- default:
- err = ARGP_ERR_UNKNOWN;
- break;
- }
-
- return err;
-}
-
-/* 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 parser for only the startup options. */
-static struct argp argp_parser_startup_options =
- { argp_startup_options, argp_parse_startup_options, 0, 0, 0 };
-
-/* The children parser for runtime arguments. */
-static const struct argp_child argp_children_runtime[] =
- {
- { &argp_parser_common_options },
- { &netfs_std_runtime_argp },
- { 0 }
- };
-
-/* The children parser for startup arguments. */
-const struct argp_child argp_children_startup[] =
- {
- { &argp_parser_startup_options },
- { &argp_parser_common_options },
- { &netfs_std_startup_argp },
- { 0 }
- };
-
-const char *argp_program_version = STANDARD_HURD_VERSION (unionfs);
-const char *argp_program_bug_address =
-"Gianluca Guida <glguida@gmail.com>";
-
-#define ARGS_DOC "FILESYSTEMS ..."
-#define DOC "Hurd unionfs server"
-
-/* The final argp parser for runtime arguments. */
-struct argp argp_runtime =
- { 0, 0, 0, 0, argp_children_runtime };
-
-/* The final argp parser for startup arguments. */
-struct argp argp_startup =
- { 0, 0, ARGS_DOC, DOC, argp_children_startup };
diff --git a/unionfs/options.h b/unionfs/options.h
deleted file mode 100644
index eb74ce61..00000000
--- a/unionfs/options.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
- Written by Moritz Schulte <moritz@duesseldorf.ccc.de>.
-
- 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. */
-
-/* Argument parsing. */
-
-/* The possible short options. */
-#define OPT_UNDERLYING 'u'
-#define OPT_WRITABLE 'w'
-#define OPT_DEBUG 'd'
-#define OPT_CACHE_SIZE 'c'
-#define OPT_REMOVE 'r'
-#define OPT_ADD 'a'
-#define OPT_PATTERN 'm'
-#define OPT_PRIORITY 'p'
-#define OPT_STOW 's'
-
-/* The long options. */
-#define OPT_LONG_UNDERLYING "underlying"
-#define OPT_LONG_WRITABLE "writable"
-#define OPT_LONG_DEBUG "debug"
-#define OPT_LONG_CACHE_SIZE "cache-size"
-#define OPT_LONG_REMOVE "remove"
-#define OPT_LONG_ADD "add"
-#define OPT_LONG_PATTERN "match"
-#define OPT_LONG_PRIORITY "priority"
-#define OPT_LONG_STOW "stow"
-
-#define OPT_LONG(o) "--" o
-
-/* The final argp parser for runtime arguments. */
-extern struct argp argp_startup;
-
-/* The final argp parser for startup arguments. */
-extern struct argp argp_runtime;
-
-#define ULFS_MODE_ADD 0
-#define ULFS_MODE_REMOVE 1
diff --git a/unionfs/pattern.c b/unionfs/pattern.c
deleted file mode 100644
index 68a07917..00000000
--- a/unionfs/pattern.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
- Written by Gianluca Guida <glguida@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. */
-
-/* Pattern list management. */
-
-#define _GNU_SOURCE
-
-#include <hurd/netfs.h>
-#include <stdlib.h>
-#include <fnmatch.h>
-#include <errno.h>
-
-#include "pattern.h"
-
-/* Add a wildcard expression *PATTERN to **PATTERNLIST. */
-error_t
-patternlist_add (struct patternlist *list, char *pattern)
-{
- error_t err = 0;
- struct pattern *listentry;
- char *dup;
-
- if (pattern == NULL) /* BUG. */
- err = EINVAL;
-
- if (err)
- return err;
-
- dup = strdup (pattern);
- if (dup == NULL)
- err = ENOMEM;
-
- if (err)
- return err;
-
- listentry = malloc (sizeof (struct pattern));
- if (listentry == NULL)
- err = ENOMEM;
-
- if (err)
- return err;
-
- listentry->pattern = dup;
-
- mutex_lock (& (list->lock));
- if (list->head == NULL) /* List is empty. */
- {
- list->head = listentry;
- listentry->next = NULL;
- }
- else
- {
- listentry->next = list->head;
- list->head = listentry;
- }
- mutex_unlock (& (list->lock));
-
- return err;
-}
-
-/* Check for match all pattern of the list *LIST, returning logical OR
- of results. */
-int
-patternlist_match (struct patternlist *list, char *string)
-{
- struct pattern *ptr;
- error_t err = ~0; /* Return false by default */
-
- ptr = list->head;
-
- mutex_lock (&list->lock);
- while (ptr != NULL)
- {
- err = fnmatch (ptr->pattern, string, FNM_FILE_NAME);
-
- if (!err) /* String matched. */
- break;
-
- ptr = ptr->next;
- }
- mutex_unlock (&list->lock);
-
- return err;
-}
-
-/* Free all resource used by *PATTERNLIST. */
-void
-patternlist_destroy (struct patternlist *list)
-{
- struct pattern *next, *ptr = list->head;
-
- mutex_lock (& (list->lock));
- while (ptr != NULL)
- {
- next = ptr->next;
-
- free (ptr);
-
- ptr = next;
- }
- mutex_unlock (& (list->lock));
-}
-
-/* Return nonzero if *PATTERNLIST is empty. */
-int
-patternlist_isempty (struct patternlist *list)
-{
- int ret;
-
- mutex_lock (& (list->lock));
- ret = (list->head == NULL);
- mutex_unlock (& (list->lock));
-
- return ret;
-}
diff --git a/unionfs/pattern.h b/unionfs/pattern.h
deleted file mode 100644
index 1bab9933..00000000
--- a/unionfs/pattern.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
- Written by Gianluca Guida <glguida@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. */
-
-/* Pattern list management. */
-
-#ifndef _PATTERN_H
-#define _PATTERN_H
-
-#include <hurd/netfs.h> /* For mutex stuff. */
-
-struct pattern
-{
- char *pattern;
-
- struct pattern *next;
-};
-
-struct patternlist
-{
- struct mutex lock;
- struct pattern *head;
-};
-
-/* Add a wildcard expression *PATTERN to **PATTERNLIST. */
-extern error_t patternlist_add (struct patternlist *list, char *pattern);
-
-/* Check for match all pattern of the list *LIST, returning logical OR
- of results. */
-extern int patternlist_match (struct patternlist *list, char *string);
-
-/* Free all resource used by *PATTERNLIST */
-extern void patternlist_destroy (struct patternlist *list);
-
-/* Return nonzero if *PATTERNLIST is empty */
-extern int patternlist_isempty (struct patternlist *list);
-
-#endif /* _PATTERN_H */
diff --git a/unionfs/stow-mutations.h b/unionfs/stow-mutations.h
deleted file mode 100644
index d36280d2..00000000
--- a/unionfs/stow-mutations.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* stow-mutations.h - MIG mutations unionfs.
- Copyright (C) 2005 Free Software Foundation, Inc.
- Written by Gianluca Guida <glguida@gmail.com>.
-
- This file is part of the GNU Hurd.
-
- The GNU Hurd 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, or (at
- your option) any later version.
-
- The GNU Hurd 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, USA. */
-
-/* Only CPP macro definitions should go in this file. */
-
-#define FS_NOTIFY_INTRAN stow_notify_t begin_using_notify_port (fs_notify_t)
-#define FS_NOTIFY_DESTRUCTOR end_using_notify_port (stow_notify_t)
-
-#define FS_NOTIFY_IMPORTS import "stow-priv.h";
-
diff --git a/unionfs/stow-priv.h b/unionfs/stow-priv.h
deleted file mode 100644
index 2212ac98..00000000
--- a/unionfs/stow-priv.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2005 Free Software Foundation, Inc.
- Written by Gianluca Guida <glguida@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. */
-
-#ifndef __STOW_PRIVDATA_H__
-#define __STOW_PRIVDATA_H__
-
-#include <hurd/ports.h>
-
-struct stow_notify
-{
- struct port_info pi;
-
- char *dir_name;
- struct stow_privdata *priv;
-};
-typedef struct stow_notify *stow_notify_t;
-
-
-/* Called by MiG to translate ports into stow_notify_t. mutations.h
- arranges for this to happen for the fs_notify interfaces. */
-stow_notify_t begin_using_notify_port (fs_notify_t port);
-
-
-/* Called by MiG after server routines have been run; this balances
- begin_using_notify_port, and is arranged for the fs_notify
- interfaces by mutations.h. */
-void end_using_notify_port (stow_notify_t cred);
-
-#endif /* STOW_PRIVDATA_H */
diff --git a/unionfs/stow.c b/unionfs/stow.c
deleted file mode 100644
index fa997472..00000000
--- a/unionfs/stow.c
+++ /dev/null
@@ -1,328 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2005 Free Software Foundation, Inc.
- Written by Gianluca Guida <glguida@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. */
-
-
-/* Stow mode for unionfs. */
-
-#define _GNU_SOURCE
-
-#include <argp.h>
-#include <error.h>
-
-#include "ulfs.h"
-#include "lib.h"
-#include "pattern.h"
-#include "update.h"
-
-struct stow_privdata
-{
- struct patternlist *patternlist;
- int flags;
- int priority;
- struct mutex lock;
-};
-
-static error_t
-_stow_registermatchingdirs (char *arg, char *dirpath, void *priv)
-{
- error_t err = 0;
- char *filepath;
-
- struct stow_privdata *privdata = (struct stow_privdata *) priv ;
-
- err = patternlist_match (privdata->patternlist, arg);
- if (err)
- return 0; /* It doesn't match. This is not an error. */
-
- filepath = make_filepath (dirpath, arg);
-
- err = ulfs_register (filepath, privdata->flags, privdata->priority);
-
- free (filepath);
-
- if (err)
- return err;
-
- return 0;
-}
-
-static error_t
-_stow_scanstowentry (char *arg, char *dirpath, void *priv)
-{
- char *filepath = dirpath;
- error_t err;
-
- struct stow_privdata *privdata = (struct stow_privdata *) priv ;
-
- if (dirpath)
- {
- char *tmp;
- tmp = make_filepath (dirpath, arg);
- filepath = make_filepath (tmp, "/");
- free (tmp);
- }
-
- mutex_lock (&privdata->lock);
-
- if (patternlist_isempty (privdata->patternlist))
- {
-
- err = ulfs_register (filepath, privdata->flags, privdata->priority);
- if (err)
- {
- mutex_unlock (&privdata->lock);
- return err;
- }
-
- }
- else
- {
- err = for_each_subdir_priv (filepath, _stow_registermatchingdirs, priv);
- if (err)
- {
- mutex_unlock (&privdata->lock);
- free (filepath);
- return err;
- }
- }
-
- free (filepath);
- mutex_unlock (&privdata->lock);
- return err;
-}
-
-
-/* Implement server for fs_notify. */
-
-#include <cthreads.h>
-#include <hurd/port.h>
-
-#include "stow-priv.h"
-#include "ncache.h"
-
-struct port_bucket *stow_port_bucket;
-struct port_class *stow_port_class;
-
-static error_t
-_stow_notify_init(char *dir_name, void *priv)
-{
- error_t err;
- file_t dir_port;
- mach_port_t notify_port;
- stow_notify_t stow_notify_port;
-
- err = ports_create_port (stow_port_class, stow_port_bucket,
- sizeof (*stow_notify_port),
- &stow_notify_port);
- if (err)
- return err;
-
- stow_notify_port->dir_name = dir_name;
- stow_notify_port->priv = priv;
-
- dir_port = file_name_lookup (dir_name, 0, 0);
-
- if (!port_valid (dir_port))
- return ENOENT; /* ? */
-
-
- notify_port = ports_get_right (stow_notify_port);
-
- if (!port_valid (notify_port))
- {
- port_dealloc (dir_port);
- return EACCES; /* ? */
- }
-
- err = dir_notice_changes (dir_port, notify_port,
- MACH_MSG_TYPE_MAKE_SEND);
- if (err)
- {
- port_dealloc (dir_port);
- port_dealloc (notify_port);
- return err;
- }
-
- return err;
-}
-
-/* Called by MiG to translate ports into stow_notify_t. mutations.h
- arranges for this to happen for the fs_notify interfaces. */
-stow_notify_t
-begin_using_notify_port (fs_notify_t port)
-{
- return ports_lookup_port (stow_port_bucket, port, stow_port_class);
-}
-
-/* Called by MiG after server routines have been run; this balances
- begin_using_notify_port, and is arranged for the fs_notify
- interfaces by mutations.h. */
-void
-end_using_notify_port (stow_notify_t cred)
-{
- if (cred)
- ports_port_deref (cred);
-}
-
-/* We don't ask for file_changes, but this function has to be defined . */
-kern_return_t
-stow_S_file_changed (stow_notify_t notify, natural_t tickno,
- file_changed_type_t change, loff_t start,
- loff_t end)
-{
- return EOPNOTSUPP;
-}
-
-/* Called when we receive a dir_changed message. */
-kern_return_t
-stow_S_dir_changed (stow_notify_t notify, natural_t tickno,
- dir_changed_type_t change, string_t name)
-{
- error_t err;
-
- if (!notify || !notify->dir_name || !notify->priv)
- return EOPNOTSUPP;
-
- switch (change)
- {
- case DIR_CHANGED_NULL:
- break;
- case DIR_CHANGED_NEW:
- root_update_disable ();
-
- err = _stow_scanstowentry (name, notify->dir_name, notify->priv);
- if (err)
- debug_msg_send ("scanstowentry: %s\n", strerror (err));
-
- root_update_schedule ();
- root_update_enable ();
- break;
-
- case DIR_CHANGED_UNLINK:
- root_update_schedule ();
- break;
-
- default:
- debug_msg_send ("unsupported dir change notify");
- return EINVAL;
- }
-
- return 0;
-}
-
-/* This is the server thread waiting for dir_changed messages. */
-static void
-_stow_notify_thread()
-{
- int stow_demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp)
- {
- int stow_fs_notify_server (mach_msg_header_t *inp,
- mach_msg_header_t *outp);
-
- return (stow_fs_notify_server (inp, outp));
- }
-
- do
- {
- ports_manage_port_operations_multithread (stow_port_bucket,
- stow_demuxer,
- 1000 * 60 * 2,
- 1000 * 60 * 10,
- 0);
- }
- while (1);
-}
-
-
-
-/* Interface to unionfs. */
-
-error_t
-stow_diradd (char *dir, int flags, struct patternlist *patternlist,
- int priority)
-{
-
- error_t err;
- struct stow_privdata *mypriv;
- int dir_len;
-
- dir_len = strlen(dir);
- if (dir_len == 0)
- {
- return EOPNOTSUPP;
- }
-
- if (dir[dir_len - 1 ] != '/')
- {
- char *tmp;
-
- tmp = (char *) malloc (dir_len + 1);
-
- if (tmp == NULL)
- return ENOMEM;
-
- strncpy (tmp, dir, dir_len);
-
- tmp[dir_len] = '/';
-
- dir = tmp;
- }
-
- mypriv = malloc (sizeof (struct stow_privdata));
- if (!mypriv)
- {
- free (dir);
- return ENOMEM;
- }
-
- mypriv->patternlist = patternlist;
- mypriv->flags = flags;
- mypriv->priority = priority;
- mutex_init (&mypriv->lock);
-
- err = for_each_subdir_priv (dir, _stow_scanstowentry, (void *)mypriv);
- if (err)
- {
- /* FIXME: rescan and delete previous inserted things. */
- return err;
- }
-
- err = _stow_notify_init (dir, mypriv);
- assert (!err);
-
- return err;
-}
-
-error_t
-stow_init (void)
-{
- error_t err = 0;
-
- stow_port_bucket = ports_create_bucket ();
- if (!stow_port_bucket)
- return errno;
-
- stow_port_class = ports_create_class (NULL, NULL);
- if (!stow_port_class)
- return errno;
-
- cthread_detach (cthread_fork ( (cthread_fn_t)_stow_notify_thread, 0));
-
- return err;
-}
diff --git a/unionfs/stow.h b/unionfs/stow.h
deleted file mode 100644
index 54ff7060..00000000
--- a/unionfs/stow.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2005 Free Software Foundation, Inc.
- Written by Gianluca Guida <glguida@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. */
-
-/* Stow mode for unionfs. */
-
-#ifndef _STOW_H
-#define _STOW_H
-
-#include "pattern.h"
-
-error_t stow_init (void);
-error_t stow_diradd (char *, int, struct patternlist *, int);
-
-#endif /* _STOW_H */
diff --git a/unionfs/ulfs.c b/unionfs/ulfs.c
deleted file mode 100644
index 3c565a5c..00000000
--- a/unionfs/ulfs.c
+++ /dev/null
@@ -1,321 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
- Written by Moritz Schulte <moritz@duesseldorf.ccc.de>.
-
- 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. */
-
-/* Underlying filesystem management. */
-
-#define _GNU_SOURCE
-
-#include <hurd/netfs.h>
-#include <stdlib.h>
-#include <error.h>
-#include <string.h>
-
-#include "unionfs.h"
-#include <fcntl.h>
-
-#include "lib.h"
-#include "ulfs.h"
-
-/* The start of the ulfs chain. */
-ulfs_t *ulfs_chain_start;
-
-/* The end of the ulfs chain, we need this, to go through the chain in
- reversed order. */
-ulfs_t *ulfs_chain_end;
-
-/* Number of registered underlying filesystems. */
-unsigned int ulfs_num;
-
-/* The lock protecting the ulfs data structures. */
-struct mutex ulfs_lock = MUTEX_INITIALIZER;
-
-/* Create a new ulfs element. */
-static error_t
-ulfs_create (char *path, ulfs_t **ulfs)
-{
- ulfs_t *ulfs_new = malloc (sizeof (ulfs_t));
- error_t err = 0;
-
- if (! ulfs_new)
- err = ENOMEM;
- else
- {
- char *path_cp = path ? strdup (path) : NULL;
-
- if (path && (! path_cp))
- {
- err = ENOMEM;
- free (ulfs_new);
- }
- else
- {
- ulfs_new->path = path_cp;
- ulfs_new->flags = 0;
- ulfs_new->next = NULL;
- ulfs_new->prev = NULL;
- *ulfs = ulfs_new;
- }
- }
- return err;
-}
-
-/* Destroy an ulfs element. */
-static void
-ulfs_destroy (ulfs_t *ulfs)
-{
- free (ulfs->path);
- free (ulfs);
-}
-
-/* Install ULFS into the linked list of registered filesystems in
- * priority order. */
-static void
-ulfs_install (ulfs_t *ulfs)
-{
- ulfs_t *u = ulfs_chain_start;
- int insert_at_end = 0;
- if (ulfs_num == 0)
- {
- ulfs_chain_start = ulfs;
- return;
- }
-
- /* walk the chain until a filesystem has a priority that's too high. */
- while (u->priority > ulfs->priority)
- {
- if (u->next == NULL)
- {
- insert_at_end = 1;
- break;
- }
- u = u->next;
- }
-
- if (insert_at_end)
- {
- u->next = ulfs;
- ulfs->prev = u;
- }
- else
- {
- if (u == ulfs_chain_start)
- {
- ulfs_chain_start = ulfs;
- ulfs->next = u;
- ulfs->prev = NULL;
- u->prev = ulfs;
- }
- else
- {
- ulfs->next = u;
- ulfs->prev = u->prev;
- u->prev->next = ulfs;
- u->prev = ulfs;
- }
- }
-
- return;
-}
-
-/* Remove ULFS from the linked list of registered filesystems. */
-static void
-ulfs_uninstall (ulfs_t *ulfs)
-{
- if (ulfs == ulfs_chain_start)
- ulfs_chain_start = ulfs->next;
-
- if (ulfs->next)
- ulfs->next->prev = ulfs->prev;
-
- if (ulfs->prev)
- ulfs->prev->next = ulfs->next;
-}
-
-/* Get an ulfs element by it's index. */
-error_t
-ulfs_get_num (int num, ulfs_t **ulfs)
-{
- error_t err = EINVAL;
- ulfs_t *u;
- int i;
-
- for (u = ulfs_chain_start, i = 0;
- u && i < num;
- u = u->next, i++);
- if (u)
- {
- err = 0;
- *ulfs = u;
- }
-
- return err;
-}
-
-/* Get an ulfs element by the associated path. */
-static error_t
-ulfs_get_path (char *path, ulfs_t **ulfs)
-{
- error_t err = ENOENT;
- ulfs_t *u;
-
- for (u = ulfs_chain_start;
- u && (! (((! path) && path == u->path)
- || (path && u->path && (! strcmp (path, u->path)))));
- u = u->next);
- if (u)
- {
- err = 0;
- *ulfs = u;
- }
- return err;
-}
-
-error_t
-ulfs_for_each_under_priv (char *path_under,
- error_t (*func) (char *, char *, void *),
- void *priv)
-{
- error_t err = 0;
- ulfs_t *u;
- size_t length;
-
- length = strlen (path_under);
-
- for (u = ulfs_chain_start; u; u = u->next)
- {
- if (!u->path)
- continue;
-
- if (memcmp (u->path, path_under, length))
- continue;
-
- /* This ulfs is under path_under. */
- func ((char *)(u->path + length), path_under, priv);
- }
-
- return err;
-}
-
-/* Register a new underlying filesystem. */
-error_t
-ulfs_register (char *path, int flags, int priority)
-{
- ulfs_t *ulfs;
- error_t err;
-
- if (path)
- {
- err = check_dir (path);
- if (err)
- return err;
- }
-
- mutex_lock (&ulfs_lock);
- err = ulfs_create (path, &ulfs);
- if (! err)
- {
- ulfs->flags = flags;
- ulfs->priority = priority;
- ulfs_install (ulfs);
- ulfs_num++;
- }
- mutex_unlock (&ulfs_lock);
- return err;
-}
-
-/* Check for deleted ulfs entries. */
-/* FIXME: Ugly as hell. Rewrite the whole ulfs.c */
-void
-ulfs_check ()
-{
- ulfs_t *u;
- file_t p;
-
- struct ulfs_destroy
- {
- ulfs_t *ulfs;
-
- struct ulfs_destroy *next;
- } *ulfs_destroy_q = NULL;
-
- mutex_lock (&ulfs_lock);
-
- u = ulfs_chain_start;
- while (u)
- {
-
- if (u->path)
- p = file_name_lookup (u->path, O_READ | O_DIRECTORY, 0);
- else
- p = underlying_node;
-
- if (! port_valid (p))
- {
- struct ulfs_destroy *ptr;
-
- /* Add to destroy list. */
- ptr = malloc (sizeof (struct ulfs_destroy));
- assert (ptr);
-
- ptr->ulfs = u;
-
- ptr->next = ulfs_destroy_q;
- ulfs_destroy_q = ptr;
- }
-
- u = u->next;
- }
-
- while (ulfs_destroy_q)
- {
- struct ulfs_destroy *ptr;
-
- ptr = ulfs_destroy_q;
- ulfs_destroy_q = ptr->next;
-
- ulfs_uninstall (ptr->ulfs);
- ulfs_destroy (ptr->ulfs);
- ulfs_num--;
-
- free (ptr);
- }
-
- mutex_unlock (&ulfs_lock);
-
-}
-
-/* Unregister an underlying filesystem. */
-error_t
-ulfs_unregister (char *path)
-{
- ulfs_t *ulfs;
- error_t err;
-
- mutex_lock (&ulfs_lock);
- err = ulfs_get_path (path, &ulfs);
- if (! err)
- {
- ulfs_uninstall (ulfs);
- ulfs_destroy (ulfs);
- ulfs_num--;
- }
- mutex_unlock (&ulfs_lock);
-
- return err;
-}
diff --git a/unionfs/ulfs.h b/unionfs/ulfs.h
deleted file mode 100644
index 532e3c74..00000000
--- a/unionfs/ulfs.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
- Written by Moritz Schulte <moritz@duesseldorf.ccc.de>.
-
- 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. */
-
-/* Underlying filesystem management. */
-
-#ifndef INCLUDED_ULFS_H
-#define INCLUDED_ULFS_H
-
-/* The structure for each registered underlying filesystem. */
-typedef struct ulfs
-{
- char *path;
- int flags;
- int priority;
- struct ulfs *next, *prev;
-} ulfs_t;
-
-/* Flags. */
-
-/* The according ulfs is marked writable. */
-#define FLAG_ULFS_WRITABLE 0x00000001
-
-/* The start of the ulfs chain. */
-extern ulfs_t *ulfs_chain_start;
-
-/* The end of the ulfs chain, we need this, to go through the chain in
- reversed order. */
-extern ulfs_t *ulfs_chain_end;
-
-/* Number of registered underlying filesystems. */
-extern unsigned int ulfs_num;
-
-/* The lock protecting the ulfs data structures. */
-extern struct mutex ulfs_lock;
-
-/* Register a new underlying filesystem. */
-error_t ulfs_register (char *path, int flags, int priority);
-
-/* Unregister an underlying filesystem. */
-error_t ulfs_unregister (char *path);
-
-/* Get an ULFS element by it's index. */
-error_t ulfs_get_num (int num, ulfs_t **ulfs);
-
-/* Removes invalid ulfs entries. */
-void ulfs_check (void);
-
-#define ulfs_iterate \
- for (ulfs_t *ulfs = (mutex_lock (&ulfs_lock), \
- ulfs_chain_start); \
- ulfs || (mutex_unlock (&ulfs_lock), 0); \
- ulfs = ulfs->next)
-
-#define ulfs_iterate_unlocked \
- for (ulfs_t *ulfs = ulfs_chain_start; \
- ulfs; \
- ulfs = ulfs->next)
-
-#endif
diff --git a/unionfs/unionfs.h b/unionfs/unionfs.h
deleted file mode 100644
index 8f5a0873..00000000
--- a/unionfs/unionfs.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
- Written by Moritz Schulte <moritz@duesseldorf.ccc.de>.
-
- 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. */
-
-/* This unionfs knows about two different kind of nodes: `light nodes'
- (in short: lnode) and `nodes' (or: netfs nodes) as used by
- libnetfs. They have different tasks and therefore this division
- makes sense.
-
- lnodes form the filesystem tree as seen by the user; most
- importantly they contain the `name' of the node.
-
- lnodes are small and cheap, they are not cached (nodes are).
-
- lnodes are usually created when a node is looked up and destroyed
- when that node gets destroyed; but there are also reasons for
- lnodes _not_ being destroyed.
-
- The distinction makes it possible to keep certain information for
- the unionfs in these lnodes while netfs nodes don't have to stay in
- memory.
-
- lnodes have to be looked up first before a node is looked up. Each
- lnode contains a pointer to the netfs node, which might be NULL in
- case the netfs node is not in memory anymore. */
-
-/* General information and properties for the unionfs. */
-
-#ifndef INCLUDED_UNIONFS_H
-#define INCLUDED_UNIONFS_H
-
-#include <hurd/netfs.h>
-#include <sys/types.h>
-
-#include "node.h"
-#include "lib.h"
-
-/* Default maximum number of nodes in the cache. */
-#define NCACHE_SIZE 256
-
-/* The inode for the root node. */
-#define UNIONFS_ROOT_INODE 1
-
-/* Flags for UNIONFS_FLAGS. */
-
-/* Print debugging messages to stderr. */
-#define FLAG_UNIONFS_MODE_DEBUG 0x00000001
-/* Use copy-on-write. */
-#define FLAG_UNIONFS_MODE_COW 0x00000002
-
-/* Flags describing certain properties of the unionfs. */
-extern int unionfs_flags;
-
-/* The filesystem id (the pid). */
-extern pid_t fsid;
-
-/* Mapped time, used for updating node information. */
-extern volatile struct mapped_time_value *maptime;
-
-/* A port to the underlying node. */
-extern mach_port_t underlying_node;
-
-/* stat information for the underlying node. */
-extern struct stat underlying_node_stat;
-
-/* Send a debugging message, if unionfs is in debugging mode. */
-#define debug_msg(fmt, args...) \
- do \
- { \
- if (unionfs_flags & FLAG_UNIONFS_MODE_DEBUG) \
- debug_msg_send (fmt , ## args); \
- } \
- while (0)
-
-#endif
diff --git a/unionfs/update.c b/unionfs/update.c
deleted file mode 100644
index 8ec66883..00000000
--- a/unionfs/update.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2005 Free Software Foundation, Inc.
- Written by Gianluca Guida <glguida@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. */
-
-/* Update thread: A clean way to solve locking issues of
- root node update. */
-
-#define _GNU_SOURCE
-
-#include <errno.h>
-#include <string.h>
-#include <cthreads.h>
-#include <rwlock.h>
-
-#include "ncache.h"
-#include "node.h"
-#include "ulfs.h"
-
-/* Reader lock is used by threads that are going to
- add/remove an ulfs; writer lock is hold by the
- update thread. */
-static struct rwlock update_rwlock;
-static struct condition update_wakeup;
-static struct mutex update_lock;
-
-static void
-_root_update_thread ()
-{
- error_t err;
-
- while (1)
- {
- if (hurd_condition_wait (&update_wakeup, &update_lock))
- mutex_unlock (&update_lock);
-
- rwlock_writer_lock (&update_rwlock);
-
- do
- {
- ulfs_check();
- err = node_init_root (netfs_root_node);
- }
- while (err == ENOENT);
-
- if (err)
- {
- fprintf (stderr, "update thread: got a %s\n", strerror (err));
- }
-
- ncache_reset ();
-
- rwlock_writer_unlock (&update_rwlock);
- }
-}
-
-void
-root_update_schedule ()
-{
- condition_signal (&update_wakeup);
-}
-
-void
-root_update_disable ()
-{
- rwlock_reader_lock (&update_rwlock);
-}
-
-void
-root_update_enable ()
-{
- rwlock_reader_unlock (&update_rwlock);
-}
-
-void
-root_update_init()
-{
- mutex_init (&update_lock);
- rwlock_init (&update_rwlock);
- condition_init (&update_wakeup);
-
- cthread_detach (cthread_fork ( (cthread_fn_t)_root_update_thread, 0));
-}
diff --git a/unionfs/update.h b/unionfs/update.h
deleted file mode 100644
index 6ebd6fc6..00000000
--- a/unionfs/update.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Hurd unionfs
- Copyright (C) 2005 Free Software Foundation, Inc.
- Written by Gianluca Guida <glguida@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. */
-
-#ifndef _UDPATE_H
-#define _UPDATE_H
-
-void root_update_schedule ();
-void root_update_disable ();
-void root_update_enable ();
-void root_update_init ();
-
-#endif /* UPDATE_H */
diff --git a/unionfs/version.h b/unionfs/version.h
deleted file mode 100644
index 8969db31..00000000
--- a/unionfs/version.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Hurd version
- Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
- Written by Thomas Bushnell, n/BSG.
-
- This file is part of the GNU Hurd.
-
- The GNU Hurd 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, or (at
- your option) any later version.
-
- The GNU Hurd 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, USA. */
-
-#ifndef HURD_VERSION
-#define HURD_VERSION "0.3"
-#endif
-
-/* The standard way to print versions for --version. */
-#define STANDARD_HURD_VERSION(s) \
- #s " (GNU Hurd) " HURD_VERSION
-#define STANDARD_HURD_VERSION_EXTRA(s, extra) \
- #s " (GNU Hurd; " extra ") " HURD_VERSION