func newUploader() *Uploader { cc := client.NewOrFail() if !*flagVerbose { cc.SetLogger(nil) } httpStats := &httputil.StatsTransport{ VerboseLog: *flagHTTP, } cc.SetHTTPClient(&http.Client{Transport: httpStats}) pwd, err := os.Getwd() if err != nil { log.Fatalf("os.Getwd: %v", err) } return &Uploader{ Client: cc, transport: httpStats, pwd: pwd, entityFetcher: &jsonsign.CachingEntityFetcher{ Fetcher: &jsonsign.FileEntityFetcher{File: cc.SecretRingFile()}, }, } }
func newUploader() *Uploader { cc := client.NewOrFail() if !*cmdmain.FlagVerbose { cc.SetLogger(nil) } proxy := http.ProxyFromEnvironment if flagProxyLocal { proxy = proxyFromEnvironment } tr := cc.TransportForConfig( &client.TransportConfig{ Proxy: proxy, Verbose: *flagHTTP, }) httpStats, _ := tr.(*httputil.StatsTransport) cc.SetHTTPClient(&http.Client{Transport: tr}) pwd, err := os.Getwd() if err != nil { log.Fatalf("os.Getwd: %v", err) } return &Uploader{ Client: cc, transport: httpStats, pwd: pwd, } }
// TODO(rh): tame copy/paste code from cammount func main() { client.AddFlags() flag.Parse() cacheDir, err := ioutil.TempDir("", "camlicache") if err != nil { log.Fatalf("Error creating temp cache directory: %v", err) } defer os.RemoveAll(cacheDir) diskcache, err := localdisk.New(cacheDir) if err != nil { log.Fatalf("Error setting up local disk cache: %v", err) } if flag.NArg() != 1 { log.Fatal("usage: camwebdav <blobref>") } br := blobref.Parse(flag.Arg(0)) if br == nil { log.Fatalf("%s was not a valid blobref.", flag.Arg(0)) } client := client.NewOrFail() fetcher := cacher.NewCachingFetcher(diskcache, client) f = fs.NewCamliFileSystem(fetcher, br) http.HandleFunc("/", webdav) err = http.ListenAndServe(*davaddr, nil) if err != nil { log.Fatalf("Error starting WebDAV server: %v", err) } }
func main() { // Scans the arg list and sets up flags debug := flag.Bool("debug", false, "print debugging messages.") client.AddFlags() flag.Parse() errorf := func(msg string, args ...interface{}) { fmt.Fprintf(os.Stderr, msg, args...) os.Exit(2) } if n := flag.NArg(); n < 1 || n > 2 { errorf("usage: cammount <mountpoint> [<root-blobref>]\n") } mountPoint := flag.Arg(0) client := client.NewOrFail() // automatic from flags cacheDir, err := ioutil.TempDir("", "camlicache") if err != nil { errorf("Error creating temp cache directory: %v\n", err) } defer os.RemoveAll(cacheDir) diskcache, err := localdisk.New(cacheDir) if err != nil { errorf("Error setting up local disk cache: %v", err) } fetcher := cacher.NewCachingFetcher(diskcache, client) var camfs *fs.CamliFileSystem if flag.NArg() == 2 { root := blobref.Parse(flag.Arg(1)) if root == nil { errorf("Error parsing root blobref: %q\n", root) } var err error camfs, err = fs.NewRootedCamliFileSystem(fetcher, root) if err != nil { errorf("Error creating root with %v: %v", root, err) } } else { camfs = fs.NewCamliFileSystem(fetcher) log.Printf("starting with fs %#v", camfs) } if *debug { // TODO: set fs's logger } conn, err := fuse.Mount(mountPoint) if err != nil { log.Fatalf("Mount: %v", err) } err = conn.Serve(camfs) if err != nil { log.Fatalf("Serve: %v", err) } log.Printf("fuse process ending.") }
// discoClient returns a client initialized with a server // based from --src or from the configuration file if --src // is blank. The returned client can then be used to discover // the blobRoot and syncHandlers. func discoClient() *client.Client { var cl *client.Client if *flagSrc == "" { cl = client.NewOrFail() } else { cl = client.New(*flagSrc) } cl.SetupAuth() return cl }
// newClient returns a Camlistore client for the server. // The server may be: // * blank, to use the default in the config file // * an alias, to use that named alias in the config file // * host:port // * https?://host[:port][/path] func newClient(server string, opts ...client.ClientOption) *client.Client { if server == "" { return client.NewOrFail(opts...) } cl := client.New(server, opts...) if err := cl.SetupAuth(); err != nil { log.Fatalf("Could not setup auth for connecting to %v: %v", server, err) } return cl }
// discoClient returns a client initialized with a server // based from the configuration file. The returned client // can then be used to discover the blobRoot and syncHandlers. func (c *indexCmd) discoClient() *client.Client { var cl *client.Client cl = client.NewOrFail() cl.InsecureTLS = c.insecureTLS cl.SetHTTPClient(&http.Client{ Transport: cl.TransportForConfig(nil), }) cl.SetupAuth() return cl }
// discoClient returns a client initialized with a server // based from --src or from the configuration file if --src // is blank. The returned client can then be used to discover // the blobRoot and syncHandlers. func (c *syncCmd) discoClient() *client.Client { var cl *client.Client if c.src == "" { cl = client.NewOrFail() } else { cl = client.New(c.src) } cl.SetupAuth() return cl }
func (c *claimsCmd) client() *client.Client { var cl *client.Client if c.src == "" { cl = client.NewOrFail() } else { cl = client.New(c.src) } cl.SetLogger(c.logger) cl.SetHTTPClient(&http.Client{ Transport: cl.TransportForConfig(nil), }) cl.SetupAuth() return cl }
// discoClient returns a client initialized with a server // based from --src or from the configuration file if --src // is blank. The returned client can then be used to discover // the blobRoot and syncHandlers. func (c *syncCmd) discoClient() *client.Client { var cl *client.Client if c.src == "" { cl = client.NewOrFail() } else { cl = client.New(c.src) } cl.SetLogger(c.logger) cl.InsecureTLS = c.insecureTLS cl.SetHTTPClient(&http.Client{ Transport: cl.TransportForConfig(nil), }) cl.SetupAuth() return cl }
// newClient returns a Camlistore client for the server. // The server may be: // * blank, to use the default in the config file // * an alias, to use that named alias in the config file // * host:port // * https?://host[:port][/path] func newClient(server string) *client.Client { var cl *client.Client if server == "" { cl = client.NewOrFail() } else { cl = client.New(server) if err := cl.SetupAuth(); err != nil { log.Fatalf("Could not setup auth for connecting to %v: %v", server, err) } } cl.SetHTTPClient(&http.Client{ Transport: cl.TransportForConfig(nil), }) return cl }
func main() { client.AddFlags() flag.Parse() if len(*flagVia) > 0 { vs := strings.Split(*flagVia, ",") viaRefs = make([]*blobref.BlobRef, len(vs)) for i, sbr := range vs { viaRefs[i] = blobref.Parse(sbr) if viaRefs[i] == nil { log.Fatalf("Invalid -via blobref: %q", sbr) } if *flagVerbose { log.Printf("via: %s", sbr) } } } cl := client.NewOrFail() for n := 0; n < flag.NArg(); n++ { arg := flag.Arg(n) br := blobref.Parse(arg) if br == nil { log.Fatalf("Failed to parse argument %q as a blobref.", arg) } if *flagCheck { // TODO: do HEAD requests checking if the blobs exists. log.Fatal("not implemented") return } if *flagOutput == "-" { rc, err := fetch(cl, br) if err != nil { log.Fatal(err) } defer rc.Close() if _, err := io.Copy(os.Stdout, rc); err != nil { log.Fatalf("Failed reading %q: %v", br, err) } return } if err := smartFetch(cl, *flagOutput, br); err != nil { log.Fatal(err) } } }
func newUploader() *Uploader { cc := client.NewOrFail() if !*cmdmain.FlagVerbose { cc.SetLogger(nil) } var transport http.RoundTripper proxy := http.ProxyFromEnvironment if flagProxyLocal { proxy = proxyFromEnvironment } tlsConfig, err := cc.TLSConfig() if err != nil { log.Fatalf("Error while configuring TLS for client: %v", err) } transport = &http.Transport{ Dial: cc.DialFunc(), TLSClientConfig: tlsConfig, Proxy: proxy, } httpStats := &httputil.StatsTransport{ VerboseLog: *flagHTTP, Transport: transport, } transport = httpStats if client.AndroidOutput() { transport = client.AndroidStatsTransport{transport} } cc.SetHTTPClient(&http.Client{Transport: transport}) pwd, err := os.Getwd() if err != nil { log.Fatalf("os.Getwd: %v", err) } return &Uploader{ Client: cc, transport: httpStats, pwd: pwd, entityFetcher: &jsonsign.CachingEntityFetcher{ Fetcher: &jsonsign.FileEntityFetcher{File: cc.SecretRingFile()}, }, } }
func newUploader() *Uploader { var cc *client.Client var httpStats *httputil.StatsTransport if d := *flagBlobDir; d != "" { ss, err := dir.New(d) if err != nil && d == "discard" { ss = discardStorage{} err = nil } if err != nil { log.Fatalf("Error using dir %s as storage: %v", d, err) } cc = client.NewStorageClient(ss) } else { cc = client.NewOrFail() proxy := http.ProxyFromEnvironment if flagProxyLocal { proxy = proxyFromEnvironment } tr := cc.TransportForConfig( &client.TransportConfig{ Proxy: proxy, Verbose: *flagHTTP, }) httpStats, _ = tr.(*httputil.StatsTransport) cc.SetHTTPClient(&http.Client{Transport: tr}) } if *cmdmain.FlagVerbose { cc.SetLogger(log.New(cmdmain.Stderr, "", log.LstdFlags)) } else { cc.SetLogger(nil) } pwd, err := os.Getwd() if err != nil { log.Fatalf("os.Getwd: %v", err) } return &Uploader{ Client: cc, transport: httpStats, pwd: pwd, fdGate: syncutil.NewGate(100), // gate things that waste fds, assuming a low system limit } }
func newUploader() *Uploader { cc := client.NewOrFail() if !*flagVerbose { cc.SetLogger(nil) } transport := new(tinkerTransport) transport.transport = &http.Transport{DisableKeepAlives: false} cc.SetHttpClient(&http.Client{Transport: transport}) pwd, err := os.Getwd() if err != nil { log.Fatalf("os.Getwd: %v", err) } return &Uploader{ Client: cc, transport: transport, pwd: pwd, entityFetcher: &jsonsign.CachingEntityFetcher{ Fetcher: &jsonsign.FileEntityFetcher{File: cc.SecretRingFile()}, }, } }
func main() { // Scans the arg list and sets up flags debug := flag.Bool("debug", false, "print debugging messages.") client.AddFlags() flag.Parse() errorf := func(msg string, args ...interface{}) { fmt.Fprintf(os.Stderr, msg, args...) fmt.Fprint(os.Stderr, "\n") usage() } nargs := flag.NArg() if nargs < 1 || nargs > 2 { usage() } mountPoint := flag.Arg(0) var ( cl *client.Client root *blobref.BlobRef // nil if only one arg camfs *fs.CamliFileSystem ) if nargs == 2 { rootArg := flag.Arg(1) // not trying very hard since NewFromShareRoot will do it better with a regex if strings.HasPrefix(rootArg, "http://") || strings.HasPrefix(rootArg, "https://") { if client.ExplicitServer() != "" { errorf("Can't use an explicit blobserver with a share URL; the blobserver is implicit from the share URL.") } var err error cl, root, err = client.NewFromShareRoot(rootArg) if err != nil { log.Fatal(err) } } else { cl = client.NewOrFail() // automatic from flags root = blobref.Parse(rootArg) if root == nil { log.Fatalf("Error parsing root blobref: %q\n", rootArg) } cl.SetHTTPClient(&http.Client{Transport: cl.TransportForConfig(nil)}) } } else { cl = client.NewOrFail() // automatic from flags cl.SetHTTPClient(&http.Client{Transport: cl.TransportForConfig(nil)}) } diskCacheFetcher, err := cacher.NewDiskCache(cl) if err != nil { log.Fatalf("Error setting up local disk cache: %v", err) } defer diskCacheFetcher.Clean() if root != nil { var err error camfs, err = fs.NewRootedCamliFileSystem(diskCacheFetcher, root) if err != nil { log.Fatalf("Error creating root with %v: %v", root, err) } } else { camfs = fs.NewCamliFileSystem(cl, diskCacheFetcher) log.Printf("starting with fs %#v", camfs) } if *debug { // TODO: set fs's logger } // This doesn't appear to work on OS X: sigc := make(chan os.Signal, 1) go func() { log.Fatalf("Signal %s received, shutting down.", <-sigc) }() signal.Notify(sigc, syscall.SIGQUIT, syscall.SIGTERM) conn, err := fuse.Mount(mountPoint) if err != nil { log.Fatalf("Mount: %v", err) } err = conn.Serve(camfs) if err != nil { log.Fatalf("Serve: %v", err) } log.Printf("fuse process ending.") }
func main() { client.AddFlags() flag.Parse() if *flagVersion { fmt.Fprintf(os.Stderr, "camget version: %s\n", buildinfo.Version()) return } if *flagGraph && flag.NArg() != 1 { log.Fatalf("The --graph option requires exactly one parameter.") } var cl *client.Client var items []*blobref.BlobRef if *flagShared != "" { if client.ExplicitServer() != "" { log.Fatal("Can't use --shared with an explicit blobserver; blobserver is implicit from the --shared URL.") } if flag.NArg() != 0 { log.Fatal("No arguments permitted when using --shared") } cl1, target, err := client.NewFromShareRoot(*flagShared, client.OptionInsecure(*flagInsecureTLS)) if err != nil { log.Fatal(err) } cl = cl1 items = append(items, target) } else { cl = client.NewOrFail() for n := 0; n < flag.NArg(); n++ { arg := flag.Arg(n) br := blobref.Parse(arg) if br == nil { log.Fatalf("Failed to parse argument %q as a blobref.", arg) } items = append(items, br) } } cl.InsecureTLS = *flagInsecureTLS tr := cl.TransportForConfig(&client.TransportConfig{ Verbose: *flagHTTP, }) httpStats, _ := tr.(*httputil.StatsTransport) cl.SetHTTPClient(&http.Client{Transport: tr}) diskCacheFetcher, err := cacher.NewDiskCache(cl) if err != nil { log.Fatalf("Error setting up local disk cache: %v", err) } defer diskCacheFetcher.Clean() if *flagVerbose { log.Printf("Using temp blob cache directory %s", diskCacheFetcher.Root) } for _, br := range items { if *flagGraph { printGraph(diskCacheFetcher, br) return } if *flagCheck { // TODO: do HEAD requests checking if the blobs exists. log.Fatal("not implemented") return } if *flagOutput == "-" { var rc io.ReadCloser var err error if *flagContents { rc, err = schema.NewFileReader(diskCacheFetcher, br) if err == nil { rc.(*schema.FileReader).LoadAllChunks() } } else { rc, err = fetch(diskCacheFetcher, br) } if err != nil { log.Fatal(err) } defer rc.Close() if _, err := io.Copy(os.Stdout, rc); err != nil { log.Fatalf("Failed reading %q: %v", br, err) } } else { if err := smartFetch(diskCacheFetcher, *flagOutput, br); err != nil { log.Fatal(err) } } } if *flagVerbose { log.Printf("HTTP requests: %d\n", httpStats.Requests()) } }
func main() { client.AddFlags() flag.Parse() if *cmdmain.FlagHelp { flag.PrintDefaults() } if *flagVersion { fmt.Fprintf(os.Stderr, "camget version: %s\n", buildinfo.Version()) return } if *cmdmain.FlagLegal { cmdmain.PrintLicenses() return } if *flagGraph && flag.NArg() != 1 { log.Fatalf("The --graph option requires exactly one parameter.") } var cl *client.Client var items []blob.Ref optTransportConfig := client.OptionTransportConfig(&client.TransportConfig{ Verbose: *flagHTTP, }) if *flagShared != "" { if client.ExplicitServer() != "" { log.Fatal("Can't use --shared with an explicit blobserver; blobserver is implicit from the --shared URL.") } if flag.NArg() != 0 { log.Fatal("No arguments permitted when using --shared") } cl1, target, err := client.NewFromShareRoot(*flagShared, client.OptionInsecure(*flagInsecureTLS), client.OptionTrustedCert(*flagTrustedCert), optTransportConfig, ) if err != nil { log.Fatal(err) } cl = cl1 items = append(items, target) } else { if *flagTrustedCert != "" { log.Fatal("Can't use --cert without --shared.") } cl = client.NewOrFail(client.OptionInsecure(*flagInsecureTLS), optTransportConfig) for n := 0; n < flag.NArg(); n++ { arg := flag.Arg(n) br, ok := blob.Parse(arg) if !ok { log.Fatalf("Failed to parse argument %q as a blobref.", arg) } items = append(items, br) } } httpStats := cl.HTTPStats() diskCacheFetcher, err := cacher.NewDiskCache(cl) if err != nil { log.Fatalf("Error setting up local disk cache: %v", err) } defer diskCacheFetcher.Clean() if *flagVerbose { log.Printf("Using temp blob cache directory %s", diskCacheFetcher.Root) } if *flagShared != "" { diskCacheFetcher.SetCacheHitHook(func(br blob.Ref, rc io.ReadCloser) (io.ReadCloser, error) { var buf bytes.Buffer if err := cl.UpdateShareChain(br, io.TeeReader(rc, &buf)); err != nil { rc.Close() return nil, err } return struct { io.Reader io.Closer }{io.MultiReader(&buf, rc), rc}, nil }) } for _, br := range items { if *flagGraph { printGraph(diskCacheFetcher, br) return } if *flagCheck { // TODO: do HEAD requests checking if the blobs exists. log.Fatal("not implemented") return } if *flagOutput == "-" { var rc io.ReadCloser var err error if *flagContents { rc, err = schema.NewFileReader(diskCacheFetcher, br) if err == nil { rc.(*schema.FileReader).LoadAllChunks() } } else { rc, err = fetch(diskCacheFetcher, br) } if err != nil { log.Fatal(err) } defer rc.Close() if _, err := io.Copy(os.Stdout, rc); err != nil { log.Fatalf("Failed reading %q: %v", br, err) } } else { if err := smartFetch(diskCacheFetcher, *flagOutput, br); err != nil { log.Fatal(err) } } } if *flagVerbose { log.Printf("HTTP requests: %d\n", httpStats.Requests()) h1, h2 := httpStats.ProtoVersions() log.Printf(" responses: %d (h1), %d (h2)\n", h1, h2) } }
func main() { var conn *fuse.Conn // Scans the arg list and sets up flags client.AddFlags() flag.Usage = usage flag.Parse() if *cmdmain.FlagLegal { cmdmain.PrintLicenses() return } if *cmdmain.FlagHelp { usage() } narg := flag.NArg() if narg > 2 { usage() } var mountPoint string var err error if narg > 0 { mountPoint = flag.Arg(0) } else { mountPoint, err = ioutil.TempDir("", "cammount") if err != nil { log.Fatal(err) } log.Printf("No mount point given. Using: %s", mountPoint) defer os.Remove(mountPoint) } errorf := func(msg string, args ...interface{}) { fmt.Fprintf(os.Stderr, msg, args...) fmt.Fprint(os.Stderr, "\n") usage() } var ( cl *client.Client root blob.Ref // nil if only one arg camfs *fs.CamliFileSystem ) if narg == 2 { rootArg := flag.Arg(1) // not trying very hard since NewFromShareRoot will do it better with a regex if strings.HasPrefix(rootArg, "http://") || strings.HasPrefix(rootArg, "https://") { if client.ExplicitServer() != "" { errorf("Can't use an explicit blobserver with a share URL; the blobserver is implicit from the share URL.") } var err error cl, root, err = client.NewFromShareRoot(rootArg) if err != nil { log.Fatal(err) } } else { cl = client.NewOrFail() // automatic from flags var ok bool root, ok = blob.Parse(rootArg) if !ok { // not a blobref, check for root name instead req := &search.WithAttrRequest{N: 1, Attr: "camliRoot", Value: rootArg} wres, err := cl.GetPermanodesWithAttr(req) if err != nil { log.Fatal("could not query search") } if wres.WithAttr != nil { root = wres.WithAttr[0].Permanode } else { log.Fatalf("root specified is not a blobref or name of a root: %q\n", rootArg) } } } } else { cl = client.NewOrFail() // automatic from flags } diskCacheFetcher, err := cacher.NewDiskCache(cl) if err != nil { log.Fatalf("Error setting up local disk cache: %v", err) } defer diskCacheFetcher.Clean() if root.Valid() { var err error camfs, err = fs.NewRootedCamliFileSystem(cl, diskCacheFetcher, root) if err != nil { log.Fatalf("Error creating root with %v: %v", root, err) } } else { camfs = fs.NewDefaultCamliFileSystem(cl, diskCacheFetcher) } if *debug { fuse.Debug = func(msg interface{}) { log.Print(msg) } // TODO: set fs's logger } // This doesn't appear to work on OS X: sigc := make(chan os.Signal, 1) conn, err = fuse.Mount(mountPoint, fuse.VolumeName(filepath.Base(mountPoint))) if err != nil { if err == fuse.ErrOSXFUSENotFound { log.Fatal("FUSE not available; install from http://osxfuse.github.io/") } log.Fatalf("Mount: %v", err) } xtermDone := make(chan bool, 1) if *xterm { cmd := exec.Command("xterm") cmd.Dir = mountPoint if err := cmd.Start(); err != nil { log.Printf("Error starting xterm: %v", err) } else { go func() { cmd.Wait() xtermDone <- true }() defer cmd.Process.Kill() } } if *open { if runtime.GOOS == "darwin" { go exec.Command("open", mountPoint).Run() } } if *term { if runtime.GOOS == "darwin" { if osutil.DirExists("/Applications/iTerm.app/") { go exec.Command("open", "-a", "iTerm", mountPoint).Run() } else { log.Printf("TODO: iTerm not installed. Figure out how to open with Terminal.app instead.") } } } signal.Notify(sigc, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT) doneServe := make(chan error, 1) go func() { doneServe <- fusefs.Serve(conn, camfs) }() quitKey := make(chan bool, 1) go awaitQuitKey(quitKey) select { case err := <-doneServe: log.Printf("conn.Serve returned %v", err) // check if the mount process has an error to report <-conn.Ready if err := conn.MountError; err != nil { log.Printf("conn.MountError: %v", err) } case sig := <-sigc: log.Printf("Signal %s received, shutting down.", sig) case <-quitKey: log.Printf("Quit key pressed. Shutting down.") case <-xtermDone: log.Printf("xterm done") } time.AfterFunc(2*time.Second, func() { os.Exit(1) }) log.Printf("Unmounting...") err = fs.Unmount(mountPoint) log.Printf("Unmount = %v", err) log.Printf("cammount FUSE process ending.") }
func main() { // Scans the arg list and sets up flags debug := flag.Bool("debug", false, "print debugging messages.") client.AddFlags() flag.Parse() errorf := func(msg string, args ...interface{}) { fmt.Fprintf(os.Stderr, msg, args...) os.Exit(2) } if n := flag.NArg(); n < 1 || n > 2 { errorf("usage: cammount <mountpoint> [<root-blobref>]\n") } mountPoint := flag.Arg(0) client := client.NewOrFail() // automatic from flags diskCacheFetcher, err := cacher.NewDiskCache(client) if err != nil { errorf("Error setting up local disk cache: %v", err) } defer diskCacheFetcher.Clean() var camfs *fs.CamliFileSystem if flag.NArg() == 2 { root := blobref.Parse(flag.Arg(1)) if root == nil { errorf("Error parsing root blobref: %q\n", root) } var err error camfs, err = fs.NewRootedCamliFileSystem(diskCacheFetcher, root) if err != nil { errorf("Error creating root with %v: %v", root, err) } } else { camfs = fs.NewCamliFileSystem(client, diskCacheFetcher) log.Printf("starting with fs %#v", camfs) } if *debug { // TODO: set fs's logger } // This doesn't appear to work on OS X: sigc := make(chan os.Signal, 1) go func() { log.Fatalf("Signal %s received, shutting down.", <-sigc) }() signal.Notify(sigc, syscall.SIGQUIT, syscall.SIGTERM) conn, err := fuse.Mount(mountPoint) if err != nil { log.Fatalf("Mount: %v", err) } err = conn.Serve(camfs) if err != nil { log.Fatalf("Serve: %v", err) } log.Printf("fuse process ending.") }
func main() { var conn *fuse.Conn // Scans the arg list and sets up flags client.AddFlags() flag.Parse() narg := flag.NArg() if narg > 2 { usage() } var mountPoint string var err error if narg > 0 { mountPoint = flag.Arg(0) } else { mountPoint, err = ioutil.TempDir("", "cammount") if err != nil { log.Fatal(err) } defer os.Remove(mountPoint) } errorf := func(msg string, args ...interface{}) { fmt.Fprintf(os.Stderr, msg, args...) fmt.Fprint(os.Stderr, "\n") usage() } var ( cl *client.Client root blob.Ref // nil if only one arg camfs *fs.CamliFileSystem ) if narg == 2 { rootArg := flag.Arg(1) // not trying very hard since NewFromShareRoot will do it better with a regex if strings.HasPrefix(rootArg, "http://") || strings.HasPrefix(rootArg, "https://") { if client.ExplicitServer() != "" { errorf("Can't use an explicit blobserver with a share URL; the blobserver is implicit from the share URL.") } var err error cl, root, err = client.NewFromShareRoot(rootArg) if err != nil { log.Fatal(err) } } else { cl = client.NewOrFail() // automatic from flags var ok bool root, ok = blob.Parse(rootArg) if !ok { log.Fatalf("Error parsing root blobref: %q\n", rootArg) } cl.SetHTTPClient(&http.Client{Transport: cl.TransportForConfig(nil)}) } } else { cl = client.NewOrFail() // automatic from flags cl.SetHTTPClient(&http.Client{Transport: cl.TransportForConfig(nil)}) } diskCacheFetcher, err := cacher.NewDiskCache(cl) if err != nil { log.Fatalf("Error setting up local disk cache: %v", err) } defer diskCacheFetcher.Clean() if root.Valid() { var err error camfs, err = fs.NewRootedCamliFileSystem(diskCacheFetcher, root) if err != nil { log.Fatalf("Error creating root with %v: %v", root, err) } } else { camfs = fs.NewCamliFileSystem(cl, diskCacheFetcher) } if *debug { fuse.Debugf = log.Printf // TODO: set fs's logger } // This doesn't appear to work on OS X: sigc := make(chan os.Signal, 1) conn, err = fuse.Mount(mountPoint) if err != nil { if err.Error() == "cannot find load_fusefs" && runtime.GOOS == "darwin" { log.Fatal("FUSE not available; install from http://osxfuse.github.io/") } log.Fatalf("Mount: %v", err) } xtermDone := make(chan bool, 1) if *xterm { cmd := exec.Command("xterm") cmd.Dir = mountPoint if err := cmd.Start(); err != nil { log.Printf("Error starting xterm: %v", err) } else { go func() { cmd.Wait() xtermDone <- true }() defer cmd.Process.Kill() } } if *open { if runtime.GOOS == "darwin" { cmd := exec.Command("open", mountPoint) go cmd.Run() } } signal.Notify(sigc, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT) doneServe := make(chan error, 1) go func() { doneServe <- conn.Serve(camfs) }() quitKey := make(chan bool, 1) go awaitQuitKey(quitKey) select { case err := <-doneServe: log.Printf("conn.Serve returned %v", err) case sig := <-sigc: log.Printf("Signal %s received, shutting down.", sig) case <-quitKey: log.Printf("Quit key pressed. Shutting down.") case <-xtermDone: log.Printf("xterm done") } time.AfterFunc(2*time.Second, func() { os.Exit(1) }) log.Printf("Unmounting...") err = fs.Unmount(mountPoint) log.Printf("Unmount = %v", err) log.Printf("cammount FUSE process ending.") }
func main() { client.AddFlags() flag.Parse() if len(*flagVia) > 0 { vs := strings.Split(*flagVia, ",") viaRefs = make([]*blobref.BlobRef, len(vs)) for i, sbr := range vs { viaRefs[i] = blobref.Parse(sbr) if viaRefs[i] == nil { log.Fatalf("Invalid -via blobref: %q", sbr) } if *flagVerbose { log.Printf("via: %s", sbr) } } } if *flagGraph && flag.NArg() != 1 { log.Fatalf("The --graph option requires exactly one parameter.") } cl := client.NewOrFail() for n := 0; n < flag.NArg(); n++ { arg := flag.Arg(n) br := blobref.Parse(arg) if br == nil { log.Fatalf("Failed to parse argument %q as a blobref.", arg) } if *flagGraph { printGraph(cl, br) return } if *flagCheck { // TODO: do HEAD requests checking if the blobs exists. log.Fatal("not implemented") return } if *flagOutput == "-" { var rc io.ReadCloser var err error if *flagContents { seekFetcher := blobref.SeekerFromStreamingFetcher(cl) rc, err = schema.NewFileReader(seekFetcher, br) } else { rc, err = fetch(cl, br) } if err != nil { log.Fatal(err) } defer rc.Close() if _, err := io.Copy(os.Stdout, rc); err != nil { log.Fatalf("Failed reading %q: %v", br, err) } return } if err := smartFetch(cl, *flagOutput, br); err != nil { log.Fatal(err) } } }
"log" "os" "path/filepath" "sync" "time" "camlistore.org/pkg/client" "camlistore.org/pkg/schema" "camlistore.org/pkg/syncutil" "github.com/dustin/go-couch" "strings" ) var srcPath = flag.String("path", "", "Source of files on local filesystem") var camliClient = client.NewOrFail() type dateOnly time.Time func (d *dateOnly) UnmarshalJSON(in []byte) error { t, err := time.Parse("2006-01-02", string(in[1:len(in)-1])) if err == nil { *d = dateOnly(t) } return err } type photo struct { Id string `json:"_id"` Type string Extension string
func main() { client.AddFlags() flag.Parse() if *flagGraph && flag.NArg() != 1 { log.Fatalf("The --graph option requires exactly one parameter.") } var cl *client.Client var items []*blobref.BlobRef if *flagShared != "" { if client.ExplicitServer() != "" { log.Fatal("Can't use --shared with an explicit blobserver; blobserver is implicit from the --shared URL.") } if flag.NArg() != 0 { log.Fatal("No arguments permitted when using --shared") } cl1, target, err := client.NewFromShareRoot(*flagShared) if err != nil { log.Fatal(err) } cl = cl1 items = append(items, target) } else { cl = client.NewOrFail() for n := 0; n < flag.NArg(); n++ { arg := flag.Arg(n) br := blobref.Parse(arg) if br == nil { log.Fatalf("Failed to parse argument %q as a blobref.", arg) } items = append(items, br) } } httpStats := &httputil.StatsTransport{ VerboseLog: *flagHTTP, } if *flagHTTP { httpStats.Transport = &http.Transport{ Dial: func(net_, addr string) (net.Conn, error) { log.Printf("Dialing %s", addr) return net.Dial(net_, addr) }, } } cl.SetHTTPClient(&http.Client{Transport: httpStats}) // Put a local disk cache in front of the HTTP client. // TODO: this could be better about proactively cleaning things. // Fetching 2 TB shouldn't write 2 TB to /tmp before it's done. // Maybe the cache needs an LRU/size cap. cacheDir, err := ioutil.TempDir("", "camlicache") if err != nil { log.Fatalf("Error creating temp cache directory: %v\n", err) } defer os.RemoveAll(cacheDir) diskcache, err := localdisk.New(cacheDir) if err != nil { log.Fatalf("Error setting up local disk cache: %v", err) } if *flagVerbose { log.Printf("Using temp blob cache directory %s", cacheDir) } fetcher := cacher.NewCachingFetcher(diskcache, cl) for _, br := range items { if *flagGraph { printGraph(fetcher, br) return } if *flagCheck { // TODO: do HEAD requests checking if the blobs exists. log.Fatal("not implemented") return } if *flagOutput == "-" { var rc io.ReadCloser var err error if *flagContents { seekFetcher := blobref.SeekerFromStreamingFetcher(fetcher) rc, err = schema.NewFileReader(seekFetcher, br) if err == nil { rc.(*schema.FileReader).LoadAllChunks() } } else { rc, err = fetch(fetcher, br) } if err != nil { log.Fatal(err) } defer rc.Close() if _, err := io.Copy(os.Stdout, rc); err != nil { log.Fatalf("Failed reading %q: %v", br, err) } } else { if err := smartFetch(fetcher, *flagOutput, br); err != nil { log.Fatal(err) } } } if *flagVerbose { log.Printf("HTTP requests: %d\n", httpStats.Requests()) } }