2013-07-05 17:41:07 +00:00
// +build linux darwin
2012-04-29 04:29:51 +00:00
/ *
Copyright 2012 Google Inc .
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
package fs
import (
"log"
"os"
2013-02-08 06:43:50 +00:00
"sync"
2012-04-29 04:29:51 +00:00
2016-04-07 19:19:05 +00:00
"bazil.org/fuse"
"bazil.org/fuse/fs"
2016-04-22 04:34:24 +00:00
"camlistore.org/pkg/blob"
2016-04-07 19:19:05 +00:00
"golang.org/x/net/context"
2012-04-29 04:29:51 +00:00
)
// root implements fuse.Node and is the typical root of a
// CamliFilesystem with a little hello message and the ability to
// search and browse static snapshots, etc.
type root struct {
fs * CamliFileSystem
2013-02-08 06:43:50 +00:00
mu sync . Mutex // guards recent
recent * recentDir
2013-07-10 11:10:48 +00:00
roots * rootsDir
2013-12-21 22:22:26 +00:00
atDir * atDir
2012-04-29 04:29:51 +00:00
}
2016-04-07 19:19:05 +00:00
var (
_ fs . Node = ( * root ) ( nil )
_ fs . HandleReadDirAller = ( * root ) ( nil )
_ fs . NodeStringLookuper = ( * root ) ( nil )
)
func ( n * root ) Attr ( ctx context . Context , a * fuse . Attr ) error {
a . Mode = os . ModeDir | 0700
a . Uid = uint32 ( os . Getuid ( ) )
a . Gid = uint32 ( os . Getgid ( ) )
return nil
2012-04-29 04:29:51 +00:00
}
2016-04-07 19:19:05 +00:00
func ( n * root ) ReadDirAll ( ctx context . Context ) ( [ ] fuse . Dirent , error ) {
2012-04-29 04:29:51 +00:00
return [ ] fuse . Dirent {
{ Name : "WELCOME.txt" } ,
{ Name : "tag" } ,
{ Name : "date" } ,
2013-02-07 05:47:01 +00:00
{ Name : "recent" } ,
2013-07-10 11:10:48 +00:00
{ Name : "roots" } ,
2013-12-21 22:22:26 +00:00
{ Name : "at" } ,
2012-04-30 09:43:06 +00:00
{ Name : "sha1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" } ,
2012-04-29 04:29:51 +00:00
} , nil
}
2013-02-08 06:43:50 +00:00
func ( n * root ) getRecentDir ( ) * recentDir {
n . mu . Lock ( )
defer n . mu . Unlock ( )
if n . recent == nil {
n . recent = & recentDir { fs : n . fs }
}
return n . recent
}
2013-07-10 11:10:48 +00:00
func ( n * root ) getRootsDir ( ) * rootsDir {
n . mu . Lock ( )
defer n . mu . Unlock ( )
if n . roots == nil {
n . roots = & rootsDir { fs : n . fs }
}
return n . roots
}
2013-12-21 22:22:26 +00:00
func ( n * root ) getAtDir ( ) * atDir {
n . mu . Lock ( )
defer n . mu . Unlock ( )
if n . atDir == nil {
n . atDir = & atDir { fs : n . fs }
}
return n . atDir
}
2016-04-07 19:19:05 +00:00
func ( n * root ) Lookup ( ctx context . Context , name string ) ( fs . Node , error ) {
log . Printf ( "root.Lookup(%s)" , name )
2012-04-30 09:43:06 +00:00
switch name {
case ".quitquitquit" :
2012-04-29 04:29:51 +00:00
log . Fatalf ( "Shutting down due to root .quitquitquit lookup." )
2012-04-30 09:43:06 +00:00
case "WELCOME.txt" :
return staticFileNode ( "Welcome to CamlistoreFS.\n\nFor now you can only cd into a sha1-xxxx directory, if you know the blobref of a directory or a file.\n" ) , nil
2013-02-07 05:57:07 +00:00
case "recent" :
2013-02-08 06:43:50 +00:00
return n . getRecentDir ( ) , nil
2012-04-30 09:43:06 +00:00
case "tag" , "date" :
return notImplementDirNode { } , nil
2013-12-21 22:22:26 +00:00
case "at" :
return n . getAtDir ( ) , nil
2013-07-10 11:10:48 +00:00
case "roots" :
return n . getRootsDir ( ) , nil
2012-04-30 09:43:06 +00:00
case "sha1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" :
return notImplementDirNode { } , nil
2013-07-22 04:13:16 +00:00
case ".camli_fs_stats" :
return statsDir { } , nil
2013-07-11 09:21:59 +00:00
case "mach_kernel" , ".hidden" , "._." :
2013-07-22 04:13:16 +00:00
// Just quiet some log noise on OS X.
2013-07-11 09:21:59 +00:00
return nil , fuse . ENOENT
2012-04-29 04:29:51 +00:00
}
2013-08-04 02:54:30 +00:00
if br , ok := blob . Parse ( name ) ; ok {
log . Printf ( "Root lookup of blobref. %q => %v" , name , br )
2012-04-29 04:29:51 +00:00
return & node { fs : n . fs , blobref : br } , nil
}
2013-08-04 02:54:30 +00:00
log . Printf ( "Bogus root lookup of %q" , name )
2012-04-29 04:29:51 +00:00
return nil , fuse . ENOENT
}