1 /* squat_dump.c -- SQUAT-based index dumping tool
2 *
3 * Copyright (c) 1994-2012 Carnegie Mellon University. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. The name "Carnegie Mellon University" must not be used to
18 * endorse or promote products derived from this software without
19 * prior written permission. For permission or any legal
20 * details, please contact
21 * Carnegie Mellon University
22 * Center for Technology Transfer and Enterprise Creation
23 * 4615 Forbes Avenue
24 * Suite 302
25 * Pittsburgh, PA 15213
26 * (412) 268-7393, fax: (412) 268-7395
27 * innovation@andrew.cmu.edu
28 *
29 * 4. Redistributions of any form whatsoever must retain the following
30 * acknowledgment:
31 * "This product includes software developed by Computing Services
32 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
33 *
34 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
35 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
36 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
37 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
38 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
39 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
40 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
41 */
42
43 /*
44 This tool dumps out a SQUAT index in various ways. It's useful
45 for debugging.
46
47 Currently hardcoded for SQUAT, doesn't use struct search_engine.
48 */
49
50 #include <config.h>
51
52 #ifdef HAVE_UNISTD_H
53 #include <unistd.h>
54 #endif
55 #include <stdlib.h>
56 #include <stdio.h>
57 #include <errno.h>
58 #include <sys/stat.h>
59 #include <sys/types.h>
60 #include <fcntl.h>
61 #include <sysexits.h>
62 #include <syslog.h>
63 #include <string.h>
64
65 #include "assert.h"
66 #include "global.h"
67 #include "xmalloc.h"
68 #include "xstrlcpy.h"
69 #include "xstrlcat.h"
70 #include "mboxlist.h"
71 #include "mailbox.h"
72 #include "mboxname.h"
73 #include "squat.h"
74 #include "util.h"
75
76 /* generated headers are not necessarily in current directory */
77 #include "imap/imap_err.h"
78
79 extern char *optarg;
80 extern int optind;
81
usage(const char * name)82 static int usage(const char *name)
83 {
84 fprintf(stderr,
85 "usage: %s [-C <alt_config>] mailbox [...]\n",
86 name);
87
88 exit(EX_USAGE);
89 }
90
squat_strerror(int err)91 static const char *squat_strerror(int err)
92 {
93 static char buf[64];
94
95 switch (err) {
96 case SQUAT_ERR_SYSERR:
97 return strerror(errno);
98 default:
99 /* There are other error codes, but they only apply for searching,
100 not index construction */
101 snprintf(buf, sizeof(buf), "unknown squat error %d", err);
102 return buf;
103 }
104 }
105
dump_doc(void * closure,const SquatListDoc * doc)106 static int dump_doc(void *closure __attribute__((unused)),
107 const SquatListDoc *doc)
108 {
109 printf("DOC %s %llu\n", doc->doc_name, doc->size);
110 return SQUAT_CALLBACK_CONTINUE;
111 }
112
113 /* This is called once for each mailbox we're told to dump. */
dump_one(char * name)114 static int dump_one(char *name)
115 {
116 struct mboxlist_entry *mbentry = NULL;
117 struct mailbox *mailbox = NULL;
118 int r;
119 int fd = -1;
120 SquatSearchIndex *index = NULL;
121 char *fname = NULL;
122
123 /* Skip remote mailboxes */
124 r = mboxlist_lookup(name, &mbentry, NULL);
125 if (r) {
126 fprintf(stderr, "error opening looking up %s: %s\n",
127 name, error_message(r));
128 return 1;
129 }
130
131 if (mbentry->mbtype & MBTYPE_REMOTE) {
132 mboxlist_entry_free(&mbentry);
133 return 0;
134 }
135
136 mboxlist_entry_free(&mbentry);
137
138 r = mailbox_open_irl(name, &mailbox);
139 if (r) {
140 fprintf(stderr, "error opening mailbox %s: %s\n",
141 name, error_message(r));
142 return 1;
143 }
144
145 fname = xstrdup(mailbox_meta_fname(mailbox, META_SQUAT));
146
147 mailbox_close(&mailbox);
148
149 fd = open(fname, O_RDONLY, 0);
150 if (fd < 0) {
151 fprintf(stderr, "error opening file %s: %s\n",
152 fname, error_message(errno));
153 goto out;
154 }
155
156 index = squat_search_open(fd);
157 if (index == NULL) {
158 fprintf(stderr, "error opening index %s: %s\n",
159 fname, squat_strerror(squat_get_last_error()));
160 goto out;
161 }
162
163 printf("MAILBOX %s\n", name);
164
165 r = squat_search_list_docs(index, dump_doc, NULL);
166 if (r != SQUAT_OK) {
167 fprintf(stderr, "error listing index %s: %s\n",
168 fname, squat_strerror(r));
169 goto out;
170 }
171
172 out:
173 if (fd >= 0) close(fd);
174 if (index != NULL) squat_search_close(index);
175 free(fname);
176 return 0;
177 }
178
main(int argc,char ** argv)179 int main(int argc, char **argv)
180 {
181 int opt;
182 char *alt_config = NULL;
183 int i;
184
185 while ((opt = getopt(argc, argv, "C:")) != EOF) {
186 switch (opt) {
187 case 'C': /* alt config file */
188 alt_config = optarg;
189 break;
190
191 default:
192 usage(argv[0]);
193 }
194 }
195
196 cyrus_init(alt_config, "squat_dump", 0, CONFIG_NEED_PARTITION_DATA);
197
198 if (optind == argc)
199 usage(argv[0]);
200
201 for (i = optind; i < argc; i++)
202 dump_one(argv[i]);
203
204 cyrus_done();
205
206 return 0;
207 }
208