mirror of
https://github.com/safing/portmaster
synced 2025-09-01 18:19:12 +00:00
124 lines
2.1 KiB
Go
124 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
|
|
"github.com/safing/portbase/info"
|
|
"github.com/safing/portmaster/updates"
|
|
)
|
|
|
|
var (
|
|
oldBinSuffix = "-old"
|
|
)
|
|
|
|
func checkForUpgrade() (update *updates.File) {
|
|
info := info.GetInfo()
|
|
file, err := updates.GetLocalPlatformFile("control/portmaster-control")
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
if info.Version != file.Version() {
|
|
return file
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func doSelfUpgrade(file *updates.File) error {
|
|
|
|
// FIXME: fix permissions if needed
|
|
|
|
// get destination
|
|
dst, err := os.Executable()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
dst, err = filepath.EvalSymlinks(dst)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// mv destination
|
|
err = os.Rename(dst, dst+oldBinSuffix)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// hard link
|
|
err = os.Link(file.Path(), dst)
|
|
if err != nil {
|
|
fmt.Printf("%s failed to hardlink self upgrade: %s, will copy...\n", logPrefix, err)
|
|
err = copyFile(file.Path(), dst)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// check permission
|
|
if runtime.GOOS != "windows" {
|
|
info, err := os.Stat(dst)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get file info on %s: %s", dst, err)
|
|
}
|
|
if info.Mode() != 0755 {
|
|
err := os.Chmod(dst, 0755)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to set permissions on %s: %s", dst, err)
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func copyFile(srcPath, dstPath string) (err error) {
|
|
srcFile, err := os.Open(srcPath)
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer srcFile.Close()
|
|
|
|
dstFile, err := os.Create(dstPath)
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer func() {
|
|
closeErr := dstFile.Close()
|
|
if err == nil {
|
|
err = closeErr
|
|
}
|
|
}()
|
|
|
|
_, err = io.Copy(dstFile, srcFile)
|
|
if err != nil {
|
|
return
|
|
}
|
|
err = dstFile.Sync()
|
|
return
|
|
}
|
|
|
|
func removeOldBin() error {
|
|
// get location
|
|
dst, err := os.Executable()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
dst, err = filepath.EvalSymlinks(dst)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// delete old
|
|
err = os.Remove(dst + oldBinSuffix)
|
|
if err != nil {
|
|
if !os.IsNotExist(err) {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
fmt.Println("removed previous portmaster-control")
|
|
return nil
|
|
}
|