diff --git a/cmd/syncthing/main.go b/cmd/syncthing/main.go index da5536a08..98605c50f 100644 --- a/cmd/syncthing/main.go +++ b/cmd/syncthing/main.go @@ -580,11 +580,13 @@ func getDefaultConfDir() string { switch runtime.GOOS { case "windows": return filepath.Join(os.Getenv("AppData"), "Syncthing") + case "darwin": return expandTilde("~/Library/Application Support/Syncthing") + default: if xdgCfg := os.Getenv("XDG_CONFIG_HOME"); xdgCfg != "" { - return xdgCfg + "/syncthing" + return filepath.Join(xdgCfg, "syncthing") } else { return expandTilde("~/.config/syncthing") } @@ -592,17 +594,11 @@ func getDefaultConfDir() string { } func expandTilde(p string) string { - if !strings.HasPrefix(p, "~/") { + if runtime.GOOS == "windows" || !strings.HasPrefix(p, "~/") { return p } - switch runtime.GOOS { - case "windows": - return p - - default: - return filepath.Join(getHomeDir(), p[2:]) - } + return filepath.Join(getHomeDir(), p[2:]) } func getHomeDir() string { @@ -610,7 +606,7 @@ func getHomeDir() string { switch runtime.GOOS { case "windows": - home = os.Getenv("HomeDrive") + os.Getenv("HomePath") + home = filepath.Join(os.Getenv("HomeDrive"), os.Getenv("HomePath")) if home == "" { home = os.Getenv("UserProfile") } diff --git a/cmd/syncthing/puller.go b/cmd/syncthing/puller.go index 45e030675..33cec278e 100644 --- a/cmd/syncthing/puller.go +++ b/cmd/syncthing/puller.go @@ -313,6 +313,7 @@ func (p *puller) handleRequestResult(res requestResult) { t := time.Unix(f.Modified, 0) os.Chtimes(of.temp, t, t) os.Chmod(of.temp, os.FileMode(f.Flags&0777)) + defTempNamer.Show(of.temp) if debugPull { dlog.Printf("pull: rename %q / %q: %q", p.repo, f.Name, of.filepath) } @@ -371,6 +372,7 @@ func (p *puller) handleBlock(b bqBlock) { p.requestSlots <- true return } + defTempNamer.Hide(of.temp) } if of.err != nil { @@ -514,6 +516,7 @@ func (p *puller) handleEmptyBlock(b bqBlock) { t := time.Unix(f.Modified, 0) os.Chtimes(of.temp, t, t) os.Chmod(of.temp, os.FileMode(f.Flags&0777)) + defTempNamer.Show(of.temp) Rename(of.temp, of.filepath) } delete(p.openFiles, f.Name) diff --git a/cmd/syncthing/tempname.go b/cmd/syncthing/tempname.go index a444ea2b1..e4e7ed239 100644 --- a/cmd/syncthing/tempname.go +++ b/cmd/syncthing/tempname.go @@ -1,3 +1,5 @@ +// +build !windows + package main import ( @@ -21,3 +23,11 @@ func (t tempNamer) TempName(name string) string { tname := fmt.Sprintf("%s.%s", t.prefix, filepath.Base(name)) return filepath.Join(tdir, tname) } + +func (t tempNamer) Hide(path string) error { + return nil +} + +func (t tempNamer) Show(path string) error { + return nil +} diff --git a/cmd/syncthing/tempname_windows.go b/cmd/syncthing/tempname_windows.go new file mode 100644 index 000000000..3fdf17550 --- /dev/null +++ b/cmd/syncthing/tempname_windows.go @@ -0,0 +1,56 @@ +// +build windows + +package main + +import ( + "fmt" + "path/filepath" + "strings" + "syscall" +) + +type tempNamer struct { + prefix string +} + +var defTempNamer = tempNamer{"~syncthing~"} + +func (t tempNamer) IsTemporary(name string) bool { + return strings.HasPrefix(filepath.Base(name), t.prefix) +} + +func (t tempNamer) TempName(name string) string { + tdir := filepath.Dir(name) + tname := fmt.Sprintf("%s.%s.tmp", t.prefix, filepath.Base(name)) + return filepath.Join(tdir, tname) +} + +func (t tempNamer) Hide(path string) error { + p, err := syscall.UTF16PtrFromString(path) + if err != nil { + return err + } + + attrs, err := syscall.GetFileAttributes(p) + if err != nil { + return err + } + + attrs |= syscall.FILE_ATTRIBUTE_HIDDEN + return syscall.SetFileAttributes(p, attrs) +} + +func (t tempNamer) Show(path string) error { + p, err := syscall.UTF16PtrFromString(path) + if err != nil { + return err + } + + attrs, err := syscall.GetFileAttributes(p) + if err != nil { + return err + } + + attrs &^= syscall.FILE_ATTRIBUTE_HIDDEN + return syscall.SetFileAttributes(p, attrs) +}