main.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // Full featured and highly configurable SFTP server.
  2. // For more details about features, installation, configuration and usage please refer to the README inside the source tree:
  3. // https://github.com/drakkan/sftpgo/blob/master/README.md
  4. package main // import "github.com/drakkan/sftpgo"
  5. import (
  6. "flag"
  7. "fmt"
  8. "net/http"
  9. "os"
  10. "path/filepath"
  11. "time"
  12. _ "github.com/go-sql-driver/mysql"
  13. _ "github.com/lib/pq"
  14. _ "github.com/mattn/go-sqlite3"
  15. "github.com/drakkan/sftpgo/api"
  16. "github.com/drakkan/sftpgo/config"
  17. "github.com/drakkan/sftpgo/dataprovider"
  18. "github.com/drakkan/sftpgo/logger"
  19. "github.com/drakkan/sftpgo/sftpd"
  20. "github.com/drakkan/sftpgo/utils"
  21. "github.com/rs/zerolog"
  22. )
  23. func main() {
  24. logSender := "main"
  25. var (
  26. configDir string
  27. configFileName string
  28. logFilePath string
  29. logMaxSize int
  30. logMaxBackups int
  31. logMaxAge int
  32. logCompress bool
  33. logVerbose bool
  34. )
  35. flag.StringVar(&configDir, "config-dir", utils.GetEnvVar("SFTPGO_CONFIG_DIR", "."), "Location for SFTPGo config dir. It must contain "+
  36. "sftpgo.conf or the configured config-file-name and it is used as the base for files with a relative path (eg. the private "+
  37. "keys for the SFTP server, the SQLite database if you use SQLite as data provider).")
  38. flag.StringVar(&configFileName, "config-file-name", utils.GetEnvVar("SFTPGO_CONFIG_FILE_NAME", "sftpgo.conf"), "Name for SFTPGo "+
  39. "configuration file. It must be the name of a file stored in config-dir not the absolute path to the configuration file")
  40. flag.StringVar(&logFilePath, "log-file-path", utils.GetEnvVar("SFTPGO_LOG_FILE_PATH", "sftpgo.log"), "Location for the log file")
  41. flag.IntVar(&logMaxSize, "log-max-size", utils.GetEnvVarAsInt("SFTPGO_LOG_MAX_SIZE", 10), "Maximum size in megabytes of the log file "+
  42. "before it gets rotated.")
  43. flag.IntVar(&logMaxBackups, "log-max-backups", utils.GetEnvVarAsInt("SFTPGO_LOG_MAX_BACKUPS", 5), "Maximum number of old log files "+
  44. "to retain")
  45. flag.IntVar(&logMaxAge, "log-max-age", utils.GetEnvVarAsInt("SFTPGO_LOG_MAX_AGE", 28), "Maximum number of days to retain old log files")
  46. flag.BoolVar(&logCompress, "log-compress", utils.GetEnvVarAsInt("SFTPGO_LOG_COMPRESS", 0) > 0, "Determine if the rotated log files "+
  47. "should be compressed using gzip")
  48. flag.BoolVar(&logVerbose, "log-verbose", utils.GetEnvVarAsInt("SFTPGO_LOG_VERBOSE", 1) > 0, "Enable verbose logs")
  49. flag.Parse()
  50. configFilePath := filepath.Join(configDir, configFileName)
  51. logLevel := zerolog.DebugLevel
  52. if !logVerbose {
  53. logLevel = zerolog.InfoLevel
  54. }
  55. logger.InitLogger(logFilePath, logMaxSize, logMaxBackups, logMaxAge, logCompress, logLevel)
  56. logger.Info(logSender, "starting SFTPGo, config dir: %v", configDir)
  57. config.LoadConfig(configFilePath)
  58. providerConf := config.GetProviderConf()
  59. err := dataprovider.Initialize(providerConf, configDir)
  60. if err != nil {
  61. logger.Error(logSender, "error initializing data provider: %v", err)
  62. logger.ErrorToConsole("error initializing data provider: %v", err)
  63. os.Exit(1)
  64. }
  65. dataProvider := dataprovider.GetProvider()
  66. sftpdConf := config.GetSFTPDConfig()
  67. httpdConf := config.GetHTTPDConfig()
  68. sftpd.SetDataProvider(dataProvider)
  69. shutdown := make(chan bool)
  70. go func() {
  71. logger.Debug(logSender, "initializing SFTP server with config %+v", sftpdConf)
  72. if err := sftpdConf.Initialize(configDir); err != nil {
  73. logger.Error(logSender, "could not start SFTP server: %v", err)
  74. logger.ErrorToConsole("could not start SFTP server: %v", err)
  75. }
  76. shutdown <- true
  77. }()
  78. if httpdConf.BindPort > 0 {
  79. router := api.GetHTTPRouter()
  80. api.SetDataProvider(dataProvider)
  81. go func() {
  82. logger.Debug(logSender, "initializing HTTP server with config %+v", httpdConf)
  83. s := &http.Server{
  84. Addr: fmt.Sprintf("%s:%d", httpdConf.BindAddress, httpdConf.BindPort),
  85. Handler: router,
  86. ReadTimeout: 300 * time.Second,
  87. WriteTimeout: 300 * time.Second,
  88. MaxHeaderBytes: 1 << 20, // 1MB
  89. }
  90. if err := s.ListenAndServe(); err != nil {
  91. logger.Error(logSender, "could not start HTTP server: %v", err)
  92. logger.ErrorToConsole("could not start HTTP server: %v", err)
  93. }
  94. shutdown <- true
  95. }()
  96. } else {
  97. logger.Debug(logSender, "HTTP server not started, disabled in config file")
  98. logger.DebugToConsole("HTTP server not started, disabled in config file")
  99. }
  100. <-shutdown
  101. }