func (transfer *Transfer) move(srcStore fs.BlockStore) os.Error { if err := mkParentDirs(transfer.To); err != nil { return err } return fs.Move(transfer.From.Resolve(), transfer.To.Resolve()) }
func (rwt *ReplaceWithTemp) Exec(srcStore fs.BlockStore) (err os.Error) { tempName := rwt.Temp.tempFh.Name() rwt.Temp.localFh.Close() rwt.Temp.localFh = nil rwt.Temp.tempFh.Close() rwt.Temp.tempFh = nil err = os.Remove(rwt.Temp.Path.Resolve()) if err != nil { return err } err = fs.Move(tempName, rwt.Temp.Path.Resolve()) if err != nil { return err } return nil }
func PatchFile(src string, dst string) error { match, err := Match(src, dst) if match == nil { return err } var buf [fs.BLOCKSIZE]byte _, dstname := filepath.Split(dst) newdstF, err := ioutil.TempFile("", dstname) if newdstF == nil { return err } defer newdstF.Close() dstF, err := os.Open(dst) if dstF == nil { return err } defer dstF.Close() // Write blocks from dst that we already have DST_2_NEWDST: for _, blockMatch := range match.BlockMatches { dstF.Seek(blockMatch.DstOffset, 0) newdstF.Seek(blockMatch.DstOffset, 0) switch rd, err := dstF.Read(buf[:]); true { case rd < 0: return err case rd == 0: break DST_2_NEWDST case rd > 0: newdstF.Write(buf[:rd]) } } srcF, err := os.Open(src) if srcF == nil { return err } defer srcF.Close() // Fill in the rest from src SRC_2_NEWDST: for _, notMatch := range match.NotMatched() { srcF.Seek(notMatch.From, 0) newdstF.Seek(notMatch.From, 0) for toRd := notMatch.Size(); toRd > 0; { var rd int switch rd, err := srcF.Read(buf[:]); true { case rd < 0: return err case rd == 0: break SRC_2_NEWDST case rd > 0: newdstF.Write(buf[:rd]) } toRd -= int64(rd) } } newdst := newdstF.Name() newdstF.Close() dstF.Close() os.Remove(dst) err = fs.Move(newdst, dst) return err }