├── .gitignore ├── vendor └── github.com │ ├── jacobsa │ └── fuse │ │ ├── internal │ │ ├── fusekernel │ │ │ ├── fuse_kernel_std.go │ │ │ ├── fuse_kernel_linux.go │ │ │ ├── fuse_kernel_darwin.go │ │ │ └── protocol.go │ │ ├── buffer │ │ │ ├── out_message_darwin.go │ │ │ ├── out_message_linux.go │ │ │ ├── in_message_linux.go │ │ │ ├── in_message_darwin.go │ │ │ ├── runtime.go │ │ │ ├── runtime_other.s │ │ │ ├── runtime_go1.8.s │ │ │ ├── in_message.go │ │ │ └── out_message.go │ │ └── freelist │ │ │ └── freelist.go │ │ ├── samples │ │ ├── memfs │ │ │ ├── memfs_go18_test.go │ │ │ └── memfs_others_test.go │ │ ├── unmount.go │ │ ├── errorfs │ │ │ └── error_fs_test.go │ │ ├── statfs │ │ │ ├── statfs_linux_test.go │ │ │ └── statfs.go │ │ ├── in_process.go │ │ ├── forgetfs │ │ │ └── forget_fs_test.go │ │ ├── interruptfs │ │ │ └── interrupt_fs_test.go │ │ └── mount_sample │ │ │ └── mount.go │ │ ├── unmount_std.go │ │ ├── .gitignore │ │ ├── unmount_linux.go │ │ ├── fuseutil │ │ ├── doc.go │ │ └── dirent.go │ │ ├── fuseops │ │ └── doc.go │ │ ├── unmount.go │ │ ├── fsutil │ │ ├── fdatasync_darwin.go │ │ ├── fdatasync_linux.go │ │ └── fsutil.go │ │ ├── .travis.yml │ │ ├── errors.go │ │ ├── README.md │ │ ├── fusetesting │ │ ├── stat_linux.go │ │ ├── stat_darwin.go │ │ ├── readdir.go │ │ └── stat.go │ │ ├── ops.go │ │ ├── doc.go │ │ ├── mounted_file_system.go │ │ ├── freelists.go │ │ ├── mount.go │ │ ├── mount_linux.go │ │ ├── mount_test.go │ │ └── debug.go │ ├── t3rm1n4l │ └── go-mega │ │ ├── Makefile │ │ ├── .travis.yml │ │ ├── README.md │ │ ├── errors.go │ │ └── messages.go │ └── dropbox │ └── dropbox-sdk-go-unofficial │ ├── .gitignore │ ├── .gitmodules │ ├── generator │ ├── dropbox-api-spec │ │ ├── README.md │ │ ├── sharing.stone │ │ ├── users_common.stone │ │ ├── stone_cfg.stone │ │ ├── team_common.stone │ │ ├── common.stone │ │ ├── team_log.stone │ │ ├── team_policies.stone │ │ ├── auth.stone │ │ ├── async.stone │ │ ├── team_property_templates.stone │ │ ├── shared_content_links.stone │ │ └── properties.stone │ ├── generate-sdk.sh │ ├── go_rsrc │ │ ├── sharing │ │ │ └── metadata.go │ │ └── files │ │ │ └── metadata.go │ └── go_helpers.py │ ├── .travis.yml │ ├── LICENSE │ ├── dropbox │ ├── users_common │ │ └── types.go │ ├── sharing │ │ └── metadata.go │ ├── files │ │ └── metadata.go │ ├── team_common │ │ └── types.go │ ├── common │ │ └── types.go │ ├── async │ │ └── types.go │ └── team_policies │ │ └── types.go │ └── README.md ├── version.go ├── internal ├── fs │ ├── basefs │ │ ├── change.go │ │ ├── file_wrapper.go │ │ ├── service.go │ │ ├── file.go │ │ └── file_entry.go │ ├── megafs │ │ ├── config.go │ │ └── megafs.go │ ├── dropboxfs │ │ ├── config.go │ │ └── dropboxfs.go │ └── gdrivefs │ │ ├── config.go │ │ └── gdrivefs.go ├── core │ ├── driverfs.go │ ├── config.go │ └── core.go ├── oauth2util │ └── oauth2util.go └── coreutil │ └── util.go ├── boiler ├── templates │ └── fs │ │ ├── config.go.boiler │ │ ├── genfs.go.boiler │ │ └── service.go.boiler └── config.yml ├── TODO.md ├── main.go └── flags.go /.gitignore: -------------------------------------------------------------------------------- 1 | test 2 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/internal/fusekernel/fuse_kernel_std.go: -------------------------------------------------------------------------------- 1 | package fusekernel 2 | -------------------------------------------------------------------------------- /vendor/github.com/t3rm1n4l/go-mega/Makefile: -------------------------------------------------------------------------------- 1 | build: 2 | go build 3 | 4 | test: 5 | go test -v 6 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/.gitignore: -------------------------------------------------------------------------------- 1 | # swap 2 | [._]*.s[a-w][a-z] 3 | [._]s[a-w][a-z] 4 | 5 | .pyc 6 | __pycache__ 7 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/samples/memfs/memfs_go18_test.go: -------------------------------------------------------------------------------- 1 | // +build go1.8 2 | 3 | package memfs_test 4 | 5 | const atLeastGo18 = true 6 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/samples/memfs/memfs_others_test.go: -------------------------------------------------------------------------------- 1 | // +build !go1.8 2 | 3 | package memfs_test 4 | 5 | const atLeastGo18 = false 6 | -------------------------------------------------------------------------------- /version.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | const ( 4 | //Version contains version of the package 5 | Version = "0.7-9-g359da9e - built: 2018-06-10 13:43:05 UTC" 6 | ) 7 | -------------------------------------------------------------------------------- /internal/fs/basefs/change.go: -------------------------------------------------------------------------------- 1 | package basefs 2 | 3 | //Change information retrieved by API deltas 4 | type Change struct { 5 | ID string 6 | File *File 7 | Remove bool 8 | } 9 | -------------------------------------------------------------------------------- /boiler/templates/fs/config.go.boiler: -------------------------------------------------------------------------------- 1 | package {{.name}}fs 2 | 3 | //Config {{.name}}.yaml config file structure 4 | type Config struct { 5 | // Fs service specific configuration here 6 | } 7 | 8 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "generator/dropbox-api-spec"] 2 | path = generator/dropbox-api-spec 3 | url = https://github.com/dropbox/dropbox-api-spec 4 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/generator/dropbox-api-spec/README.md: -------------------------------------------------------------------------------- 1 | Dropbox API Spec 2 | ================ 3 | 4 | The Stone API specification that describes the Dropbox v2 API. 5 | 6 | -------------------------------------------------------------------------------- /internal/fs/megafs/config.go: -------------------------------------------------------------------------------- 1 | package megafs 2 | 3 | //Config mega.yaml config file structure 4 | type Config struct { 5 | // Fs service specific configuration here 6 | Credentials struct { 7 | Email string 8 | Password string 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/generator/dropbox-api-spec/sharing.stone: -------------------------------------------------------------------------------- 1 | namespace sharing 2 | "This namespace contains endpoints and data types for creating and managing shared links and 3 | shared folders." 4 | 5 | import common 6 | import files 7 | import users 8 | -------------------------------------------------------------------------------- /internal/core/driverfs.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import "github.com/jacobsa/fuse/fuseutil" 4 | 5 | // DriverFS default interface for fs driver 6 | type DriverFS interface { 7 | fuseutil.FileSystem 8 | //Init() 9 | Start() 10 | //Refresh() 11 | } 12 | 13 | //DriverFactory function type for a FS factory 14 | type DriverFactory func(*Core) DriverFS 15 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.6.4 5 | - 1.7.5 6 | - 1.8 7 | 8 | install: 9 | - go get -u golang.org/x/oauth2 10 | 11 | before_script: 12 | - go get -u github.com/mitchellh/gox 13 | 14 | script: 15 | - gox -osarch="darwin/amd64 linux/amd64 windows/amd64" ./dropbox/... 16 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/unmount_std.go: -------------------------------------------------------------------------------- 1 | // +build !linux 2 | 3 | package fuse 4 | 5 | import ( 6 | "os" 7 | "syscall" 8 | ) 9 | 10 | func unmount(dir string) (err error) { 11 | err = syscall.Unmount(dir, 0) 12 | if err != nil { 13 | err = &os.PathError{Op: "unmount", Path: dir, Err: err} 14 | return 15 | } 16 | 17 | return 18 | } 19 | -------------------------------------------------------------------------------- /boiler/config.yml: -------------------------------------------------------------------------------- 1 | description: 2 | vars: [] 3 | generators: 4 | fs: 5 | files: 6 | - {source: fs/config.go.boiler, target: "{{.projRoot}}/internal/fs/{{.name}}fs/config.go" } 7 | - {source: fs/genfs.go.boiler, target: "{{.projRoot}}/internal/fs/{{.name}}fs/{{.name}}fs.go" } 8 | - {source: fs/service.go.boiler, target: "{{.projRoot}}/internal/fs/{{.name}}fs/service.go" } 9 | 10 | 11 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/.gitignore: -------------------------------------------------------------------------------- 1 | # Vim detritus 2 | .*.swp 3 | 4 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 5 | *.o 6 | *.a 7 | *.so 8 | 9 | # Folders 10 | _obj 11 | _test 12 | 13 | # Architecture specific extensions/prefixes 14 | *.[568vq] 15 | [568vq].out 16 | 17 | *.cgo1.go 18 | *.cgo2.c 19 | _cgo_defun.c 20 | _cgo_gotypes.go 21 | _cgo_export.* 22 | 23 | _testmain.go 24 | 25 | *.exe 26 | *.test 27 | *.prof 28 | -------------------------------------------------------------------------------- /internal/fs/dropboxfs/config.go: -------------------------------------------------------------------------------- 1 | package dropboxfs 2 | 3 | import "golang.org/x/oauth2" 4 | 5 | //Config Configuration 6 | type Config struct { 7 | ClientSecret struct { 8 | ClientID string `json:"client_id" yaml:"client_id"` 9 | ClientSecret string `json:"client_secret" yaml:"client_secret"` 10 | } `json:"client_secret" yaml:"client_secret"` 11 | Auth *oauth2.Token `json:"auth" yaml:"auth"` 12 | Options struct { 13 | Safemode bool 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/unmount_linux.go: -------------------------------------------------------------------------------- 1 | package fuse 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "os/exec" 7 | ) 8 | 9 | func unmount(dir string) (err error) { 10 | // Call fusermount. 11 | cmd := exec.Command("fusermount", "-u", dir) 12 | output, err := cmd.CombinedOutput() 13 | if err != nil { 14 | if len(output) > 0 { 15 | output = bytes.TrimRight(output, "\n") 16 | err = fmt.Errorf("%v: %s", err, output) 17 | } 18 | 19 | return 20 | } 21 | 22 | return 23 | } 24 | -------------------------------------------------------------------------------- /vendor/github.com/t3rm1n4l/go-mega/.travis.yml: -------------------------------------------------------------------------------- 1 | script: go test -v ./... 2 | env: 3 | global: 4 | - secure: RzsF80V1i69FVJwKSF8WrFzk5bRUKtPxRkhjiLOO0b1usFg0EIY6XFp3s/VTR6oT91LRXml3Bp7wHHrkPvGnHyUyuxj6loj3gIrsX8cZHUtjyQX/Szfi9MOJpbdJvfCcHByEh9YGldAz//9zvEo5oGuI29Luur3cv+BJNJElmHg= 5 | - secure: Eu3kWJbxpKyioitPQo75gI3gL/HKEHVMdp6YLxxcmlrbG2xyXdlFhTB2YkkmnC8jNvf7XJWdtYnhlWM9MrNY1fUiRyGSAmpSlzzCa9XQ9lCv0hUH57+D3PAcH6gdgKn6q1iOk26CxOCKAHVaj5xdDMIyCc4mD+sLyTDQhBIHABc= 6 | notifications: 7 | email: false 8 | language: go 9 | -------------------------------------------------------------------------------- /internal/fs/gdrivefs/config.go: -------------------------------------------------------------------------------- 1 | package gdrivefs 2 | 3 | import "golang.org/x/oauth2" 4 | 5 | //Config gdrive.yaml config file structure 6 | type Config struct { 7 | ClientSecret struct { 8 | ClientID string `json:"client_id" yaml:"client_id"` 9 | ClientSecret string `json:"client_secret" yaml:"client_secret"` 10 | } `json:"client_secret" yaml:"client_secret"` 11 | 12 | Auth *oauth2.Token `json:"auth" yaml:"auth"` 13 | Mime map[string]string `json:"mime" yaml:"mime"` 14 | Options struct { 15 | Safemode bool 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /internal/fs/basefs/file_wrapper.go: -------------------------------------------------------------------------------- 1 | package basefs 2 | 3 | // Unfortunately Dropbox/net/http closes the file after sending (even if it is io.Reader only) and in this case we still need it locally open 4 | 5 | import "os" 6 | 7 | //FileWrapper helper to prevent http.Post to close my files 8 | type FileWrapper struct { 9 | *os.File 10 | } 11 | 12 | //Close ignore close 13 | func (f *FileWrapper) Close() error { 14 | // Ignore closers 15 | return nil 16 | } 17 | 18 | //RealClose to be called internally to close the file 19 | func (f *FileWrapper) RealClose() error { 20 | return f.File.Close() 21 | } 22 | -------------------------------------------------------------------------------- /internal/fs/basefs/service.go: -------------------------------------------------------------------------------- 1 | package basefs 2 | 3 | import ( 4 | "io" 5 | 6 | "github.com/jacobsa/fuse/fuseops" 7 | ) 8 | 9 | // Service interface 10 | type Service interface { 11 | Changes() ([]*Change, error) 12 | ListAll() ([]*File, error) 13 | Create(parent *File, name string, isDir bool) (*File, error) 14 | //Truncate(file *File) (*File, error) 15 | Upload(reader io.Reader, file *File) (*File, error) 16 | DownloadTo(w io.Writer, file *File) error 17 | Move(file *File, newParent *File, name string) (*File, error) 18 | Delete(file *File) error 19 | //-- implementing 20 | StatFS(*fuseops.StatFSOp) error 21 | } 22 | -------------------------------------------------------------------------------- /internal/fs/dropboxfs/dropboxfs.go: -------------------------------------------------------------------------------- 1 | package dropboxfs 2 | 3 | import ( 4 | "github.com/gohxs/cloudmount/internal/core" 5 | "github.com/gohxs/cloudmount/internal/fs/basefs" 6 | "github.com/gohxs/prettylog" 7 | ) 8 | 9 | var ( 10 | pname = "dropboxfs" 11 | log = prettylog.Dummy() 12 | errlog = prettylog.New(pname + "-err") 13 | ) 14 | 15 | // New Create basefs with Dropbox service 16 | func New(core *core.Core) core.DriverFS { 17 | if core.Config.VerboseLog { 18 | log = prettylog.New(pname) 19 | } 20 | fs := basefs.New(core) 21 | fs.Service = NewService(&core.Config) // DropBoxService 22 | 23 | return fs 24 | } 25 | -------------------------------------------------------------------------------- /boiler/templates/fs/genfs.go.boiler: -------------------------------------------------------------------------------- 1 | package megafs 2 | 3 | import ( 4 | "github.com/gohxs/cloudmount/internal/core" 5 | "github.com/gohxs/cloudmount/internal/fs/basefs" 6 | "github.com/gohxs/prettylog" 7 | ) 8 | 9 | var ( 10 | pname = "{{.name}}" 11 | log = prettylog.Dummy() 12 | errlog = prettylog.New(pname + "-err") 13 | ) 14 | 15 | // New Filesystem implementation based on basefs Service 16 | func New(core *core.Core) core.DriverFS { 17 | 18 | if core.Config.VerboseLog { 19 | log = prettylog.New(pname) 20 | } 21 | 22 | fs := basefs.New(core) 23 | fs.Service = NewService(&core.Config) 24 | 25 | return fs 26 | } 27 | -------------------------------------------------------------------------------- /internal/fs/gdrivefs/gdrivefs.go: -------------------------------------------------------------------------------- 1 | package gdrivefs 2 | 3 | import ( 4 | "github.com/gohxs/cloudmount/internal/core" 5 | "github.com/gohxs/cloudmount/internal/fs/basefs" 6 | "github.com/gohxs/prettylog" 7 | ) 8 | 9 | var ( 10 | pname = "gdrive" 11 | log = prettylog.Dummy() 12 | errlog = prettylog.New(pname + "-err") 13 | ) 14 | 15 | // New new Filesystem implementation based on gdrive Service 16 | func New(core *core.Core) core.DriverFS { 17 | 18 | if core.Config.VerboseLog { 19 | log = prettylog.New(pname) 20 | } 21 | 22 | fs := basefs.New(core) 23 | fs.Service = NewService(&core.Config) 24 | 25 | return fs 26 | } 27 | -------------------------------------------------------------------------------- /internal/fs/megafs/megafs.go: -------------------------------------------------------------------------------- 1 | package megafs 2 | 3 | import ( 4 | "github.com/gohxs/cloudmount/internal/core" 5 | "github.com/gohxs/cloudmount/internal/fs/basefs" 6 | "github.com/gohxs/prettylog" 7 | ) 8 | 9 | var ( 10 | pname = "mega" 11 | log = prettylog.Dummy() 12 | errlog = prettylog.New(pname + "-err") 13 | ) 14 | 15 | // New Filesystem implementation based on basefs(webfs) Service 16 | func New(core *core.Core) core.DriverFS { 17 | 18 | if core.Config.VerboseLog { 19 | log = prettylog.New(pname) 20 | } 21 | 22 | fs := basefs.New(core) 23 | fs.Service = NewService(&core.Config, fs) 24 | 25 | return fs 26 | } 27 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/generator/dropbox-api-spec/users_common.stone: -------------------------------------------------------------------------------- 1 | namespace users_common 2 | "This namespace contains common data types used within the users namespace" 3 | 4 | alias AccountId = String(min_length=40, max_length=40) 5 | 6 | union_closed AccountType 7 | "What type of account this user has." 8 | 9 | basic 10 | "The basic account type." 11 | pro 12 | "The Dropbox Pro account type." 13 | business 14 | "The Dropbox Business account type." 15 | 16 | example default 17 | basic = null 18 | 19 | example business 20 | business = null 21 | -------------------------------------------------------------------------------- /internal/fs/basefs/file.go: -------------------------------------------------------------------------------- 1 | package basefs 2 | 3 | import ( 4 | "os" 5 | "time" 6 | ) 7 | 8 | //File entry structure all basefs based services must use these 9 | type File struct { 10 | ID string 11 | Name string 12 | Size uint64 13 | CreatedTime time.Time 14 | ModifiedTime time.Time 15 | AccessedTime time.Time 16 | Mode os.FileMode 17 | Parents []string 18 | Data interface{} // Any thing 19 | } 20 | 21 | // HasParent check file parenting 22 | func (f *File) HasParent(parent *File) bool { 23 | parentID := "" 24 | if parent != nil { 25 | parentID = parent.ID 26 | } 27 | for _, p := range f.Parents { 28 | if p == parentID { 29 | return true 30 | } 31 | } 32 | return false 33 | } 34 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/fuseutil/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Types and functions that make it easier to work with package fuse. 16 | package fuseutil 17 | -------------------------------------------------------------------------------- /internal/core/config.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/gohxs/cloudmount/internal/coreutil" 7 | ) 8 | 9 | // Config struct 10 | type Config struct { 11 | Foreground bool 12 | Type string 13 | VerboseLog bool 14 | Verbose2Log bool 15 | RefreshTime time.Duration 16 | HomeDir string 17 | Target string // should be a folder 18 | Source string 19 | 20 | //Options map[string]string 21 | Options Options 22 | } 23 | 24 | // Options are specified in cloudmount -o option1=1, option2=2 25 | type Options struct { // are Options for specific driver? 26 | // Sub options 27 | UID uint32 `opt:"uid"` 28 | GID uint32 `opt:"gid"` // Mount GID 29 | Readonly bool `opt:"ro"` 30 | } 31 | 32 | func (o Options) String() string { 33 | return coreutil.OptionString(o) 34 | } 35 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/generator/generate-sdk.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | set -euo pipefail 3 | 4 | if [[ $# -ne 0 ]]; then 5 | echo "$0: Not expecting any command-line arguments, got $#." 1>&2 6 | exit 1 7 | fi 8 | 9 | loc=$(realpath -e $0) 10 | base_dir=$(dirname "$loc") 11 | spec_dir="$base_dir/dropbox-api-spec" 12 | gen_dir=$(dirname ${base_dir})/dropbox 13 | 14 | stone -v -a :all go_types.stoneg.py "$gen_dir" "$spec_dir"/*.stone 15 | stone -v -a :all go_client.stoneg.py "$gen_dir" "$spec_dir"/*.stone 16 | 17 | # Update SDK and API spec versions 18 | sdk_version="1.0.0-beta" 19 | pushd ${spec_dir} 20 | spec_version=$(git rev-parse --short HEAD) 21 | popd 22 | 23 | sed -i '' -e "s/UNKNOWN SDK VERSION/${sdk_version}/" \ 24 | -e "s/UNKNOWN SPEC VERSION/${spec_version}/" ${gen_dir}/sdk.go 25 | goimports -l -w ${gen_dir} 26 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/fuseops/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package fuseops contains ops that may be returned by fuse.Connection.ReadOp. 16 | // See documentation in that package for more. 17 | package fuseops 18 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/unmount.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package fuse 16 | 17 | // Unmount attempts to unmount the file system whose mount point is the 18 | // supplied directory. 19 | func Unmount(dir string) error { 20 | return unmount(dir) 21 | } 22 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/fsutil/fdatasync_darwin.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package fsutil 16 | 17 | import "os" 18 | 19 | const FdatasyncSupported = false 20 | 21 | func fdatasync(f *os.File) error { 22 | panic("We require FdatasyncSupported be true.") 23 | } 24 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/fsutil/fdatasync_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package fsutil 16 | 17 | import ( 18 | "os" 19 | "syscall" 20 | ) 21 | 22 | const FdatasyncSupported = true 23 | 24 | func fdatasync(f *os.File) error { 25 | return syscall.Fdatasync(int(f.Fd())) 26 | } 27 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/internal/buffer/out_message_darwin.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package buffer 16 | 17 | // The maximum read size that we expect to ever see from the kernel, used for 18 | // calculating the size of out messages. 19 | // 20 | // Experimentally determined on OS X. 21 | const MaxReadSize = 1 << 20 22 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | #### TODO: 2 | * Fix google retry when error 3 | * Improve logging system (is a bit messy) 4 | * Create test cases 5 | * Remove default gdrive and determine fs by arg[0] when possible 6 | * cloudmount.gdrive will mount gdrive 7 | * cloudmount.dropbox .. 8 | 9 | #### Done: 10 | * Create and reference dropbox oauth doc 11 | * Add verbosity levels (sometimes just want to log the driver and not fuse) 12 | * Safemode flag not needed i supose 13 | * move client from fs's to service.go 14 | * Sanitize error on basefs, file_container produces err, basefs produces fuse.E.. 15 | 16 | 17 | #### Ideas: 18 | Sub mounting: 19 | 20 | Current: 21 | cloudmount -t gdrive source.yaml destfolder 22 | 23 | Idea: 24 | cloudmount -t gdrive gdrive.yaml/My\ Drive destfolder 25 | 26 | Problem: 27 | Hard to figure which part of the path is our configuration file so subsequent paths could be issue to find 28 | 29 | Solution: 30 | Setup Root folder in configs 31 | 32 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/.travis.yml: -------------------------------------------------------------------------------- 1 | # Cf. http://docs.travis-ci.com/user/getting-started/ 2 | # Cf. http://docs.travis-ci.com/user/languages/go/ 3 | 4 | matrix: 5 | include: 6 | - os: linux 7 | language: go 8 | go: 1.8.1 9 | # Use the virtualized Trusty beta Travis is running in order to get 10 | # support for installing fuse. 11 | # 12 | # Cf. Personal communication from support@travis-ci.com. 13 | dist: trusty 14 | sudo: required 15 | - os: osx 16 | language: go 17 | go: 1.8.1 18 | 19 | # Install fuse before installing our code. 20 | before_install: 21 | # For linux: install fuse. 22 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then 23 | sudo apt-get install -qq fuse; 24 | fi 25 | 26 | # For macOS: update homebrew and then install osxfuse. 27 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi 28 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew cask install osxfuse; fi 29 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/internal/buffer/out_message_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package buffer 16 | 17 | // The maximum read size that we expect to ever see from the kernel, used for 18 | // calculating the size of out messages. 19 | // 20 | // For 4 KiB pages, this is 128 KiB (cf. https://goo.gl/HOiEYo) 21 | const MaxReadSize = 1 << 17 22 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/internal/buffer/in_message_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package buffer 16 | 17 | // The maximum fuse write request size that InMessage can acommodate. 18 | // 19 | // Experimentally, Linux appears to refuse to honor a MaxWrite setting in an 20 | // INIT response of more than 128 KiB. 21 | const MaxWriteSize = 1 << 17 22 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/internal/buffer/in_message_darwin.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package buffer 16 | 17 | // The maximum fuse write request size that InMessage can acommodate. 18 | // 19 | // Experimentally, OS X appears to cap the size of writes to 1 MiB, regardless 20 | // of whether a larger size is specified in the mount options. 21 | const MaxWriteSize = 1 << 20 22 | -------------------------------------------------------------------------------- /internal/oauth2util/oauth2util.go: -------------------------------------------------------------------------------- 1 | package oauth2util 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | 7 | "golang.org/x/oauth2" 8 | ) 9 | 10 | //GetTokenFromWeb shows link to user, and requests the informed token 11 | func GetTokenFromWeb(config *oauth2.Config) *oauth2.Token { 12 | //authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline) 13 | authURL := config.AuthCodeURL("state-token") 14 | 15 | fmt.Printf( 16 | `Go to the following link in your browser: 17 | ---------------------------------------------------------------------------------------------- 18 | %v 19 | ---------------------------------------------------------------------------------------------- 20 | 21 | type the authorization code: `, authURL) 22 | 23 | var code string 24 | if _, err := fmt.Scan(&code); err != nil { 25 | log.Fatalf("Unable to read authorization code %v", err) 26 | } 27 | 28 | tok, err := config.Exchange(oauth2.NoContext, code) 29 | if err != nil { 30 | log.Fatalf("Unable to retrieve token from web: %v", err) 31 | } 32 | 33 | return tok 34 | } 35 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/internal/buffer/runtime.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package buffer 16 | 17 | import "unsafe" 18 | 19 | //go:noescape 20 | 21 | // Zero the n bytes starting at p. 22 | // 23 | // REQUIRES: the region does not contain any Go pointers. 24 | func memclr(p unsafe.Pointer, n uintptr) 25 | 26 | //go:noescape 27 | 28 | // Copy from src to dst, allowing overlap. 29 | func memmove(dst unsafe.Pointer, src unsafe.Pointer, n uintptr) 30 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/errors.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package fuse 16 | 17 | import "syscall" 18 | 19 | const ( 20 | // Errors corresponding to kernel error numbers. These may be treated 21 | // specially by Connection.Reply. 22 | EEXIST = syscall.EEXIST 23 | EINVAL = syscall.EINVAL 24 | EIO = syscall.EIO 25 | ENOATTR = syscall.ENODATA 26 | ENOENT = syscall.ENOENT 27 | ENOSYS = syscall.ENOSYS 28 | ENOTDIR = syscall.ENOTDIR 29 | ENOTEMPTY = syscall.ENOTEMPTY 30 | ) 31 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009-2016 Dropbox Inc., http://www.dropbox.com/ 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/internal/freelist/freelist.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package freelist 16 | 17 | import "unsafe" 18 | 19 | // A freelist for arbitrary pointers. Not safe for concurrent access. 20 | type Freelist struct { 21 | list []unsafe.Pointer 22 | } 23 | 24 | // Get an element from the freelist, returning nil if empty. 25 | func (fl *Freelist) Get() (p unsafe.Pointer) { 26 | l := len(fl.list) 27 | if l == 0 { 28 | return 29 | } 30 | 31 | p = fl.list[l-1] 32 | fl.list = fl.list[:l-1] 33 | 34 | return 35 | } 36 | 37 | // Contribute an element back to the freelist. 38 | func (fl *Freelist) Put(p unsafe.Pointer) { 39 | fl.list = append(fl.list, p) 40 | } 41 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/README.md: -------------------------------------------------------------------------------- 1 | [![GoDoc](https://godoc.org/github.com/jacobsa/ogletest?status.svg)](https://godoc.org/github.com/jacobsa/fuse) 2 | 3 | This package allows for writing and mounting user-space file systems from Go. 4 | Install it as follows: 5 | 6 | go get -u github.com/jacobsa/fuse 7 | 8 | Afterward, see the documentation for the following three packages: 9 | 10 | * Package [fuse][] provides support for mounting a new file system and 11 | reading requests from the kernel. 12 | 13 | * Package [fuseops][] enumerates the supported requests from the kernel, and 14 | provides documentation on their semantics. 15 | 16 | * Package [fuseutil][], in particular the `FileSystem` interface, provides a 17 | convenient way to create a file system type and export it to the kernel via 18 | `fuse.Mount`. 19 | 20 | Make sure to also see the sub-packages of the [samples][] package for examples 21 | and tests. 22 | 23 | This package owes its inspiration and most of its kernel-related code to 24 | [bazil.org/fuse][bazil]. 25 | 26 | [fuse]: http://godoc.org/github.com/jacobsa/fuse 27 | [fuseops]: http://godoc.org/github.com/jacobsa/fuse/fuseops 28 | [fuseutil]: http://godoc.org/github.com/jacobsa/fuse/fuseutil 29 | [samples]: http://godoc.org/github.com/jacobsa/fuse/samples 30 | [bazil]: http://godoc.org/bazil.org/fuse 31 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/internal/buffer/runtime_other.s: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // +build amd64 arm64 ppc64 ppc64le arm 16 | // +build !go1.8 17 | 18 | // Assembly code isn't subject to visibility restrictions, so we can jump 19 | // directly into package runtime. 20 | // 21 | // Technique copied from here: 22 | // https://github.com/golang/go/blob/d8c6dac/src/os/signal/sig.s 23 | 24 | #include "textflag.h" 25 | 26 | #ifdef GOARCH_arm 27 | #define JMP B 28 | #endif 29 | #ifdef GOARCH_ppc64 30 | #define JMP BR 31 | #endif 32 | #ifdef GOARCH_ppc64le 33 | #define JMP BR 34 | #endif 35 | 36 | TEXT ·memclr(SB),NOSPLIT,$0-16 37 | JMP runtime·memclr(SB) 38 | 39 | TEXT ·memmove(SB),NOSPLIT,$0-24 40 | JMP runtime·memmove(SB) 41 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/internal/buffer/runtime_go1.8.s: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // +build amd64 arm64 ppc64 ppc64le arm 16 | // +build go1.8 17 | 18 | // Assembly code isn't subject to visibility restrictions, so we can jump 19 | // directly into package runtime. 20 | // 21 | // Technique copied from here: 22 | // https://github.com/golang/go/blob/d8c6dac/src/os/signal/sig.s 23 | 24 | #include "textflag.h" 25 | 26 | #ifdef GOARCH_arm 27 | #define JMP B 28 | #endif 29 | #ifdef GOARCH_ppc64 30 | #define JMP BR 31 | #endif 32 | #ifdef GOARCH_ppc64le 33 | #define JMP BR 34 | #endif 35 | 36 | TEXT ·memclr(SB),NOSPLIT,$0-16 37 | JMP runtime·memclrNoHeapPointers(SB) 38 | 39 | TEXT ·memmove(SB),NOSPLIT,$0-24 40 | JMP runtime·memmove(SB) 41 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/fusetesting/stat_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package fusetesting 16 | 17 | import ( 18 | "syscall" 19 | "time" 20 | ) 21 | 22 | func extractMtime(sys interface{}) (mtime time.Time, ok bool) { 23 | mtime = time.Unix(sys.(*syscall.Stat_t).Mtim.Unix()) 24 | ok = true 25 | return 26 | } 27 | 28 | func extractBirthtime(sys interface{}) (birthtime time.Time, ok bool) { 29 | return 30 | } 31 | 32 | func extractNlink(sys interface{}) (nlink uint64, ok bool) { 33 | nlink = sys.(*syscall.Stat_t).Nlink 34 | ok = true 35 | return 36 | } 37 | 38 | func getTimes(stat *syscall.Stat_t) (atime, ctime, mtime time.Time) { 39 | atime = time.Unix(stat.Atim.Unix()) 40 | ctime = time.Unix(stat.Ctim.Unix()) 41 | mtime = time.Unix(stat.Mtim.Unix()) 42 | return 43 | } 44 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/ops.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package fuse 16 | 17 | import ( 18 | "github.com/jacobsa/fuse/fuseops" 19 | "github.com/jacobsa/fuse/internal/fusekernel" 20 | ) 21 | 22 | // A sentinel used for unknown ops. The user is expected to respond with a 23 | // non-nil error. 24 | type unknownOp struct { 25 | OpCode uint32 26 | Inode fuseops.InodeID 27 | } 28 | 29 | // Causes us to cancel the associated context. 30 | type interruptOp struct { 31 | FuseID uint64 32 | } 33 | 34 | // Required in order to mount on Linux and OS X. 35 | type initOp struct { 36 | // In 37 | Kernel fusekernel.Protocol 38 | 39 | // In/out 40 | Flags fusekernel.InitFlags 41 | 42 | // Out 43 | Library fusekernel.Protocol 44 | MaxReadahead uint32 45 | MaxWrite uint32 46 | } 47 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/fusetesting/stat_darwin.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package fusetesting 16 | 17 | import ( 18 | "syscall" 19 | "time" 20 | ) 21 | 22 | func extractMtime(sys interface{}) (mtime time.Time, ok bool) { 23 | mtime = time.Unix(sys.(*syscall.Stat_t).Mtimespec.Unix()) 24 | ok = true 25 | return 26 | } 27 | 28 | func extractBirthtime(sys interface{}) (birthtime time.Time, ok bool) { 29 | birthtime = time.Unix(sys.(*syscall.Stat_t).Birthtimespec.Unix()) 30 | ok = true 31 | return 32 | } 33 | 34 | func extractNlink(sys interface{}) (nlink uint64, ok bool) { 35 | nlink = uint64(sys.(*syscall.Stat_t).Nlink) 36 | ok = true 37 | return 38 | } 39 | 40 | func getTimes(stat *syscall.Stat_t) (atime, ctime, mtime time.Time) { 41 | atime = time.Unix(stat.Atimespec.Unix()) 42 | ctime = time.Unix(stat.Ctimespec.Unix()) 43 | mtime = time.Unix(stat.Mtimespec.Unix()) 44 | return 45 | } 46 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/samples/unmount.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package samples 16 | 17 | import ( 18 | "fmt" 19 | "log" 20 | "strings" 21 | "time" 22 | 23 | "github.com/jacobsa/fuse" 24 | ) 25 | 26 | // Unmount the file system mounted at the supplied directory. Try again on 27 | // "resource busy" errors, which happen from time to time on OS X (due to weird 28 | // requests from the Finder) and when tests don't or can't synchronize all 29 | // events. 30 | func unmount(dir string) (err error) { 31 | delay := 10 * time.Millisecond 32 | for { 33 | err = fuse.Unmount(dir) 34 | if err == nil { 35 | return 36 | } 37 | 38 | if strings.Contains(err.Error(), "resource busy") { 39 | log.Println("Resource busy error while unmounting; trying again") 40 | time.Sleep(delay) 41 | delay = time.Duration(1.3 * float64(delay)) 42 | continue 43 | } 44 | 45 | err = fmt.Errorf("Unmount: %v", err) 46 | return 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/internal/fusekernel/fuse_kernel_linux.go: -------------------------------------------------------------------------------- 1 | package fusekernel 2 | 3 | import "time" 4 | 5 | type Attr struct { 6 | Ino uint64 7 | Size uint64 8 | Blocks uint64 9 | Atime uint64 10 | Mtime uint64 11 | Ctime uint64 12 | AtimeNsec uint32 13 | MtimeNsec uint32 14 | CtimeNsec uint32 15 | Mode uint32 16 | Nlink uint32 17 | Uid uint32 18 | Gid uint32 19 | Rdev uint32 20 | Blksize uint32 21 | padding uint32 22 | } 23 | 24 | func (a *Attr) Crtime() time.Time { 25 | return time.Time{} 26 | } 27 | 28 | func (a *Attr) SetCrtime(s uint64, ns uint32) { 29 | // Ignored on Linux. 30 | } 31 | 32 | func (a *Attr) SetFlags(f uint32) { 33 | // Ignored on Linux. 34 | } 35 | 36 | type SetattrIn struct { 37 | setattrInCommon 38 | } 39 | 40 | func (in *SetattrIn) BkupTime() time.Time { 41 | return time.Time{} 42 | } 43 | 44 | func (in *SetattrIn) Chgtime() time.Time { 45 | return time.Time{} 46 | } 47 | 48 | func (in *SetattrIn) Flags() uint32 { 49 | return 0 50 | } 51 | 52 | func openFlags(flags uint32) OpenFlags { 53 | // on amd64, the 32-bit O_LARGEFILE flag is always seen; 54 | // on i386, the flag probably depends on the app 55 | // requesting, but in any case should be utterly 56 | // uninteresting to us here; our kernel protocol messages 57 | // are not directly related to the client app's kernel 58 | // API/ABI 59 | flags &^= 0x8000 60 | 61 | return OpenFlags(flags) 62 | } 63 | 64 | type GetxattrIn struct { 65 | getxattrInCommon 66 | } 67 | 68 | type SetxattrIn struct { 69 | setxattrInCommon 70 | } 71 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package fuse enables writing and mounting user-space file systems. 16 | // 17 | // The primary elements of interest are: 18 | // 19 | // * The fuseops package, which defines the operations that fuse might send 20 | // to your userspace daemon. 21 | // 22 | // * The Server interface, which your daemon must implement. 23 | // 24 | // * fuseutil.NewFileSystemServer, which offers a convenient way to implement 25 | // the Server interface. 26 | // 27 | // * Mount, a function that allows for mounting a Server as a file system. 28 | // 29 | // Make sure to see the examples in the sub-packages of samples/, which double 30 | // as tests for this package: http://godoc.org/github.com/jacobsa/fuse/samples 31 | // 32 | // In order to use this package to mount file systems on OS X, the system must 33 | // have FUSE for OS X installed (see http://osxfuse.github.io/). Do note that 34 | // there are several OS X-specific oddities; grep through the documentation for 35 | // more info. 36 | package fuse 37 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/dropbox/users_common/types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) Dropbox, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | // Package users_common : This namespace contains common data types used within 22 | // the users namespace 23 | package users_common 24 | 25 | import "github.com/dropbox/dropbox-sdk-go-unofficial/dropbox" 26 | 27 | // AccountType : What type of account this user has. 28 | type AccountType struct { 29 | dropbox.Tagged 30 | } 31 | 32 | // Valid tag values for AccountType 33 | const ( 34 | AccountTypeBasic = "basic" 35 | AccountTypePro = "pro" 36 | AccountTypeBusiness = "business" 37 | ) 38 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/generator/dropbox-api-spec/stone_cfg.stone: -------------------------------------------------------------------------------- 1 | namespace stone_cfg 2 | 3 | struct Route 4 | 5 | auth String = "user" 6 | "The auth type for the route. Valid values: user, team, app, noauth." 7 | host String = "api" 8 | "The server to make the request to. Valid values: api, content, 9 | and notify." 10 | style String = "rpc" 11 | "The RPC format to use for the request. Valid values: rpc, download, 12 | and upload." 13 | api_group String? 14 | "The API group to which this route belongs (useful for filtering 15 | via Stone's -f command line argument)." 16 | is_preview Boolean = false 17 | "A flag indicating whether the route is subject to breaking 18 | changes without notice." 19 | # We can switch the type from String to a Union once all generators support 20 | # unions in attributes. 21 | owner String(pattern="adminx|dev-plat|sfi|home|sharing|company-dropbox-team|paper-eng|notifications-team|sub-growth|productivity-infra-team|prodsec|cash-team|premium-labs")? 22 | "The team that currently owns the route." 23 | cluster String(min_length=1) = "meta-api" 24 | "The cluster that handles this route." 25 | feature String? 26 | "Set if the route belongs to an orion feature. Accounts must have access to the feature to 27 | successfully make a request to the route. Only features with boolean value are supported" 28 | allow_app_folder_app Boolean = false 29 | "If app folder app is allowed to use this endpoint." 30 | takes_path_root Boolean = false 31 | "A flag indicating whether the route's behavior is affected by use of 32 | the Dropbox-API-Path-Root header." 33 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/fsutil/fsutil.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package fsutil 16 | 17 | import ( 18 | "fmt" 19 | "io/ioutil" 20 | "os" 21 | "path" 22 | ) 23 | 24 | // Create a temporary file with the same semantics as ioutil.TempFile, but 25 | // ensure that it is unlinked before returning so that it does not persist 26 | // after the process exits. 27 | // 28 | // Warning: this is not production-quality code, and should only be used for 29 | // testing purposes. In particular, there is a race between creating and 30 | // unlinking by name. 31 | func AnonymousFile(dir string) (f *os.File, err error) { 32 | // Choose a prefix based on the binary name. 33 | prefix := path.Base(os.Args[0]) 34 | 35 | // Create the file. 36 | f, err = ioutil.TempFile(dir, prefix) 37 | if err != nil { 38 | err = fmt.Errorf("TempFile: %v", err) 39 | return 40 | } 41 | 42 | // Unlink it. 43 | err = os.Remove(f.Name()) 44 | if err != nil { 45 | err = fmt.Errorf("Remove: %v", err) 46 | return 47 | } 48 | 49 | return 50 | } 51 | 52 | // Call fdatasync on the supplied file. 53 | // 54 | // REQUIRES: FdatasyncSupported is true. 55 | func Fdatasync(f *os.File) error { 56 | return fdatasync(f) 57 | } 58 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/mounted_file_system.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package fuse 16 | 17 | import "golang.org/x/net/context" 18 | 19 | // MountedFileSystem represents the status of a mount operation, with a method 20 | // that waits for unmounting. 21 | type MountedFileSystem struct { 22 | dir string 23 | 24 | // The result to return from Join. Not valid until the channel is closed. 25 | joinStatus error 26 | joinStatusAvailable chan struct{} 27 | } 28 | 29 | // Dir returns the directory on which the file system is mounted (or where we 30 | // attempted to mount it.) 31 | func (mfs *MountedFileSystem) Dir() string { 32 | return mfs.dir 33 | } 34 | 35 | // Join blocks until a mounted file system has been unmounted. It does not 36 | // return successfully until all ops read from the connection have been 37 | // responded to (i.e. the file system server has finished processing all 38 | // in-flight ops). 39 | // 40 | // The return value will be non-nil if anything unexpected happened while 41 | // serving. May be called multiple times. 42 | func (mfs *MountedFileSystem) Join(ctx context.Context) error { 43 | select { 44 | case <-mfs.joinStatusAvailable: 45 | return mfs.joinStatus 46 | case <-ctx.Done(): 47 | return ctx.Err() 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/generator/dropbox-api-spec/team_common.stone: -------------------------------------------------------------------------------- 1 | namespace team_common 2 | 3 | import common 4 | 5 | alias TeamMemberId = String 6 | alias MemberExternalId = String(max_length=64) 7 | alias GroupExternalId = String 8 | 9 | alias GroupId = String 10 | alias ResellerId = String 11 | 12 | struct GroupSummary 13 | "Information about a group." 14 | 15 | group_name String 16 | group_id GroupId 17 | group_external_id GroupExternalId? 18 | "External ID of group. This is an arbitrary ID that an admin can attach to a group." 19 | member_count UInt32? 20 | "The number of members in the group." 21 | group_management_type GroupManagementType 22 | "Who is allowed to manage the group." 23 | 24 | example default 25 | group_name = "Test group" 26 | group_id = "g:e2db7665347abcd600000000001a2b3c" 27 | member_count = 10 28 | group_management_type = user_managed 29 | 30 | 31 | union GroupManagementType 32 | "The group type determines how a group is managed." 33 | 34 | user_managed 35 | "A group which is managed by selected users." 36 | company_managed 37 | "A group which is managed by team admins only." 38 | system_managed 39 | "A group which is managed automatically by Dropbox." 40 | 41 | 42 | union GroupType 43 | "The group type determines how a group is created and managed." 44 | 45 | team 46 | "A group to which team members are automatically added. Applicable to 47 | :link:`team folders https://www.dropbox.com/help/986` only." 48 | user_managed 49 | "A group is created and managed by a user." 50 | 51 | struct TimeRange 52 | "Time range." 53 | start_time common.DropboxTimestamp? 54 | "Optional starting time (inclusive)." 55 | end_time common.DropboxTimestamp? 56 | "Optional ending time (exclusive)." 57 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/internal/fusekernel/fuse_kernel_darwin.go: -------------------------------------------------------------------------------- 1 | package fusekernel 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type Attr struct { 8 | Ino uint64 9 | Size uint64 10 | Blocks uint64 11 | Atime uint64 12 | Mtime uint64 13 | Ctime uint64 14 | Crtime_ uint64 // OS X only 15 | AtimeNsec uint32 16 | MtimeNsec uint32 17 | CtimeNsec uint32 18 | CrtimeNsec uint32 // OS X only 19 | Mode uint32 20 | Nlink uint32 21 | Uid uint32 22 | Gid uint32 23 | Rdev uint32 24 | Flags_ uint32 // OS X only; see chflags(2) 25 | Blksize uint32 26 | padding uint32 27 | } 28 | 29 | func (a *Attr) SetCrtime(s uint64, ns uint32) { 30 | a.Crtime_, a.CrtimeNsec = s, ns 31 | } 32 | 33 | func (a *Attr) SetFlags(f uint32) { 34 | a.Flags_ = f 35 | } 36 | 37 | type SetattrIn struct { 38 | setattrInCommon 39 | 40 | // OS X only 41 | Bkuptime_ uint64 42 | Chgtime_ uint64 43 | Crtime uint64 44 | BkuptimeNsec uint32 45 | ChgtimeNsec uint32 46 | CrtimeNsec uint32 47 | Flags_ uint32 // see chflags(2) 48 | } 49 | 50 | func (in *SetattrIn) BkupTime() time.Time { 51 | return time.Unix(int64(in.Bkuptime_), int64(in.BkuptimeNsec)) 52 | } 53 | 54 | func (in *SetattrIn) Chgtime() time.Time { 55 | return time.Unix(int64(in.Chgtime_), int64(in.ChgtimeNsec)) 56 | } 57 | 58 | func (in *SetattrIn) Flags() uint32 { 59 | return in.Flags_ 60 | } 61 | 62 | func openFlags(flags uint32) OpenFlags { 63 | return OpenFlags(flags) 64 | } 65 | 66 | type GetxattrIn struct { 67 | getxattrInCommon 68 | 69 | // OS X only 70 | Position uint32 71 | Padding uint32 72 | } 73 | 74 | func (g *GetxattrIn) GetPosition() uint32 { 75 | return g.Position 76 | } 77 | 78 | type SetxattrIn struct { 79 | setxattrInCommon 80 | 81 | // OS X only 82 | Position uint32 83 | Padding uint32 84 | } 85 | 86 | func (s *SetxattrIn) GetPosition() uint32 { 87 | return s.Position 88 | } 89 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/internal/fusekernel/protocol.go: -------------------------------------------------------------------------------- 1 | package fusekernel 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | // Protocol is a FUSE protocol version number. 8 | type Protocol struct { 9 | Major uint32 10 | Minor uint32 11 | } 12 | 13 | func (p Protocol) String() string { 14 | return fmt.Sprintf("%d.%d", p.Major, p.Minor) 15 | } 16 | 17 | // LT returns whether a is less than b. 18 | func (a Protocol) LT(b Protocol) bool { 19 | return a.Major < b.Major || 20 | (a.Major == b.Major && a.Minor < b.Minor) 21 | } 22 | 23 | // GE returns whether a is greater than or equal to b. 24 | func (a Protocol) GE(b Protocol) bool { 25 | return a.Major > b.Major || 26 | (a.Major == b.Major && a.Minor >= b.Minor) 27 | } 28 | 29 | func (a Protocol) is79() bool { 30 | return a.GE(Protocol{7, 9}) 31 | } 32 | 33 | // HasAttrBlockSize returns whether Attr.BlockSize is respected by the 34 | // kernel. 35 | func (a Protocol) HasAttrBlockSize() bool { 36 | return a.is79() 37 | } 38 | 39 | // HasReadWriteFlags returns whether ReadRequest/WriteRequest 40 | // fields Flags and FileFlags are valid. 41 | func (a Protocol) HasReadWriteFlags() bool { 42 | return a.is79() 43 | } 44 | 45 | // HasGetattrFlags returns whether GetattrRequest field Flags is 46 | // valid. 47 | func (a Protocol) HasGetattrFlags() bool { 48 | return a.is79() 49 | } 50 | 51 | func (a Protocol) is710() bool { 52 | return a.GE(Protocol{7, 10}) 53 | } 54 | 55 | // HasOpenNonSeekable returns whether OpenResponse field Flags flag 56 | // OpenNonSeekable is supported. 57 | func (a Protocol) HasOpenNonSeekable() bool { 58 | return a.is710() 59 | } 60 | 61 | func (a Protocol) is712() bool { 62 | return a.GE(Protocol{7, 12}) 63 | } 64 | 65 | // HasUmask returns whether CreateRequest/MkdirRequest/MknodRequest 66 | // field Umask is valid. 67 | func (a Protocol) HasUmask() bool { 68 | return a.is712() 69 | } 70 | 71 | // HasInvalidate returns whether InvalidateNode/InvalidateEntry are 72 | // supported. 73 | func (a Protocol) HasInvalidate() bool { 74 | return a.is712() 75 | } 76 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/dropbox/sharing/metadata.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) Dropbox, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package sharing 22 | 23 | import "encoding/json" 24 | 25 | type listSharedLinksResult struct { 26 | Links []sharedLinkMetadataUnion `json:"links"` 27 | HasMore bool `json:"has_more"` 28 | Cursor string `json:"cursor,omitempty"` 29 | } 30 | 31 | // UnmarshalJSON deserializes into a ListSharedLinksResult instance 32 | func (r *ListSharedLinksResult) UnmarshalJSON(b []byte) error { 33 | var l listSharedLinksResult 34 | if err := json.Unmarshal(b, &l); err != nil { 35 | return err 36 | } 37 | r.Cursor = l.Cursor 38 | r.HasMore = l.HasMore 39 | r.Links = make([]IsSharedLinkMetadata, len(l.Links)) 40 | for i, e := range l.Links { 41 | switch e.Tag { 42 | case "file": 43 | r.Links[i] = e.File 44 | case "folder": 45 | r.Links[i] = e.Folder 46 | } 47 | } 48 | return nil 49 | } 50 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/generator/go_rsrc/sharing/metadata.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) Dropbox, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package sharing 22 | 23 | import "encoding/json" 24 | 25 | type listSharedLinksResult struct { 26 | Links []sharedLinkMetadataUnion `json:"links"` 27 | HasMore bool `json:"has_more"` 28 | Cursor string `json:"cursor,omitempty"` 29 | } 30 | 31 | // UnmarshalJSON deserializes into a ListSharedLinksResult instance 32 | func (r *ListSharedLinksResult) UnmarshalJSON(b []byte) error { 33 | var l listSharedLinksResult 34 | if err := json.Unmarshal(b, &l); err != nil { 35 | return err 36 | } 37 | r.Cursor = l.Cursor 38 | r.HasMore = l.HasMore 39 | r.Links = make([]IsSharedLinkMetadata, len(l.Links)) 40 | for i, e := range l.Links { 41 | switch e.Tag { 42 | case "file": 43 | r.Links[i] = e.File 44 | case "folder": 45 | r.Links[i] = e.Folder 46 | } 47 | } 48 | return nil 49 | } 50 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | // +build linux 2 | 3 | package main 4 | 5 | //go:generate go get dev.hexasoftware.com/hxs/genversion 6 | //go:generate genversion -package main -out version.go 7 | 8 | import ( 9 | "fmt" 10 | "log" 11 | "os" 12 | 13 | "github.com/gohxs/cloudmount/internal/core" 14 | 15 | "github.com/gohxs/cloudmount/internal/fs/dropboxfs" 16 | "github.com/gohxs/cloudmount/internal/fs/gdrivefs" 17 | "github.com/gohxs/cloudmount/internal/fs/megafs" 18 | "github.com/gohxs/prettylog" 19 | 20 | "os/exec" 21 | ) 22 | 23 | var ( 24 | //Name app name 25 | Name = "cloudmount" 26 | ) 27 | 28 | func main() { 29 | // TODO: TEMP 30 | /*{ 31 | // Globally insecure SSL for debugging 32 | r, _ := http.NewRequest("GET", "http://localhost", nil) 33 | cli := &http.Client{} 34 | cli.Do(r) 35 | tr := http.DefaultTransport.(*http.Transport) 36 | tr.TLSClientConfig.InsecureSkipVerify = true 37 | }*/ 38 | 39 | prettylog.Global() 40 | 41 | fmt.Fprintf(os.Stderr, "%s-%s\n", Name, Version) 42 | // getClient 43 | c := core.New() 44 | 45 | // More will be added later 46 | c.Drivers["gdrive"] = gdrivefs.New 47 | c.Drivers["dropbox"] = dropboxfs.New 48 | c.Drivers["mega"] = megafs.New 49 | 50 | if err := parseFlags(&c.Config); err != nil { 51 | log.Fatalln(err) 52 | } 53 | 54 | err := c.Init() // Before daemon, because might require interactivity 55 | if err != nil { 56 | log.Println("Err:", err) 57 | return 58 | } 59 | fmt.Fprintf(os.Stderr, "%s on %s type %s\n", c.Config.Source, c.Config.Target, c.Config.Type) 60 | 61 | //////////////////////////////// 62 | // Daemon 63 | ///////////////// 64 | if !c.Config.Foreground { 65 | subArgs := []string{"-f"} 66 | for _, arg := range os.Args[1:] { 67 | if arg == "-f" { // ignore daemon flag, already added 68 | continue 69 | } 70 | subArgs = append(subArgs, arg) 71 | } 72 | 73 | cmd := exec.Command(os.Args[0], subArgs...) 74 | //cmd.Stdout = os.Stdout 75 | //cmd.Stderr = os.Stderr 76 | cmd.Start() 77 | fmt.Println("[PID]", cmd.Process.Pid) 78 | os.Exit(0) 79 | return 80 | } 81 | 82 | c.Mount() 83 | 84 | } 85 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/freelists.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package fuse 16 | 17 | import ( 18 | "unsafe" 19 | 20 | "github.com/jacobsa/fuse/internal/buffer" 21 | ) 22 | 23 | //////////////////////////////////////////////////////////////////////// 24 | // buffer.InMessage 25 | //////////////////////////////////////////////////////////////////////// 26 | 27 | // LOCKS_EXCLUDED(c.mu) 28 | func (c *Connection) getInMessage() (x *buffer.InMessage) { 29 | c.mu.Lock() 30 | x = (*buffer.InMessage)(c.inMessages.Get()) 31 | c.mu.Unlock() 32 | 33 | if x == nil { 34 | x = new(buffer.InMessage) 35 | } 36 | 37 | return 38 | } 39 | 40 | // LOCKS_EXCLUDED(c.mu) 41 | func (c *Connection) putInMessage(x *buffer.InMessage) { 42 | c.mu.Lock() 43 | c.inMessages.Put(unsafe.Pointer(x)) 44 | c.mu.Unlock() 45 | } 46 | 47 | //////////////////////////////////////////////////////////////////////// 48 | // buffer.OutMessage 49 | //////////////////////////////////////////////////////////////////////// 50 | 51 | // LOCKS_EXCLUDED(c.mu) 52 | func (c *Connection) getOutMessage() (x *buffer.OutMessage) { 53 | c.mu.Lock() 54 | x = (*buffer.OutMessage)(c.outMessages.Get()) 55 | c.mu.Unlock() 56 | 57 | if x == nil { 58 | x = new(buffer.OutMessage) 59 | } 60 | x.Reset() 61 | 62 | return 63 | } 64 | 65 | // LOCKS_EXCLUDED(c.mu) 66 | func (c *Connection) putOutMessage(x *buffer.OutMessage) { 67 | c.mu.Lock() 68 | c.outMessages.Put(unsafe.Pointer(x)) 69 | c.mu.Unlock() 70 | } 71 | -------------------------------------------------------------------------------- /vendor/github.com/t3rm1n4l/go-mega/README.md: -------------------------------------------------------------------------------- 1 | go-mega 2 | ======= 3 | 4 | A client library in go for mega.co.nz storage service. 5 | 6 | An implementation of command-line utility can be found at [https://github.com/t3rm1n4l/megacmd](https://github.com/t3rm1n4l/megacmd) 7 | 8 | [![Build Status](https://secure.travis-ci.org/t3rm1n4l/go-mega.png?branch=master)](http://travis-ci.org/t3rm1n4l/go-mega) 9 | 10 | ### What can i do with this library? 11 | This is an API client library for MEGA storage service. Currently, the library supports the basic APIs and operations as follows: 12 | - User login 13 | - Fetch filesystem tree 14 | - Upload file 15 | - Download file 16 | - Create directory 17 | - Move file or directory 18 | - Rename file or directory 19 | - Delete file or directory 20 | - Parallel split download and upload 21 | - Filesystem events auto sync 22 | - Unit tests 23 | 24 | ### API methods 25 | 26 | Please find full doc at [http://godoc.org/github.com/t3rm1n4l/go-mega](http://godoc.org/github.com/t3rm1n4l/go-mega) 27 | 28 | ### Testing 29 | 30 | export MEGA_USER= 31 | export MEGA_PASSWD= 32 | $ make test 33 | go test -v 34 | === RUN TestLogin 35 | --- PASS: TestLogin (1.90 seconds) 36 | === RUN TestGetUser 37 | --- PASS: TestGetUser (1.65 seconds) 38 | === RUN TestUploadDownload 39 | --- PASS: TestUploadDownload (12.28 seconds) 40 | === RUN TestMove 41 | --- PASS: TestMove (9.31 seconds) 42 | === RUN TestRename 43 | --- PASS: TestRename (9.16 seconds) 44 | === RUN TestDelete 45 | --- PASS: TestDelete (3.87 seconds) 46 | === RUN TestCreateDir 47 | --- PASS: TestCreateDir (2.34 seconds) 48 | === RUN TestConfig 49 | --- PASS: TestConfig (0.01 seconds) 50 | === RUN TestPathLookup 51 | --- PASS: TestPathLookup (8.54 seconds) 52 | === RUN TestEventNotify 53 | --- PASS: TestEventNotify (19.65 seconds) 54 | PASS 55 | ok github.com/t3rm1n4l/go-mega68.745s 56 | 57 | ### TODO 58 | - Implement APIs for public download url generation 59 | - Implement download from public url 60 | - Add shared user content management APIs 61 | - Add contact list management APIs 62 | 63 | ### License 64 | 65 | MIT 66 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/fusetesting/readdir.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package fusetesting 16 | 17 | import ( 18 | "fmt" 19 | "os" 20 | "path" 21 | "sort" 22 | ) 23 | 24 | type sortedEntries []os.FileInfo 25 | 26 | func (f sortedEntries) Len() int { return len(f) } 27 | func (f sortedEntries) Less(i, j int) bool { return f[i].Name() < f[j].Name() } 28 | func (f sortedEntries) Swap(i, j int) { f[i], f[j] = f[j], f[i] } 29 | 30 | // Read the directory with the given name and return a list of directory 31 | // entries, sorted by name. 32 | // 33 | // Unlike ioutil.ReadDir (cf. http://goo.gl/i0nNP4), this function does not 34 | // silently ignore "file not found" errors when stat'ing the names read from 35 | // the directory. 36 | func ReadDirPicky(dirname string) (entries []os.FileInfo, err error) { 37 | // Open the directory. 38 | f, err := os.Open(dirname) 39 | if err != nil { 40 | err = fmt.Errorf("Open: %v", err) 41 | return 42 | } 43 | 44 | // Don't forget to close it later. 45 | defer func() { 46 | closeErr := f.Close() 47 | if closeErr != nil && err == nil { 48 | err = fmt.Errorf("Close: %v", closeErr) 49 | } 50 | }() 51 | 52 | // Read all of the names from the directory. 53 | names, err := f.Readdirnames(-1) 54 | if err != nil { 55 | err = fmt.Errorf("Readdirnames: %v", err) 56 | return 57 | } 58 | 59 | // Stat each one. 60 | for _, name := range names { 61 | var fi os.FileInfo 62 | 63 | fi, err = os.Lstat(path.Join(dirname, name)) 64 | if err != nil { 65 | err = fmt.Errorf("Lstat(%s): %v", name, err) 66 | return 67 | } 68 | 69 | entries = append(entries, fi) 70 | } 71 | 72 | // Sort the entries by name. 73 | sort.Sort(sortedEntries(entries)) 74 | 75 | return 76 | } 77 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/generator/dropbox-api-spec/common.stone: -------------------------------------------------------------------------------- 1 | namespace common 2 | 3 | alias DropboxTimestamp = Timestamp("%Y-%m-%dT%H:%M:%SZ") 4 | 5 | alias Date = Timestamp("%Y-%m-%d") 6 | 7 | # Note - "\\." is needed in order to translate to "\." 8 | alias EmailAddress = String(pattern="^['&A-Za-z0-9._%+-]+@[A-Za-z0-9-][A-Za-z0-9.-]*.[A-Za-z]{2,15}$", max_length=255) 9 | 10 | # First name or Last name. NOTE: max_length should be synced with USER_NAME_MAX_LEN 11 | alias NamePart = String(pattern="[^\/:?*<>\"|]*", min_length=1, max_length=100) 12 | 13 | # Display name. We don't limit the length because it's always generated from the first & last names. 14 | alias DisplayName = String(pattern="[^\/:?*<>\"|]*", min_length=1) 15 | 16 | alias NamespaceId = String(pattern="[-_0-9a-zA-Z:]+") 17 | alias SharedFolderId = NamespaceId 18 | 19 | alias SessionId = String 20 | 21 | alias PathRootId = NamespaceId 22 | 23 | union PathRoot 24 | home 25 | "Paths are relative to the authenticating user's home directory, 26 | whether or not that user belongs to a team." 27 | 28 | member_home 29 | "Paths are relative to the authenticating team member's home 30 | directory. (This results in :field:`PathRootError.invalid' if the 31 | user does not belong to a team.)" 32 | 33 | team PathRootId 34 | "Paths are relative to the given team directory. (This results in 35 | :field:`PathRootError.invalid` if the user is not a member of 36 | the team associated with that path root id.)" 37 | 38 | user_home 39 | "Paths are relative to the user's home directory. (This results in 40 | :field:`PathRootError.invalid` if the belongs to a team.)" 41 | 42 | shared_folder PathRootId 43 | "Paths are relative to given shared folder id (This results in 44 | :field:`PathRootError.no_permission` if you don't have access 45 | to this shared folder.)" 46 | 47 | 48 | struct InvalidPathRootError 49 | path_root PathRootId? 50 | "The latest path root id for user's team if the user is still in 51 | a team." 52 | 53 | 54 | union PathRootError 55 | invalid InvalidPathRootError 56 | "The path root id value in Dropbox-API-Path-Root header is no longer 57 | valid." 58 | no_permission 59 | "You don't have permission to access the path root id in Dropbox-API-Path-Root 60 | header." 61 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/dropbox/files/metadata.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) Dropbox, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package files 22 | 23 | import "encoding/json" 24 | 25 | type listFolderResult struct { 26 | Entries []metadataUnion `json:"entries"` 27 | Cursor string `json:"cursor"` 28 | HasMore bool `json:"has_more"` 29 | } 30 | 31 | // UnmarshalJSON deserializes into a ListFolderResult instance 32 | func (r *ListFolderResult) UnmarshalJSON(b []byte) error { 33 | var l listFolderResult 34 | if err := json.Unmarshal(b, &l); err != nil { 35 | return err 36 | } 37 | r.Cursor = l.Cursor 38 | r.HasMore = l.HasMore 39 | r.Entries = make([]IsMetadata, len(l.Entries)) 40 | for i, e := range l.Entries { 41 | switch e.Tag { 42 | case "file": 43 | r.Entries[i] = e.File 44 | case "folder": 45 | r.Entries[i] = e.Folder 46 | case "deleted": 47 | r.Entries[i] = e.Deleted 48 | } 49 | } 50 | return nil 51 | } 52 | 53 | type searchMatch struct { 54 | MatchType *SearchMatchType `json:"match_type"` 55 | Metadata metadataUnion `json:"metadata"` 56 | } 57 | 58 | // UnmarshalJSON deserializes into a SearchMatch instance 59 | func (s *SearchMatch) UnmarshalJSON(b []byte) error { 60 | var m searchMatch 61 | if err := json.Unmarshal(b, &m); err != nil { 62 | return err 63 | } 64 | s.MatchType = m.MatchType 65 | e := m.Metadata 66 | switch e.Tag { 67 | case "file": 68 | s.Metadata = e.File 69 | case "folder": 70 | s.Metadata = e.Folder 71 | case "deleted": 72 | s.Metadata = e.Deleted 73 | } 74 | return nil 75 | } 76 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/generator/go_rsrc/files/metadata.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) Dropbox, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package files 22 | 23 | import "encoding/json" 24 | 25 | type listFolderResult struct { 26 | Entries []metadataUnion `json:"entries"` 27 | Cursor string `json:"cursor"` 28 | HasMore bool `json:"has_more"` 29 | } 30 | 31 | // UnmarshalJSON deserializes into a ListFolderResult instance 32 | func (r *ListFolderResult) UnmarshalJSON(b []byte) error { 33 | var l listFolderResult 34 | if err := json.Unmarshal(b, &l); err != nil { 35 | return err 36 | } 37 | r.Cursor = l.Cursor 38 | r.HasMore = l.HasMore 39 | r.Entries = make([]IsMetadata, len(l.Entries)) 40 | for i, e := range l.Entries { 41 | switch e.Tag { 42 | case "file": 43 | r.Entries[i] = e.File 44 | case "folder": 45 | r.Entries[i] = e.Folder 46 | case "deleted": 47 | r.Entries[i] = e.Deleted 48 | } 49 | } 50 | return nil 51 | } 52 | 53 | type searchMatch struct { 54 | MatchType *SearchMatchType `json:"match_type"` 55 | Metadata metadataUnion `json:"metadata"` 56 | } 57 | 58 | // UnmarshalJSON deserializes into a SearchMatch instance 59 | func (s *SearchMatch) UnmarshalJSON(b []byte) error { 60 | var m searchMatch 61 | if err := json.Unmarshal(b, &m); err != nil { 62 | return err 63 | } 64 | s.MatchType = m.MatchType 65 | e := m.Metadata 66 | switch e.Tag { 67 | case "file": 68 | s.Metadata = e.File 69 | case "folder": 70 | s.Metadata = e.Folder 71 | case "deleted": 72 | s.Metadata = e.Deleted 73 | } 74 | return nil 75 | } 76 | -------------------------------------------------------------------------------- /vendor/github.com/t3rm1n4l/go-mega/errors.go: -------------------------------------------------------------------------------- 1 | package mega 2 | 3 | import ( 4 | "errors" 5 | ) 6 | 7 | var ( 8 | // General errors 9 | EINTERNAL = errors.New("Internal error occured") 10 | EARGS = errors.New("Invalid arguments") 11 | EAGAIN = errors.New("Try again") 12 | ERATELIMIT = errors.New("Rate limit reached") 13 | EBADRESP = errors.New("Bad response from server") 14 | 15 | // Upload errors 16 | EFAILED = errors.New("The upload failed. Please restart it from scratch") 17 | ETOOMANY = errors.New("Too many concurrent IP addresses are accessing this upload target URL") 18 | ERANGE = errors.New("The upload file packet is out of range or not starting and ending on a chunk boundary") 19 | EEXPIRED = errors.New("The upload target URL you are trying to access has expired. Please request a fresh one") 20 | 21 | // Filesystem/Account errors 22 | ENOENT = errors.New("Object (typically, node or user) not found") 23 | ECIRCULAR = errors.New("Circular linkage attempted") 24 | EACCESS = errors.New("Access violation") 25 | EEXIST = errors.New("Trying to create an object that already exists") 26 | EINCOMPLETE = errors.New("Trying to access an incomplete resource") 27 | EKEY = errors.New("A decryption operation failed") 28 | ESID = errors.New("Invalid or expired user session, please relogin") 29 | EBLOCKED = errors.New("User blocked") 30 | EOVERQUOTA = errors.New("Request over quota") 31 | ETEMPUNAVAIL = errors.New("Resource temporarily not available, please try again later") 32 | EMACMISMATCH = errors.New("MAC verification failed") 33 | EBADATTR = errors.New("Bad node attribute") 34 | 35 | // Config errors 36 | EWORKER_LIMIT_EXCEEDED = errors.New("Maximum worker limit exceeded") 37 | ) 38 | 39 | type ErrorMsg int 40 | 41 | func parseError(errno ErrorMsg) error { 42 | switch { 43 | case errno == -1: 44 | return EINTERNAL 45 | case errno == -2: 46 | return EARGS 47 | case errno == -3: 48 | return EAGAIN 49 | case errno == -4: 50 | return ERATELIMIT 51 | case errno == -5: 52 | return EFAILED 53 | case errno == -6: 54 | return ETOOMANY 55 | case errno == -7: 56 | return ERANGE 57 | case errno == -8: 58 | return EEXPIRED 59 | case errno == -9: 60 | return ENOENT 61 | case errno == -10: 62 | return ECIRCULAR 63 | case errno == -11: 64 | return EACCESS 65 | case errno == -12: 66 | return EEXIST 67 | case errno == -13: 68 | return EINCOMPLETE 69 | case errno == -14: 70 | return EKEY 71 | case errno == -15: 72 | return ESID 73 | case errno == -16: 74 | return EBLOCKED 75 | case errno == -17: 76 | return EOVERQUOTA 77 | case errno == -18: 78 | return ETEMPUNAVAIL 79 | } 80 | 81 | return nil 82 | } 83 | -------------------------------------------------------------------------------- /flags.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "flag" 6 | "fmt" 7 | "log" 8 | "os" 9 | "path/filepath" 10 | 11 | "github.com/gohxs/cloudmount/internal/core" 12 | "github.com/gohxs/cloudmount/internal/coreutil" 13 | ) 14 | 15 | func parseFlags(config *core.Config) (err error) { 16 | var mountoptsFlag string 17 | 18 | flag.StringVar(&config.Type, "t", config.Type, "which cloud service to use [gdrive,dropbox]") 19 | flag.BoolVar(&config.Foreground, "f", false, "Run app in foreground") 20 | flag.BoolVar(&config.VerboseLog, "v", false, "Verbose log") 21 | flag.BoolVar(&config.Verbose2Log, "vv", false, "Extra Verbose log") 22 | flag.StringVar(&config.HomeDir, "w", config.HomeDir, "Work dir, path that holds configurations") 23 | flag.DurationVar(&config.RefreshTime, "r", config.RefreshTime, "Timed cloud synchronization interval [if applied]") 24 | 25 | flag.StringVar(&mountoptsFlag, "o", "", fmt.Sprintf("%v", config.Options)) 26 | 27 | flag.Usage = func() { 28 | fmt.Fprintf(os.Stderr, "\n") 29 | fmt.Fprintf(os.Stderr, "Usage: %s [options] [] \n\n", os.Args[0]) 30 | fmt.Fprintf(os.Stderr, "Source: can be json/yaml configuration file usually with credentials or cloud specific configuration\n\n") 31 | fmt.Fprintf(os.Stderr, "Options:\n") 32 | flag.PrintDefaults() 33 | fmt.Fprintf(os.Stderr, "\n") 34 | } 35 | flag.Parse() 36 | 37 | fileExt := filepath.Ext(os.Args[0]) 38 | if fileExt != "" { 39 | if config.Type != "" { 40 | log.Fatal("Cannot specify -t when type is specified in executable name") 41 | } 42 | config.Type = fileExt[1:] 43 | } 44 | 45 | if flag.NArg() < 1 { 46 | flag.Usage() 47 | //fmt.Println("Usage:\n gdrivemount [-d] [-v] ") 48 | return errors.New("Missing parameter") 49 | } 50 | if flag.NArg() == 1 { 51 | config.Source = filepath.Join(config.HomeDir, config.Type+".yaml") 52 | config.Target = flag.Arg(0) 53 | } else { 54 | config.Source = flag.Arg(0) 55 | config.Target = flag.Arg(1) 56 | } 57 | 58 | if config.Verbose2Log { 59 | config.VerboseLog = true 60 | } 61 | 62 | // Read fs type from config file 63 | sourceType := struct { 64 | Type string `json:"type"` 65 | }{} 66 | coreutil.ParseConfig(config.Source, &sourceType) 67 | if sourceType.Type != "" { 68 | if config.Type != "" && sourceType.Type != config.Type { 69 | log.Fatalf("ERR: service mismatch specifies '%s' while flag -t is '%s'", sourceType.Type, config.Type) 70 | } 71 | config.Type = sourceType.Type 72 | } 73 | 74 | if config.Type == "" { 75 | log.Fatalf("ERR: Missing -t param, unknown file system") 76 | } 77 | 78 | err = coreutil.ParseOptions(mountoptsFlag, &config.Options) 79 | if err != nil { 80 | log.Fatal("ERR: Invalid syntax parsing mount options") 81 | } 82 | return 83 | } 84 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/generator/dropbox-api-spec/team_log.stone: -------------------------------------------------------------------------------- 1 | namespace team_log 2 | 3 | import async 4 | import team 5 | import team_common 6 | import users_common 7 | 8 | ############################### 9 | # Routes declarations 10 | ############################### 11 | 12 | struct GetTeamEventsArg 13 | limit UInt32(min_value=1, max_value=1000) = 1000 14 | "Number of results to return per call." 15 | account_id users_common.AccountId? 16 | "Filter the events by account ID. Return ony events with this account_id as either 17 | Actor, Context, or Participants." 18 | time team_common.TimeRange? 19 | "Filter by time range." 20 | # category filtering is disablled for now. to be enabled when 21 | # TeamEventGetEvents.SUPPORT_CATEGORY_BASED_FILTERING_FLAG is changed 22 | # category EventCategory? 23 | # "Filter the returned events to a single category." 24 | 25 | example default 26 | limit=50 27 | #category=groups 28 | 29 | 30 | struct GetTeamEventsResult 31 | events List(TeamEvent) 32 | "List of events." 33 | cursor String 34 | "Pass the cursor into :route:`get_events/continue` to obtain additional events." 35 | has_more Boolean 36 | "Is true if there are additional events that have not been returned yet. 37 | An additional call to :route:`get_events/continue` can retrieve them." 38 | 39 | example default 40 | events = [default] 41 | cursor = "ZtkX9_EHj3x7PMkVuFIhwKYXEpwpLwyxp9vMKomUhllil9q7eWiAu" 42 | has_more = false 43 | 44 | union GetTeamEventsError 45 | "Errors that can be raised when calling :route:`get_events`." 46 | 47 | account_id_not_found 48 | "No user found matching the provided account_id." 49 | invalid_time_range 50 | "Invalid time range." 51 | 52 | example default 53 | account_id_not_found = null 54 | 55 | route get_events(GetTeamEventsArg, GetTeamEventsResult, GetTeamEventsError) 56 | "Retrieves team events. 57 | 58 | Permission : Team Auditing." 59 | 60 | attrs 61 | auth = "team" 62 | owner = "adminx" 63 | is_preview = true 64 | 65 | struct GetTeamEventsContinueArg 66 | cursor String 67 | "Indicates from what point to get the next set of events." 68 | 69 | example default 70 | cursor = "ZtkX9_EHj3x7PMkVuFIhwKYXEpwpLwyxp9vMKomUhllil9q7eWiAu" 71 | 72 | 73 | union GetTeamEventsContinueError 74 | "Errors that can be raised when calling :route:`get_events/continue`." 75 | 76 | bad_cursor 77 | "Bad cursor." 78 | 79 | example default 80 | bad_cursor = null 81 | 82 | route get_events/continue(GetTeamEventsContinueArg, GetTeamEventsResult, GetTeamEventsContinueError) 83 | "Once a cursor has been retrieved from :route:`get_events`, use this to paginate through all events. 84 | 85 | Permission : Team Auditing." 86 | 87 | attrs 88 | auth = "team" 89 | owner = "adminx" 90 | is_preview = true 91 | -------------------------------------------------------------------------------- /boiler/templates/fs/service.go.boiler: -------------------------------------------------------------------------------- 1 | package {{.name}}fs 2 | 3 | import ( 4 | "io" 5 | 6 | "github.com/gohxs/cloudmount/internal/core" 7 | "github.com/gohxs/cloudmount/internal/coreutil" 8 | "github.com/gohxs/cloudmount/internal/fs/basefs" 9 | ) 10 | 11 | 12 | 13 | //Service gdrive service information 14 | type Service struct { 15 | // raw client to access service 16 | 17 | } 18 | 19 | //NewService creates and initializes a new GDrive service 20 | func NewService(coreConfig *core.Config) *Service { 21 | 22 | serviceConfig := Config{} 23 | log.Println("Initializing",name,"service") 24 | log.Println("Source config:", coreConfig.Source) 25 | 26 | err := coreutil.ParseConfig(coreConfig.Source, &serviceConfig) 27 | if err != nil { 28 | errlog.Fatalf("Unable to read : %v", err) 29 | } 30 | // Initialize cloud service here 31 | 32 | return nil 33 | //return &Service{...} 34 | 35 | } 36 | 37 | //Changes populate a list with changes to be handled on basefs 38 | // Returns a list with fs changes from cloud service 39 | func (s *Service) Changes() ([]*basefs.Change, error) { 40 | return nil, basefs.ErrNotImplemented 41 | } 42 | 43 | //ListAll lists all files recursively to cache locally 44 | // Return a list of all file entries 45 | func (s *Service) ListAll() ([]*basefs.File, error) { 46 | return nil, basefs.ErrNotImplemented 47 | } 48 | 49 | //Create create an entry in google drive 50 | func (s *Service) Create(parent *basefs.File, name string, isDir bool) (*basefs.File, error) { 51 | return nil, basefs.ErrNotImplemented 52 | } 53 | 54 | //Upload a file 55 | func (s *Service) Upload(reader io.Reader, file *basefs.File) (*basefs.File, error) { 56 | return nil, basefs.ErrNotImplemented 57 | } 58 | 59 | //DownloadTo from gdrive to a writer 60 | func (s *Service) DownloadTo(w io.Writer, file *basefs.File) error { 61 | return basefs.ErrNotImplemented 62 | } 63 | 64 | //Move a file in drive 65 | func (s *Service) Move(file *basefs.File, newParent *basefs.File, name string) (*basefs.File, error) { 66 | return nil, basefs.ErrNotImplemented 67 | } 68 | 69 | //Delete file from drive 70 | func (s *Service) Delete(file *basefs.File) error { 71 | return basefs.ErrNotImplemented 72 | } 73 | 74 | //Example: File converts a google drive File structure to baseFS 75 | /* from drivefs 76 | func File( service file here ) *basefs.File { 77 | if gfile == nil { 78 | return nil 79 | } 80 | 81 | createdTime, _ := time.Parse(time.RFC3339, gfile.CreatedTime) 82 | modifiedTime, _ := time.Parse(time.RFC3339, gfile.ModifiedTime) 83 | 84 | mode := os.FileMode(0644) 85 | if gfile.MimeType == "application/vnd.google-apps.folder" { 86 | mode = os.FileMode(0755) | os.ModeDir 87 | } 88 | 89 | file := &basefs.File{ 90 | ID: gfile.Id, 91 | Name: gfile.Name, 92 | Size: uint64(gfile.Size), 93 | CreatedTime: createdTime, 94 | ModifiedTime: modifiedTime, 95 | AccessedTime: modifiedTime, 96 | Mode: mode, 97 | 98 | Parents: gfile.Parents, 99 | Data: gfile, // Extra gfile 100 | } 101 | return file 102 | }*/ 103 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/generator/dropbox-api-spec/team_policies.stone: -------------------------------------------------------------------------------- 1 | namespace team_policies 2 | 3 | struct TeamMemberPolicies 4 | "Policies governing team members." 5 | 6 | sharing TeamSharingPolicies 7 | "Policies governing sharing." 8 | emm_state EmmState 9 | "This describes the Enterprise Mobility Management (EMM) state for this team. 10 | This information can be used to understand if an organization is integrating with 11 | a third-party EMM vendor to further manage and apply restrictions upon the team's 12 | Dropbox usage on mobile devices. 13 | This is a new feature and in the future we'll be adding more new fields and additional 14 | documentation." 15 | 16 | example default 17 | sharing = default 18 | emm_state = disabled 19 | 20 | struct TeamSharingPolicies 21 | "Policies governing sharing within and outside of the team." 22 | 23 | shared_folder_member_policy SharedFolderMemberPolicy 24 | "Who can join folders shared by team members." 25 | shared_folder_join_policy SharedFolderJoinPolicy 26 | "Which shared folders team members can join." 27 | shared_link_create_policy SharedLinkCreatePolicy 28 | "Who can view shared links owned by team members." 29 | 30 | example default 31 | shared_folder_member_policy = team 32 | shared_folder_join_policy = from_anyone 33 | shared_link_create_policy = team_only 34 | 35 | # NOTE: we do not reuse sharing.MemberPolicy here since we may want to enable folder-specific member 36 | # policies that work on top of the broader team policies. 37 | union SharedFolderMemberPolicy 38 | "Policy governing who can be a member of a folder shared by a team member." 39 | 40 | team 41 | "Only a teammate can be a member of a folder shared by a team member." 42 | anyone 43 | "Anyone can be a member of a folder shared by a team member." 44 | 45 | union SharedFolderJoinPolicy 46 | "Policy governing which shared folders a team member can join." 47 | 48 | from_team_only 49 | "Team members can only join folders shared by teammates." 50 | from_anyone 51 | "Team members can join any shared folder, including those shared by users outside the team." 52 | 53 | union SharedLinkCreatePolicy 54 | "Policy governing the visibility of shared links. This policy can apply to newly created shared 55 | links, or all shared links." 56 | 57 | default_public 58 | "By default, anyone can access newly created shared links. 59 | No login will be required to access the shared links unless overridden." 60 | default_team_only 61 | "By default, only members of the same team can access newly created shared links. 62 | Login will be required to access the shared links unless overridden." 63 | team_only 64 | "Only members of the same team can access all shared links. 65 | Login will be required to access all shared links." 66 | 67 | union EmmState 68 | disabled 69 | "Emm token is disabled" 70 | optional 71 | "Emm token is optional" 72 | required 73 | "Emm token is required" 74 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/mount.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package fuse 16 | 17 | import ( 18 | "fmt" 19 | "os" 20 | 21 | "golang.org/x/net/context" 22 | ) 23 | 24 | // Server is an interface for any type that knows how to serve ops read from a 25 | // connection. 26 | type Server interface { 27 | // Read and serve ops from the supplied connection until EOF. Do not return 28 | // until all operations have been responded to. Must not be called more than 29 | // once. 30 | ServeOps(*Connection) 31 | } 32 | 33 | // Mount attempts to mount a file system on the given directory, using the 34 | // supplied Server to serve connection requests. It blocks until the file 35 | // system is successfully mounted. 36 | func Mount( 37 | dir string, 38 | server Server, 39 | config *MountConfig) (mfs *MountedFileSystem, err error) { 40 | // Sanity check: make sure the mount point exists and is a directory. This 41 | // saves us from some confusing errors later on OS X. 42 | fi, err := os.Stat(dir) 43 | switch { 44 | case os.IsNotExist(err): 45 | return 46 | 47 | case err != nil: 48 | err = fmt.Errorf("Statting mount point: %v", err) 49 | return 50 | 51 | case !fi.IsDir(): 52 | err = fmt.Errorf("Mount point %s is not a directory", dir) 53 | return 54 | } 55 | 56 | // Initialize the struct. 57 | mfs = &MountedFileSystem{ 58 | dir: dir, 59 | joinStatusAvailable: make(chan struct{}), 60 | } 61 | 62 | // Begin the mounting process, which will continue in the background. 63 | ready := make(chan error, 1) 64 | dev, err := mount(dir, config, ready) 65 | if err != nil { 66 | err = fmt.Errorf("mount: %v", err) 67 | return 68 | } 69 | 70 | // Choose a parent context for ops. 71 | cfgCopy := *config 72 | if cfgCopy.OpContext == nil { 73 | cfgCopy.OpContext = context.Background() 74 | } 75 | 76 | // Create a Connection object wrapping the device. 77 | connection, err := newConnection( 78 | cfgCopy, 79 | config.DebugLogger, 80 | config.ErrorLogger, 81 | dev) 82 | 83 | if err != nil { 84 | err = fmt.Errorf("newConnection: %v", err) 85 | return 86 | } 87 | 88 | // Serve the connection in the background. When done, set the join status. 89 | go func() { 90 | server.ServeOps(connection) 91 | mfs.joinStatus = connection.close() 92 | close(mfs.joinStatusAvailable) 93 | }() 94 | 95 | // Wait for the mount process to complete. 96 | if err = <-ready; err != nil { 97 | err = fmt.Errorf("mount (background): %v", err) 98 | return 99 | } 100 | 101 | return 102 | } 103 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/mount_linux.go: -------------------------------------------------------------------------------- 1 | package fuse 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "net" 7 | "os" 8 | "os/exec" 9 | "syscall" 10 | ) 11 | 12 | // Begin the process of mounting at the given directory, returning a connection 13 | // to the kernel. Mounting continues in the background, and is complete when an 14 | // error is written to the supplied channel. The file system may need to 15 | // service the connection in order for mounting to complete. 16 | func mount( 17 | dir string, 18 | cfg *MountConfig, 19 | ready chan<- error) (dev *os.File, err error) { 20 | // On linux, mounting is never delayed. 21 | ready <- nil 22 | 23 | // Create a socket pair. 24 | fds, err := syscall.Socketpair(syscall.AF_FILE, syscall.SOCK_STREAM, 0) 25 | if err != nil { 26 | err = fmt.Errorf("Socketpair: %v", err) 27 | return 28 | } 29 | 30 | // Wrap the sockets into os.File objects that we will pass off to fusermount. 31 | writeFile := os.NewFile(uintptr(fds[0]), "fusermount-child-writes") 32 | defer writeFile.Close() 33 | 34 | readFile := os.NewFile(uintptr(fds[1]), "fusermount-parent-reads") 35 | defer readFile.Close() 36 | 37 | // Start fusermount, passing it a buffer in which to write stderr. 38 | var stderr bytes.Buffer 39 | 40 | cmd := exec.Command( 41 | "fusermount", 42 | "-o", cfg.toOptionsString(), 43 | "--", 44 | dir, 45 | ) 46 | 47 | cmd.Env = append(os.Environ(), "_FUSE_COMMFD=3") 48 | cmd.ExtraFiles = []*os.File{writeFile} 49 | cmd.Stderr = &stderr 50 | 51 | // Run the command. 52 | err = cmd.Run() 53 | if err != nil { 54 | err = fmt.Errorf("running fusermount: %v\n\nstderr:\n%s", err, stderr.Bytes()) 55 | return 56 | } 57 | 58 | // Wrap the socket file in a connection. 59 | c, err := net.FileConn(readFile) 60 | if err != nil { 61 | err = fmt.Errorf("FileConn: %v", err) 62 | return 63 | } 64 | defer c.Close() 65 | 66 | // We expect to have a Unix domain socket. 67 | uc, ok := c.(*net.UnixConn) 68 | if !ok { 69 | err = fmt.Errorf("Expected UnixConn, got %T", c) 70 | return 71 | } 72 | 73 | // Read a message. 74 | buf := make([]byte, 32) // expect 1 byte 75 | oob := make([]byte, 32) // expect 24 bytes 76 | _, oobn, _, _, err := uc.ReadMsgUnix(buf, oob) 77 | if err != nil { 78 | err = fmt.Errorf("ReadMsgUnix: %v", err) 79 | return 80 | } 81 | 82 | // Parse the message. 83 | scms, err := syscall.ParseSocketControlMessage(oob[:oobn]) 84 | if err != nil { 85 | err = fmt.Errorf("ParseSocketControlMessage: %v", err) 86 | return 87 | } 88 | 89 | // We expect one message. 90 | if len(scms) != 1 { 91 | err = fmt.Errorf("expected 1 SocketControlMessage; got scms = %#v", scms) 92 | return 93 | } 94 | 95 | scm := scms[0] 96 | 97 | // Pull out the FD returned by fusermount 98 | gotFds, err := syscall.ParseUnixRights(&scm) 99 | if err != nil { 100 | err = fmt.Errorf("syscall.ParseUnixRights: %v", err) 101 | return 102 | } 103 | 104 | if len(gotFds) != 1 { 105 | err = fmt.Errorf("wanted 1 fd; got %#v", gotFds) 106 | return 107 | } 108 | 109 | // Turn the FD into an os.File. 110 | dev = os.NewFile(uintptr(gotFds[0]), "/dev/fuse") 111 | 112 | return 113 | } 114 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/samples/errorfs/error_fs_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package errorfs_test 16 | 17 | import ( 18 | "io/ioutil" 19 | "os" 20 | "path" 21 | "reflect" 22 | "syscall" 23 | "testing" 24 | 25 | "github.com/jacobsa/fuse/fuseops" 26 | "github.com/jacobsa/fuse/fuseutil" 27 | "github.com/jacobsa/fuse/samples" 28 | "github.com/jacobsa/fuse/samples/errorfs" 29 | . "github.com/jacobsa/oglematchers" 30 | . "github.com/jacobsa/ogletest" 31 | ) 32 | 33 | func TestErrorFS(t *testing.T) { RunTests(t) } 34 | 35 | //////////////////////////////////////////////////////////////////////// 36 | // Boilerplate 37 | //////////////////////////////////////////////////////////////////////// 38 | 39 | type ErrorFSTest struct { 40 | samples.SampleTest 41 | fs errorfs.FS 42 | } 43 | 44 | func init() { RegisterTestSuite(&ErrorFSTest{}) } 45 | 46 | var _ SetUpInterface = &ErrorFSTest{} 47 | var _ TearDownInterface = &ErrorFSTest{} 48 | 49 | func (t *ErrorFSTest) SetUp(ti *TestInfo) { 50 | var err error 51 | 52 | // Create the file system. 53 | t.fs, err = errorfs.New() 54 | AssertEq(nil, err) 55 | 56 | t.Server = fuseutil.NewFileSystemServer(t.fs) 57 | 58 | // Mount it. 59 | t.SampleTest.SetUp(ti) 60 | } 61 | 62 | //////////////////////////////////////////////////////////////////////// 63 | // Tests 64 | //////////////////////////////////////////////////////////////////////// 65 | 66 | func (t *ErrorFSTest) OpenFile() { 67 | t.fs.SetError(reflect.TypeOf(&fuseops.OpenFileOp{}), syscall.EOWNERDEAD) 68 | 69 | f, err := os.Open(path.Join(t.Dir, "foo")) 70 | defer f.Close() 71 | ExpectThat(err, Error(MatchesRegexp("open.*: .*owner died"))) 72 | } 73 | 74 | func (t *ErrorFSTest) ReadFile() { 75 | t.fs.SetError(reflect.TypeOf(&fuseops.ReadFileOp{}), syscall.EOWNERDEAD) 76 | 77 | // Open 78 | f, err := os.Open(path.Join(t.Dir, "foo")) 79 | defer f.Close() 80 | AssertEq(nil, err) 81 | 82 | // Read 83 | _, err = ioutil.ReadAll(f) 84 | ExpectThat(err, Error(MatchesRegexp("read.*: .*owner died"))) 85 | } 86 | 87 | func (t *ErrorFSTest) OpenDir() { 88 | t.fs.SetError(reflect.TypeOf(&fuseops.OpenDirOp{}), syscall.EOWNERDEAD) 89 | 90 | f, err := os.Open(t.Dir) 91 | defer f.Close() 92 | ExpectThat(err, Error(MatchesRegexp("open.*: .*owner died"))) 93 | } 94 | 95 | func (t *ErrorFSTest) ReadDir() { 96 | t.fs.SetError(reflect.TypeOf(&fuseops.ReadDirOp{}), syscall.EOWNERDEAD) 97 | 98 | // Open 99 | f, err := os.Open(t.Dir) 100 | defer f.Close() 101 | AssertEq(nil, err) 102 | 103 | // Read 104 | _, err = f.Readdirnames(1) 105 | ExpectThat(err, Error(MatchesRegexp("read.*: .*owner died"))) 106 | } 107 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/generator/dropbox-api-spec/auth.stone: -------------------------------------------------------------------------------- 1 | namespace auth 2 | 3 | union AuthError 4 | "Errors occurred during authentication." 5 | 6 | invalid_access_token 7 | "The access token is invalid." 8 | invalid_select_user 9 | "The user specified in 'Dropbox-API-Select-User' is no longer on the team." 10 | invalid_select_admin 11 | "The user specified in 'Dropbox-API-Select-Admin' is not a Dropbox Business team admin." 12 | user_suspended 13 | "The user has been suspended." 14 | 15 | route token/revoke(Void, Void, Void) 16 | "Disables the access token used to authenticate the call." 17 | 18 | attrs 19 | owner = "dev-plat" 20 | allow_app_folder_app = true 21 | 22 | union RateLimitReason 23 | too_many_requests 24 | "You are making too many requests in the past few minutes." 25 | too_many_write_operations 26 | "There are currently too many write operations happening in the user's Dropbox." 27 | 28 | struct RateLimitError 29 | "Error occurred because the app is being rate limited." 30 | 31 | reason RateLimitReason 32 | "The reason why the app is being rate limited." 33 | 34 | retry_after UInt64 = 1 35 | "The number of seconds that the app should wait 36 | before making another request." 37 | 38 | # 39 | # OAuth 1.0 token conversion 40 | # 41 | 42 | struct TokenFromOAuth1Arg 43 | oauth1_token String(min_length=1) 44 | "The supplied OAuth 1.0 access token." 45 | oauth1_token_secret String(min_length=1) 46 | "The token secret associated with the supplied access token." 47 | 48 | example default 49 | oauth1_token = "qievr8hamyg6ndck" 50 | oauth1_token_secret = "qomoftv0472git7" 51 | 52 | struct TokenFromOAuth1Result 53 | oauth2_token String(min_length=1) 54 | "The OAuth 2.0 token generated from the supplied OAuth 1.0 token." 55 | 56 | example default 57 | oauth2_token = "9mCrkS7BIdAAAAAAAAAAHHS0TsSnpYvKQVtKdBnN5IuzhYOGblSgTcHgBFKFMmFn" 58 | 59 | union TokenFromOAuth1Error 60 | invalid_oauth1_token_info 61 | "Part or all of the OAuth 1.0 access token info is invalid." 62 | app_id_mismatch 63 | "The authorized app does not match the app associated with the supplied access token." 64 | 65 | route token/from_oauth1(TokenFromOAuth1Arg, TokenFromOAuth1Result, TokenFromOAuth1Error) 66 | "Creates an OAuth 2.0 access token from the supplied OAuth 1.0 access token." 67 | attrs 68 | auth = "app" 69 | owner = "dev-plat" 70 | allow_app_folder_app = true 71 | 72 | union AccessError 73 | "Error occurred because the account doesn't have permission to access the resource." 74 | 75 | invalid_account_type InvalidAccountTypeError 76 | "Current account type cannot access the resource." 77 | 78 | paper_access_denied PaperAccessError 79 | "Current account cannot access Paper." 80 | 81 | union PaperAccessError 82 | paper_disabled 83 | "Paper is disabled." 84 | not_paper_user 85 | "The provided user has not used Paper yet." 86 | 87 | union InvalidAccountTypeError 88 | endpoint 89 | "Current account type doesn't have permission to access this route endpoint." 90 | feature 91 | "Current account type doesn't have permission to access this feature." 92 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/generator/dropbox-api-spec/async.stone: -------------------------------------------------------------------------------- 1 | namespace async 2 | 3 | # 4 | # Types for writing asynchronous API methods. 5 | # 6 | # There are two calls for each asynchronous method: 7 | # 1. A "Launch" method that (optionally) launches the asynchronous job 8 | # 2. A "Polling" method that polls for the status of the job that was launched by the first call. 9 | # 10 | # The following definitions are prefixed by "Launch" or "Poll", according to their intended use. 11 | 12 | 13 | alias AsyncJobId = String(min_length=1) 14 | 15 | 16 | # 17 | # Launch 18 | # 19 | 20 | union_closed LaunchResultBase 21 | "Result returned by methods that launch an asynchronous job. 22 | 23 | A method who may either launch an asynchronous job, or complete the request 24 | synchronously, can use this union by extending it, and adding a 'complete' field 25 | with the type of the synchronous response. 26 | 27 | See :type:`LaunchEmptyResult` for an example." 28 | 29 | async_job_id AsyncJobId 30 | "This response indicates that the processing is asynchronous. 31 | The string is an id that can be used to obtain the status of the asynchronous job." 32 | 33 | 34 | union_closed LaunchEmptyResult extends LaunchResultBase 35 | "Result returned by methods that may either launch an asynchronous job or complete synchronously. 36 | Upon synchronous completion of the job, no additional information is returned." 37 | 38 | complete 39 | "The job finished synchronously and successfully." 40 | 41 | example complete 42 | complete = null 43 | 44 | example async_job_id 45 | async_job_id = "34g93hh34h04y384084" 46 | 47 | # 48 | # Poll 49 | # 50 | 51 | struct PollArg 52 | "Arguments for methods that poll the status of an asynchronous job." 53 | 54 | async_job_id AsyncJobId 55 | "Id of the asynchronous job. 56 | This is the value of a response returned from the method that launched the job." 57 | 58 | example default 59 | async_job_id = "34g93hh34h04y384084" 60 | 61 | # TODO(kelkabany): Remove `error_msg` since others might want to return it 62 | # differently. 63 | union_closed PollResultBase 64 | "Result returned by methods that poll for the status of an asynchronous job. 65 | Unions that extend this union should add a 'complete' field with a type of 66 | the information returned upon job completion. 67 | 68 | See :type:`PollEmptyResult` for an example." 69 | 70 | in_progress 71 | "The asynchronous job is still in progress." 72 | 73 | 74 | union_closed PollEmptyResult extends PollResultBase 75 | "Result returned by methods that poll for the status of an asynchronous job. 76 | Upon completion of the job, no additional information is returned." 77 | 78 | complete 79 | "The asynchronous job has completed successfully." 80 | 81 | example complete 82 | complete = null 83 | 84 | example in_progress 85 | in_progress = null 86 | 87 | 88 | union PollError 89 | "Error returned by methods for polling the status of asynchronous job." 90 | 91 | invalid_async_job_id 92 | "The job ID is invalid." 93 | internal_error 94 | "Something went wrong with the job on Dropbox's end. You'll need to 95 | verify that the action you were taking succeeded, and if not, try 96 | again. This should happen very rarely." 97 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/generator/dropbox-api-spec/team_property_templates.stone: -------------------------------------------------------------------------------- 1 | namespace team 2 | 3 | import properties 4 | 5 | # 6 | # Property Group Template Routes 7 | # 8 | 9 | route properties/template/add(AddPropertyTemplateArg, AddPropertyTemplateResult, properties.ModifyPropertyTemplateError) 10 | "Add a property template. See route files/properties/add to add properties to a file." 11 | 12 | attrs 13 | auth="team" 14 | api_group="properties" 15 | is_preview=true 16 | owner="dev-plat" 17 | 18 | route properties/template/update(UpdatePropertyTemplateArg, UpdatePropertyTemplateResult, properties.ModifyPropertyTemplateError) 19 | "Update a property template. This route can update the template name, 20 | the template description and add optional properties to templates." 21 | 22 | attrs 23 | auth="team" 24 | api_group="properties" 25 | is_preview=true 26 | owner="dev-plat" 27 | 28 | route properties/template/get(properties.GetPropertyTemplateArg, properties.GetPropertyTemplateResult, properties.PropertyTemplateError) 29 | "Get the schema for a specified template." 30 | 31 | attrs 32 | auth="team" 33 | api_group="properties" 34 | is_preview=true 35 | owner="dev-plat" 36 | 37 | route properties/template/list(Void, properties.ListPropertyTemplateIds, properties.PropertyTemplateError) 38 | "Get the property template identifiers for a team. To get the schema of 39 | each template use :route:`properties/template/get`." 40 | 41 | attrs 42 | auth="team" 43 | api_group="properties" 44 | is_preview=true 45 | owner="dev-plat" 46 | 47 | struct AddPropertyTemplateArg extends properties.PropertyGroupTemplate 48 | "Arguments for adding property templates." 49 | 50 | example default 51 | name = "Security" 52 | description = "These properties describe how confidential this file is." 53 | fields = [default] 54 | 55 | struct AddPropertyTemplateResult 56 | template_id properties.TemplateId 57 | "An identifier for property template added by :route:`properties/template/add`." 58 | 59 | example default 60 | template_id = "ptid:1a5n2i6d3OYEAAAAAAAAAYa" 61 | 62 | struct UpdatePropertyTemplateArg 63 | template_id properties.TemplateId 64 | "An identifier for property template added by :route:`properties/template/add`." 65 | name String? 66 | "A display name for the property template. Property template names can 67 | be up to 256 bytes." 68 | description String? 69 | "Description for new property template. Property template descriptions 70 | can be up to 1024 bytes." 71 | add_fields List(properties.PropertyFieldTemplate)? 72 | "This is a list of custom properties to add to the property template. 73 | There can be up to 64 properties in a single property template." 74 | 75 | example default 76 | template_id = "ptid:1a5n2i6d3OYEAAAAAAAAAYa" 77 | name = "New Security Template Name" 78 | description = "These properties will describe how confidential this file is." 79 | add_fields = [default] 80 | 81 | struct UpdatePropertyTemplateResult 82 | template_id properties.TemplateId 83 | "An identifier for property template added by :route:`properties/template/add`." 84 | 85 | example default 86 | template_id = "ptid:1a5n2i6d3OYEAAAAAAAAAYa" 87 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/internal/buffer/in_message.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package buffer 16 | 17 | import ( 18 | "fmt" 19 | "io" 20 | "syscall" 21 | "unsafe" 22 | 23 | "github.com/jacobsa/fuse/internal/fusekernel" 24 | ) 25 | 26 | // All requests read from the kernel, without data, are shorter than 27 | // this. 28 | const pageSize = 4096 29 | 30 | func init() { 31 | // Confirm the page size. 32 | if syscall.Getpagesize() != pageSize { 33 | panic(fmt.Sprintf("Page size is unexpectedly %d", syscall.Getpagesize())) 34 | } 35 | } 36 | 37 | // We size the buffer to have enough room for a fuse request plus data 38 | // associated with a write request. 39 | const bufSize = pageSize + MaxWriteSize 40 | 41 | // An incoming message from the kernel, including leading fusekernel.InHeader 42 | // struct. Provides storage for messages and convenient access to their 43 | // contents. 44 | type InMessage struct { 45 | remaining []byte 46 | storage [bufSize]byte 47 | } 48 | 49 | // Initialize with the data read by a single call to r.Read. The first call to 50 | // Consume will consume the bytes directly after the fusekernel.InHeader 51 | // struct. 52 | func (m *InMessage) Init(r io.Reader) (err error) { 53 | n, err := r.Read(m.storage[:]) 54 | if err != nil { 55 | return 56 | } 57 | 58 | // Make sure the message is long enough. 59 | const headerSize = unsafe.Sizeof(fusekernel.InHeader{}) 60 | if uintptr(n) < headerSize { 61 | err = fmt.Errorf("Unexpectedly read only %d bytes.", n) 62 | return 63 | } 64 | 65 | m.remaining = m.storage[headerSize:n] 66 | 67 | // Check the header's length. 68 | if int(m.Header().Len) != n { 69 | err = fmt.Errorf( 70 | "Header says %d bytes, but we read %d", 71 | m.Header().Len, 72 | n) 73 | 74 | return 75 | } 76 | 77 | return 78 | } 79 | 80 | // Return a reference to the header read in the most recent call to Init. 81 | func (m *InMessage) Header() (h *fusekernel.InHeader) { 82 | h = (*fusekernel.InHeader)(unsafe.Pointer(&m.storage[0])) 83 | return 84 | } 85 | 86 | // Return the number of bytes left to consume. 87 | func (m *InMessage) Len() uintptr { 88 | return uintptr(len(m.remaining)) 89 | } 90 | 91 | // Consume the next n bytes from the message, returning a nil pointer if there 92 | // are fewer than n bytes available. 93 | func (m *InMessage) Consume(n uintptr) (p unsafe.Pointer) { 94 | if m.Len() == 0 || n > m.Len() { 95 | return 96 | } 97 | 98 | p = unsafe.Pointer(&m.remaining[0]) 99 | m.remaining = m.remaining[n:] 100 | 101 | return 102 | } 103 | 104 | // Equivalent to Consume, except returns a slice of bytes. The result will be 105 | // nil if Consume would fail. 106 | func (m *InMessage) ConsumeBytes(n uintptr) (b []byte) { 107 | if n > m.Len() { 108 | return 109 | } 110 | 111 | b = m.remaining[:n] 112 | m.remaining = m.remaining[n:] 113 | 114 | return 115 | } 116 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/dropbox/team_common/types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) Dropbox, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | // Package team_common : has no documentation (yet) 22 | package team_common 23 | 24 | import ( 25 | "time" 26 | 27 | "github.com/dropbox/dropbox-sdk-go-unofficial/dropbox" 28 | ) 29 | 30 | // GroupManagementType : The group type determines how a group is managed. 31 | type GroupManagementType struct { 32 | dropbox.Tagged 33 | } 34 | 35 | // Valid tag values for GroupManagementType 36 | const ( 37 | GroupManagementTypeUserManaged = "user_managed" 38 | GroupManagementTypeCompanyManaged = "company_managed" 39 | GroupManagementTypeSystemManaged = "system_managed" 40 | GroupManagementTypeOther = "other" 41 | ) 42 | 43 | // GroupSummary : Information about a group. 44 | type GroupSummary struct { 45 | // GroupName : has no documentation (yet) 46 | GroupName string `json:"group_name"` 47 | // GroupId : has no documentation (yet) 48 | GroupId string `json:"group_id"` 49 | // GroupExternalId : External ID of group. This is an arbitrary ID that an 50 | // admin can attach to a group. 51 | GroupExternalId string `json:"group_external_id,omitempty"` 52 | // MemberCount : The number of members in the group. 53 | MemberCount uint32 `json:"member_count,omitempty"` 54 | // GroupManagementType : Who is allowed to manage the group. 55 | GroupManagementType *GroupManagementType `json:"group_management_type"` 56 | } 57 | 58 | // NewGroupSummary returns a new GroupSummary instance 59 | func NewGroupSummary(GroupName string, GroupId string, GroupManagementType *GroupManagementType) *GroupSummary { 60 | s := new(GroupSummary) 61 | s.GroupName = GroupName 62 | s.GroupId = GroupId 63 | s.GroupManagementType = GroupManagementType 64 | return s 65 | } 66 | 67 | // GroupType : The group type determines how a group is created and managed. 68 | type GroupType struct { 69 | dropbox.Tagged 70 | } 71 | 72 | // Valid tag values for GroupType 73 | const ( 74 | GroupTypeTeam = "team" 75 | GroupTypeUserManaged = "user_managed" 76 | GroupTypeOther = "other" 77 | ) 78 | 79 | // TimeRange : Time range. 80 | type TimeRange struct { 81 | // StartTime : Optional starting time (inclusive). 82 | StartTime time.Time `json:"start_time,omitempty"` 83 | // EndTime : Optional ending time (exclusive). 84 | EndTime time.Time `json:"end_time,omitempty"` 85 | } 86 | 87 | // NewTimeRange returns a new TimeRange instance 88 | func NewTimeRange() *TimeRange { 89 | s := new(TimeRange) 90 | return s 91 | } 92 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/fuseutil/dirent.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package fuseutil 16 | 17 | import ( 18 | "syscall" 19 | "unsafe" 20 | 21 | "github.com/jacobsa/fuse/fuseops" 22 | ) 23 | 24 | type DirentType uint32 25 | 26 | const ( 27 | DT_Unknown DirentType = 0 28 | DT_Socket DirentType = syscall.DT_SOCK 29 | DT_Link DirentType = syscall.DT_LNK 30 | DT_File DirentType = syscall.DT_REG 31 | DT_Block DirentType = syscall.DT_BLK 32 | DT_Directory DirentType = syscall.DT_DIR 33 | DT_Char DirentType = syscall.DT_CHR 34 | DT_FIFO DirentType = syscall.DT_FIFO 35 | ) 36 | 37 | // A struct representing an entry within a directory file, describing a child. 38 | // See notes on fuseops.ReadDirOp and on WriteDirent for details. 39 | type Dirent struct { 40 | // The (opaque) offset within the directory file of the entry following this 41 | // one. See notes on fuseops.ReadDirOp.Offset for details. 42 | Offset fuseops.DirOffset 43 | 44 | // The inode of the child file or directory, and its name within the parent. 45 | Inode fuseops.InodeID 46 | Name string 47 | 48 | // The type of the child. The zero value (DT_Unknown) is legal, but means 49 | // that the kernel will need to call GetAttr when the type is needed. 50 | Type DirentType 51 | } 52 | 53 | // Write the supplied directory entry intto the given buffer in the format 54 | // expected in fuseops.ReadFileOp.Data, returning the number of bytes written. 55 | // Return zero if the entry would not fit. 56 | func WriteDirent(buf []byte, d Dirent) (n int) { 57 | // We want to write bytes with the layout of fuse_dirent 58 | // (http://goo.gl/BmFxob) in host order. The struct must be aligned according 59 | // to FUSE_DIRENT_ALIGN (http://goo.gl/UziWvH), which dictates 8-byte 60 | // alignment. 61 | type fuse_dirent struct { 62 | ino uint64 63 | off uint64 64 | namelen uint32 65 | type_ uint32 66 | name [0]byte 67 | } 68 | 69 | const direntAlignment = 8 70 | const direntSize = 8 + 8 + 4 + 4 71 | 72 | // Compute the number of bytes of padding we'll need to maintain alignment 73 | // for the next entry. 74 | var padLen int 75 | if len(d.Name)%direntAlignment != 0 { 76 | padLen = direntAlignment - (len(d.Name) % direntAlignment) 77 | } 78 | 79 | // Do we have enough room? 80 | totalLen := direntSize + len(d.Name) + padLen 81 | if totalLen > len(buf) { 82 | return 83 | } 84 | 85 | // Write the header. 86 | de := fuse_dirent{ 87 | ino: uint64(d.Inode), 88 | off: uint64(d.Offset), 89 | namelen: uint32(len(d.Name)), 90 | type_: uint32(d.Type), 91 | } 92 | 93 | n += copy(buf[n:], (*[direntSize]byte)(unsafe.Pointer(&de))[:]) 94 | 95 | // Write the name afterward. 96 | n += copy(buf[n:], d.Name) 97 | 98 | // Add any necessary padding. 99 | if padLen != 0 { 100 | var padding [direntAlignment]byte 101 | n += copy(buf[n:], padding[:padLen]) 102 | } 103 | 104 | return 105 | } 106 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/mount_test.go: -------------------------------------------------------------------------------- 1 | package fuse_test 2 | 3 | import ( 4 | "io/ioutil" 5 | "os" 6 | "path" 7 | "runtime" 8 | "strings" 9 | "testing" 10 | 11 | "golang.org/x/net/context" 12 | 13 | "github.com/jacobsa/fuse" 14 | "github.com/jacobsa/fuse/fuseops" 15 | "github.com/jacobsa/fuse/fuseutil" 16 | ) 17 | 18 | //////////////////////////////////////////////////////////////////////// 19 | // minimalFS 20 | //////////////////////////////////////////////////////////////////////// 21 | 22 | // A minimal fuseutil.FileSystem that can successfully mount but do nothing 23 | // else. 24 | type minimalFS struct { 25 | fuseutil.NotImplementedFileSystem 26 | } 27 | 28 | func (fs *minimalFS) StatFS( 29 | ctx context.Context, 30 | op *fuseops.StatFSOp) (err error) { 31 | return 32 | } 33 | 34 | //////////////////////////////////////////////////////////////////////// 35 | // Tests 36 | //////////////////////////////////////////////////////////////////////// 37 | 38 | func TestSuccessfulMount(t *testing.T) { 39 | ctx := context.Background() 40 | 41 | // Set up a temporary directory. 42 | dir, err := ioutil.TempDir("", "mount_test") 43 | if err != nil { 44 | t.Fatal("ioutil.TempDir: %v", err) 45 | } 46 | 47 | defer os.RemoveAll(dir) 48 | 49 | // Mount. 50 | fs := &minimalFS{} 51 | mfs, err := fuse.Mount( 52 | dir, 53 | fuseutil.NewFileSystemServer(fs), 54 | &fuse.MountConfig{}) 55 | 56 | if err != nil { 57 | t.Fatalf("fuse.Mount: %v", err) 58 | } 59 | 60 | defer func() { 61 | if err := mfs.Join(ctx); err != nil { 62 | t.Errorf("Joining: %v", err) 63 | } 64 | }() 65 | 66 | defer fuse.Unmount(mfs.Dir()) 67 | } 68 | 69 | func TestNonEmptyMountPoint(t *testing.T) { 70 | ctx := context.Background() 71 | 72 | // osxfuse appears to be happy to mount over a non-empty mount point. 73 | // 74 | // We leave this test in for Linux, because it tickles the behavior of 75 | // fusermount writing to stderr and exiting with an error code. We want to 76 | // make sure that a descriptive error makes it back to the user. 77 | if runtime.GOOS == "darwin" { 78 | return 79 | } 80 | 81 | // Set up a temporary directory. 82 | dir, err := ioutil.TempDir("", "mount_test") 83 | if err != nil { 84 | t.Fatal("ioutil.TempDir: %v", err) 85 | } 86 | 87 | defer os.RemoveAll(dir) 88 | 89 | // Add a file within it. 90 | err = ioutil.WriteFile(path.Join(dir, "foo"), []byte{}, 0600) 91 | if err != nil { 92 | t.Fatalf("ioutil.WriteFile: %v", err) 93 | } 94 | 95 | // Attempt to mount. 96 | fs := &minimalFS{} 97 | mfs, err := fuse.Mount( 98 | dir, 99 | fuseutil.NewFileSystemServer(fs), 100 | &fuse.MountConfig{}) 101 | 102 | if err == nil { 103 | fuse.Unmount(mfs.Dir()) 104 | mfs.Join(ctx) 105 | t.Fatal("fuse.Mount returned nil") 106 | } 107 | 108 | const want = "not empty" 109 | if got := err.Error(); !strings.Contains(got, want) { 110 | t.Errorf("Unexpected error: %v", got) 111 | } 112 | } 113 | 114 | func TestNonexistentMountPoint(t *testing.T) { 115 | ctx := context.Background() 116 | 117 | // Set up a temporary directory. 118 | dir, err := ioutil.TempDir("", "mount_test") 119 | if err != nil { 120 | t.Fatal("ioutil.TempDir: %v", err) 121 | } 122 | 123 | defer os.RemoveAll(dir) 124 | 125 | // Attempt to mount into a sub-directory that doesn't exist. 126 | fs := &minimalFS{} 127 | mfs, err := fuse.Mount( 128 | path.Join(dir, "foo"), 129 | fuseutil.NewFileSystemServer(fs), 130 | &fuse.MountConfig{}) 131 | 132 | if err == nil { 133 | fuse.Unmount(mfs.Dir()) 134 | mfs.Join(ctx) 135 | t.Fatal("fuse.Mount returned nil") 136 | } 137 | 138 | const want = "no such file" 139 | if got := err.Error(); !strings.Contains(got, want) { 140 | t.Errorf("Unexpected error: %v", got) 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /vendor/github.com/t3rm1n4l/go-mega/messages.go: -------------------------------------------------------------------------------- 1 | package mega 2 | 3 | type LoginMsg struct { 4 | Cmd string `json:"a"` 5 | User string `json:"user"` 6 | Handle string `json:"uh"` 7 | } 8 | 9 | type LoginResp struct { 10 | Csid string `json:"csid"` 11 | Privk string `json:"privk"` 12 | Key string `json:"k"` 13 | } 14 | 15 | type UserMsg struct { 16 | Cmd string `json:"a"` 17 | } 18 | 19 | type UserResp struct { 20 | U string `json:"u"` 21 | S int `json:"s"` 22 | Email string `json:"email"` 23 | Name string `json:"name"` 24 | Key string `json:"k"` 25 | C int `json:"c"` 26 | Pubk string `json:"pubk"` 27 | Privk string `json:"privk"` 28 | Terms string `json: "terms"` 29 | TS string `json:"ts"` 30 | } 31 | 32 | type FilesMsg struct { 33 | Cmd string `json:"a"` 34 | C int `json:"c"` 35 | } 36 | 37 | type FSNode struct { 38 | Hash string `json:"h"` 39 | Parent string `json:"p"` 40 | User string `json:"u"` 41 | T int `json:"t"` 42 | Attr string `json:"a"` 43 | Key string `json:"k"` 44 | Ts int64 `json:"ts"` 45 | SUser string `json:"su"` 46 | SKey string `json:"sk"` 47 | Sz int64 `json:"s"` 48 | } 49 | 50 | type FilesResp struct { 51 | F []FSNode `json:"f"` 52 | 53 | Ok []struct { 54 | Hash string `json:"h"` 55 | Key string `json:"k"` 56 | } `json:"ok"` 57 | 58 | S []struct { 59 | Hash string `json:"h"` 60 | User string `json:"u"` 61 | } `json:"s"` 62 | User []struct { 63 | User string `json:"u"` 64 | C int `json:"c"` 65 | Email string `json:"m"` 66 | } `json:"u"` 67 | Sn string `json:"sn"` 68 | } 69 | 70 | type FileAttr struct { 71 | Name string `json:"n"` 72 | } 73 | 74 | type GetLinkMsg struct { 75 | Cmd string `json:"a"` 76 | N string `json:"n"` 77 | } 78 | 79 | type DownloadMsg struct { 80 | Cmd string `json:"a"` 81 | G int `json:"g"` 82 | P string `json:"p,omitempty"` 83 | N string `json:"n,omitempty"` 84 | } 85 | 86 | type DownloadResp struct { 87 | G string `json:"g"` 88 | Size uint64 `json:"s"` 89 | Attr string `json:"at"` 90 | Err uint32 `json:"e"` 91 | } 92 | 93 | type UploadMsg struct { 94 | Cmd string `json:"a"` 95 | S int64 `json:"s"` 96 | } 97 | 98 | type UploadResp struct { 99 | P string `json:"p"` 100 | } 101 | 102 | type UploadCompleteMsg struct { 103 | Cmd string `json:"a"` 104 | T string `json:"t"` 105 | N [1]struct { 106 | H string `json:"h"` 107 | T int `json:"t"` 108 | A string `json:"a"` 109 | K string `json:"k"` 110 | } `json:"n"` 111 | I string `json:"i,omitempty"` 112 | } 113 | 114 | type UploadCompleteResp struct { 115 | F []FSNode `json:"f"` 116 | } 117 | 118 | type FileInfoMsg struct { 119 | Cmd string `json:"a"` 120 | F int `json:"f"` 121 | P string `json:"p"` 122 | } 123 | 124 | type MoveFileMsg struct { 125 | Cmd string `json:"a"` 126 | N string `json:"n"` 127 | T string `json:"t"` 128 | I string `json:"i"` 129 | } 130 | 131 | type FileAttrMsg struct { 132 | Cmd string `json:"a"` 133 | Attr string `json:"attr"` 134 | Key string `json:"key"` 135 | N string `json:"n"` 136 | I string `json:"i"` 137 | } 138 | 139 | type FileDeleteMsg struct { 140 | Cmd string `json:"a"` 141 | N string `json:"n"` 142 | I string `json:"i"` 143 | } 144 | 145 | type Event struct { 146 | Cmd string `json:"a"` 147 | /* 148 | // Delete (a=d) 149 | delEvent 150 | // Update attr (a=u) 151 | updateEvent 152 | // New nodes (a=t) 153 | createEvent 154 | */ 155 | T struct { 156 | Files []FSNode `json:"f"` 157 | } `json:"t"` 158 | Owner string `json:"ou"` 159 | 160 | N string `json:"n"` 161 | User string `json:"u"` 162 | Attr string `json:"at"` 163 | Key string `json:"k"` 164 | Ts int64 `json:"ts"` 165 | I string `json:"i"` 166 | } 167 | 168 | type EventMsg struct { 169 | W string `json:"w"` 170 | Sn string `json:"sn"` 171 | E []Event `json:"a"` 172 | } 173 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/debug.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package fuse 16 | 17 | import ( 18 | "fmt" 19 | "reflect" 20 | "strings" 21 | 22 | "github.com/jacobsa/fuse/fuseops" 23 | ) 24 | 25 | // Decide on the name of the given op. 26 | func opName(op interface{}) string { 27 | // We expect all ops to be pointers. 28 | t := reflect.TypeOf(op).Elem() 29 | 30 | // Strip the "Op" from "FooOp". 31 | return strings.TrimSuffix(t.Name(), "Op") 32 | } 33 | 34 | func describeRequest(op interface{}) (s string) { 35 | v := reflect.ValueOf(op).Elem() 36 | 37 | // We will set up a comma-separated list of components. 38 | var components []string 39 | addComponent := func(format string, v ...interface{}) { 40 | components = append(components, fmt.Sprintf(format, v...)) 41 | } 42 | 43 | // Include an inode number, if available. 44 | if f := v.FieldByName("Inode"); f.IsValid() { 45 | addComponent("inode %v", f.Interface()) 46 | } 47 | 48 | // Include a parent inode number, if available. 49 | if f := v.FieldByName("Parent"); f.IsValid() { 50 | addComponent("parent %v", f.Interface()) 51 | } 52 | 53 | // Include a name, if available. 54 | if f := v.FieldByName("Name"); f.IsValid() { 55 | addComponent("name %q", f.Interface()) 56 | } 57 | 58 | // Handle special cases. 59 | switch typed := op.(type) { 60 | case *interruptOp: 61 | addComponent("fuseid 0x%08x", typed.FuseID) 62 | 63 | case *unknownOp: 64 | addComponent("opcode %d", typed.OpCode) 65 | 66 | case *fuseops.SetInodeAttributesOp: 67 | if typed.Size != nil { 68 | addComponent("size %d", *typed.Size) 69 | } 70 | 71 | if typed.Mode != nil { 72 | addComponent("mode %v", *typed.Mode) 73 | } 74 | 75 | if typed.Atime != nil { 76 | addComponent("atime %v", *typed.Atime) 77 | } 78 | 79 | if typed.Mtime != nil { 80 | addComponent("mtime %v", *typed.Mtime) 81 | } 82 | 83 | case *fuseops.ReadFileOp: 84 | addComponent("handle %d", typed.Handle) 85 | addComponent("offset %d", typed.Offset) 86 | addComponent("%d bytes", len(typed.Dst)) 87 | 88 | case *fuseops.WriteFileOp: 89 | addComponent("handle %d", typed.Handle) 90 | addComponent("offset %d", typed.Offset) 91 | addComponent("%d bytes", len(typed.Data)) 92 | 93 | case *fuseops.RemoveXattrOp: 94 | addComponent("name %s", typed.Name) 95 | 96 | case *fuseops.GetXattrOp: 97 | addComponent("name %s", typed.Name) 98 | 99 | case *fuseops.SetXattrOp: 100 | addComponent("name %s", typed.Name) 101 | } 102 | 103 | // Use just the name if there is no extra info. 104 | if len(components) == 0 { 105 | return opName(op) 106 | } 107 | 108 | // Otherwise, include the extra info. 109 | return fmt.Sprintf("%s (%s)", opName(op), strings.Join(components, ", ")) 110 | } 111 | 112 | func describeResponse(op interface{}) string { 113 | v := reflect.ValueOf(op).Elem() 114 | 115 | // We will set up a comma-separated list of components. 116 | var components []string 117 | addComponent := func(format string, v ...interface{}) { 118 | components = append(components, fmt.Sprintf(format, v...)) 119 | } 120 | 121 | // Include a resulting inode number, if available. 122 | if f := v.FieldByName("Entry"); f.IsValid() { 123 | if entry, ok := f.Interface().(fuseops.ChildInodeEntry); ok { 124 | addComponent("inode %v", entry.Child) 125 | } 126 | } 127 | 128 | return fmt.Sprintf("%s", strings.Join(components, ", ")) 129 | } 130 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/fusetesting/stat.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package fusetesting 16 | 17 | import ( 18 | "fmt" 19 | "os" 20 | "reflect" 21 | "syscall" 22 | "time" 23 | 24 | "github.com/jacobsa/oglematchers" 25 | ) 26 | 27 | // Match os.FileInfo values that specify an mtime equal to the given time. 28 | func MtimeIs(expected time.Time) oglematchers.Matcher { 29 | return oglematchers.NewMatcher( 30 | func(c interface{}) error { return mtimeIsWithin(c, expected, 0) }, 31 | fmt.Sprintf("mtime is %v", expected)) 32 | } 33 | 34 | // Like MtimeIs, but allows for a tolerance. 35 | func MtimeIsWithin(expected time.Time, d time.Duration) oglematchers.Matcher { 36 | return oglematchers.NewMatcher( 37 | func(c interface{}) error { return mtimeIsWithin(c, expected, d) }, 38 | fmt.Sprintf("mtime is within %v of %v", d, expected)) 39 | } 40 | 41 | func mtimeIsWithin(c interface{}, expected time.Time, d time.Duration) error { 42 | fi, ok := c.(os.FileInfo) 43 | if !ok { 44 | return fmt.Errorf("which is of type %v", reflect.TypeOf(c)) 45 | } 46 | 47 | // Check ModTime(). 48 | diff := fi.ModTime().Sub(expected) 49 | absDiff := diff 50 | if absDiff < 0 { 51 | absDiff = -absDiff 52 | } 53 | 54 | if !(absDiff < d) { 55 | return fmt.Errorf("which has mtime %v, off by %v", fi.ModTime(), diff) 56 | } 57 | 58 | return nil 59 | } 60 | 61 | // Match os.FileInfo values that specify a file birth time within the supplied 62 | // radius of the given time. On platforms where there is no birth time 63 | // available, match all os.FileInfo values. 64 | func BirthtimeIsWithin( 65 | expected time.Time, 66 | d time.Duration) oglematchers.Matcher { 67 | return oglematchers.NewMatcher( 68 | func(c interface{}) error { return birthtimeIsWithin(c, expected, d) }, 69 | fmt.Sprintf("birthtime is within %v of %v", d, expected)) 70 | } 71 | 72 | func birthtimeIsWithin( 73 | c interface{}, 74 | expected time.Time, 75 | d time.Duration) error { 76 | fi, ok := c.(os.FileInfo) 77 | if !ok { 78 | return fmt.Errorf("which is of type %v", reflect.TypeOf(c)) 79 | } 80 | 81 | t, ok := extractBirthtime(fi.Sys()) 82 | if !ok { 83 | return nil 84 | } 85 | 86 | diff := t.Sub(expected) 87 | absDiff := diff 88 | if absDiff < 0 { 89 | absDiff = -absDiff 90 | } 91 | 92 | if !(absDiff < d) { 93 | return fmt.Errorf("which has birth time %v, off by %v", t, diff) 94 | } 95 | 96 | return nil 97 | } 98 | 99 | // Extract time information from the supplied file info. Panic on platforms 100 | // where this is not possible. 101 | func GetTimes(fi os.FileInfo) (atime, ctime, mtime time.Time) { 102 | return getTimes(fi.Sys().(*syscall.Stat_t)) 103 | } 104 | 105 | // Match os.FileInfo values that specify a number of links equal to the given 106 | // number. On platforms where there is no nlink field available, match all 107 | // os.FileInfo values. 108 | func NlinkIs(expected uint64) oglematchers.Matcher { 109 | return oglematchers.NewMatcher( 110 | func(c interface{}) error { return nlinkIs(c, expected) }, 111 | fmt.Sprintf("nlink is %v", expected)) 112 | } 113 | 114 | func nlinkIs(c interface{}, expected uint64) error { 115 | fi, ok := c.(os.FileInfo) 116 | if !ok { 117 | return fmt.Errorf("which is of type %v", reflect.TypeOf(c)) 118 | } 119 | 120 | if actual, ok := extractNlink(fi.Sys()); ok && actual != expected { 121 | return fmt.Errorf("which has nlink == %v", actual) 122 | } 123 | 124 | return nil 125 | } 126 | -------------------------------------------------------------------------------- /internal/core/core.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import ( 4 | "context" 5 | "flag" 6 | glog "log" 7 | "os" 8 | "os/signal" 9 | "os/user" 10 | "path/filepath" 11 | "runtime" 12 | "syscall" 13 | "time" 14 | 15 | "github.com/gohxs/cloudmount/internal/coreutil" 16 | "github.com/gohxs/prettylog" 17 | "github.com/jacobsa/fuse" 18 | "github.com/jacobsa/fuse/fuseutil" 19 | ) 20 | 21 | var ( 22 | pname = "cloudmount" 23 | log = prettylog.Dummy() 24 | errlog = prettylog.New(pname + "-err") 25 | ) 26 | 27 | // Core struct 28 | type Core struct { 29 | Config Config 30 | Drivers map[string]DriverFactory 31 | 32 | CurrentFS DriverFS 33 | } 34 | 35 | // New create a New cloudmount core 36 | func New() *Core { 37 | 38 | // TODO: friendly panics 39 | usr, err := user.Current() 40 | if err != nil { 41 | panic(err) 42 | } 43 | 44 | var uid, gid uint32 45 | err = coreutil.StringAssign(usr.Uid, &uid) 46 | if err != nil { 47 | panic(err) 48 | } 49 | err = coreutil.StringAssign(usr.Gid, &gid) 50 | if err != nil { 51 | panic(err) 52 | } 53 | 54 | return &Core{ 55 | Drivers: map[string]DriverFactory{}, 56 | Config: Config{ 57 | Foreground: false, 58 | Type: "", 59 | VerboseLog: false, 60 | RefreshTime: 5 * time.Second, 61 | HomeDir: filepath.Join(usr.HomeDir, ".cloudmount"), 62 | Source: filepath.Join(usr.HomeDir, ".cloudmount", "gdrive.yaml"), 63 | 64 | // Defaults at least 65 | Options: Options{ 66 | UID: uint32(uid), 67 | GID: uint32(gid), 68 | Readonly: false, 69 | }, 70 | }, 71 | } 72 | 73 | } 74 | 75 | // Init to be run after configuration 76 | func (c *Core) Init() (err error) { 77 | 78 | if c.Config.VerboseLog { 79 | log = prettylog.New(pname) 80 | } 81 | 82 | fsFactory, ok := c.Drivers[c.Config.Type] 83 | if !ok { 84 | errlog.Fatal("CloudFS not supported") 85 | } 86 | 87 | c.CurrentFS = fsFactory(c) // Factory 88 | 89 | return 90 | } 91 | 92 | //Mount performs the mount 93 | func (c *Core) Mount() { 94 | 95 | // Start Selected driveFS 96 | c.CurrentFS.Start() // Should not block 97 | ////////////// 98 | // Server 99 | ///////// 100 | ctx := context.Background() 101 | server := fuseutil.NewFileSystemServer(c.CurrentFS) 102 | mountPath := c.Config.Target 103 | 104 | var err error 105 | var mfs *fuse.MountedFileSystem 106 | 107 | fsname := c.Config.Source 108 | 109 | var dbgLogger *glog.Logger 110 | var errLogger *glog.Logger 111 | if c.Config.Verbose2Log { // Extra verbose 112 | dbgLogger = prettylog.New("fuse") 113 | errLogger = prettylog.New("fuse-err") 114 | } 115 | 116 | mfs, err = fuse.Mount(mountPath, server, &fuse.MountConfig{ 117 | VolumeName: "cloudmount", 118 | //Options: coreutil.OptionMap(c.Config.Options), 119 | FSName: fsname, 120 | DebugLogger: dbgLogger, 121 | ErrorLogger: errLogger, 122 | ReadOnly: c.Config.Options.Readonly, 123 | }) 124 | if err != nil { 125 | errlog.Fatal("Failed mounting path ", flag.Arg(0), err) 126 | } 127 | 128 | // Signal handling to refresh Drives 129 | sigs := make(chan os.Signal, 2) 130 | signal.Notify(sigs, syscall.SIGUSR1, syscall.SIGHUP, syscall.SIGINT, os.Interrupt, syscall.SIGTERM) 131 | go func() { 132 | for sig := range sigs { 133 | log.Println("Signal:", sig) 134 | switch sig { 135 | //case syscall.SIGUSR1: 136 | //log.Println("Manually Refresh drive") 137 | //go c.CurrentFS.Refresh() 138 | case syscall.SIGHUP: 139 | log.Println("GC") 140 | mem := runtime.MemStats{} 141 | runtime.ReadMemStats(&mem) 142 | log.Printf("Mem: %.2fMB", float64(mem.Alloc)/1024/1024) 143 | runtime.GC() 144 | 145 | runtime.ReadMemStats(&mem) 146 | log.Printf("After gc: Mem: %.2fMB", float64(mem.Alloc)/1024/1024) 147 | 148 | case os.Interrupt: 149 | log.Println("Graceful unmount") 150 | fuse.Unmount(mountPath) 151 | os.Exit(1) 152 | case syscall.SIGTERM: 153 | log.Println("Graceful unmount") 154 | fuse.Unmount(mountPath) 155 | os.Exit(1) 156 | } 157 | 158 | } 159 | }() 160 | 161 | if err := mfs.Join(ctx); err != nil { 162 | errlog.Fatalf("Joining: %v", err) 163 | } 164 | 165 | } 166 | -------------------------------------------------------------------------------- /internal/fs/basefs/file_entry.go: -------------------------------------------------------------------------------- 1 | package basefs 2 | 3 | import ( 4 | "io" 5 | "io/ioutil" 6 | "os" 7 | "sync" 8 | 9 | "github.com/jacobsa/fuse/fuseops" 10 | ) 11 | 12 | //FileEntry entry to handle files 13 | type FileEntry struct { 14 | sync.Mutex 15 | Inode fuseops.InodeID // Inode 16 | File *File // Remote file information 17 | Name string // local name 18 | Attr fuseops.InodeAttributes // Cached attributes 19 | tempFile *FileWrapper // Cached file 20 | } 21 | 22 | // SetFile update attributes and set drive.File 23 | func (fe *FileEntry) SetFile(file *File, uid, gid uint32) { // Should remove from here maybe? 24 | fe.File = file 25 | fe.Attr = fuseops.InodeAttributes{ 26 | Size: fe.File.Size, 27 | Crtime: file.CreatedTime, 28 | Ctime: file.CreatedTime, 29 | Mtime: file.ModifiedTime, 30 | Atime: file.AccessedTime, 31 | Mode: file.Mode, 32 | Uid: uid, 33 | Gid: gid, 34 | } 35 | } 36 | 37 | // IsDir returns true if entry is a directory:w 38 | func (fe *FileEntry) IsDir() bool { 39 | return fe.Attr.Mode&os.ModeDir == os.ModeDir 40 | } 41 | 42 | // HasParentID check parent by cloud ID 43 | func (fe *FileEntry) HasParentID(parentID string) bool { 44 | // Exceptional case 45 | if fe.Inode == fuseops.RootInodeID { 46 | return false 47 | } 48 | if parentID == "" { 49 | if fe.File == nil || len(fe.File.Parents) == 0 { // We are looking in root 50 | return true 51 | } 52 | return false 53 | } 54 | if fe.File == nil { // Case gid is not empty and GFile is null 55 | return false 56 | } 57 | for _, pgid := range fe.File.Parents { 58 | if pgid == parentID { 59 | return true 60 | } 61 | } 62 | return false 63 | } 64 | 65 | // HasParent check Parent by entry 66 | func (fe *FileEntry) HasParent(parent *FileEntry) bool { 67 | // Exceptional case 68 | if fe.Inode == fuseops.RootInodeID { 69 | return false 70 | } 71 | if parent.File == nil { 72 | return fe.HasParentID("") 73 | } 74 | return fe.HasParentID(parent.File.ID) 75 | } 76 | 77 | //ClearCache remove local file 78 | // XXX: move this to FileEntry 79 | func (fe *FileEntry) ClearCache() (err error) { 80 | fe.Lock() 81 | defer fe.Unlock() 82 | if fe.tempFile == nil { 83 | return 84 | } 85 | fe.tempFile.RealClose() 86 | os.Remove(fe.tempFile.Name()) 87 | fe.tempFile = nil 88 | return 89 | } 90 | 91 | // Truncate truncates localFile to 0 bytes 92 | func (fe *FileEntry) Truncate() (err error) { 93 | fe.Lock() 94 | defer fe.Unlock() 95 | // Delete and create another on truncate 0 96 | localFile, err := ioutil.TempFile(os.TempDir(), "gdfs") // TODO: const this elsewhere 97 | if err != nil { 98 | return err 99 | } 100 | fe.tempFile = &FileWrapper{localFile} 101 | 102 | return 103 | } 104 | 105 | //Sync will flush, upload file and update local entry 106 | func (fe *FileEntry) Sync(fc *FileContainer) (err error) { 107 | fe.Lock() 108 | defer fe.Unlock() 109 | 110 | if fe.tempFile == nil { 111 | return 112 | } 113 | fe.tempFile.Sync() 114 | fe.tempFile.Seek(0, io.SeekStart) // Depends??, for reading? 115 | 116 | upFile, err := fc.fs.Service.Upload(fe.tempFile, fe.File) 117 | if err != nil { 118 | return err 119 | } 120 | fe.SetFile(upFile, fc.uid, fc.gid) // update local GFile entry 121 | return 122 | 123 | } 124 | 125 | //Cache download cloud file to a temporary local file or return already created file 126 | func (fe *FileEntry) Cache(fc *FileContainer) *FileWrapper { 127 | fe.Lock() 128 | defer fe.Unlock() 129 | 130 | if fe.tempFile != nil { 131 | return fe.tempFile 132 | } 133 | var err error 134 | 135 | // Local copy 136 | localFile, err := ioutil.TempFile(os.TempDir(), "gdfs") // TODO: const this elsewhere 137 | if err != nil { 138 | return nil 139 | } 140 | fe.tempFile = &FileWrapper{localFile} 141 | 142 | err = fc.fs.Service.DownloadTo(fe.tempFile, fe.File) 143 | // ignore download since can be a bogus file, for certain file systems 144 | //if err != nil { // Ignore this error 145 | // return nil 146 | //} 147 | 148 | // tempFile could change to null in the meantime (download might take long?) 149 | fe.tempFile.Seek(0, io.SeekStart) 150 | 151 | return fe.tempFile 152 | 153 | } 154 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/samples/statfs/statfs_linux_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package statfs_test 16 | 17 | import ( 18 | "fmt" 19 | "math" 20 | "regexp" 21 | "syscall" 22 | 23 | "github.com/jacobsa/fuse/fuseops" 24 | . "github.com/jacobsa/ogletest" 25 | ) 26 | 27 | // Sample output: 28 | // 29 | // Filesystem 1K-blocks Used Available Use% Mounted on 30 | // some_fuse_file_system 512 64 384 15% /tmp/sample_test001288095 31 | // 32 | var gDfOutputRegexp = regexp.MustCompile(`^\S+\s+(\d+)\s+(\d+)\s+(\d+)\s+\d+%.*$`) 33 | 34 | //////////////////////////////////////////////////////////////////////// 35 | // Tests 36 | //////////////////////////////////////////////////////////////////////// 37 | 38 | func (t *StatFSTest) Syscall_ZeroValues() { 39 | var err error 40 | var stat syscall.Statfs_t 41 | 42 | // Call without configuring a canned response, meaning the OS will see the 43 | // zero value for each field. The assertions below act as documentation for 44 | // the OS's behavior in this case. 45 | err = syscall.Statfs(t.Dir, &stat) 46 | AssertEq(nil, err) 47 | 48 | ExpectEq(0, stat.Bsize) 49 | ExpectEq(0, stat.Frsize) 50 | ExpectEq(0, stat.Blocks) 51 | ExpectEq(0, stat.Bfree) 52 | ExpectEq(0, stat.Bavail) 53 | ExpectEq(0, stat.Files) 54 | ExpectEq(0, stat.Ffree) 55 | } 56 | 57 | func (t *StatFSTest) Syscall_NonZeroValues() { 58 | var err error 59 | var stat syscall.Statfs_t 60 | 61 | // Set up the canned response. 62 | canned := fuseops.StatFSOp{ 63 | BlockSize: 1 << 15, 64 | IoSize: 1 << 16, 65 | 66 | Blocks: 1<<51 + 3, 67 | BlocksFree: 1<<43 + 5, 68 | BlocksAvailable: 1<<41 + 7, 69 | 70 | Inodes: 1<<59 + 11, 71 | InodesFree: 1<<58 + 13, 72 | } 73 | 74 | t.fs.SetStatFSResponse(canned) 75 | 76 | // Stat. 77 | err = syscall.Statfs(t.Dir, &stat) 78 | AssertEq(nil, err) 79 | 80 | ExpectEq(canned.BlockSize, stat.Frsize) 81 | ExpectEq(canned.IoSize, stat.Bsize) 82 | ExpectEq(canned.Blocks, stat.Blocks) 83 | ExpectEq(canned.BlocksFree, stat.Bfree) 84 | ExpectEq(canned.BlocksAvailable, stat.Bavail) 85 | ExpectEq(canned.Inodes, stat.Files) 86 | ExpectEq(canned.InodesFree, stat.Ffree) 87 | } 88 | 89 | func (t *StatFSTest) BlockSizes() { 90 | var err error 91 | 92 | // Test a bunch of weird block sizes that OS X would be cranky about. 93 | blockSizes := []uint32{ 94 | 0, 95 | 1, 96 | 3, 97 | 17, 98 | 1<<20 - 1, 99 | 1<<20 + 0, 100 | 1<<20 + 1, 101 | math.MaxInt32, 102 | math.MaxInt32 + 1, 103 | math.MaxUint32, 104 | } 105 | 106 | for _, bs := range blockSizes { 107 | desc := fmt.Sprintf("block size %d", bs) 108 | 109 | // Set up. 110 | canned := fuseops.StatFSOp{ 111 | BlockSize: bs, 112 | Blocks: 10, 113 | } 114 | 115 | t.fs.SetStatFSResponse(canned) 116 | 117 | // Check. 118 | var stat syscall.Statfs_t 119 | err = syscall.Statfs(t.Dir, &stat) 120 | AssertEq(nil, err) 121 | 122 | ExpectEq(bs, stat.Frsize, "%s", desc) 123 | } 124 | } 125 | 126 | func (t *StatFSTest) IoSizes() { 127 | var err error 128 | 129 | // Test a bunch of weird IO sizes that OS X would be cranky about. 130 | ioSizes := []uint32{ 131 | 0, 132 | 1, 133 | 3, 134 | 17, 135 | 1<<20 - 1, 136 | 1<<20 + 0, 137 | 1<<20 + 1, 138 | math.MaxInt32, 139 | math.MaxInt32 + 1, 140 | math.MaxUint32, 141 | } 142 | 143 | for _, bs := range ioSizes { 144 | desc := fmt.Sprintf("IO size %d", bs) 145 | 146 | // Set up. 147 | canned := fuseops.StatFSOp{ 148 | IoSize: bs, 149 | Blocks: 10, 150 | } 151 | 152 | t.fs.SetStatFSResponse(canned) 153 | 154 | // Check. 155 | var stat syscall.Statfs_t 156 | err = syscall.Statfs(t.Dir, &stat) 157 | AssertEq(nil, err) 158 | 159 | ExpectEq(bs, stat.Bsize, "%s", desc) 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/samples/in_process.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package samples 16 | 17 | import ( 18 | "fmt" 19 | "io" 20 | "io/ioutil" 21 | "log" 22 | "os" 23 | "time" 24 | 25 | "github.com/jacobsa/fuse" 26 | "github.com/jacobsa/ogletest" 27 | "github.com/jacobsa/timeutil" 28 | "golang.org/x/net/context" 29 | ) 30 | 31 | // A struct that implements common behavior needed by tests in the samples/ 32 | // directory. Use it as an embedded field in your test fixture, calling its 33 | // SetUp method from your SetUp method after setting the Server field. 34 | type SampleTest struct { 35 | // The server under test and the configuration with which it should be 36 | // mounted. These must be set by the user of this type before calling SetUp; 37 | // all the other fields below are set by SetUp itself. 38 | Server fuse.Server 39 | MountConfig fuse.MountConfig 40 | 41 | // A context object that can be used for long-running operations. 42 | Ctx context.Context 43 | 44 | // A clock with a fixed initial time. The test's set up method may use this 45 | // to wire the server with a clock, if desired. 46 | Clock timeutil.SimulatedClock 47 | 48 | // The directory at which the file system is mounted. 49 | Dir string 50 | 51 | // Anothing non-nil in this slice will be closed by TearDown. The test will 52 | // fail if closing fails. 53 | ToClose []io.Closer 54 | 55 | mfs *fuse.MountedFileSystem 56 | } 57 | 58 | // Mount t.Server and initialize the other exported fields of the struct. 59 | // Panics on error. 60 | // 61 | // REQUIRES: t.Server has been set. 62 | func (t *SampleTest) SetUp(ti *ogletest.TestInfo) { 63 | cfg := t.MountConfig 64 | if *fDebug { 65 | cfg.DebugLogger = log.New(os.Stderr, "fuse: ", 0) 66 | } 67 | 68 | err := t.initialize(ti.Ctx, t.Server, &cfg) 69 | if err != nil { 70 | panic(err) 71 | } 72 | } 73 | 74 | // Like SetUp, but doens't panic. 75 | func (t *SampleTest) initialize( 76 | ctx context.Context, 77 | server fuse.Server, 78 | config *fuse.MountConfig) (err error) { 79 | // Initialize the context used by the test. 80 | t.Ctx = ctx 81 | 82 | // Make the server share that context, if the test hasn't already set some 83 | // other one. 84 | if config.OpContext == nil { 85 | config.OpContext = ctx 86 | } 87 | 88 | // Initialize the clock. 89 | t.Clock.SetTime(time.Date(2012, 8, 15, 22, 56, 0, 0, time.Local)) 90 | 91 | // Set up a temporary directory. 92 | t.Dir, err = ioutil.TempDir("", "sample_test") 93 | if err != nil { 94 | err = fmt.Errorf("TempDir: %v", err) 95 | return 96 | } 97 | 98 | // Mount the file system. 99 | t.mfs, err = fuse.Mount(t.Dir, server, config) 100 | if err != nil { 101 | err = fmt.Errorf("Mount: %v", err) 102 | return 103 | } 104 | 105 | return 106 | } 107 | 108 | // Unmount the file system and clean up. Panics on error. 109 | func (t *SampleTest) TearDown() { 110 | err := t.destroy() 111 | if err != nil { 112 | panic(err) 113 | } 114 | } 115 | 116 | // Like TearDown, but doesn't panic. 117 | func (t *SampleTest) destroy() (err error) { 118 | // Close what is necessary. 119 | for _, c := range t.ToClose { 120 | if c == nil { 121 | continue 122 | } 123 | 124 | ogletest.ExpectEq(nil, c.Close()) 125 | } 126 | 127 | // Was the file system mounted? 128 | if t.mfs == nil { 129 | return 130 | } 131 | 132 | // Unmount the file system. 133 | err = unmount(t.Dir) 134 | if err != nil { 135 | err = fmt.Errorf("unmount: %v", err) 136 | return 137 | } 138 | 139 | // Unlink the mount point. 140 | if err = os.Remove(t.Dir); err != nil { 141 | err = fmt.Errorf("Unlinking mount point: %v", err) 142 | return 143 | } 144 | 145 | // Join the file system. 146 | err = t.mfs.Join(t.Ctx) 147 | if err != nil { 148 | err = fmt.Errorf("mfs.Join: %v", err) 149 | return 150 | } 151 | 152 | return 153 | } 154 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/dropbox/common/types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) Dropbox, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | // Package common : has no documentation (yet) 22 | package common 23 | 24 | import ( 25 | "encoding/json" 26 | 27 | "github.com/dropbox/dropbox-sdk-go-unofficial/dropbox" 28 | ) 29 | 30 | // InvalidPathRootError : has no documentation (yet) 31 | type InvalidPathRootError struct { 32 | // PathRoot : The latest path root id for user's team if the user is still 33 | // in a team. 34 | PathRoot string `json:"path_root,omitempty"` 35 | } 36 | 37 | // NewInvalidPathRootError returns a new InvalidPathRootError instance 38 | func NewInvalidPathRootError() *InvalidPathRootError { 39 | s := new(InvalidPathRootError) 40 | return s 41 | } 42 | 43 | // PathRoot : has no documentation (yet) 44 | type PathRoot struct { 45 | dropbox.Tagged 46 | // Team : Paths are relative to the given team directory. (This results in 47 | // `PathRootError.invalid` if the user is not a member of the team 48 | // associated with that path root id.) 49 | Team string `json:"team,omitempty"` 50 | // SharedFolder : Paths are relative to given shared folder id (This results 51 | // in `PathRootError.no_permission` if you don't have access to this shared 52 | // folder.) 53 | SharedFolder string `json:"shared_folder,omitempty"` 54 | } 55 | 56 | // Valid tag values for PathRoot 57 | const ( 58 | PathRootHome = "home" 59 | PathRootMemberHome = "member_home" 60 | PathRootTeam = "team" 61 | PathRootUserHome = "user_home" 62 | PathRootSharedFolder = "shared_folder" 63 | PathRootOther = "other" 64 | ) 65 | 66 | // UnmarshalJSON deserializes into a PathRoot instance 67 | func (u *PathRoot) UnmarshalJSON(body []byte) error { 68 | type wrap struct { 69 | dropbox.Tagged 70 | } 71 | var w wrap 72 | var err error 73 | if err = json.Unmarshal(body, &w); err != nil { 74 | return err 75 | } 76 | u.Tag = w.Tag 77 | switch u.Tag { 78 | case "team": 79 | err = json.Unmarshal(body, &u.Team) 80 | 81 | if err != nil { 82 | return err 83 | } 84 | case "shared_folder": 85 | err = json.Unmarshal(body, &u.SharedFolder) 86 | 87 | if err != nil { 88 | return err 89 | } 90 | } 91 | return nil 92 | } 93 | 94 | // PathRootError : has no documentation (yet) 95 | type PathRootError struct { 96 | dropbox.Tagged 97 | // Invalid : The path root id value in Dropbox-API-Path-Root header is no 98 | // longer valid. 99 | Invalid *InvalidPathRootError `json:"invalid,omitempty"` 100 | } 101 | 102 | // Valid tag values for PathRootError 103 | const ( 104 | PathRootErrorInvalid = "invalid" 105 | PathRootErrorNoPermission = "no_permission" 106 | PathRootErrorOther = "other" 107 | ) 108 | 109 | // UnmarshalJSON deserializes into a PathRootError instance 110 | func (u *PathRootError) UnmarshalJSON(body []byte) error { 111 | type wrap struct { 112 | dropbox.Tagged 113 | // Invalid : The path root id value in Dropbox-API-Path-Root header is 114 | // no longer valid. 115 | Invalid json.RawMessage `json:"invalid,omitempty"` 116 | } 117 | var w wrap 118 | var err error 119 | if err = json.Unmarshal(body, &w); err != nil { 120 | return err 121 | } 122 | u.Tag = w.Tag 123 | switch u.Tag { 124 | case "invalid": 125 | err = json.Unmarshal(body, &u.Invalid) 126 | 127 | if err != nil { 128 | return err 129 | } 130 | } 131 | return nil 132 | } 133 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/generator/dropbox-api-spec/shared_content_links.stone: -------------------------------------------------------------------------------- 1 | namespace sharing 2 | 3 | import common 4 | 5 | 6 | union LinkExpiry 7 | remove_expiry 8 | "Remove the currently set expiry for the link." 9 | set_expiry common.DropboxTimestamp 10 | "Set a new expiry or change an existing expiry." 11 | 12 | union LinkPassword 13 | remove_password 14 | "Remove the currently set password for the link." 15 | set_password String 16 | "Set a new password or change an existing password." 17 | 18 | struct LinkSettings 19 | "Settings that apply to a link." 20 | access_level AccessLevel? 21 | "The access level on the link for this file. Currently, 22 | it only accepts 'viewer' and 'viewer_no_comment'." 23 | audience LinkAudience? 24 | "The type of audience on the link for this file." 25 | expiry LinkExpiry? 26 | "An expiry timestamp to set on a link." 27 | password LinkPassword? 28 | "The password for the link." 29 | 30 | union LinkAudience 31 | public 32 | "Link is accessible by anyone." 33 | team 34 | "Link is accessible only by team members." 35 | members 36 | "Link is accessible only by members of the content." 37 | 38 | struct LinkPermission 39 | "Permissions for actions that can be performed on a link." 40 | action LinkAction 41 | allow Boolean 42 | reason PermissionDeniedReason? 43 | 44 | example default 45 | action = change_audience 46 | allow = true 47 | 48 | union LinkAction 49 | "Actions that can be performed on a link." 50 | change_access_level 51 | "Change the access level of the link." 52 | change_audience 53 | "Change the audience of the link." 54 | remove_expiry 55 | "Remove the expiry date of the link." 56 | remove_password 57 | "Remove the password of the link." 58 | set_expiry 59 | "Create or modify the expiry date of the link." 60 | set_password 61 | "Create or modify the password of the link." 62 | 63 | struct SharedContentLinkMetadataBase 64 | access_level AccessLevel? 65 | "The access level on the link for this file." 66 | audience_options List(LinkAudience) 67 | "The audience options that are available for the content. Some audience options may be 68 | unavailable. For example, team_only may be unavailable if the content is not owned by a 69 | user on a team. The 'default' audience option is always available if the user can modify 70 | link settings." 71 | audience_restricting_shared_folder AudienceRestrictingSharedFolder? 72 | "The shared folder that prevents the link audience for this link from being more 73 | restrictive." 74 | current_audience LinkAudience 75 | "The current audience of the link." 76 | expiry common.DropboxTimestamp? 77 | "Whether the link has an expiry set on it. A link with an expiry will have its 78 | audience changed to members when the expiry is reached." 79 | link_permissions List(LinkPermission) 80 | "A list of permissions for actions you can perform on the link." 81 | password_protected Boolean 82 | "Whether the link is protected by a password." 83 | 84 | struct SharedContentLinkMetadata extends SharedContentLinkMetadataBase 85 | "Metadata of a shared link for a file or folder." 86 | url String 87 | "The URL of the link." 88 | 89 | example default 90 | audience_options = [public, team, members] 91 | current_audience = public 92 | link_permissions = [default] 93 | password_protected = false 94 | url = "" 95 | 96 | struct ExpectedSharedContentLinkMetadata extends SharedContentLinkMetadataBase 97 | "The expected metadata of a shared link for a file or folder when a link is first created for 98 | the content. Absent if the link already exists." 99 | 100 | example default 101 | audience_options = [public, team, members] 102 | current_audience = public 103 | link_permissions = [default] 104 | password_protected = false 105 | 106 | struct AudienceRestrictingSharedFolder 107 | "Information about the shared folder that prevents the link audience for this link from being 108 | more restrictive." 109 | shared_folder_id common.SharedFolderId 110 | "The ID of the shared folder." 111 | name String 112 | "The name of the shared folder." 113 | audience LinkAudience 114 | "The link audience of the shared folder." 115 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/samples/forgetfs/forget_fs_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package forgetfs_test 16 | 17 | import ( 18 | "io" 19 | "os" 20 | "path" 21 | "testing" 22 | 23 | "github.com/jacobsa/fuse/samples" 24 | "github.com/jacobsa/fuse/samples/forgetfs" 25 | . "github.com/jacobsa/ogletest" 26 | ) 27 | 28 | func TestForgetFS(t *testing.T) { RunTests(t) } 29 | 30 | //////////////////////////////////////////////////////////////////////// 31 | // Boilerplate 32 | //////////////////////////////////////////////////////////////////////// 33 | 34 | type ForgetFSTest struct { 35 | samples.SampleTest 36 | fs *forgetfs.ForgetFS 37 | } 38 | 39 | func init() { RegisterTestSuite(&ForgetFSTest{}) } 40 | 41 | func (t *ForgetFSTest) SetUp(ti *TestInfo) { 42 | t.fs = forgetfs.NewFileSystem() 43 | t.Server = t.fs 44 | t.SampleTest.SetUp(ti) 45 | } 46 | 47 | func (t *ForgetFSTest) TearDown() { 48 | // Unmount. 49 | t.SampleTest.TearDown() 50 | 51 | // Crash if anything is left. 52 | t.fs.Check() 53 | } 54 | 55 | //////////////////////////////////////////////////////////////////////// 56 | // Tests 57 | //////////////////////////////////////////////////////////////////////// 58 | 59 | func (t *ForgetFSTest) Open_Foo() { 60 | var err error 61 | 62 | f, err := os.Open(path.Join(t.Dir, "foo")) 63 | AssertEq(nil, err) 64 | 65 | err = f.Close() 66 | AssertEq(nil, err) 67 | } 68 | 69 | func (t *ForgetFSTest) Open_Bar() { 70 | var err error 71 | 72 | f, err := os.Open(path.Join(t.Dir, "bar")) 73 | AssertEq(nil, err) 74 | 75 | err = f.Close() 76 | AssertEq(nil, err) 77 | } 78 | 79 | func (t *ForgetFSTest) Open_ManyTimes() { 80 | // Set up a slice of files that will be closed when we're done. 81 | var toClose []io.Closer 82 | defer func() { 83 | for _, c := range toClose { 84 | ExpectEq(nil, c.Close()) 85 | } 86 | }() 87 | 88 | // Open foo many times. 89 | for i := 0; i < 100; i++ { 90 | f, err := os.Open(path.Join(t.Dir, "foo")) 91 | AssertEq(nil, err) 92 | toClose = append(toClose, f) 93 | } 94 | 95 | // Open bar many times. 96 | for i := 0; i < 100; i++ { 97 | f, err := os.Open(path.Join(t.Dir, "bar")) 98 | AssertEq(nil, err) 99 | toClose = append(toClose, f) 100 | } 101 | } 102 | 103 | func (t *ForgetFSTest) Stat_Foo() { 104 | var fi os.FileInfo 105 | var err error 106 | 107 | fi, err = os.Stat(path.Join(t.Dir, "foo")) 108 | AssertEq(nil, err) 109 | AssertEq("foo", fi.Name()) 110 | AssertEq(os.FileMode(0777), fi.Mode()) 111 | } 112 | 113 | func (t *ForgetFSTest) Stat_Bar() { 114 | var fi os.FileInfo 115 | var err error 116 | 117 | fi, err = os.Stat(path.Join(t.Dir, "bar")) 118 | AssertEq(nil, err) 119 | AssertEq("bar", fi.Name()) 120 | AssertEq(0777|os.ModeDir, fi.Mode()) 121 | } 122 | 123 | func (t *ForgetFSTest) Stat_ManyTimes() { 124 | var err error 125 | 126 | // Stat foo many times. 127 | for i := 0; i < 100; i++ { 128 | _, err = os.Stat(path.Join(t.Dir, "foo")) 129 | AssertEq(nil, err) 130 | } 131 | 132 | // Stat bar many times. 133 | for i := 0; i < 100; i++ { 134 | _, err = os.Stat(path.Join(t.Dir, "bar")) 135 | AssertEq(nil, err) 136 | } 137 | } 138 | 139 | func (t *ForgetFSTest) CreateFile() { 140 | // Create and close many files within the root. 141 | for i := 0; i < 100; i++ { 142 | f, err := os.Create(path.Join(t.Dir, "blah")) 143 | AssertEq(nil, err) 144 | AssertEq(nil, f.Close()) 145 | } 146 | 147 | // Create and close many files within the sub-directory. 148 | for i := 0; i < 100; i++ { 149 | f, err := os.Create(path.Join(t.Dir, "bar", "blah")) 150 | AssertEq(nil, err) 151 | AssertEq(nil, f.Close()) 152 | } 153 | } 154 | 155 | func (t *ForgetFSTest) MkDir() { 156 | // Create many directories within the root. 157 | for i := 0; i < 100; i++ { 158 | err := os.Mkdir(path.Join(t.Dir, "blah"), 0777) 159 | AssertEq(nil, err) 160 | } 161 | 162 | // Create many directories within the sub-directory. 163 | for i := 0; i < 100; i++ { 164 | err := os.Mkdir(path.Join(t.Dir, "bar", "blah"), 0777) 165 | AssertEq(nil, err) 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/samples/interruptfs/interrupt_fs_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package interruptfs_test 16 | 17 | import ( 18 | "bytes" 19 | "os" 20 | "os/exec" 21 | "path" 22 | "testing" 23 | "time" 24 | 25 | "github.com/jacobsa/fuse/fuseutil" 26 | "github.com/jacobsa/fuse/samples" 27 | "github.com/jacobsa/fuse/samples/interruptfs" 28 | . "github.com/jacobsa/oglematchers" 29 | . "github.com/jacobsa/ogletest" 30 | ) 31 | 32 | func TestInterruptFS(t *testing.T) { RunTests(t) } 33 | 34 | //////////////////////////////////////////////////////////////////////// 35 | // Boilerplate 36 | //////////////////////////////////////////////////////////////////////// 37 | 38 | type InterruptFSTest struct { 39 | samples.SampleTest 40 | fs *interruptfs.InterruptFS 41 | } 42 | 43 | func init() { RegisterTestSuite(&InterruptFSTest{}) } 44 | 45 | var _ SetUpInterface = &InterruptFSTest{} 46 | var _ TearDownInterface = &InterruptFSTest{} 47 | 48 | func (t *InterruptFSTest) SetUp(ti *TestInfo) { 49 | var err error 50 | 51 | // Create the file system. 52 | t.fs = interruptfs.New() 53 | AssertEq(nil, err) 54 | 55 | t.Server = fuseutil.NewFileSystemServer(t.fs) 56 | 57 | // Mount it. 58 | t.SampleTest.SetUp(ti) 59 | } 60 | 61 | //////////////////////////////////////////////////////////////////////// 62 | // Test functions 63 | //////////////////////////////////////////////////////////////////////// 64 | 65 | func (t *InterruptFSTest) StatFoo() { 66 | fi, err := os.Stat(path.Join(t.Dir, "foo")) 67 | AssertEq(nil, err) 68 | 69 | ExpectEq("foo", fi.Name()) 70 | ExpectEq(0777, fi.Mode()) 71 | ExpectFalse(fi.IsDir()) 72 | } 73 | 74 | func (t *InterruptFSTest) InterruptedDuringRead() { 75 | var err error 76 | t.fs.EnableReadBlocking() 77 | 78 | // Start a sub-process that attempts to read the file. 79 | cmd := exec.Command("cat", path.Join(t.Dir, "foo")) 80 | 81 | var cmdOutput bytes.Buffer 82 | cmd.Stdout = &cmdOutput 83 | cmd.Stderr = &cmdOutput 84 | 85 | err = cmd.Start() 86 | AssertEq(nil, err) 87 | 88 | // Wait for the command in the background, writing to a channel when it is 89 | // finished. 90 | cmdErr := make(chan error) 91 | go func() { 92 | cmdErr <- cmd.Wait() 93 | }() 94 | 95 | // Wait for the read to make it to the file system. 96 | t.fs.WaitForFirstRead() 97 | 98 | // The command should be hanging on the read, and not yet have returned. 99 | select { 100 | case err = <-cmdErr: 101 | AddFailure("Command returned early with error: %v", err) 102 | AbortTest() 103 | 104 | case <-time.After(10 * time.Millisecond): 105 | } 106 | 107 | // Send SIGINT. 108 | cmd.Process.Signal(os.Interrupt) 109 | 110 | // Now the command should return, with an appropriate error. 111 | err = <-cmdErr 112 | ExpectThat(err, Error(HasSubstr("signal"))) 113 | ExpectThat(err, Error(HasSubstr("interrupt"))) 114 | } 115 | 116 | func (t *InterruptFSTest) InterruptedDuringFlush() { 117 | var err error 118 | t.fs.EnableFlushBlocking() 119 | 120 | // Start a sub-process that attempts to read the file. 121 | cmd := exec.Command("cat", path.Join(t.Dir, "foo")) 122 | 123 | var cmdOutput bytes.Buffer 124 | cmd.Stdout = &cmdOutput 125 | cmd.Stderr = &cmdOutput 126 | 127 | err = cmd.Start() 128 | AssertEq(nil, err) 129 | 130 | // Wait for the command in the background, writing to a channel when it is 131 | // finished. 132 | cmdErr := make(chan error) 133 | go func() { 134 | cmdErr <- cmd.Wait() 135 | }() 136 | 137 | // Wait for the flush to make it to the file system. 138 | t.fs.WaitForFirstFlush() 139 | 140 | // The command should be hanging on the flush, and not yet have returned. 141 | select { 142 | case err = <-cmdErr: 143 | AddFailure("Command returned early with error: %v", err) 144 | AbortTest() 145 | 146 | case <-time.After(10 * time.Millisecond): 147 | } 148 | 149 | // Send SIGINT. 150 | cmd.Process.Signal(os.Interrupt) 151 | 152 | // Now the command should return, with an appropriate error. 153 | err = <-cmdErr 154 | ExpectThat(err, Error(HasSubstr("signal"))) 155 | ExpectThat(err, Error(HasSubstr("interrupt"))) 156 | } 157 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/samples/mount_sample/mount.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // A simple tool for mounting sample file systems, used by the tests in 16 | // samples/. 17 | package main 18 | 19 | import ( 20 | "errors" 21 | "flag" 22 | "fmt" 23 | "log" 24 | "os" 25 | "runtime" 26 | "syscall" 27 | 28 | "github.com/jacobsa/fuse" 29 | "github.com/jacobsa/fuse/samples/flushfs" 30 | "golang.org/x/net/context" 31 | ) 32 | 33 | var fType = flag.String("type", "", "The name of the samples/ sub-dir.") 34 | var fMountPoint = flag.String("mount_point", "", "Path to mount point.") 35 | var fReadyFile = flag.Uint64("ready_file", 0, "FD to signal when ready.") 36 | 37 | var fFlushesFile = flag.Uint64("flushfs.flushes_file", 0, "") 38 | var fFsyncsFile = flag.Uint64("flushfs.fsyncs_file", 0, "") 39 | var fFlushError = flag.Int("flushfs.flush_error", 0, "") 40 | var fFsyncError = flag.Int("flushfs.fsync_error", 0, "") 41 | 42 | var fReadOnly = flag.Bool("read_only", false, "Mount in read-only mode.") 43 | var fDebug = flag.Bool("debug", false, "Enable debug logging.") 44 | 45 | func makeFlushFS() (server fuse.Server, err error) { 46 | // Check the flags. 47 | if *fFlushesFile == 0 || *fFsyncsFile == 0 { 48 | err = fmt.Errorf("You must set the flushfs flags.") 49 | return 50 | } 51 | 52 | // Set up the files. 53 | flushes := os.NewFile(uintptr(*fFlushesFile), "(flushes file)") 54 | fsyncs := os.NewFile(uintptr(*fFsyncsFile), "(fsyncs file)") 55 | 56 | // Set up errors. 57 | var flushErr error 58 | var fsyncErr error 59 | 60 | if *fFlushError != 0 { 61 | flushErr = syscall.Errno(*fFlushError) 62 | } 63 | 64 | if *fFsyncError != 0 { 65 | fsyncErr = syscall.Errno(*fFsyncError) 66 | } 67 | 68 | // Report flushes and fsyncs by writing the contents followed by a newline. 69 | report := func(f *os.File, outErr error) func(string) error { 70 | return func(s string) (err error) { 71 | buf := []byte(s) 72 | buf = append(buf, '\n') 73 | 74 | _, err = f.Write(buf) 75 | if err != nil { 76 | err = fmt.Errorf("Write: %v", err) 77 | return 78 | } 79 | 80 | err = outErr 81 | return 82 | } 83 | } 84 | 85 | reportFlush := report(flushes, flushErr) 86 | reportFsync := report(fsyncs, fsyncErr) 87 | 88 | // Create the file system. 89 | server, err = flushfs.NewFileSystem(reportFlush, reportFsync) 90 | 91 | return 92 | } 93 | 94 | func makeFS() (server fuse.Server, err error) { 95 | switch *fType { 96 | default: 97 | err = fmt.Errorf("Unknown FS type: %v", *fType) 98 | 99 | case "flushfs": 100 | server, err = makeFlushFS() 101 | } 102 | 103 | return 104 | } 105 | 106 | func getReadyFile() (f *os.File, err error) { 107 | if *fReadyFile == 0 { 108 | err = errors.New("You must set --ready_file.") 109 | return 110 | } 111 | 112 | f = os.NewFile(uintptr(*fReadyFile), "(ready file)") 113 | return 114 | } 115 | 116 | func main() { 117 | flag.Parse() 118 | 119 | // Allow parallelism in the file system implementation, to help flush out 120 | // bugs like https://github.com/jacobsa/fuse/issues/4. 121 | runtime.GOMAXPROCS(2) 122 | 123 | // Grab the file to signal when ready. 124 | readyFile, err := getReadyFile() 125 | if err != nil { 126 | log.Fatalf("getReadyFile:", err) 127 | } 128 | 129 | // Create an appropriate file system. 130 | server, err := makeFS() 131 | if err != nil { 132 | log.Fatalf("makeFS: %v", err) 133 | } 134 | 135 | // Mount the file system. 136 | if *fMountPoint == "" { 137 | log.Fatalf("You must set --mount_point.") 138 | } 139 | 140 | cfg := &fuse.MountConfig{ 141 | ReadOnly: *fReadOnly, 142 | } 143 | 144 | if *fDebug { 145 | cfg.DebugLogger = log.New(os.Stderr, "fuse: ", 0) 146 | } 147 | 148 | mfs, err := fuse.Mount(*fMountPoint, server, cfg) 149 | if err != nil { 150 | log.Fatalf("Mount: %v", err) 151 | } 152 | 153 | // Signal that it is ready. 154 | _, err = readyFile.Write([]byte("x")) 155 | if err != nil { 156 | log.Fatalf("readyFile.Write: %v", err) 157 | } 158 | 159 | // Wait for it to be unmounted. 160 | if err = mfs.Join(context.Background()); err != nil { 161 | log.Fatalf("Join: %v", err) 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/dropbox/async/types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) Dropbox, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | // Package async : has no documentation (yet) 22 | package async 23 | 24 | import ( 25 | "encoding/json" 26 | 27 | "github.com/dropbox/dropbox-sdk-go-unofficial/dropbox" 28 | ) 29 | 30 | // LaunchResultBase : Result returned by methods that launch an asynchronous 31 | // job. A method who may either launch an asynchronous job, or complete the 32 | // request synchronously, can use this union by extending it, and adding a 33 | // 'complete' field with the type of the synchronous response. See 34 | // `LaunchEmptyResult` for an example. 35 | type LaunchResultBase struct { 36 | dropbox.Tagged 37 | // AsyncJobId : This response indicates that the processing is asynchronous. 38 | // The string is an id that can be used to obtain the status of the 39 | // asynchronous job. 40 | AsyncJobId string `json:"async_job_id,omitempty"` 41 | } 42 | 43 | // Valid tag values for LaunchResultBase 44 | const ( 45 | LaunchResultBaseAsyncJobId = "async_job_id" 46 | ) 47 | 48 | // UnmarshalJSON deserializes into a LaunchResultBase instance 49 | func (u *LaunchResultBase) UnmarshalJSON(body []byte) error { 50 | type wrap struct { 51 | dropbox.Tagged 52 | } 53 | var w wrap 54 | var err error 55 | if err = json.Unmarshal(body, &w); err != nil { 56 | return err 57 | } 58 | u.Tag = w.Tag 59 | switch u.Tag { 60 | case "async_job_id": 61 | err = json.Unmarshal(body, &u.AsyncJobId) 62 | 63 | if err != nil { 64 | return err 65 | } 66 | } 67 | return nil 68 | } 69 | 70 | // LaunchEmptyResult : Result returned by methods that may either launch an 71 | // asynchronous job or complete synchronously. Upon synchronous completion of 72 | // the job, no additional information is returned. 73 | type LaunchEmptyResult struct { 74 | dropbox.Tagged 75 | } 76 | 77 | // Valid tag values for LaunchEmptyResult 78 | const ( 79 | LaunchEmptyResultComplete = "complete" 80 | ) 81 | 82 | // PollArg : Arguments for methods that poll the status of an asynchronous job. 83 | type PollArg struct { 84 | // AsyncJobId : Id of the asynchronous job. This is the value of a response 85 | // returned from the method that launched the job. 86 | AsyncJobId string `json:"async_job_id"` 87 | } 88 | 89 | // NewPollArg returns a new PollArg instance 90 | func NewPollArg(AsyncJobId string) *PollArg { 91 | s := new(PollArg) 92 | s.AsyncJobId = AsyncJobId 93 | return s 94 | } 95 | 96 | // PollResultBase : Result returned by methods that poll for the status of an 97 | // asynchronous job. Unions that extend this union should add a 'complete' field 98 | // with a type of the information returned upon job completion. See 99 | // `PollEmptyResult` for an example. 100 | type PollResultBase struct { 101 | dropbox.Tagged 102 | } 103 | 104 | // Valid tag values for PollResultBase 105 | const ( 106 | PollResultBaseInProgress = "in_progress" 107 | ) 108 | 109 | // PollEmptyResult : Result returned by methods that poll for the status of an 110 | // asynchronous job. Upon completion of the job, no additional information is 111 | // returned. 112 | type PollEmptyResult struct { 113 | dropbox.Tagged 114 | } 115 | 116 | // Valid tag values for PollEmptyResult 117 | const ( 118 | PollEmptyResultComplete = "complete" 119 | ) 120 | 121 | // PollError : Error returned by methods for polling the status of asynchronous 122 | // job. 123 | type PollError struct { 124 | dropbox.Tagged 125 | } 126 | 127 | // Valid tag values for PollError 128 | const ( 129 | PollErrorInvalidAsyncJobId = "invalid_async_job_id" 130 | PollErrorInternalError = "internal_error" 131 | PollErrorOther = "other" 132 | ) 133 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/generator/dropbox-api-spec/properties.stone: -------------------------------------------------------------------------------- 1 | namespace properties 2 | "This namespace contains helper entities for property and property/template endpoints." 3 | 4 | alias TemplateId = String(min_length=1,pattern="(/|ptid:).*") 5 | 6 | struct PropertyGroupTemplate 7 | "Describes property templates that can be filled and associated with a file." 8 | 9 | name String 10 | "A display name for the property template. Property template names can 11 | be up to 256 bytes." 12 | description String 13 | "Description for new property template. Property template descriptions 14 | can be up to 1024 bytes." 15 | fields List(PropertyFieldTemplate) 16 | "This is a list of custom properties associated with a property template. 17 | There can be up to 64 properties in a single property template." 18 | 19 | example default 20 | name = "Security" 21 | description = "These properties describe how confidential this file is." 22 | fields = [default] 23 | 24 | struct PropertyFieldTemplate 25 | "Describe a single property field type which that can be part of a property template." 26 | 27 | name String 28 | "This is the name or key of a custom property in a property template. 29 | File property names can be up to 256 bytes." 30 | description String 31 | "This is the description for a custom property in a property template. 32 | File property description can be up to 1024 bytes." 33 | type PropertyType 34 | "This is the data type of the value of this property. This type 35 | will be enforced upon property creation and modifications." 36 | 37 | example default 38 | name = "Security Policy" 39 | description = "This is the security policy of the file or folder described. 40 | Policies can be Confidential, Public or Internal." 41 | type = default 42 | 43 | union ModifyPropertyTemplateError extends PropertyTemplateError 44 | conflicting_property_names 45 | "A property field name already exists in the template." 46 | too_many_properties 47 | "There are too many properties in the changed template. 48 | The maximum number of properties per template is 32." 49 | too_many_templates 50 | "There are too many templates for the team." 51 | template_attribute_too_large 52 | "The template name, description or field names is too large." 53 | 54 | union PropertyTemplateError 55 | template_not_found TemplateId 56 | "Property template does not exist for given identifier." 57 | restricted_content 58 | "You do not have the permissions to modify this property template." 59 | 60 | struct PropertyGroup 61 | "Collection of custom properties in filled property templates." 62 | 63 | template_id TemplateId 64 | "A unique identifier for a property template type." 65 | fields List(PropertyField) 66 | "This is a list of custom properties associated with a file. 67 | There can be up to 32 properties for a template." 68 | 69 | example default 70 | template_id = "ptid:1a5n2i6d3OYEAAAAAAAAAYa" 71 | fields = [default] 72 | 73 | struct PropertyField 74 | name String 75 | "This is the name or key of a custom property in a property template. 76 | File property names can be up to 256 bytes." 77 | value String 78 | "Value of a custom property attached to a file. Values can be up to 1024 79 | bytes." 80 | 81 | example default 82 | name = "Security Policy" 83 | value = "Confidential" 84 | 85 | union PropertyType 86 | "Data type of the given property added. This endpoint is in beta and 87 | only properties of type strings is supported." 88 | 89 | string 90 | "The associated property will be of type string. Unicode is supported." 91 | 92 | example default 93 | string = null 94 | 95 | # 96 | # Shared struct used for /template/list and /template/get 97 | # 98 | 99 | struct GetPropertyTemplateArg 100 | template_id TemplateId 101 | "An identifier for property template added by route properties/template/add." 102 | 103 | example default 104 | template_id = "ptid:1a5n2i6d3OYEAAAAAAAAAYa" 105 | 106 | struct GetPropertyTemplateResult extends PropertyGroupTemplate 107 | "The Property template for the specified template." 108 | 109 | example default 110 | name = "Security" 111 | description = "These properties describe how confidential this file is." 112 | fields = [default] 113 | 114 | struct ListPropertyTemplateIds 115 | template_ids List(TemplateId) 116 | "List of identifiers for templates added by route properties/template/add." 117 | 118 | example default 119 | template_ids = ["ptid:1a5n2i6d3OYEAAAAAAAAAYa"] 120 | 121 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/generator/go_helpers.py: -------------------------------------------------------------------------------- 1 | from stone.api import ApiNamespace 2 | from stone.data_type import ( 3 | Boolean, 4 | Float32, 5 | Float64, 6 | Int32, 7 | Int64, 8 | String, 9 | Timestamp, 10 | UInt32, 11 | UInt64, 12 | unwrap_nullable, 13 | is_composite_type, 14 | is_list_type, 15 | is_struct_type, 16 | Void, 17 | ) 18 | from stone.target import helpers 19 | 20 | HEADER = """\ 21 | // Copyright (c) Dropbox, Inc. 22 | // 23 | // Permission is hereby granted, free of charge, to any person obtaining a copy 24 | // of this software and associated documentation files (the "Software"), to deal 25 | // in the Software without restriction, including without limitation the rights 26 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 27 | // copies of the Software, and to permit persons to whom the Software is 28 | // furnished to do so, subject to the following conditions: 29 | // 30 | // The above copyright notice and this permission notice shall be included in 31 | // all copies or substantial portions of the Software. 32 | // 33 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 34 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 35 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 36 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 37 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 38 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 39 | // THE SOFTWARE. 40 | """ 41 | 42 | _reserved_keywords = { 43 | 'break', 'default', 'func', 'interface', 'select', 44 | 'case', 'defer', 'go', 'map', 'struct', 45 | 'chan', 'else', 'goto', 'package', 'switch', 46 | 'const', 'fallthrough', 'if', 'range', 'type', 47 | 'continue', 'for', 'import', 'return', 'var', 48 | } 49 | 50 | _type_table = { 51 | UInt64: 'uint64', 52 | Int64: 'int64', 53 | UInt32: 'uint32', 54 | Int32: 'int32', 55 | Float64: 'float64', 56 | Float32: 'float32', 57 | Boolean: 'bool', 58 | String: 'string', 59 | Timestamp: 'time.Time', 60 | Void: 'struct{}', 61 | } 62 | 63 | 64 | def _rename_if_reserved(s): 65 | if s in _reserved_keywords: 66 | return s + '_' 67 | else: 68 | return s 69 | 70 | 71 | def fmt_type(data_type, namespace=None, use_interface=False): 72 | data_type, nullable = unwrap_nullable(data_type) 73 | if is_list_type(data_type): 74 | return '[]%s' % fmt_type(data_type.data_type, namespace, use_interface) 75 | type_name = data_type.name 76 | if use_interface and _needs_base_type(data_type): 77 | type_name = 'Is' + type_name 78 | if is_composite_type(data_type) and namespace is not None and \ 79 | namespace.name != data_type.namespace.name: 80 | type_name = data_type.namespace.name + '.' + type_name 81 | if use_interface and _needs_base_type(data_type): 82 | return _type_table.get(data_type.__class__, type_name) 83 | else: 84 | return _type_table.get(data_type.__class__, '*' + type_name) 85 | 86 | 87 | def fmt_var(name, export=True, check_reserved=False): 88 | s = helpers.fmt_pascal(name) if export else helpers.fmt_camel(name) 89 | return _rename_if_reserved(s) if check_reserved else s 90 | 91 | 92 | def _doc_handler(tag, val): 93 | if tag == 'type': 94 | return '`{}`'.format(val) 95 | elif tag == 'route': 96 | return '`{}`'.format(helpers.fmt_camel(val)) 97 | elif tag == 'link': 98 | anchor, link = val.rsplit(' ', 1) 99 | return '`{}` <{}>'.format(anchor, link) 100 | elif tag == 'val': 101 | if val == 'null': 102 | return 'nil' 103 | else: 104 | return val 105 | elif tag == 'field': 106 | return '`{}`'.format(val) 107 | else: 108 | raise RuntimeError('Unknown doc ref tag %r' % tag) 109 | 110 | 111 | def generate_doc(code_generator, t): 112 | doc = t.doc 113 | if doc is None: 114 | doc = 'has no documentation (yet)' 115 | doc = code_generator.process_doc(doc, _doc_handler) 116 | d = '%s : %s' % (fmt_var(t.name), doc) 117 | if isinstance(t, ApiNamespace): 118 | d = 'Package %s : %s' % (t.name, doc) 119 | code_generator.emit_wrapped_text(d, prefix='// ') 120 | 121 | 122 | def _needs_base_type(data_type): 123 | if is_struct_type(data_type) and data_type.has_enumerated_subtypes(): 124 | return True 125 | if is_list_type(data_type): 126 | return _needs_base_type(data_type.data_type) 127 | return False 128 | 129 | 130 | def needs_base_type(struct): 131 | for field in struct.fields: 132 | if _needs_base_type(field.data_type): 133 | return True 134 | return False 135 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/dropbox/team_policies/types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) Dropbox, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | // Package team_policies : has no documentation (yet) 22 | package team_policies 23 | 24 | import "github.com/dropbox/dropbox-sdk-go-unofficial/dropbox" 25 | 26 | // EmmState : has no documentation (yet) 27 | type EmmState struct { 28 | dropbox.Tagged 29 | } 30 | 31 | // Valid tag values for EmmState 32 | const ( 33 | EmmStateDisabled = "disabled" 34 | EmmStateOptional = "optional" 35 | EmmStateRequired = "required" 36 | EmmStateOther = "other" 37 | ) 38 | 39 | // SharedFolderJoinPolicy : Policy governing which shared folders a team member 40 | // can join. 41 | type SharedFolderJoinPolicy struct { 42 | dropbox.Tagged 43 | } 44 | 45 | // Valid tag values for SharedFolderJoinPolicy 46 | const ( 47 | SharedFolderJoinPolicyFromTeamOnly = "from_team_only" 48 | SharedFolderJoinPolicyFromAnyone = "from_anyone" 49 | SharedFolderJoinPolicyOther = "other" 50 | ) 51 | 52 | // SharedFolderMemberPolicy : Policy governing who can be a member of a folder 53 | // shared by a team member. 54 | type SharedFolderMemberPolicy struct { 55 | dropbox.Tagged 56 | } 57 | 58 | // Valid tag values for SharedFolderMemberPolicy 59 | const ( 60 | SharedFolderMemberPolicyTeam = "team" 61 | SharedFolderMemberPolicyAnyone = "anyone" 62 | SharedFolderMemberPolicyOther = "other" 63 | ) 64 | 65 | // SharedLinkCreatePolicy : Policy governing the visibility of shared links. 66 | // This policy can apply to newly created shared links, or all shared links. 67 | type SharedLinkCreatePolicy struct { 68 | dropbox.Tagged 69 | } 70 | 71 | // Valid tag values for SharedLinkCreatePolicy 72 | const ( 73 | SharedLinkCreatePolicyDefaultPublic = "default_public" 74 | SharedLinkCreatePolicyDefaultTeamOnly = "default_team_only" 75 | SharedLinkCreatePolicyTeamOnly = "team_only" 76 | SharedLinkCreatePolicyOther = "other" 77 | ) 78 | 79 | // TeamMemberPolicies : Policies governing team members. 80 | type TeamMemberPolicies struct { 81 | // Sharing : Policies governing sharing. 82 | Sharing *TeamSharingPolicies `json:"sharing"` 83 | // EmmState : This describes the Enterprise Mobility Management (EMM) state 84 | // for this team. This information can be used to understand if an 85 | // organization is integrating with a third-party EMM vendor to further 86 | // manage and apply restrictions upon the team's Dropbox usage on mobile 87 | // devices. This is a new feature and in the future we'll be adding more new 88 | // fields and additional documentation. 89 | EmmState *EmmState `json:"emm_state"` 90 | } 91 | 92 | // NewTeamMemberPolicies returns a new TeamMemberPolicies instance 93 | func NewTeamMemberPolicies(Sharing *TeamSharingPolicies, EmmState *EmmState) *TeamMemberPolicies { 94 | s := new(TeamMemberPolicies) 95 | s.Sharing = Sharing 96 | s.EmmState = EmmState 97 | return s 98 | } 99 | 100 | // TeamSharingPolicies : Policies governing sharing within and outside of the 101 | // team. 102 | type TeamSharingPolicies struct { 103 | // SharedFolderMemberPolicy : Who can join folders shared by team members. 104 | SharedFolderMemberPolicy *SharedFolderMemberPolicy `json:"shared_folder_member_policy"` 105 | // SharedFolderJoinPolicy : Which shared folders team members can join. 106 | SharedFolderJoinPolicy *SharedFolderJoinPolicy `json:"shared_folder_join_policy"` 107 | // SharedLinkCreatePolicy : Who can view shared links owned by team members. 108 | SharedLinkCreatePolicy *SharedLinkCreatePolicy `json:"shared_link_create_policy"` 109 | } 110 | 111 | // NewTeamSharingPolicies returns a new TeamSharingPolicies instance 112 | func NewTeamSharingPolicies(SharedFolderMemberPolicy *SharedFolderMemberPolicy, SharedFolderJoinPolicy *SharedFolderJoinPolicy, SharedLinkCreatePolicy *SharedLinkCreatePolicy) *TeamSharingPolicies { 113 | s := new(TeamSharingPolicies) 114 | s.SharedFolderMemberPolicy = SharedFolderMemberPolicy 115 | s.SharedFolderJoinPolicy = SharedFolderJoinPolicy 116 | s.SharedLinkCreatePolicy = SharedLinkCreatePolicy 117 | return s 118 | } 119 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/samples/statfs/statfs.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package statfs 16 | 17 | import ( 18 | "os" 19 | "sync" 20 | 21 | "golang.org/x/net/context" 22 | 23 | "github.com/jacobsa/fuse" 24 | "github.com/jacobsa/fuse/fuseops" 25 | "github.com/jacobsa/fuse/fuseutil" 26 | ) 27 | 28 | // A file system that allows orchestrating canned responses to statfs ops, for 29 | // testng out OS-specific statfs behavior. 30 | // 31 | // The file system allows opening and writing to any name that is a child of 32 | // the root inode, and keeps track of the most recent write size delivered by 33 | // the kernel (in order to test statfs response block size effects on write 34 | // size, if any). 35 | // 36 | // Safe for concurrent access. 37 | type FS interface { 38 | fuseutil.FileSystem 39 | 40 | // Set the canned response to be used for future statfs ops. 41 | SetStatFSResponse(r fuseops.StatFSOp) 42 | 43 | // Set the canned response to be used for future stat ops. 44 | SetStatResponse(r fuseops.InodeAttributes) 45 | 46 | // Return the size of the most recent write delivered by the kernel, or -1 if 47 | // none. 48 | MostRecentWriteSize() int 49 | } 50 | 51 | func New() (fs FS) { 52 | fs = &statFS{ 53 | cannedStatResponse: fuseops.InodeAttributes{ 54 | Mode: 0666, 55 | }, 56 | mostRecentWriteSize: -1, 57 | } 58 | 59 | return 60 | } 61 | 62 | const childInodeID = fuseops.RootInodeID + 1 63 | 64 | type statFS struct { 65 | fuseutil.NotImplementedFileSystem 66 | 67 | mu sync.Mutex 68 | cannedResponse fuseops.StatFSOp // GUARDED_BY(mu) 69 | cannedStatResponse fuseops.InodeAttributes // GUARDED_BY(mu) 70 | mostRecentWriteSize int // GUARDED_BY(mu) 71 | } 72 | 73 | //////////////////////////////////////////////////////////////////////// 74 | // Helpers 75 | //////////////////////////////////////////////////////////////////////// 76 | 77 | func dirAttrs() fuseops.InodeAttributes { 78 | return fuseops.InodeAttributes{ 79 | Mode: os.ModeDir | 0777, 80 | } 81 | } 82 | 83 | func (fs *statFS) fileAttrs() fuseops.InodeAttributes { 84 | return fs.cannedStatResponse 85 | } 86 | 87 | //////////////////////////////////////////////////////////////////////// 88 | // Public interface 89 | //////////////////////////////////////////////////////////////////////// 90 | 91 | // LOCKS_EXCLUDED(fs.mu) 92 | func (fs *statFS) SetStatFSResponse(r fuseops.StatFSOp) { 93 | fs.mu.Lock() 94 | defer fs.mu.Unlock() 95 | 96 | fs.cannedResponse = r 97 | } 98 | 99 | // LOCKS_EXCLUDED(fs.mu) 100 | func (fs *statFS) SetStatResponse(r fuseops.InodeAttributes) { 101 | fs.mu.Lock() 102 | defer fs.mu.Unlock() 103 | 104 | fs.cannedStatResponse = r 105 | } 106 | 107 | // LOCKS_EXCLUDED(fs.mu) 108 | func (fs *statFS) MostRecentWriteSize() int { 109 | fs.mu.Lock() 110 | defer fs.mu.Unlock() 111 | 112 | return fs.mostRecentWriteSize 113 | } 114 | 115 | //////////////////////////////////////////////////////////////////////// 116 | // FileSystem methods 117 | //////////////////////////////////////////////////////////////////////// 118 | 119 | // LOCKS_EXCLUDED(fs.mu) 120 | func (fs *statFS) StatFS( 121 | ctx context.Context, 122 | op *fuseops.StatFSOp) (err error) { 123 | fs.mu.Lock() 124 | defer fs.mu.Unlock() 125 | 126 | *op = fs.cannedResponse 127 | return 128 | } 129 | 130 | func (fs *statFS) LookUpInode( 131 | ctx context.Context, 132 | op *fuseops.LookUpInodeOp) (err error) { 133 | // Only the root has children. 134 | if op.Parent != fuseops.RootInodeID { 135 | err = fuse.ENOENT 136 | return 137 | } 138 | 139 | op.Entry.Child = childInodeID 140 | op.Entry.Attributes = fs.fileAttrs() 141 | 142 | return 143 | } 144 | 145 | func (fs *statFS) GetInodeAttributes( 146 | ctx context.Context, 147 | op *fuseops.GetInodeAttributesOp) (err error) { 148 | switch op.Inode { 149 | case fuseops.RootInodeID: 150 | op.Attributes = dirAttrs() 151 | 152 | case childInodeID: 153 | op.Attributes = fs.fileAttrs() 154 | 155 | default: 156 | err = fuse.ENOENT 157 | } 158 | 159 | return 160 | } 161 | 162 | func (fs *statFS) SetInodeAttributes( 163 | ctx context.Context, 164 | op *fuseops.SetInodeAttributesOp) (err error) { 165 | // Ignore calls to truncate existing files when opening. 166 | return 167 | } 168 | 169 | func (fs *statFS) OpenFile( 170 | ctx context.Context, 171 | op *fuseops.OpenFileOp) (err error) { 172 | return 173 | } 174 | 175 | // LOCKS_EXCLUDED(fs.mu) 176 | func (fs *statFS) WriteFile( 177 | ctx context.Context, 178 | op *fuseops.WriteFileOp) (err error) { 179 | fs.mu.Lock() 180 | defer fs.mu.Unlock() 181 | 182 | fs.mostRecentWriteSize = len(op.Data) 183 | return 184 | } 185 | -------------------------------------------------------------------------------- /vendor/github.com/dropbox/dropbox-sdk-go-unofficial/README.md: -------------------------------------------------------------------------------- 1 | # Dropbox SDK for Go [UNOFFICIAL] [![GoDoc](https://godoc.org/github.com/dropbox/dropbox-sdk-go-unofficial/dropbox?status.svg)](https://godoc.org/github.com/dropbox/dropbox-sdk-go-unofficial/dropbox) [![Build Status](https://travis-ci.org/dropbox/dropbox-sdk-go-unofficial.svg?branch=master)](https://travis-ci.org/dropbox/dropbox-sdk-go-unofficial) 2 | 3 | An **UNOFFICIAL** Go SDK for integrating with the Dropbox API v2. Tested with Go 1.5+ 4 | 5 | :warning: WARNING: This SDK is **NOT yet official**. What does this mean? 6 | 7 | * There is no formal Dropbox [support](https://www.dropbox.com/developers/support) for this SDK at this point 8 | * Bugs may or may not get fixed 9 | * Not all SDK features may be implemented and implemented features may be buggy or incorrect 10 | 11 | 12 | ### Uh OK, so why are you releasing this? 13 | 14 | * the SDK, while unofficial, _is_ usable. See [dbxcli](https://github.com/dropbox/dbxcli) for an example application built using the SDK 15 | * we would like to get feedback from the community and evaluate the level of interest/enthusiasm before investing into official supporting one more SDK 16 | 17 | ## Installation 18 | 19 | ```sh 20 | $ go get github.com/dropbox/dropbox-sdk-go-unofficial/dropbox/... 21 | ``` 22 | 23 | For most applications, you should just import the relevant namespace(s) only. The SDK exports the following sub-packages: 24 | 25 | * `github.com/dropbox/dropbox-sdk-go-unofficial/dropbox/auth` 26 | * `github.com/dropbox/dropbox-sdk-go-unofficial/dropbox/files` 27 | * `github.com/dropbox/dropbox-sdk-go-unofficial/dropbox/sharing` 28 | * `github.com/dropbox/dropbox-sdk-go-unofficial/dropbox/team` 29 | * `github.com/dropbox/dropbox-sdk-go-unofficial/dropbox/users` 30 | 31 | Additionally, the base `github.com/dropbox/dropbox-sdk-go-unofficial/dropbox` package exports some configuration and helper methods. 32 | 33 | ## Usage 34 | 35 | First, you need to [register a new "app"](https://dropbox.com/developers/apps) to start making API requests. Once you have created an app, you can either use the SDK via an access token (useful for testing) or via the regular OAuth2 flow (recommended for production). 36 | 37 | ### Using OAuth token 38 | 39 | Once you've created an app, you can get an access token from the app's console. Note that this token will only work for the Dropbox account the token is associated with. 40 | 41 | ```go 42 | import "github.com/dropbox/dropbox-sdk-go-unofficial/dropbox" 43 | import "github.com/dropbox/dropbox-sdk-go-unofficial/dropbox/users" 44 | 45 | func main() { 46 | config := dropbox.Config{Token: token, Verbose: true} // second arg enables verbose logging in the SDK 47 | dbx := users.New(config) 48 | // start making API calls 49 | } 50 | ``` 51 | 52 | ### Using OAuth2 flow 53 | 54 | For this, you will need your `APP_KEY` and `APP_SECRET` from the developers console. Your app will then have to take users though the oauth flow, as part of which users will explicitly grant permissions to your app. At the end of this process, users will get a token that the app can then use for subsequent authentication. See [this](https://godoc.org/golang.org/x/oauth2#example-Config) for an example of oauth2 flow in Go. 55 | 56 | Once you have the token, usage is same as above. 57 | 58 | ### Making API calls 59 | 60 | Each Dropbox API takes in a request type and returns a response type. For instance, [/users/get_account](https://www.dropbox.com/developers/documentation/http/documentation#users-get_account) takes as input a `GetAccountArg` and returns a `BasicAccount`. The typical pattern for making API calls is: 61 | 62 | * Instantiate the argument via the `New*` convenience functions in the SDK 63 | * Invoke the API 64 | * Process the response (or handle error, as below) 65 | 66 | Here's an example: 67 | 68 | ```go 69 | arg := users.NewGetAccountArg(accountId) 70 | if resp, err := dbx.GetAccount(arg); err != nil { 71 | return err 72 | } 73 | fmt.Printf("Name: %v", resp.Name) 74 | ``` 75 | 76 | ### Error Handling 77 | 78 | As described in the [API docs](https://www.dropbox.com/developers/documentation/http/documentation#error-handling), all HTTP errors _except_ 409 are returned as-is to the client (with a helpful text message where possible). In case of a 409, the SDK will return an endpoint-specific error as described in the API. This will be made available as `EndpointError` member in the error. 79 | 80 | ## Note on using the Teams API 81 | 82 | To use the Team API, you will need to create a Dropbox Business App. The OAuth token from this app will _only_ work for the Team API. 83 | 84 | Please read the [API docs](https://www.dropbox.com/developers/documentation/http/teams) carefully to appropriate secure your apps and tokens when using the Team API. 85 | 86 | ## Code Generation 87 | 88 | This SDK is automatically generated using the public [Dropbox API spec](https://github.com/dropbox/dropbox-api-spec) and [Stone](https://github.com/dropbox/stone). See this [README](https://github.com/dropbox/dropbox-sdk-go-unofficial/blob/master/generator/README.md) 89 | for more details on how code is generated. 90 | 91 | ## Caveats 92 | 93 | * To re-iterate, this is an **UNOFFICIAL** SDK and thus has no official support from Dropbox 94 | * Only supports the v2 API. Parts of the v2 API are still in beta, and thus subject to change 95 | * This SDK itself is in beta, and so interfaces may change at any point 96 | -------------------------------------------------------------------------------- /internal/coreutil/util.go: -------------------------------------------------------------------------------- 1 | package coreutil 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io/ioutil" 7 | "log" 8 | "os" 9 | "reflect" 10 | "strconv" 11 | "strings" 12 | 13 | "github.com/go-yaml/yaml" 14 | ) 15 | 16 | // ParseConfig reads yaml or json file into a struct 17 | func ParseConfig(srcfile string, out interface{}) (err error) { 18 | if srcfile == "" { 19 | return 20 | } 21 | f, err := os.Open(srcfile) 22 | if err != nil { 23 | return err 24 | } 25 | defer f.Close() 26 | 27 | if strings.HasSuffix(srcfile, ".json") { 28 | // Read as JSON 29 | json.NewDecoder(f).Decode(out) 30 | return 31 | } 32 | if strings.HasSuffix(srcfile, ".yaml") { 33 | data, err := ioutil.ReadAll(f) 34 | if err != nil { 35 | return err 36 | } 37 | // Read as yaml 38 | yaml.Unmarshal(data, out) 39 | } 40 | return err 41 | } 42 | 43 | // SaveConfig saves configuration file in specified 'json or yaml' extension 44 | func SaveConfig(name string, obj interface{}) (err error) { 45 | var data []byte 46 | if strings.HasSuffix(name, ".json") { 47 | data, err = json.MarshalIndent(obj, " ", " ") 48 | if err != nil { 49 | return err 50 | } 51 | } 52 | if strings.HasSuffix(name, ".yaml") { 53 | data, err = yaml.Marshal(obj) 54 | if err != nil { 55 | return err 56 | } 57 | } 58 | 59 | f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) 60 | if err != nil { 61 | log.Fatalf("Unable to save config: %v\n", err) 62 | } 63 | defer f.Close() 64 | 65 | f.Write(data) 66 | f.Sync() 67 | 68 | return err 69 | } 70 | 71 | // ParseOptions parses mount options like -o uid=100,gid=100 to struct 72 | func ParseOptions(opt string, out interface{}) (err error) { 73 | mountopts := map[string]string{} 74 | parts := strings.Split(opt, ",") 75 | // First Map to keyvalue 76 | for _, v := range parts { 77 | if keyindex := strings.Index(v, "="); keyindex != -1 { // Eq 78 | key := strings.TrimSpace(v[:keyindex]) 79 | value := strings.TrimSpace(v[keyindex+1:]) 80 | mountopts[key] = value 81 | } else { 82 | mountopts[v] = "true" 83 | } 84 | } 85 | 86 | // Assign map to object by Tag by iterating fields 87 | typ := reflect.TypeOf(out).Elem() // Should be pointer 88 | val := reflect.ValueOf(out).Elem() 89 | for i := 0; i < typ.NumField(); i++ { 90 | fieldTyp := typ.Field(i) 91 | fieldVal := val.Field(i) 92 | name := strings.ToLower(fieldTyp.Name) 93 | if tag, ok := fieldTyp.Tag.Lookup("opt"); ok { 94 | tagParts := strings.Split(tag, ",") 95 | if len(tagParts) > 0 && tagParts[0] != "" { 96 | name = tagParts[0] 97 | } 98 | } 99 | 100 | if v, ok := mountopts[name]; ok { 101 | err = StringAssign(v, fieldVal.Addr().Interface()) 102 | if err != nil { 103 | return err 104 | } 105 | } 106 | } 107 | return 108 | } 109 | 110 | // StringAssign parseString and place value in 111 | func StringAssign(s string, v interface{}) (err error) { 112 | val := reflect.ValueOf(v).Elem() 113 | switch val.Kind() { 114 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: // More values 115 | parsed, err := strconv.ParseInt(s, 10, 64) 116 | if err != nil { 117 | return err 118 | } 119 | sval := reflect.ValueOf(parsed) 120 | val.Set(sval.Convert(val.Type())) 121 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: // More values 122 | parsed, err := strconv.ParseUint(s, 10, 64) 123 | if err != nil { 124 | return err 125 | } 126 | sval := reflect.ValueOf(parsed) 127 | val.Set(sval.Convert(val.Type())) 128 | case reflect.Bool: 129 | parsed, err := strconv.ParseBool(s) 130 | if err != nil { 131 | return err 132 | } 133 | sval := reflect.ValueOf(parsed) 134 | val.Set(sval) 135 | } 136 | 137 | return 138 | } 139 | 140 | //OptionString helper to print a struct into -o mount like key=value 141 | func OptionString(o interface{}) string { 142 | ret := "" 143 | typ := reflect.TypeOf(o) // Should be pointer 144 | val := reflect.ValueOf(o) 145 | for i := 0; i < typ.NumField(); i++ { 146 | fieldTyp := typ.Field(i) 147 | fieldVal := val.Field(i) 148 | name := strings.ToLower(fieldTyp.Name) 149 | desc := "" 150 | if tag, ok := fieldTyp.Tag.Lookup("opt"); ok { 151 | tagParts := strings.Split(tag, ",") 152 | if len(tagParts) > 0 && tagParts[0] != "" { 153 | name = tagParts[0] 154 | } 155 | /*if len(tagParts) >= 2 { 156 | desc = tagParts[1] 157 | }*/ 158 | } 159 | if i != 0 { 160 | ret += "," 161 | } 162 | if desc != "" { 163 | ret += fmt.Sprintf("%s=%v (%s)", name, fieldVal.Interface(), desc) 164 | } else { 165 | ret += fmt.Sprintf("%s=%v", name, fieldVal.Interface()) 166 | } 167 | } 168 | 169 | return ret 170 | } 171 | 172 | // OptionMap retrieves mount like -o key,value into a map 173 | func OptionMap(o interface{}) map[string]string { 174 | ret := map[string]string{} 175 | typ := reflect.TypeOf(o) // Should be pointer 176 | val := reflect.ValueOf(o) 177 | for i := 0; i < typ.NumField(); i++ { 178 | fieldTyp := typ.Field(i) 179 | fieldVal := val.Field(i) 180 | name := strings.ToLower(fieldTyp.Name) 181 | if tag, ok := fieldTyp.Tag.Lookup("opt"); ok { 182 | tagParts := strings.Split(tag, ",") 183 | if len(tagParts) > 0 && tagParts[0] != "" { 184 | name = tagParts[0] 185 | } 186 | } 187 | ret[name] = fmt.Sprintf("%v", fieldVal.Interface()) 188 | } 189 | return ret 190 | } 191 | -------------------------------------------------------------------------------- /vendor/github.com/jacobsa/fuse/internal/buffer/out_message.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package buffer 16 | 17 | import ( 18 | "fmt" 19 | "log" 20 | "reflect" 21 | "unsafe" 22 | 23 | "github.com/jacobsa/fuse/internal/fusekernel" 24 | ) 25 | 26 | // OutMessageHeaderSize is the size of the leading header in every 27 | // properly-constructed OutMessage. Reset brings the message back to this size. 28 | const OutMessageHeaderSize = int(unsafe.Sizeof(fusekernel.OutHeader{})) 29 | 30 | // OutMessage provides a mechanism for constructing a single contiguous fuse 31 | // message from multiple segments, where the first segment is always a 32 | // fusekernel.OutHeader message. 33 | // 34 | // Must be initialized with Reset. 35 | type OutMessage struct { 36 | // The offset into payload to which we're currently writing. 37 | payloadOffset int 38 | 39 | header fusekernel.OutHeader 40 | payload [MaxReadSize]byte 41 | } 42 | 43 | // Make sure that the header and payload are contiguous. 44 | func init() { 45 | a := unsafe.Offsetof(OutMessage{}.header) + uintptr(OutMessageHeaderSize) 46 | b := unsafe.Offsetof(OutMessage{}.payload) 47 | 48 | if a != b { 49 | log.Panicf( 50 | "header ends at offset %d, but payload starts at offset %d", 51 | a, b) 52 | } 53 | } 54 | 55 | // Reset resets m so that it's ready to be used again. Afterward, the contents 56 | // are solely a zeroed fusekernel.OutHeader struct. 57 | func (m *OutMessage) Reset() { 58 | // Ideally we'd like to write: 59 | // 60 | // m.payloadOffset = 0 61 | // m.header = fusekernel.OutHeader{} 62 | // 63 | // But Go 1.8 beta 2 generates bad code for this 64 | // (https://golang.org/issue/18370). Encourage it to generate the same code 65 | // as Go 1.7.4 did. 66 | //if unsafe.Offsetof(m.payload) != 24 { 67 | // panic("unexpected OutMessage layout") 68 | //} 69 | 70 | //a := (*[3]uint64)(unsafe.Pointer(m)) 71 | //a[0] = 0 72 | //a[1] = 0 73 | //a[2] = 0 74 | 75 | m.payloadOffset = 0 76 | m.header = fusekernel.OutHeader{} 77 | } 78 | 79 | // OutHeader returns a pointer to the header at the start of the message. 80 | func (m *OutMessage) OutHeader() *fusekernel.OutHeader { 81 | return &m.header 82 | } 83 | 84 | // Grow grows m's buffer by the given number of bytes, returning a pointer to 85 | // the start of the new segment, which is guaranteed to be zeroed. If there is 86 | // insufficient space, it returns nil. 87 | func (m *OutMessage) Grow(n int) (p unsafe.Pointer) { 88 | p = m.GrowNoZero(n) 89 | if p != nil { 90 | memclr(p, uintptr(n)) 91 | } 92 | 93 | return 94 | } 95 | 96 | // GrowNoZero is equivalent to Grow, except the new segment is not zeroed. Use 97 | // with caution! 98 | func (m *OutMessage) GrowNoZero(n int) (p unsafe.Pointer) { 99 | // Will we overflow the buffer? 100 | o := m.payloadOffset 101 | if len(m.payload)-o < n { 102 | return 103 | } 104 | 105 | p = unsafe.Pointer(uintptr(unsafe.Pointer(&m.payload)) + uintptr(o)) 106 | m.payloadOffset = o + n 107 | 108 | return 109 | } 110 | 111 | // ShrinkTo shrinks m to the given size. It panics if the size is greater than 112 | // Len() or less than OutMessageHeaderSize. 113 | func (m *OutMessage) ShrinkTo(n int) { 114 | if n < OutMessageHeaderSize || n > m.Len() { 115 | panic(fmt.Sprintf( 116 | "ShrinkTo(%d) out of range (current Len: %d)", 117 | n, 118 | m.Len())) 119 | } 120 | 121 | m.payloadOffset = n - OutMessageHeaderSize 122 | } 123 | 124 | // Append is equivalent to growing by len(src), then copying src over the new 125 | // segment. Int panics if there is not enough room available. 126 | func (m *OutMessage) Append(src []byte) { 127 | p := m.GrowNoZero(len(src)) 128 | if p == nil { 129 | panic(fmt.Sprintf("Can't grow %d bytes", len(src))) 130 | } 131 | 132 | sh := (*reflect.SliceHeader)(unsafe.Pointer(&src)) 133 | memmove(p, unsafe.Pointer(sh.Data), uintptr(sh.Len)) 134 | 135 | return 136 | } 137 | 138 | // AppendString is like Append, but accepts string input. 139 | func (m *OutMessage) AppendString(src string) { 140 | p := m.GrowNoZero(len(src)) 141 | if p == nil { 142 | panic(fmt.Sprintf("Can't grow %d bytes", len(src))) 143 | } 144 | 145 | sh := (*reflect.StringHeader)(unsafe.Pointer(&src)) 146 | memmove(p, unsafe.Pointer(sh.Data), uintptr(sh.Len)) 147 | 148 | return 149 | } 150 | 151 | // Len returns the current size of the message, including the leading header. 152 | func (m *OutMessage) Len() int { 153 | return OutMessageHeaderSize + m.payloadOffset 154 | } 155 | 156 | // Bytes returns a reference to the current contents of the buffer, including 157 | // the leading header. 158 | func (m *OutMessage) Bytes() []byte { 159 | l := m.Len() 160 | sh := reflect.SliceHeader{ 161 | Data: uintptr(unsafe.Pointer(&m.header)), 162 | Len: l, 163 | Cap: l, 164 | } 165 | 166 | return *(*[]byte)(unsafe.Pointer(&sh)) 167 | } 168 | --------------------------------------------------------------------------------