diff options
43 files changed, 0 insertions, 4026 deletions
diff --git a/perl/.cvsignore b/perl/.cvsignore deleted file mode 100644 index 5d5c2dc..0000000 --- a/perl/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -Fuse.bs Fuse.c Makefile blib pm_to_blib diff --git a/perl/Changes b/perl/Changes deleted file mode 100644 index 56b4733..0000000 --- a/perl/Changes +++ /dev/null @@ -1,12 +0,0 @@ -Revision history for Perl extension Fuse. - -0.01 Wed Nov 28 21:45:20 2001 - - original version; created by h2xs 1.21 with options - include/fuse.h - -0.02 Sun Dec 2 18:59:56 2001 - - works well enough to release, but still needs testing - -0.03 Wed Dec 5 02:17:52 2001 - - changed getattr() to smell like perl's stat() - - fleshed out the documentation a bit diff --git a/perl/Fuse.pm b/perl/Fuse.pm deleted file mode 100644 index 6a01677..0000000 --- a/perl/Fuse.pm +++ /dev/null @@ -1,360 +0,0 @@ -package Fuse; - -use 5.006; -use strict; -use warnings; -use Errno; -use Carp; - -require Exporter; -require DynaLoader; -use AutoLoader; -use Data::Dumper; -our @ISA = qw(Exporter DynaLoader); - -# Items to export into callers namespace by default. Note: do not export -# names by default without a very good reason. Use EXPORT_OK instead. -# Do not simply export all your public functions/methods/constants. - -# This allows declaration use Fuse ':all'; -# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK -# will save memory. -our %EXPORT_TAGS = ( 'all' => [ qw( - FUSE_DEBUG -) ] ); - -our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); - -our @EXPORT = qw( - FUSE_DEBUG -); -our $VERSION = '0.01'; - -sub AUTOLOAD { - # This AUTOLOAD is used to 'autoload' constants from the constant() - # XS function. If a constant is not found then control is passed - # to the AUTOLOAD in AutoLoader. - - my $constname; - our $AUTOLOAD; - ($constname = $AUTOLOAD) =~ s/.*:://; - croak "& not defined" if $constname eq 'constant'; - my $val = constant($constname, @_ ? $_[0] : 0); - if ($! != 0) { - if ($!{EINVAL}) { - $AutoLoader::AUTOLOAD = $AUTOLOAD; - goto &AutoLoader::AUTOLOAD; - } - else { - croak "Your vendor has not defined Fuse macro $constname"; - } - } - { - no strict 'refs'; - # Fixed between 5.005_53 and 5.005_61 - if ($] >= 5.00561) { - *$AUTOLOAD = sub () { $val }; - } - else { - *$AUTOLOAD = sub { $val }; - } - } - goto &$AUTOLOAD; -} - -bootstrap Fuse $VERSION; - -sub main { - my (@subs) = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - my (@names) = qw(getattr readlink getdir mknod mkdir unlink rmdir symlink - rename link chmod chown truncate utime open read write statfs); - my ($tmp) = 0; - my (%mapping) = map { $_ => $tmp++ } (@names); - my (%otherargs) = (debug=>0, mountpoint=>""); - while(my $name = shift) { - my ($subref) = shift; - if(exists($otherargs{$name})) { - $otherargs{$name} = $subref; - } else { - croak "There is no function $name" unless exists($mapping{$name}); - croak "Usage: Fuse::main(getattr => &my_getattr, ...)" unless $subref; - croak "Usage: Fuse::main(getattr => &my_getattr, ...)" unless ref($subref); - croak "Usage: Fuse::main(getattr => &my_getattr, ...)" unless ref($subref) eq "CODE"; - $subs[$mapping{$name}] = $subref; - } - } - perl_fuse_main($otherargs{debug},$otherargs{mountpoint},@subs); -} - -# Autoload methods go after =cut, and are processed by the autosplit program. - -1; -__END__ - -=head1 NAME - -Fuse - write filesystems in Perl using FUSE - -=head1 SYNOPSIS - - use Fuse; - my ($mountpoint) = ""; - $mountpoint = shift(@ARGV) if @ARGV; - Fuse::main(mountpoint=>$mountpoint, getattr=>\&my_getattr, getdir=>\&my_getdir, ...); - -=head1 DESCRIPTION - -This lets you implement filesystems in perl, through the FUSE -(Filesystem in USErspace) kernel/lib interface. - -FUSE expects you to implement callbacks for the various functions. - -NOTE: I have only tested the things implemented in example.pl! -It should work, but some things may not. - -In the following definitions, "errno" can be 0 (for a success), --EINVAL, -ENOENT, -EONFIRE, any integer less than 1 really. - -You can import standard error constants by saying something like -"use POSIX qw(EDOTDOT ENOANO);". - -Every constant you need (file types, open() flags, error values, -etc) can be imported either from POSIX or from Fcntl, often both. -See their respective documentations, for more information. - -=head2 EXPORT - -None by default. - -=head2 EXPORTABLE CONSTANTS - -None. - -=head2 FUNCTIONS - -=head3 Fuse::main - -Takes arguments in the form of hash key=>value pairs. There are -many valid keys. Most of them correspond with names of callback -functions, as described in section 'FUNCTIONS YOUR FILESYSTEM MAY IMPLEMENT'. -A few special keys also exist: - - -debug => boolean - -=over 1 - -This turns FUSE call tracing on and off. Default is 0 (which means off). - -=back - -mountpoint => string - -=over 1 - -The point at which to mount this filesystem. There is no default, you must -specify this. An example would be '/mnt'. - -=back - -unthreaded => boolean - -=over 1 - -This turns FUSE multithreading off and on. NOTE: This perlmodule does not -currently work properly in multithreaded mode! The author is unfortunately -not familiar enough with perl-threads internals, and according to the -documentation available at time of writing (2002-03-08), those internals are -subject to changing anyway. Note that singlethreaded mode also means that -you will not have to worry about reentrancy, though you will have to worry -about recursive lookups (since the kernel holds a global lock on your -filesystem and blocks waiting for one callback to complete before calling -another). - -I hope to add full multithreading functionality later, but for now, I -recommend you leave this option at the default, 1 (which means -unthreaded, no threads will be used and no reentrancy is needed). - -=back - -=head2 FUNCTIONS YOUR FILESYSTEM MAY IMPLEMENT - -=head3 getattr - -Arguments: filename. -Returns a list, very similar to the 'stat' function (see -perlfunc). On error, simply return a single numeric scalar -value (e.g. "return -ENOENT();"). - -FIXME: the "ino" field is currently ignored. I tried setting it to 0 -in an example script, which consistently caused segfaults. - -Fields (the following was stolen from perlfunc(1) with apologies): - -($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, - $atime,$mtime,$ctime,$blksize,$blocks) - = getattr($filename); - -Here are the meaning of the fields: - - 0 dev device number of filesystem - 1 ino inode number - 2 mode file mode (type and permissions) - 3 nlink number of (hard) links to the file - 4 uid numeric user ID of file's owner - 5 gid numeric group ID of file's owner - 6 rdev the device identifier (special files only) - 7 size total size of file, in bytes - 8 atime last access time in seconds since the epoch - 9 mtime last modify time in seconds since the epoch -10 ctime inode change time (NOT creation time!) in seconds - since the epoch -11 blksize preferred block size for file system I/O -12 blocks actual number of blocks allocated - -(The epoch was at 00:00 January 1, 1970 GMT.) - -=head3 readlink - -Arguments: link pathname. -Returns a scalar: either a numeric constant, or a text string. - -This is called when dereferencing symbolic links, to learn the target. - -example rv: return "/proc/self/fd/stdin"; - -=head3 getdir - -Arguments: Containing directory name. -Returns a list: 0 or more text strings (the filenames), followed by a numeric errno (usually 0). - -This is used to obtain directory listings. Its opendir(), readdir(), filldir() and closedir() all in one call. - -example rv: return ('.', 'a', 'b', 0); - -=head3 mknod - -Arguments: Filename, numeric modes, numeric device -Returns an errno (0 upon success, as usual). - -This function is called for all non-directory, non-symlink nodes, -not just devices. - -=head3 mkdir - -Arguments: New directory pathname, numeric modes. -Returns an errno. - -Called to create a directory. - -=head3 unlink - -Arguments: Filename. -Returns an errno. - -Called to remove a file, device, or symlink. - -=head3 rmdir - -Arguments: Pathname. -Returns an errno. - -Called to remove a directory. - -=head3 symlink - -Arguments: Existing filename, symlink name. -Returns an errno. - -Called to create a symbolic link. - -=head3 rename - -Arguments: old filename, new filename. -Returns an errno. - -Called to rename a file, and/or move a file from one directory to another. - -=head3 link - -Arguments: Existing filename, hardlink name. -Returns an errno. - -Called to create hard links. - -=head3 chmod - -Arguments: Pathname, numeric modes. -Returns an errno. - -Called to change permissions on a file/directory/device/symlink. - -=head3 chown - -Arguments: Pathname, numeric uid, numeric gid. -Returns an errno. - -Called to change ownership of a file/directory/device/symlink. - -=head3 truncate - -Arguments: Pathname, numeric offset. -Returns an errno. - -Called to truncate a file, at the given offset. - -=head3 utime - -Arguments: Pathname, numeric actime, numeric modtime. -Returns an errno. - -Called to change access/modification times for a file/directory/device/symlink. - -=head3 open - -Arguments: Pathname, numeric flags (which is an OR-ing of stuff like O_RDONLY -and O_SYNC, constants you can import from POSIX). -Returns an errno. - -No creation, or trunctation flags (O_CREAT, O_EXCL, O_TRUNC) will be passed to open(). -Your open() method needs only check if the operation is permitted for the given flags, and return 0 for success. - -=head3 read - -Arguments: Pathname, numeric requestedsize, numeric offset. -Returns a numeric errno, or a string scalar with up to $requestedsize bytes of data. - -Called in an attempt to fetch a portion of the file. - -=head3 write - -Arguments: Pathname, scalar buffer, numeric offset. You can use length($buffer) to -find the buffersize. -Returns an errno. - -Called in an attempt to write (or overwrite) a portion of the file. Be prepared because $buffer could contain random binary data with NULLs and all sorts of other wonderful stuff. - -=head3 statfs - -Arguments: none -Returns any of the following: - --ENOANO() - -or - -$namelen, $files, $files_free, $blocks, $blocks_avail, $blocksize - -or - --ENOANO(), $namelen, $files, $files_free, $blocks, $blocks_avail, $blocksize - -=head1 AUTHOR - -Mark Glines, E<lt>mark@glines.orgE<gt> - -=head1 SEE ALSO - -L<perl>, the FUSE documentation. - -=cut diff --git a/perl/Fuse.xs b/perl/Fuse.xs deleted file mode 100644 index 233139a..0000000 --- a/perl/Fuse.xs +++ /dev/null @@ -1,572 +0,0 @@ -#include "EXTERN.h" -#include "perl.h" -#include "XSUB.h" - -#include <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 --git a/perl/MANIFEST b/perl/MANIFEST deleted file mode 100644 index 3012c02..0000000 --- a/perl/MANIFEST +++ /dev/null @@ -1,7 +0,0 @@ -Changes -Fuse.pm -Fuse.xs -Makefile.PL -MANIFEST -README -test.pl diff --git a/perl/Makefile.PL b/perl/Makefile.PL deleted file mode 100644 index 6e66f46..0000000 --- a/perl/Makefile.PL +++ /dev/null @@ -1,17 +0,0 @@ -use ExtUtils::MakeMaker; -# See lib/ExtUtils/MakeMaker.pm for details of how to influence -# the contents of the Makefile that is written. -WriteMakefile( - 'NAME' => 'Fuse', - 'VERSION_FROM' => 'Fuse.pm', # finds $VERSION - 'PREREQ_PM' => {}, # e.g., Module::Name => 1.1 - ($] >= 5.005 ? ## Add these new keywords supported since 5.005 - (ABSTRACT_FROM => 'Fuse.pm', # retrieve abstract from module - AUTHOR => 'Mark Glines <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 --git a/perl/README b/perl/README deleted file mode 100644 index fb49cd7..0000000 --- a/perl/README +++ /dev/null @@ -1,69 +0,0 @@ -Fuse version 0.03 -================= - -This is a test release. It seems to work quite well. In fact, I can't -find any problems with it whatsoever. If you do, I want to know. - - -INSTALLATION - -To install this module type the standard commands as root: - - perl Makefile.PL - make - make test - make install - - -DEPENDENCIES - -This module requires the FUSE userspace library and the FUSE kernel module. - - -COPYRIGHT AND LICENCE - -This is contributed to the FUSE project by Mark Glines <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 --git a/perl/examples/example.pl b/perl/examples/example.pl deleted file mode 100755 index 9ba1117..0000000 --- a/perl/examples/example.pl +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/perl - -use Fuse; -use POSIX qw(ENOENT EISDIR EINVAL); - -my (%files) = ( - '.' => { - type => 0040, - mode => 0755, - ctime => time()-1000 - }, - a => { - cont => "File 'a'.\n", - type => 0100, - mode => 0755, - ctime => time()-2000 - }, - b => { - cont => "This is file 'b'.\n", - type => 0100, - mode => 0644, - ctime => time()-1000 - }, -); - -sub filename_fixup { - my ($file) = shift; - $file =~ s,^/,,; - $file = '.' unless length($file); - return $file; -} - -sub e_getattr { - my ($file) = filename_fixup(shift); - $file =~ s,^/,,; - $file = '.' unless length($file); - return -ENOENT() unless exists($files{$file}); - my ($size) = exists($files{$file}{cont}) ? length($files{$file}{cont}) : 0; - my ($modes) = ($files{$file}{type}<<9) + $files{$file}{mode}; - my ($dev, $ino, $rdev, $blocks, $gid, $uid, $nlink, $blksize) = (0,0,0,1,0,0,1,1024); - my ($atime, $ctime, $mtime); - $atime = $ctime = $mtime = $files{$file}{ctime}; - # 2 possible types of return values: - #return -ENOENT(); # or any other error you care to - #print(join(",",($dev,$ino,$modes,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks)),"\n"); - return ($dev,$ino,$modes,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks); -} - -sub e_getdir { - # return as many text filenames as you like, followed by the retval. - print((scalar keys %files)."\n"); - return (keys %files),0; -} - -sub e_open { - # VFS sanity check; it keeps all the necessary state, not much to do here. - my ($file) = filename_fixup(shift); - print("open called\n"); - return -ENOENT() unless exists($files{$file}); - return -EISDIR() unless exists($files{$file}{cont}); - print("open ok\n"); - return 0; -} - -sub e_read { - # return an error numeric, or binary/text string. (note: 0 means EOF, "0" will - # give a byte (ascii "0") to the reading program) - my ($file) = filename_fixup(shift); - my ($buf,$off) = @_; - return -ENOENT() unless exists($files{$file}); - return -EINVAL() if $off > length($files{$file}{cont}); - return 0 if $off == length($files{$file}{cont}); - return substr($files{$file}{cont},$off,$buf); -} - -sub e_statfs { return 255, 1, 1, 1, 1, 2 } - -# If you run the script directly, it will run fusermount, which will in turn -# re-run this script. Hence the funky semantics. -my ($mountpoint) = ""; -$mountpoint = shift(@ARGV) if @ARGV; -Fuse::main( - mountpoint=>$mountpoint, - getattr=>\&e_getattr, - getdir=>\&e_getdir, - open=>\&e_open, - statfs=>\&e_statfs, - read=>\&e_read, - #debug=>1, threaded=>0 -); diff --git a/perl/examples/loopback.pl b/perl/examples/loopback.pl deleted file mode 100755 index bdc8c22..0000000 --- a/perl/examples/loopback.pl +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/perl - -use strict; -use Fuse; -use IO::File; -use POSIX qw(ENOENT ENOSYS EEXIST EPERM O_RDONLY O_RDWR O_APPEND O_CREAT); -use Fcntl qw(S_ISBLK S_ISCHR S_ISFIFO SEEK_SET); -require 'syscall.ph'; # for SYS_mknod and SYS_lchown - -sub fixup { return "/tmp/fusetest" . shift } - -sub x_getattr { - my ($file) = fixup(shift); - my (@list) = lstat($file); - return -$! unless @list; - return @list; -} - -sub x_getdir { - my ($dirname) = fixup(shift); - unless(opendir(DIRHANDLE,$dirname)) { - return -ENOENT(); - } - my (@files) = readdir(DIRHANDLE); - closedir(DIRHANDLE); - return (@files, 0); -} - -sub x_open { - my ($file) = fixup(shift); - my ($mode) = shift; - return -$! unless sysopen(FILE,$file,$mode); - close(FILE); - return 0; -} - -sub x_read { - my ($file,$bufsize,$off) = @_; - my ($rv) = -ENOSYS(); - my ($handle) = new IO::File; - return -ENOENT() unless -e ($file = fixup($file)); - my ($fsize) = -s $file; - return -ENOSYS() unless open($handle,$file); - if(seek($handle,$off,SEEK_SET)) { - read($handle,$rv,$bufsize); - } - return $rv; -} - -sub x_write { - my ($file,$buf,$off) = @_; - my ($rv); - return -ENOENT() unless -e ($file = fixup($file)); - my ($fsize) = -s $file; - return -ENOSYS() unless open(FILE,'+<',$file); - if($rv = seek(FILE,$off,SEEK_SET)) { - $rv = print(FILE $buf); - } - $rv = -ENOSYS() unless $rv; - close(FILE); - return length($buf); -} - -sub err { return (-shift || -$!) } - -sub x_readlink { return readlink(fixup(shift) ); } -sub x_unlink { return unlink(fixup(shift)) ? 0 : -$!; } -sub x_rmdir { return err(rmdir(fixup(shift)) ); } - -sub x_symlink { print "symlink\n"; return symlink(shift,fixup(shift)) ? 0 : -$!; } - -sub x_rename { - my ($old) = fixup(shift); - my ($new) = fixup(shift); - my ($err) = rename($old,$new) ? 0 : -ENOENT(); - return $err; -} -sub x_link { return link(fixup(shift),fixup(shift)) ? 0 : -$! } -sub x_chown { - my ($fn) = fixup(shift); - print "nonexistent $fn\n" unless -e $fn; - my ($uid,$gid) = @_; - # perl's chown() does not chown symlinks, it chowns the symlink's - # target. it fails when the link's target doesn't exist, because - # the stat64() syscall fails. - # this causes error messages when unpacking symlinks in tarballs. - my ($err) = syscall(&SYS_lchown,$fn,$uid,$gid,$fn) ? -$! : 0; - return $err; -} -sub x_chmod { - my ($fn) = fixup(shift); - my ($mode) = shift; - my ($err) = chmod($mode,$fn) ? 0 : -$!; - return $err; -} -sub x_truncate { return truncate(fixup(shift),shift) ? 0 : -$! ; } -sub x_utime { return utime($_[1],$_[2],fixup($_[0])) ? 0:-$!; } - -sub x_mkdir { my ($name, $perm) = @_; return 0 if mkdir(fixup($name),$perm); return -$!; } -sub x_rmdir { return 0 if rmdir fixup(shift); return -$!; } - -sub x_mknod { - # since this is called for ALL files, not just devices, I'll do some checks - # and possibly run the real mknod command. - my ($file, $modes, $dev) = @_; - $file = fixup($file); - $! = 0; - syscall(&SYS_mknod,$file,$modes,$dev); - return -$!; -} - -# kludge -sub x_statfs {return 255,1000000,500000,1000000,500000,4096} -my ($mountpoint) = ""; -$mountpoint = shift(@ARGV) if @ARGV; -Fuse::main( - mountpoint=>$mountpoint, - getattr=>\&x_getattr, - readlink=>\&x_readlink, - getdir=>\&x_getdir, - mknod=>\&x_mknod, - mkdir=>\&x_mkdir, - unlink=>\&x_unlink, - rmdir=>\&x_rmdir, - symlink=>\&x_symlink, - rename=>\&x_rename, - link=>\&x_link, - chmod=>\&x_chmod, - chown=>\&x_chown, - truncate=>\&x_truncate, - utime=>\&x_utime, - open=>\&x_open, - read=>\&x_read, - write=>\&x_write, - statfs=>\&x_statfs, -); diff --git a/perl/examples/rmount.pl b/perl/examples/rmount.pl deleted file mode 100755 index 9ae1cc1..0000000 --- a/perl/examples/rmount.pl +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/perl - -use strict; -use Net::SSH 'sshopen2'; -use IPC::Open2; -use Fuse; -use Data::Dumper; - -my ($host, $dir, $mount) = @ARGV; -if(!defined($mount)) { - $mount = $dir; - if($host =~ /^(.*):(.*)$/) { - ($host,$dir) = ($1,$2); - } else { - die "usage: $0 user\@host remotedir mountpoint\n". - "or : $0 user\@host:remotedir mountpoint\n"; - } -} - -`umount $mount` unless -d $mount; -die "mountpoint $mount isn't a directory!\n" unless -d $mount; - -my (%args) = (mountpoint => $mount); - -map { my ($str) = $_; $args{$str} = sub { netlink($str,@_) } } - qw(getattr getdir open read write readlink unlink rmdir - symlink rename link chown chmod truncate utime mkdir - rmdir mknod statfs); - -sub connect_remote { - sshopen2($host, *READER, *WRITER, "./rmount_remote.pl $dir") - or die "ssh: $!\n"; - select WRITER; - $| = 1; - select STDOUT; -} - -$SIG{CHLD} = sub { - use POSIX ":sys_wait_h"; - my $kid; - do { - $kid = waitpid(-1,WNOHANG); - } until $kid < 1; -}; - -connect_remote; - -sub netlink { - my ($str) = Dumper(\@_)."\n"; - $str = sprintf("%08i\n%s",length($str),$str); - while(1) { # retry as necessary - my ($sig) = $SIG{ALRM}; - my ($VAR1); - $VAR1 = undef; - eval { - $SIG{ALRM} = sub { die "timeout\n" }; - alarm 10; - print WRITER $str; - my ($len, $data); - if(read(READER,$len,9) == 9) { - read(READER,$data,$len-length($data),length($data)) - while(length($data) < $len); - eval $data; - } - }; - alarm 0; - $SIG{ALRM} = $sig; - if(defined $VAR1) { - return wantarray ? @{$VAR1} : $$VAR1[0]; - } - print STDERR "failed to send command; reconnecting ssh\n"; - close(READER); - close(WRITER); - connect_remote(); - } -} - -Fuse::main(%args); - -netlink("bye"); -close(READER); -close(WRITER); diff --git a/perl/examples/rmount_remote.pl b/perl/examples/rmount_remote.pl deleted file mode 100755 index e9e0866..0000000 --- a/perl/examples/rmount_remote.pl +++ /dev/null @@ -1,143 +0,0 @@ -#!/usr/bin/perl - -use strict; -use IO::File; -use POSIX qw(ENOENT ENOSYS EEXIST EPERM O_RDONLY O_RDWR O_APPEND O_CREAT); -use Fcntl qw(S_ISBLK S_ISCHR S_ISFIFO SEEK_SET); -use Data::Dumper; -require 'syscall.ph'; # for SYS_mknod and SYS_lchown - -my ($rootdir) = @ARGV; - -# strip leading and trailing slashes -$rootdir = $1 if($rootdir =~ /^\/?(.*)\/?$/); - -sub fixup { return "/$rootdir" . shift } - -sub x_getattr { - my ($file) = fixup(shift); - my (@list) = lstat($file); - return -$! unless @list; - return @list; -} - -sub x_getdir { - my ($dirname) = fixup(shift); - unless(opendir(DIRHANDLE,$dirname)) { - return -ENOENT(); - } - my (@files) = readdir(DIRHANDLE); - closedir(DIRHANDLE); - return (@files, 0); -} - -sub x_open { - my ($file) = fixup(shift); - my ($mode) = shift; - return -$! unless sysopen(FILE,$file,$mode); - close(FILE); - return 0; -} - -sub x_read { - my ($file,$bufsize,$off) = @_; - my ($rv) = -ENOSYS(); - my ($handle) = new IO::File; - return -ENOENT() unless -e ($file = fixup($file)); - my ($fsize) = -s $file; - return -ENOSYS() unless open($handle,$file); - if(seek($handle,$off,SEEK_SET)) { - read($handle,$rv,$bufsize); - } - return $rv; -} - -sub x_write { - my ($file,$buf,$off) = @_; - my ($rv); - return -ENOENT() unless -e ($file = fixup($file)); - my ($fsize) = -s $file; - return -ENOSYS() unless open(FILE,'+<',$file); - if($rv = seek(FILE,$off,SEEK_SET)) { - $rv = print(FILE $buf); - } - $rv = -ENOSYS() unless $rv; - close(FILE); - return length($buf); -} - -sub err { return (-shift || -$!) } - -sub x_readlink { return readlink(fixup(shift) ); } -sub x_unlink { return unlink(fixup(shift)) ? 0 : -$!; } -sub x_rmdir { return err(rmdir(fixup(shift)) ); } - -sub x_symlink { print "symlink\n"; return symlink(shift,fixup(shift)) ? 0 : -$!; } - -sub x_rename { - my ($old) = fixup(shift); - my ($new) = fixup(shift); - my ($err) = rename($old,$new) ? 0 : -ENOENT(); - return $err; -} -sub x_link { return link(fixup(shift),fixup(shift)) ? 0 : -$! } -sub x_chown { - my ($fn) = fixup(shift); - print "nonexistent $fn\n" unless -e $fn; - my ($uid,$gid) = @_; - # perl's chown() does not chown symlinks, it chowns the symlink's - # target. it fails when the link's target doesn't exist, because - # the stat64() syscall fails. - # this causes error messages when unpacking symlinks in tarballs. - my ($err) = syscall(&SYS_lchown,$fn,$uid,$gid,$fn) ? -$! : 0; - return $err; -} -sub x_chmod { - my ($fn) = fixup(shift); - my ($mode) = shift; - my ($err) = chmod($mode,$fn) ? 0 : -$!; - return $err; -} -sub x_truncate { return truncate(fixup(shift),shift) ? 0 : -$! ; } -sub x_utime { return utime($_[1],$_[2],fixup($_[0])) ? 0:-$!; } - -sub x_mkdir { my ($name, $perm) = @_; return 0 if mkdir(fixup($name),$perm); return -$!; } -sub x_rmdir { return 0 if rmdir fixup(shift); return -$!; } - -sub x_mknod { - # since this is called for ALL files, not just devices, I'll do some checks - # and possibly run the real mknod command. - my ($file, $modes, $dev) = @_; - $file = fixup($file); - $! = 0; - syscall(&SYS_mknod,$file,$modes,$dev); - return -$!; -} - -# kludge -sub x_statfs {return 255,1000000,500000,1000000,500000,4096} - -$| = 1; -my ($len); -while(read(STDIN,$len,9) == 9) { - chomp $len; - my ($data,$VAR1,@args); - eval { - $SIG{ALRM} = sub { die "timeout\n"}; - $data = ""; - alarm 5; - read(STDIN,$data,$len-length($data),length($data)) - while(length($data) < $len); - alarm 0; - }; - die $@ if $@; - eval $data; - @args = @{$VAR1}; - my $cmd = shift(@args); - exit 0 if $cmd eq "bye"; - die "cannot find command $cmd\n" unless exists($main::{"x_$cmd"}); - @args = $main::{"x_$cmd"}(@args); - $cmd = Dumper(\@args)."\n"; - $cmd = sprintf("%08i\n%s",length($cmd),$cmd); - print $cmd; -} diff --git a/perl/test.pl b/perl/test.pl deleted file mode 100644 index e8152fd..0000000 --- a/perl/test.pl +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/perl -BEGIN { $ENV{HARNESS_IGNORE_EXITCODE} = 1; } - -use Test::Harness qw(&runtests $verbose); -$verbose=0; -die "cannot find test directory!" unless -d "test"; -my (@files) = <test/*.t>; -runtests("test/s/mount.t",sort(@files),"test/s/umount.t"); diff --git a/perl/test/chmod.t b/perl/test/chmod.t deleted file mode 100644 index 366f89b..0000000 --- a/perl/test/chmod.t +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 4; -chdir($_point); -system("echo frog >file"); -ok(chmod(0644,"file"),"set unexecutable"); -ok(!-x "file","unexecutable"); -ok(chmod(0755,"file"),"set executable"); -ok(-x "file","executable"); -unlink("file"); diff --git a/perl/test/chown.t b/perl/test/chown.t deleted file mode 100644 index 8ccbb88..0000000 --- a/perl/test/chown.t +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 4; -my (@stat); -chdir($_point); -system("echo frog >file"); -ok(chown(0,0,"file"),"set 0,0"); -@stat = stat("file"); -ok($stat[4] == 0 && $stat[5] == 0,"0,0"); -ok(chown(1,1,"file"),"set 1,1"); -@stat = stat("file"); -ok($stat[4] == 1 && $stat[5] == 1,"1,1"); -unlink("file"); diff --git a/perl/test/getattr.t b/perl/test/getattr.t deleted file mode 100644 index 4203275..0000000 --- a/perl/test/getattr.t +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -use Data::Dumper; -plan tests => 28; -my ($a, $b) = ("$_real/wibble","$_point/wibble"); -`touch $b`; -is(-A "$a", -A "$b", '-A'); # 1 -is(-B "$a", -B "$b", '-B'); # 2 -is(-C "$a", -C "$b", '-C'); # 3 -is(-M "$a", -M "$b", '-M'); # 4 -is(-O "$a", -O "$b", '-O'); # 5 -is(-R "$a", -R "$b", '-R'); # 6 -is(-S "$a", -S "$b", '-S'); # 7 -is(-T "$a", -T "$b", '-T'); # 8 -is(-W "$a", -W "$b", '-W'); # 9 -is(-X "$a", -X "$b", '-X'); # 10 -is(-b "$a", -b "$b", '-b'); # 11 -is(-c "$a", -c "$b", '-c'); # 12 -is(-d "$a", -d "$b", '-d'); # 13 -is(-e "$a", -e "$b", '-e'); # 14 -is(-f "$a", -f "$b", '-f'); # 15 -is(-g "$a", -g "$b", '-g'); # 16 -is(-k "$a", -k "$b", '-k'); # 17 -is(-l "$a", -l "$b", '-l'); # 18 -is(-o "$a", -o "$b", '-o'); # 19 -is(-p "$a", -p "$b", '-p'); # 20 -is(-r "$a", -r "$b", '-r'); # 21 -is(-s "$a", -s "$b", '-s'); # 22 -is(-t "$a", -t "$b", '-t'); # 23 -is(-u "$a", -u "$b", '-u'); # 24 -is(-w "$a", -w "$b", '-w'); # 25 -is(-x "$a", -x "$b", '-x'); # 26 -is(-z "$a", -z "$b", '-z'); # 27 -my (@astat, @bstat); -@astat = stat("$a"); -@bstat = stat("$b"); -# dev and inode can legally change -shift(@astat); shift(@astat); -shift(@bstat); shift(@bstat); -is(join(" ",@astat),join(" ",@bstat),"stat()"); -`rm -f $a`; diff --git a/perl/test/getdir.t b/perl/test/getdir.t deleted file mode 100644 index 1d60561..0000000 --- a/perl/test/getdir.t +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -my (@names) = qw(abc def ghi jkl mno pqr stu jlk sfdaljk sdfakjlsdfa kjldsf kjl;sdf akjl;asdf klj;asdf lkjsdflkjsdfkjlsdfakjsdfakjlsadfkjl;asdfklj;asdfkjl;asdfklj;asdfkjl;asdfkjlasdflkj;sadf); -@names = sort(@names); -plan tests => 2 * scalar @names; -chdir($_real); - -# create entries -map { system("touch \"$_\"") } @names; - -# make sure they exist in real dir -opendir(REAL,$_real); -my (@ents) = readdir(REAL); -closedir(REAL); -@ents = sort(@ents); -map { - shift(@ents) while($ents[0] eq '.' || $ents[0] eq '..'); - is(shift(@ents),$_,"ent $_") -} @names; - -# make sure they exist in fuse dir -opendir(POINT,$_point); -@ents = readdir(POINT); -closedir(POINT); -@ents = sort(@ents); -map { - shift(@ents) while($ents[0] eq '.' || $ents[0] eq '..'); - is(shift(@ents),$_,"ent $_") -} @names; - -# remove them -map { unlink } @names; diff --git a/perl/test/helper.pm b/perl/test/helper.pm deleted file mode 100644 index cd2bd55..0000000 --- a/perl/test/helper.pm +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/perl -package test::helper; -use strict; -use Exporter; -our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); -@ISA = "Exporter"; -@EXPORT_OK = qw($_loop $_point $_pidfile $_real); -our($_loop, $_point, $_pidfile, $_real) = ("examples/loopback.pl","/mnt","test/s/mounted.pid","/tmp/fusetest"); -if($0 !~ qr|s/u?mount\.t$|) { - my ($reject) = 1; - if(-f $_pidfile) { - unless(system("ps `cat $_pidfile` | grep \"$_loop $_point\" >/dev/null")>>8) { - if(`mount | grep "on $_point"`) { - $reject = 0; - } else { - system("kill `cat $_pidfile`"); - } - } - } - $reject = 1 if (system("ls $_point >&/dev/null") >> 8); - die "not properly mounted\n" if $reject; -} -1; diff --git a/perl/test/link.t b/perl/test/link.t deleted file mode 100644 index 391b2f0..0000000 --- a/perl/test/link.t +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 8; -chdir($_point); -system("echo hippity >womble"); -ok(-f "womble","exists"); -ok(!-f "rabbit","target file doesn't exist"); -is(-s "womble",8,"right size"); -ok(link("womble","rabbit"),"link"); -ok(-f "womble","old file exists"); -ok(-f "rabbit","target file exists"); -is(-s "womble",8,"right size"); -is(-s "rabbit",8,"right size"); -unlink("womble"); -unlink("rabbit"); diff --git a/perl/test/mkdir.t b/perl/test/mkdir.t deleted file mode 100644 index 90ec6f3..0000000 --- a/perl/test/mkdir.t +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 3; -chdir($_point); -ok(mkdir("dir"),"mkdir"); -ok(-d "dir","dir exists"); -chdir($_real); -ok(-d "dir","dir really exists"); -chdir($_point); -rmdir("dir"); diff --git a/perl/test/mknod.t b/perl/test/mknod.t deleted file mode 100644 index 35c5c82..0000000 --- a/perl/test/mknod.t +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 24; -my (@stat); -chdir($_point); -ok(!(system("touch reg" )>>8),"create normal file"); -ok(!(system("mknod chr c 2 3")>>8),"create chrdev"); -ok(!(system("mknod blk b 2 3")>>8),"create blkdev"); -ok(!(system("mknod fifo p" )>>8),"create fifo"); -chdir($_real); -ok(-e "reg" ,"normal file exists"); -ok(-e "chr" ,"chrdev exists"); -ok(-e "blk" ,"blkdev exists"); -ok(-e "fifo","fifo exists"); -ok(-f "reg" ,"normal file is normal file"); -ok(-c "chr" ,"chrdev is chrdev"); -ok(-b "blk" ,"blkdev is blkdev"); -ok(-p "fifo","fifo is fifo"); -@stat = stat("chr"); -is($stat[6],3+(2<<8),"chrdev has right major,minor"); -@stat = stat("blk"); -is($stat[6],3+(2<<8),"blkdev has right major,minor"); -chdir($_point); -ok(-e "reg" ,"normal file exists"); -ok(-e "chr" ,"chrdev exists"); -ok(-e "blk" ,"blkdev exists"); -ok(-e "fifo","fifo exists"); -ok(-f "reg" ,"normal file is normal file"); -ok(-c "chr" ,"chrdev is chrdev"); -ok(-b "blk" ,"blkdev is blkdev"); -ok(-p "fifo","fifo is fifo"); -@stat = stat("chr"); -is($stat[6],3+(2<<8),"chrdev has right major,minor"); -@stat = stat("blk"); -is($stat[6],3+(2<<8),"blkdev has right major,minor"); -map { unlink } qw(reg chr blk fifo); diff --git a/perl/test/open.t b/perl/test/open.t deleted file mode 100644 index 030dc1f..0000000 --- a/perl/test/open.t +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 1; -chdir($_real); -system("echo frog >file"); -chdir($_point); -ok(open(FILE,"file"),"open"); -close(FILE); -unlink("file"); diff --git a/perl/test/read.t b/perl/test/read.t deleted file mode 100644 index 5eca920..0000000 --- a/perl/test/read.t +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 3; -chdir($_real); -system("echo frog >file"); -chdir($_point); -ok(open(FILE,"file"),"open"); -my ($data) = <FILE>; -close(FILE); -is(length($data),5,"right amount read"); -is($data,"frog\n","right data read"); -unlink("file"); diff --git a/perl/test/readlink.t b/perl/test/readlink.t deleted file mode 100644 index 85b9ffc..0000000 --- a/perl/test/readlink.t +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_point $_real); -use Test::More; -plan tests => 4; -chdir($_real); -ok(symlink("abc","def"),"OS supports symlinks"); -is(readlink("def"),"abc","OS supports symlinks"); -chdir($_point); -ok(-l "def","symlink exists"); -is(readlink("def"),"abc","readlink"); -unlink("def"); diff --git a/perl/test/rename.t b/perl/test/rename.t deleted file mode 100644 index 9fbb330..0000000 --- a/perl/test/rename.t +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 5; -chdir($_point); -system("echo hippity >frog"); -ok(-f "frog","exists"); -ok(!-f "toad","target file doesn't exist"); -ok(rename("frog","toad"),"rename"); -ok(!-f "frog","old file doesn't exist"); -ok(-f "toad","target file exists"); -unlink("toad"); diff --git a/perl/test/rmdir.t b/perl/test/rmdir.t deleted file mode 100644 index 36f0378..0000000 --- a/perl/test/rmdir.t +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 5; -chdir($_real); -ok(mkdir("dir"),"mkdir"); -ok(-d "dir","dir really exists"); -chdir($_point); -ok(-d "dir","dir exists"); -rmdir("dir"); -ok(! -d "dir","dir removed"); -chdir($_real); -ok(! -d "dir","dir really removed"); diff --git a/perl/test/s/mount.t b/perl/test/s/mount.t deleted file mode 100644 index 26f6fc2..0000000 --- a/perl/test/s/mount.t +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/perl -w -use test::helper qw($_point $_loop $_real $_pidfile); -use strict; -use Test::More tests => 3; -ok(!(scalar grep(/ on $_point /,`cat /proc/mounts`)),"already mounted"); -ok(-f $_loop,"loopback exists"); - -if(!fork()) { - #close(STDIN); - close(STDOUT); - close(STDERR); - `echo $$ >test/s/mounted.pid`; - exec("perl $_loop $_point"); - exit(1); -} -select(undef, undef, undef, 0.5); -my ($success) = `cat /proc/mounts` =~ / $_point /; -ok($success,"mount succeeded"); -system("rm -rf $_real"); -unless($success) { - kill('INT',`cat $_pidfile`); - unlink($_pidfile); -} else { - mkdir($_real); -} diff --git a/perl/test/s/umount.t b/perl/test/s/umount.t deleted file mode 100644 index da60677..0000000 --- a/perl/test/s/umount.t +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_point $_real $_pidfile); -use strict; -use Test::More tests => 1; -system("umount $_point"); -ok(1,"unmount"); -system("rm -rf $_real $_pidfile"); diff --git a/perl/test/statfs.t b/perl/test/statfs.t deleted file mode 100644 index fb94704..0000000 --- a/perl/test/statfs.t +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -require 'syscall.ph'; # for SYS_statfs -plan tests => 7; -my ($statfs_data) = " " x 10; -my ($tmp) = $_point; -ok(!syscall(&SYS_statfs,$tmp,$statfs_data),"statfs"); -# FIXME: this is soooooo linux-centric. perhaps parse the output of /bin/df? -my @list = unpack("LSSL8",$statfs_data); -shift(@list); -is(shift(@list),4096,"block size"); -shift(@list); -is(shift(@list),1000000,"blocks"); -is(shift(@list),500000,"blocks free"); -shift(@list); -is(shift(@list),1000000,"files"); -is(shift(@list),500000,"files free"); -shift(@list); -shift(@list); -is(shift(@list),255,"namelen"); diff --git a/perl/test/symlink.t b/perl/test/symlink.t deleted file mode 100644 index 19cc72d..0000000 --- a/perl/test/symlink.t +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_point $_real); -use Test::More; -plan tests => 6; -chdir($_point); -ok(symlink("abc","def"),"symlink created"); -ok(-l "def","symlink exists"); -is(readlink("def"),"abc","it worked"); -chdir($_real); -ok(-l "def","symlink really exists"); -is(readlink("def"),"abc","really worked"); -unlink("def"); - -# bug: doing a 'cp -a' on a directory which contains a symlink -# reports an error -mkdir("dira"); -system("cd dira; touch filea; ln -s filea fileb"); -is(system("cp -a dira dirb")>>8,0,"cp -a"); -system("rm -rf dira dirb"); diff --git a/perl/test/test-template b/perl/test/test-template deleted file mode 100644 index ef57e08..0000000 --- a/perl/test/test-template +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 1; -ok(1); diff --git a/perl/test/truncate.t b/perl/test/truncate.t deleted file mode 100644 index 8607421..0000000 --- a/perl/test/truncate.t +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 5; -chdir($_point); -system("echo hippity >womble"); -ok(-f "womble","exists"); -is(-s "womble",8,"right size"); -ok(truncate("womble",4),"truncate"); -ok(-f "womble","file exists"); -is(-s "womble",4,"right size"); -unlink("womble"); diff --git a/perl/test/unlink.t b/perl/test/unlink.t deleted file mode 100644 index eef8c1a..0000000 --- a/perl/test/unlink.t +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 4; -chdir($_point); -system("touch file"); -ok(-f "file","file exists"); -chdir($_real); -ok(-f "file","file really exists"); -chdir($_point); -unlink("file"); -ok(! -f "file","file unlinked"); -chdir($_real); -ok(! -f "file","file really unlinked"); diff --git a/perl/test/utime.t b/perl/test/utime.t deleted file mode 100644 index 8ccefc6..0000000 --- a/perl/test/utime.t +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 3; -my (@stat); -chdir($_real); -system("echo frog >file"); -chdir($_point); -ok(utime(1,2,"file"),"set utime"); -@stat = stat("file"); -is($stat[8],1,"atime"); -is($stat[9],2,"mtime"); -unlink("file"); diff --git a/perl/test/write.t b/perl/test/write.t deleted file mode 100644 index 58af2aa..0000000 --- a/perl/test/write.t +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/perl -use test::helper qw($_real $_point); -use Test::More; -plan tests => 15; -my ($data); -chdir($_point); -undef $/; # slurp it all -# create file -system("echo frogbing >writefile"); - -# fetch contents of file -ok(open(FILE,"writefile"),"open"); -$data = <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 --git a/python/ChangeLog b/python/ChangeLog deleted file mode 100644 index f422b2a..0000000 --- a/python/ChangeLog +++ /dev/null @@ -1,6 +0,0 @@ -2004-09-27 Miklos Szeredi <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 --git a/python/INSTALL b/python/INSTALL deleted file mode 100644 index 917c1c0..0000000 --- a/python/INSTALL +++ /dev/null @@ -1,8 +0,0 @@ -The best way to install this python FUSE module is: - 1. make sure the rest of FUSE (incl libfuse.a) has built successfully - 2. type 'python setup.py build' - 3. if all has gone ok, become root and type 'python setup.py install' - -That way, the FUSE python modules will be built against the correct version -of python and installed in your system-wide python directory. This will allow -your filesystem script to find them, no matter where it's residing. diff --git a/python/Makefile b/python/Makefile deleted file mode 100644 index 1313e9e..0000000 --- a/python/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -#@+leo-ver=4 -#@+node:@file Makefile -# Makefile now uses distutils - -_fusemodule.so: _fusemodule.c - #gcc -g3 -I/usr/include/python2.1 _fusemodule.c -Wl,-shared -o _fusemodule.so -Wimplicit -lfuse && python -c 'import _fuse' - python setup.py build_ext --inplace - -install: _fusemodule.so - python setup.py install - -clean: - rm -rf _fusemodule.so *.pyc *.pyo *~ build -#@-node:@file Makefile -#@-leo diff --git a/python/README b/python/README deleted file mode 100644 index 2a3af2b..0000000 --- a/python/README +++ /dev/null @@ -1,92 +0,0 @@ -#@+leo-ver=4 -#@+node:@file README -#@@language - -Refer to the INSTALL file for build/install instructions - -General Information -=================== - -This is a Python[1] interface to FUSE[2]. - -FUSE (Filesystem in USErspace) is a simple interface for userspace -programs to export a virtual filesystem to the linux kernel. FUSE -also aims to provide a secure method for non privileged users to -create and mount their own filesystem implementations. - -When run from the commandline, "fuse.py" simply reexports the root -filesystem within the mount point as example/fusexmp does in the main -FUSE distribution. It also offers a class, fuse.Fuse, which can be -subclassed to create a filesystem. fuse.Xmp is the example filesystem -implementation. - -In your subclass of fuse, add attributes with the expected names -("getattr", "readlink", etc) and call signatures (refer to fuse.Xmp) -then call main(). Make it runnable as a #! script, and mount with - fusermount <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 --git a/python/_fusemodule.c b/python/_fusemodule.c deleted file mode 100644 index fba65b4..0000000 --- a/python/_fusemodule.c +++ /dev/null @@ -1,552 +0,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 --git a/python/code.leo b/python/code.leo deleted file mode 100644 index 8ff723e..0000000 --- a/python/code.leo +++ /dev/null @@ -1,1120 +0,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><< fuse declarations >></vh></v> -<v t="davidmcnab.121403050157.2" a="E"><vh>class ErrnoWrapper</vh> -<v t="davidmcnab.121403050157.3"><vh><< class ErrnoWrapper declarations >></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><< class Fuse declarations >></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 <jepler@unpythonic.dhs.org> - - This program can be distributed under the terms of the GNU GPL. - See the file COPYING. -*/ - -@others - -</t> -<t tx="davidmcnab.121303142957.2">#include <Python.h> -#include <fuse.h> -#include <time.h> -</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) < 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 -} - -</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 < 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->actime : time(NULL); - int modtime = u ? u->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) > 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()->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(&op, 0, sizeof(op)); - - if (!PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOOOOOOOOOOOOOOOii", - 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, - &flags, &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, &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 <jepler@unpythonic.dhs.org> -# -# 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 > 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) -</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 && 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 <jepler@unpythonic.dhs.org> -# -# 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 <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/ -</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 < 3 or sys.argv[3] != "-o": - usage(1) - - dev = sys.argv[1] - mountpoint = sys.argv[2] - - # grab options, if any - optdict = {} - optlist = [] - if argc > 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) < 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->block_size = retvalues[0]; - fst->blocks = retvalues[1]; - fst->blocks_free = retvalues[2]; - fst->files = retvalues[3]; - fst->files_free = retvalues[4]; - fst->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 -<< fuse declarations >> -@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 <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, DEBUG -import os, sys -from errno import * - -#@-node:imports -#@+node:class ErrnoWrapper -</t> -<t tx="davidmcnab.121403050157.2">class ErrnoWrapper: - << class ErrnoWrapper declarations >> - @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: - << class Fuse declarations >> - @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 > 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) -</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 --git a/python/fuse.py b/python/fuse.py deleted file mode 100644 index ece9686..0000000 --- a/python/fuse.py +++ /dev/null @@ -1,121 +0,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 --git a/python/setup.py b/python/setup.py deleted file mode 100644 index beb5c53..0000000 --- a/python/setup.py +++ /dev/null @@ -1,21 +0,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 --git a/python/xmp.py b/python/xmp.py deleted file mode 100755 index 946bca8..0000000 --- a/python/xmp.py +++ /dev/null @@ -1,187 +0,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 |