1 # id3fs - a FUSE-based filesystem for browsing audio metadata
2 # Copyright (C) 2010 Ian Beckwith <ianb@erislabs.net>
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 use POSIX qw(EINVAL EROFS ENOENT EOPNOTSUPP S_IRUSR S_IRGRP S_IROTH S_IXUSR S_IXGRP S_IXOTH);
26 our ($TYPE_DIR, $TYPE_SYMLINK)=(0040, 0120);
27 our $DEFAULT_MAXTAGDEPTH = 10;
31 my $class=ref($proto) || $proto;
36 $self->{source}=shift;
37 $self->{mountpoint}=Cwd::abs_path(shift);
38 $self->{verbose}=shift;
39 $self->{tagdepth}=shift;
40 $self->{tagdepth}=$DEFAULT_MAXTAGDEPTH unless($self->{tagdepth});
41 $self->{perms} = S_IRUSR() | S_IXUSR() | S_IRGRP() | S_IXGRP() | S_IROTH() | S_IXOTH();
50 mountpoint => $self->{mountpoint},
52 debug => ($self->{verbose} > 1),
53 mountopts => "allow_other,ro",
54 getattr => sub { $self->getattr(@_); },
55 readlink => sub { $self->readlink(@_); },
56 getdir => sub { $self->getdir(@_); },
59 # mknod => sub { $self->mknod(@_); },
60 # mkdir => sub { $self->mkdir(@_); },
61 # unlink => sub { $self->unlink(@_); },
62 # rmdir => sub { $self->rmdir(@_); },
63 # symlink => sub { $self->symlink(@_); },
64 # rename => sub { $self->rename(@_); },
65 # link => sub { $self->link(@_); },
66 # chmod => sub { $self->chmod(@_); },
67 # chown => sub { $self->chown(@_); },
68 # truncate => sub { $self->truncate(@_); },
69 # utime => sub { $self->utime(@_); },
70 # open => sub { $self->open(@_); },
71 # read => sub { $self->read(@_); },
72 # write => sub { $self->write(@_); },
73 # statfs => sub { $self->statfs(@_); },
74 # release => sub { $self->release(@_); },
75 # fsync => sub { $self->fsync(@_); },
76 # setxattr => sub { $self->setxattr(@_); },
77 # getxattr => sub { $self->getxattr(@_); },
78 # listxattr => sub { $self->listxattr(@_); },
79 # removexattr => sub { $self->removexattr(@_); },
85 my($self, $filename)=@_;
86 # print "**GETATTR: $filename\n";
87 my $path=ID3FS::Path->new($self->{db}, $filename, $self->{verbose}, $self->{tagdepth});
88 my $last_update=$self->{db}->last_update();
89 return(-ENOENT()) unless($path->isvalid());
90 my($dev,$ino,$nlink)=(0,0,1);
92 my $gid=(split(/ /, $( ))[0];
93 my($rdev,$size)=(0,1);
94 my($atime,$mtime,$ctime)=($last_update) x 3;
95 my($blksize,$blocks)=(512,1);
96 my $mode=$self->mode( $path->isdir() ? $TYPE_DIR : $TYPE_SYMLINK );
97 return($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
98 $atime, $mtime, $ctime, $blksize, $blocks);
103 my($self,$filename)=@_;
104 # print "**READLINK: $filename\n";
105 my $path=ID3FS::Path->new($self->{db}, $filename, $self->{verbose}, $self->{tagdepth});
106 return(-EINVAL()) unless($path->isfile());
107 return $path->dest($self->{mountpoint});
112 my($self, $filename)=@_;
113 # print "**GETDIR: $filename\n";
114 my $path=ID3FS::Path->new($self->{db}, $filename, $self->{verbose}, $self->{tagdepth});
115 return(-ENOENT()) unless($path->isvalid());
116 return(-ENOTDIR()) unless($path->isdir());
118 my($dirs, $files)=$path->dirents();
120 # push(@dents, $path->filter(@$dirs));
121 push(@dents, @$dirs);
122 push(@dents, @$files);
125 return( (".", "..", @dents, 0) );
131 sub mknod { print "FUSE: mknod\n"; return -EROFS(); }
132 sub mkdir { print "FUSE: mkdir\n"; return -EROFS(); }
133 sub unlink { print "FUSE: unlink\n"; return -EROFS(); }
134 sub rmdir { print "FUSE: rmdir\n"; return -EROFS(); }
135 sub symlink { print "FUSE: symlink\n"; return -EROFS(); }
136 sub rename { print "FUSE: rename\n"; return -EROFS(); }
137 sub link { print "FUSE: link\n"; return -EROFS(); }
138 sub chmod { print "FUSE: chmod\n"; return -EROFS(); }
139 sub chown { print "FUSE: chown\n"; return -EROFS(); }
140 sub truncate { print "FUSE: truncate\n"; return -EROFS(); }
141 sub utime { print "FUSE: utime\n"; return -EINVAL(); }
142 sub open { print "FUSE: open\n"; return -EINVAL(); }
143 sub read { print "FUSE: read\n"; return -EINVAL(); }
144 sub write { print "FUSE: write\n"; return -EROFS(); }
145 sub statfs { print "FUSE: statfs\n"; return -EINVAL(); }
146 sub release { print "FUSE: release\n"; return 0; }
147 sub fsync { print "FUSE: fsync\n"; return 0; }
148 sub setxattr { print "FUSE: setxattr\n"; return -EOPNOTSUPP(); }
149 sub getxattr { print "FUSE: getxattr\n"; return -EOPNOTSUPP(); }
150 sub listxattr { print "FUSE: listxattr\n"; return -EOPNOTSUPP(); }
151 sub removexattr { print "FUSE: removexattr\n"; return -EOPNOTSUPP(); }
156 return(($type << 9) | $self->{perms});