external.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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. )
  14. func init() {
  15. // Register the constructor for this type of versioner with the name "external"
  16. Factories["external"] = NewExternal
  17. }
  18. // The type holds our configuration
  19. type External struct {
  20. command string
  21. folderPath string
  22. }
  23. // The constructor function takes a map of parameters and creates the type.
  24. func NewExternal(folderID, folderPath string, params map[string]string) Versioner {
  25. command := params["command"]
  26. s := External{
  27. command: command,
  28. folderPath: folderPath,
  29. }
  30. if debug {
  31. l.Debugf("instantiated %#v", s)
  32. }
  33. return s
  34. }
  35. // Move away the named file to a version archive. If this function returns
  36. // nil, the named file does not exist any more (has been archived).
  37. func (v External) Archive(filePath string) error {
  38. _, err := os.Lstat(filePath)
  39. if os.IsNotExist(err) {
  40. if debug {
  41. l.Debugln("not archiving nonexistent file", filePath)
  42. }
  43. return nil
  44. } else if err != nil {
  45. return err
  46. }
  47. if debug {
  48. l.Debugln("archiving", filePath)
  49. }
  50. inFolderPath, err := filepath.Rel(v.folderPath, filePath)
  51. if err != nil {
  52. return err
  53. }
  54. if v.command == "" {
  55. return errors.New("Versioner: command is empty, please enter a valid command")
  56. }
  57. cmd := exec.Command(v.command, v.folderPath, inFolderPath)
  58. env := os.Environ()
  59. // filter STGUIAUTH and STGUIAPIKEY from environment variables
  60. filteredEnv := []string{}
  61. for _, x := range env {
  62. if !strings.HasPrefix(x, "STGUIAUTH=") && !strings.HasPrefix(x, "STGUIAPIKEY=") {
  63. filteredEnv = append(filteredEnv, x)
  64. }
  65. }
  66. cmd.Env = filteredEnv
  67. err = cmd.Run()
  68. if err != nil {
  69. return err
  70. }
  71. // return error if the file was not removed
  72. if _, err = os.Lstat(filePath); os.IsNotExist(err) {
  73. return nil
  74. }
  75. return errors.New("Versioner: file was not removed by external script")
  76. }