--- /dev/null
+/*
+ * This file is part of the gogopherd project.
+ *
+ * Copyright 2019 Urban Wallasch <irrwahn35@freenet.de>
+ * See LICENSE file for more details.
+ *
+ */
+
+package main
+
+import (
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "os"
+)
+
+var cfg = struct {
+ iface string
+ port string
+ fqdn string
+ docRoot string
+ message string
+ fsymln bool
+ verbose bool
+}{
+ iface: "localhost",
+ port: "7070",
+ fqdn: "localhost",
+ docRoot: ".",
+ message: "",
+ fsymln: false,
+ verbose: false,
+}
+
+func initialize() {
+ help := false
+ 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")
+ flag.StringVar(&cfg.docRoot, "r", cfg.docRoot, "document root directory")
+ flag.StringVar(&cfg.message, "M", cfg.message, "index greeter message")
+ flag.BoolVar(&help, "h", help, "show this help page")
+ flag.BoolVar(&cfg.fsymln, "s", cfg.fsymln, "follow symbolic links")
+ flag.BoolVar(&cfg.verbose, "v", cfg.verbose, "produce verbose output")
+ flag.Parse()
+ if help {
+ fmt.Println("Version ", version)
+ flag.Usage()
+ os.Exit(1)
+ }
+ if 0 != len(flag.Args()) {
+ fmt.Println("Version ", version)
+ fmt.Println("unrecognized options: ", flag.Args())
+ flag.Usage()
+ os.Exit(1)
+ }
+
+ logger = log.New(os.Stderr, "", log.Ldate|log.Ltime|log.Lshortfile)
+ if cfg.verbose {
+ tracer = log.New(os.Stderr, "", log.Ldate|log.Ltime|log.Lshortfile)
+ } else {
+ tracer = log.New(ioutil.Discard, "", 0)
+ }
+ pathSep = string(os.PathSeparator)
+
+ var err error
+ cfg.docRoot, err = canonicalizePath(cfg.docRoot)
+ checkFatal(err, "canonicalizePath "+cfg.docRoot)
+
+ if cfg.message != "" {
+ cfg.message = fmt.Sprintf("i%s\t\t\t\r\n", cfg.message)
+ }
+
+ tracer.Print("Version ", version)
+ tracer.Print("interface: ", cfg.iface)
+ tracer.Print("TCP port: ", cfg.port)
+ tracer.Print("doc root: ", cfg.docRoot)
+ tracer.Print("fsymlinks: ", cfg.fsymln)
+ tracer.Print("fqdn: ", cfg.fqdn)
+ tracer.Print("message: ", cfg.message)
+ tracer.Print("verbose: ", cfg.verbose)
+}
+
+/* EOF */
import (
"bufio"
- "errors"
- "flag"
"fmt"
"io"
"io/ioutil"
- "log"
"net"
- "net/http"
"os"
"path/filepath"
"strconv"
"strings"
)
-var (
- logger *log.Logger
- tracer *log.Logger
- pathSep string
-)
-
-var cfg = struct {
- iface string
- port string
- fqdn string
- docRoot string
- message string
- fsymln bool
- verbose bool
-}{
- iface: "localhost",
- port: "7070",
- fqdn: "localhost",
- docRoot: ".",
- message: "",
- fsymln: false,
- verbose: false,
-}
-
-func initialize() {
- help := false
- 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")
- flag.StringVar(&cfg.docRoot, "r", cfg.docRoot, "document root directory")
- flag.StringVar(&cfg.message, "M", cfg.message, "index greeter message")
- flag.BoolVar(&help, "h", help, "show this help page")
- flag.BoolVar(&cfg.fsymln, "s", cfg.fsymln, "follow symbolic links")
- flag.BoolVar(&cfg.verbose, "v", cfg.verbose, "produce verbose output")
- flag.Parse()
- if help {
- fmt.Println("Version ", version)
- flag.Usage()
- os.Exit(1)
- }
- if 0 != len(flag.Args()) {
- fmt.Println("Version ", version)
- fmt.Println("unrecognized options: ", flag.Args())
- flag.Usage()
- os.Exit(1)
- }
-
- logger = log.New(os.Stderr, "", log.Ldate|log.Ltime|log.Lshortfile)
- if cfg.verbose {
- tracer = log.New(os.Stderr, "", log.Ldate|log.Ltime|log.Lshortfile)
- } else {
- tracer = log.New(ioutil.Discard, "", 0)
- }
- pathSep = string(os.PathSeparator)
-
- var err error
- cfg.docRoot, err = canonicalizePath(cfg.docRoot)
- checkFatal(err, "canonicalizePath "+cfg.docRoot)
-
- if cfg.message != "" {
- cfg.message = fmt.Sprintf("i%s\t\t\t\r\n", cfg.message)
- }
-
- tracer.Print("interface: ", cfg.iface)
- tracer.Print("TCP port: ", cfg.port)
- tracer.Print("doc root: ", cfg.docRoot)
- tracer.Print("fsymlinks: ", cfg.fsymln)
- tracer.Print("fqdn: ", cfg.fqdn)
- tracer.Print("message: ", cfg.message)
- tracer.Print("verbose: ", cfg.verbose)
-}
-
-func checkFatal(err error, msg string) {
- if err != nil {
- logger.Print(msg, ": ", err.Error())
- os.Exit(1)
- }
-}
-
-func check(err error, msg string) error {
- if err != nil {
- tracer.Print(msg, ": ", err.Error())
- }
- return err
-}
-
-func canonicalizePath(path string) (string, error) {
- abs, err := filepath.Abs(path)
- if check(err, "Abs "+path) != nil {
- return path, err
- }
- return abs, err
-}
-
-func validatePath(root string, path string) (string, error) {
- cpath, err := canonicalizePath(path)
- if check(err, "canonicalizePath "+path) != nil {
- return path, err
- }
- if len(cpath) < len(root) || cpath[:len(root)] != root {
- return cpath, errors.New("Path outside root")
- }
- return cpath, err
-}
-
-func guessFiletype(path string) (string, error) {
- // Open File
- f, err := os.Open(path)
- if check(err, "Open "+path) != nil {
- return "i", err
- }
- defer f.Close()
- // Get the content
- buffer := make([]byte, 512)
- n, err := f.Read(buffer)
- if err != io.EOF && check(err, "Read "+path) != nil {
- return "i", err
- }
- buffer = buffer[:n]
- contentType := http.DetectContentType(buffer)
- //tracer.Print("Content Type " + path + " == "+ contentType)
- shortType := strings.Split(contentType, ";")[0]
- genType := strings.Split(shortType, "/")[0]
- gopherType := "9"
- if shortType == "text/html" {
- gopherType = "h"
- } else if genType == "text" {
- gopherType = "0"
- } else if shortType == "image/gif" {
- gopherType = "g"
- } else if genType == "image" {
- gopherType = "I"
- } else if genType == "audio" {
- gopherType = "s"
- }
- return gopherType, nil
-}
-
-func humanSize(bytes int64) string {
- var units = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"}
- ui := 0
- decimals := 1
- if bytes < 1024 {
- decimals = 0
- }
- var n float64
- for n = float64(bytes); n > 1024; n /= 1024 {
- ui = ui + 1
- }
- return fmt.Sprintf("%.*f %s", decimals, n, units[ui])
-}
-
func createIndex(selector string) (string, error) {
dirname := cfg.docRoot + selector
fi, err := ioutil.ReadDir(dirname)
--- /dev/null
+/*
+ * This file is part of the gogopherd project.
+ *
+ * Copyright 2019 Urban Wallasch <irrwahn35@freenet.de>
+ * See LICENSE file for more details.
+ *
+ */
+
+package main
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "log"
+ "net/http"
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+var (
+ logger *log.Logger
+ tracer *log.Logger
+ pathSep string
+)
+
+func checkFatal(err error, msg string) {
+ if err != nil {
+ logger.Print(msg, ": ", err.Error())
+ os.Exit(1)
+ }
+}
+
+func check(err error, msg string) error {
+ if err != nil {
+ tracer.Print(msg, ": ", err.Error())
+ }
+ return err
+}
+
+func canonicalizePath(path string) (string, error) {
+ abs, err := filepath.Abs(path)
+ if check(err, "Abs "+path) != nil {
+ return path, err
+ }
+ return abs, err
+}
+
+func validatePath(root string, path string) (string, error) {
+ cpath, err := canonicalizePath(path)
+ if check(err, "canonicalizePath "+path) != nil {
+ return path, err
+ }
+ if len(cpath) < len(root) || cpath[:len(root)] != root {
+ return cpath, errors.New("Path outside doc root hierarchy")
+ }
+ return cpath, err
+}
+
+func guessFiletype(path string) (string, error) {
+ // Open File
+ f, err := os.Open(path)
+ if check(err, "Open "+path) != nil {
+ return "i", err
+ }
+ defer f.Close()
+ // Get the content
+ buffer := make([]byte, 512)
+ n, err := f.Read(buffer)
+ if err != io.EOF && check(err, "Read "+path) != nil {
+ return "i", err
+ }
+ buffer = buffer[:n]
+ contentType := http.DetectContentType(buffer)
+ //tracer.Print("Content Type " + path + " == "+ contentType)
+ shortType := strings.Split(contentType, ";")[0]
+ genType := strings.Split(shortType, "/")[0]
+ gopherType := "9"
+ if shortType == "text/html" {
+ gopherType = "h"
+ } else if genType == "text" {
+ gopherType = "0"
+ } else if shortType == "image/gif" {
+ gopherType = "g"
+ } else if genType == "image" {
+ gopherType = "I"
+ } else if genType == "audio" {
+ gopherType = "s"
+ }
+ return gopherType, nil
+}
+
+func humanSize(bytes int64) string {
+ var units = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"}
+ ui := 0
+ decimals := 1
+ if bytes < 1024 {
+ decimals = 0
+ }
+ var n float64
+ for n = float64(bytes); n > 1024; n /= 1024 {
+ ui = ui + 1
+ }
+ return fmt.Sprintf("%.*f %s", decimals, n, units[ui])
+}
+
+/* EOF */