github.com/olivere/camlistore@v0.0.0-20140121221811-1b7ac2da0199/cmd/camput/blobs.go (about) 1 /* 2 Copyright 2011 Google Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package main 18 19 import ( 20 "bytes" 21 "crypto/sha1" 22 "errors" 23 "flag" 24 "fmt" 25 "io" 26 "os" 27 28 "camlistore.org/pkg/blob" 29 "camlistore.org/pkg/client" 30 "camlistore.org/pkg/cmdmain" 31 ) 32 33 type blobCmd struct{} 34 35 func init() { 36 cmdmain.RegisterCommand("blob", func(flags *flag.FlagSet) cmdmain.CommandRunner { 37 return new(blobCmd) 38 }) 39 } 40 41 func (c *blobCmd) Describe() string { 42 return "Upload raw blob(s)." 43 } 44 45 func (c *blobCmd) Usage() { 46 fmt.Fprintf(cmdmain.Stderr, "Usage: camput [globalopts] blob <files>\n camput [globalopts] blob -\n") 47 } 48 49 func (c *blobCmd) Examples() []string { 50 return []string{ 51 "<files> (raw, without any metadata)", 52 "- (read from stdin)", 53 } 54 } 55 56 func (c *blobCmd) RunCommand(args []string) error { 57 if len(args) == 0 { 58 return errors.New("No files given.") 59 } 60 61 up := getUploader() 62 for _, arg := range args { 63 var ( 64 handle *client.UploadHandle 65 err error 66 ) 67 if arg == "-" { 68 handle, err = stdinBlobHandle() 69 } else { 70 handle, err = fileBlobHandle(up, arg) 71 } 72 if err != nil { 73 return err 74 } 75 put, err := up.Upload(handle) 76 handleResult("blob", put, err) 77 continue 78 } 79 return nil 80 } 81 82 func stdinBlobHandle() (uh *client.UploadHandle, err error) { 83 var buf bytes.Buffer 84 size, err := io.Copy(&buf, cmdmain.Stdin) 85 if err != nil { 86 return 87 } 88 // TODO(bradfitz,mpl): limit this buffer size? 89 file := buf.Bytes() 90 h := blob.NewHash() 91 size, err = io.Copy(h, bytes.NewReader(file)) 92 if err != nil { 93 return 94 } 95 return &client.UploadHandle{ 96 BlobRef: blob.RefFromHash(h), 97 Size: size, 98 Contents: io.LimitReader(bytes.NewReader(file), size), 99 }, nil 100 } 101 102 func fileBlobHandle(up *Uploader, path string) (uh *client.UploadHandle, err error) { 103 fi, err := up.stat(path) 104 if err != nil { 105 return 106 } 107 if fi.Mode()&os.ModeType != 0 { 108 return nil, fmt.Errorf("%q is not a regular file", path) 109 } 110 file, err := up.open(path) 111 if err != nil { 112 return 113 } 114 ref, size, err := blobDetails(file) 115 if err != nil { 116 return nil, err 117 } 118 return &client.UploadHandle{ 119 BlobRef: ref, 120 Size: size, 121 Contents: io.LimitReader(file, size), 122 }, nil 123 } 124 125 func blobDetails(contents io.ReadSeeker) (bref blob.Ref, size int64, err error) { 126 s1 := sha1.New() 127 contents.Seek(0, 0) 128 size, err = io.Copy(s1, contents) 129 if err == nil { 130 bref = blob.RefFromHash(s1) 131 } 132 contents.Seek(0, 0) 133 return 134 }