package main import ( "flag" "log" "net/http" "os" "path/filepath" "strings" "chfs-ng/internal/api" "chfs-ng/internal/auth" "chfs-ng/internal/config" "chfs-ng/internal/storage" ) func main() { file := flag.String("file", "", "configuration file") pathFlag := flag.String("path", "/data", "shared path") port := flag.Int("port", 80, "listen port") allow := flag.String("allow", "", "allowed IPv4 addresses") var rules multiFlag flag.Var(&rules, "rule", "access rule (repeatable)") flag.Parse() cfg := config.Default() if *file != "" { loaded, err := config.Load(*file) if err != nil && !os.IsNotExist(err) { log.Fatal(err) } if err == nil { cfg = loaded } } flag.CommandLine.Visit(func(f *flag.Flag) { switch f.Name { case "path": cfg.Path = splitPath(*pathFlag) case "port": cfg.Port = *port case "allow": cfg.Allow = *allow case "rule": cfg.Rules = append([]string(nil), rules...) } }) if len(cfg.Path) == 0 { cfg.Path = []string{"/data"} } if err := cfg.Validate(); err != nil { log.Fatal(err) } root := cfg.Path[0] if len(cfg.Path) > 1 { log.Printf("warning: %d shared roots configured; v1 compatibility currently serves the first root %q", len(cfg.Path), root) } if err := os.MkdirAll(root, 0755); err != nil { log.Fatal(err) } mgr, err := auth.ParseRules(cfg.Rules) if err != nil { log.Fatal(err) } srv := &api.Server{Store: storage.Local{Root: root}, Auth: mgr, Sessions: map[string]*auth.Account{}, WebDAVRoot: root} addr := ":" + itoa(cfg.Port) log.Printf("chfs-ng listening on %s root=%s", addr, filepath.Clean(root)) if cfg.SSLCert != "" && cfg.SSLKey != "" { log.Fatal(http.ListenAndServeTLS(addr, cfg.SSLCert, cfg.SSLKey, srv.Handler())) } log.Fatal(http.ListenAndServe(addr, srv.Handler())) } type multiFlag []string func (m *multiFlag) String() string { return strings.Join(*m, "|") } func (m *multiFlag) Set(v string) error { *m = append(*m, v); return nil } func itoa(n int) string { const d = "0123456789" if n == 0 { return "0" } b := make([]byte, 0, 6) for n > 0 { b = append([]byte{d[n%10]}, b...) n /= 10 } return string(b) } func splitPath(v string) []string { var out []string for _, p := range strings.Split(v, "|") { p = strings.TrimSpace(p) if p != "" { out = append(out, p) } } return out }