diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..208d37e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +tokiko diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d21321f --- /dev/null +++ b/Makefile @@ -0,0 +1,36 @@ +GO ?= go +RM ?= rm +GOFLAGS ?= -v -ldflags "-w -X `go list`.Version=$(VERSION) -X `go list`.Commit=$(COMMIT) -X `go list`.Build=$(BUILD)" -mod=vendor +PREFIX ?= /usr/local +BINDIR ?= bin +MANDIR ?= share/man +MKDIR ?= mkdir +CP ?= cp +SYSCONFDIR ?= /etc + +VERSION = `git describe --abbrev=0 --tags 2>/dev/null || echo "$VERSION"` +COMMIT = `git rev-parse --short HEAD || echo "$COMMIT"` +BRANCH = `git rev-parse --abbrev-ref HEAD` +BUILD = `git show -s --pretty=format:%cI` + +GOARCH ?= amd64 +GOOS ?= linux + +all: tokiko + +tokiko: + $(GO) build $(GOFLAGS) ./cmd/tokiko +clean: + $(RM) -f tokiko +install: + $(MKDIR) -p $(DESTDIR)$(PREFIX)/$(BINDIR) + $(MKDIR) -p $(DESTDIR)$(PREFIX)/$(MANDIR)/man1 + $(MKDIR) -p $(DESTDIR)${SYSCONFDIR}/tokiko + $(CP) -f tokiko $(DESTDIR)$(PREFIX)/$(BINDIR) + $(CP) -f doc/tokiko.1 $(DESTDIR)$(PREFIX)/$(MANDIR)/man1 + [ -f $(DESTDIR)${SYSCONFDIR}/tokiko/config.ini ] || $(CP) -f config.ini $(DESTDIR)${SYSCONFDIR}/tokiko/config.ini +test: + go test +vendor: + go mod vendor +.PHONY: tokiko clean install diff --git a/README b/README index 612dc5f..4320fc1 100644 --- a/README +++ b/README @@ -3,15 +3,18 @@ Tokiko A simple gopher daemon written in Golang. Forked from shokara/thomomys -Flags ------ --i = IP address for Tokiko to listen on (Default: 0.0.0.0) --p = Port for Tokiko to listen on (Default: 70) --h = Default hostname that gets printed for links (Default: localhost) --d = Root directory that gets served (Default: current directory) - +Config +------ +addr = IP address for Tokiko to listen on (Default: 127.0.0.1) +port = Port for Tokiko to listen on (Default: 70) +hostname = Default hostname that gets printed for links (Default: localhost) +rootdir = Root directory that gets served (Default: /var/gopher) + Why? ---- -Anything can and will happen. Simple as that. -And while environment variables are okay, they are rather messy to deal with, in my opinion, but that's just me I guess. +Yes. + +Credits +------- +I blatantly copied the parseconfig code from https://git.z3bra.org/partage diff --git a/go.mod b/go.mod index 381d7dd..dca23ee 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,7 @@ -module gt.kalli.st/novaburst/thomomys +module marisa.chaotic.ninja/tokiko go 1.18 + +require gopkg.in/ini.v1 v1.67.0 + +require github.com/stretchr/testify v1.8.4 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..a313164 --- /dev/null +++ b/go.sum @@ -0,0 +1,7 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/main.go b/main.go deleted file mode 100644 index 57ae1a6..0000000 --- a/main.go +++ /dev/null @@ -1,158 +0,0 @@ -// A barebones gopher server written in Golang -// This fork in particular uses flags instead of environment variables. -// Copyright: -// (C) 2021 Shokara Kou -// (C) 2023 Izuru Yakumo - -package main - -import ( - "bufio" - "io" - "log" - "net" - "os" - "strings" - "flag" -) - -var ( - ADDR_IP string - ADDR_PORT string - HOSTNAME string - SRVDIR string -) - -func formatLine(line string) string { - trimmed := strings.TrimRight(line, "\r\n") - splitted := strings.Split(trimmed, "\t") - - if len(splitted) == 3 { - return line - } else if len(splitted) == 2 { - line += "\t" + HOSTNAME + "\t" + ADDR_PORT - } else if len(splitted) == 1 { - line += "\tErr\t" + HOSTNAME + "\t" + ADDR_PORT - } - - return line + "\n" -} - -func writeError(c net.Conn, msg string) { - c.Write([]byte(formatLine("3" + msg))) -} - -func printGophermap(c net.Conn, dir string) { - file, err := os.Open(dir + "/Gophermap") - if err != nil { - writeError(c, err.Error()) - log.Println(err) - } - defer func() { - if err = file.Close(); err != nil { - log.Println(err) - } - }() - - scanner := bufio.NewScanner(file) - for scanner.Scan() { - c.Write([]byte(formatLine(scanner.Text()) + "\n")) - } - - c.Write([]byte(".\r\n")) -} - -func printFile(c net.Conn, path string) { - file, err := os.Open(path) - if err != nil { - writeError(c, err.Error()) - log.Println(err) - } - defer func() { - if err = file.Close(); err != nil { - log.Println(err) - } - }() - - const bufSz = 1024 - b := make([]byte, bufSz) - - for { - readSz, err := file.Read(b) - if err != nil { - if err != io.EOF { - log.Println(err) - } - break - } - - c.Write(b[:readSz]) - } -} - -func connHandle(c net.Conn) { - data, err := bufio.NewReader(c).ReadString('\n') - if err != nil { - log.Println(err) - return - } - - selector := strings.TrimRight(data, "\r\n") - - if selector == "" { - printGophermap(c, "./") - } else if strings.Contains(selector, "..") { - writeError(c, "Selector contains ..") - } else if selector[0] == '/' { - info, err := os.Stat(selector[1:]) - if err != nil { - writeError(c, err.Error()) - log.Println(err) - - c.Close() - return - } - - if info.IsDir() { - printGophermap(c, selector[1:]) - } else { - printFile(c, selector[1:]) - } - } else { - writeError(c, "Selector doesn't start with a /") - } - - c.Close() -} - -func init() { - flag.StringVar(&ADDR_IP, "i", "0.0.0.0", "IP address for Tokiko to listen on .Default is 0.0.0.0") - flag.StringVar(&ADDR_PORT, "p", "70", "Port for Tokiko to listen on. Default is 70") - flag.StringVar(&HOSTNAME, "h", "localhost", "Hostname that gets printed for links. Default is localhost") - flag.StringVar(&SRVDIR, "s", ".", "Root directory that gets served. Default is current directory") -} -func main() { - flag.Parse() - - LISTEN_ADDR := ADDR_IP + ":" + ADDR_PORT - log.Printf("Starting thomomys on %s\n", LISTEN_ADDR) - - os.Chdir(SRVDIR) - - l, err := net.Listen("tcp", LISTEN_ADDR) - if err != nil { - log.Fatal(err) - return - } - defer l.Close() - - for { - c, err := l.Accept() - if err != nil { - log.Println(err) - return - } - - go connHandle(c) - } -} diff --git a/version.go b/version.go new file mode 100644 index 0000000..956d95a --- /dev/null +++ b/version.go @@ -0,0 +1,50 @@ +package tokiko + +import ( + "fmt" + "runtime/debug" + "strings" +) + +const ( + defaultVersion = "0.0.0" + defaultCommit = "HEAD" + defaultBuild = "0000-01-01:00:00+00:00" +) + +var ( + // Version is the tagged release version in the form .. + // following semantic versioning and is overwritten by the build system. + Version = defaultVersion + + // Commit is the commit sha of the build (normally from Git) and is overwritten + // by the build system. + Commit = defaultCommit + + // Build is the date and time of the build as an RFC3339 formatted string + // and is overwritten by the build system. + Build = defaultBuild +) + +// FullVersion display the full version and build +func FullVersion() string { + var sb strings.Builder + + isDefault := Version == defaultVersion && Commit == defaultCommit && Build == defaultBuild + + if !isDefault { + sb.WriteString(fmt.Sprintf("%s@%s %s", Version, Commit, Build)) + } + + if info, ok := debug.ReadBuildInfo(); ok { + if isDefault { + sb.WriteString(fmt.Sprintf(" %s", info.Main.Version)) + } + sb.WriteString(fmt.Sprintf(" %s", info.GoVersion)) + if info.Main.Sum != "" { + sb.WriteString(fmt.Sprintf(" %s", info.Main.Sum)) + } + } + + return sb.String() +}