func rebuild_file(c []child, patch_num int, dest string) string { if patch_num == 0 { return "restored/.tmp/" + c[0].Name } err := os.Rename("restored/.tmp/"+c[0].Name, "restored/.tmp/base") if err != nil { log.Fatal(err) } for i := 1; i <= patch_num; i++ { f, err := os.Open("restored/.tmp/base") if err != nil { log.Fatal(err) } m, err := os.OpenFile("restored/.tmp/master", os.O_CREATE|os.O_WRONLY, 0777) if err != nil { log.Fatal(err) } p, err := os.Open("restored/.tmp/" + c[i].Name) if err != nil { log.Fatal(err) } err = binarydist.Patch(f, m, p) if err != nil { log.Fatal(err) } m.Close() f.Close() p.Close() os.Rename("restored/.tmp/master", "restored/.tmp/base") } return "restored/.tmp/base" }
func (u *Updater) fetchAndApplyPatch(old io.Reader) ([]byte, error) { r, err := fetch(u.diffURL + u.cmdName + "/" + Version + "/" + u.info.Version + "/" + plat) if err != nil { return nil, err } defer r.Close() var buf bytes.Buffer err = binarydist.Patch(old, &buf, r) return buf.Bytes(), err }
func applyPatch(patch io.Reader, updatePath string) ([]byte, error) { // open the file to update old, err := os.Open(updatePath) if err != nil { return nil, err } defer old.Close() // apply the patch applied := new(bytes.Buffer) if err = binarydist.Patch(old, applied, patch); err != nil { return nil, err } return applied.Bytes(), nil }
// Update the currently running binary to a specific version func (d *Dist) UpdateTo(to string) (err error) { if d.Version == to { return errors.New("nothing to update") } binary, _ := osext.Executable() reader, err := os.Open(binary) if err != nil { return err } defer reader.Close() url := fmt.Sprintf("%s/projects/%s/diff/%s/%s/%s-%s", d.Host, d.Project, d.Version, to, runtime.GOOS, runtime.GOARCH) patch, err := d.httpGet(url) if err != nil { return err } writer := new(bytes.Buffer) err = binarydist.Patch(reader, writer, bytes.NewReader(patch)) if err != nil { return err } reader.Close() err, _ = update.FromStream(writer) return }
func (u *Updater) fetchAndApply() { instPath, err := exec.LookPath("hk") if err != nil { log.Fatal(err) } old, err := os.Open(instPath) if err != nil { log.Fatal(err) } plat := runtime.GOOS + "-" + runtime.GOARCH resp, err := http.Get(u.url + plat + "/" + Version + "/next.hkdiff") if err != nil { log.Fatal(err) } defer resp.Body.Close() if resp.StatusCode != 200 { log.Fatal(resp.Status) } var header struct { Magic [8]byte OldHash [sha1.Size]byte NewHash [sha1.Size]byte DiffHash [sha1.Size]byte } err = binary.Read(resp.Body, binary.BigEndian, &header) if err != nil { log.Fatal(err) } if header.Magic != magic { log.Fatal("format error in update file") } patch, err := ioutil.ReadAll(resp.Body) if err != nil { log.Fatal(err) } if !sha1matches(header.OldHash, old) { log.Fatal("existing version hash match update") } if !sha1matches(header.DiffHash, bytes.NewReader(patch)) { log.Fatal("bad patch file") } _, err = old.Seek(0, 0) if err != nil { log.Fatal(err) } part := u.dir + upnextPath + ".part" newPart, err := os.OpenFile(part, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777) if err != nil { log.Fatal(err) } err = binarydist.Patch(old, newPart, bytes.NewReader(patch)) if err != nil { log.Fatal(err) } err = newPart.Close() if err != nil { log.Fatal(err) } newPart, err = os.Open(part) if err != nil { log.Fatal(err) } if !sha1matches(header.NewHash, newPart) { log.Fatal("checksum mismatch after patch") } err = os.Rename(part, u.dir+upnextPath) if err != nil { log.Fatal(err) } }
func (u *Updater) fetchAndApply() error { instPath, err := exec.LookPath("hk") if err != nil { return err } old, err := os.Open(instPath) if err != nil { return err } plat := runtime.GOOS + "-" + runtime.GOARCH name := "hk-" + Version + "-next-" + plat + ".hkdiff" resp, err := http.Get(u.url + name) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode != 200 { log.Fatal(resp.Status) } var header struct { Magic [8]byte OldHash [sha1.Size]byte NewHash [sha1.Size]byte DiffHash [sha1.Size]byte } err = binary.Read(resp.Body, binary.BigEndian, &header) if err != nil { return err } if header.Magic != magic { log.Fatal("format error in update file") } patch, err := ioutil.ReadAll(resp.Body) if err != nil { return err } if readSha1(old) != header.OldHash { log.Fatal("old hash mismatch") } if readSha1(bytes.NewReader(patch)) != header.DiffHash { log.Fatal("bad patch file") } _, err = old.Seek(0, 0) if err != nil { return err } var buf bytes.Buffer err = binarydist.Patch(old, &buf, bytes.NewReader(patch)) if err != nil { return err } if readSha1(bytes.NewReader(buf.Bytes())) != header.NewHash { log.Fatal("checksum mismatch after patch") } part := path.Dir(instPath) + "/.hk.part" dstf, err := os.OpenFile(part, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777) if err != nil { return err } defer os.Remove(part) _, err = dstf.Write(buf.Bytes()) if err != nil { return err } err = dstf.Close() if err != nil { return err } return os.Rename(part, instPath) }