func (adder *Adder) addDir(dir files.File) error { log.Infof("adding directory: %s", dir.FileName()) err := mfs.Mkdir(adder.mr, dir.FileName(), true, false) if err != nil { return err } for { file, err := dir.NextFile() if err != nil && err != io.EOF { return err } if file == nil { break } err = adder.addFile(file) if _, ok := err.(*hiddenFileError); ok { // hidden file error, skip file continue } else if err != nil { return err } } return nil }
func (adder *Adder) addDir(dir files.File) error { log.Infof("adding directory: %s", dir.FileName()) err := mfs.Mkdir(adder.mr, dir.FileName(), true, false) if err != nil { return err } for { file, err := dir.NextFile() if err != nil && err != io.EOF { return err } if file == nil { break } // Skip hidden files when adding recursively, unless Hidden is enabled. if files.IsHidden(file) && !adder.Hidden { log.Infof("%s is hidden, skipping", file.FileName()) continue } err = adder.addFile(file) if err != nil { return err } } return nil }
// Add the given file while respecting the params. func (params *adder) addFile(file files.File) (*dag.Node, error) { // Check if file is hidden if fileIsHidden := files.IsHidden(file); fileIsHidden && !params.hidden { log.Debugf("%s is hidden, skipping", file.FileName()) return nil, &hiddenFileError{file.FileName()} } // Check if "file" is actually a directory if file.IsDirectory() { return params.addDir(file) } // if the progress flag was specified, wrap the file so that we can send // progress updates to the client (over the output channel) var reader io.Reader = file if params.progress { reader = &progressReader{file: file, out: params.out} } dagnode, err := add(params.node, reader, params.trickle) if err != nil { return nil, err } log.Infof("adding file: %s", file.FileName()) if err := outputDagnode(params.out, file.FileName(), dagnode); err != nil { return nil, err } return dagnode, nil }
func (adder *Adder) addFile(file files.File) error { err := adder.maybePauseForGC() if err != nil { return err } if file.IsDirectory() { return adder.addDir(file) } // case for symlink if s, ok := file.(*files.Symlink); ok { sdata, err := unixfs.SymlinkData(s.Target) if err != nil { return err } dagnode := dag.NodeWithData(sdata) _, err = adder.dagService.Add(dagnode) if err != nil { return err } return adder.addNode(dagnode, s.FileName()) } // case for regular file // if the progress flag was specified, wrap the file so that we can send // progress updates to the client (over the output channel) var reader io.Reader = file if adder.Progress { rdr := &progressReader{file: file, out: adder.Out} if fi, ok := file.(files.FileInfo); ok { reader = &progressReader2{rdr, fi} } else { reader = rdr } } dagnode, err := adder.add(reader) if err != nil { return err } // patch it into the root return adder.addNode(dagnode, file.FileName()) }
func addDir(n *core.IpfsNode, dir files.File, out chan interface{}, progress bool, useTrickle bool) (*dag.Node, error) { log.Infof("adding directory: %s", dir.FileName()) tree := &dag.Node{Data: ft.FolderPBData()} for { file, err := dir.NextFile() if err != nil && err != io.EOF { return nil, err } if file == nil { break } node, err := addFile(n, file, out, progress, false, useTrickle) if err != nil { return nil, err } _, name := path.Split(file.FileName()) err = tree.AddNodeLink(name, node) if err != nil { return nil, err } } err := outputDagnode(out, dir.FileName(), tree) if err != nil { return nil, err } k, err := n.DAG.Add(tree) if err != nil { return nil, err } n.Pinning.GetManual().PinWithMode(k, pin.Indirect) return tree, nil }
func addFile(n *core.IpfsNode, file files.File, out chan interface{}, progress bool, wrap bool, useTrickle bool) (*dag.Node, error) { if file.IsDirectory() { return addDir(n, file, out, progress, useTrickle) } // if the progress flag was specified, wrap the file so that we can send // progress updates to the client (over the output channel) var reader io.Reader = file if progress { reader = &progressReader{file: file, out: out} } if wrap { p, dagnode, err := coreunix.AddWrapped(n, reader, path.Base(file.FileName())) if err != nil { return nil, err } out <- &AddedObject{ Hash: p, Name: file.FileName(), } return dagnode, nil } dagnode, err := add(n, reader, useTrickle) if err != nil { return nil, err } log.Infof("adding file: %s", file.FileName()) if err := outputDagnode(out, file.FileName(), dagnode); err != nil { return nil, err } return dagnode, nil }
// Add the given file while respecting the params. func (params *adder) addFile(file files.File) (*dag.Node, error) { // Check if file is hidden if fileIsHidden := files.IsHidden(file); fileIsHidden && !params.hidden { log.Debugf("%s is hidden, skipping", file.FileName()) return nil, &hiddenFileError{file.FileName()} } // Check if "file" is actually a directory if file.IsDirectory() { return params.addDir(file) } if s, ok := file.(*files.Symlink); ok { sdata, err := ft.SymlinkData(s.Target) if err != nil { return nil, err } dagnode := &dag.Node{Data: sdata} _, err = params.node.DAG.Add(dagnode) if err != nil { return nil, err } err = params.addNode(dagnode, s.FileName()) return dagnode, err } // if the progress flag was specified, wrap the file so that we can send // progress updates to the client (over the output channel) var reader io.Reader = file if params.progress { reader = &progressReader{file: file, out: params.out} } dagnode, err := add(params.node, reader, params.trickle, params.chunker) if err != nil { return nil, err } // patch it into the root log.Infof("adding file: %s", file.FileName()) err = params.addNode(dagnode, file.FileName()) return dagnode, err }
func (adder *Adder) addFile(file files.File) error { err := adder.maybePauseForGC() if err != nil { return err } switch { case files.IsHidden(file) && !adder.Hidden: log.Infof("%s is hidden, skipping", file.FileName()) return &hiddenFileError{file.FileName()} case file.IsDirectory(): return adder.addDir(file) } // case for symlink if s, ok := file.(*files.Symlink); ok { sdata, err := unixfs.SymlinkData(s.Target) if err != nil { return err } dagnode := &dag.Node{Data: sdata} _, err = adder.node.DAG.Add(dagnode) if err != nil { return err } return adder.addNode(dagnode, s.FileName()) } // case for regular file // if the progress flag was specified, wrap the file so that we can send // progress updates to the client (over the output channel) var reader io.Reader = file if adder.Progress { reader = &progressReader{file: file, out: adder.out} } dagnode, err := adder.add(reader) if err != nil { return err } // patch it into the root return adder.addNode(dagnode, file.FileName()) }
func (params *adder) addDir(file files.File) (*dag.Node, error) { tree := &dag.Node{Data: ft.FolderPBData()} log.Infof("adding directory: %s", file.FileName()) for { file, err := file.NextFile() if err != nil && err != io.EOF { return nil, err } if file == nil { break } node, err := params.addFile(file) if _, ok := err.(*hiddenFileError); ok { // hidden file error, set the node to nil for below node = nil } else if err != nil { return nil, err } if node != nil { _, name := path.Split(file.FileName()) err = tree.AddNodeLink(name, node) if err != nil { return nil, err } } } err := outputDagnode(params.out, file.FileName(), tree) if err != nil { return nil, err } k, err := params.node.DAG.Add(tree) if err != nil { return nil, err } params.node.Pinning.GetManual().PinWithMode(k, pin.Indirect) return tree, nil }
func (mfr *MultiFileReader) Read(buf []byte) (written int, err error) { mfr.mutex.Lock() defer mfr.mutex.Unlock() // if we are closed and the buffer is flushed, end reading if mfr.closed && mfr.buf.Len() == 0 { return 0, io.EOF } // if the current file isn't set, advance to the next file if mfr.currentFile == nil { var file files.File for file == nil { if len(mfr.files) == 0 { mfr.mpWriter.Close() mfr.closed = true return mfr.buf.Read(buf) } nextfile, err := mfr.files[len(mfr.files)-1].NextFile() if err == io.EOF { mfr.files = mfr.files[:len(mfr.files)-1] continue } else if err != nil { return 0, err } file = nextfile } // handle starting a new file part if !mfr.closed { var contentType string if _, ok := file.(*files.Symlink); ok { contentType = "application/symlink" } else if file.IsDirectory() { mfr.files = append(mfr.files, file) contentType = "application/x-directory" } else { // otherwise, use the file as a reader to read its contents contentType = "application/octet-stream" } mfr.currentFile = file // write the boundary and headers header := make(textproto.MIMEHeader) filename := url.QueryEscape(file.FileName()) header.Set("Content-Disposition", fmt.Sprintf("file; filename=\"%s\"", filename)) header.Set("Content-Type", contentType) _, err := mfr.mpWriter.CreatePart(header) if err != nil { return 0, err } } } // if the buffer has something in it, read from it if mfr.buf.Len() > 0 { return mfr.buf.Read(buf) } // otherwise, read from file data written, err = mfr.currentFile.Read(buf) if err == io.EOF { mfr.currentFile = nil return written, nil } return written, err }