From c9dc8ef72b22c38e36469c96e7a7fa87aafa0e63 Mon Sep 17 00:00:00 2001 From: Urban Wallasch Date: Sun, 7 Apr 2019 00:04:02 +0200 Subject: [PATCH] * Added a sorry excuse for a configuration file parser. --- .gitignore | 1 + README.md | 33 +++++++++++++++++------------ config.go | 49 ++++++++++++++++++++++++++++++++++++++++++- gogopherd.cfg.example | 23 ++++++++++++++++++++ gogopherd.go | 6 +++--- util.go | 8 +++++++ 6 files changed, 103 insertions(+), 17 deletions(-) create mode 100644 gogopherd.cfg.example diff --git a/.gitignore b/.gitignore index 825745f..afeadb1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ gogopherd +gogopherd.cfg version.go diff --git a/README.md b/README.md index f0c00c3..5795a6a 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,8 @@ _(Source: Wikipedia)_ ## Motivation -For the fun of it. Also, given the golang.org mascot, what could be -more appropriate? +For the fun of it. Also, considering the golang.org mascot, what +could be more appropriate than writing gopher software in Go? ## Installation @@ -35,37 +35,44 @@ The `gogopherd` executable recognizes the following command line options: ``` - -M string - index greeter message + -I string + directory index page (default "index.goph") + + -c string + configuration file (default "gogopherd.cfg") -d - allow access to dotfiles + allow access to dotfiles -f string - fully qualified domain name (default "localhost") + fully qualified domain name (default "localhost") -h - show this help page + show this help page -i string - interface to bind to (default "localhost") + interface to bind to (default "localhost") -l - allow directory listings + allow directory listings -p string - TCP port to listen on (default "7070") + TCP port to listen on (default "7070") -r string - document root directory (default ".") + document root directory (default ".") -s - follow symbolic links + follow symbolic links -v - produce verbose output + produce verbose output ``` +An example configuration file, `gogopherd.cfg`, is included. Any options +provided on the command line will override the respective settings as +read from the configuration file. + ## Release History diff --git a/config.go b/config.go index 2928658..6e4817a 100644 --- a/config.go +++ b/config.go @@ -11,6 +11,7 @@ package main import ( "flag" "fmt" + "io/ioutil" "os" "path/filepath" "strings" @@ -38,8 +39,51 @@ var cfg = struct { verbose: false, } +func parseConfigFile(filename string) error { + tracer.Print("reading config from " + filename) + file, err := ioutil.ReadFile(filename) + if err != nil { + logger.Print("ReadFile: ", err.Error()) + return err + } + lines := strings.Split(string(file), "\n") + for _, line := range lines { + line = strings.TrimSpace(string(line)) + if len(line) == 0 || line[:1] == "#" || line[:1] == ";" { + continue + } + assign := strings.Split(line, "=") + name := strings.ToLower(strings.TrimSpace(assign[0])) + val := strings.Trim(strings.TrimSpace(assign[1]), "\"") + tracer.Print(name + "=" + val) + switch name { + case "iface": + cfg.iface = val + case "port": + cfg.port = val + case "fqdn": + cfg.fqdn = val + case "docroot": + cfg.docRoot = val + case "diridx": + cfg.dirIdx = val + case "fsymln": + cfg.fsymln = strToBool(val) + case "showdot": + cfg.showdot = strToBool(val) + case "noidx": + cfg.noidx = strToBool(val) + default: + logger.Print("ignoring unknown config item: " + name) + } + } + return nil +} + func initialize() { help := false + cfgfile := "gogopherd.cfg" + flag.StringVar(&cfgfile, "c", cfgfile, "configuration file") flag.StringVar(&cfg.iface, "i", cfg.iface, "interface to bind to") flag.StringVar(&cfg.port, "p", cfg.port, "TCP port to listen on") flag.StringVar(&cfg.fqdn, "f", cfg.fqdn, "fully qualified domain name") @@ -62,8 +106,11 @@ func initialize() { flag.Usage() os.Exit(1) } - initUtil(cfg.verbose) + if len(cfgfile) > 0 { + parseConfigFile(cfgfile) + flag.Parse() + } var err error cfg.docRoot, err = canonicalizePath(cfg.docRoot) diff --git a/gogopherd.cfg.example b/gogopherd.cfg.example new file mode 100644 index 0000000..d9a6464 --- /dev/null +++ b/gogopherd.cfg.example @@ -0,0 +1,23 @@ +# Example configuration for gogopherd. +# Command line options will override values set here. + +# Network interface to bind to, empty means all. +iface = "" +# TCP port to listen on. +port = 7070 +# Fully qualified domain name associated with server. +fqdn = "localhost" + +# Root directory of document hierarchy. +docroot = "." +# Name of directory index files. +diridx = "index.goph" + +# If true, follow symbolic links. +fsymln = true +# Show dot files. +showdot = false +# Do not generate directory listings when no index file is present. +noidx = false + +# EOF diff --git a/gogopherd.go b/gogopherd.go index bc31d17..29669f5 100644 --- a/gogopherd.go +++ b/gogopherd.go @@ -77,7 +77,7 @@ func createIndex(dirname string, selector string) (string, error) { } } } else { - tracer.Print("unhandled file mode: " + fi.Name() + " (" + fmode.String() + ")") + logger.Print("unhandled file mode: " + fi.Name() + " (" + fmode.String() + ")") } } return list, error(nil) @@ -208,7 +208,7 @@ func serveTCP(sock net.Listener) { for { conn, err := sock.Accept() checkFatal(err, "Accept") - tracer.Print("TCP connect from ", conn.RemoteAddr()) + logger.Print("TCP connect from ", conn.RemoteAddr()) go handleRequest(conn) } } @@ -219,7 +219,7 @@ func main() { tsock, err := net.Listen("tcp", bindaddr) checkFatal(err, "net.Listen tcp "+bindaddr) defer tsock.Close() - tracer.Print("listening on TCP ", bindaddr) + logger.Print("listening on TCP ", bindaddr) go serveTCP(tsock) // send ready signal fmt.Println("") diff --git a/util.go b/util.go index 29d453b..fef860a 100644 --- a/util.go +++ b/util.go @@ -125,4 +125,12 @@ func humanDate(t time.Time) string { return t.Format("2006-01-02 15:04:05 -07:00") } +func strToBool(s string) bool { + switch strings.ToLower(s) { + case "yes", "1", "on", "true", "aye", "yup": + return true + } + return false +} + /* EOF */ -- 2.30.2