github.com/slspeek/camlistore_namedsearch@v0.0.0-20140519202248-ed6f70f7721a/pkg/fs/root.go (about) 1 // +build linux darwin 2 3 /* 4 Copyright 2012 Google Inc. 5 6 Licensed under the Apache License, Version 2.0 (the "License"); 7 you may not use this file except in compliance with the License. 8 You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12 Unless required by applicable law or agreed to in writing, software 13 distributed under the License is distributed on an "AS IS" BASIS, 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 See the License for the specific language governing permissions and 16 limitations under the License. 17 */ 18 19 package fs 20 21 import ( 22 "log" 23 "os" 24 "sync" 25 26 "camlistore.org/pkg/blob" 27 28 "camlistore.org/third_party/bazil.org/fuse" 29 "camlistore.org/third_party/bazil.org/fuse/fs" 30 ) 31 32 // root implements fuse.Node and is the typical root of a 33 // CamliFilesystem with a little hello message and the ability to 34 // search and browse static snapshots, etc. 35 type root struct { 36 noXattr 37 fs *CamliFileSystem 38 39 mu sync.Mutex // guards recent 40 recent *recentDir 41 roots *rootsDir 42 atDir *atDir 43 } 44 45 func (n *root) Attr() fuse.Attr { 46 return fuse.Attr{ 47 Mode: os.ModeDir | 0700, 48 Uid: uint32(os.Getuid()), 49 Gid: uint32(os.Getgid()), 50 } 51 } 52 53 func (n *root) ReadDir(intr fs.Intr) ([]fuse.Dirent, fuse.Error) { 54 return []fuse.Dirent{ 55 {Name: "WELCOME.txt"}, 56 {Name: "tag"}, 57 {Name: "date"}, 58 {Name: "recent"}, 59 {Name: "roots"}, 60 {Name: "at"}, 61 {Name: "sha1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}, 62 }, nil 63 } 64 65 func (n *root) getRecentDir() *recentDir { 66 n.mu.Lock() 67 defer n.mu.Unlock() 68 if n.recent == nil { 69 n.recent = &recentDir{fs: n.fs} 70 } 71 return n.recent 72 } 73 74 func (n *root) getRootsDir() *rootsDir { 75 n.mu.Lock() 76 defer n.mu.Unlock() 77 if n.roots == nil { 78 n.roots = &rootsDir{fs: n.fs} 79 } 80 return n.roots 81 } 82 83 func (n *root) getAtDir() *atDir { 84 n.mu.Lock() 85 defer n.mu.Unlock() 86 if n.atDir == nil { 87 n.atDir = &atDir{fs: n.fs} 88 } 89 return n.atDir 90 } 91 92 func (n *root) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) { 93 switch name { 94 case ".quitquitquit": 95 log.Fatalf("Shutting down due to root .quitquitquit lookup.") 96 case "WELCOME.txt": 97 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 98 case "recent": 99 return n.getRecentDir(), nil 100 case "tag", "date": 101 return notImplementDirNode{}, nil 102 case "at": 103 return n.getAtDir(), nil 104 case "roots": 105 return n.getRootsDir(), nil 106 case "sha1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx": 107 return notImplementDirNode{}, nil 108 case ".camli_fs_stats": 109 return statsDir{}, nil 110 case "mach_kernel", ".hidden", "._.": 111 // Just quiet some log noise on OS X. 112 return nil, fuse.ENOENT 113 } 114 115 if br, ok := blob.Parse(name); ok { 116 log.Printf("Root lookup of blobref. %q => %v", name, br) 117 return &node{fs: n.fs, blobref: br}, nil 118 } 119 log.Printf("Bogus root lookup of %q", name) 120 return nil, fuse.ENOENT 121 }