func (sfd *SrcFileDownload) Exec(srcStore fs.BlockStore) os.Error { if err := mkParentDirs(sfd.Path); err != nil { return err } dstFh, err := os.Create(sfd.Path.Resolve()) if dstFh == nil { return err } _, err = srcStore.ReadInto(sfd.SrcFile.Info().Strong, 0, sfd.SrcFile.Info().Size, dstFh) return err }
func NewPatchPlan(srcStore fs.BlockStore, dstStore fs.LocalStore) *PatchPlan { plan := &PatchPlan{srcStore: srcStore, dstStore: dstStore} plan.dstFileUnmatch = make(map[string]fs.File) fs.Walk(dstStore.Repo().Root(), func(dstNode fs.Node) bool { dstFile, isDstFile := dstNode.(fs.File) if isDstFile { plan.dstFileUnmatch[fs.RelPath(dstFile)] = dstFile } return !isDstFile }) relocRefs := make(map[string]int) // Find all the FsNode matches fs.Walk(srcStore.Repo().Root(), func(srcNode fs.Node) bool { // Ignore non-FsNodes srcFsNode, isSrcFsNode := srcNode.(fs.FsNode) if !isSrcFsNode { return false } // log.Printf("In src: %s", fs.RelPath(srcFsNode)) srcFile, isSrcFile := srcNode.(fs.File) srcPath := fs.RelPath(srcFsNode) // Remove this srcPath from dst unmatched, if it was present plan.dstFileUnmatch[srcPath] = nil, false var srcStrong string if isSrcFile { srcStrong = srcFile.Info().Strong } else if srcDir, isSrcDir := srcNode.(fs.Dir); isSrcDir { srcStrong = srcDir.Info().Strong } var dstNode fs.FsNode var hasDstNode bool dstNode, hasDstNode = dstStore.Repo().File(srcStrong) if !hasDstNode { dstNode, hasDstNode = dstStore.Repo().Dir(srcStrong) } isDstFile := false if hasDstNode { _, isDstFile = dstNode.(fs.File) } dstFilePath := dstStore.Resolve(srcPath) dstFileInfo, _ := os.Stat(dstFilePath) // Resolve dst node that matches strong checksum with source if hasDstNode && isSrcFile == isDstFile { dstPath := fs.RelPath(dstNode) relocRefs[dstPath]++ // dstPath will be used in this cmd, inc ref count // log.Printf("srcPath=%s dstPath=%s", srcPath, dstPath) if srcPath != dstPath { // Local dst file needs to be renamed or copied to src path from := &LocalPath{LocalStore: dstStore, RelPath: dstPath} to := &LocalPath{LocalStore: dstStore, RelPath: srcPath} plan.Cmds = append(plan.Cmds, &Transfer{From: from, To: to, relocRefs: relocRefs}) } else { // Same path, keep it where it is plan.Cmds = append(plan.Cmds, &Keep{ Path: &LocalPath{LocalStore: dstStore, RelPath: srcPath}}) } // If its a file, figure out what to do with it } else if isSrcFile { switch { // Destination is not a file, so get rid of whatever is there first case dstFileInfo != nil && !dstFileInfo.IsRegular(): plan.Cmds = append(plan.Cmds, &Conflict{ Path: &LocalPath{LocalStore: dstStore, RelPath: srcPath}, FileInfo: dstFileInfo}) fallthrough // Destination file does not exist, so full source copy needed case dstFileInfo == nil: plan.Cmds = append(plan.Cmds, &SrcFileDownload{ SrcFile: srcFile, Path: &LocalPath{LocalStore: dstStore, RelPath: srcPath}}) break // Destination file exists, add block-level commands default: plan.appendFilePlan(srcFile, srcPath) break } // If its a directory, check for conflicting files of same name } else { if dstFileInfo != nil && !dstFileInfo.IsDirectory() { plan.Cmds = append(plan.Cmds, &Conflict{ Path: &LocalPath{LocalStore: dstStore, RelPath: dstFilePath}, FileInfo: dstFileInfo}) } } return !isSrcFile }) return plan }
func (stc *SrcTempCopy) Exec(srcStore fs.BlockStore) os.Error { stc.Temp.tempFh.Seek(stc.TempOffset, 0) _, err := srcStore.ReadInto(stc.SrcStrong, stc.SrcOffset, stc.Length, stc.Temp.tempFh) return err }