1 /* chk_cyrus.c: cyrus mailstore consistency checker
2 *
3 * Copyright (c) 1994-2008 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 #include <config.h>
44
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <sysexits.h>
49 #include <sys/types.h>
50 #include <sys/stat.h>
51 #include <sys/mman.h>
52 #include <fcntl.h>
53 #include <netinet/in.h>
54 #include <limits.h>
55 #ifdef HAVE_UNISTD_H
56 #include <unistd.h>
57 #endif
58
59 #include "index.h"
60 #include "global.h"
61 #include "mboxlist.h"
62 #include "mailbox.h"
63 #include "map.h"
64 #include "xmalloc.h"
65
usage(void)66 static void usage(void)
67 {
68 fprintf(stderr, "chk_cyrus [-C <altconfig>] partition\n");
69 exit(-1);
70 }
71
72 static const char *check_part = NULL; /* partition we are checking */
73
chkmbox(struct findall_data * data,void * rock)74 static int chkmbox(struct findall_data *data, void *rock __attribute__((unused)))
75 {
76 if (!data) return 0;
77 if (!data->is_exactmatch) return 0;
78 int r;
79 mbentry_t *mbentry = NULL;
80 const char *name = mbname_intname(data->mbname);
81
82 r = mboxlist_lookup(name, &mbentry, NULL);
83
84 /* xxx reserved mailboxes? */
85
86 if (r) {
87 fprintf(stderr, "bad mailbox %s in chkmbox\n", name);
88 fatal("fatal error",EX_TEMPFAIL);
89 }
90
91 /* are we on the partition we are checking? */
92 if (check_part && strcmp(mbentry->partition, check_part)) {
93 mboxlist_entry_free(&mbentry);
94 return 0;
95 }
96
97 fprintf(stderr, "checking: %s\n", name);
98
99 mailbox_reconstruct(name, 0); /* no changes allowed */
100
101 mboxlist_entry_free(&mbentry);
102
103 return 0;
104 }
105
main(int argc,char ** argv)106 int main(int argc, char **argv)
107 {
108 char *alt_config = NULL;
109 char pattern[2] = { '*', '\0' };
110 const char *mailbox = NULL;
111
112 extern char *optarg;
113 int opt;
114
115 while ((opt = getopt(argc, argv, "C:P:M:")) != EOF) {
116 switch (opt) {
117 case 'C': /* alt config file */
118 alt_config = optarg;
119 break;
120
121 case 'P':
122 if(mailbox) {
123 usage();
124 exit(EX_USAGE);
125 }
126 check_part = optarg;
127 break;
128
129 case 'M':
130 if(check_part) {
131 usage();
132 exit(EX_USAGE);
133 }
134 mailbox = optarg;
135 break;
136
137 default:
138 usage();
139 /* NOTREACHED */
140 }
141 }
142
143 cyrus_init(alt_config, "chk_cyrus", 0, CONFIG_NEED_PARTITION_DATA);
144
145 if(mailbox) {
146 fprintf(stderr, "Examining mailbox: %s\n", mailbox);
147 mboxlist_findone(NULL, mailbox, 1, NULL,
148 NULL, chkmbox, NULL);
149 } else {
150 fprintf(stderr, "Examining partition: %s\n",
151 (check_part ? check_part : "ALL PARTITIONS"));
152
153 /* build a list of mailboxes - we're using internal names here */
154 mboxlist_findall(NULL, pattern, 1, NULL,
155 NULL, chkmbox, NULL);
156 }
157
158 cyrus_done();
159
160 return 0;
161 }
162