Skip to content

Commit

Permalink
fix cross device rename issue
Browse files Browse the repository at this point in the history
  • Loading branch information
zyxkad committed Mar 3, 2024
1 parent 187989d commit d06fd01
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 14 deletions.
9 changes: 5 additions & 4 deletions forge_installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,18 @@ func (r *ForgeInstaller) InstallWithLoader(path, name string, target string, loa

if lessV1_17 { // < 1.17 use forge-<minecraft_version>-<loader_version>.jar
installed = filepath.Join(path, name+".jar")
if err = renameIfNotExist("forge-"+version+".jar", installed); err != nil {
if err = renameIfNotExist("forge-"+version+".jar", installed, 0644); err != nil {
return
}
return
}
// >= 1.17 use run.sh or run.bat
installedSh := filepath.Join(path, name+".sh")
if err = renameIfNotExist("run.sh", installedSh); err != nil {
if err = renameIfNotExist("run.sh", installedSh, 0744); err != nil {
return
}
installedBat := filepath.Join(path, name+".bat")
if err = renameIfNotExist("run.bat", installedBat); err != nil {
if err = renameIfNotExist("run.bat", installedBat, 0744); err != nil {
return
}
installed = installedSh
Expand Down Expand Up @@ -142,8 +142,9 @@ func (r *ForgeInstaller) GetLatestInstaller(target string) (version string, err
if err != nil {
return
}
tgName := target + "-"
for _, v := range data.Versioning.Versions {
if strings.HasPrefix(v, target+"-") {
if strings.HasPrefix(v, tgName) {
version = v
break
}
Expand Down
4 changes: 2 additions & 2 deletions httpclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func (c *HTTPClient) NewRequest(method string, url string, body io.Reader) (req
}

func (c *HTTPClient) Do(req *http.Request) (res *http.Response, err error) {
if _, ok := req.Header["User-Agent"]; !ok {
if ua := req.Header.Get("User-Agent"); ua == "" {
req.Header.Set("User-Agent", c.UserAgent)
}
if res, err = c.Client.Do(req); err != nil {
Expand Down Expand Up @@ -165,7 +165,7 @@ func (c *HTTPClient) DownloadTmp(url string, pattern string, mode os.FileMode, h
func (c *HTTPClient) Download(url string, path string, mode os.FileMode, hashes StringMap, size int64, cb DlCallback) (err error) {
var tmppath string
tmppath, err = c.DownloadTmp(url, path+".*.downloading", mode, hashes, size, cb)
if err = renameIfNotExist(tmppath, path); err != nil {
if err = renameIfNotExist(tmppath, path, 0644); err != nil {
return
}
return
Expand Down
4 changes: 2 additions & 2 deletions quilt_installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func (r *QuiltInstaller) InstallWithLoader(path, name string, target string, loa

// --download-server flag will install vanilla server to server.jar, we need rename it
if name == "server" { // name collision
if err = renameIfNotExist("server.jar", "vanilla_server.jar"); err != nil {
if err = renameIfNotExist("server.jar", "vanilla_server.jar", 0644); err != nil {
return
}
var fd *os.File
Expand All @@ -95,7 +95,7 @@ func (r *QuiltInstaller) InstallWithLoader(path, name string, target string, loa
}
// Quilt use quilt-server-launch.jar, for some reason, the --create-scripts flag won't work
installed = filepath.Join(path, name+".jar")
if err = renameIfNotExist("quilt-server-launch.jar", installed); err != nil {
if err = renameIfNotExist("quilt-server-launch.jar", installed, 0644); err != nil {
return
}
return
Expand Down
16 changes: 16 additions & 0 deletions rename_notwindows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//go:build !windows

package installer

import (
"errors"
"syscall"
)

func crossDevice(err error) bool {
var sysErr syscall.Errno
if errors.As(err, &sysErr) {
return err == syscall.EXDEV
}
return false
}
16 changes: 16 additions & 0 deletions rename_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//go:build windows

package installer

import (
"errors"
"syscall"
)

func crossDevice(err error) bool {
var sysErr syscall.Errno
if errors.As(err, &sysErr) {
return err == syscall.EXDEV || err == syscall.ERROR_NOT_SAME_DEVICE

Check failure on line 13 in rename_windows.go

View workflow job for this annotation

GitHub Actions / release

undefined: syscall.ERROR_NOT_SAME_DEVICE

Check failure on line 13 in rename_windows.go

View workflow job for this annotation

GitHub Actions / release

undefined: syscall.ERROR_NOT_SAME_DEVICE

Check failure on line 13 in rename_windows.go

View workflow job for this annotation

GitHub Actions / release

undefined: syscall.ERROR_NOT_SAME_DEVICE

Check failure on line 13 in rename_windows.go

View workflow job for this annotation

GitHub Actions / release

undefined: syscall.ERROR_NOT_SAME_DEVICE
}
return false
}
5 changes: 3 additions & 2 deletions spigot_installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,10 @@ func (*SpigotInstaller) Install(path, name string, target string) (installed str
foundVersion += "(" + target + ")"
}

buildDir := filepath.Join(os.TempDir(), "server-installer-" + PkgVersion + ".bukkit-build-tools.tmp")
buildDir := filepath.Join(os.TempDir(), "server-installer-"+PkgVersion+".bukkit-build-tools.tmp")
loger.Infof("Getting %q...", SpigotBuildToolsURI)
buildToolJar := filepath.Join(buildDir, "BuildTools.jar")
// TODO: use cached BuildTools.Jar if possible
if err = DefaultHTTPClient.Download(SpigotBuildToolsURI, buildToolJar, 0644, nil, -1,
downloadingCallback(SpigotBuildToolsURI)); err != nil {
return
Expand All @@ -67,7 +68,7 @@ func (*SpigotInstaller) Install(path, name string, target string) (installed str
return
}
installed = filepath.Join(path, name+".jar")
if err = renameIfNotExist(filepath.Join(buildDir, "spigot-"+target+".jar"), installed); err != nil {
if err = renameIfNotExist(filepath.Join(buildDir, "spigot-"+target+".jar"), installed, 0644); err != nil {
return
}
return
Expand Down
37 changes: 33 additions & 4 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,28 @@ var EmptyLinkArrayErr = errors.New("Link array is empty")

type StringMap = map[string]string

func renameIfNotExist(src, dst string) (err error) {
func osCopy(src, dst string, mode os.FileMode) (err error) {
srcFd, err := os.Open(src)
if err != nil {
return
}
defer srcFd.Close()
dstFd, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, mode)
if err != nil {
return
}
_, err = io.Copy(dstFd, srcFd)
if er := dstFd.Close(); err == nil && er != nil {
err = er
}
if err != nil {
os.Remove(dst)
return
}
return
}

func renameIfNotExist(src, dst string, mode os.FileMode) (err error) {
if _, e := os.Stat(dst); os.IsNotExist(e) {
if err = os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
return
Expand All @@ -35,8 +56,16 @@ func renameIfNotExist(src, dst string) (err error) {
}
}
if err = os.Rename(src, dst); err != nil {
if crossDevice(err) {
if err = osCopy(src, dst, mode); err != nil {
return
}
os.Remove(src)
return
}
return
}
os.Chmod(dst, mode)
return
}

Expand All @@ -51,7 +80,7 @@ func safeDownload(reader io.Reader, path string) (err error) {
if err != nil {
return
}
if err = renameIfNotExist(fd.Name(), path); err != nil {
if err = renameIfNotExist(fd.Name(), path, 0644); err != nil {
return
}
return nil
Expand Down Expand Up @@ -131,12 +160,12 @@ func downloadAnyAndCheckHashes(links []string, path string, hashes StringMap, si
}
for _, l := range links {
var tmp string
if tmp, err = DefaultHTTPClient.DownloadTmp(l, "downloading_", 0644, hashes, size,
if tmp, err = DefaultHTTPClient.DownloadTmp(l, "*.downloading", 0644, hashes, size,
downloadingCallback(l)); err != nil {
continue
}
defer os.Remove(tmp)
if err = renameIfNotExist(tmp, path); err != nil {
if err = renameIfNotExist(tmp, path, 0644); err != nil {
return
}
break
Expand Down

0 comments on commit d06fd01

Please sign in to comment.