mirror of
https://github.com/YGGverse/nexd.git
synced 2026-03-31 09:45:28 +00:00
initial commit
This commit is contained in:
commit
a3ffecb1db
4 changed files with 186 additions and 0 deletions
22
LICENSE
Normal file
22
LICENSE
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 m15o
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice (including the next
|
||||||
|
paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
2
Makefile
Normal file
2
Makefile
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
build:
|
||||||
|
GOARCH=amd64 go build -o nexd nexd.go
|
||||||
19
README.md
Normal file
19
README.md
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# nexd - Server for Nex Protocol written in Go
|
||||||
|
|
||||||
|
Unofficial GIT build of [nexd](https://hg.sr.ht/~m15o/nexd) Mercurial repository.
|
||||||
|
|
||||||
|
Includes [nex-pfm](https://hg.sr.ht/~m15o/nex-pfm) + modified for Linux / amd64 makefile version.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
* `git clone https://github.com/YGGverse/nexd.git`
|
||||||
|
* `cd nexd`
|
||||||
|
* `make`
|
||||||
|
|
||||||
|
## Launch
|
||||||
|
|
||||||
|
```
|
||||||
|
nexd path/to/destination/folder
|
||||||
|
```
|
||||||
|
|
||||||
|
* server open `index` file by default, directory listing instead
|
||||||
143
nexd.go
Normal file
143
nexd.go
Normal file
|
|
@ -0,0 +1,143 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"io"
|
||||||
|
"io/fs"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func write(w io.Writer, s string) (int, error) {
|
||||||
|
return w.Write([]byte(s + "\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
type Handler struct {
|
||||||
|
FS fs.FS
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) handleDir(p string, w io.Writer) error {
|
||||||
|
if header, err := fs.ReadFile(h.FS, path.Join(p, ".header")); err == nil {
|
||||||
|
write(w, string(header))
|
||||||
|
}
|
||||||
|
modified := true
|
||||||
|
if _, err := fs.Stat(h.FS, path.Join(p, ".modified")); err != nil {
|
||||||
|
modified = false
|
||||||
|
}
|
||||||
|
asc := false
|
||||||
|
if _, err := fs.Stat(h.FS, path.Join(p, ".desc")); err != nil {
|
||||||
|
asc = true
|
||||||
|
}
|
||||||
|
dirents, err := fs.ReadDir(h.FS, p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sort.Slice(dirents, func(i, j int) bool {
|
||||||
|
if modified {
|
||||||
|
st1, err := dirents[i].Info()
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
st2, err := dirents[j].Info()
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return st1.ModTime().After(st2.ModTime())
|
||||||
|
} else if asc {
|
||||||
|
return dirents[i].Name() < dirents[j].Name()
|
||||||
|
} else {
|
||||||
|
return dirents[i].Name() > dirents[j].Name()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
for _, entry := range dirents {
|
||||||
|
name := entry.Name()
|
||||||
|
if strings.HasPrefix(name, ".") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
i, err := entry.Info()
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if i.Mode()&(1<<2) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if entry.IsDir() {
|
||||||
|
name += "/"
|
||||||
|
}
|
||||||
|
if _, err := write(w, "=> "+name); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) Handle(p string, w io.Writer) error {
|
||||||
|
if p == "/" || p == "" {
|
||||||
|
p = "."
|
||||||
|
} else {
|
||||||
|
p = strings.Trim(p, "/")
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := h.FS.Open(p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
stat, err := f.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if stat.IsDir() {
|
||||||
|
index, err := h.FS.Open(path.Join(p, "index"))
|
||||||
|
if err != nil {
|
||||||
|
return h.handleDir(p, w)
|
||||||
|
}
|
||||||
|
defer index.Close()
|
||||||
|
f = index
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(w, f)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func serve(h *Handler, rw io.ReadWriteCloser) {
|
||||||
|
defer rw.Close()
|
||||||
|
scanner := bufio.NewScanner(rw)
|
||||||
|
scanner.Scan()
|
||||||
|
sel := scanner.Text()
|
||||||
|
if err := h.Handle(sel, rw); err != nil {
|
||||||
|
rw.Write([]byte("document not found"))
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func listenAndServe(h *Handler) error {
|
||||||
|
l, err := net.Listen("tcp", ":1900")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer l.Close()
|
||||||
|
|
||||||
|
for {
|
||||||
|
rw, err := l.Accept()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
go serve(h, rw)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if len(os.Args) < 2 {
|
||||||
|
log.Fatal("usage: nexd path")
|
||||||
|
}
|
||||||
|
|
||||||
|
h := Handler{FS: os.DirFS(os.Args[1])}
|
||||||
|
log.Fatal(listenAndServe(&h))
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue