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  }