Blob


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