Blame


1 e2b5610c 2022-04-11 op /*
2 c00beb4f 2022-04-14 op * Copyright (c) 2022 Omar Polo <op@omarpolo.com>
3 e2b5610c 2022-04-11 op *
4 e2b5610c 2022-04-11 op * Permission to use, copy, modify, and distribute this software for any
5 e2b5610c 2022-04-11 op * purpose with or without fee is hereby granted, provided that the above
6 e2b5610c 2022-04-11 op * copyright notice and this permission notice appear in all copies.
7 e2b5610c 2022-04-11 op *
8 e2b5610c 2022-04-11 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 e2b5610c 2022-04-11 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 e2b5610c 2022-04-11 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 e2b5610c 2022-04-11 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 e2b5610c 2022-04-11 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 e2b5610c 2022-04-11 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 e2b5610c 2022-04-11 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 e2b5610c 2022-04-11 op */
16 e2b5610c 2022-04-11 op
17 e2b5610c 2022-04-11 op #include <err.h>
18 e2b5610c 2022-04-11 op #include <fcntl.h>
19 e2b5610c 2022-04-11 op #include <limits.h>
20 e2b5610c 2022-04-11 op #include <stdio.h>
21 e2b5610c 2022-04-11 op #include <stdlib.h>
22 e2b5610c 2022-04-11 op #include <unistd.h>
23 e2b5610c 2022-04-11 op
24 e2b5610c 2022-04-11 op #include "db.h"
25 e2b5610c 2022-04-11 op #include "fts.h"
26 e2b5610c 2022-04-11 op #include "tokenize.h"
27 e2b5610c 2022-04-11 op
28 e2b5610c 2022-04-11 op const char *dbpath;
29 e2b5610c 2022-04-11 op
30 e2b5610c 2022-04-11 op static void __dead
31 e2b5610c 2022-04-11 op usage(void)
32 e2b5610c 2022-04-11 op {
33 e2b5610c 2022-04-11 op fprintf(stderr, "usage: %s [-d db] -l | -s | query",
34 e2b5610c 2022-04-11 op getprogname());
35 e2b5610c 2022-04-11 op exit(1);
36 e2b5610c 2022-04-11 op }
37 e2b5610c 2022-04-11 op
38 e2b5610c 2022-04-11 op static int
39 e2b5610c 2022-04-11 op print_entry(struct db *db, struct db_entry *entry, void *data)
40 e2b5610c 2022-04-11 op {
41 e2b5610c 2022-04-11 op printf("%-18s %s\n", entry->name, entry->descr);
42 e2b5610c 2022-04-11 op return 0;
43 e2b5610c 2022-04-11 op }
44 e2b5610c 2022-04-11 op
45 e2b5610c 2022-04-11 op int
46 e2b5610c 2022-04-11 op main(int argc, char **argv)
47 e2b5610c 2022-04-11 op {
48 e2b5610c 2022-04-11 op struct db db;
49 e2b5610c 2022-04-11 op const char *errstr;
50 e2b5610c 2022-04-11 op int fd, ch;
51 e2b5610c 2022-04-11 op int list = 0, stats = 0, docid = -1;
52 e2b5610c 2022-04-11 op
53 e2b5610c 2022-04-11 op while ((ch = getopt(argc, argv, "d:lp:s")) != -1) {
54 e2b5610c 2022-04-11 op switch (ch) {
55 e2b5610c 2022-04-11 op case 'd':
56 e2b5610c 2022-04-11 op dbpath = optarg;
57 e2b5610c 2022-04-11 op break;
58 e2b5610c 2022-04-11 op case 'l':
59 e2b5610c 2022-04-11 op list = 1;
60 e2b5610c 2022-04-11 op break;
61 e2b5610c 2022-04-11 op case 'p':
62 e2b5610c 2022-04-11 op docid = strtonum(optarg, 0, INT_MAX, &errstr);
63 e2b5610c 2022-04-11 op if (errstr != NULL)
64 e2b5610c 2022-04-11 op errx(1, "document id is %s: %s", errstr,
65 e2b5610c 2022-04-11 op optarg);
66 e2b5610c 2022-04-11 op break;
67 e2b5610c 2022-04-11 op case 's':
68 e2b5610c 2022-04-11 op stats = 1;
69 e2b5610c 2022-04-11 op break;
70 e2b5610c 2022-04-11 op default:
71 e2b5610c 2022-04-11 op usage();
72 e2b5610c 2022-04-11 op }
73 e2b5610c 2022-04-11 op }
74 e2b5610c 2022-04-11 op argc -= optind;
75 e2b5610c 2022-04-11 op argv += optind;
76 e2b5610c 2022-04-11 op
77 e2b5610c 2022-04-11 op if (dbpath == NULL)
78 e2b5610c 2022-04-11 op dbpath = "db";
79 e2b5610c 2022-04-11 op
80 e2b5610c 2022-04-11 op if (list && stats)
81 e2b5610c 2022-04-11 op usage();
82 e2b5610c 2022-04-11 op
83 e2b5610c 2022-04-11 op if ((fd = open(dbpath, O_RDONLY)) == -1)
84 e2b5610c 2022-04-11 op err(1, "can't open %s", dbpath);
85 e2b5610c 2022-04-11 op
86 e2b5610c 2022-04-11 op if (pledge("stdio", NULL) == -1)
87 e2b5610c 2022-04-11 op err(1, "pledge");
88 e2b5610c 2022-04-11 op
89 e2b5610c 2022-04-11 op if (db_open(&db, fd) == -1)
90 e2b5610c 2022-04-11 op err(1, "db_open");
91 e2b5610c 2022-04-11 op
92 e2b5610c 2022-04-11 op if (list) {
93 e2b5610c 2022-04-11 op if (db_listall(&db, print_entry, NULL) == -1)
94 e2b5610c 2022-04-11 op err(1, "db_listall");
95 e2b5610c 2022-04-11 op } else if (stats) {
96 e2b5610c 2022-04-11 op struct db_stats st;
97 e2b5610c 2022-04-11 op
98 e2b5610c 2022-04-11 op if (db_stats(&db, &st) == -1)
99 e2b5610c 2022-04-11 op err(1, "db_stats");
100 e2b5610c 2022-04-11 op printf("unique words = %zu\n", st.nwords);
101 e2b5610c 2022-04-11 op printf("documents = %zu\n", st.ndocs);
102 e2b5610c 2022-04-11 op printf("longest word = %s\n", st.longest_word);
103 e2b5610c 2022-04-11 op printf("most popular = %s (%zu)\n", st.most_popular,
104 e2b5610c 2022-04-11 op st.most_popular_ndocs);
105 e2b5610c 2022-04-11 op } else if (docid != -1) {
106 e2b5610c 2022-04-11 op struct db_entry e;
107 e2b5610c 2022-04-11 op
108 e2b5610c 2022-04-11 op if (db_doc_by_id(&db, docid, &e) == -1)
109 e2b5610c 2022-04-11 op errx(1, "failed to fetch document #%d", docid);
110 e2b5610c 2022-04-11 op print_entry(&db, &e, NULL);
111 e2b5610c 2022-04-11 op } else {
112 e2b5610c 2022-04-11 op if (argc != 1)
113 e2b5610c 2022-04-11 op usage();
114 e2b5610c 2022-04-11 op if (fts(&db, *argv, print_entry, NULL) == -1)
115 e2b5610c 2022-04-11 op errx(1, "fts failed");
116 e2b5610c 2022-04-11 op }
117 e2b5610c 2022-04-11 op
118 e2b5610c 2022-04-11 op db_close(&db);
119 e2b5610c 2022-04-11 op close(fd);
120 e2b5610c 2022-04-11 op }