1 /*
2 * accessdb.c: show every key/content pair in the database.
3 *
4 * Copyright (C) 1994, 1995 Graeme W. Wilford. (Wilf.)
5 * Copyright (C) 2002 Colin Watson.
6 *
7 * This file is part of man-db.
8 *
9 * man-db is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * man-db is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with man-db; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 *
23 * Tue Apr 26 12:56:44 BST 1994 Wilf. (G.Wilford@ee.surrey.ac.uk)
24 */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif /* HAVE_CONFIG_H */
29
30 #include <stdbool.h>
31 #include <stdio.h>
32 #include <errno.h>
33 #include <string.h>
34 #include <stdlib.h>
35
36 #include "argp.h"
37 #include "attribute.h"
38 #include "progname.h"
39 #include "xalloc.h"
40 #include "xvasprintf.h"
41
42 #include "gettext.h"
43 #define _(String) gettext (String)
44 #define N_(String) gettext_noop (String)
45
46 #include "manconfig.h"
47
48 #include "debug.h"
49 #include "fatal.h"
50 #include "util.h"
51
52 #include "mydbm.h"
53
54 const char *cat_root;
55
56 char *database;
57
58 const char *argp_program_version = "accessdb " PACKAGE_VERSION;
59 const char *argp_program_bug_address = PACKAGE_BUGREPORT;
60 error_t argp_err_exit_status = FAIL;
61
62 static const char args_doc[] = N_("[MAN DATABASE]");
63 static const char doc[] = "\v" N_("The man database defaults to %s%s.");
64
65 static struct argp_option options[] = {
66 OPT ("debug", 'd', 0, N_ ("emit debugging messages")),
67 OPT_HELP_COMPAT,
68 {0}
69 };
70
71 static error_t parse_opt (int key, char *arg, struct argp_state *state)
72 {
73 switch (key) {
74 case 'd':
75 debug_level = true;
76 return 0;
77 case 'h':
78 argp_state_help (state, state->out_stream,
79 ARGP_HELP_STD_HELP &
80 ~ARGP_HELP_PRE_DOC);
81 break;
82 case ARGP_KEY_ARG:
83 if (database)
84 argp_usage (state);
85 database = arg;
86 return 0;
87 case ARGP_KEY_NO_ARGS:
88 database = mkdbname (cat_root);
89 return 0;
90 }
91 return ARGP_ERR_UNKNOWN;
92 }
93
94 #pragma GCC diagnostic push
95 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
96 static char *help_filter (int key, const char *text, void *input MAYBE_UNUSED)
97 {
98 switch (key) {
99 case ARGP_KEY_HELP_PRE_DOC:
100 /* We have no pre-options help text, but the input
101 * text may contain header junk due to gettext ("").
102 */
103 return NULL;
104 case ARGP_KEY_HELP_POST_DOC:
105 return xasprintf (text, cat_root, MAN_DB);
106 default:
107 return (char *) text;
108 }
109 }
110 #pragma GCC diagnostic pop
111
112 static struct argp argp = { options, parse_opt, args_doc, doc, 0,
113 help_filter };
114
115 int main (int argc, char *argv[])
116 {
117 MYDBM_FILE dbf;
118 datum key;
119 int ret = OK;
120
121 set_program_name (argv[0]);
122
123 init_debug ();
124 init_locale ();
125
126 if (is_directory (FHS_CAT_ROOT) == 1)
127 cat_root = FHS_CAT_ROOT;
128 else if (is_directory (CAT_ROOT) == 1)
129 cat_root = CAT_ROOT;
130
131 if (argp_parse (&argp, argc, argv, 0, 0, 0))
132 exit (FAIL);
133
134 dbf = MYDBM_NEW (database);
135 if (!MYDBM_RDOPEN (dbf) || dbver_rd (dbf)) {
136 MYDBM_FREE (dbf);
137 dbf = NULL;
138 }
139 if (!dbf)
140 fatal (errno, _("can't open %s for reading"), database);
141
142 key = MYDBM_FIRSTKEY (dbf);
143
144 while (MYDBM_DPTR (key) != NULL) {
145 datum content, nextkey;
146 char *t, *nicekey;
147
148 content = MYDBM_FETCH (dbf, key);
149 if (!MYDBM_DPTR (content)) {
150 debug ("key %s has no content!\n", MYDBM_DPTR (key));
151 ret = FATAL;
152 goto next;
153 }
154 nicekey = xstrdup (MYDBM_DPTR (key));
155 while ( (t = strchr (nicekey, '\t')) )
156 *t = '~';
157 while ( (t = strchr (MYDBM_DPTR (content), '\t')) )
158 *t = ' ';
159 printf ("%s -> \"%s\"\n", nicekey, MYDBM_DPTR (content));
160 free (nicekey);
161 #pragma GCC diagnostic push
162 #if GNUC_PREREQ(10,0)
163 # pragma GCC diagnostic ignored "-Wanalyzer-double-free"
164 #endif
165 MYDBM_FREE_DPTR (content);
166 next:
167 nextkey = MYDBM_NEXTKEY (dbf, key);
168 MYDBM_FREE_DPTR (key);
169 #pragma GCC diagnostic pop
170 key = nextkey;
171 }
172
173 MYDBM_FREE (dbf);
174 exit (ret);
175 }