This commit was manufactured by cvs2svn to create branch 'fuse_2_0_bugfix'.
authorcvs2git <>
Mon, 8 Nov 2004 21:11:54 +0000 (21:11 +0000)
committercvs2git <>
Mon, 8 Nov 2004 21:11:54 +0000 (21:11 +0000)
43 files changed:
1  2 
perl/.cvsignore
perl/Changes
perl/Fuse.pm
perl/Fuse.xs
perl/MANIFEST
perl/Makefile.PL
perl/README
perl/examples/example.pl
perl/examples/loopback.pl
perl/examples/rmount.pl
perl/examples/rmount_remote.pl
perl/test.pl
perl/test/chmod.t
perl/test/chown.t
perl/test/getattr.t
perl/test/getdir.t
perl/test/helper.pm
perl/test/link.t
perl/test/mkdir.t
perl/test/mknod.t
perl/test/open.t
perl/test/read.t
perl/test/readlink.t
perl/test/rename.t
perl/test/rmdir.t
perl/test/s/mount.t
perl/test/s/umount.t
perl/test/statfs.t
perl/test/symlink.t
perl/test/test-template
perl/test/truncate.t
perl/test/unlink.t
perl/test/utime.t
perl/test/write.t
python/ChangeLog
python/INSTALL
python/Makefile
python/README
python/_fusemodule.c
python/code.leo
python/fuse.py
python/setup.py
python/xmp.py

diff --cc perl/.cvsignore
index 5d5c2dc699c338d9e08873ae1e83d0c30ebf4974,5d5c2dc699c338d9e08873ae1e83d0c30ebf4974..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,1 -1,1 +1,0 @@@
--Fuse.bs Fuse.c Makefile blib pm_to_blib
diff --cc perl/Changes
index 56b4733244e13f75a6028c832053f58307e9cbf2,56b4733244e13f75a6028c832053f58307e9cbf2..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,12 -1,12 +1,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 --cc perl/Fuse.pm
index 6a01677a816dcde9f2be953a54618b59864083ef,6a01677a816dcde9f2be953a54618b59864083ef..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,360 -1,360 +1,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, E<lt>mark@glines.orgE<gt>
--
--=head1 SEE ALSO
--
--L<perl>, the FUSE documentation.
--
--=cut
diff --cc perl/Fuse.xs
index 233139a6221fd4f52a8d9ba263810bda1b2b8f93,233139a6221fd4f52a8d9ba263810bda1b2b8f93..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,572 -1,572 +1,0 @@@
--#include "EXTERN.h"
--#include "perl.h"
--#include "XSUB.h"
--
--#include <fuse.h>
--
--#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 --cc perl/MANIFEST
index 3012c026dd85a78aa7375ecd891db35c32378a4b,3012c026dd85a78aa7375ecd891db35c32378a4b..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,7 -1,7 +1,0 @@@
--Changes
--Fuse.pm
--Fuse.xs
--Makefile.PL
--MANIFEST
--README
--test.pl
diff --cc perl/Makefile.PL
index 6e66f46c5aa1c49d2638d26760e4a573eb6c6549,6e66f46c5aa1c49d2638d26760e4a573eb6c6549..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,17 -1,17 +1,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 <mark@glines.org>') : ()),
--    '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 --cc perl/README
index fb49cd700e22dae81f11fb37a1eae7596720232e,fb49cd700e22dae81f11fb37a1eae7596720232e..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,69 -1,69 +1,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 <mark@glines.org>,
--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 --cc perl/examples/example.pl
index 9ba1117554f23da578aec902cb370d2c09a23fb0,9ba1117554f23da578aec902cb370d2c09a23fb0..0000000000000000000000000000000000000000
deleted file mode 100755,100755
+++ /dev/null
@@@ -1,90 -1,90 +1,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 --cc perl/examples/loopback.pl
index bdc8c2218f1d7bb8c23f5c91bc68c575c3992c43,bdc8c2218f1d7bb8c23f5c91bc68c575c3992c43..0000000000000000000000000000000000000000
deleted file mode 100755,100755
+++ /dev/null
@@@ -1,136 -1,136 +1,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 --cc perl/examples/rmount.pl
index 9ae1cc1ad4e00cacc9de8da062e392189bf8b83a,9ae1cc1ad4e00cacc9de8da062e392189bf8b83a..0000000000000000000000000000000000000000
deleted file mode 100755,100755
+++ /dev/null
@@@ -1,82 -1,82 +1,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 --cc perl/examples/rmount_remote.pl
index e9e0866168522b8a048f9769bb27b041ad6418d2,e9e0866168522b8a048f9769bb27b041ad6418d2..0000000000000000000000000000000000000000
deleted file mode 100755,100755
+++ /dev/null
@@@ -1,143 -1,143 +1,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 --cc perl/test.pl
index e8152fd7d2cdc9438860c21849e2313fdb936eea,e8152fd7d2cdc9438860c21849e2313fdb936eea..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,8 -1,8 +1,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) = <test/*.t>;
--runtests("test/s/mount.t",sort(@files),"test/s/umount.t");
diff --cc perl/test/chmod.t
index 366f89bdf84eef81d1b47d99fa03eca1919a1c6d,366f89bdf84eef81d1b47d99fa03eca1919a1c6d..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,11 -1,11 +1,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 --cc perl/test/chown.t
index 8ccbb8832124539e94670c87ae86dbe5619ec21e,8ccbb8832124539e94670c87ae86dbe5619ec21e..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,14 -1,14 +1,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 --cc perl/test/getattr.t
index 420327510b84bfc798bfa19756bf5ca90532b451,420327510b84bfc798bfa19756bf5ca90532b451..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,42 -1,42 +1,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 --cc perl/test/getdir.t
index 1d605613e35d0cc81a983340e6123cdaca121850,1d605613e35d0cc81a983340e6123cdaca121850..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,33 -1,33 +1,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 --cc perl/test/helper.pm
index cd2bd55907f1d77cdd2825bc2589114b5738e648,cd2bd55907f1d77cdd2825bc2589114b5738e648..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,23 -1,23 +1,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 --cc perl/test/link.t
index 391b2f005ddeb3290f0adf4e5961b7dfd8f1f939,391b2f005ddeb3290f0adf4e5961b7dfd8f1f939..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,16 -1,16 +1,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 --cc perl/test/mkdir.t
index 90ec6f32449f40255691846bd60c8b239059e2d1,90ec6f32449f40255691846bd60c8b239059e2d1..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,11 -1,11 +1,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 --cc perl/test/mknod.t
index 35c5c8219a38fbb85c39e494a56e992d403b03d6,35c5c8219a38fbb85c39e494a56e992d403b03d6..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,37 -1,37 +1,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 --cc perl/test/open.t
index 030dc1f7cdbf893b0a25a0ab915526739368a22c,030dc1f7cdbf893b0a25a0ab915526739368a22c..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,10 -1,10 +1,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 --cc perl/test/read.t
index 5eca920578f30d30a0c604781478c2e62356a651,5eca920578f30d30a0c604781478c2e62356a651..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,13 -1,13 +1,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) = <FILE>;
--close(FILE);
--is(length($data),5,"right amount read");
--is($data,"frog\n","right data read");
--unlink("file");
diff --cc perl/test/readlink.t
index 85b9ffc77da2e0f59d2803aa1bcf716f6256fc80,85b9ffc77da2e0f59d2803aa1bcf716f6256fc80..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,11 -1,11 +1,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 --cc perl/test/rename.t
index 9fbb330338916326f24599df7a775d8d4cad0ccf,9fbb330338916326f24599df7a775d8d4cad0ccf..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,12 -1,12 +1,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 --cc perl/test/rmdir.t
index 36f03788258e582198b177edc5e98a20b9d8264a,36f03788258e582198b177edc5e98a20b9d8264a..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,13 -1,13 +1,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 --cc perl/test/s/mount.t
index 26f6fc2a3034802343228f35f216acf3194634de,26f6fc2a3034802343228f35f216acf3194634de..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,25 -1,25 +1,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 --cc perl/test/s/umount.t
index da60677a5009cea1e2b0996b4a5474fc3b10a748,da60677a5009cea1e2b0996b4a5474fc3b10a748..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,7 -1,7 +1,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 --cc perl/test/statfs.t
index fb94704298dc1807b9a17a891decff981b51cbc4,fb94704298dc1807b9a17a891decff981b51cbc4..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,21 -1,21 +1,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 --cc perl/test/symlink.t
index 19cc72d446ceec1a01451f5814be55d831feb3fa,19cc72d446ceec1a01451f5814be55d831feb3fa..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,19 -1,19 +1,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 --cc perl/test/test-template
index ef57e0842696c59c5c297424a24c147147e3b991,ef57e0842696c59c5c297424a24c147147e3b991..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,5 -1,5 +1,0 @@@
--#!/usr/bin/perl
--use test::helper qw($_real $_point);
--use Test::More;
--plan tests => 1;
--ok(1);
diff --cc perl/test/truncate.t
index 8607421182bfdb3a7a03e012b3b8728e3884f647,8607421182bfdb3a7a03e012b3b8728e3884f647..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,12 -1,12 +1,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 --cc perl/test/unlink.t
index eef8c1a9263aed12c2995a7e33a3020204929b9f,eef8c1a9263aed12c2995a7e33a3020204929b9f..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,14 -1,14 +1,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 --cc perl/test/utime.t
index 8ccefc671bbf0769bb612e6191aead5d5a2a7861,8ccefc671bbf0769bb612e6191aead5d5a2a7861..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,13 -1,13 +1,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 --cc perl/test/write.t
index 58af2aa04cdcaaab951925f5a4fdaae5c6c4f725,58af2aa04cdcaaab951925f5a4fdaae5c6c4f725..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,45 -1,45 +1,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 = <FILE>;
--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 = <FILE>;
--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 = <FILE>;
--close(FILE);
--is(length($data),10,"right amount read");
--is($data,"fribbingle","right data read");
--
--# kill file
--unlink("writefile");
diff --cc python/ChangeLog
index f422b2a508dabd686dd5519b16f4d8f982c3b027,f422b2a508dabd686dd5519b16f4d8f982c3b027..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,6 -1,6 +1,0 @@@
--2004-09-27  Miklos Szeredi <miklos@szeredi.hu>
--
--      * 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 --cc python/INSTALL
index 917c1c09783e02a32ea7201229945bb4f234c023,917c1c09783e02a32ea7201229945bb4f234c023..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,8 -1,8 +1,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 --cc python/Makefile
index 1313e9e4307e9a44c3e9901473ff5278208618a7,1313e9e4307e9a44c3e9901473ff5278208618a7..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,15 -1,15 +1,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 --cc python/README
index 2a3af2b57450b80d0643f5db58a1f76d70a82bbf,2a3af2b57450b80d0643f5db58a1f76d70a82bbf..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,92 -1,92 +1,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 <mount point> <script name>
--for some reason,
--      fusermount <mount point> python <script name>
--does not seem to work. (why?)
--
--Update
--======
--
--Updated 13-Dec-2003 by David McNab <david@rebirthing.co.nz>
--
--    - changed Makefile to use Pyton distutils
--    - added setup.py for distutils
--
--    - added 'code.leo' file for convenience of those who use the Leo
--      code editor (leo.sf.net)
--    
--    - added support for 'statfs' and 'fsync' methods (refer xmp.py)
--
--Updated Dec 2003 by David McNab <david@rebirthing.co.nz>:
--    
--    - added support for 'release' events (ie when file gets closed)
--    - added __init__ to base class, which picks off parameters and
--      stores them as instance attributes:
--          - self.mountpoint - the mountpoint as given in the mount command
--          - self.optlist - unnamed options (eg 'rw', 'exec' etc)
--          - self.optdict - named options (eg, '-o arg1=val1,arg2=val2...' from mount cmd)
--    - fixed incompatibility issues with recent pythons (original was broken
--      under python2.3)
--
--Limitations
--===========
--
--This is minimally tested, though I think I have exercised each function.
--There's no documentation, docstrings, or tests.
--
--Python's lstat() does not return some fields which must be filled in
--(st_blksize, st_blocks, st_ino), and _fusemodule assumes that the return
--value from the lstat() method is identical to Python's lstat().  This
--limitation should be lifted, and some standard order chosen for these
--three values.  For now, though, default values are chosen and du returns a
--number similar to the "real" one.
--
--The Python Global Interpreter Lock is not handled, so using
--fuse.MULTITHREAD will not work.  Modifying the PROLOGUE and EPILOGUE
--functions may take care of this.  For now, just run without
--fuse.MULTITHREAD in flags.
--
--Author
--======
--
--I'm Jeff Epler <jepler@unpythonic.dhs.org>.  I've been dabbling in
--Python for nearly 7 years now, and interested (despite the lack of a
--real practical use) in userspace filesystems ever since I couldn't get
--userfs to compile way back in '93 or so.  FUSE is cool, but i'm still
--not sure what it's good for in practical terms.
--
--I don't know how high a level of interest I'll maintain in this project,
--so if you want to do something with it feel free to do so.  Like FUSE,
--this software is distributed under the terms of the GNU General Public
--License, Version 2.  Future versions, if any, will be available at [3].
--
--
--[1] http://www.python.org
--[2] http://sourceforge.net/projects/avf/
--[3] http://unpythonic.dhs.org/~jepler/fuse/
--#@-node:@file README
--#@-leo
diff --cc python/_fusemodule.c
index fba65b47c031ee1d85fe087825a4532d1acbf20f,fba65b47c031ee1d85fe087825a4532d1acbf20f..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,552 -1,552 +1,0 @@@
--//@+leo-ver=4
--//@+node:@file _fusemodule.c
--//@@language c
--/*
--    Copyright (C) 2001  Jeff Epler  <jepler@unpythonic.dhs.org>
--
--    This program can be distributed under the terms of the GNU GPL.
--    See the file COPYING.
--
--    Updated for libfuse API changes
--    2004 Steven James <pyro@linuxlabs.com> and
--    Linux Labs International, Inc. http://www.linuxlabs.com
--
--    
--*/
--
--//@+others
--//@+node:includes
--#include <Python.h>
--#include "fuse.h"
--#include <time.h>
--//@-node:includes
--//@+node:globals
--
--static PyObject *getattr_cb=NULL, *readlink_cb=NULL, *getdir_cb=NULL,
--  *mknod_cb=NULL, *mkdir_cb=NULL, *unlink_cb=NULL, *rmdir_cb=NULL,
--  *symlink_cb=NULL, *rename_cb=NULL, *link_cb=NULL, *chmod_cb=NULL,
--  *chown_cb=NULL, *truncate_cb=NULL, *utime_cb=NULL,
--  *open_cb=NULL, *read_cb=NULL, *write_cb=NULL, *release_cb=NULL,
--  *statfs_cb=NULL, *fsync_cb=NULL
--  ;
--
--static int debuglevel=0;
--
--//@-node:globals
--//@+node:PROLOGUE
--#define PROLOGUE \
--int ret = -EINVAL; \
--if (!v) { PyErr_Print(); goto OUT; } \
--if(v == Py_None) { ret = 0; goto OUT_DECREF; } \
--if(PyInt_Check(v)) { ret = PyInt_AsLong(v); goto OUT_DECREF; }
--
--//@-node:PROLOGUE
--//@+node:EPILOGUE
--#define EPILOGUE \
--OUT_DECREF: \
--      Py_DECREF(v); \
--OUT: \
--      return ret; 
--//@-node:EPILOGUE
--//@+node:getattr_func
--
--/* 
-- * Local Variables:
-- * indent-tabs-mode: t
-- * c-basic-offset: 8
-- * End:
-- * Changed by David McNab (david@rebirthing.co.nz) to work with recent pythons.
-- * Namely, replacing PyTuple_* with PySequence_*, and checking numerical values
-- * with both PyInt_Check and PyLong_Check.
-- */
--
--static int getattr_func(const char *path, struct stat *st)
--{
--int i;
--PyObject *v = PyObject_CallFunction(getattr_cb, "s", path);
--PROLOGUE
--
--if(!PySequence_Check(v)) { goto OUT_DECREF; }
--if(PySequence_Size(v) < 10) { goto OUT_DECREF; }
--for(i=0; i<10; i++)
--{
--    PyObject *tmp = PySequence_GetItem(v, i);
--      if (!(PyInt_Check(tmp) || PyLong_Check(tmp))) goto OUT_DECREF;
--}
--
--st->st_mode = PyInt_AsLong(PySequence_GetItem(v, 0));
--st->st_ino  = PyInt_AsLong(PySequence_GetItem(v, 1));
--st->st_dev  = PyInt_AsLong(PySequence_GetItem(v, 2));
--st->st_nlink= PyInt_AsLong(PySequence_GetItem(v, 3));
--st->st_uid  = PyInt_AsLong(PySequence_GetItem(v, 4));
--st->st_gid  = PyInt_AsLong(PySequence_GetItem(v, 5));
--st->st_size = PyInt_AsLong(PySequence_GetItem(v, 6));
--st->st_atime= PyInt_AsLong(PySequence_GetItem(v, 7));
--st->st_mtime= PyInt_AsLong(PySequence_GetItem(v, 8));
--st->st_ctime= PyInt_AsLong(PySequence_GetItem(v, 9));
--
--/* Fill in fields not provided by Python lstat() */
--st->st_blksize= 4096;
--st->st_blocks= (st->st_size + 511)/512;
--st->st_ino  = 0;
--
--ret = 0;
--EPILOGUE
--}
--
--//@-node:getattr_func
--//@+node:readlink_func
--
--static int readlink_func(const char *path, char *link, size_t size)
--{
--      PyObject *v = PyObject_CallFunction(readlink_cb, "s", path);
--      char *s;
--      PROLOGUE
--
--      if(!PyString_Check(v)) { ret = -EINVAL; goto OUT_DECREF; }
--      s = PyString_AsString(v);
--      strncpy(link, s, size);
--      link[size-1] = '\0';
--      ret = 0;
--
--      EPILOGUE
--}
--//@-node:readlink_func
--//@+node:getdir_add_entry
--
--static int getdir_add_entry(PyObject *w, fuse_dirh_t dh, fuse_dirfil_t df)
--{
--      PyObject *o0;
--      PyObject *o1;
--      int ret = -EINVAL;
--
--      if(!PySequence_Check(w)) {
--              printf("getdir item not sequence\n");
--              goto out;
--      }
--      if(PySequence_Length(w) != 2) {
--              printf("getdir item not len 2\n");
--              goto out;
--      }
--      o0 = PySequence_GetItem(w, 0);
--      o1 = PySequence_GetItem(w, 1);
--
--      if(!PyString_Check(o0)) {
--              printf("getdir item[0] not string\n");
--              goto out_decref;
--      }
--      if(!PyInt_Check(o1)) {
--              printf("getdir item[1] not int\n");
--              goto out_decref;
--      }
--
--      ret = df(dh, PyString_AsString(o0), PyInt_AsLong(o1));  
--
--out_decref:
--      Py_DECREF(o0);
--      Py_DECREF(o1);
--
--out:
--      return ret;
--}
--//@-node:getdir_add_entry
--//@+node:getdir_func
--
--static int getdir_func(const char *path, fuse_dirh_t dh, fuse_dirfil_t df)
--{
--      PyObject *v = PyObject_CallFunction(getdir_cb, "s", path);
--      int i;
--      PROLOGUE
--
--      if(!PySequence_Check(v)) {
--              printf("getdir_func not sequence\n");
--              goto OUT_DECREF;
--      }
--      for(i=0; i < PySequence_Length(v); i++) {
--              PyObject *w = PySequence_GetItem(v, i);
--              ret = getdir_add_entry(w, dh, df);
--              Py_DECREF(w);
--              if(ret != 0)
--                      goto OUT_DECREF;
--      }
--      ret = 0;
--
--      EPILOGUE
--}
--//@-node:getdir_func
--//@+node:mknod_func
--
--static int mknod_func(const char *path, mode_t m, dev_t d)
--{
--      PyObject *v = PyObject_CallFunction(mknod_cb, "sii", path, m, d);
--      PROLOGUE
--      EPILOGUE
--}
--//@-node:mknod_func
--//@+node:mkdir_func
--
--static int mkdir_func(const char *path, mode_t m)
--{
--      PyObject *v = PyObject_CallFunction(mkdir_cb, "si", path, m);
--      PROLOGUE
--      EPILOGUE
--}
--//@-node:mkdir_func
--//@+node:unlink_func
--
--static int unlink_func(const char *path)
--{
--      PyObject *v = PyObject_CallFunction(unlink_cb, "s", path);
--      PROLOGUE
--      EPILOGUE
--}
--//@-node:unlink_func
--//@+node:rmdir_func
--
--static int rmdir_func(const char *path)
--{
--      PyObject *v = PyObject_CallFunction(rmdir_cb, "s", path);
--      PROLOGUE
--      EPILOGUE
--}
--//@-node:rmdir_func
--//@+node:symlink_func
--
--static int symlink_func(const char *path, const char *path1)
--{
--      PyObject *v = PyObject_CallFunction(symlink_cb, "ss", path, path1);
--      PROLOGUE
--      EPILOGUE
--}
--//@-node:symlink_func
--//@+node:rename_func
--
--static int rename_func(const char *path, const char *path1)
--{
--      PyObject *v = PyObject_CallFunction(rename_cb, "ss", path, path1);
--      PROLOGUE
--      EPILOGUE
--}
--//@-node:rename_func
--//@+node:link_func
--
--static int link_func(const char *path, const char *path1)
--{
--      PyObject *v = PyObject_CallFunction(link_cb, "ss", path, path1);
--      PROLOGUE
--      EPILOGUE
--}
--//@-node:link_func
--//@+node:chmod_func
--
--static int chmod_func(const char *path, mode_t m) 
--{
--      PyObject *v = PyObject_CallFunction(chmod_cb, "si", path, m);
--      PROLOGUE
--      EPILOGUE
--}
--//@-node:chmod_func
--//@+node:chown_func
--
--static int chown_func(const char *path, uid_t u, gid_t g) 
--{
--      PyObject *v = PyObject_CallFunction(chown_cb, "sii", path, u, g);
--      PROLOGUE
--      EPILOGUE
--}
--//@-node:chown_func
--//@+node:truncate_func
--
--static int truncate_func(const char *path, off_t o)
--{
--      PyObject *v = PyObject_CallFunction(truncate_cb, "si", path, o);
--      PROLOGUE
--      EPILOGUE
--}
--//@-node:truncate_func
--//@+node:utime_func
--
--static int utime_func(const char *path, struct utimbuf *u) {
--      int actime = u ? u->actime : time(NULL);
--      int modtime = u ? u->modtime : actime;
--      PyObject *v = PyObject_CallFunction(utime_cb, "s(ii)",
--                                      path, actime, modtime);
--      PROLOGUE
--      EPILOGUE
--}
--//@-node:utime_func
--//@+node:read_func
--
--static int read_func(const char *path, char *buf, size_t s, off_t off)
--{
--      PyObject *v = PyObject_CallFunction(read_cb, "sii", path, s, off);
--      PROLOGUE
--      if(PyString_Check(v)) {
--              if(PyString_Size(v) > s) goto OUT_DECREF;
--              memcpy(buf, PyString_AsString(v), PyString_Size(v));
--              ret = PyString_Size(v);
--      }
--      EPILOGUE
--}
--//@-node:read_func
--//@+node:write_func
--
--static int write_func(const char *path, const char *buf, size_t t, off_t off)
--{
--      PyObject *v = PyObject_CallFunction(write_cb,"ss#i", path, buf, t, off);
--      PROLOGUE
--      EPILOGUE
--}
--//@-node:write_func
--//@+node:open_func
--
--static int open_func(const char *path, int mode)
--{
--      PyObject *v = PyObject_CallFunction(open_cb, "si", path, mode);
--      PROLOGUE
--    printf("open_func: path=%s\n", path);
--      EPILOGUE
--}
--//@-node:open_func
--//@+node:release_func
--static int release_func(const char *path, int flags)
--{
--  PyObject *v = PyObject_CallFunction(release_cb, "si", path, flags);
--  PROLOGUE
--    //printf("release_func: path=%s flags=%d\n", path, flags);
--  EPILOGUE
--}
--//@-node:release_func
--//@+node:statfs_func
--static int statfs_func( const char *dummy, struct statfs *fst)
--{
--  int i;
--  long retvalues[6];
--  PyObject *v = PyObject_CallFunction(statfs_cb, "");
--PROLOGUE
--
--  if (!PySequence_Check(v))
--    { goto OUT_DECREF; }
-- if (PySequence_Size(v) < 6)
--   { goto OUT_DECREF; }
-- for(i=0; i<6; i++)
--   {
--     PyObject *tmp = PySequence_GetItem(v, i);
--     retvalues[i] = PyInt_Check(tmp)
--       ? PyInt_AsLong(tmp)
--       : (PyLong_Check(tmp)
--          ? PyLong_AsLong(tmp)
--          : 0);
--   }
--
-- fst->f_bsize = retvalues[0];
-- fst->f_blocks        = retvalues[1];
-- fst->f_bfree = retvalues[2];
-- fst->f_files = retvalues[3];
-- fst->f_ffree = retvalues[4];
-- fst->f_namelen       = retvalues[5];
--
-- ret = 0;
-- 
--#ifdef IGNORE_THIS
-- printf("block_size=%ld, blocks=%ld, blocks_free=%ld, files=%ld, files_free=%ld, namelen=%ld\n",
--        retvalues[0], retvalues[1], retvalues[2], retvalues[3], retvalues[4], retvalues[5]);
--#endif
--
--EPILOGUE
--
--}
--
--//@-node:statfs_func
--//@+node:fsync_func
--static int fsync_func(const char *path, int isfsyncfile)
--{
--      PyObject *v = PyObject_CallFunction(fsync_cb, "si", path, isfsyncfile);
--      PROLOGUE
--      EPILOGUE
--}
--
--//@-node:fsync_func
--//@+node:process_cmd
--
--static void process_cmd(struct fuse *f, struct fuse_cmd *cmd, void *data)
--{
--      PyInterpreterState *interp = (PyInterpreterState *) data;
--      PyThreadState *state;
--
--      PyEval_AcquireLock();
--      state = PyThreadState_New(interp);
--      PyThreadState_Swap(state);
--      __fuse_process_cmd(f, cmd);
--      PyThreadState_Clear(state);
--      PyThreadState_Swap(NULL);
--      PyThreadState_Delete(state);
--      PyEval_ReleaseLock();
--}
--//@-node:process_cmd
--//@+node:pyfuse_loop_mt
--
--static void pyfuse_loop_mt(struct fuse *f)
--{
--      PyInterpreterState *interp;
--      PyThreadState *save;
--
--      PyEval_InitThreads();
--      interp = PyThreadState_Get()->interp;
--      save = PyEval_SaveThread();
--      __fuse_loop_mt(f, process_cmd, interp);
--      /* Not yet reached: */
--      PyEval_RestoreThread(save);
--}
--//@-node:pyfuse_loop_mt
--//@+node:Fuse_main
--
--static struct fuse *fuse=NULL;
--
--static PyObject *
--Fuse_main(PyObject *self, PyObject *args, PyObject *kw)
--{
--      int fd;
--      int multithreaded=0;
--      char *lopts=NULL;
--      char *kopts=NULL;
--      char *mountpoint;
--
--      struct fuse_operations op;
--
--      static char  *kwlist[] = {
--              "getattr", "readlink", "getdir", "mknod",
--              "mkdir", "unlink", "rmdir", "symlink", "rename",
--              "link", "chmod", "chown", "truncate", "utime",
--              "open", "read", "write", "release", "statfs", "fsync",
--              "mountpoint", "kopts", "lopts", "multithreaded", 
--              "debug", NULL};
--      
--      memset(&op, 0, sizeof(op));
--
--      if (!PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOOOOOOOOOOOOOOOsssii", 
--                                      kwlist, &getattr_cb, &readlink_cb, &getdir_cb, &mknod_cb,
--                                      &mkdir_cb, &unlink_cb, &rmdir_cb, &symlink_cb, &rename_cb,
--                                      &link_cb, &chmod_cb, &chown_cb, &truncate_cb, &utime_cb,
--                                      &open_cb, &read_cb, &write_cb, &release_cb, &statfs_cb, &fsync_cb,
--                                      &mountpoint, &kopts, &lopts, &multithreaded, &debuglevel))
--              return NULL;
--      
--#define DO_ONE_ATTR(name) if(name ## _cb) { Py_INCREF(name ## _cb); op.name = name ## _func; } else { op.name = NULL; }
--
--      DO_ONE_ATTR(getattr);
--      DO_ONE_ATTR(readlink);
--      DO_ONE_ATTR(getdir);
--      DO_ONE_ATTR(mknod);
--      DO_ONE_ATTR(mkdir);
--      DO_ONE_ATTR(unlink);
--      DO_ONE_ATTR(rmdir);
--      DO_ONE_ATTR(symlink);
--      DO_ONE_ATTR(rename);
--      DO_ONE_ATTR(link);
--      DO_ONE_ATTR(chmod);
--      DO_ONE_ATTR(chown);
--      DO_ONE_ATTR(truncate);
--      DO_ONE_ATTR(utime);
--      DO_ONE_ATTR(open);
--      DO_ONE_ATTR(read);
--      DO_ONE_ATTR(write);
--      DO_ONE_ATTR(release);
--      DO_ONE_ATTR(statfs);
--      DO_ONE_ATTR(fsync);
--
--      fd = fuse_mount(mountpoint, kopts);
--      fuse = fuse_new(fd, lopts, &op);
--      if(multithreaded)
--              pyfuse_loop_mt(fuse);
--      else
--              fuse_loop(fuse);
--
--    //printf("Fuse_main: called\n");
--
--      Py_INCREF(Py_None);
--      return Py_None;
--}
--//@-node:Fuse_main
--//@+node:DL_EXPORT
--//@+at 
--//@nonl
--// List of functions defined in the module
--//@-at
--//@@c
--static char FuseInvalidate__doc__[] =
--      "Tell Fuse kernel module to explicitly invalidate a cached inode's contents\n";
--
--static PyObject *FuseInvalidate( PyObject *self, PyObject *args) {
--      char *path;
--      PyObject *ret;
--      int err;
--
--      PyString_Check(args);
--
--      path = PyString_AsString(args);
--
--      err = fuse_invalidate(fuse, path);
--
--      ret = PyInt_FromLong(err);
--
--      return(ret);
--}
--
--static char FuseGetContext__doc__[] =
--      "Return the context of a filesystem operation in a dict. uid, gid, pid\n";
--
--static PyObject *FuseGetContext( PyObject *self, PyObject *args) {
--      struct fuse_context *fc;
--      PyObject *ret;
--      PyObject *num;
--
--      fc = fuse_get_context();
--      ret = PyDict_New();
--
--      if(!ret)
--              return(NULL);
--
--      num = PyInt_FromLong( fc->uid);
--      PyDict_SetItemString( ret, "uid", num); 
--
--      num = PyInt_FromLong( fc->gid);
--      PyDict_SetItemString( ret, "gid", num); 
--
--      num = PyInt_FromLong( fc->pid);
--      PyDict_SetItemString( ret, "pid", num); 
--
--      return(ret);
--
--}
--
--static PyMethodDef Fuse_methods[] = {
--      {"main",        (PyCFunction)Fuse_main,  METH_VARARGS|METH_KEYWORDS},
--      {"FuseGetContext", (PyCFunction)FuseGetContext, METH_VARARGS, FuseGetContext__doc__},
--      {"FuseInvalidate", (PyCFunction)FuseInvalidate, METH_VARARGS, FuseInvalidate__doc__},
--      {NULL,          NULL}           /* sentinel */
--};
--
--
--/* Initialization function for the module (*must* be called init_fuse) */
--
--DL_EXPORT(void)
--init_fuse(void)
--{
--      PyObject *m, *d;
--      static PyObject *ErrorObject;
-- 
--      /* Create the module and add the functions */
--      m = Py_InitModule("_fuse", Fuse_methods);
--
--      /* Add some symbolic constants to the module */
--      d = PyModule_GetDict(m);
--      ErrorObject = PyErr_NewException("fuse.error", NULL, NULL);
--      PyDict_SetItemString(d, "error", ErrorObject);
--//    PyDict_SetItemString(d, "DEBUG", PyInt_FromLong(FUSE_DEBUG));
--}
--//@-node:DL_EXPORT
--//@-others
--
--//@-node:@file _fusemodule.c
--//@-leo
diff --cc python/code.leo
index 8ff723efe1103d668c9d1eec30e2b22d24d92d41,8ff723efe1103d668c9d1eec30e2b22d24d92d41..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,1120 -1,1120 +1,0 @@@
--<?xml version="1.0" encoding="UTF-8"?>
--<leo_file>
--<leo_header file_format="2" tnodes="0" max_tnode_index="69" clone_windows="0"/>
--<globals body_outline_ratio="0.2448559670781893">
--      <global_window_position top="129" left="90" height="631" width="1124"/>
--      <global_log_window_position top="0" left="0" height="0" width="0"/>
--</globals>
--<preferences>
--</preferences>
--<find_panel_settings>
--      <find_string></find_string>
--      <change_string></change_string>
--</find_panel_settings>
--<vnodes>
--<v t="davidmcnab.121303142957" a="E"><vh>fuse python bindings</vh>
--<v t="davidmcnab.121303142957.1" a="E" tnodeList="davidmcnab.121303142957.1,davidmcnab.121303142957.2,davidmcnab.121303142957.3,davidmcnab.121303142957.4,davidmcnab.121303142957.5,davidmcnab.121303142957.6,davidmcnab.121303142957.7,davidmcnab.121303142957.8,davidmcnab.121303142957.9,davidmcnab.121303142957.10,davidmcnab.121303142957.11,davidmcnab.121303142957.12,davidmcnab.121303142957.13,davidmcnab.121303142957.14,davidmcnab.121303142957.15,davidmcnab.121303142957.16,davidmcnab.121303142957.17,davidmcnab.121303142957.18,davidmcnab.121303142957.19,davidmcnab.121303142957.20,davidmcnab.121303142957.21,davidmcnab.121303142957.22,davidmcnab.121303142957.23,davidmcnab.121303142957.24,davidmcnab.121303144441,davidmcnab.121303144441.1,davidmcnab.121303142957.25,davidmcnab.121303142957.26,davidmcnab.121303142957.27,davidmcnab.121303142957.28"><vh>@file _fusemodule.c</vh>
--<v t="davidmcnab.121303142957.2"><vh>includes</vh></v>
--<v t="davidmcnab.121303142957.3" a="M"><vh>globals</vh></v>
--<v t="davidmcnab.121303142957.4"><vh>PROLOGUE</vh></v>
--<v t="davidmcnab.121303142957.5"><vh>EPILOGUE</vh></v>
--<v t="davidmcnab.121303142957.6"><vh>getattr_func</vh></v>
--<v t="davidmcnab.121303142957.7"><vh>readlink_func</vh></v>
--<v t="davidmcnab.121303142957.8"><vh>getdir_add_entry</vh></v>
--<v t="davidmcnab.121303142957.9"><vh>getdir_func</vh></v>
--<v t="davidmcnab.121303142957.10"><vh>mknod_func</vh></v>
--<v t="davidmcnab.121303142957.11"><vh>mkdir_func</vh></v>
--<v t="davidmcnab.121303142957.12"><vh>unlink_func</vh></v>
--<v t="davidmcnab.121303142957.13"><vh>rmdir_func</vh></v>
--<v t="davidmcnab.121303142957.14"><vh>symlink_func</vh></v>
--<v t="davidmcnab.121303142957.15"><vh>rename_func</vh></v>
--<v t="davidmcnab.121303142957.16"><vh>link_func</vh></v>
--<v t="davidmcnab.121303142957.17"><vh>chmod_func</vh></v>
--<v t="davidmcnab.121303142957.18"><vh>chown_func</vh></v>
--<v t="davidmcnab.121303142957.19"><vh>truncate_func</vh></v>
--<v t="davidmcnab.121303142957.20"><vh>utime_func</vh></v>
--<v t="davidmcnab.121303142957.21"><vh>read_func</vh></v>
--<v t="davidmcnab.121303142957.22"><vh>write_func</vh></v>
--<v t="davidmcnab.121303142957.23"><vh>open_func</vh></v>
--<v t="davidmcnab.121303142957.24" a="M"><vh>release_func</vh></v>
--<v t="davidmcnab.121303144441"><vh>statfs_func</vh></v>
--<v t="davidmcnab.121303144441.1"><vh>fsync_func</vh></v>
--<v t="davidmcnab.121303142957.25" a="M"><vh>process_cmd</vh></v>
--<v t="davidmcnab.121303142957.26"><vh>pyfuse_loop_mt</vh></v>
--<v t="davidmcnab.121303142957.27" a="M"><vh>Fuse_main</vh></v>
--<v t="davidmcnab.121303142957.28"><vh>DL_EXPORT</vh></v>
--</v>
--<v t="davidmcnab.121303142957.29" tnodeList="davidmcnab.121303142957.29,davidmcnab.121303142957.30,davidmcnab.121303142957.31,davidmcnab.121303142957.32,davidmcnab.121303142957.33,davidmcnab.121303142957.34,davidmcnab.121303142957.35,davidmcnab.121303142957.36,davidmcnab.121303142957.37"><vh>@file fuse.py</vh>
--<v t="davidmcnab.121303142957.30"><vh>imports</vh></v>
--<v t="davidmcnab.121303142957.31" a="E"><vh>class ErrnoWrapper</vh>
--<v t="davidmcnab.121303142957.32"><vh>__init__</vh></v>
--<v t="davidmcnab.121303142957.33"><vh>__call__</vh></v>
--</v>
--<v t="davidmcnab.121303142957.34" a="E"><vh>class Fuse</vh>
--<v t="davidmcnab.121303142957.35" a="M"><vh>attribs</vh></v>
--<v t="davidmcnab.121303142957.36"><vh>__init__</vh></v>
--<v t="davidmcnab.121303142957.37"><vh>main</vh></v>
--</v>
--</v>
--<v t="davidmcnab.121303142957.38" tnodeList="davidmcnab.121303142957.38"><vh>@file Makefile</vh></v>
--<v t="davidmcnab.121303142957.39" a="E" tnodeList="davidmcnab.121303142957.39,davidmcnab.121303142957.40,davidmcnab.121303142957.41,davidmcnab.121303142957.42,davidmcnab.121303142957.43,davidmcnab.121303142957.44,davidmcnab.121303142957.45,davidmcnab.121303142957.46,davidmcnab.121303142957.47,davidmcnab.121303142957.48,davidmcnab.121303142957.49,davidmcnab.121303142957.50,davidmcnab.121303142957.51,davidmcnab.121303142957.52,davidmcnab.121303142957.53,davidmcnab.121303142957.54,davidmcnab.121303142957.55,davidmcnab.121303142957.56,davidmcnab.121303142957.57,davidmcnab.121303142957.58,davidmcnab.121303142957.59,davidmcnab.121303142957.60,davidmcnab.121303142957.61,davidmcnab.121303142957.62,davidmcnab.121303144134,davidmcnab.121303144134.1,davidmcnab.121303142957.63"><vh>@file xmp.py</vh>
--<v t="davidmcnab.121303142957.40"><vh>imports</vh></v>
--<v t="davidmcnab.121303142957.41" a="E"><vh>class Xmp</vh>
--<v t="davidmcnab.121303142957.42"><vh>__init__</vh></v>
--<v t="davidmcnab.121303142957.43"><vh>mythread</vh></v>
--<v t="davidmcnab.121303142957.44"><vh>attribs</vh></v>
--<v t="davidmcnab.121303142957.45"><vh>getattr</vh></v>
--<v t="davidmcnab.121303142957.46"><vh>readlink</vh></v>
--<v t="davidmcnab.121303142957.47"><vh>getdir</vh></v>
--<v t="davidmcnab.121303142957.48"><vh>unlink</vh></v>
--<v t="davidmcnab.121303142957.49"><vh>rmdir</vh></v>
--<v t="davidmcnab.121303142957.50"><vh>symlink</vh></v>
--<v t="davidmcnab.121303142957.51"><vh>rename</vh></v>
--<v t="davidmcnab.121303142957.52"><vh>link</vh></v>
--<v t="davidmcnab.121303142957.53"><vh>chmod</vh></v>
--<v t="davidmcnab.121303142957.54"><vh>chown</vh></v>
--<v t="davidmcnab.121303142957.55"><vh>truncate</vh></v>
--<v t="davidmcnab.121303142957.56"><vh>mknod</vh></v>
--<v t="davidmcnab.121303142957.57"><vh>mkdir</vh></v>
--<v t="davidmcnab.121303142957.58"><vh>utime</vh></v>
--<v t="davidmcnab.121303142957.59"><vh>open</vh></v>
--<v t="davidmcnab.121303142957.60"><vh>read</vh></v>
--<v t="davidmcnab.121303142957.61"><vh>write</vh></v>
--<v t="davidmcnab.121303142957.62" a="M"><vh>release</vh></v>
--<v t="davidmcnab.121303144134"><vh>statfs</vh></v>
--<v t="davidmcnab.121303144134.1"><vh>fsync</vh></v>
--</v>
--<v t="davidmcnab.121303142957.63"><vh>mainline</vh></v>
--</v>
--<v t="davidmcnab.121303142957.64" tnodeList="davidmcnab.121303142957.64"><vh>@file setup.py</vh></v>
--<v t="davidmcnab.121303142957.65" tnodeList="davidmcnab.121303142957.65"><vh>@file README</vh></v>
--<v t="davidmcnab.121303142957.67" a="E" tnodeList="davidmcnab.121303142957.67"><vh>@file mount.fuse</vh></v>
--<v t="davidmcnab.121403050157" a="E"><vh>@file fuse.py</vh>
--<v t="davidmcnab.121403050157.1"><vh>&lt;&lt; fuse declarations &gt;&gt;</vh></v>
--<v t="davidmcnab.121403050157.2" a="E"><vh>class ErrnoWrapper</vh>
--<v t="davidmcnab.121403050157.3"><vh>&lt;&lt; class ErrnoWrapper declarations &gt;&gt;</vh></v>
--<v t="davidmcnab.121403050157.4"><vh>__init__</vh></v>
--<v t="davidmcnab.121403050157.5" a="V"><vh>__call__</vh></v>
--</v>
--<v t="davidmcnab.121403050157.6" a="E"><vh>class Fuse</vh>
--<v t="davidmcnab.121403050157.7"><vh>&lt;&lt; class Fuse declarations &gt;&gt;</vh></v>
--<v t="davidmcnab.121403050157.8"><vh>__init__</vh></v>
--<v t="davidmcnab.121403050157.9"><vh>main</vh></v>
--</v>
--</v>
--</v>
--</vnodes>
--<tnodes>
--<t tx="davidmcnab.121303142957"></t>
--<t tx="davidmcnab.121303142957.1">@language c
--/*
--    Copyright (C) 2001  Jeff Epler  &lt;jepler@unpythonic.dhs.org&gt;
--
--    This program can be distributed under the terms of the GNU GPL.
--    See the file COPYING.
--*/
--
--@others
--
--</t>
--<t tx="davidmcnab.121303142957.2">#include &lt;Python.h&gt;
--#include &lt;fuse.h&gt;
--#include &lt;time.h&gt;
--</t>
--<t tx="davidmcnab.121303142957.3">
--static PyObject *getattr_cb=NULL, *readlink_cb=NULL, *getdir_cb=NULL,
--  *mknod_cb=NULL, *mkdir_cb=NULL, *unlink_cb=NULL, *rmdir_cb=NULL,
--  *symlink_cb=NULL, *rename_cb=NULL, *link_cb=NULL, *chmod_cb=NULL,
--  *chown_cb=NULL, *truncate_cb=NULL, *utime_cb=NULL,
--  *open_cb=NULL, *read_cb=NULL, *write_cb=NULL, *release_cb=NULL,
--  *statfs_cb=NULL, *fsync_cb=NULL
--  ;
--</t>
--<t tx="davidmcnab.121303142957.4">#define PROLOGUE \
--int ret = -EINVAL; \
--if (!v) { PyErr_Print(); goto OUT; } \
--if(v == Py_None) { ret = 0; goto OUT_DECREF; } \
--if(PyInt_Check(v)) { ret = PyInt_AsLong(v); goto OUT_DECREF; }
--
--</t>
--<t tx="davidmcnab.121303142957.5">#define EPILOGUE \
--OUT_DECREF: \
--      Py_DECREF(v); \
--OUT: \
--      return ret; 
--</t>
--<t tx="davidmcnab.121303142957.6">
--/* 
-- * Local Variables:
-- * indent-tabs-mode: t
-- * c-basic-offset: 8
-- * End:
-- * Changed by David McNab (david@rebirthing.co.nz) to work with recent pythons.
-- * Namely, replacing PyTuple_* with PySequence_*, and checking numerical values
-- * with both PyInt_Check and PyLong_Check.
-- */
--
--static int getattr_func(const char *path, struct stat *st)
--{
--int i;
--PyObject *v = PyObject_CallFunction(getattr_cb, "s", path);
--PROLOGUE
--
--if(!PySequence_Check(v)) { goto OUT_DECREF; }
--if(PySequence_Size(v) &lt; 10) { goto OUT_DECREF; }
--for(i=0; i&lt;10; i++)
--{
--    PyObject *tmp = PySequence_GetItem(v, i);
--      if (!(PyInt_Check(tmp) || PyLong_Check(tmp))) goto OUT_DECREF;
--}
--
--st-&gt;st_mode = PyInt_AsLong(PySequence_GetItem(v, 0));
--st-&gt;st_ino  = PyInt_AsLong(PySequence_GetItem(v, 1));
--st-&gt;st_dev  = PyInt_AsLong(PySequence_GetItem(v, 2));
--st-&gt;st_nlink= PyInt_AsLong(PySequence_GetItem(v, 3));
--st-&gt;st_uid  = PyInt_AsLong(PySequence_GetItem(v, 4));
--st-&gt;st_gid  = PyInt_AsLong(PySequence_GetItem(v, 5));
--st-&gt;st_size = PyInt_AsLong(PySequence_GetItem(v, 6));
--st-&gt;st_atime= PyInt_AsLong(PySequence_GetItem(v, 7));
--st-&gt;st_mtime= PyInt_AsLong(PySequence_GetItem(v, 8));
--st-&gt;st_ctime= PyInt_AsLong(PySequence_GetItem(v, 9));
--
--/* Fill in fields not provided by Python lstat() */
--st-&gt;st_blksize= 4096;
--st-&gt;st_blocks= (st-&gt;st_size + 511)/512;
--st-&gt;st_ino  = 0;
--
--ret = 0;
--EPILOGUE
--}
--
--</t>
--<t tx="davidmcnab.121303142957.7">
--static int readlink_func(const char *path, char *link, size_t size)
--{
--      PyObject *v = PyObject_CallFunction(readlink_cb, "s", path);
--      char *s;
--      PROLOGUE
--
--      if(!PyString_Check(v)) { ret = -EINVAL; goto OUT_DECREF; }
--      s = PyString_AsString(v);
--      strncpy(link, s, size);
--      link[size-1] = '\0';
--      ret = 0;
--
--      EPILOGUE
--}
--</t>
--<t tx="davidmcnab.121303142957.8">
--static int getdir_add_entry(PyObject *w, fuse_dirh_t dh, fuse_dirfil_t df)
--{
--      PyObject *o0;
--      PyObject *o1;
--      int ret = -EINVAL;
--
--      if(!PySequence_Check(w)) {
--              printf("getdir item not sequence\n");
--              goto out;
--      }
--      if(PySequence_Length(w) != 2) {
--              printf("getdir item not len 2\n");
--              goto out;
--      }
--      o0 = PySequence_GetItem(w, 0);
--      o1 = PySequence_GetItem(w, 1);
--
--      if(!PyString_Check(o0)) {
--              printf("getdir item[0] not string\n");
--              goto out_decref;
--      }
--      if(!PyInt_Check(o1)) {
--              printf("getdir item[1] not int\n");
--              goto out_decref;
--      }
--
--      ret = df(dh, PyString_AsString(o0), PyInt_AsLong(o1));  
--
--out_decref:
--      Py_DECREF(o0);
--      Py_DECREF(o1);
--
--out:
--      return ret;
--}
--</t>
--<t tx="davidmcnab.121303142957.9">
--static int getdir_func(const char *path, fuse_dirh_t dh, fuse_dirfil_t df)
--{
--      PyObject *v = PyObject_CallFunction(getdir_cb, "s", path);
--      int i;
--      PROLOGUE
--
--      if(!PySequence_Check(v)) {
--              printf("getdir_func not sequence\n");
--              goto OUT_DECREF;
--      }
--      for(i=0; i &lt; PySequence_Length(v); i++) {
--              PyObject *w = PySequence_GetItem(v, i);
--              ret = getdir_add_entry(w, dh, df);
--              Py_DECREF(w);
--              if(ret != 0)
--                      goto OUT_DECREF;
--      }
--      ret = 0;
--
--      EPILOGUE
--}
--</t>
--<t tx="davidmcnab.121303142957.10">
--static int mknod_func(const char *path, mode_t m, dev_t d)
--{
--      PyObject *v = PyObject_CallFunction(mknod_cb, "sii", path, m, d);
--      PROLOGUE
--      EPILOGUE
--}
--</t>
--<t tx="davidmcnab.121303142957.11">
--static int mkdir_func(const char *path, mode_t m)
--{
--      PyObject *v = PyObject_CallFunction(mkdir_cb, "si", path, m);
--      PROLOGUE
--      EPILOGUE
--}
--</t>
--<t tx="davidmcnab.121303142957.12">
--static int unlink_func(const char *path)
--{
--      PyObject *v = PyObject_CallFunction(unlink_cb, "s", path);
--      PROLOGUE
--      EPILOGUE
--}
--</t>
--<t tx="davidmcnab.121303142957.13">
--static int rmdir_func(const char *path)
--{
--      PyObject *v = PyObject_CallFunction(rmdir_cb, "s", path);
--      PROLOGUE
--      EPILOGUE
--}
--</t>
--<t tx="davidmcnab.121303142957.14">
--static int symlink_func(const char *path, const char *path1)
--{
--      PyObject *v = PyObject_CallFunction(symlink_cb, "ss", path, path1);
--      PROLOGUE
--      EPILOGUE
--}
--</t>
--<t tx="davidmcnab.121303142957.15">
--static int rename_func(const char *path, const char *path1)
--{
--      PyObject *v = PyObject_CallFunction(rename_cb, "ss", path, path1);
--      PROLOGUE
--      EPILOGUE
--}
--</t>
--<t tx="davidmcnab.121303142957.16">
--static int link_func(const char *path, const char *path1)
--{
--      PyObject *v = PyObject_CallFunction(link_cb, "ss", path, path1);
--      PROLOGUE
--      EPILOGUE
--}
--</t>
--<t tx="davidmcnab.121303142957.17">
--static int chmod_func(const char *path, mode_t m) 
--{
--      PyObject *v = PyObject_CallFunction(chmod_cb, "si", path, m);
--      PROLOGUE
--      EPILOGUE
--}
--</t>
--<t tx="davidmcnab.121303142957.18">
--static int chown_func(const char *path, uid_t u, gid_t g) 
--{
--      PyObject *v = PyObject_CallFunction(chown_cb, "sii", path, u, g);
--      PROLOGUE
--      EPILOGUE
--}
--</t>
--<t tx="davidmcnab.121303142957.19">
--static int truncate_func(const char *path, off_t o)
--{
--      PyObject *v = PyObject_CallFunction(truncate_cb, "si", path, o);
--      PROLOGUE
--      EPILOGUE
--}
--</t>
--<t tx="davidmcnab.121303142957.20">
--static int utime_func(const char *path, struct utimbuf *u) {
--      int actime = u ? u-&gt;actime : time(NULL);
--      int modtime = u ? u-&gt;modtime : actime;
--      PyObject *v = PyObject_CallFunction(utime_cb, "s(ii)",
--                                      path, actime, modtime);
--      PROLOGUE
--      EPILOGUE
--}
--</t>
--<t tx="davidmcnab.121303142957.21">
--static int read_func(const char *path, char *buf, size_t s, off_t off)
--{
--      PyObject *v = PyObject_CallFunction(read_cb, "sii", path, s, off);
--      PROLOGUE
--      if(PyString_Check(v)) {
--              if(PyString_Size(v) &gt; s) goto OUT_DECREF;
--              memcpy(buf, PyString_AsString(v), PyString_Size(v));
--              ret = PyString_Size(v);
--      }
--      EPILOGUE
--}
--</t>
--<t tx="davidmcnab.121303142957.22">
--static int write_func(const char *path, const char *buf, size_t t, off_t off)
--{
--      PyObject *v = PyObject_CallFunction(write_cb,"ss#i", path, buf, t, off);
--      PROLOGUE
--      EPILOGUE
--}
--</t>
--<t tx="davidmcnab.121303142957.23">
--static int open_func(const char *path, int mode)
--{
--      PyObject *v = PyObject_CallFunction(open_cb, "si", path, mode);
--      PROLOGUE
--    printf("open_func: path=%s\n", path);
--      EPILOGUE
--}
--</t>
--<t tx="davidmcnab.121303142957.24">static int release_func(const char *path, int flags)
--{
--  PyObject *v = PyObject_CallFunction(release_cb, "si", path, flags);
--  PROLOGUE
--    //printf("release_func: path=%s flags=%d\n", path, flags);
--  EPILOGUE
--}
--</t>
--<t tx="davidmcnab.121303142957.25">
--static void process_cmd(struct fuse *f, struct fuse_cmd *cmd, void *data)
--{
--      PyInterpreterState *interp = (PyInterpreterState *) data;
--      PyThreadState *state;
--
--      PyEval_AcquireLock();
--      state = PyThreadState_New(interp);
--      PyThreadState_Swap(state);
--      __fuse_process_cmd(f, cmd);
--      PyThreadState_Clear(state);
--      PyThreadState_Swap(NULL);
--      PyThreadState_Delete(state);
--      PyEval_ReleaseLock();
--}
--</t>
--<t tx="davidmcnab.121303142957.26">
--static void pyfuse_loop_mt(struct fuse *f)
--{
--      PyInterpreterState *interp;
--      PyThreadState *save;
--
--      PyEval_InitThreads();
--      interp = PyThreadState_Get()-&gt;interp;
--      save = PyEval_SaveThread();
--      __fuse_loop_mt(f, process_cmd, interp);
--      /* Not yet reached: */
--      PyEval_RestoreThread(save);
--}
--</t>
--<t tx="davidmcnab.121303142957.27">
--
--static PyObject *
--Fuse_main(PyObject *self, PyObject *args, PyObject *kw)
--{
--      int flags=0;
--      int multithreaded=0;
--      static struct fuse *fuse=NULL;
--
--      struct fuse_operations op;
--
--      static char  *kwlist[] = {
--              "getattr", "readlink", "getdir", "mknod",
--              "mkdir", "unlink", "rmdir", "symlink", "rename",
--              "link", "chmod", "chown", "truncate", "utime",
--              "open", "read", "write", "release", "statfs", "fsync",
--        "flags", "multithreaded", NULL};
--      
--      memset(&amp;op, 0, sizeof(op));
--
--      if (!PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOOOOOOOOOOOOOOOii", 
--                                     kwlist, &amp;getattr_cb, &amp;readlink_cb, &amp;getdir_cb, &amp;mknod_cb,
--                                     &amp;mkdir_cb, &amp;unlink_cb, &amp;rmdir_cb, &amp;symlink_cb, &amp;rename_cb,
--                                     &amp;link_cb, &amp;chmod_cb, &amp;chown_cb, &amp;truncate_cb, &amp;utime_cb,
--                                     &amp;open_cb, &amp;read_cb, &amp;write_cb, &amp;release_cb, &amp;statfs_cb, &amp;fsync_cb,
--                                     &amp;flags, &amp;multithreaded))
--              return NULL;
--      
--    #define DO_ONE_ATTR(name) if(name ## _cb) { Py_INCREF(name ## _cb); op.name = name ## _func; } else { op.name = NULL; }
--
--      DO_ONE_ATTR(getattr);
--      DO_ONE_ATTR(readlink);
--      DO_ONE_ATTR(getdir);
--      DO_ONE_ATTR(mknod);
--      DO_ONE_ATTR(mkdir);
--      DO_ONE_ATTR(unlink);
--      DO_ONE_ATTR(rmdir);
--      DO_ONE_ATTR(symlink);
--      DO_ONE_ATTR(rename);
--      DO_ONE_ATTR(link);
--      DO_ONE_ATTR(chmod);
--      DO_ONE_ATTR(chown);
--      DO_ONE_ATTR(truncate);
--      DO_ONE_ATTR(utime);
--      DO_ONE_ATTR(open);
--      DO_ONE_ATTR(read);
--      DO_ONE_ATTR(write);
--    DO_ONE_ATTR(release);
--    DO_ONE_ATTR(statfs);
--    DO_ONE_ATTR(fsync);
--
--      fuse = fuse_new(0, flags, &amp;op);
--      if(multithreaded)
--              pyfuse_loop_mt(fuse);
--      else
--              fuse_loop(fuse);
--
--    //printf("Fuse_main: called\n");
--
--      Py_INCREF(Py_None);
--      return Py_None;
--}
--</t>
--<t tx="davidmcnab.121303142957.28">@ List of functions defined in the module
--@c
--
--static PyMethodDef Fuse_methods[] = {
--      {"main",        (PyCFunction)Fuse_main,  METH_VARARGS|METH_KEYWORDS},
--      {NULL,          NULL}           /* sentinel */
--};
--
--
--/* Initialization function for the module (*must* be called init_fuse) */
--
--DL_EXPORT(void)
--init_fuse(void)
--{
--      PyObject *m, *d;
--      static PyObject *ErrorObject;
-- 
--      /* Create the module and add the functions */
--      m = Py_InitModule("_fuse", Fuse_methods);
--
--      /* Add some symbolic constants to the module */
--      d = PyModule_GetDict(m);
--      ErrorObject = PyErr_NewException("fuse.error", NULL, NULL);
--      PyDict_SetItemString(d, "error", ErrorObject);
--      PyDict_SetItemString(d, "DEBUG", PyInt_FromLong(FUSE_DEBUG));
--}
--</t>
--<t tx="davidmcnab.121303142957.29">#
--#    Copyright (C) 2001  Jeff Epler  &lt;jepler@unpythonic.dhs.org&gt;
--#
--#    This program can be distributed under the terms of the GNU GPL.
--#    See the file COPYING.
--#
--
--
--@language python
--@others
--</t>
--<t tx="davidmcnab.121303142957.30"># suppress version mismatch warnings
--try:
--    import warnings
--    warnings.filterwarnings('ignore',
--                            'Python C API version mismatch',
--                            RuntimeWarning,
--                            )
--except:
--    pass
-- 
--from _fuse import main, DEBUG
--import os, sys
--from errno import *
--
--</t>
--<t tx="davidmcnab.121303142957.31">class ErrnoWrapper:
--      @others
--</t>
--<t tx="davidmcnab.121303142957.32">def __init__(self, func):
--      self.func = func
--</t>
--<t tx="davidmcnab.121303142957.33">def __call__(self, *args, **kw):
--      try:
--              return apply(self.func, args, kw)
--      except (IOError, OSError), detail:
--              # Sometimes this is an int, sometimes an instance...
--              if hasattr(detail, "errno"): detail = detail.errno
--              return -detail
--</t>
--<t tx="davidmcnab.121303142957.34">class Fuse:
--
--      @others
--</t>
--<t tx="davidmcnab.121303142957.35">_attrs = ['getattr', 'readlink', 'getdir', 'mknod', 'mkdir',
--        'unlink', 'rmdir', 'symlink', 'rename', 'link', 'chmod',
--        'chown', 'truncate', 'utime', 'open', 'read', 'write', 'release',
--      'statfs', 'fsync']
--
--flags = 0
--multithreaded = 0
--
--</t>
--<t tx="davidmcnab.121303142957.36">def __init__(self, *args, **kw):
--
--    # default attributes
--    self.optlist = []
--    self.optdict = {}
--    self.mountpoint = None
--
--    # grab arguments, if any
--    argv = sys.argv
--    argc = len(argv)
--    if argc &gt; 1:
--        # we've been given the mountpoint
--        self.mountpoint = argv[1]
--    if argc &gt; 2:
--        # we've received mount args
--        optstr = argv[2]
--        opts = optstr.split(",")
--        for o in opts:
--            try:
--                k, v = o.split("=", 1)
--                self.optdict[k] = v
--            except:
--                self.optlist.append(o)
--</t>
--<t tx="davidmcnab.121303142957.37">def main(self):
--      d = {'flags': self.flags}
--      d['multithreaded'] = self.multithreaded
--      for a in self._attrs:
--              if hasattr(self,a):
--                      d[a] = ErrnoWrapper(getattr(self, a))
--      apply(main, (), d)
--</t>
--<t tx="davidmcnab.121303142957.38"># Makefile now uses distutils
--
--_fusemodule.so: _fusemodule.c
--      #gcc -g3 -I/usr/include/python2.1 _fusemodule.c -Wl,-shared -o _fusemodule.so -Wimplicit -lfuse &amp;&amp; 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
--</t>
--<t tx="davidmcnab.121303142957.39">@first #!/usr/bin/env python
--#
--#    Copyright (C) 2001  Jeff Epler  &lt;jepler@unpythonic.dhs.org&gt;
--#
--#    This program can be distributed under the terms of the GNU GPL.
--#    See the file COPYING.
--#
--
--@others
--</t>
--<t tx="davidmcnab.121303142957.40">
--from fuse import Fuse
--import os
--from errno import *
--from stat import *
--
--import thread
--</t>
--<t tx="davidmcnab.121303142957.41">class Xmp(Fuse):
--
--      @others
--</t>
--<t tx="davidmcnab.121303142957.42">def __init__(self, *args, **kw):
--
--    Fuse.__init__(self, *args, **kw)
--
--    if 0:
--        print "xmp.py:Xmp:mountpoint: %s" % repr(self.mountpoint)
--        print "xmp.py:Xmp:unnamed mount options: %s" % self.optlist
--        print "xmp.py:Xmp:named mount options: %s" % self.optdict
--
--    # do stuff to set up your filesystem here, if you want
--    #thread.start_new_thread(self.mythread, ())
--    pass
--</t>
--<t tx="davidmcnab.121303142957.43">def mythread(self):
--
--    """
--    The beauty of the FUSE python implementation is that with the python interp
--    running in foreground, you can have threads
--    """    
--    print "mythread: started"
--    #while 1:
--    #    time.sleep(120)
--    #    print "mythread: ticking"
--
--</t>
--<t tx="davidmcnab.121303142957.44">flags = 1
--
--</t>
--<t tx="davidmcnab.121303142957.45">def getattr(self, path):
--      return os.lstat(path)
--</t>
--<t tx="davidmcnab.121303142957.46">def readlink(self, path):
--      return os.readlink(path)
--</t>
--<t tx="davidmcnab.121303142957.47">def getdir(self, path):
--      return map(lambda x: (x,0), os.listdir(path))
--</t>
--<t tx="davidmcnab.121303142957.48">def unlink(self, path):
--      return os.unlink(path)
--</t>
--<t tx="davidmcnab.121303142957.49">def rmdir(self, path):
--      return os.rmdir(path)
--</t>
--<t tx="davidmcnab.121303142957.50">def symlink(self, path, path1):
--      return os.symlink(path, path1)
--</t>
--<t tx="davidmcnab.121303142957.51">def rename(self, path, path1):
--      return os.rename(path, path1)
--</t>
--<t tx="davidmcnab.121303142957.52">def link(self, path, path1):
--      return os.link(path, path1)
--</t>
--<t tx="davidmcnab.121303142957.53">def chmod(self, path, mode):
--      return os.chmod(path, mode)
--</t>
--<t tx="davidmcnab.121303142957.54">def chown(self, path, user, group):
--      return os.chown(path, user, group)
--</t>
--<t tx="davidmcnab.121303142957.55">def truncate(self, path, size):
--      f = open(path, "w+")
--      return f.truncate(size)
--</t>
--<t tx="davidmcnab.121303142957.56">def mknod(self, path, mode, dev):
--      """ Python has no os.mknod, so we can only do some things """
--      if S_ISREG(mode):
--              open(path, "w")
--      else:
--              return -EINVAL
--</t>
--<t tx="davidmcnab.121303142957.57">def mkdir(self, path, mode):
--      return os.mkdir(path, mode)
--</t>
--<t tx="davidmcnab.121303142957.58">def utime(self, path, times):
--      return os.utime(path, times)
--</t>
--<t tx="davidmcnab.121303142957.59">def open(self, path, flags):
--    #print "xmp.py:Xmp:open: %s" % path
--      os.close(os.open(path, flags))
--      return 0
--
--</t>
--<t tx="davidmcnab.121303142957.60">def read(self, path, len, offset):
--    #print "xmp.py:Xmp:read: %s" % path
--      f = open(path, "r")
--      f.seek(offset)
--      return f.read(len)
--
--</t>
--<t tx="davidmcnab.121303142957.61">def write(self, path, buf, off):
--    #print "xmp.py:Xmp:write: %s" % path
--      f = open(path, "r+")
--      f.seek(off)
--      f.write(buf)
--      return len(buf)
--
--</t>
--<t tx="davidmcnab.121303142957.62">def release(self, path, flags):
--    print "xmp.py:Xmp:release: %s %s" % (path, flags)
--    return 0
--</t>
--<t tx="davidmcnab.121303142957.63">
--if __name__ == '__main__':
--
--      server = Xmp()
--      server.flags = 0
--      server.multithreaded = 1;
--      server.main()
--</t>
--<t tx="davidmcnab.121303142957.64">"""
--distutils script for FUSE python module
--"""
--
--from distutils.core import setup, Extension
--
--setup(name="fuse",
--      version="0.1",
--      ext_modules=[Extension("_fusemodule", ["_fusemodule.c"],
--                             library_dirs=["../lib",],
--                             libraries=["fuse",],
--                             ),
--                   ],
--      py_modules=["fuse"],
--      )
--
--</t>
--<t tx="davidmcnab.121303142957.65">@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 &lt;mount point&gt; &lt;script name&gt;
--for some reason,
--      fusermount &lt;mount point&gt; python &lt;script name&gt;
--does not seem to work. (why?)
--
--Update
--======
--
--Updated 13-Dec-2003 by David McNab &lt;david@rebirthing.co.nz&gt;
--
--    - changed Makefile to use Pyton distutils
--    - added setup.py for distutils
--
--    - added 'code.leo' file for convenience of those who use the Leo
--      code editor (leo.sf.net)
--    
--    - added support for 'statfs' and 'fsync' methods (refer xmp.py)
--
--Updated Dec 2003 by David McNab &lt;david@rebirthing.co.nz&gt;:
--    
--    - added support for 'release' events (ie when file gets closed)
--    - added __init__ to base class, which picks off parameters and
--      stores them as instance attributes:
--          - self.mountpoint - the mountpoint as given in the mount command
--          - self.optlist - unnamed options (eg 'rw', 'exec' etc)
--          - self.optdict - named options (eg, '-o arg1=val1,arg2=val2...' from mount cmd)
--    - fixed incompatibility issues with recent pythons (original was broken
--      under python2.3)
--
--Limitations
--===========
--
--This is minimally tested, though I think I have exercised each function.
--There's no documentation, docstrings, or tests.
--
--Python's lstat() does not return some fields which must be filled in
--(st_blksize, st_blocks, st_ino), and _fusemodule assumes that the return
--value from the lstat() method is identical to Python's lstat().  This
--limitation should be lifted, and some standard order chosen for these
--three values.  For now, though, default values are chosen and du returns a
--number similar to the "real" one.
--
--The Python Global Interpreter Lock is not handled, so using
--fuse.MULTITHREAD will not work.  Modifying the PROLOGUE and EPILOGUE
--functions may take care of this.  For now, just run without
--fuse.MULTITHREAD in flags.
--
--Author
--======
--
--I'm Jeff Epler &lt;jepler@unpythonic.dhs.org&gt;.  I've been dabbling in
--Python for nearly 7 years now, and interested (despite the lack of a
--real practical use) in userspace filesystems ever since I couldn't get
--userfs to compile way back in '93 or so.  FUSE is cool, but i'm still
--not sure what it's good for in practical terms.
--
--I don't know how high a level of interest I'll maintain in this project,
--so if you want to do something with it feel free to do so.  Like FUSE,
--this software is distributed under the terms of the GNU General Public
--License, Version 2.  Future versions, if any, will be available at [3].
--
--
--[1] http://www.python.org
--[2] http://sourceforge.net/projects/avf/
--[3] http://unpythonic.dhs.org/~jepler/fuse/
--</t>
--<t tx="davidmcnab.121303142957.67">@first #!/usr/bin/env python
--
--"""
--This utility allows FUSE filesystems to be mounted with the regular *nix
--'mount' command, or even be listed in /etc/fstab
--
--To enable this, you need to:
-- 1. set execute-permission on this script
-- 2. symlink this script into /sbin/mount.fuse
--
--Usage:
--
-- You can use this in 3 ways:
--     1.  mount -t fuse /path/to/script/or/program /path/of/mount/point [options]
--     2.  mount -t fuse none /path/of/mount/point -o fs=/path/to/script/or/prog[,opt=val...]
--     3.  in /etc/fstab, add:
--           /path/to/script/or/prog /path/of/mount/point fuse noauto[,...]
--"""
--
--import sys, os, time
--
--progname = sys.argv[0]
--
--def usage(ret):
--    print "Usage: %s /path/to/fuse/fs /path/of/mountpoint [-o options]" % progname
--    print "or:    %s none /path/of/mountpoint [-o fs=/path/to/fuse/fs[,...]]" % progname
--    sys.exit(ret)
--
--def main():
--
--    # initial sanity check
--    argc = len(sys.argv)
--    if argc &lt; 3 or sys.argv[3] != "-o":
--        usage(1)
--
--    dev = sys.argv[1]
--    mountpoint = sys.argv[2]
--
--    # grab options, if any
--    optdict = {}
--    optlist = []
--    if argc &gt; 4:
--        odata = sys.argv[4]
--        opts = odata.split(",")
--        #print opts
--        for o in opts:
--            try:
--                k, v = o.split("=", 1)
--                optdict[k] = v
--            except:
--                optlist.append(o)
--    else:
--        odata = ""
--
--    #print sys.argv
--    if dev == 'none':
--        if not optdict.has_key("fs"):
--            print "%s: Must specify python file with 'fs' option\n" % progname
--            usage(1)
--        pyfile = optdict['fs']
--    else:
--        pyfile = dev
--
--    if not os.path.isfile(pyfile):
--        print "%s: file %s doesn't exist, or is not a file" % (progname, pyfile)
--        sys.exit(1)
--    pypath = os.path.abspath(pyfile)
--
--    #print optdict, optlist
--
--    # all seems ok - run our fuse fs as a child
--    if os.fork() == 0:
--        os.system("fusermount -c -x %s %s %s %s" % (mountpoint, pypath, mountpoint, odata))
--    else:
--        #print "parent exiting..."
--        pass
--
--if __name__ == '__main__':
--    main()
--
--</t>
--<t tx="davidmcnab.121303144134">def statfs(self):
--    """
--    Should return a tuple with the following 6 elements:
--        - blocksize - size of file blocks, in bytes
--        - totalblocks - total number of blocks in the filesystem
--        - freeblocks - number of free blocks
--        - totalfiles - total number of file inodes
--        - freefiles - nunber of free file inodes
--
--    Feel free to set any of the above values to 0, which tells
--    the kernel that the info is not available.
--    """
--    print "xmp.py:Xmp:statfs: returning fictitious values"
--    blocks_size = 1024
--    blocks = 100000
--    blocks_free = 25000
--    files = 100000
--    files_free = 60000
--    namelen = 80
--    return (blocks_size, blocks, blocks_free, files, files_free, namelen)
--</t>
--<t tx="davidmcnab.121303144134.1">def fsync(self, path, isfsyncfile):
--    print "xmp.py:Xmp:fsync: path=%s, isfsyncfile=%s" % (path, isfsyncfile)
--    return 0
--
--</t>
--<t tx="davidmcnab.121303144441">static int statfs_func(struct fuse_statfs *fst)
--{
--  int i;
--  long retvalues[6];
--  PyObject *v = PyObject_CallFunction(statfs_cb, "");
--PROLOGUE
--
--  if (!PySequence_Check(v))
--    { goto OUT_DECREF; }
-- if (PySequence_Size(v) &lt; 6)
--   { goto OUT_DECREF; }
-- for(i=0; i&lt;6; i++)
--   {
--     PyObject *tmp = PySequence_GetItem(v, i);
--     retvalues[i] = PyInt_Check(tmp)
--       ? PyInt_AsLong(tmp)
--       : (PyLong_Check(tmp)
--          ? PyLong_AsLong(tmp)
--          : 0);
--   }
--
-- fst-&gt;block_size  = retvalues[0];
-- fst-&gt;blocks      = retvalues[1];
-- fst-&gt;blocks_free = retvalues[2];
-- fst-&gt;files       = retvalues[3];
-- fst-&gt;files_free  = retvalues[4];
-- fst-&gt;namelen     = retvalues[5];
-- ret = 0;
-- 
--#ifdef IGNORE_THIS
-- printf("block_size=%ld, blocks=%ld, blocks_free=%ld, files=%ld, files_free=%ld, namelen=%ld\n",
--        retvalues[0], retvalues[1], retvalues[2], retvalues[3], retvalues[4], retvalues[5]);
--#endif
--
--EPILOGUE
--
--}
--
--</t>
--<t tx="davidmcnab.121303144441.1">static int fsync_func(const char *path, int isfsyncfile)
--{
--      PyObject *v = PyObject_CallFunction(fsync_cb, "si", path, isfsyncfile);
--      PROLOGUE
--      EPILOGUE
--}
--
--</t>
--<t tx="davidmcnab.121403050157">@ignore
--@language python
--&lt;&lt; fuse declarations &gt;&gt;
--@others
--    #@-node:main
--    #@-others
--#@-node:class Fuse
--#@-others
--#@-node:@file fuse.py
--#@-leo
--</t>
--<t tx="davidmcnab.121403050157.1">#@+leo-ver=4
--#@+node:@file fuse.py
--#
--#    Copyright (C) 2001  Jeff Epler  &lt;jepler@unpythonic.dhs.org&gt;
--#
--#    This program can be distributed under the terms of the GNU GPL.
--#    See the file COPYING.
--#
--
--
--#@@language python
--#@+others
--#@+node:imports
--# suppress version mismatch warnings
--try:
--    import warnings
--    warnings.filterwarnings('ignore',
--                            'Python C API version mismatch',
--                            RuntimeWarning,
--                            )
--except:
--    pass
-- 
--from _fuse import main, DEBUG
--import os, sys
--from errno import *
--
--#@-node:imports
--#@+node:class ErrnoWrapper
--</t>
--<t tx="davidmcnab.121403050157.2">class ErrnoWrapper:
--      &lt;&lt; class ErrnoWrapper declarations &gt;&gt;
--      @others
--</t>
--<t tx="davidmcnab.121403050157.3">    #@      @+others
--    #@+node:__init__
--</t>
--<t tx="davidmcnab.121403050157.4">def __init__(self, func):
--      self.func = func
--</t>
--<t tx="davidmcnab.121403050157.5">#@-node:__init__
--#@+node:__call__
--def __call__(self, *args, **kw):
--      try:
--              return apply(self.func, args, kw)
--      except (IOError, OSError), detail:
--              # Sometimes this is an int, sometimes an instance...
--              if hasattr(detail, "errno"): detail = detail.errno
--              return -detail
--</t>
--<t tx="davidmcnab.121403050157.6">    #@-node:__call__
--    #@-others
--#@-node:class ErrnoWrapper
--#@+node:class Fuse
--class Fuse:
--      &lt;&lt; class Fuse declarations &gt;&gt;
--      @others
--</t>
--<t tx="davidmcnab.121403050157.7">#@  @+others
--#@+node:attribs
--_attrs = ['getattr', 'readlink', 'getdir', 'mknod', 'mkdir',
--        'unlink', 'rmdir', 'symlink', 'rename', 'link', 'chmod',
--        'chown', 'truncate', 'utime', 'open', 'read', 'write', 'release',
--      'statfs', 'fsync']
--
--flags = 0
--multithreaded = 0
--
--#@-node:attribs
--#@+node:__init__
--</t>
--<t tx="davidmcnab.121403050157.8">def __init__(self, *args, **kw):
--
--    # default attributes
--    self.optlist = []
--    self.optdict = {}
--    self.mountpoint = None
--
--    # grab arguments, if any
--    argv = sys.argv
--    argc = len(argv)
--    if argc &gt; 1:
--        # we've been given the mountpoint
--        self.mountpoint = argv[1]
--    if argc &gt; 2:
--        # we've received mount args
--        optstr = argv[2]
--        opts = optstr.split(",")
--        for o in opts:
--            try:
--                k, v = o.split("=", 1)
--                self.optdict[k] = v
--            except:
--                self.optlist.append(o)
--</t>
--<t tx="davidmcnab.121403050157.9">#@-node:__init__
--#@+node:main
--def main(self):
--      d = {'flags': self.flags}
--      d['multithreaded'] = self.multithreaded
--      for a in self._attrs:
--              if hasattr(self,a):
--                      d[a] = ErrnoWrapper(getattr(self, a))
--      apply(main, (), d)
--</t>
--</tnodes>
--</leo_file>
diff --cc python/fuse.py
index ece9686263d5ffee1aabc92f803b4b3c24109936,ece9686263d5ffee1aabc92f803b4b3c24109936..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,121 -1,121 +1,0 @@@
--#@+leo-ver=4
--#@+node:@file fuse.py
--#
--#    Copyright (C) 2001  Jeff Epler  <jepler@unpythonic.dhs.org>
--#
--#    This program can be distributed under the terms of the GNU GPL.
--#    See the file COPYING.
--#
--
--
--#@@language python
--#@+others
--#@+node:imports
--# suppress version mismatch warnings
--try:
--    import warnings
--    warnings.filterwarnings('ignore',
--                            'Python C API version mismatch',
--                            RuntimeWarning,
--                            )
--except:
--    pass
-- 
--from _fuse import main, FuseGetContext, FuseInvalidate
--from string import join
--import os, sys
--from errno import *
--
--#@-node:imports
--#@+node:class ErrnoWrapper
--class ErrnoWrapper:
--    #@        @+others
--    #@+node:__init__
--    def __init__(self, func):
--      self.func = func
--    #@-node:__init__
--    #@+node:__call__
--    def __call__(self, *args, **kw):
--      try:
--              return apply(self.func, args, kw)
--      except (IOError, OSError), detail:
--              # Sometimes this is an int, sometimes an instance...
--              if hasattr(detail, "errno"): detail = detail.errno
--              return -detail
--    #@-node:__call__
--    #@-others
--#@-node:class ErrnoWrapper
--#@+node:class Fuse
--class Fuse:
--
--    #@        @+others
--    #@+node:attribs
--    _attrs = ['getattr', 'readlink', 'getdir', 'mknod', 'mkdir',
--        'unlink', 'rmdir', 'symlink', 'rename', 'link', 'chmod',
--        'chown', 'truncate', 'utime', 'open', 'read', 'write', 'release',
--          'statfs', 'fsync']
--    
--    flags = 0
--    multithreaded = 0
--    
--    #@-node:attribs
--    #@+node:__init__
--    def __init__(self, *args, **kw):
--    
--        # default attributes
--        self.optlist = []
--        self.optdict = {}
--        self.mountpoint = None
--    
--        # grab arguments, if any
--        argv = sys.argv
--        argc = len(argv)
--        if argc > 1:
--            # we've been given the mountpoint
--            self.mountpoint = argv[1]
--        if argc > 2:
--            # we've received mount args
--            optstr = argv[2]
--            opts = optstr.split(",")
--            for o in opts:
--                try:
--                    k, v = o.split("=", 1)
--                    self.optdict[k] = v
--                except:
--                    self.optlist.append(o)
--
--    def GetContext(self):
--      return FuseGetContext(self)
--
--    def Invalidate(self, path):
--        return FuseInvalidate(self, path)
--
--    #@-node:__init__
--    #@+node:main
--    def main(self):
--
--        d = {'mountpoint': self.mountpoint}
--        d['multithreaded'] = self.multithreaded
--        if hasattr( self, 'debug'):
--            d['lopts'] = 'debug';
--
--        k=[]
--        if hasattr(self,'allow_other'):
--                k.append('allow_other')
--
--        if hasattr(self,'kernel_cache'):
--                k.append('kernel_cache')
--
--      if len(k):
--                d['kopts'] = join(k,',')
--      
--      for a in self._attrs:
--              if hasattr(self,a):
--                      d[a] = ErrnoWrapper(getattr(self, a))
--      apply(main, (), d)
--    #@-node:main
--    #@-others
--#@-node:class Fuse
--#@-others
--#@-node:@file fuse.py
--#@-leo
diff --cc python/setup.py
index beb5c533d4c46265592da496eab9e20ea553d969,beb5c533d4c46265592da496eab9e20ea553d969..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,21 -1,21 +1,0 @@@
--#@+leo-ver=4
--#@+node:@file setup.py
--"""
--distutils script for FUSE python module
--"""
--
--from distutils.core import setup, Extension
--
--setup(name="fuse",
--      version="0.1",
--      ext_modules=[Extension("_fusemodule", ["_fusemodule.c"],
--                             library_dirs=["../lib/.libs",],
--                             include_dirs=["../include",],
--                             libraries=["fuse",],
--                             ),
--                   ],
--      py_modules=["fuse"],
--      )
--
--#@-node:@file setup.py
--#@-leo
diff --cc python/xmp.py
index 946bca86932d6e6eae8678a5c923eac53f1352a2,946bca86932d6e6eae8678a5c923eac53f1352a2..0000000000000000000000000000000000000000
deleted file mode 100755,100755
+++ /dev/null
@@@ -1,187 -1,187 +1,0 @@@
--#!/usr/bin/env python
--#@+leo-ver=4
--#@+node:@file xmp.py
--#@@first
--#
--#    Copyright (C) 2001  Jeff Epler  <jepler@unpythonic.dhs.org>
--#
--#    This program can be distributed under the terms of the GNU GPL.
--#    See the file COPYING.
--#
--
--#@+others
--#@+node:imports
--
--from fuse import Fuse
--import os
--from errno import *
--from stat import *
--
--import thread
--#@-node:imports
--#@+node:class Xmp
--class Xmp(Fuse):
--
--    #@        @+others
--    #@+node:__init__
--    def __init__(self, *args, **kw):
--    
--        Fuse.__init__(self, *args, **kw)
--    
--        if 0:
--            print "xmp.py:Xmp:mountpoint: %s" % repr(self.mountpoint)
--            print "xmp.py:Xmp:unnamed mount options: %s" % self.optlist
--            print "xmp.py:Xmp:named mount options: %s" % self.optdict
--    
--        # do stuff to set up your filesystem here, if you want
--        #thread.start_new_thread(self.mythread, ())
--        pass
--    #@-node:__init__
--    #@+node:mythread
--    def mythread(self):
--    
--        """
--        The beauty of the FUSE python implementation is that with the python interp
--        running in foreground, you can have threads
--        """    
--        print "mythread: started"
--        #while 1:
--        #    time.sleep(120)
--        #    print "mythread: ticking"
--    
--    #@-node:mythread
--    #@+node:attribs
--    flags = 1
--    
--    #@-node:attribs
--    #@+node:getattr
--    def getattr(self, path):
--      return os.lstat(path)
--    #@-node:getattr
--    #@+node:readlink
--    def readlink(self, path):
--      return os.readlink(path)
--    #@-node:readlink
--    #@+node:getdir
--    def getdir(self, path):
--      return map(lambda x: (x,0), os.listdir(path))
--    #@-node:getdir
--    #@+node:unlink
--    def unlink(self, path):
--      return os.unlink(path)
--    #@-node:unlink
--    #@+node:rmdir
--    def rmdir(self, path):
--      return os.rmdir(path)
--    #@-node:rmdir
--    #@+node:symlink
--    def symlink(self, path, path1):
--      return os.symlink(path, path1)
--    #@-node:symlink
--    #@+node:rename
--    def rename(self, path, path1):
--      return os.rename(path, path1)
--    #@-node:rename
--    #@+node:link
--    def link(self, path, path1):
--      return os.link(path, path1)
--    #@-node:link
--    #@+node:chmod
--    def chmod(self, path, mode):
--      return os.chmod(path, mode)
--    #@-node:chmod
--    #@+node:chown
--    def chown(self, path, user, group):
--      return os.chown(path, user, group)
--    #@-node:chown
--    #@+node:truncate
--    def truncate(self, path, size):
--      f = open(path, "w+")
--      return f.truncate(size)
--    #@-node:truncate
--    #@+node:mknod
--    def mknod(self, path, mode, dev):
--      """ Python has no os.mknod, so we can only do some things """
--      if S_ISREG(mode):
--              open(path, "w")
--      else:
--              return -EINVAL
--    #@-node:mknod
--    #@+node:mkdir
--    def mkdir(self, path, mode):
--      return os.mkdir(path, mode)
--    #@-node:mkdir
--    #@+node:utime
--    def utime(self, path, times):
--      return os.utime(path, times)
--    #@-node:utime
--    #@+node:open
--    def open(self, path, flags):
--        #print "xmp.py:Xmp:open: %s" % path
--      os.close(os.open(path, flags))
--      return 0
--    
--    #@-node:open
--    #@+node:read
--    def read(self, path, len, offset):
--        #print "xmp.py:Xmp:read: %s" % path
--      f = open(path, "r")
--      f.seek(offset)
--      return f.read(len)
--    
--    #@-node:read
--    #@+node:write
--    def write(self, path, buf, off):
--        #print "xmp.py:Xmp:write: %s" % path
--      f = open(path, "r+")
--      f.seek(off)
--      f.write(buf)
--      return len(buf)
--    
--    #@-node:write
--    #@+node:release
--    def release(self, path, flags):
--        print "xmp.py:Xmp:release: %s %s" % (path, flags)
--        return 0
--    #@-node:release
--    #@+node:statfs
--    def statfs(self):
--        """
--        Should return a tuple with the following 6 elements:
--            - blocksize - size of file blocks, in bytes
--            - totalblocks - total number of blocks in the filesystem
--            - freeblocks - number of free blocks
--            - totalfiles - total number of file inodes
--            - freefiles - nunber of free file inodes
--    
--        Feel free to set any of the above values to 0, which tells
--        the kernel that the info is not available.
--        """
--        print "xmp.py:Xmp:statfs: returning fictitious values"
--        blocks_size = 1024
--        blocks = 100000
--        blocks_free = 25000
--        files = 100000
--        files_free = 60000
--        namelen = 80
--        return (blocks_size, blocks, blocks_free, files, files_free, namelen)
--    #@-node:statfs
--    #@+node:fsync
--    def fsync(self, path, isfsyncfile):
--        print "xmp.py:Xmp:fsync: path=%s, isfsyncfile=%s" % (path, isfsyncfile)
--        return 0
--    
--    #@-node:fsync
--    #@-others
--#@-node:class Xmp
--#@+node:mainline
--
--if __name__ == '__main__':
--
--      server = Xmp()
--      server.multithreaded = 1;
--      server.main()
--#@-node:mainline
--#@-others
--#@-node:@file xmp.py
--#@-leo