package main import ( "bufio" "fmt" "html/template" //"net/http" // "net/http/cgi" "os" "os/exec" "strings" "time" ) type Result struct { Name string Version string URL string Suite string } type ResultPage struct { Query string Release string NumResults int Time string Results []Result } var resTempl = ` i | _) _| Err pkginfo.devuan.org 70 i __ \ | / _' | | __ \ | _ \ Err pkginfo.devuan.org 70 i | | < ( | | | | __| ( | Err pkginfo.devuan.org 70 i .__/ _|\_\ \__, | _| _| _| _| \___/ Err pkginfo.devuan.org 70 i _| |___/ Err pkginfo.devuan.org 70 i Err pkginfo.devuan.org 70 i Devuan Package information Err pkginfo.devuan.org 70 i Err pkginfo.devuan.org 70 i {{.NumResults}} results for "{{.Query}}" (in {{.Time}}) Err pkginfo.devuan.org 70 i -------------------------- Err pkginfo.devuan.org 70 {{range .Results}} 1 {{.Suite}}] {{.Name}}-{{.Version}} {{URL}} pkginfo.devuan.org 70 {{end}} ` var releaseMap = map[string]string{ "jessie": "index_jessie.txt", "ascii": "index_ascii.txt", "beowulf": "index_beowulf.txt", "ceres": "index_ceres.txt", "experimental": "index_experimental.txt", "any": "index.txt"} func printError(errCode int, errMsg string) { fmt.Printf("Status:%d %s\r\n", errCode, errMsg) fmt.Printf("Content-Type: text/plain\r\n") fmt.Printf("\r\n%s\r\n", errMsg) } func parseLines(s string) []Result { results := make([]Result, 0, 10) scanner := bufio.NewScanner(strings.NewReader(s)) for scanner.Scan() { URL := scanner.Text() URLParts := strings.Split(URL, "/")[1:] pkgNameVer := strings.Split(URLParts[len(URLParts)-1], ".html")[0] Name := strings.Split(pkgNameVer, "_")[0] Version := strings.Split(pkgNameVer, "_")[1] Suite := URLParts[2] results = append(results, Result{URL: URL, Name: Name, Version: Version, Suite: Suite}) } //fmt.Printf("len(results): %d\n", resSize) return results } func pipeComands(commands []*exec.Cmd) ([]byte, error) { for i, command := range commands[:len(commands)-1] { out, err := command.StdoutPipe() if err != nil { return nil, err } command.Start() commands[i+1].Stdin = out } final, err := commands[len(commands)-1].Output() if err != nil { return nil, err } return final, nil } func getResults() (ResultPage, error) { var res ResultPage var release string searchQuery := os.Getenv("X_GOPHER_SEARCH") if len(searchQuery) < 1 { printError(503, fmt.Sprintf("Something went wrong in parsing query...\r\n")) os.Exit(0) } res.Query = searchQuery QueryTerms := strings.Split(res.Query, " ") res.Release = "any" fmt.Printf("QueryTerms: %s\n", QueryTerms) startTime := time.Now() commands := make([]*exec.Cmd, 0) cmd := "grep" args := []string{QueryTerms[0], releaseMap[release]} commands = append(commands, exec.Command(cmd, args...)) for _, word := range QueryTerms[1:] { args = []string{word} fmt.Printf("word: %s\r\n", word) commands = append(commands, exec.Command(cmd, args...)) } //if cmdOut, err := exec.Command(cmd, args...).Output(); err != nil { if cmdOut, err := pipeComands(commands); err != nil { fmt.Printf("error executing command: %s %s", commands, err) res.Time = fmt.Sprintf("%s", time.Since(startTime)) return res, nil } else { res.Results = parseLines(string(cmdOut[:len(cmdOut)])) res.NumResults = len(res.Results) res.Time = fmt.Sprintf("%s", time.Since(startTime)) } return res, nil } func printResults(results ResultPage) { t, err := template.New("webpage").Parse(resTempl) if err != nil { printError(502, "Something went wrong...") return } //fmt.Printf("Status: 200 OK\r\n") //fmt.Printf("Content-Type: text/html\r\n") t.Execute(os.Stdout, results) } func main() { var err error res, err := getResults() if err != nil { printError(404, fmt.Sprintf("%s", err)) } else { printResults(res) } }