diff --git a/cmd/root.go b/cmd/root.go index 8deeac5..a17b584 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -5,13 +5,14 @@ Copyright © 2022 Seednode package cmd import ( - "log" + "fmt" "github.com/spf13/cobra" ) var Port int var Recursive bool +var Verbose bool var rootCmd = &cobra.Command{ Use: "roulette [path2] ... [pathN]", @@ -26,12 +27,14 @@ var rootCmd = &cobra.Command{ func Execute() { err := rootCmd.Execute() if err != nil { - log.Fatal(err) + fmt.Println(err) + panic(Exit{1}) } } func init() { rootCmd.Flags().IntVarP(&Port, "port", "p", 8080, "port to listen on") rootCmd.Flags().BoolVarP(&Recursive, "recursive", "r", false, "recurse into subdirectories") + rootCmd.Flags().BoolVarP(&Verbose, "verbose", "v", false, "also write output to stdout") rootCmd.Flags().SetInterspersed(false) } diff --git a/cmd/utils.go b/cmd/utils.go new file mode 100644 index 0000000..8c2bb29 --- /dev/null +++ b/cmd/utils.go @@ -0,0 +1,102 @@ +/* +Copyright © 2022 Seednode +*/ + +package cmd + +import ( + "bufio" + "os" + "strings" +) + +type Exit struct{ Code int } + +func Chunks(s string, chunkSize int) []string { + if len(s) == 0 { + return nil + } + + if chunkSize >= len(s) { + return []string{s} + } + + var chunks []string = make([]string, 0, (len(s)-1)/chunkSize+1) + + currentLen := 0 + currentStart := 0 + + for i := range s { + if currentLen == chunkSize { + chunks = append(chunks, s[currentStart:i]) + currentLen = 0 + currentStart = i + } + + currentLen++ + } + + chunks = append(chunks, s[currentStart:]) + + return chunks +} + +func CollectOutputs(output chan string, outputs chan<- []string) { + o := []string{} + + for r := range output { + o = append(o, r) + } + + outputs <- o + + close(outputs) +} + +func FirstN(s string, n int) string { + i := 0 + for j := range s { + if i == n { + return s[:j] + } + i++ + } + return s +} + +func HandleExit() { + if e := recover(); e != nil { + if exit, ok := e.(Exit); ok == true { + os.Exit(exit.Code) + } + panic(e) + } +} + +func ScanFile(dbfile string) (func(), *bufio.Scanner, error) { + readFile, err := os.Open(dbfile) + if err != nil { + return func() {}, nil, err + } + + fileScanner := bufio.NewScanner(readFile) + buffer := make([]byte, 0, 64*1024) + fileScanner.Buffer(buffer, 1024*1024) + + return func() { _ = readFile.Close() }, fileScanner, nil +} + +func Strip(s string) string { + var result strings.Builder + for i := 0; i < len(s); i++ { + b := s[i] + + if ('a' <= b && b <= 'z') || + ('A' <= b && b <= 'Z') || + ('0' <= b && b <= '9') { + result.WriteByte(b) + } + } + + return result.String() +} diff --git a/cmd/version.go b/cmd/version.go index c5eb350..8fc183c 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -10,7 +10,7 @@ import ( "github.com/spf13/cobra" ) -var Version = "0.1.1" +var Version = "0.1.0" func init() { rootCmd.AddCommand(versionCmd) diff --git a/cmd/web.go b/cmd/web.go index 2270853..a7b306f 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -16,17 +16,6 @@ import ( "strings" ) -type Exit struct{ Code int } - -func HandleExit() { - if e := recover(); e != nil { - if exit, ok := e.(Exit); ok == true { - os.Exit(exit.Code) - } - panic(e) - } -} - func generatePageHtml(w http.ResponseWriter, paths []string) error { fileList, err := getFileList(paths) if err != nil { @@ -71,6 +60,20 @@ func statusNotFound(w http.ResponseWriter, filePath string) error { return nil } +func statusForbidden(w http.ResponseWriter, filePath string) error { + fmt.Println("Client requested forbidden file " + filePath + ".") + + w.WriteHeader(http.StatusForbidden) + w.Header().Set("Content-Type", "txt/plain") + htmlBody := "Access denied." + _, err := io.WriteString(w, htmlBody) + if err != nil { + return err + } + + return nil +} + func serveStaticFile(w http.ResponseWriter, request string, paths []string) error { filePath, err := url.QueryUnescape(request) if err != nil {