package main import ( "dwelling-upload/internal/configuration" "dwelling-upload/internal/handlers" "dwelling-upload/pkg/logging" "dwelling-upload/pkg/server" "dwelling-upload/pkg/utils" "dwelling-upload/pkg/watcher" "flag" "fmt" "log" "os" "os/signal" "syscall" ) var configPath *string = flag.String("conf", "config.yaml", "path to configuration file") var logToStdout *bool = flag.Bool("log-stdout", false, "write logs to stdout") var showVersion *bool = flag.Bool("v", false, "show version") func main() { flag.Parse() if *showVersion { fmt.Println("dwelling-upload Ver. 23.8.0\nCopyright (c) 2022,2023 Alexander \"Arav\" Andreev ") return } config, err := configuration.LoadConfiguration(*configPath) if err != nil { log.Fatalln(err) } defer func() { if typ, addr := config.SplitNetworkAddress(); typ == "unix" { os.Remove(addr) } }() if *logToStdout { config.Log.ToStdout = true } logErr, err := logging.NewLogger(config.Log.Error, config.Log.ToStdout) if err != nil { log.Fatalln("error logger:", err) } defer logErr.Close() logUpload, err := logging.NewLogger(config.Log.Upload, config.Log.ToStdout) if err != nil { log.Fatalln("upload logger:", err) } defer logUpload.Close() logDownload, err := logging.NewLogger(config.Log.Download, config.Log.ToStdout) if err != nil { log.Fatalln("download logger:", err) } defer logDownload.Close() logDelete, err := logging.NewLogger(config.Log.Delete, config.Log.ToStdout) if err != nil { log.Fatalln("delete logger:", err) } defer logDelete.Close() watcha, err := watcher.NewInotifyWatcher() if err != nil { logErr.Fatalln(err) } defer watcha.Close() if err := watcha.AddWatch(config.Uploads.Directory, watcher.CrDelMask); err != nil { logErr.Fatalln(err) } uploadDirNotify := make(chan uint32) uploadDirSize, err := utils.DirectorySize(config.Uploads.Directory) if err != nil { logErr.Fatalf("failed to get initial size of %s: %s", config.Uploads.Directory, err) } watcha.WatchForMask(uploadDirNotify, watcher.CrDelMask) hand := handlers.NewUploadHandlers(config, logErr, logUpload, logDownload, logDelete, &uploadDirSize) srv := server.NewHttpServer() srv.SetNotFoundHandler(hand.NotFound) srv.ServeStatic("/assets/*filepath", hand.AssetsFS()) srv.GET("/", hand.Index) srv.POST("/", hand.Upload) srv.POST("/delete", hand.Delete) srv.GET("/f/:hash/:name", hand.Download) srv.DELETE("/:hash", hand.Delete) if err := srv.Start(config.SplitNetworkAddress()); err != nil { logErr.Fatalln("failed to start a server:", err) } doneSignal := make(chan os.Signal, 1) signal.Notify(doneSignal, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) logReopenSignal := make(chan os.Signal, 1) signal.Notify(logReopenSignal, syscall.SIGHUP) go func() { for { select { case <-logReopenSignal: logErr.Reopen(config.Log.Error) logUpload.Reopen(config.Log.Upload) logDownload.Reopen(config.Log.Download) case <-uploadDirNotify: sz, err := utils.DirectorySize(config.Uploads.Directory) if err != nil { logErr.Println("failed to get uploads directory size:", err) } if sz > 0 { uploadDirSize = sz } } } }() <-doneSignal if err := srv.Stop(); err != nil { logErr.Fatalln("failed to properly shutdown a server:", err) } }