external.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // Copyright (C) 2015 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at http://mozilla.org/MPL/2.0/.
  6. package versioner
  7. import (
  8. "errors"
  9. "os"
  10. "os/exec"
  11. "path/filepath"
  12. "strings"
  13. "github.com/syncthing/syncthing/internal/osutil"
  14. )
  15. func init() {
  16. // Register the constructor for this type of versioner with the name "external"
  17. Factories["external"] = NewExternal
  18. }
  19. // The type holds our configuration
  20. type External struct {
  21. command string
  22. folderPath string
  23. }
  24. // The constructor function takes a map of parameters and creates the type.
  25. func NewExternal(folderID, folderPath string, params map[string]string) Versioner {
  26. command := params["command"]
  27. s := External{
  28. command: command,
  29. folderPath: folderPath,
  30. }
  31. if debug {
  32. l.Debugf("instantiated %#v", s)
  33. }
  34. return s
  35. }
  36. // Move away the named file to a version archive. If this function returns
  37. // nil, the named file does not exist any more (has been archived).
  38. func (v External) Archive(filePath string) error {
  39. _, err := osutil.Lstat(filePath)
  40. if os.IsNotExist(err) {
  41. if debug {
  42. l.Debugln("not archiving nonexistent file", filePath)
  43. }
  44. return nil
  45. } else if err != nil {
  46. return err
  47. }
  48. if debug {
  49. l.Debugln("archiving", filePath)
  50. }
  51. inFolderPath, err := filepath.Rel(v.folderPath, filePath)
  52. if err != nil {
  53. return err
  54. }
  55. if v.command == "" {
  56. return errors.New("Versioner: command is empty, please enter a valid command")
  57. }
  58. cmd := exec.Command(v.command, v.folderPath, inFolderPath)
  59. env := os.Environ()
  60. // filter STGUIAUTH and STGUIAPIKEY from environment variables
  61. filteredEnv := []string{}
  62. for _, x := range env {
  63. if !strings.HasPrefix(x, "STGUIAUTH=") && !strings.HasPrefix(x, "STGUIAPIKEY=") {
  64. filteredEnv = append(filteredEnv, x)
  65. }
  66. }
  67. cmd.Env = filteredEnv
  68. err = cmd.Run()
  69. if err != nil {
  70. return err
  71. }
  72. // return error if the file was not removed
  73. if _, err = osutil.Lstat(filePath); os.IsNotExist(err) {
  74. return nil
  75. }
  76. return errors.New("Versioner: file was not removed by external script")
  77. }