package main import ( "flag" "log" "net" "net/http" "net/http/fcgi" "os" "os/signal" "syscall" "marisa.chaotic.ninja/marisa" ) type templatedata struct { Links []string Size string Maxsize string } type metadata struct { Filename string Size int64 Expiry int64 } var conf struct { user string group string chroot string listen string baseuri string rootdir string tmplpath string filepath string metapath string filectx string maxsize int64 expiry int64 } var verbose bool func main() { var err error var configfile string var listener net.Listener /* default values */ conf.listen = "127.0.0.1:8080" conf.baseuri = "http://127.0.0.1:8080" conf.rootdir = "static" conf.tmplpath = "templates" conf.filepath = "files" conf.metapath = "meta" conf.filectx = "/f/" conf.maxsize = 34359738368 conf.expiry = 86400 flag.StringVar(&configfile, "f", "", "Configuration file") flag.BoolVar(&verbose, "v", false, "Verbose logging") flag.Parse() if configfile != "" { if verbose { log.Printf("Reading configuration %s", configfile) } parseconfig(configfile) } if conf.chroot != "" { if verbose { log.Printf("Changing root to %s", conf.chroot) } syscall.Chroot(conf.chroot) } if conf.listen[0] == '/' { /* Remove any stale socket */ os.Remove(conf.listen) if listener, err = net.Listen("unix", conf.listen); err != nil { log.Fatal(err) } defer listener.Close() /* * Ensure unix socket is removed on exit. * Note: this might not work when dropping privileges… */ defer os.Remove(conf.listen) sigs := make(chan os.Signal, 1) signal.Notify(sigs, os.Interrupt, os.Kill, syscall.SIGTERM) go func() { _ = <-sigs listener.Close() if err = os.Remove(conf.listen); err != nil { log.Fatal(err) } os.Exit(0) }() } else { if listener, err = net.Listen("tcp", conf.listen); err != nil { log.Fatal(err) } defer listener.Close() } if conf.user != "" { if verbose { log.Printf("Dropping privileges to %s", conf.user) } uid, gid, err := usergroupids(conf.user, conf.group) if err != nil { log.Fatal(err) } if listener.Addr().Network() == "unix" { os.Chown(conf.listen, uid, gid) } syscall.Setuid(uid) syscall.Setgid(gid) } http.HandleFunc("/", uploader) http.Handle(conf.filectx, http.StripPrefix(conf.filectx, http.FileServer(http.Dir(conf.filepath)))) if verbose { log.Printf("Starting marisa %v\n", marisa.FullVersion()) log.Printf("Listening on %s", conf.listen) } if listener.Addr().Network() == "unix" { err = fcgi.Serve(listener, nil) log.Fatal(err) /* NOTREACHED */ } err = http.Serve(listener, nil) log.Fatal(err) /* NOTREACHED */ }