incomplete support for filtering directories by whether they actually have contents
[id3fs.git] / lib / ID3FS / Fuse.pm
index de81df9..f24f680 100644 (file)
@@ -4,9 +4,9 @@ use strict;
 use warnings;
 use ID3FS::Path;
 use Fuse;
+use Cwd;
 use POSIX qw(EINVAL EROFS ENOENT EOPNOTSUPP S_IRUSR S_IRGRP S_IROTH S_IXUSR S_IXGRP S_IXOTH);
-use vars qw($TYPE_DIR $TYPE_SYMLINK);
-($TYPE_DIR, $TYPE_SYMLINK)=(0040, 0120);
+our ($TYPE_DIR, $TYPE_SYMLINK)=(0040, 0120);
 
 sub new
 {
@@ -17,7 +17,7 @@ sub new
 
     $self->{db}=shift;
     $self->{source}=shift;
-    $self->{mountpoint}=shift;
+    $self->{mountpoint}=Cwd::abs_path(shift);
     $self->{debug}=shift;
     $self->{perms} = S_IRUSR() | S_IXUSR() | S_IRGRP() | S_IXGRP() | S_IROTH() | S_IXOTH();
 
@@ -35,27 +35,28 @@ sub run
        getattr     => sub { $self->getattr(@_); },
        readlink    => sub { $self->readlink(@_); },
        getdir      => sub { $self->getdir(@_); },
+
        # Not used
-#      mknod       => sub { $self->mknod(@_); },
-#      mkdir       => sub { $self->mkdir(@_); },
-#      unlink      => sub { $self->unlink(@_); },
-#      rmdir       => sub { $self->rmdir(@_); },
-#      symlink     => sub { $self->symlink(@_); },
-#      rename      => sub { $self->rename(@_); },
-#      link        => sub { $self->link(@_); },
-#      chmod       => sub { $self->chmod(@_); },
-#      chown       => sub { $self->chown(@_); },
-#      truncate    => sub { $self->truncate(@_); },
-#      utime       => sub { $self->utime(@_); },
-#      open        => sub { $self->open(@_); },
-#      read        => sub { $self->read(@_); },
-#      write       => sub { $self->write(@_); },
-#      statfs      => sub { $self->statfs(@_); },
-#      release     => sub { $self->release(@_); },
-#      fsync       => sub { $self->fsync(@_); },
-#      setxattr    => sub { $self->setxattr(@_); },
-#      getxattr    => sub { $self->getxattr(@_); },
-#      listxattr   => sub { $self->listxattr(@_); },
+#      mknod       => sub { $self->mknod(@_);       },
+#      mkdir       => sub { $self->mkdir(@_);       },
+#      unlink      => sub { $self->unlink(@_);      },
+#      rmdir       => sub { $self->rmdir(@_);       },
+#      symlink     => sub { $self->symlink(@_);     },
+#      rename      => sub { $self->rename(@_);      },
+#      link        => sub { $self->link(@_);        },
+#      chmod       => sub { $self->chmod(@_);       },
+#      chown       => sub { $self->chown(@_);       },
+#      truncate    => sub { $self->truncate(@_);    },
+#      utime       => sub { $self->utime(@_);       },
+#      open        => sub { $self->open(@_);        },
+#      read        => sub { $self->read(@_);        },
+#      write       => sub { $self->write(@_);       },
+#      statfs      => sub { $self->statfs(@_);      },
+#      release     => sub { $self->release(@_);     },
+#      fsync       => sub { $self->fsync(@_);       },
+#      setxattr    => sub { $self->setxattr(@_);    },
+#      getxattr    => sub { $self->getxattr(@_);    },
+#      listxattr   => sub { $self->listxattr(@_);   },
 #      removexattr => sub { $self->removexattr(@_); },
        );
 }
@@ -63,64 +64,82 @@ sub run
 sub getattr
 {
     my($self, $filename)=@_;
-    print "**GETATTR: $filename\n";
+#    print "**GETATTR: $filename\n";
     my $path=ID3FS::Path->new($self->{db}, $filename);
+    my $last_update=$self->{db}->last_update();
     return(-ENOENT()) unless($path->isvalid());
     my($dev,$ino,$nlink)=(0,0,1);
     my $uid=$<;
     my $gid=(split(/ /, $( ))[0];
     my($rdev,$size)=(0,1);
-    my($atime,$mtime,$ctime)=(0,0,0);
+    my($atime,$mtime,$ctime)=($last_update) x 3;
     my($blksize,$blocks)=(512,1);
     my $mode=$self->mode( $path->isdir() ? $TYPE_DIR : $TYPE_SYMLINK );
-    return($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
-          $atime,$mtime,$ctime,$blksize,$blocks);
+    return($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
+          $atime, $mtime, $ctime, $blksize, $blocks);
 }
 
 sub readlink
 {
     my($self,$filename)=@_;
-    print "**READLINK: $filename\n";
+#    print "**READLINK: $filename\n";
     my $path=ID3FS::Path->new($self->{db}, $filename);
-    return(-EINVAL()) if($path->isdir());
-    return $path->dest();
+    return(-EINVAL()) unless($path->isfile());
+    return $path->dest($self->{mountpoint});
 }
 
 sub getdir
 {
     my($self, $filename)=@_;
-    print "**GETDIR: $filename\n";
+#    print "**GETDIR: $filename\n";
     my $path=ID3FS::Path->new($self->{db}, $filename);
     return(-ENOENT()) unless($path->isvalid());
-    if($path->isdir())
-    {
-       return(".", "..", $path->dirents(), 0);
-    }
-    return -ENOTDIR();
+    return(-ENOTDIR()) unless($path->isdir());
+    my @dents=(".", "..");
+    my($dirs, $files)=$path->dirents();
+    push(@dents, grep { $self->hascontents($filename, $_); } @$dirs);
+    push(@dents, @$files);
+    return(@dents, 0);
+}
+
+sub hascontents
+{
+    return 1;
+    # FIXME
+    my($self, $base, $dir)=@_;
+    print "hascontents: $base / $dir\n";
+    my $path=ID3FS::Path->new($self->{db}, "$base/$dir");
+    print "VALID: ", $path->isvalid(), "\n";
+    return 1 unless($path->isvalid());
+    my($subdirs,$subfiles)=$path->dirents();
+    print "SUBDIRS: ", join(", ", @$subdirs), "\n";
+    print "SUBFILES: ", join(", ", @$subfiles), "\n";
+    return 1 if(@$subdirs || @$subfiles);
+    return 0;
 }
 
 # unused stubs
-sub mknod       { print "mknod\n"; return -EROFS();            }
-sub mkdir       { print "mkdir\n"; return -EROFS();            }
-sub unlink      { print "unlink\n"; return -EROFS();           }
-sub rmdir       { print "rmdir\n"; return -EROFS();            }
-sub symlink     { print "symlink\n"; return -EROFS();          }
-sub rename      { print "rename\n"; return -EROFS();           }
-sub link        { print "link\n"; return -EROFS();             }
-sub chmod       { print "chmod\n"; return -EROFS();            }
-sub chown       { print "chown\n"; return -EROFS();            }
-sub truncate    { print "truncate\n"; return -EROFS();         }
-sub utime       { print "utime\n"; return -EINVAL();           }
-sub open        { print "open\n"; return -EINVAL();            }
-sub read        { print "read\n"; return -EINVAL();            }
-sub write       { print "write\n"; return -EROFS();            }
-sub statfs      { print "statfs\n"; return -EINVAL();          }
-sub release     { print "release\n"; return 0;                 }
-sub fsync       { print "fsync\n"; return 0;                   }
-sub setxattr    { print "setxattr\n"; return -EOPNOTSUPP();    }
-sub getxattr    { print "getxattr\n"; return -EOPNOTSUPP();    }
-sub listxattr   { print "listxattr\n"; return -EOPNOTSUPP();   }
-sub removexattr { print "removexattr\n"; return -EOPNOTSUPP(); }
+sub mknod       { print "FUSE: mknod\n";       return -EROFS();      }
+sub mkdir       { print "FUSE: mkdir\n";       return -EROFS();      }
+sub unlink      { print "FUSE: unlink\n";      return -EROFS();      }
+sub rmdir       { print "FUSE: rmdir\n";       return -EROFS();      }
+sub symlink     { print "FUSE: symlink\n";     return -EROFS();      }
+sub rename      { print "FUSE: rename\n";      return -EROFS();      }
+sub link        { print "FUSE: link\n";        return -EROFS();      }
+sub chmod       { print "FUSE: chmod\n";       return -EROFS();      }
+sub chown       { print "FUSE: chown\n";       return -EROFS();      }
+sub truncate    { print "FUSE: truncate\n";    return -EROFS();      }
+sub utime       { print "FUSE: utime\n";       return -EINVAL();     }
+sub open        { print "FUSE: open\n";        return -EINVAL();     }
+sub read        { print "FUSE: read\n";        return -EINVAL();     }
+sub write       { print "FUSE: write\n";       return -EROFS();      }
+sub statfs      { print "FUSE: statfs\n";      return -EINVAL();     }
+sub release     { print "FUSE: release\n";     return 0;             }
+sub fsync       { print "FUSE: fsync\n";       return 0;             }
+sub setxattr    { print "FUSE: setxattr\n";    return -EOPNOTSUPP(); }
+sub getxattr    { print "FUSE: getxattr\n";    return -EOPNOTSUPP(); }
+sub listxattr   { print "FUSE: listxattr\n";   return -EOPNOTSUPP(); }
+sub removexattr { print "FUSE: removexattr\n"; return -EOPNOTSUPP(); }
 
 sub mode
 {
@@ -128,6 +147,4 @@ sub mode
     return(($type << 9) | $self->{perms});
 }
 
-
-
 1;