From 30e8eb3e135291717eceaae69162fceb91d30aa1 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Thu, 11 Nov 2004 15:20:05 +0000 Subject: [PATCH] move perl python and lufis directories one level up --- lufis/.cvsignore | 1 - lufis/COPYING | 340 ---------- lufis/ChangeLog | 8 - lufis/Makefile | 21 - lufis/README | 50 -- lufis/dircache.c | 478 -------------- lufis/dircache.h | 75 --- lufis/list.h | 171 ----- lufis/lufis.c | 800 ----------------------- lufis/options.c | 301 --------- perl/.cvsignore | 1 - perl/AUTHORS | 4 - perl/Changes | 12 - perl/Fuse.pm | 360 ---------- perl/Fuse.xs | 572 ---------------- perl/MANIFEST | 7 - perl/Makefile.PL | 17 - perl/README | 69 -- perl/examples/example.pl | 90 --- perl/examples/loopback.pl | 136 ---- perl/examples/rmount.pl | 82 --- perl/examples/rmount_remote.pl | 143 ---- perl/test.pl | 8 - perl/test/chmod.t | 11 - perl/test/chown.t | 14 - perl/test/getattr.t | 42 -- perl/test/getdir.t | 33 - perl/test/helper.pm | 23 - perl/test/link.t | 16 - perl/test/mkdir.t | 11 - perl/test/mknod.t | 37 -- perl/test/open.t | 10 - perl/test/read.t | 13 - perl/test/readlink.t | 11 - perl/test/rename.t | 12 - perl/test/rmdir.t | 13 - perl/test/s/mount.t | 25 - perl/test/s/umount.t | 7 - perl/test/statfs.t | 21 - perl/test/symlink.t | 19 - perl/test/test-template | 5 - perl/test/truncate.t | 12 - perl/test/unlink.t | 14 - perl/test/utime.t | 13 - perl/test/write.t | 45 -- python/AUTHORS | 4 - python/ChangeLog | 6 - python/INSTALL | 8 - python/Makefile | 15 - python/README | 92 --- python/_fusemodule.c | 552 ---------------- python/code.leo | 1120 -------------------------------- python/fuse.py | 121 ---- python/setup.py | 21 - python/xmp.py | 187 ------ 55 files changed, 6279 deletions(-) delete mode 100644 lufis/.cvsignore delete mode 100644 lufis/COPYING delete mode 100644 lufis/ChangeLog delete mode 100644 lufis/Makefile delete mode 100644 lufis/README delete mode 100644 lufis/dircache.c delete mode 100644 lufis/dircache.h delete mode 100644 lufis/list.h delete mode 100644 lufis/lufis.c delete mode 100644 lufis/options.c delete mode 100644 perl/.cvsignore delete mode 100644 perl/AUTHORS delete mode 100644 perl/Changes delete mode 100644 perl/Fuse.pm delete mode 100644 perl/Fuse.xs delete mode 100644 perl/MANIFEST delete mode 100644 perl/Makefile.PL delete mode 100644 perl/README delete mode 100755 perl/examples/example.pl delete mode 100755 perl/examples/loopback.pl delete mode 100755 perl/examples/rmount.pl delete mode 100755 perl/examples/rmount_remote.pl delete mode 100644 perl/test.pl delete mode 100644 perl/test/chmod.t delete mode 100644 perl/test/chown.t delete mode 100644 perl/test/getattr.t delete mode 100644 perl/test/getdir.t delete mode 100644 perl/test/helper.pm delete mode 100644 perl/test/link.t delete mode 100644 perl/test/mkdir.t delete mode 100644 perl/test/mknod.t delete mode 100644 perl/test/open.t delete mode 100644 perl/test/read.t delete mode 100644 perl/test/readlink.t delete mode 100644 perl/test/rename.t delete mode 100644 perl/test/rmdir.t delete mode 100644 perl/test/s/mount.t delete mode 100644 perl/test/s/umount.t delete mode 100644 perl/test/statfs.t delete mode 100644 perl/test/symlink.t delete mode 100644 perl/test/test-template delete mode 100644 perl/test/truncate.t delete mode 100644 perl/test/unlink.t delete mode 100644 perl/test/utime.t delete mode 100644 perl/test/write.t delete mode 100644 python/AUTHORS delete mode 100644 python/ChangeLog delete mode 100644 python/INSTALL delete mode 100644 python/Makefile delete mode 100644 python/README delete mode 100644 python/_fusemodule.c delete mode 100644 python/code.leo delete mode 100644 python/fuse.py delete mode 100644 python/setup.py delete mode 100755 python/xmp.py diff --git a/lufis/.cvsignore b/lufis/.cvsignore deleted file mode 100644 index dc5eb9e..0000000 --- a/lufis/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -lufis diff --git a/lufis/COPYING b/lufis/COPYING deleted file mode 100644 index d60c31a..0000000 --- a/lufis/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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 - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/lufis/ChangeLog b/lufis/ChangeLog deleted file mode 100644 index d3256b4..0000000 --- a/lufis/ChangeLog +++ /dev/null @@ -1,8 +0,0 @@ -2004-10-09 Miklos Szeredi - - * Fix compilation with post 1.9 FUSE - -2004-03-09 Miklos Szeredi - - * Make it possible to mount captivefs filesystem - diff --git a/lufis/Makefile b/lufis/Makefile deleted file mode 100644 index 5ff0392..0000000 --- a/lufis/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -CC = gcc - -CFLAGS := -Wall -W -g -LDLIBS := -lpthread -ldl -rdynamic - -PKGCONFIG := env PKG_CONFIG_PATH=/usr/local/lib/pkgconfig pkg-config -FUSEVER := $(shell $(PKGCONFIG) --modversion fuse 2> /dev/null) -ifeq ($(FUSEVER),) - LDLIBS += -lfuse -else - CFLAGS += $(shell $(PKGCONFIG) --cflags fuse) - LDLIBS += $(shell $(PKGCONFIG) --libs fuse) -endif - -CPPFLAGS := -D_FILE_OFFSET_BITS=64 -#CPPFLAGS += -DDEBUG - -lufis: lufis.o options.o dircache.o - -clean: - rm -f *.o lufis diff --git a/lufis/README b/lufis/README deleted file mode 100644 index 93db721..0000000 --- a/lufis/README +++ /dev/null @@ -1,50 +0,0 @@ -This is a modified LUFS daemon, which uses the FUSE kernel module. It -is binary compatible with existing LUFS filesystems, so no -recompilation is needed. - -Licence: - -GPL (see COPYING). Most of the code is copied from the LUFS source -written by Florin Malita , thanks! - -Disclaimer: - -This is currently just a proof-of-concept implementation, not a -finished product. That said it seems perfectly stable. Comments, are -of course welcome . - -Installation: - - - install lufs (0.9.7) - - install fuse (1.1) - - enter 'make' in this directory - -Usage, for exampe: - - ./lufis fs=sshfs,host=kempelen,username=mszeredi /mnt/lufis/ -s - -Don't forget the '-s' option, without it the filesystem may misbehave! - -For help on FUSE specific options see: - - ./lufis fs=localfs -h - -and - - ./lufis fs=localfs / -- -h - -For LUFS specific options (can only be specified in the first -argument) see the README in the LUFS distribution - - -Captivefs: - -from version 0.2 lufis supports mounting the captivefs. Command line -should be something like this: - -lufis "fs=captivefs,dir_cache_entries=0,image=/store/ntfs/ntfs.img,captive_options=--rw;--load-module=/var/lib/captive/ntoskrnl.exe;--filesystem=/var/lib/captive/ntfs.sys;--sandbox-server=/usr/sbin/captive-sandbox-server;" /mnt/ntfs -s - -It may work without the '-s' option, but this is untested. - -umounting should be done with 'umount' as root or 'fusermount -u' as -non-root. diff --git a/lufis/dircache.c b/lufis/dircache.c deleted file mode 100644 index bdd8717..0000000 --- a/lufis/dircache.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - * dircache.c - * Copyright (C) 2002 Florin Malita - * - * This file is part of LUFS, a free userspace filesystem implementation. - * See http://lufs.sourceforge.net/ for updates. - * - * LUFS 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. - * - * LUFS 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 - */ - -#include -#include -#include -#include - -#include - -#include -#include - -#include "list.h" -#include "dircache.h" - -static char root_dir[]="/"; -static char current_dir[]="."; - -static unsigned long -hash(char *name){ - unsigned long res = 0; - unsigned int i; - - for(i = 0; i < strlen(name); i++) - if(name[i] != '/') - res = 0x21413 * (res + name[i]); - - return res % NBUCKETS; -} - -static void -delete_dir(struct directory *d){ - struct list_head *p, *tmp; - struct direntry *de; - - TRACE("in"); - list_for_each_safe(p, tmp, &d->d_entries){ - de = list_entry(p, struct direntry, e_list); - list_del(&de->e_list); - free(de->e_name); - if(de->e_link) - free(de->e_link); - free(de); - } - - list_del(&d->d_list); - free(d->d_name); - free(d); - - TRACE("out"); -} - -struct dir_cache* -lu_cache_create(struct list_head *cfg){ - struct dir_cache *cache; - int i; - const char *c; - - TRACE("creating dir cache..."); - - if(!(cache = malloc(sizeof(struct dir_cache)))) - return NULL; - - memset(cache, 0, sizeof(struct dir_cache)); - - for(i = 0; i < NBUCKETS; i++) - INIT_LIST_HEAD(&cache->buckets[i]); - - pthread_mutex_init(&cache->lock, NULL); - - cache->ttl = DEF_TTL; - if((c = lu_opt_getchar(cfg, "LUFSD", "DirCacheTTL")) && atoi(c)) - cache->ttl = atoi(c); - if((c = lu_opt_getchar(cfg, "MOUNT", "dir_cache_ttl")) && atoi(c)) - cache->ttl = atoi(c); - - cache->entries = DEF_NENTRIES; - if((c = lu_opt_getchar(cfg, "LUFSD", "DirCacheEntries")) && atoi(c)) - cache->entries = atoi(c); - if((c = lu_opt_getchar(cfg, "MOUNT", "dir_cache_entries")) && atoi(c)) - cache->entries = atoi(c); - - TRACE("entries: %d, ttl: %d", cache->entries, cache->ttl); - - return cache; -} - -void -lu_cache_destroy(struct dir_cache *cache){ - struct list_head *p, *tmp; - int i; - - for(i = 0; i < NBUCKETS; i++){ - list_for_each_safe(p, tmp, &cache->buckets[i]){ - delete_dir(list_entry(p, struct directory, d_list)); - } - } - - free(cache); -} - -static struct directory* -search(struct dir_cache *cache, char *dir){ - struct list_head *p, *tmp; - struct directory *d; - int hsh; - - hsh = hash(dir); - - TRACE("search %s in bucket %u, size=%u", dir, hsh, cache->lengths[hsh]); - - list_for_each_safe(p, tmp, &cache->buckets[hsh]){ - d = list_entry(p, struct directory, d_list); - - if(time(NULL) - d->d_stamp >= (unsigned long) cache->ttl){ - TRACE("%s expired...", d->d_name); - delete_dir(d); - cache->lengths[hsh]--; - TRACE("directory deleted"); - }else if(!strcmp(dir, d->d_name)){ - TRACE("%s found", dir); - d->d_stamp = time(NULL); - return d; - } - } - - TRACE("dir not found"); - return NULL; -} - -int -lu_cache_lookup(struct dir_cache *cache, char *dir, char *file, struct lufs_fattr *fattr, char *link, int buflen){ - struct directory *d; - struct direntry *de; - struct list_head *p; - int res = -1; - - TRACE("looking up %s in dir %s", file, dir); - - pthread_mutex_lock(&cache->lock); - - if(!(d = search(cache, dir))) - goto out; - - list_for_each(p, &d->d_entries){ - de = list_entry(p, struct direntry, e_list); - if(!strcmp(file, de->e_name)){ - TRACE("file found"); - - memcpy(fattr, &de->e_attr, sizeof(struct lufs_fattr)); - if(link){ - if(de->e_link){ - if(snprintf(link, buflen, "%s", de->e_link) >= buflen){ - WARN("link too long!"); - link[buflen - 1] =0; - } - }else{ - link[0] = 0; - } - } - - res = 0; - goto out; - } - } - - TRACE("file not found!"); - - out: - pthread_mutex_unlock(&cache->lock); - return res; -} - -static void -shrink(struct dir_cache *cache, int hsh){ - struct directory *dir; - - TRACE("shrinking bucket %u, len=%u", hsh, cache->lengths[hsh]); - - if(list_empty(&cache->buckets[hsh])) - return; - - dir = list_entry(cache->buckets[hsh].prev, struct directory, d_list); - - TRACE("deleting dir %s", dir->d_name); - - delete_dir(dir); - cache->lengths[hsh]--; -} - -static void -check_dir(struct directory *d){ - struct list_head *p, *tmp; - struct direntry *e; - struct lufs_fattr dummy; - int dot = 0, dotdot = 0; - - memset(&dummy, 0, sizeof(struct lufs_fattr)); - dummy.f_nlink = 1; - dummy.f_uid = dummy.f_gid = 1; - dummy.f_mode = S_IFDIR | S_IRWXU | S_IRGRP | S_IXGRP; - dummy.f_mtime = dummy.f_atime = dummy.f_ctime = time(NULL); - dummy.f_size = 512; - - do{ - list_for_each_safe(p, tmp, &d->d_entries){ - e = list_entry(p, struct direntry, e_list); - - if(!strcmp(e->e_name, ".")){ - TRACE("'.' entry found"); - list_del(&e->e_list); - list_add(&e->e_list, &d->d_entries); - dot = 1; - continue; - } - - if(!strcmp(e->e_name, "..")){ - TRACE("'..' entry found"); - list_del(&e->e_list); - if(!dot) - list_add(&e->e_list, &d->d_entries); - else - list_add(&e->e_list, d->d_entries.next); - - dotdot = 1; - } - } - - if(!dot) - lu_cache_add2dir(d, ".", NULL, &dummy); - - if(!dotdot) - lu_cache_add2dir(d, "..", NULL, &dummy); - - }while((!dot) || (!dotdot)); - -} - -void -lu_cache_add_dir(struct dir_cache *cache, struct directory *d){ - struct directory *dir; - int hsh; - - hsh = hash(d->d_name); - - TRACE("adding dir %s to bucket %i", d->d_name, hsh); - - check_dir(d); - - pthread_mutex_lock(&cache->lock); - - if((dir = search(cache, d->d_name))){ - TRACE("directory already in cache, deleting..."); - delete_dir(dir); - cache->lengths[hsh]--; - } - - d->d_stamp = time(NULL); - - list_add(&d->d_list, &cache->buckets[hsh]); - cache->lengths[hsh]++; - - while(cache->lengths[hsh] > cache->entries) - shrink(cache, hsh); - - pthread_mutex_unlock(&cache->lock); - - TRACE("out"); -} - -int lu_cache_readdir(struct dir_cache *cache, char *dir, - fuse_dirh_t h, fuse_dirfil_t filler) -{ - struct directory *d; - struct direntry *de; - struct list_head *p; - int res = -1; - - TRACE("reading directory %s", dir); - - pthread_mutex_lock(&cache->lock); - - if(!(d = search(cache, dir))) - goto out; - - list_for_each(p, &d->d_entries){ - de = list_entry(p, struct direntry, e_list); -#if FUSE_MAJOR_VERSION < 2 || (FUSE_MAJOR_VERSION == 2 && FUSE_MINOR_VERSION < 1) - filler(h, de->e_name, 0); -#else - filler(h, de->e_name, 0, 0); -#endif - } - - d->d_stamp = time(NULL); - - res = 0; - - out: - pthread_mutex_unlock(&cache->lock); - TRACE("out"); - return res; -} - -int -lu_cache_lookup_file(struct dir_cache *cache, char *file, struct lufs_fattr *fattr, char *link, int buflen){ - int res; - - char *sep, *dir; - - if(!(sep = strrchr(file, '/'))){ - WARN("separator not present!"); - return -1; - } - - *sep = 0; - - if(sep == file) - dir = root_dir; - else - dir = file; - - if(*(sep+1)) - file = sep + 1; - else - file = current_dir; - - TRACE("dir: %s, file: %s", dir, file); - - res = lu_cache_lookup(cache, dir, file, fattr, link, buflen); - *sep = '/'; - - return res; -} - -int -lu_cache_invalidate(struct dir_cache *cache, char *file){ - struct directory *d; - char *sep, *dir; - - if(!(sep = strrchr(file, '/'))){ - WARN("separator not present!"); - return -1; - } - - *sep = 0; - - if(sep == file) - dir = root_dir; - else - dir = file; - - TRACE("invalidating dir %s", dir); - - pthread_mutex_lock(&cache->lock); - - if(!(d = search(cache, dir))){ - *sep = '/'; - pthread_mutex_unlock(&cache->lock); - return -1; - } - - d->d_stamp = 0; - - pthread_mutex_unlock(&cache->lock); - *sep = '/'; - - return 0; -} - -struct directory* -lu_cache_mkdir(char *dir){ - struct directory *res; - - TRACE("create dir %s", dir); - - if(!(res = malloc(sizeof(struct directory)))){ - WARN("out of mem!"); - return NULL; - } - - memset(res, 0, sizeof(struct directory)); - - if(!(res->d_name = malloc(strlen(dir) + 1))){ - WARN("out of mem!"); - free(res); - return NULL; - } - - INIT_LIST_HEAD(&res->d_entries); - res->d_stamp = time(NULL); - strcpy(res->d_name, dir); - - return res; -} - -int -lu_cache_add2dir(struct directory *d, char *fname, char *link, struct lufs_fattr *fattr){ - struct direntry *de; - - TRACE("adding %s->%s to %s", fname, link, d->d_name); - - if(!(de = malloc(sizeof(struct direntry)))) - goto fail; - - - if(!(de->e_name = malloc(strlen(fname) + 1))) - goto fail_de; - - - if(link) - de->e_link = malloc(strlen(link) + 1); - else - de->e_link = malloc(2); - - if(!de->e_link) - goto fail_ename; - - memcpy(&de->e_attr, fattr, sizeof(struct lufs_fattr)); - strcpy(de->e_name, fname); - if(link) - strcpy(de->e_link, link); - else - strcpy(de->e_link, ""); - - list_add_tail(&de->e_list, &d->d_entries); - - return 0; - - fail_ename: - free(de->e_name); - fail_de: - free(de); - fail: - WARN("out of mem!"); - return -1; -} - -void -lu_cache_killdir(struct directory *d){ - struct list_head *p, *tmp; - struct direntry *de; - - TRACE("in"); - - list_for_each_safe(p, tmp, &d->d_entries){ - de = list_entry(p, struct direntry, e_list); - list_del(&de->e_list); - free(de->e_name); - if(de->e_link) - free(de->e_link); - free(de); - } - - free(d->d_name); - free(d); - -} diff --git a/lufis/dircache.h b/lufis/dircache.h deleted file mode 100644 index 3c33d25..0000000 --- a/lufis/dircache.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * dircache.h - * Copyright (C) 2002 Florin Malita - * - * This file is part of LUFS, a free userspace filesystem implementation. - * See http://lufs.sourceforge.net/ for updates. - * - * LUFS 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. - * - * LUFS 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 _DIRCACHE_H_ -#define _DIRCACHE_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -#define NBUCKETS 7 -#define DEF_NENTRIES 6 -#define DEF_TTL 20 - -struct list_head; - -struct direntry{ - char *e_name; - char *e_link; - struct list_head e_list; - struct lufs_fattr e_attr; -}; - -struct directory{ - char *d_name; - struct list_head d_entries; - struct list_head d_list; - unsigned long d_stamp; -}; - -struct dir_cache{ - int ttl; - int entries; - pthread_mutex_t lock; - struct list_head buckets[NBUCKETS]; - int lengths[NBUCKETS]; -}; - -struct dir_cache* lu_cache_create(struct list_head*); -void lu_cache_destroy(struct dir_cache*); - -int lu_cache_lookup_file(struct dir_cache*, char*, struct lufs_fattr*, char*, int); -void lu_cache_add(struct dir_cache*, char*, char*, struct lufs_fattr*, char*); -int lu_cache_readdir(struct dir_cache *cache, char *dir, - fuse_dirh_t h, fuse_dirfil_t filler); -int lu_cache_invalidate(struct dir_cache*, char*); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/lufis/list.h b/lufis/list.h deleted file mode 100644 index f3cb6f5..0000000 --- a/lufis/list.h +++ /dev/null @@ -1,171 +0,0 @@ -#ifndef _LINUX_LIST_H -#define _LINUX_LIST_H - -/* - * Simple doubly linked list implementation. - * - * Some of the internal functions ("__xxx") are useful when - * manipulating whole lists rather than single entries, as - * sometimes we already know the next/prev entries and we can - * generate better code by using them directly rather than - * using the generic single-entry routines. - */ - -struct list_head { - struct list_head *next, *prev; -}; - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -#define INIT_LIST_HEAD(ptr) do { \ - (ptr)->next = (ptr); (ptr)->prev = (ptr); \ -} while (0) - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static __inline__ void __list_add(struct list_head * nnew, - struct list_head * prev, - struct list_head * next) -{ - next->prev = nnew; - nnew->next = next; - nnew->prev = prev; - prev->next = nnew; -} - -/** - * list_add - add a new entry - * @new: new entry to be added - * @head: list head to add it after - * - * Insert a new entry after the specified head. - * This is good for implementing stacks. - */ -static __inline__ void list_add(struct list_head *nnew, struct list_head *head) -{ - __list_add(nnew, head, head->next); -} - -/** - * list_add_tail - add a new entry - * @nnew: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - */ -static __inline__ void list_add_tail(struct list_head *nnew, struct list_head *head) -{ - __list_add(nnew, head->prev, head); -} - -/* - * Delete a list entry by making the prev/next entries - * point to each other. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static __inline__ void __list_del(struct list_head * prev, - struct list_head * next) -{ - next->prev = prev; - prev->next = next; -} - -/** - * list_del - deletes entry from list. - * @entry: the element to delete from the list. - * Note: list_empty on entry does not return true after this, the entry is in an undefined state. - */ -static __inline__ void list_del(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); -} - -/** - * list_del_init - deletes entry from list and reinitialize it. - * @entry: the element to delete from the list. - */ -static __inline__ void list_del_init(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - INIT_LIST_HEAD(entry); -} - -/** - * list_empty - tests whether a list is empty - * @head: the list to test. - */ -static __inline__ int list_empty(struct list_head *head) -{ - return head->next == head; -} - -/** - * list_splice - join two lists - * @list: the new list to add. - * @head: the place to add it in the first list. - */ -static __inline__ void list_splice(struct list_head *list, struct list_head *head) -{ - struct list_head *first = list->next; - - if (first != list) { - struct list_head *last = list->prev; - struct list_head *at = head->next; - - first->prev = head; - head->next = first; - - last->next = at; - at->prev = last; - } -} - -/** - * list_entry - get the struct for this entry - * @ptr: the &struct list_head pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - */ -#define list_entry(ptr, type, member) \ - ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) - -/** - * list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop counter. - * @head: the head for your list. - */ -#define list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); \ - pos = pos->next) - -/** - * list_for_each_safe - iterate over a list safe against removal of list entry - * @pos: the &struct list_head to use as a loop counter. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - */ -#define list_for_each_safe(pos, n, head) \ - for (pos = (head)->next, n = pos->next; pos != (head); \ - pos = n, n = pos->next) - -/** - * list_for_each_prev - iterate over a list in reverse order - * @pos: the &struct list_head to use as a loop counter. - * @head: the head for your list. - */ -#define list_for_each_prev(pos, head) \ - for (pos = (head)->prev; pos != (head); \ - pos = pos->prev) - - -#endif diff --git a/lufis/lufis.c b/lufis/lufis.c deleted file mode 100644 index 5509bdf..0000000 --- a/lufis/lufis.c +++ /dev/null @@ -1,800 +0,0 @@ -#define _GNU_SOURCE - -#include -#include -#include -#include "list.h" -#include "dircache.h" -#include -#include -#include -#include -#include -#include -#include -#include - -/* statfs extension for captivefs */ -struct lufs_sbattr_ { /* struct statfs64 */ - unsigned long long sb_bytes; - unsigned long long sb_bytes_free; - unsigned long long sb_bytes_available; - unsigned long long sb_files; - unsigned long long sb_ffree; -}; - -struct fs_operations { - void *(*init)(struct list_head*, struct dir_cache*, struct credentials*, void**); - void (*free)(void*); - int (*mount)(void*); - void (*umount)(void*); - int (*readdir)(void*, char*, struct directory*); - int (*stat)(void*, char*, struct lufs_fattr*); - int (*mkdir)(void*, char*, int); - int (*rmdir)(void*, char*); - int (*create)(void*, char*, int); - int (*unlink)(void*, char*); - int (*rename)(void*, char*, char*); - int (*open)(void*, char*, unsigned); - int (*release)(void*, char*); - int (*read)(void*, char*, long long, unsigned long, char*); - int (*write)(void*, char*, long long, unsigned long, char*); - int (*readlink)(void*, char*, char*, int); - int (*link)(void*, char*, char*); - int (*symlink)(void*, char*, char*); - int (*setattr)(void*, char*, struct lufs_fattr*); - int (*statfs)(void*, struct lufs_sbattr_*); -}; - -static struct fs_operations lu_fops; -static void *lu_dlhandle; -static struct list_head lu_cfg; -static void *lu_global_ctx; -static struct credentials lu_cred; -static void *lu_context; -static struct dir_cache *lu_cache; - -#define BUF_SIZE 1024 -#define PASSWD "/etc/passwd" -#define GROUP "/etc/group" - -int lu_check_to(int rd_fd, int wr_fd, int time_out){ - fd_set rd, wr; - int res, maxfd = 0; - struct timeval tv; - - FD_ZERO(&rd); - FD_ZERO(&wr); - - if(rd_fd){ - FD_SET(rd_fd, &rd); - maxfd = rd_fd > maxfd ? rd_fd : maxfd; - } - - if(wr_fd){ - FD_SET(wr_fd, &wr); - maxfd = wr_fd > maxfd ? wr_fd : maxfd; - } - - tv.tv_sec = time_out; - tv.tv_usec = 0; - - do{ - res = select(maxfd + 1, &rd, &wr, NULL, &tv); - - }while((res < 0) && (errno == EINTR)); - - if(res > 0) - return 0; - - if(res < 0){ - WARN("select call failed: %s", strerror(errno)); - return -errno; - } - - WARN("operation timed out!"); - - return -ETIMEDOUT; -} - -int lu_atomic_read(int fd, char *buf, int len, int time_out){ - int res, offset = 0; - - do{ - if((time_out) && ((res = lu_check_to(fd, 0, time_out)) < 0)) - return res; - - do{ - res = read(fd, buf + offset, len - offset); - }while((res < 0) && (errno == EINTR)); - - if(res <= 0){ - WARN("read call failed: %s", strerror(errno)); - return (res < 0) ? -errno : (offset > 0 ? offset : -EPIPE); - } - - offset += res; - - }while(offset < len); - - return offset; -} - -int lu_atomic_write(int fd, char *buf, int len, int time_out){ - int res, offset = 0; - - do{ - if((time_out) && ((res = lu_check_to(0, fd, time_out)) < 0)) - return res; - - do{ - res = write(fd, buf + offset, len - offset); - }while((res < 0) && (errno == EINTR)); - - if(res <= 0){ - WARN("write call failed: %s", strerror(errno)); - return (res < 0) ? -errno : (offset > 0 ? offset : -EPIPE); - } - - offset += res; - - }while(offset < len); - - return offset; -} - -static int get_filesystem(const char *fs) -{ - char *buf; - void *dlhandle; - - if(!(buf = (char*)malloc(strlen(fs) + 32))) - return -1; - - sprintf(buf, "liblufs-%s.so", fs); - if(!(dlhandle = dlopen(buf, RTLD_LAZY))){ - ERROR(dlerror()); - goto fail; - } - - sprintf(buf, "%s_init", fs); - if(!(lu_fops.init = (void*(*)(struct list_head*, struct dir_cache*, struct credentials*, void**))dlsym(dlhandle, buf))){ - ERROR(dlerror()); - goto fail_fops; - } - - sprintf(buf, "%s_free", fs); - if(!(lu_fops.free = (void(*)(void*))dlsym(dlhandle, buf))){ - ERROR(dlerror()); - goto fail_fops; - } - - sprintf(buf, "%s_mount", fs); - if(!(lu_fops.mount = (int(*)(void*))dlsym(dlhandle, buf))){ - ERROR(dlerror()); - goto fail_fops; - } - - sprintf(buf, "%s_umount", fs); - if(!(lu_fops.umount = (void(*)(void*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_readdir", fs); - if(!(lu_fops.readdir = (int(*)(void*, char*, struct directory*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_stat", fs); - if(!(lu_fops.stat = (int(*)(void*, char*, struct lufs_fattr*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_mkdir", fs); - if(!(lu_fops.mkdir = (int(*)(void*, char*, int))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_rmdir", fs); - if(!(lu_fops.rmdir = (int(*)(void*, char*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_create", fs); - if(!(lu_fops.create = (int(*)(void*, char*, int))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_unlink", fs); - if(!(lu_fops.unlink = (int(*)(void*, char*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_rename", fs); - if(!(lu_fops.rename = (int(*)(void*, char*, char*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_open", fs); - if(!(lu_fops.open = (int(*)(void*, char*, unsigned))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_release", fs); - if(!(lu_fops.release = (int(*)(void*, char*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_read", fs); - if(!(lu_fops.read = (int(*)(void*, char*, long long, unsigned long, char*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_write", fs); - if(!(lu_fops.write = (int(*)(void*, char*, long long, unsigned long, char*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_readlink", fs); - if(!(lu_fops.readlink = (int(*)(void*, char*, char*, int))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_link", fs); - if(!(lu_fops.link = (int(*)(void*, char*, char*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_symlink", fs); - if(!(lu_fops.symlink = (int(*)(void*, char*, char*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_setattr", fs); - if(!(lu_fops.setattr = (int(*)(void*, char*, struct lufs_fattr*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - sprintf(buf, "%s_statfs", fs); - lu_fops.statfs = (int(*)(void*, struct lufs_sbattr_*))dlsym(dlhandle, buf); - - lu_dlhandle = dlhandle; - free(buf); - return 0; - - fail_fops: - dlclose(dlhandle); - fail: - free(buf); - return -1; -} - -static int lu_getattr_native(const char *path, struct lufs_fattr *fattr) -{ - if(!lu_fops.stat) - return -ENOSYS; - - memset(fattr, 0, sizeof(struct lufs_fattr)); - if(lu_cache_lookup_file(lu_cache, (char *) path, fattr, NULL, 0) < 0) { - if(lu_fops.stat(lu_context, (char *) path, fattr) < 0) - return -ENOENT; - } - return 0; -} - -static int lu_getattr(const char *path, struct stat *stbuf) -{ - struct lufs_fattr fattr; - int res; - - res = lu_getattr_native(path, &fattr); - if(res < 0) - return res; - - stbuf->st_mode = fattr.f_mode; - stbuf->st_nlink = fattr.f_nlink; - stbuf->st_uid = fattr.f_uid; - stbuf->st_gid = fattr.f_gid; - stbuf->st_size = fattr.f_size; - stbuf->st_atime = fattr.f_atime; - stbuf->st_mtime = fattr.f_mtime; - stbuf->st_ctime = fattr.f_ctime; - stbuf->st_blksize = fattr.f_blksize; - stbuf->st_blocks = fattr.f_blocks; - - return 0; -} - -static int lu_readlink(const char *path, char *buf, size_t size) -{ - int len; - struct lufs_fattr fattr; - - if(!lu_fops.readlink) - return -ENOSYS; - - if(lu_cache_lookup_file(lu_cache, (char *) path, &fattr, buf, size) < 0 || - strcmp(buf, "") == 0) { - if((len = lu_fops.readlink(lu_context, (char *) path, buf, size)) < 0) - return -EPERM; - - /* FUSE leaves one extra char free at the end */ - buf[len] = '\0'; - } - - return 0; -} - -static int lu_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler) -{ - struct directory *dir; - - if(!lu_fops.readdir) - return -ENOSYS; - - if(lu_cache_readdir(lu_cache, (char *) path, h, filler) < 0){ - if(!(dir = lu_cache_mkdir((char *) path))) - return -1; - - if(lu_fops.readdir(lu_context, (char *) path, dir) < 0){ - lu_cache_killdir(dir); - return -1; - } - lu_cache_add_dir(lu_cache, dir); - - if(lu_cache_readdir(lu_cache, (char *) path, h, filler) < 0) { - return -EPERM; - } - } - return 0; -} - -static int lu_mknod(const char *path, mode_t mode, dev_t rdev) -{ - (void) rdev; - if(!S_ISREG(mode) || !lu_fops.create) - return -ENOSYS; - - if(lu_fops.create(lu_context, (char *) path, mode) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) path); - return 0; -} - -static int lu_mkdir(const char *path, mode_t mode) -{ - if(!lu_fops.mkdir) - return -ENOSYS; - - if(lu_fops.mkdir(lu_context, (char *) path, mode) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) path); - return 0; -} - -static int lu_unlink(const char *path) -{ - if(!lu_fops.unlink) - return -ENOSYS; - - if(lu_fops.unlink(lu_context, (char *) path) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) path); - return 0; -} - -static int lu_rmdir(const char *path) -{ - if(!lu_fops.rmdir) - return -ENOSYS; - - if(lu_fops.rmdir(lu_context, (char *) path) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) path); - return 0; -} - -static int lu_symlink(const char *from, const char *to) -{ - if(!lu_fops.symlink) - return -ENOSYS; - - if(lu_fops.symlink(lu_context, (char *) from, (char *) to) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) to); - return 0; -} - -static int lu_rename(const char *from, const char *to) -{ - if(!lu_fops.rename) - return -ENOSYS; - - if(lu_fops.rename(lu_context, (char *) from, (char *) to) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) from); - lu_cache_invalidate(lu_cache, (char *) to); - return 0; -} - -static int lu_link(const char *from, const char *to) -{ - if(!lu_fops.link) - return -ENOSYS; - - if(lu_fops.link(lu_context, (char *) from, (char *) to) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) from); - lu_cache_invalidate(lu_cache, (char *) to); - return 0; -} - -static int lu_chmod(const char *path, mode_t mode) -{ - int res; - struct lufs_fattr fattr; - - if(!lu_fops.setattr) - return -ENOSYS; - - res = lu_getattr_native(path, &fattr); - if(res < 0) - return res; - - fattr.f_mode = mode; - if(lu_fops.setattr(lu_context, (char *) path, &fattr) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) path); - return 0; -} - -static int lu_chown(const char *path, uid_t uid, gid_t gid) -{ - int res; - struct lufs_fattr fattr; - - if(!lu_fops.setattr) - return -ENOSYS; - - res = lu_getattr_native(path, &fattr); - if(res < 0) - return res; - - if(uid != (uid_t) -1) - fattr.f_uid = uid; - if(gid != (gid_t) -1) - fattr.f_gid = gid; - if(lu_fops.setattr(lu_context, (char *) path, &fattr) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) path); - return 0; - -} - -static int lu_truncate(const char *path, off_t size) -{ - int res; - struct lufs_fattr fattr; - - if(!lu_fops.setattr) - return -ENOSYS; - - res = lu_getattr_native(path, &fattr); - if(res < 0) - return res; - - fattr.f_size = size; - if(lu_fops.setattr(lu_context, (char *) path, &fattr) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) path); - return 0; -} - -static int lu_utime(const char *path, struct utimbuf *buf) -{ - int res; - struct lufs_fattr fattr; - - if(!lu_fops.setattr) - return -ENOSYS; - - res = lu_getattr_native(path, &fattr); - if(res < 0) - return res; - - fattr.f_atime = buf->actime; - fattr.f_mtime = buf->modtime; - if(lu_fops.setattr(lu_context, (char *) path, &fattr) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) path); - return 0; -} - - -static int lu_open(const char *path, int flags) -{ - if(!lu_fops.open) - return -ENOSYS; - - if(lu_fops.open(lu_context, (char *) path, flags & O_ACCMODE) < 0) - return -EPERM; - - return 0; -} - -static int lu_read(const char *path, char *buf, size_t size, off_t offset) -{ - int res; - if(!lu_fops.read) - return -ENOSYS; - - if((res = lu_fops.read(lu_context, (char *) path, offset, size, buf)) < 0) - return -EPERM; - - return res; -} - -static int lu_write(const char *path, const char *buf, size_t size, - off_t offset) -{ - if(!lu_fops.write) - return -ENOSYS; - - if(lu_fops.write(lu_context, (char *) path, offset, size, (char *) buf) < 0) - return -EPERM; - - return size; -} - -static int lu_release(const char *path, int flags) -{ - (void) flags; - if(!lu_fops.release) - return -ENOSYS; - - if(lu_fops.release(lu_context, (char *) path) < 0) - return -EPERM; - - return 0; -} - -#if FUSE_MAJOR_VERSION < 2 -static int lu_statfs(struct fuse_statfs *stbuf) -#else -static int lu_statfs(const char *path, struct statfs *stbuf) -#endif -{ - struct lufs_sbattr_ sbattr; - - memset(&sbattr, 0, sizeof(sbattr)); - if(lu_fops.statfs) { - if(lu_fops.statfs(lu_context, &sbattr) < 0) - return -EPERM; - } - -#if FUSE_MAJOR_VERSION < 2 - stbuf->blocks = sbattr.sb_bytes / 512; - stbuf->blocks_free = sbattr.sb_bytes_available / 512; - stbuf->files = sbattr.sb_files; - stbuf->files_free = sbattr.sb_ffree; - stbuf->namelen = 255; -#else - (void) path; - stbuf->f_bsize = 512; - stbuf->f_blocks = sbattr.sb_bytes / 512; - stbuf->f_bfree = sbattr.sb_bytes_free / 512; - stbuf->f_bavail = sbattr.sb_bytes_available / 512; - stbuf->f_files = sbattr.sb_files; - stbuf->f_ffree = sbattr.sb_ffree; - stbuf->f_namelen = 255; -#endif - return 0; -} - -static int load_credentials(void) -{ - static char buf[BUF_SIZE]; - char srch_str[MAX_LEN + 4]; - long int uid, gid; - int res, offset, chunk, readlen; - char *c; - - TRACE("loading remote credentials for %s", lu_cred.user); - - if((!lu_fops.open) || (!lu_fops.read) || (!lu_fops.release)){ - WARN("unsupported operation"); - return -1;; - } - - lu_cred.uid = lu_cred.gid = -1; - - if(lu_fops.open(lu_context, PASSWD, O_RDONLY) < 0){ - TRACE("could not open %s", PASSWD); - return -1; - } - - sprintf(srch_str, "\n%s:", lu_cred.user); - chunk = strlen(srch_str) + 64; - readlen = BUF_SIZE - chunk - 1; - - memset(buf, 32, chunk); - offset = 0; - - do{ - res = lu_fops.read(lu_context, PASSWD, offset, readlen, (buf + chunk)); - if(res > 0){ - *(buf + chunk + res) = 0; - - if((c = strstr(buf, srch_str))){ - TRACE("username found!"); - if(!(c = strchr(c + strlen(srch_str), ':'))){ - TRACE("separator not found!"); - }else{ - if(sscanf(c , ":%li:%li:", &uid, &gid) != 2){ - TRACE("uid/gid not found!"); - }else{ - TRACE("uid: %li, gid: %li", uid, gid); - - lu_cred.uid = uid; - lu_cred.gid = gid; - - break; - } - } - } - - memcpy(buf, buf + BUF_SIZE - chunk - 1, chunk); - offset += res; - } - }while(res == readlen); - - lu_fops.release(lu_context, PASSWD); - - if(res <= 0){ - TRACE("read failed"); - return -1; - } - - - if(lu_fops.open(lu_context, GROUP, O_RDONLY) < 0){ - TRACE("could not open %s", GROUP); - return -1; - } - - sprintf(srch_str, ":%li:", (long)lu_cred.gid); - chunk = strlen(srch_str) + 64; - readlen = BUF_SIZE - chunk - 1; - - memset(buf, 32, chunk); - offset = 0; - - do{ - res = lu_fops.read(lu_context, GROUP, offset, readlen, (buf + chunk)); - if(res > 0){ - *(buf + chunk + res) = 0; - - if((c = strstr(buf, srch_str))){ - TRACE("group found!"); - if(!(c = (char*)memrchr(buf, '\n', (c - buf)))){ - TRACE("separator not found!"); - }else{ - *(strchr(c, ':')) = 0; - if(strlen(c + 1) >= MAX_LEN){ - TRACE("groupname too long"); - }else{ - strcpy(lu_cred.group, c + 1); - TRACE("group: %s", lu_cred.group); - break; - } - } - } - - memcpy(buf, buf + BUF_SIZE - chunk - 1, chunk); - offset += res; - } - }while(res == readlen); - - lu_fops.release(lu_context, GROUP); - - if(res <= 0){ - TRACE("read failed"); - return -1; - } - - return 0; -} - -static int lufis_init(int *argcp, char **argvp[]) -{ - int argc = *argcp; - char **argv = *argvp; - int res; - char *opts; - const char *fs_name; - - if(argc < 2) { - fprintf(stderr, "usage: %s opts\n", argv[0]); - return -1; - } - - INIT_LIST_HEAD(&lu_cfg); - opts = argv[1]; - if(lu_opt_parse(&lu_cfg, "MOUNT", opts) < 0){ - ERROR("could not parse options!"); - return -1; - } - - lu_opt_loadcfg(&lu_cfg, "/etc/lufsd.conf"); - - (*argcp)--; - (*argvp)++; - argv[1] = argv[0]; - - - lu_cache = lu_cache_create(&lu_cfg); - if(!lu_cache) - return -1; - - if(!(fs_name = lu_opt_getchar(&lu_cfg, "MOUNT", "fs"))){ - ERROR("you need to specify a file system!"); - return -1; - } - - res = get_filesystem(fs_name); - if(res == -1) - return -1; - - if(!(lu_context = lu_fops.init(&lu_cfg, lu_cache, &lu_cred, &lu_global_ctx))) { - ERROR("could not initialize file system!"); - return -1; - } - - res = lu_fops.mount(lu_context); - if(res) { - if(load_credentials() < 0) - TRACE("could not load credentials."); - else - TRACE("credentials loaded."); - } else { - WARN("fs mount failed..."); - } - - return 0; -} - -static void lufis_cleanup(void) -{ - if(lu_fops.umount) - lu_fops.umount(lu_context); - lu_fops.free(lu_context); -} - -static struct fuse_operations lu_oper = { - .getattr = lu_getattr, - .readlink = lu_readlink, - .getdir = lu_getdir, - .mknod = lu_mknod, - .mkdir = lu_mkdir, - .symlink = lu_symlink, - .unlink = lu_unlink, - .rmdir = lu_rmdir, - .rename = lu_rename, - .link = lu_link, - .chmod = lu_chmod, - .chown = lu_chown, - .truncate = lu_truncate, - .utime = lu_utime, - .open = lu_open, - .read = lu_read, - .write = lu_write, - .release = lu_release, - .statfs = lu_statfs, -}; - -int main(int argc, char *argv[]) -{ - int res; - - res = lufis_init(&argc, &argv); - if(res == -1) - exit(1); - - fuse_main(argc, argv, &lu_oper); - lufis_cleanup(); - - return 0; -} diff --git a/lufis/options.c b/lufis/options.c deleted file mode 100644 index b8b7b3a..0000000 --- a/lufis/options.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * options.c - * Copyright (C) 2002 Florin Malita - * - * This file is part of LUFS, a free userspace filesystem implementation. - * See http://lufs.sourceforge.net/ for updates. - * - * LUFS 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. - * - * LUFS 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 - */ - -#include -#include -#include -#include - -#include - -#include "list.h" - -struct option { - char *key; - char *value; - struct list_head list; -}; - -struct domain { - char *name; - struct list_head properties; - struct list_head list; -}; - - -static void -trim(char *buf){ - int b,e; - - if(!buf[0]) - return; - - for(b = 0; (buf[b] == ' ') || (buf[b] == '\t'); b++); - for(e = strlen(buf) - 1; (e >= 0) && ((buf[e] == ' ') || (buf[e] == '\t')); e--); - if(e < 0) - e = strlen(buf) - 1; - - buf[e + 1] = 0; - - if(b) - strcpy(buf, &buf[b]); - -} - -static struct domain* -find_domain(struct list_head *conf, char *name){ - struct list_head *p; - struct domain *cls; - - list_for_each(p, conf){ - cls = list_entry(p, struct domain, list); - if(!strcmp(name, cls->name)){ - TRACE("domain found"); - return cls; - } - } - - return NULL; -} - -int -lu_opt_loadcfg(struct list_head *conf, char *file){ - struct domain *class; - struct option *prop; - FILE *f; - static char buf[1024]; - char *i, *j; - char *cls, *key, *val; - - TRACE("loading config from %s", file); - - if(!(f = fopen(file, "r"))){ - WARN("could not open file for reading!"); - return -1; - } - - while(fgets(buf, 1024, f)){ - - buf[strlen(buf) - 1] = 0; - - if((i = strchr(buf, '#'))) - *i = 0; - - if((i = strchr(buf, '='))){ - if((j = strstr(buf, "::"))){ - cls = buf; - key = j + 2; - val = i + 1; - - *i = 0; - *j = 0; - - trim(cls); - trim(key); - trim(val); - - TRACE("class: #%s#", cls); - TRACE("key: #%s#", key); - TRACE("val: #%s#", val); - - if(!(class = find_domain(conf, cls))){ - TRACE("class not found, creating..."); - - if(!(class = malloc(sizeof(struct domain)))){ - WARN("out of mem!"); - break; - } - - memset(class, 0, sizeof(struct domain)); - - if(!(class->name = malloc(strlen(cls) + 1))){ - WARN("out of mem!"); - free(class); - break; - } - - strcpy(class->name, cls); - INIT_LIST_HEAD(&class->properties); - - list_add(&class->list, conf); - } - - if(!(prop = malloc(sizeof(struct option)))){ - WARN("out of mem!"); - break; - } - - if(!(prop->key = malloc(strlen(key) + 1))){ - WARN("out of mem!"); - free(prop); - break; - } - - if(!(prop->value = malloc(strlen(val) + 1))){ - WARN("out of mem!"); - free(prop->key); - free(prop); - break; - } - - strcpy(prop->key, key); - strcpy(prop->value, val); - - list_add(&prop->list, &class->properties); - } - } - - } - - - fclose(f); - - return 0; -} - - -const char* -lu_opt_getchar(struct list_head *conf, char *cls, char *key){ - struct domain *class; - struct option *prop; - struct list_head *p; - - TRACE("retrieving %s::%s", cls, key); - - if(!(class = find_domain(conf, cls))) - return NULL; - - list_for_each(p, &class->properties){ - prop = list_entry(p, struct option, list); - - if(!strcmp(key, prop->key)){ - TRACE("key found"); - return prop->value; - } - } - - TRACE("key not found"); - - return NULL; -} - -int -lu_opt_getint(struct list_head *conf, char *domain, char *key, long int *result, int base){ - char *end; - const char *val; - long int res; - - if(!(val = lu_opt_getchar(conf, domain, key))) - return -1; - - res = strtol(val, &end, base); - - if(*end) - return -1; - - *result = res; - return 0; -} - -int -lu_opt_parse(struct list_head *conf, char *domain, char *opts){ - struct domain *class; - struct option *prop; - char *p, *sep; - - if(!(class = find_domain(conf, domain))){ - TRACE("domain not found, creating..."); - - if(!(class = malloc(sizeof(struct domain)))){ - WARN("out of mem!"); - return -1; - } - - memset(class, 0, sizeof(struct domain)); - - if(!(class->name = malloc(strlen(domain) + 1))){ - WARN("out of mem!"); - free(class); - return -1; - } - - strcpy(class->name, domain); - INIT_LIST_HEAD(&class->properties); - - list_add(&class->list, conf); - } - - for(p = strtok(opts, ","); p; p = strtok(NULL, ",")){ - if(!strstr(p, "password")) - TRACE("option: %s", p); - - if(!(prop = malloc(sizeof(struct option)))){ - WARN("out of mem!"); - return -1; - } - - if((sep = strchr(p, '='))) - *sep = 0; - - if(!(prop->key = malloc(strlen(p) + 1))){ - WARN("out of mem!"); - free(prop); - return -1; - } - strcpy(prop->key, p); - - if(sep){ - TRACE("option with parameter"); - - if(!(prop->value = malloc(strlen(sep + 1) + 1))){ - WARN("out of mem!"); - free(prop->key); - free(prop); - return -1; - } - strcpy(prop->value, sep + 1); - - if(strstr(p, "password")){ - TRACE("hiding password..."); - memset(sep + 1, ' ', strlen(sep + 1)); - } - }else{ - TRACE("flag"); - - if(!(prop->value = malloc(2))){ - WARN("out of mem!"); - free(prop->key); - free(prop); - return -1; - } - strcpy(prop->value, ""); - - } - - list_add(&prop->list, &class->properties); - - } - - return 0; -} - - diff --git a/perl/.cvsignore b/perl/.cvsignore deleted file mode 100644 index 5d5c2dc..0000000 --- a/perl/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -Fuse.bs Fuse.c Makefile blib pm_to_blib diff --git a/perl/AUTHORS b/perl/AUTHORS deleted file mode 100644 index d0b568c..0000000 --- a/perl/AUTHORS +++ /dev/null @@ -1,4 +0,0 @@ -Perl bindings -------------- - -Mark Glines diff --git a/perl/Changes b/perl/Changes deleted file mode 100644 index 56b4733..0000000 --- a/perl/Changes +++ /dev/null @@ -1,12 +0,0 @@ -Revision history for Perl extension Fuse. - -0.01 Wed Nov 28 21:45:20 2001 - - original version; created by h2xs 1.21 with options - include/fuse.h - -0.02 Sun Dec 2 18:59:56 2001 - - works well enough to release, but still needs testing - -0.03 Wed Dec 5 02:17:52 2001 - - changed getattr() to smell like perl's stat() - - fleshed out the documentation a bit diff --git a/perl/Fuse.pm b/perl/Fuse.pm deleted file mode 100644 index 6a01677..0000000 --- a/perl/Fuse.pm +++ /dev/null @@ -1,360 +0,0 @@ -package Fuse; - -use 5.006; -use strict; -use warnings; -use Errno; -use Carp; - -require Exporter; -require DynaLoader; -use AutoLoader; -use Data::Dumper; -our @ISA = qw(Exporter DynaLoader); - -# Items to export into callers namespace by default. Note: do not export -# names by default without a very good reason. Use EXPORT_OK instead. -# Do not simply export all your public functions/methods/constants. - -# This allows declaration use Fuse ':all'; -# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK -# will save memory. -our %EXPORT_TAGS = ( 'all' => [ qw( - FUSE_DEBUG -) ] ); - -our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); - -our @EXPORT = qw( - FUSE_DEBUG -); -our $VERSION = '0.01'; - -sub AUTOLOAD { - # This AUTOLOAD is used to 'autoload' constants from the constant() - # XS function. If a constant is not found then control is passed - # to the AUTOLOAD in AutoLoader. - - my $constname; - our $AUTOLOAD; - ($constname = $AUTOLOAD) =~ s/.*:://; - croak "& not defined" if $constname eq 'constant'; - my $val = constant($constname, @_ ? $_[0] : 0); - if ($! != 0) { - if ($!{EINVAL}) { - $AutoLoader::AUTOLOAD = $AUTOLOAD; - goto &AutoLoader::AUTOLOAD; - } - else { - croak "Your vendor has not defined Fuse macro $constname"; - } - } - { - no strict 'refs'; - # Fixed between 5.005_53 and 5.005_61 - if ($] >= 5.00561) { - *$AUTOLOAD = sub () { $val }; - } - else { - *$AUTOLOAD = sub { $val }; - } - } - goto &$AUTOLOAD; -} - -bootstrap Fuse $VERSION; - -sub main { - my (@subs) = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - my (@names) = qw(getattr readlink getdir mknod mkdir unlink rmdir symlink - rename link chmod chown truncate utime open read write statfs); - my ($tmp) = 0; - my (%mapping) = map { $_ => $tmp++ } (@names); - my (%otherargs) = (debug=>0, mountpoint=>""); - while(my $name = shift) { - my ($subref) = shift; - if(exists($otherargs{$name})) { - $otherargs{$name} = $subref; - } else { - croak "There is no function $name" unless exists($mapping{$name}); - croak "Usage: Fuse::main(getattr => &my_getattr, ...)" unless $subref; - croak "Usage: Fuse::main(getattr => &my_getattr, ...)" unless ref($subref); - croak "Usage: Fuse::main(getattr => &my_getattr, ...)" unless ref($subref) eq "CODE"; - $subs[$mapping{$name}] = $subref; - } - } - perl_fuse_main($otherargs{debug},$otherargs{mountpoint},@subs); -} - -# Autoload methods go after =cut, and are processed by the autosplit program. - -1; -__END__ - -=head1 NAME - -Fuse - write filesystems in Perl using FUSE - -=head1 SYNOPSIS - - use Fuse; - my ($mountpoint) = ""; - $mountpoint = shift(@ARGV) if @ARGV; - Fuse::main(mountpoint=>$mountpoint, getattr=>\&my_getattr, getdir=>\&my_getdir, ...); - -=head1 DESCRIPTION - -This lets you implement filesystems in perl, through the FUSE -(Filesystem in USErspace) kernel/lib interface. - -FUSE expects you to implement callbacks for the various functions. - -NOTE: I have only tested the things implemented in example.pl! -It should work, but some things may not. - -In the following definitions, "errno" can be 0 (for a success), --EINVAL, -ENOENT, -EONFIRE, any integer less than 1 really. - -You can import standard error constants by saying something like -"use POSIX qw(EDOTDOT ENOANO);". - -Every constant you need (file types, open() flags, error values, -etc) can be imported either from POSIX or from Fcntl, often both. -See their respective documentations, for more information. - -=head2 EXPORT - -None by default. - -=head2 EXPORTABLE CONSTANTS - -None. - -=head2 FUNCTIONS - -=head3 Fuse::main - -Takes arguments in the form of hash key=>value pairs. There are -many valid keys. Most of them correspond with names of callback -functions, as described in section 'FUNCTIONS YOUR FILESYSTEM MAY IMPLEMENT'. -A few special keys also exist: - - -debug => boolean - -=over 1 - -This turns FUSE call tracing on and off. Default is 0 (which means off). - -=back - -mountpoint => string - -=over 1 - -The point at which to mount this filesystem. There is no default, you must -specify this. An example would be '/mnt'. - -=back - -unthreaded => boolean - -=over 1 - -This turns FUSE multithreading off and on. NOTE: This perlmodule does not -currently work properly in multithreaded mode! The author is unfortunately -not familiar enough with perl-threads internals, and according to the -documentation available at time of writing (2002-03-08), those internals are -subject to changing anyway. Note that singlethreaded mode also means that -you will not have to worry about reentrancy, though you will have to worry -about recursive lookups (since the kernel holds a global lock on your -filesystem and blocks waiting for one callback to complete before calling -another). - -I hope to add full multithreading functionality later, but for now, I -recommend you leave this option at the default, 1 (which means -unthreaded, no threads will be used and no reentrancy is needed). - -=back - -=head2 FUNCTIONS YOUR FILESYSTEM MAY IMPLEMENT - -=head3 getattr - -Arguments: filename. -Returns a list, very similar to the 'stat' function (see -perlfunc). On error, simply return a single numeric scalar -value (e.g. "return -ENOENT();"). - -FIXME: the "ino" field is currently ignored. I tried setting it to 0 -in an example script, which consistently caused segfaults. - -Fields (the following was stolen from perlfunc(1) with apologies): - -($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, - $atime,$mtime,$ctime,$blksize,$blocks) - = getattr($filename); - -Here are the meaning of the fields: - - 0 dev device number of filesystem - 1 ino inode number - 2 mode file mode (type and permissions) - 3 nlink number of (hard) links to the file - 4 uid numeric user ID of file's owner - 5 gid numeric group ID of file's owner - 6 rdev the device identifier (special files only) - 7 size total size of file, in bytes - 8 atime last access time in seconds since the epoch - 9 mtime last modify time in seconds since the epoch -10 ctime inode change time (NOT creation time!) in seconds - since the epoch -11 blksize preferred block size for file system I/O -12 blocks actual number of blocks allocated - -(The epoch was at 00:00 January 1, 1970 GMT.) - -=head3 readlink - -Arguments: link pathname. -Returns a scalar: either a numeric constant, or a text string. - -This is called when dereferencing symbolic links, to learn the target. - -example rv: return "/proc/self/fd/stdin"; - -=head3 getdir - -Arguments: Containing directory name. -Returns a list: 0 or more text strings (the filenames), followed by a numeric errno (usually 0). - -This is used to obtain directory listings. Its opendir(), readdir(), filldir() and closedir() all in one call. - -example rv: return ('.', 'a', 'b', 0); - -=head3 mknod - -Arguments: Filename, numeric modes, numeric device -Returns an errno (0 upon success, as usual). - -This function is called for all non-directory, non-symlink nodes, -not just devices. - -=head3 mkdir - -Arguments: New directory pathname, numeric modes. -Returns an errno. - -Called to create a directory. - -=head3 unlink - -Arguments: Filename. -Returns an errno. - -Called to remove a file, device, or symlink. - -=head3 rmdir - -Arguments: Pathname. -Returns an errno. - -Called to remove a directory. - -=head3 symlink - -Arguments: Existing filename, symlink name. -Returns an errno. - -Called to create a symbolic link. - -=head3 rename - -Arguments: old filename, new filename. -Returns an errno. - -Called to rename a file, and/or move a file from one directory to another. - -=head3 link - -Arguments: Existing filename, hardlink name. -Returns an errno. - -Called to create hard links. - -=head3 chmod - -Arguments: Pathname, numeric modes. -Returns an errno. - -Called to change permissions on a file/directory/device/symlink. - -=head3 chown - -Arguments: Pathname, numeric uid, numeric gid. -Returns an errno. - -Called to change ownership of a file/directory/device/symlink. - -=head3 truncate - -Arguments: Pathname, numeric offset. -Returns an errno. - -Called to truncate a file, at the given offset. - -=head3 utime - -Arguments: Pathname, numeric actime, numeric modtime. -Returns an errno. - -Called to change access/modification times for a file/directory/device/symlink. - -=head3 open - -Arguments: Pathname, numeric flags (which is an OR-ing of stuff like O_RDONLY -and O_SYNC, constants you can import from POSIX). -Returns an errno. - -No creation, or trunctation flags (O_CREAT, O_EXCL, O_TRUNC) will be passed to open(). -Your open() method needs only check if the operation is permitted for the given flags, and return 0 for success. - -=head3 read - -Arguments: Pathname, numeric requestedsize, numeric offset. -Returns a numeric errno, or a string scalar with up to $requestedsize bytes of data. - -Called in an attempt to fetch a portion of the file. - -=head3 write - -Arguments: Pathname, scalar buffer, numeric offset. You can use length($buffer) to -find the buffersize. -Returns an errno. - -Called in an attempt to write (or overwrite) a portion of the file. Be prepared because $buffer could contain random binary data with NULLs and all sorts of other wonderful stuff. - -=head3 statfs - -Arguments: none -Returns any of the following: - --ENOANO() - -or - -$namelen, $files, $files_free, $blocks, $blocks_avail, $blocksize - -or - --ENOANO(), $namelen, $files, $files_free, $blocks, $blocks_avail, $blocksize - -=head1 AUTHOR - -Mark Glines, Emark@glines.orgE - -=head1 SEE ALSO - -L, the FUSE documentation. - -=cut diff --git a/perl/Fuse.xs b/perl/Fuse.xs deleted file mode 100644 index 233139a..0000000 --- a/perl/Fuse.xs +++ /dev/null @@ -1,572 +0,0 @@ -#include "EXTERN.h" -#include "perl.h" -#include "XSUB.h" - -#include - -#undef DEBUGf -#if 0 -#define DEBUGf(f, a...) fprintf(stderr, "%s:%d (%i): " f,__BASE_FILE__,__LINE__,PL_stack_sp-PL_stack_base ,##a ) -#else -#define DEBUGf(a...) -#endif - -SV *_PLfuse_callbacks[18]; - -int _PLfuse_getattr(const char *file, struct stat *result) { - dSP; - int rv, statcount; - ENTER; - SAVETMPS; - PUSHMARK(SP); - XPUSHs(sv_2mortal(newSVpv(file,strlen(file)))); - PUTBACK; - rv = call_sv(_PLfuse_callbacks[0],G_ARRAY); - SPAGAIN; - if(rv != 13) { - if(rv > 1) { - fprintf(stderr,"inappropriate number of returned values from getattr\n"); - rv = -ENOSYS; - } else if(rv) - rv = POPi; - else - rv = -ENOENT; - } else { - result->st_blksize = POPi; - result->st_ctime = POPi; - result->st_mtime = POPi; - result->st_atime = POPi; - /* What the HELL? Perl says the blockcount is the last argument. - * Everything else says the blockcount is the last argument. So why - * was it folded into the middle of the list? */ - result->st_blocks = POPi; - result->st_size = POPi; - result->st_rdev = POPi; - result->st_gid = POPi; - result->st_uid = POPi; - result->st_nlink = POPi; - result->st_mode = POPi; - /*result->st_ino =*/ POPi; - result->st_dev = POPi; - rv = 0; - } - FREETMPS; - LEAVE; - PUTBACK; - return rv; -} - -int _PLfuse_readlink(const char *file,char *buf,size_t buflen) { - int rv; - char *rvstr; - dSP; - I32 ax; - if(buflen < 1) - return EINVAL; - ENTER; - SAVETMPS; - PUSHMARK(SP); - XPUSHs(sv_2mortal(newSVpv(file,0))); - PUTBACK; - rv = call_sv(_PLfuse_callbacks[1],G_SCALAR); - SPAGAIN; - if(!rv) - rv = -ENOENT; - else { - SV *mysv = POPs; - if(SvTYPE(mysv) == SVt_IV || SvTYPE(mysv) == SVt_NV) - rv = SvIV(mysv); - else { - strncpy(buf,SvPV_nolen(mysv),buflen); - rv = 0; - } - } - FREETMPS; - LEAVE; - buf[buflen-1] = 0; - PUTBACK; - return rv; -} - -int _PLfuse_getdir(const char *file, fuse_dirh_t dirh, fuse_dirfil_t dirfil) { - int prv, rv; - dSP; - ENTER; - SAVETMPS; - PUSHMARK(SP); - XPUSHs(sv_2mortal(newSVpv(file,0))); - PUTBACK; - prv = call_sv(_PLfuse_callbacks[2],G_ARRAY); - SPAGAIN; - if(prv) { - rv = POPi; - while(--prv) - dirfil(dirh,POPp,0); - } else { - fprintf(stderr,"getdir() handler returned nothing!\n"); - rv = -ENOSYS; - } - FREETMPS; - LEAVE; - PUTBACK; - return rv; -} - -int _PLfuse_mknod (const char *file, mode_t mode, dev_t dev) { - int rv; - SV *rvsv; - char *rvstr; - dSP; - ENTER; - SAVETMPS; - PUSHMARK(SP); - XPUSHs(sv_2mortal(newSVpv(file,0))); - XPUSHs(sv_2mortal(newSViv(mode))); - XPUSHs(sv_2mortal(newSViv(dev))); - PUTBACK; - rv = call_sv(_PLfuse_callbacks[3],G_SCALAR); - SPAGAIN; - if(rv) - rv = POPi; - else - rv = 0; - FREETMPS; - LEAVE; - PUTBACK; - return rv; -} - -int _PLfuse_mkdir (const char *file, mode_t mode) { - int rv; - SV *rvsv; - char *rvstr; - dSP; - DEBUGf("mkdir begin: %i\n",sp-PL_stack_base); - ENTER; - SAVETMPS; - PUSHMARK(SP); - XPUSHs(sv_2mortal(newSVpv(file,0))); - XPUSHs(sv_2mortal(newSViv(mode))); - PUTBACK; - rv = call_sv(_PLfuse_callbacks[4],G_SCALAR); - SPAGAIN; - if(rv) - rv = POPi; - else - rv = 0; - FREETMPS; - LEAVE; - PUTBACK; - DEBUGf("mkdir end: %i %i\n",sp-PL_stack_base,rv); - return rv; -} - - -int _PLfuse_unlink (const char *file) { - int rv; - SV *rvsv; - char *rvstr; - dSP; - DEBUGf("unlink begin: %i\n",sp-PL_stack_base); - ENTER; - SAVETMPS; - PUSHMARK(SP); - XPUSHs(sv_2mortal(newSVpv(file,0))); - PUTBACK; - rv = call_sv(_PLfuse_callbacks[5],G_SCALAR); - SPAGAIN; - if(rv) - rv = POPi; - else - rv = 0; - FREETMPS; - LEAVE; - PUTBACK; - DEBUGf("unlink end: %i\n",sp-PL_stack_base); - return rv; -} - -int _PLfuse_rmdir (const char *file) { - int rv; - SV *rvsv; - char *rvstr; - dSP; - DEBUGf("rmdir begin: %i\n",sp-PL_stack_base); - ENTER; - SAVETMPS; - PUSHMARK(SP); - XPUSHs(sv_2mortal(newSVpv(file,0))); - PUTBACK; - rv = call_sv(_PLfuse_callbacks[6],G_SCALAR); - SPAGAIN; - if(rv) - rv = POPi; - else - rv = 0; - FREETMPS; - LEAVE; - PUTBACK; - DEBUGf("rmdir end: %i %i\n",sp-PL_stack_base,rv); - return rv; -} - -int _PLfuse_symlink (const char *file, const char *new) { - int rv; - SV *rvsv; - char *rvstr; - dSP; - DEBUGf("symlink begin: %i\n",sp-PL_stack_base); - ENTER; - SAVETMPS; - PUSHMARK(SP); - XPUSHs(sv_2mortal(newSVpv(file,0))); - XPUSHs(sv_2mortal(newSVpv(new,0))); - PUTBACK; - rv = call_sv(_PLfuse_callbacks[7],G_SCALAR); - SPAGAIN; - if(rv) - rv = POPi; - else - rv = 0; - FREETMPS; - LEAVE; - PUTBACK; - DEBUGf("symlink end: %i\n",sp-PL_stack_base); - return rv; -} - -int _PLfuse_rename (const char *file, const char *new) { - int rv; - SV *rvsv; - char *rvstr; - dSP; - DEBUGf("rename begin: %i\n",sp-PL_stack_base); - ENTER; - SAVETMPS; - PUSHMARK(SP); - XPUSHs(sv_2mortal(newSVpv(file,0))); - XPUSHs(sv_2mortal(newSVpv(new,0))); - PUTBACK; - rv = call_sv(_PLfuse_callbacks[8],G_SCALAR); - SPAGAIN; - if(rv) - rv = POPi; - else - rv = 0; - FREETMPS; - LEAVE; - PUTBACK; - DEBUGf("rename end: %i\n",sp-PL_stack_base); - return rv; -} - -int _PLfuse_link (const char *file, const char *new) { - int rv; - SV *rvsv; - char *rvstr; - dSP; - DEBUGf("link begin: %i\n",sp-PL_stack_base); - ENTER; - SAVETMPS; - PUSHMARK(SP); - XPUSHs(sv_2mortal(newSVpv(file,0))); - XPUSHs(sv_2mortal(newSVpv(new,0))); - PUTBACK; - rv = call_sv(_PLfuse_callbacks[9],G_SCALAR); - SPAGAIN; - if(rv) - rv = POPi; - else - rv = 0; - FREETMPS; - LEAVE; - PUTBACK; - DEBUGf("link end: %i\n",sp-PL_stack_base); - return rv; -} - -int _PLfuse_chmod (const char *file, mode_t mode) { - int rv; - SV *rvsv; - char *rvstr; - dSP; - DEBUGf("chmod begin: %i\n",sp-PL_stack_base); - ENTER; - SAVETMPS; - PUSHMARK(SP); - XPUSHs(sv_2mortal(newSVpv(file,0))); - XPUSHs(sv_2mortal(newSViv(mode))); - PUTBACK; - rv = call_sv(_PLfuse_callbacks[10],G_SCALAR); - SPAGAIN; - if(rv) - rv = POPi; - else - rv = 0; - FREETMPS; - LEAVE; - PUTBACK; - DEBUGf("chmod end: %i\n",sp-PL_stack_base); - return rv; -} - -int _PLfuse_chown (const char *file, uid_t uid, gid_t gid) { - int rv; - SV *rvsv; - char *rvstr; - dSP; - DEBUGf("chown begin: %i\n",sp-PL_stack_base); - ENTER; - SAVETMPS; - PUSHMARK(SP); - XPUSHs(sv_2mortal(newSVpv(file,0))); - XPUSHs(sv_2mortal(newSViv(uid))); - XPUSHs(sv_2mortal(newSViv(gid))); - PUTBACK; - rv = call_sv(_PLfuse_callbacks[11],G_SCALAR); - SPAGAIN; - if(rv) - rv = POPi; - else - rv = 0; - FREETMPS; - LEAVE; - PUTBACK; - DEBUGf("chown end: %i\n",sp-PL_stack_base); - return rv; -} - -int _PLfuse_truncate (const char *file, off_t off) { - int rv; - SV *rvsv; - char *rvstr; - dSP; - DEBUGf("truncate begin: %i\n",sp-PL_stack_base); - ENTER; - SAVETMPS; - PUSHMARK(SP); - XPUSHs(sv_2mortal(newSVpv(file,0))); - XPUSHs(sv_2mortal(newSViv(off))); - PUTBACK; - rv = call_sv(_PLfuse_callbacks[12],G_SCALAR); - SPAGAIN; - if(rv) - rv = POPi; - else - rv = 0; - FREETMPS; - LEAVE; - PUTBACK; - DEBUGf("truncate end: %i\n",sp-PL_stack_base); - return rv; -} - -int _PLfuse_utime (const char *file, struct utimbuf *uti) { - int rv; - SV *rvsv; - char *rvstr; - dSP; - DEBUGf("utime begin: %i\n",sp-PL_stack_base); - ENTER; - SAVETMPS; - PUSHMARK(SP); - XPUSHs(sv_2mortal(newSVpv(file,0))); - XPUSHs(sv_2mortal(newSViv(uti->actime))); - XPUSHs(sv_2mortal(newSViv(uti->modtime))); - PUTBACK; - rv = call_sv(_PLfuse_callbacks[13],G_SCALAR); - SPAGAIN; - if(rv) - rv = POPi; - else - rv = 0; - FREETMPS; - LEAVE; - PUTBACK; - DEBUGf("utime end: %i\n",sp-PL_stack_base); - return rv; -} - -int _PLfuse_open (const char *file, int flags) { - int rv; - SV *rvsv; - char *rvstr; - dSP; - DEBUGf("open begin: %i\n",sp-PL_stack_base); - ENTER; - SAVETMPS; - PUSHMARK(SP); - XPUSHs(sv_2mortal(newSVpv(file,0))); - XPUSHs(sv_2mortal(newSViv(flags))); - PUTBACK; - rv = call_sv(_PLfuse_callbacks[14],G_SCALAR); - SPAGAIN; - if(rv) - rv = POPi; - else - rv = 0; - FREETMPS; - LEAVE; - PUTBACK; - DEBUGf("open end: %i %i\n",sp-PL_stack_base,rv); - return rv; -} - -int _PLfuse_read (const char *file, char *buf, size_t buflen, off_t off) { - int rv; - char *rvstr; - dSP; - DEBUGf("read begin: %i\n",sp-PL_stack_base); - ENTER; - SAVETMPS; - PUSHMARK(SP); - XPUSHs(sv_2mortal(newSVpv(file,0))); - XPUSHs(sv_2mortal(newSViv(buflen))); - XPUSHs(sv_2mortal(newSViv(off))); - PUTBACK; - rv = call_sv(_PLfuse_callbacks[15],G_SCALAR); - SPAGAIN; - if(!rv) - rv = -ENOENT; - else { - SV *mysv = POPs; - if(SvTYPE(mysv) == SVt_NV || SvTYPE(mysv) == SVt_IV) - rv = SvIV(mysv); - else { - if(SvPOK(mysv)) { - rv = SvCUR(mysv); - } else { - rv = 0; - } - if(rv > buflen) - croak("read() handler returned more than buflen! (%i > %i)",rv,buflen); - if(rv) - memcpy(buf,SvPV_nolen(mysv),rv); - } - } - FREETMPS; - LEAVE; - PUTBACK; - DEBUGf("read end: %i %i\n",sp-PL_stack_base,rv); - return rv; -} - -int _PLfuse_write (const char *file, const char *buf, size_t buflen, off_t off) { - int rv; - char *rvstr; - dSP; - DEBUGf("write begin: %i\n",sp-PL_stack_base); - ENTER; - SAVETMPS; - PUSHMARK(SP); - XPUSHs(sv_2mortal(newSVpv(file,0))); - XPUSHs(sv_2mortal(newSVpvn(buf,buflen))); - XPUSHs(sv_2mortal(newSViv(off))); - PUTBACK; - rv = call_sv(_PLfuse_callbacks[16],G_SCALAR); - SPAGAIN; - if(rv) - rv = POPi; - else - rv = 0; - FREETMPS; - LEAVE; - PUTBACK; - DEBUGf("write end: %i\n",sp-PL_stack_base); - return rv; -} - -int _PLfuse_statfs (const char *file, struct statfs *st) { - int rv; - char *rvstr; - dSP; - DEBUGf("statfs begin: %i\n",sp-PL_stack_base); - ENTER; - SAVETMPS; - PUSHMARK(SP); - PUTBACK; - rv = call_sv(_PLfuse_callbacks[17],G_ARRAY); - SPAGAIN; - if(rv > 5) { - st->f_bsize = POPi; - st->f_bfree = POPi; - st->f_blocks = POPi; - st->f_ffree = POPi; - st->f_files = POPi; - st->f_namelen = POPi; - if(rv > 6) - rv = POPi; - else - rv = 0; - } else - if(rv > 1) - croak("inappropriate number of returned values from statfs"); - else - if(rv) - rv = POPi; - else - rv = -ENOSYS; - FREETMPS; - LEAVE; - PUTBACK; - DEBUGf("statfs end: %i\n",sp-PL_stack_base); - return rv; -} - -struct fuse_operations _available_ops = { -getattr: _PLfuse_getattr, - _PLfuse_readlink, - _PLfuse_getdir, - _PLfuse_mknod, - _PLfuse_mkdir, - _PLfuse_unlink, - _PLfuse_rmdir, - _PLfuse_symlink, - _PLfuse_rename, - _PLfuse_link, - _PLfuse_chmod, - _PLfuse_chown, - _PLfuse_truncate, - _PLfuse_utime, - _PLfuse_open, - _PLfuse_read, - _PLfuse_write, - _PLfuse_statfs -}; - -MODULE = Fuse PACKAGE = Fuse -PROTOTYPES: DISABLE - -void -perl_fuse_main(...) - PREINIT: - struct fuse_operations fops = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; - int i, fd, varnum = 0, debug, have_mnt; - char *mountpoint; - STRLEN n_a; - STRLEN l; - INIT: - if(items != 20) { - fprintf(stderr,"Perl<->C inconsistency or internal error\n"); - XSRETURN_UNDEF; - } - CODE: - debug = SvIV(ST(0)); - mountpoint = SvPV_nolen(ST(1)); - /* FIXME: reevaluate multithreading support when perl6 arrives */ - for(i=0;i<18;i++) { - SV *var = ST(i+2); - if((var != &PL_sv_undef) && SvROK(var)) { - if(SvTYPE(SvRV(var)) == SVt_PVCV) { - void **tmp1 = (void**)&_available_ops, **tmp2 = (void**)&fops; - tmp2[i] = tmp1[i]; - _PLfuse_callbacks[i] = var; - } else - croak("arg is not a code reference!"); - } - } - /* FIXME: need to pass fusermount arguments */ - fd = fuse_mount(mountpoint,NULL); - if(fd < 0) - croak("could not mount fuse filesystem!"); - fuse_loop(fuse_new(fd,debug ? "debug" : NULL,&fops)); diff --git a/perl/MANIFEST b/perl/MANIFEST deleted file mode 100644 index 3012c02..0000000 --- a/perl/MANIFEST +++ /dev/null @@ -1,7 +0,0 @@ -Changes -Fuse.pm -Fuse.xs -Makefile.PL -MANIFEST -README -test.pl diff --git a/perl/Makefile.PL b/perl/Makefile.PL deleted file mode 100644 index 6e66f46..0000000 --- a/perl/Makefile.PL +++ /dev/null @@ -1,17 +0,0 @@ -use ExtUtils::MakeMaker; -# See lib/ExtUtils/MakeMaker.pm for details of how to influence -# the contents of the Makefile that is written. -WriteMakefile( - 'NAME' => 'Fuse', - 'VERSION_FROM' => 'Fuse.pm', # finds $VERSION - 'PREREQ_PM' => {}, # e.g., Module::Name => 1.1 - ($] >= 5.005 ? ## Add these new keywords supported since 5.005 - (ABSTRACT_FROM => 'Fuse.pm', # retrieve abstract from module - AUTHOR => 'Mark Glines ') : ()), - 'LIBS' => [''], # e.g., '-lm' - 'DEFINE' => '-g -ggdb', # e.g., '-DHAVE_SOMETHING' - # Insert -I. if you add *.h files later: - 'INC' => '-I../include', # e.g., '-I/usr/include/other' - # Un-comment this if you add C files to link with later: - 'OBJECT' => 'Fuse.o ../lib/.libs/libfuse.a -lpthread', # link all the C files too -); diff --git a/perl/README b/perl/README deleted file mode 100644 index fb49cd7..0000000 --- a/perl/README +++ /dev/null @@ -1,69 +0,0 @@ -Fuse version 0.03 -================= - -This is a test release. It seems to work quite well. In fact, I can't -find any problems with it whatsoever. If you do, I want to know. - - -INSTALLATION - -To install this module type the standard commands as root: - - perl Makefile.PL - make - make test - make install - - -DEPENDENCIES - -This module requires the FUSE userspace library and the FUSE kernel module. - - -COPYRIGHT AND LICENCE - -This is contributed to the FUSE project by Mark Glines , -and is therefore subject to the same license and copyright as FUSE itself. -Please see the AUTHORS and COPYING files from the FUSE distribution for -more information. - - -EXAMPLES - -There are a few example scripts. You can find them in the examples/ -subdirectory. These are: - -* example.pl, a simple "Hello world" type of script - -* loopback.pl, a filesystem loopback-device. like fusexmp from - the main FUSE dist, it simply recurses file operations - into the real filesystem. Unlike fusexmp, it only - re-shares files under the /tmp/test directory. - -* rmount.pl, an NFS-workalike which tunnels through SSH. It requires - an account on some ssh server (obviously), with public-key - authentication enabled. (if you have to type in a password, - you don't have this. man ssh_keygen.). Copy rmount_remote.pl - to your home directory on the remote machine, and create a - subdir somewhere, and then run it like: - ./rmount.pl host /remote/dir /local/dir - -* rmount_remote.pl, a ripoff of loopback.pl meant to be used as a backend - for rmount.pl. - - -BUGS - -I've begun to build a formal testing framework. Currently it can mount -and unmount loopback.pl, and all of the base-level functions have test -scripts. These need to be fleshed out as problems are noticed. - -The current test framework seems to work well, but the underlying mount/ -unmount infrastructure is a crock. I am not pleased with that code. - -While most things work, I do still have a TODO list: -* "du -sb" reports a couple orders of magnitude too large a size. -* need to sort out cleaner mount semantics for the test framework -* figure out how to un-linuxcentrify the statfs tests -* test everything on other architectures and OS's - diff --git a/perl/examples/example.pl b/perl/examples/example.pl deleted file mode 100755 index 9ba1117..0000000 --- a/perl/examples/example.pl +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/perl - -use Fuse; -use POSIX qw(ENOENT EISDIR EINVAL); - -my (%files) = ( - '.' => { - type => 0040, - mode => 0755, - ctime => time()-1000 - }, - a => { - cont => "File 'a'.\n", - type => 0100, - mode => 0755, - ctime => time()-2000 - }, - b => { - cont => "This is file 'b'.\n", - type => 0100, - mode => 0644, - ctime => time()-1000 - }, -); - -sub filename_fixup { - my ($file) = shift; - $file =~ s,^/,,; - $file = '.' unless length($file); - return $file; -} - -sub e_getattr { - my ($file) = filename_fixup(shift); - $file =~ s,^/,,; - $file = '.' unless length($file); - return -ENOENT() unless exists($files{$file}); - my ($size) = exists($files{$file}{cont}) ? length($files{$file}{cont}) : 0; - my ($modes) = ($files{$file}{type}<<9) + $files{$file}{mode}; - my ($dev, $ino, $rdev, $blocks, $gid, $uid, $nlink, $blksize) = (0,0,0,1,0,0,1,1024); - my ($atime, $ctime, $mtime); - $atime = $ctime = $mtime = $files{$file}{ctime}; - # 2 possible types of return values: - #return -ENOENT(); # or any other error you care to - #print(join(",",($dev,$ino,$modes,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks)),"\n"); - return ($dev,$ino,$modes,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks); -} - -sub e_getdir { - # return as many text filenames as you like, followed by the retval. - print((scalar keys %files)."\n"); - return (keys %files),0; -} - -sub e_open { - # VFS sanity check; it keeps all the necessary state, not much to do here. - my ($file) = filename_fixup(shift); - print("open called\n"); - return -ENOENT() unless exists($files{$file}); - return -EISDIR() unless exists($files{$file}{cont}); - print("open ok\n"); - return 0; -} - -sub e_read { - # return an error numeric, or binary/text string. (note: 0 means EOF, "0" will - # give a byte (ascii "0") to the reading program) - my ($file) = filename_fixup(shift); - my ($buf,$off) = @_; - return -ENOENT() unless exists($files{$file}); - return -EINVAL() if $off > length($files{$file}{cont}); - return 0 if $off == length($files{$file}{cont}); - return substr($files{$file}{cont},$off,$buf); -} - -sub e_statfs { return 255, 1, 1, 1, 1, 2 } - -# If you run the script directly, it will run fusermount, which will in turn -# re-run this script. Hence the funky semantics. -my ($mountpoint) = ""; -$mountpoint = shift(@ARGV) if @ARGV; -Fuse::main( - mountpoint=>$mountpoint, - getattr=>\&e_getattr, - getdir=>\&e_getdir, - open=>\&e_open, - statfs=>\&e_statfs, - read=>\&e_read, - #debug=>1, threaded=>0 -); diff --git a/perl/examples/loopback.pl b/perl/examples/loopback.pl deleted file mode 100755 index bdc8c22..0000000 --- a/perl/examples/loopback.pl +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/perl - -use strict; -use Fuse; -use IO::File; -use POSIX qw(ENOENT ENOSYS EEXIST EPERM O_RDONLY O_RDWR O_APPEND O_CREAT); -use Fcntl qw(S_ISBLK S_ISCHR S_ISFIFO SEEK_SET); -require 'syscall.ph'; # for SYS_mknod and SYS_lchown - -sub fixup { return "/tmp/fusetest" . shift } - -sub x_getattr { - my ($file) = fixup(shift); - my (@list) = lstat($file); - return -$! unless @list; - return @list; -} - -sub x_getdir { - my ($dirname) = fixup(shift); - unless(opendir(DIRHANDLE,$dirname)) { - return -ENOENT(); - } - my (@files) = readdir(DIRHANDLE); - closedir(DIRHANDLE); - return (@files, 0); -} - -sub x_open { - my ($file) = fixup(shift); - my ($mode) = shift; - return -$! unless sysopen(FILE,$file,$mode); - close(FILE); - return 0; -} - -sub x_read { - my ($file,$bufsize,$off) = @_; - my ($rv) = -ENOSYS(); - my ($handle) = new IO::File; - return -ENOENT() unless -e ($file = fixup($file)); - my ($fsize) = -s $file; - return -ENOSYS() unless open($handle,$file); - if(seek($handle,$off,SEEK_SET)) { - read($handle,$rv,$bufsize); - } - return $rv; -} - -sub x_write { - my ($file,$buf,$off) = @_; - my ($rv); - return -ENOENT() unless -e ($file = fixup($file)); - my ($fsize) = -s $file; - return -ENOSYS() unless open(FILE,'+<',$file); - if($rv = seek(FILE,$off,SEEK_SET)) { - $rv = print(FILE $buf); - } - $rv = -ENOSYS() unless $rv; - close(FILE); - return length($buf); -} - -sub err { return (-shift || -$!) } - -sub x_readlink { return readlink(fixup(shift) ); } -sub x_unlink { return unlink(fixup(shift)) ? 0 : -$!; } -sub x_rmdir { return err(rmdir(fixup(shift)) ); } - -sub x_symlink { print "symlink\n"; return symlink(shift,fixup(shift)) ? 0 : -$!; } - -sub x_rename { - my ($old) = fixup(shift); - my ($new) = fixup(shift); - my ($err) = rename($old,$new) ? 0 : -ENOENT(); - return $err; -} -sub x_link { return link(fixup(shift),fixup(shift)) ? 0 : -$! } -sub x_chown { - my ($fn) = fixup(shift); - print "nonexistent $fn\n" unless -e $fn; - my ($uid,$gid) = @_; - # perl's chown() does not chown symlinks, it chowns the symlink's - # target. it fails when the link's target doesn't exist, because - # the stat64() syscall fails. - # this causes error messages when unpacking symlinks in tarballs. - my ($err) = syscall(&SYS_lchown,$fn,$uid,$gid,$fn) ? -$! : 0; - return $err; -} -sub x_chmod { - my ($fn) = fixup(shift); - my ($mode) = shift; - my ($err) = chmod($mode,$fn) ? 0 : -$!; - return $err; -} -sub x_truncate { return truncate(fixup(shift),shift) ? 0 : -$! ; } -sub x_utime { return utime($_[1],$_[2],fixup($_[0])) ? 0:-$!; } - -sub x_mkdir { my ($name, $perm) = @_; return 0 if mkdir(fixup($name),$perm); return -$!; } -sub x_rmdir { return 0 if rmdir fixup(shift); return -$!; } - -sub x_mknod { - # since this is called for ALL files, not just devices, I'll do some checks - # and possibly run the real mknod command. - my ($file, $modes, $dev) = @_; - $file = fixup($file); - $! = 0; - syscall(&SYS_mknod,$file,$modes,$dev); - return -$!; -} - -# kludge -sub x_statfs {return 255,1000000,500000,1000000,500000,4096} -my ($mountpoint) = ""; -$mountpoint = shift(@ARGV) if @ARGV; -Fuse::main( - mountpoint=>$mountpoint, - getattr=>\&x_getattr, - readlink=>\&x_readlink, - getdir=>\&x_getdir, - mknod=>\&x_mknod, - mkdir=>\&x_mkdir, - unlink=>\&x_unlink, - rmdir=>\&x_rmdir, - symlink=>\&x_symlink, - rename=>\&x_rename, - link=>\&x_link, - chmod=>\&x_chmod, - chown=>\&x_chown, - truncate=>\&x_truncate, - utime=>\&x_utime, - open=>\&x_open, - read=>\&x_read, - write=>\&x_write, - statfs=>\&x_statfs, -); diff --git a/perl/examples/rmount.pl b/perl/examples/rmount.pl deleted file mode 100755 index 9ae1cc1..0000000 --- a/perl/examples/rmount.pl +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/perl - -use strict; -use Net::SSH 'sshopen2'; -use IPC::Open2; -use Fuse; -use Data::Dumper; - -my ($host, $dir, $mount) = @ARGV; -if(!defined($mount)) { - $mount = $dir; - if($host =~ /^(.*):(.*)$/) { - ($host,$dir) = ($1,$2); - } else { - die "usage: $0 user\@host remotedir mountpoint\n". - "or : $0 user\@host:remotedir mountpoint\n"; - } -} - -`umount $mount` unless -d $mount; -die "mountpoint $mount isn't a directory!\n" unless -d $mount; - -my (%args) = (mountpoint => $mount); - -map { my ($str) = $_; $args{$str} = sub { netlink($str,@_) } } - qw(getattr getdir open read write readlink unlink rmdir - symlink rename link chown chmod truncate utime mkdir - rmdir mknod statfs); - -sub connect_remote { - sshopen2($host, *READER, *WRITER, "./rmount_remote.pl $dir") - or die "ssh: $!\n"; - select WRITER; - $| = 1; - select STDOUT; -} - -$SIG{CHLD} = sub { - use POSIX ":sys_wait_h"; - my $kid; - do { - $kid = waitpid(-1,WNOHANG); - } until $kid < 1; -}; - -connect_remote; - -sub netlink { - my ($str) = Dumper(\@_)."\n"; - $str = sprintf("%08i\n%s",length($str),$str); - while(1) { # retry as necessary - my ($sig) = $SIG{ALRM}; - my ($VAR1); - $VAR1 = undef; - eval { - $SIG{ALRM} = sub { die "timeout\n" }; - alarm 10; - print WRITER $str; - my ($len, $data); - if(read(READER,$len,9) == 9) { - read(READER,$data,$len-length($data),length($data)) - while(length($data) < $len); - eval $data; - } - }; - alarm 0; - $SIG{ALRM} = $sig; - if(defined $VAR1) { - return wantarray ? @{$VAR1} : $$VAR1[0]; - } - print STDERR "failed to send command; reconnecting ssh\n"; - close(READER); - close(WRITER); - connect_remote(); - } -} - -Fuse::main(%args); - -netlink("bye"); -close(READER); -close(WRITER); diff --git a/perl/examples/rmount_remote.pl b/perl/examples/rmount_remote.pl deleted file mode 100755 index e9e0866..0000000 --- a/perl/examples/rmount_remote.pl +++ /dev/null @@ -1,143 +0,0 @@ -#!/usr/bin/perl - -use strict; -use IO::File; -use POSIX qw(ENOENT ENOSYS EEXIST EPERM O_RDONLY O_RDWR O_APPEND O_CREAT); -use Fcntl qw(S_ISBLK S_ISCHR S_ISFIFO SEEK_SET); -use Data::Dumper; -require 'syscall.ph'; # for SYS_mknod and SYS_lchown - -my ($rootdir) = @ARGV; - -# strip leading and trailing slashes -$rootdir = $1 if($rootdir =~ /^\/?(.*)\/?$/); - -sub fixup { return "/$rootdir" . shift } - -sub x_getattr { - my ($file) = fixup(shift); - my (@list) = lstat($file); - return -$! unless @list; - return @list; -} - -sub x_getdir { - my ($dirname) = fixup(shift); - unless(opendir(DIRHANDLE,$dirname)) { - return -ENOENT(); - } - my (@files) = readdir(DIRHANDLE); - closedir(DIRHANDLE); - return (@files, 0); -} - -sub x_open { - my ($file) = fixup(shift); - my ($mode) = shift; - return -$! unless sysopen(FILE,$file,$mode); - close(FILE); - return 0; -} - -sub x_read { - my ($file,$bufsize,$off) = @_; - my ($rv) = -ENOSYS(); - my ($handle) = new IO::File; - return -ENOENT() unless -e ($file = fixup($file)); - my ($fsize) = -s $file; - return -ENOSYS() unless open($handle,$file); - if(seek($handle,$off,SEEK_SET)) { - read($handle,$rv,$bufsize); - } - return $rv; -} - -sub x_write { - my ($file,$buf,$off) = @_; - my ($rv); - return -ENOENT() unless -e ($file = fixup($file)); - my ($fsize) = -s $file; - return -ENOSYS() unless open(FILE,'+<',$file); - if($rv = seek(FILE,$off,SEEK_SET)) { - $rv = print(FILE $buf); - } - $rv = -ENOSYS() unless $rv; - close(FILE); - return length($buf); -} - -sub err { return (-shift || -$!) } - -sub x_readlink { return readlink(fixup(shift) ); } -sub x_unlink { return unlink(fixup(shift)) ? 0 : -$!; } -sub x_rmdir { return err(rmdir(fixup(shift)) ); } - -sub x_symlink { print "symlink\n"; return symlink(shift,fixup(shift)) ? 0 : -$!; } - -sub x_rename { - my ($old) = fixup(shift); - my ($new) = fixup(shift); - my ($err) = rename($old,$new) ? 0 : -ENOENT(); - return $err; -} -sub x_link { return link(fixup(shift),fixup(shift)) ? 0 : -$! } -sub x_chown { - my ($fn) = fixup(shift); - print "nonexistent $fn\n" unless -e $fn; - my ($uid,$gid) = @_; - # perl's chown() does not chown symlinks, it chowns the symlink's - # target. it fails when the link's target doesn't exist, because - # the stat64() syscall fails. - # this causes error messages when unpacking symlinks in tarballs. - my ($err) = syscall(&SYS_lchown,$fn,$uid,$gid,$fn) ? -$! : 0; - return $err; -} -sub x_chmod { - my ($fn) = fixup(shift); - my ($mode) = shift; - my ($err) = chmod($mode,$fn) ? 0 : -$!; - return $err; -} -sub x_truncate { return truncate(fixup(shift),shift) ? 0 : -$! ; } -sub x_utime { return utime($_[1],$_[2],fixup($_[0])) ? 0:-$!; } - -sub x_mkdir { my ($name, $perm) = @_; return 0 if mkdir(fixup($name),$perm); return -$!; } -sub x_rmdir { return 0 if rmdir fixup(shift); return -$!; } - -sub x_mknod { - # since this is called for ALL files, not just devices, I'll do some checks - # and possibly run the real mknod command. - my ($file, $modes, $dev) = @_; - $file = fixup($file); - $! = 0; - syscall(&SYS_mknod,$file,$modes,$dev); - return -$!; -} - -# kludge -sub x_statfs {return 255,1000000,500000,1000000,500000,4096} - -$| = 1; -my ($len); -while(read(STDIN,$len,9) == 9) { - chomp $len; - my ($data,$VAR1,@args); - eval { - $SIG{ALRM} = sub { die "timeout\n"}; - $data = ""; - alarm 5; - read(STDIN,$data,$len-length($data),length($data)) - while(length($data) < $len); - alarm 0; - }; - die $@ if $@; - eval $data; - @args = @{$VAR1}; - my $cmd = shift(@args); - exit 0 if $cmd eq "bye"; - die "cannot find command $cmd\n" unless exists($main::{"x_$cmd"}); - @args = $main::{"x_$cmd"}(@args); - $cmd = Dumper(\@args)."\n"; - $cmd = sprintf("%08i\n%s",length($cmd),$cmd); - print $cmd; -} diff --git a/perl/test.pl b/perl/test.pl deleted file mode 100644 index e8152fd..0000000 --- a/perl/test.pl +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/perl -BEGIN { $ENV{HARNESS_IGNORE_EXITCODE} = 1; } - -use Test::Harness qw(&runtests $verbose); -$verbose=0; -die "cannot find test directory!" unless -d "test"; -my (@files) = ; -runtests("test/s/mount.t",sort(@files),"test/s/umount.t"); diff --git a/perl/test/chmod.t b/perl/test/chmod.t deleted file mode 100644 index 366f89b..0000000 --- a/perl/test/chmod.t +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 4; -chdir($_point); -system("echo frog >file"); -ok(chmod(0644,"file"),"set unexecutable"); -ok(!-x "file","unexecutable"); -ok(chmod(0755,"file"),"set executable"); -ok(-x "file","executable"); -unlink("file"); diff --git a/perl/test/chown.t b/perl/test/chown.t deleted file mode 100644 index 8ccbb88..0000000 --- a/perl/test/chown.t +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 4; -my (@stat); -chdir($_point); -system("echo frog >file"); -ok(chown(0,0,"file"),"set 0,0"); -@stat = stat("file"); -ok($stat[4] == 0 && $stat[5] == 0,"0,0"); -ok(chown(1,1,"file"),"set 1,1"); -@stat = stat("file"); -ok($stat[4] == 1 && $stat[5] == 1,"1,1"); -unlink("file"); diff --git a/perl/test/getattr.t b/perl/test/getattr.t deleted file mode 100644 index 4203275..0000000 --- a/perl/test/getattr.t +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -use Data::Dumper; -plan tests => 28; -my ($a, $b) = ("$_real/wibble","$_point/wibble"); -`touch $b`; -is(-A "$a", -A "$b", '-A'); # 1 -is(-B "$a", -B "$b", '-B'); # 2 -is(-C "$a", -C "$b", '-C'); # 3 -is(-M "$a", -M "$b", '-M'); # 4 -is(-O "$a", -O "$b", '-O'); # 5 -is(-R "$a", -R "$b", '-R'); # 6 -is(-S "$a", -S "$b", '-S'); # 7 -is(-T "$a", -T "$b", '-T'); # 8 -is(-W "$a", -W "$b", '-W'); # 9 -is(-X "$a", -X "$b", '-X'); # 10 -is(-b "$a", -b "$b", '-b'); # 11 -is(-c "$a", -c "$b", '-c'); # 12 -is(-d "$a", -d "$b", '-d'); # 13 -is(-e "$a", -e "$b", '-e'); # 14 -is(-f "$a", -f "$b", '-f'); # 15 -is(-g "$a", -g "$b", '-g'); # 16 -is(-k "$a", -k "$b", '-k'); # 17 -is(-l "$a", -l "$b", '-l'); # 18 -is(-o "$a", -o "$b", '-o'); # 19 -is(-p "$a", -p "$b", '-p'); # 20 -is(-r "$a", -r "$b", '-r'); # 21 -is(-s "$a", -s "$b", '-s'); # 22 -is(-t "$a", -t "$b", '-t'); # 23 -is(-u "$a", -u "$b", '-u'); # 24 -is(-w "$a", -w "$b", '-w'); # 25 -is(-x "$a", -x "$b", '-x'); # 26 -is(-z "$a", -z "$b", '-z'); # 27 -my (@astat, @bstat); -@astat = stat("$a"); -@bstat = stat("$b"); -# dev and inode can legally change -shift(@astat); shift(@astat); -shift(@bstat); shift(@bstat); -is(join(" ",@astat),join(" ",@bstat),"stat()"); -`rm -f $a`; diff --git a/perl/test/getdir.t b/perl/test/getdir.t deleted file mode 100644 index 1d60561..0000000 --- a/perl/test/getdir.t +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -my (@names) = qw(abc def ghi jkl mno pqr stu jlk sfdaljk sdfakjlsdfa kjldsf kjl;sdf akjl;asdf klj;asdf lkjsdflkjsdfkjlsdfakjsdfakjlsadfkjl;asdfklj;asdfkjl;asdfklj;asdfkjl;asdfkjlasdflkj;sadf); -@names = sort(@names); -plan tests => 2 * scalar @names; -chdir($_real); - -# create entries -map { system("touch \"$_\"") } @names; - -# make sure they exist in real dir -opendir(REAL,$_real); -my (@ents) = readdir(REAL); -closedir(REAL); -@ents = sort(@ents); -map { - shift(@ents) while($ents[0] eq '.' || $ents[0] eq '..'); - is(shift(@ents),$_,"ent $_") -} @names; - -# make sure they exist in fuse dir -opendir(POINT,$_point); -@ents = readdir(POINT); -closedir(POINT); -@ents = sort(@ents); -map { - shift(@ents) while($ents[0] eq '.' || $ents[0] eq '..'); - is(shift(@ents),$_,"ent $_") -} @names; - -# remove them -map { unlink } @names; diff --git a/perl/test/helper.pm b/perl/test/helper.pm deleted file mode 100644 index cd2bd55..0000000 --- a/perl/test/helper.pm +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/perl -package test::helper; -use strict; -use Exporter; -our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); -@ISA = "Exporter"; -@EXPORT_OK = qw($_loop $_point $_pidfile $_real); -our($_loop, $_point, $_pidfile, $_real) = ("examples/loopback.pl","/mnt","test/s/mounted.pid","/tmp/fusetest"); -if($0 !~ qr|s/u?mount\.t$|) { - my ($reject) = 1; - if(-f $_pidfile) { - unless(system("ps `cat $_pidfile` | grep \"$_loop $_point\" >/dev/null")>>8) { - if(`mount | grep "on $_point"`) { - $reject = 0; - } else { - system("kill `cat $_pidfile`"); - } - } - } - $reject = 1 if (system("ls $_point >&/dev/null") >> 8); - die "not properly mounted\n" if $reject; -} -1; diff --git a/perl/test/link.t b/perl/test/link.t deleted file mode 100644 index 391b2f0..0000000 --- a/perl/test/link.t +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 8; -chdir($_point); -system("echo hippity >womble"); -ok(-f "womble","exists"); -ok(!-f "rabbit","target file doesn't exist"); -is(-s "womble",8,"right size"); -ok(link("womble","rabbit"),"link"); -ok(-f "womble","old file exists"); -ok(-f "rabbit","target file exists"); -is(-s "womble",8,"right size"); -is(-s "rabbit",8,"right size"); -unlink("womble"); -unlink("rabbit"); diff --git a/perl/test/mkdir.t b/perl/test/mkdir.t deleted file mode 100644 index 90ec6f3..0000000 --- a/perl/test/mkdir.t +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 3; -chdir($_point); -ok(mkdir("dir"),"mkdir"); -ok(-d "dir","dir exists"); -chdir($_real); -ok(-d "dir","dir really exists"); -chdir($_point); -rmdir("dir"); diff --git a/perl/test/mknod.t b/perl/test/mknod.t deleted file mode 100644 index 35c5c82..0000000 --- a/perl/test/mknod.t +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 24; -my (@stat); -chdir($_point); -ok(!(system("touch reg" )>>8),"create normal file"); -ok(!(system("mknod chr c 2 3")>>8),"create chrdev"); -ok(!(system("mknod blk b 2 3")>>8),"create blkdev"); -ok(!(system("mknod fifo p" )>>8),"create fifo"); -chdir($_real); -ok(-e "reg" ,"normal file exists"); -ok(-e "chr" ,"chrdev exists"); -ok(-e "blk" ,"blkdev exists"); -ok(-e "fifo","fifo exists"); -ok(-f "reg" ,"normal file is normal file"); -ok(-c "chr" ,"chrdev is chrdev"); -ok(-b "blk" ,"blkdev is blkdev"); -ok(-p "fifo","fifo is fifo"); -@stat = stat("chr"); -is($stat[6],3+(2<<8),"chrdev has right major,minor"); -@stat = stat("blk"); -is($stat[6],3+(2<<8),"blkdev has right major,minor"); -chdir($_point); -ok(-e "reg" ,"normal file exists"); -ok(-e "chr" ,"chrdev exists"); -ok(-e "blk" ,"blkdev exists"); -ok(-e "fifo","fifo exists"); -ok(-f "reg" ,"normal file is normal file"); -ok(-c "chr" ,"chrdev is chrdev"); -ok(-b "blk" ,"blkdev is blkdev"); -ok(-p "fifo","fifo is fifo"); -@stat = stat("chr"); -is($stat[6],3+(2<<8),"chrdev has right major,minor"); -@stat = stat("blk"); -is($stat[6],3+(2<<8),"blkdev has right major,minor"); -map { unlink } qw(reg chr blk fifo); diff --git a/perl/test/open.t b/perl/test/open.t deleted file mode 100644 index 030dc1f..0000000 --- a/perl/test/open.t +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 1; -chdir($_real); -system("echo frog >file"); -chdir($_point); -ok(open(FILE,"file"),"open"); -close(FILE); -unlink("file"); diff --git a/perl/test/read.t b/perl/test/read.t deleted file mode 100644 index 5eca920..0000000 --- a/perl/test/read.t +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 3; -chdir($_real); -system("echo frog >file"); -chdir($_point); -ok(open(FILE,"file"),"open"); -my ($data) = ; -close(FILE); -is(length($data),5,"right amount read"); -is($data,"frog\n","right data read"); -unlink("file"); diff --git a/perl/test/readlink.t b/perl/test/readlink.t deleted file mode 100644 index 85b9ffc..0000000 --- a/perl/test/readlink.t +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_point $_real); -use Test::More; -plan tests => 4; -chdir($_real); -ok(symlink("abc","def"),"OS supports symlinks"); -is(readlink("def"),"abc","OS supports symlinks"); -chdir($_point); -ok(-l "def","symlink exists"); -is(readlink("def"),"abc","readlink"); -unlink("def"); diff --git a/perl/test/rename.t b/perl/test/rename.t deleted file mode 100644 index 9fbb330..0000000 --- a/perl/test/rename.t +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 5; -chdir($_point); -system("echo hippity >frog"); -ok(-f "frog","exists"); -ok(!-f "toad","target file doesn't exist"); -ok(rename("frog","toad"),"rename"); -ok(!-f "frog","old file doesn't exist"); -ok(-f "toad","target file exists"); -unlink("toad"); diff --git a/perl/test/rmdir.t b/perl/test/rmdir.t deleted file mode 100644 index 36f0378..0000000 --- a/perl/test/rmdir.t +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 5; -chdir($_real); -ok(mkdir("dir"),"mkdir"); -ok(-d "dir","dir really exists"); -chdir($_point); -ok(-d "dir","dir exists"); -rmdir("dir"); -ok(! -d "dir","dir removed"); -chdir($_real); -ok(! -d "dir","dir really removed"); diff --git a/perl/test/s/mount.t b/perl/test/s/mount.t deleted file mode 100644 index 26f6fc2..0000000 --- a/perl/test/s/mount.t +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/perl -w -use test::helper qw($_point $_loop $_real $_pidfile); -use strict; -use Test::More tests => 3; -ok(!(scalar grep(/ on $_point /,`cat /proc/mounts`)),"already mounted"); -ok(-f $_loop,"loopback exists"); - -if(!fork()) { - #close(STDIN); - close(STDOUT); - close(STDERR); - `echo $$ >test/s/mounted.pid`; - exec("perl $_loop $_point"); - exit(1); -} -select(undef, undef, undef, 0.5); -my ($success) = `cat /proc/mounts` =~ / $_point /; -ok($success,"mount succeeded"); -system("rm -rf $_real"); -unless($success) { - kill('INT',`cat $_pidfile`); - unlink($_pidfile); -} else { - mkdir($_real); -} diff --git a/perl/test/s/umount.t b/perl/test/s/umount.t deleted file mode 100644 index da60677..0000000 --- a/perl/test/s/umount.t +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_point $_real $_pidfile); -use strict; -use Test::More tests => 1; -system("umount $_point"); -ok(1,"unmount"); -system("rm -rf $_real $_pidfile"); diff --git a/perl/test/statfs.t b/perl/test/statfs.t deleted file mode 100644 index fb94704..0000000 --- a/perl/test/statfs.t +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -require 'syscall.ph'; # for SYS_statfs -plan tests => 7; -my ($statfs_data) = " " x 10; -my ($tmp) = $_point; -ok(!syscall(&SYS_statfs,$tmp,$statfs_data),"statfs"); -# FIXME: this is soooooo linux-centric. perhaps parse the output of /bin/df? -my @list = unpack("LSSL8",$statfs_data); -shift(@list); -is(shift(@list),4096,"block size"); -shift(@list); -is(shift(@list),1000000,"blocks"); -is(shift(@list),500000,"blocks free"); -shift(@list); -is(shift(@list),1000000,"files"); -is(shift(@list),500000,"files free"); -shift(@list); -shift(@list); -is(shift(@list),255,"namelen"); diff --git a/perl/test/symlink.t b/perl/test/symlink.t deleted file mode 100644 index 19cc72d..0000000 --- a/perl/test/symlink.t +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_point $_real); -use Test::More; -plan tests => 6; -chdir($_point); -ok(symlink("abc","def"),"symlink created"); -ok(-l "def","symlink exists"); -is(readlink("def"),"abc","it worked"); -chdir($_real); -ok(-l "def","symlink really exists"); -is(readlink("def"),"abc","really worked"); -unlink("def"); - -# bug: doing a 'cp -a' on a directory which contains a symlink -# reports an error -mkdir("dira"); -system("cd dira; touch filea; ln -s filea fileb"); -is(system("cp -a dira dirb")>>8,0,"cp -a"); -system("rm -rf dira dirb"); diff --git a/perl/test/test-template b/perl/test/test-template deleted file mode 100644 index ef57e08..0000000 --- a/perl/test/test-template +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 1; -ok(1); diff --git a/perl/test/truncate.t b/perl/test/truncate.t deleted file mode 100644 index 8607421..0000000 --- a/perl/test/truncate.t +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 5; -chdir($_point); -system("echo hippity >womble"); -ok(-f "womble","exists"); -is(-s "womble",8,"right size"); -ok(truncate("womble",4),"truncate"); -ok(-f "womble","file exists"); -is(-s "womble",4,"right size"); -unlink("womble"); diff --git a/perl/test/unlink.t b/perl/test/unlink.t deleted file mode 100644 index eef8c1a..0000000 --- a/perl/test/unlink.t +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 4; -chdir($_point); -system("touch file"); -ok(-f "file","file exists"); -chdir($_real); -ok(-f "file","file really exists"); -chdir($_point); -unlink("file"); -ok(! -f "file","file unlinked"); -chdir($_real); -ok(! -f "file","file really unlinked"); diff --git a/perl/test/utime.t b/perl/test/utime.t deleted file mode 100644 index 8ccefc6..0000000 --- a/perl/test/utime.t +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 3; -my (@stat); -chdir($_real); -system("echo frog >file"); -chdir($_point); -ok(utime(1,2,"file"),"set utime"); -@stat = stat("file"); -is($stat[8],1,"atime"); -is($stat[9],2,"mtime"); -unlink("file"); diff --git a/perl/test/write.t b/perl/test/write.t deleted file mode 100644 index 58af2aa..0000000 --- a/perl/test/write.t +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 15; -my ($data); -chdir($_point); -undef $/; # slurp it all -# create file -system("echo frogbing >writefile"); - -# fetch contents of file -ok(open(FILE,"writefile"),"open"); -$data = ; -close(FILE); -is(length($data),9,"right amount read"); -is($data,"frogbing\n","right data read"); - -# overwrite part -ok(open(FILE,'+<',"writefile"),"open"); -ok(seek(FILE,2,0),"seek"); -ok(print(FILE "ib"),"print"); -close(FILE); - -# fetch contents of file -ok(open(FILE,"writefile"),"open"); -$data = ; -close(FILE); -is(length($data),9,"right amount read"); -is($data,"fribbing\n","right data read"); - -# overwrite part, append some -ok(open(FILE,'+<',"writefile"),"open"); -ok(seek(FILE,7,0),"seek"); -ok(print(FILE "gle"),"print"); -close(FILE); - -# fetch contents of file -ok(open(FILE,"writefile"),"open"); -$data = ; -close(FILE); -is(length($data),10,"right amount read"); -is($data,"fribbingle","right data read"); - -# kill file -unlink("writefile"); diff --git a/python/AUTHORS b/python/AUTHORS deleted file mode 100644 index ed57e05..0000000 --- a/python/AUTHORS +++ /dev/null @@ -1,4 +0,0 @@ -Python bindings ---------------- - -Jeff Epler diff --git a/python/ChangeLog b/python/ChangeLog deleted file mode 100644 index f422b2a..0000000 --- a/python/ChangeLog +++ /dev/null @@ -1,6 +0,0 @@ -2004-09-27 Miklos Szeredi - - * Applied patch by Steven James. The Python binding in the CVS - version fell out of date and wouldn't compile. Fixed and added - FuseGetContext call. - diff --git a/python/INSTALL b/python/INSTALL deleted file mode 100644 index 917c1c0..0000000 --- a/python/INSTALL +++ /dev/null @@ -1,8 +0,0 @@ -The best way to install this python FUSE module is: - 1. make sure the rest of FUSE (incl libfuse.a) has built successfully - 2. type 'python setup.py build' - 3. if all has gone ok, become root and type 'python setup.py install' - -That way, the FUSE python modules will be built against the correct version -of python and installed in your system-wide python directory. This will allow -your filesystem script to find them, no matter where it's residing. diff --git a/python/Makefile b/python/Makefile deleted file mode 100644 index 1313e9e..0000000 --- a/python/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -#@+leo-ver=4 -#@+node:@file Makefile -# Makefile now uses distutils - -_fusemodule.so: _fusemodule.c - #gcc -g3 -I/usr/include/python2.1 _fusemodule.c -Wl,-shared -o _fusemodule.so -Wimplicit -lfuse && python -c 'import _fuse' - python setup.py build_ext --inplace - -install: _fusemodule.so - python setup.py install - -clean: - rm -rf _fusemodule.so *.pyc *.pyo *~ build -#@-node:@file Makefile -#@-leo diff --git a/python/README b/python/README deleted file mode 100644 index 2a3af2b..0000000 --- a/python/README +++ /dev/null @@ -1,92 +0,0 @@ -#@+leo-ver=4 -#@+node:@file README -#@@language - -Refer to the INSTALL file for build/install instructions - -General Information -=================== - -This is a Python[1] interface to FUSE[2]. - -FUSE (Filesystem in USErspace) is a simple interface for userspace -programs to export a virtual filesystem to the linux kernel. FUSE -also aims to provide a secure method for non privileged users to -create and mount their own filesystem implementations. - -When run from the commandline, "fuse.py" simply reexports the root -filesystem within the mount point as example/fusexmp does in the main -FUSE distribution. It also offers a class, fuse.Fuse, which can be -subclassed to create a filesystem. fuse.Xmp is the example filesystem -implementation. - -In your subclass of fuse, add attributes with the expected names -("getattr", "readlink", etc) and call signatures (refer to fuse.Xmp) -then call main(). Make it runnable as a #! script, and mount with - fusermount