Mercurial > dovecot > core-2.2
comparison src/doveadm/doveadm-mail-mailbox-status.c @ 12550:2c299c0e3bc8
lib-storage: Moved some items from mailbox_get_status() to a new mailbox_get_metadata().
The idea is now that all status items are tracked all the time after mailbox
is opened and they can always be looked up without failure. The metadata
items are looked up lazily and the lookups may fail at any time.
mailbox_get_status() can be used after mailbox_alloc() to indicate that the
mailbox doesn't necessarily have to be opened, just that the status fields
get returned.
If mailbox is already known to be open, mailbox_get_open_status() can be
used. It never fails.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 01 Jan 2011 15:52:39 +0200 |
parents | bbfa924bc4bc |
children | 02370eda76f8 |
comparison
equal
deleted
inserted
replaced
12549:bbfa924bc4bc | 12550:2c299c0e3bc8 |
---|---|
10 #include "doveadm-mail-list-iter.h" | 10 #include "doveadm-mail-list-iter.h" |
11 | 11 |
12 #define ALL_STATUS_ITEMS \ | 12 #define ALL_STATUS_ITEMS \ |
13 (STATUS_MESSAGES | STATUS_RECENT | \ | 13 (STATUS_MESSAGES | STATUS_RECENT | \ |
14 STATUS_UIDNEXT | STATUS_UIDVALIDITY | \ | 14 STATUS_UIDNEXT | STATUS_UIDVALIDITY | \ |
15 STATUS_UNSEEN | STATUS_HIGHESTMODSEQ | STATUS_VIRTUAL_SIZE) | 15 STATUS_UNSEEN | STATUS_HIGHESTMODSEQ) |
16 #define ALL_METADATA_ITEMS \ | |
17 (MAILBOX_METADATA_VIRTUAL_SIZE | MAILBOX_METADATA_GUID) | |
16 | 18 |
17 #define TOTAL_STATUS_ITEMS \ | 19 #define TOTAL_STATUS_ITEMS \ |
18 (STATUS_MESSAGES | STATUS_RECENT | STATUS_UNSEEN | STATUS_VIRTUAL_SIZE) | 20 (STATUS_MESSAGES | STATUS_RECENT | STATUS_UNSEEN) |
21 #define TOTAL_METADATA_ITEMS \ | |
22 (MAILBOX_METADATA_VIRTUAL_SIZE) | |
19 | 23 |
20 struct status_cmd_context { | 24 struct status_cmd_context { |
21 struct doveadm_mail_cmd_context ctx; | 25 struct doveadm_mail_cmd_context ctx; |
22 struct mail_search_args *search_args; | 26 struct mail_search_args *search_args; |
23 enum mailbox_status_items items; | 27 |
28 enum mailbox_status_items status_items; | |
29 enum mailbox_metadata_items metadata_items; | |
24 struct mailbox_status total_status; | 30 struct mailbox_status total_status; |
25 | 31 struct mailbox_metadata total_metadata; |
26 unsigned int guid:1; | 32 |
27 unsigned int total_sum:1; | 33 unsigned int total_sum:1; |
28 }; | 34 }; |
29 | 35 |
30 static void status_parse_fields(struct status_cmd_context *ctx, | 36 static void status_parse_fields(struct status_cmd_context *ctx, |
31 const char *const *fields) | 37 const char *const *fields) |
35 | 41 |
36 for (; *fields != NULL; fields++) { | 42 for (; *fields != NULL; fields++) { |
37 const char *field = *fields; | 43 const char *field = *fields; |
38 | 44 |
39 if (strcmp(field, "all") == 0) { | 45 if (strcmp(field, "all") == 0) { |
40 if (ctx->total_sum) | 46 if (ctx->total_sum) { |
41 ctx->items |= TOTAL_STATUS_ITEMS; | 47 ctx->status_items |= TOTAL_STATUS_ITEMS; |
42 else { | 48 ctx->metadata_items |= TOTAL_METADATA_ITEMS; |
43 ctx->items |= ALL_STATUS_ITEMS; | 49 } else { |
44 ctx->guid = TRUE; | 50 ctx->status_items |= ALL_STATUS_ITEMS; |
51 ctx->metadata_items |= ALL_METADATA_ITEMS; | |
45 } | 52 } |
46 } else if (strcmp(field, "messages") == 0) | 53 } else if (strcmp(field, "messages") == 0) |
47 ctx->items |= STATUS_MESSAGES; | 54 ctx->status_items |= STATUS_MESSAGES; |
48 else if (strcmp(field, "recent") == 0) | 55 else if (strcmp(field, "recent") == 0) |
49 ctx->items |= STATUS_RECENT; | 56 ctx->status_items |= STATUS_RECENT; |
50 else if (strcmp(field, "uidnext") == 0) | 57 else if (strcmp(field, "uidnext") == 0) |
51 ctx->items |= STATUS_UIDNEXT; | 58 ctx->status_items |= STATUS_UIDNEXT; |
52 else if (strcmp(field, "uidvalidity") == 0) | 59 else if (strcmp(field, "uidvalidity") == 0) |
53 ctx->items |= STATUS_UIDVALIDITY; | 60 ctx->status_items |= STATUS_UIDVALIDITY; |
54 else if (strcmp(field, "unseen") == 0) | 61 else if (strcmp(field, "unseen") == 0) |
55 ctx->items |= STATUS_UNSEEN; | 62 ctx->status_items |= STATUS_UNSEEN; |
56 else if (strcmp(field, "highestmodseq") == 0) | 63 else if (strcmp(field, "highestmodseq") == 0) |
57 ctx->items |= STATUS_HIGHESTMODSEQ; | 64 ctx->status_items |= STATUS_HIGHESTMODSEQ; |
58 else if (strcmp(field, "vsize") == 0) | 65 else if (strcmp(field, "vsize") == 0) |
59 ctx->items |= STATUS_VIRTUAL_SIZE; | 66 ctx->metadata_items |= MAILBOX_METADATA_VIRTUAL_SIZE; |
60 else if (strcmp(field, "guid") == 0) | 67 else if (strcmp(field, "guid") == 0) |
61 ctx->guid = TRUE; | 68 ctx->metadata_items |= MAILBOX_METADATA_GUID; |
62 else | 69 else |
63 i_fatal("Unknown status field: %s", field); | 70 i_fatal("Unknown status field: %s", field); |
64 | 71 |
65 if (ctx->total_sum && | 72 if (ctx->total_sum && |
66 ((ctx->items & ~TOTAL_STATUS_ITEMS) != 0 || ctx->guid)) | 73 ((ctx->status_items & ~TOTAL_STATUS_ITEMS) != 0 || |
74 (ctx->metadata_items & ~TOTAL_METADATA_ITEMS) != 0)) | |
67 i_fatal("Status field %s can't be used with -t", field); | 75 i_fatal("Status field %s can't be used with -t", field); |
68 } | 76 } |
69 } | 77 } |
70 | 78 |
71 static void status_output(struct status_cmd_context *ctx, struct mailbox *box, | 79 static void status_output(struct status_cmd_context *ctx, struct mailbox *box, |
72 const struct mailbox_status *status, | 80 const struct mailbox_status *status, |
73 uint8_t mailbox_guid[MAIL_GUID_128_SIZE]) | 81 const struct mailbox_metadata *metadata) |
74 { | 82 { |
75 string_t *name; | 83 string_t *name; |
76 | 84 |
77 if (box != NULL) { | 85 if (box != NULL) { |
78 name = t_str_new(128); | 86 name = t_str_new(128); |
81 str_append(name, mailbox_get_vname(box)); | 89 str_append(name, mailbox_get_vname(box)); |
82 } | 90 } |
83 doveadm_print(str_c(name)); | 91 doveadm_print(str_c(name)); |
84 } | 92 } |
85 | 93 |
86 if ((ctx->items & STATUS_MESSAGES) != 0) | 94 if ((ctx->status_items & STATUS_MESSAGES) != 0) |
87 doveadm_print_num(status->messages); | 95 doveadm_print_num(status->messages); |
88 if ((ctx->items & STATUS_RECENT) != 0) | 96 if ((ctx->status_items & STATUS_RECENT) != 0) |
89 doveadm_print_num(status->recent); | 97 doveadm_print_num(status->recent); |
90 if ((ctx->items & STATUS_UIDNEXT) != 0) | 98 if ((ctx->status_items & STATUS_UIDNEXT) != 0) |
91 doveadm_print_num(status->uidnext); | 99 doveadm_print_num(status->uidnext); |
92 if ((ctx->items & STATUS_UIDVALIDITY) != 0) | 100 if ((ctx->status_items & STATUS_UIDVALIDITY) != 0) |
93 doveadm_print_num(status->uidvalidity); | 101 doveadm_print_num(status->uidvalidity); |
94 if ((ctx->items & STATUS_UNSEEN) != 0) | 102 if ((ctx->status_items & STATUS_UNSEEN) != 0) |
95 doveadm_print_num(status->unseen); | 103 doveadm_print_num(status->unseen); |
96 if ((ctx->items & STATUS_HIGHESTMODSEQ) != 0) | 104 if ((ctx->status_items & STATUS_HIGHESTMODSEQ) != 0) |
97 doveadm_print_num(status->highest_modseq); | 105 doveadm_print_num(status->highest_modseq); |
98 if ((ctx->items & STATUS_VIRTUAL_SIZE) != 0) | 106 if ((ctx->metadata_items & MAILBOX_METADATA_VIRTUAL_SIZE) != 0) |
99 doveadm_print_num(status->virtual_size); | 107 doveadm_print_num(metadata->virtual_size); |
100 if (ctx->guid) | 108 if ((ctx->metadata_items & MAILBOX_METADATA_GUID) != 0) |
101 doveadm_print(mail_guid_128_to_string(mailbox_guid)); | 109 doveadm_print(mail_guid_128_to_string(metadata->guid)); |
102 } | 110 } |
103 | 111 |
104 static void | 112 static void |
105 status_sum(struct status_cmd_context *ctx, | 113 status_sum(struct status_cmd_context *ctx, |
106 const struct mailbox_status *status) | 114 const struct mailbox_status *status, |
115 const struct mailbox_metadata *metadata) | |
107 { | 116 { |
108 struct mailbox_status *dest = &ctx->total_status; | 117 struct mailbox_status *dest = &ctx->total_status; |
109 | 118 |
110 dest->messages += status->messages; | 119 dest->messages += status->messages; |
111 dest->recent += status->recent; | 120 dest->recent += status->recent; |
112 dest->unseen += status->unseen; | 121 dest->unseen += status->unseen; |
113 dest->virtual_size += status->virtual_size; | 122 ctx->total_metadata.virtual_size += metadata->virtual_size; |
114 } | 123 } |
115 | 124 |
116 static void | 125 static void |
117 status_mailbox(struct status_cmd_context *ctx, const struct mailbox_info *info) | 126 status_mailbox(struct status_cmd_context *ctx, const struct mailbox_info *info) |
118 { | 127 { |
119 struct mailbox *box; | 128 struct mailbox *box; |
120 struct mailbox_status status; | 129 struct mailbox_status status; |
121 uint8_t mailbox_guid[MAIL_GUID_128_SIZE]; | 130 struct mailbox_metadata metadata; |
122 string_t *mailbox_name = t_str_new(128); | 131 string_t *mailbox_name = t_str_new(128); |
123 | 132 |
124 if (imap_utf7_to_utf8(info->name, mailbox_name) < 0) { | 133 if (imap_utf7_to_utf8(info->name, mailbox_name) < 0) { |
125 str_truncate(mailbox_name, 0); | 134 str_truncate(mailbox_name, 0); |
126 str_append(mailbox_name, info->name); | 135 str_append(mailbox_name, info->name); |
127 } | 136 } |
128 | 137 |
129 if (doveadm_mailbox_find_and_sync(ctx->ctx.cur_mail_user, | 138 box = doveadm_mailbox_find(ctx->ctx.cur_mail_user, str_c(mailbox_name)); |
130 str_c(mailbox_name), &box) < 0 || | 139 if (mailbox_get_status(box, ctx->status_items, &status) < 0 || |
131 mailbox_get_status(box, ctx->items, &status) < 0) { | 140 mailbox_get_metadata(box, ctx->metadata_items, &metadata) < 0) { |
132 ctx->ctx.failed = TRUE; | 141 ctx->ctx.failed = TRUE; |
142 mailbox_free(&box); | |
133 return; | 143 return; |
134 } | 144 } |
135 if (ctx->guid) { | |
136 if (mailbox_get_guid(box, mailbox_guid) < 0) | |
137 memset(mailbox_guid, 0, sizeof(mailbox_guid)); | |
138 } | |
139 if (!ctx->total_sum) | 145 if (!ctx->total_sum) |
140 status_output(ctx, box, &status, mailbox_guid); | 146 status_output(ctx, box, &status, &metadata); |
141 else | 147 else |
142 status_sum(ctx, &status); | 148 status_sum(ctx, &status, &metadata); |
143 mailbox_free(&box); | 149 mailbox_free(&box); |
144 } | 150 } |
145 | 151 |
146 static void | 152 static void |
147 cmd_mailbox_status_run(struct doveadm_mail_cmd_context *_ctx, | 153 cmd_mailbox_status_run(struct doveadm_mail_cmd_context *_ctx, |
163 status_mailbox(ctx, info); | 169 status_mailbox(ctx, info); |
164 } T_END; | 170 } T_END; |
165 } | 171 } |
166 doveadm_mail_list_iter_deinit(&iter); | 172 doveadm_mail_list_iter_deinit(&iter); |
167 | 173 |
168 if (ctx->total_sum) | 174 if (ctx->total_sum) { |
169 status_output(ctx, NULL, &ctx->total_status, NULL); | 175 status_output(ctx, NULL, &ctx->total_status, |
176 &ctx->total_metadata); | |
177 } | |
170 } | 178 } |
171 | 179 |
172 static void cmd_mailbox_status_init(struct doveadm_mail_cmd_context *_ctx, | 180 static void cmd_mailbox_status_init(struct doveadm_mail_cmd_context *_ctx, |
173 const char *const args[]) | 181 const char *const args[]) |
174 { | 182 { |
183 | 191 |
184 if (!ctx->total_sum) { | 192 if (!ctx->total_sum) { |
185 doveadm_print_header("mailbox", "mailbox", | 193 doveadm_print_header("mailbox", "mailbox", |
186 DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE); | 194 DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE); |
187 } | 195 } |
188 if ((ctx->items & STATUS_MESSAGES) != 0) | 196 if ((ctx->status_items & STATUS_MESSAGES) != 0) |
189 doveadm_print_header_simple("messages"); | 197 doveadm_print_header_simple("messages"); |
190 if ((ctx->items & STATUS_RECENT) != 0) | 198 if ((ctx->status_items & STATUS_RECENT) != 0) |
191 doveadm_print_header_simple("recent"); | 199 doveadm_print_header_simple("recent"); |
192 if ((ctx->items & STATUS_UIDNEXT) != 0) | 200 if ((ctx->status_items & STATUS_UIDNEXT) != 0) |
193 doveadm_print_header_simple("uidnext"); | 201 doveadm_print_header_simple("uidnext"); |
194 if ((ctx->items & STATUS_UIDVALIDITY) != 0) | 202 if ((ctx->status_items & STATUS_UIDVALIDITY) != 0) |
195 doveadm_print_header_simple("uidvalidity"); | 203 doveadm_print_header_simple("uidvalidity"); |
196 if ((ctx->items & STATUS_UNSEEN) != 0) | 204 if ((ctx->status_items & STATUS_UNSEEN) != 0) |
197 doveadm_print_header_simple("unseen"); | 205 doveadm_print_header_simple("unseen"); |
198 if ((ctx->items & STATUS_HIGHESTMODSEQ) != 0) | 206 if ((ctx->status_items & STATUS_HIGHESTMODSEQ) != 0) |
199 doveadm_print_header_simple("highestmodseq"); | 207 doveadm_print_header_simple("highestmodseq"); |
200 if ((ctx->items & STATUS_VIRTUAL_SIZE) != 0) | 208 if ((ctx->metadata_items & MAILBOX_METADATA_VIRTUAL_SIZE) != 0) |
201 doveadm_print_header_simple("vsize"); | 209 doveadm_print_header_simple("vsize"); |
202 if (ctx->guid) | 210 if ((ctx->metadata_items & MAILBOX_METADATA_GUID) != 0) |
203 doveadm_print_header_simple("guid"); | 211 doveadm_print_header_simple("guid"); |
204 } | 212 } |
205 | 213 |
206 static bool | 214 static bool |
207 cmd_mailbox_status_parse_arg(struct doveadm_mail_cmd_context *_ctx, int c) | 215 cmd_mailbox_status_parse_arg(struct doveadm_mail_cmd_context *_ctx, int c) |