static void subquery_free(void *data) { search_subquery_t *sub = data; free(sub->mboxname); search_expr_free(sub->indexed); search_expr_free(sub->expr); free(sub); }
EXPORTED void search_query_free(search_query_t *query) { int i; if (!query) return; free_hash_table(&query->subs_by_folder, subquery_free); free_hash_table(&query->subs_by_indexed, subquery_free); search_expr_free(query->global_sub.expr); ptrarray_fini(&query->folders_by_id); free_hash_table(&query->folders_by_name, folder_free); ptrarray_fini(&query->merged_msgdata); /* free pending MsgData arrays */ for (i = 0 ; i < query->saved_msgdata.count ; i++) { struct search_saved_msgdata *saved = ptrarray_nth(&query->saved_msgdata, i); index_msgdata_free(saved->msgdata, saved->n); free(saved); } ptrarray_fini(&query->saved_msgdata); free(query); }
static int dump_me(struct findall_data *data, void *rock) { int r; char boundary[128]; struct imapurl url; char imapurl[MAX_MAILBOX_PATH+1]; struct incremental_record *irec = (struct incremental_record *) rock; struct searchargs searchargs; struct index_state *state; unsigned *uids = NULL; unsigned *uidseq = NULL; int i, n, numuids; unsigned msgno; /* don't want partial matches */ if (!data || !data->mbname) return 0; const char *name = mbname_intname(data->mbname); r = index_open(name, NULL, &state); if (r) { if (verbose) { printf("error opening %s: %s\n", name, error_message(r)); } return 0; } generate_boundary(boundary, sizeof(boundary)); printf("Content-Type: multipart/related; boundary=\"%s\"\n\n", boundary); printf("--%s\n", boundary); printf("Content-Type: text/xml\n"); printf("IMAP-Dump-Version: 0\n"); printf("\n"); printf("<imapdump uniqueid=\"%s\">\n", state->mailbox->uniqueid); memset(&url, 0, sizeof(struct imapurl)); url.server = config_servername; url.mailbox = name; imapurl_toURL(imapurl, &url); printf(" <mailbox-url>%s</mailbox-url>\n", imapurl); printf(" <incremental-uid>%d</incremental-uid>\n", irec->incruid); printf(" <nextuid>%u</nextuid>\n", state->mailbox->i.last_uid + 1); printf("\n"); memset(&searchargs, 0, sizeof(struct searchargs)); searchargs.root = search_expr_new(NULL, SEOP_TRUE); numuids = index_getuidsequence(state, &searchargs, &uids); search_expr_free(searchargs.root); print_seq("uidlist", NULL, uids, numuids); printf("\n"); printf(" <flags>\n"); searchargs.root = systemflag_match(FLAG_ANSWERED); uidseq = NULL; n = index_getuidsequence(state, &searchargs, &uidseq); search_expr_free(searchargs.root); print_seq("flag", "name=\"\\Answered\" user=\"*\"", uidseq, n); if (uidseq) free(uidseq); searchargs.root = systemflag_match(FLAG_DELETED); uidseq = NULL; n = index_getuidsequence(state, &searchargs, &uidseq); search_expr_free(searchargs.root); print_seq("flag", "name=\"\\Deleted\" user=\"*\"", uidseq, n); if (uidseq) free(uidseq); searchargs.root = systemflag_match(FLAG_DRAFT); uidseq = NULL; n = index_getuidsequence(state, &searchargs, &uidseq); search_expr_free(searchargs.root); print_seq("flag", "name=\"\\Draft\" user=\"*\"", uidseq, n); if (uidseq) free(uidseq); searchargs.root = systemflag_match(FLAG_FLAGGED); uidseq = NULL; n = index_getuidsequence(state, &searchargs, &uidseq); search_expr_free(searchargs.root); print_seq("flag", "name=\"\\Flagged\" user=\"*\"", uidseq, n); if (uidseq) free(uidseq); printf(" </flags>\n"); printf("</imapdump>\n"); i = 0; while (i < numuids && uids[i] < irec->incruid) { /* already dumped this message */ /* xxx could do binary search to get to the first undumped uid */ i++; } for (msgno = 1; msgno <= state->exists; msgno++) { struct buf buf = BUF_INITIALIZER; struct index_map *im = &state->map[msgno-1]; struct index_record record; while (im->uid > uids[i] && i < numuids) i++; if (i >= numuids) break; if (im->uid < uids[i]) continue; /* got a match */ i++; memset(&record, 0, sizeof(struct index_record)); record.recno = im->recno; record.uid = im->uid; if (mailbox_reload_index_record(state->mailbox, &record)) continue; printf("\n--%s\n", boundary); printf("Content-Type: message/rfc822\n"); printf("Content-ID: %d\n", uids[i]); printf("\n"); r = mailbox_map_record(state->mailbox, &record, &buf); if (r) { if (verbose) { printf("error mapping message %u: %s\n", record.uid, error_message(r)); } break; } fwrite(buf.s, 1, buf.len, stdout); buf_free(&buf); } printf("\n--%s--\n", boundary); free(uids); index_close(&state); return 0; }