aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Duncan <pabs@pablotron.org>2022-02-27 05:02:05 -0500
committerPaul Duncan <pabs@pablotron.org>2022-02-27 05:02:05 -0500
commit92c3256b7127b7a494d6f11a94e0ffebc0fc85a5 (patch)
tree6db67c8c8950c9d1376f1316f23dd51d5c160f56
parent163666e3966058e906b9d19687da9acc62158232 (diff)
downloadcvez-92c3256b7127b7a494d6f11a94e0ffebc0fc85a5.tar.bz2
cvez-92c3256b7127b7a494d6f11a94e0ffebc0fc85a5.zip
add datadir and cmd/search.go
-rw-r--r--cmd/search.go76
-rw-r--r--datadir/datadir.go48
2 files changed, 124 insertions, 0 deletions
diff --git a/cmd/search.go b/cmd/search.go
new file mode 100644
index 0000000..ba831df
--- /dev/null
+++ b/cmd/search.go
@@ -0,0 +1,76 @@
+package cmd
+
+import (
+ "context"
+ "encoding/json"
+ "github.com/pablotron/cvez/datadir"
+ "github.com/pablotron/cvez/dbstore"
+ "github.com/spf13/cobra"
+ "github.com/rs/zerolog"
+ "github.com/rs/zerolog/log"
+ "os"
+ "strings"
+ "time"
+)
+
+// Build query string.
+func getSearchQuery(args []string) string {
+ r := make([]string, len(args))
+
+ for i, v := range(args) {
+ r[i] = "\"" + strings.ReplaceAll(strings.ToLower(v), "\"", "\"\"") + "\""
+ }
+
+ return strings.Join(r, " AND ")
+}
+
+// Get database store.
+func getDb() dbstore.DbStore {
+ // build database path
+ dbPath, err := datadir.Join("cvez.db")
+ if err != nil {
+ log.Error().Err(err).Msg("Join")
+ os.Exit(-1)
+ }
+
+ // open database
+ db, err := dbstore.Open(dbPath)
+ if err != nil {
+ log.Error().Err(err).Msg("Open")
+ os.Exit(-1)
+ }
+
+ return db
+}
+
+var searchCmd = &cobra.Command{
+ Use: "search",
+ Args: cobra.MinimumNArgs(1),
+ Short: "Search CVEs.",
+ Long: `Common Vulnerability Enumeration (CVE) search.`,
+
+ Run: func(cmd *cobra.Command, args []string) {
+ ctx := context.Background()
+
+ // set global logging options
+ zerolog.TimeFieldFormat = time.RFC3339
+ zerolog.SetGlobalLevel(zerolog.InfoLevel)
+
+ // search for CVEs
+ rows, err := getDb().CveSearch(ctx, getSearchQuery(args))
+ if err != nil {
+ log.Error().Err(err).Msg("CveSearch")
+ os.Exit(-1)
+ }
+
+ // search for CVEs, write result
+ e := json.NewEncoder(os.Stdout)
+ if err := e.Encode(rows); err != nil {
+ log.Error().Err(err).Msg("Encode")
+ }
+ },
+}
+
+func init() {
+ rootCmd.AddCommand(searchCmd)
+}
diff --git a/datadir/datadir.go b/datadir/datadir.go
new file mode 100644
index 0000000..9019e5d
--- /dev/null
+++ b/datadir/datadir.go
@@ -0,0 +1,48 @@
+// data directory
+package datadir
+
+import (
+ "errors"
+ "io/fs"
+ "os"
+ "path/filepath"
+)
+
+// Get data directory path.
+func DataDir() (string, error) {
+ var dir string
+
+ // check environment
+ if val, ok := os.LookupEnv("CVEZ_DATA_DIR"); ok {
+ return val, nil
+ }
+
+ // get config dir
+ configDir, err := os.UserConfigDir()
+ if err != nil {
+ return dir, err
+ }
+
+ // build path to data directory in config dir
+ dir = filepath.Join(configDir, "cvez")
+ if _, err = os.Stat(dir); err != nil {
+ if errors.Is(err, fs.ErrNotExist) {
+ // create data directory
+ return dir, os.MkdirAll(dir, 0700)
+ } else {
+ // return error
+ return "", err
+ }
+ } else {
+ return dir, nil
+ }
+}
+
+// Build path to file in cvez data directory.
+func Join(args ...string) (string, error) {
+ if dir, err := DataDir(); err != nil {
+ return "", err
+ } else {
+ return filepath.Join(dir, filepath.Join(args...)), nil
+ }
+}