static int getmailboxexists(void *sc, const char *extname) { script_data_t *sd = (script_data_t *)sc; char *intname = mboxname_from_external(extname, sd->ns, mbname_userid(sd->mbname)); int r = mboxlist_lookup(intname, NULL, NULL); free(intname); return r ? 0 : 1; /* 0 => exists */ }
static int getmetadata(void *sc, const char *extname, const char *keyname, char **res) { script_data_t *sd = (script_data_t *)sc; struct buf attrib = BUF_INITIALIZER; char *intname = extname ? mboxname_from_external(extname, sd->ns, mbname_userid(sd->mbname)) : xstrdup(""); int r; if (!strncmp(keyname, "/private/", 9)) { r = annotatemore_lookup(intname, keyname+8, mbname_userid(sd->mbname), &attrib); } else if (!strncmp(keyname, "/shared/", 8)) { r = annotatemore_lookup(intname, keyname+7, "", &attrib); } else { r = IMAP_MAILBOX_NONEXISTENT; } *res = (r || !attrib.len) ? NULL : buf_release(&attrib); free(intname); buf_free(&attrib); return r ? 0 : 1; }
static void expand_mboxnames(strarray_t *sa, int nmboxnames, const char **mboxnames, int user_mode) { int i; if (!nmboxnames) { assert(!recursive_flag); mboxlist_allmbox(NULL, addmbox, sa, 0); } for (i = 0; i < nmboxnames; i++) { if (user_mode) { mboxlist_usermboxtree(mboxnames[i], addmbox, sa, 0); } else { /* Translate any separators in mailboxname */ char *intname = mboxname_from_external(mboxnames[i], &squat_namespace, NULL); int flags = recursive_flag ? 0 : MBOXTREE_SKIP_CHILDREN; mboxlist_mboxtree(intname, addmbox, sa, flags); free(intname); } } }
int main(int argc, char *argv[]) { extern char *optarg; int opt, r = 0; char *alt_config = NULL, *intname = NULL, *extname = NULL; struct mailbox *mailbox = NULL; int mode = MODE_UNKNOWN; unsigned numrestored = 0; time_t time_since = time(NULL); int len, secs = 0; unsigned long *uids = NULL; unsigned nuids = 0; while ((opt = getopt(argc, argv, "C:laudt:f:v")) != EOF) { switch (opt) { case 'C': /* alt config file */ alt_config = optarg; break; case 'l': if (mode != MODE_UNKNOWN) usage(); mode = MODE_LIST; break; case 'a': if (mode != MODE_UNKNOWN) usage(); mode = MODE_ALL; break; case 't': if (mode != MODE_UNKNOWN) usage(); mode = MODE_TIME; secs = atoi(optarg); len = strlen(optarg); if ((secs > 0) && (len > 1)) { switch (optarg[len-1]) { case 'm': secs *= 60; break; case 'h': secs *= (60*60); break; case 'd': secs *= (24*60*60); break; case 'w': secs *= (7*24*60*60); break; } } time_since = time(NULL) - secs; break; case 'u': if (mode != MODE_UNKNOWN) usage(); mode = MODE_UID; break; case 'd': unsetdeleted = 1; break; case 'f': addflag = optarg; break; case 'v': verbose = 1; break; default: usage(); break; } } /* sanity check */ if (mode == MODE_UNKNOWN || (optind + (mode == MODE_UID ? 1 : 0)) >= argc) usage(); cyrus_init(alt_config, "unexpunge", 0, 0); sync_log_init(); if (addflag && addflag[0] == '\\') { syslog(LOG_ERR, "can't set a system flag"); fatal("can't set a system flag", EX_SOFTWARE); } /* Set namespace -- force standard (internal) */ if ((r = mboxname_init_namespace(&unex_namespace, 1)) != 0) { syslog(LOG_ERR, "%s", error_message(r)); fatal(error_message(r), EX_CONFIG); } /* Translate mailboxname */ intname = mboxname_from_external(argv[optind], &unex_namespace, NULL); if (mode == MODE_LIST) { list_expunged(intname); goto done; } /* Open/lock header */ r = mailbox_open_iwl(intname, &mailbox); if (r) { printf("Failed to open mailbox '%s'\n", intname); goto done; } if (mode == MODE_UID) { unsigned i; nuids = argc - ++optind; uids = (unsigned long *) xmalloc(nuids * sizeof(unsigned long)); for (i = 0; i < nuids; i++) uids[i] = strtoul(argv[optind+i], NULL, 10); /* Sort the UIDs so we can binary search */ qsort(uids, nuids, sizeof(unsigned long), compare_uid); } extname = mboxname_to_external(intname, &unex_namespace, NULL); printf("restoring %sexpunged messages in mailbox '%s'\n", mode == MODE_ALL ? "all " : "", extname); r = restore_expunged(mailbox, mode, uids, nuids, time_since, &numrestored, extname); if (!r) { printf("restored %u expunged messages\n", numrestored); syslog(LOG_NOTICE, "restored %u expunged messages in mailbox '%s'", numrestored, extname); } mailbox_close(&mailbox); done: free(intname); free(extname); sync_log_done(); cyrus_done(); exit(r); }
/* This handles piping of the LSUB command, because we have to figure out * what mailboxes actually exist before passing them to the end user. * * It is also needed if we are doing a FIND MAILBOXES, for that we do an * LSUB on the backend anyway, because the semantics of FIND do not allow * it to return nonexistant mailboxes (RFC1176), but we need to really dumb * down the response when this is the case. */ int pipe_lsub(struct backend *s, const char *userid, const char *tag, int force_notfatal, const char *resp) { int taglen = strlen(tag); int c; int r = PROXY_OK; int exist_r; static struct buf tagb, cmd, sep, name; struct buf flags = BUF_INITIALIZER; const char *end_strip_flags[] = { " \\NonExistent)", "\\NonExistent)", " \\Noselect)", "\\Noselect)", NULL }; const char *mid_strip_flags[] = { "\\NonExistent ", "\\Noselect ", NULL }; assert(s); assert(s->timeout); s->timeout->mark = time(NULL) + IDLE_TIMEOUT; while(1) { c = getword(s->in, &tagb); if(c == EOF) { if(s == backend_current && !force_notfatal) fatal("Lost connection to selected backend", EC_UNAVAILABLE); proxy_downserver(s); r = PROXY_NOCONNECTION; goto out; } if(!strncmp(tag, tagb.s, taglen)) { char buf[2048]; if(!prot_fgets(buf, sizeof(buf), s->in)) { if(s == backend_current && !force_notfatal) fatal("Lost connection to selected backend", EC_UNAVAILABLE); proxy_downserver(s); r = PROXY_NOCONNECTION; goto out; } /* Got the end of the response */ buf_appendcstr(&s->last_result, buf); buf_cstring(&s->last_result); switch (buf[0]) { case 'O': case 'o': r = PROXY_OK; break; case 'N': case 'n': r = PROXY_NO; break; case 'B': case 'b': r = PROXY_BAD; break; default: /* huh? no result? */ if(s == backend_current && !force_notfatal) fatal("Lost connection to selected backend", EC_UNAVAILABLE); proxy_downserver(s); r = PROXY_NOCONNECTION; break; } break; /* we're done */ } c = getword(s->in, &cmd); if(c == EOF) { if(s == backend_current && !force_notfatal) fatal("Lost connection to selected backend", EC_UNAVAILABLE); proxy_downserver(s); r = PROXY_NOCONNECTION; goto out; } if(strncasecmp("LSUB", cmd.s, 4) && strncasecmp("LIST", cmd.s, 4)) { prot_printf(imapd_out, "%s %s ", tagb.s, cmd.s); r = pipe_to_end_of_response(s, force_notfatal); if (r != PROXY_OK) goto out; } else { /* build up the response bit by bit */ int i; buf_reset(&flags); c = prot_getc(s->in); while(c != ')' && c != EOF) { buf_putc(&flags, c); c = prot_getc(s->in); } if(c != EOF) { /* terminate string */ buf_putc(&flags, ')'); buf_cstring(&flags); /* get the next character */ c = prot_getc(s->in); } if(c != ' ') { if(s == backend_current && !force_notfatal) fatal("Bad LSUB response from selected backend", EC_UNAVAILABLE); proxy_downserver(s); r = PROXY_NOCONNECTION; goto out; } /* Check for flags that we should remove * (e.g. Noselect, NonExistent) */ for(i=0; end_strip_flags[i]; i++) buf_replace_all(&flags, end_strip_flags[i], ")"); for (i=0; mid_strip_flags[i]; i++) buf_replace_all(&flags, mid_strip_flags[i], NULL); /* Get separator */ c = getastring(s->in, s->out, &sep); if(c != ' ') { if(s == backend_current && !force_notfatal) fatal("Bad LSUB response from selected backend", EC_UNAVAILABLE); proxy_downserver(s); r = PROXY_NOCONNECTION; goto out; } /* Get name */ c = getastring(s->in, s->out, &name); if(c == '\r') c = prot_getc(s->in); if(c != '\n') { if(s == backend_current && !force_notfatal) fatal("Bad LSUB response from selected backend", EC_UNAVAILABLE); proxy_downserver(s); r = PROXY_NOCONNECTION; goto out; } /* lookup name */ exist_r = 1; char *intname = mboxname_from_external(name.s, &imapd_namespace, userid); mbentry_t *mbentry = NULL; exist_r = mboxlist_lookup(intname, &mbentry, NULL); free(intname); if(!exist_r && (mbentry->mbtype & MBTYPE_RESERVE)) exist_r = IMAP_MAILBOX_RESERVED; mboxlist_entry_free(&mbentry); /* send our response */ /* we need to set \Noselect if it's not in our mailboxes.db */ if (resp[0] == 'L') { if(!exist_r) { prot_printf(imapd_out, "* %s %s \"%s\" ", resp, flags.s, sep.s); } else { prot_printf(imapd_out, "* %s (\\Noselect) \"%s\" ", resp, sep.s); } prot_printstring(imapd_out, name.s); prot_printf(imapd_out, "\r\n"); } else if(resp[0] == 'M' && !exist_r) { /* Note that it has to exist for a find response */ prot_printf(imapd_out, "* %s ", resp); prot_printastring(imapd_out, name.s); prot_printf(imapd_out, "\r\n"); } } } /* while(1) */ out: buf_free(&flags); return r; }
int main(int argc, char **argv) { int opt, i, r; char buf[MAX_MAILBOX_PATH+1]; char *alt_config = NULL; int quotachk = 0; if ((geteuid()) == 0 && (become_cyrus(/*is_master*/0) != 0)) { fatal("must run as the Cyrus user", EC_USAGE); } while ((opt = getopt(argc, argv, "C:u:s:q")) != EOF) { switch (opt) { case 'C': /* alt config file */ alt_config = optarg; break; case 'u': if(wantvalue) usage(); wantuid = 1; wantvalue = atoi(optarg); break; case 's': if(wantvalue) usage(); wantvalue = atoi(optarg); break; case 'q': quotachk = 1; break; default: usage(); } } cyrus_init(alt_config, "mbexamine", 0, 0); /* Set namespace -- force standard (internal) */ if ((r = mboxname_init_namespace(&recon_namespace, 1)) != 0) { syslog(LOG_ERR, "%s", error_message(r)); fatal(error_message(r), EC_CONFIG); } mboxlist_init(0); mboxlist_open(NULL); signals_set_shutdown(&shut_down); signals_add_handlers(0); if (optind == argc) { strlcpy(buf, "*", sizeof(buf)); mboxlist_findall(&recon_namespace, buf, 1, 0, 0, quotachk ? do_quota : do_examine, NULL); } for (i = optind; i < argc; i++) { /* Handle virtdomains and separators in mailboxname */ char *intname = mboxname_from_external(argv[i], &recon_namespace, NULL); mboxlist_findall(&recon_namespace, intname, 1, 0, 0, quotachk ? do_quota : do_examine, NULL); free(intname); } mboxlist_close(); mboxlist_done(); exit(0); }
int main(int argc, char **argv) { int opt, i, r; int dousers = 0; int rflag = 0; int mflag = 0; int fflag = 0; int xflag = 0; char buf[MAX_MAILBOX_PATH+1]; strarray_t discovered = STRARRAY_INITIALIZER; char *alt_config = NULL; char *start_part = NULL; if ((geteuid()) == 0 && (become_cyrus(/*is_master*/0) != 0)) { fatal("must run as the Cyrus user", EC_USAGE); } construct_hash_table(&unqid_table, 2047, 1); while ((opt = getopt(argc, argv, "C:kp:rmfsxgGqRUMoOnV:u")) != EOF) { switch (opt) { case 'C': /* alt config file */ alt_config = optarg; break; case 'p': start_part = optarg; break; case 'r': rflag = 1; break; case 'u': dousers = 1; break; case 'm': mflag = 1; break; case 'n': reconstruct_flags &= ~RECONSTRUCT_MAKE_CHANGES; break; case 'g': fprintf(stderr, "reconstruct: deprecated option -g ignored\n"); break; case 'G': reconstruct_flags |= RECONSTRUCT_ALWAYS_PARSE; break; case 'f': fflag = 1; break; case 'x': xflag = 1; break; case 'k': fprintf(stderr, "reconstruct: deprecated option -k ignored\n"); break; case 's': reconstruct_flags &= ~RECONSTRUCT_DO_STAT; break; case 'q': reconstruct_flags |= RECONSTRUCT_QUIET; break; case 'R': reconstruct_flags |= RECONSTRUCT_GUID_REWRITE; break; case 'U': reconstruct_flags |= RECONSTRUCT_GUID_UNLINK; break; case 'o': reconstruct_flags |= RECONSTRUCT_IGNORE_ODDFILES; break; case 'O': reconstruct_flags |= RECONSTRUCT_REMOVE_ODDFILES; break; case 'M': reconstruct_flags |= RECONSTRUCT_PREFER_MBOXLIST; break; case 'V': if (!strcasecmp(optarg, "max")) setversion = MAILBOX_MINOR_VERSION; else setversion = atoi(optarg); break; default: usage(); } } cyrus_init(alt_config, "reconstruct", 0, CONFIG_NEED_PARTITION_DATA); global_sasl_init(1,0,NULL); /* Set namespace -- force standard (internal) */ if ((r = mboxname_init_namespace(&recon_namespace, 1)) != 0) { syslog(LOG_ERR, "%s", error_message(r)); fatal(error_message(r), EC_CONFIG); } sync_log_init(); if (mflag) { if (rflag || fflag || optind != argc) { cyrus_done(); usage(); } do_mboxlist(); } mboxlist_init(0); mboxlist_open(NULL); quotadb_init(0); quotadb_open(NULL); #ifdef WITH_DAV caldav_init(); carddav_init(); webdav_init(); #endif /* Deal with nonexistent mailboxes */ if (start_part) { /* We were handed a mailbox that does not exist currently */ if(optind == argc) { fprintf(stderr, "When using -p, you must specify a mailbox to attempt to reconstruct."); exit(EC_USAGE); } /* do any of the mailboxes exist in mboxlist already? */ /* Do they look like mailboxes? */ for (i = optind; i < argc; i++) { if (strchr(argv[i],'%') || strchr(argv[i],'*')) { fprintf(stderr, "Using wildcards with -p is not supported.\n"); exit(EC_USAGE); } /* Translate mailboxname */ char *intname = mboxname_from_external(argv[i], &recon_namespace, NULL); /* Does it exist */ do { r = mboxlist_lookup(intname, NULL, NULL); } while (r == IMAP_AGAIN); if (r != IMAP_MAILBOX_NONEXISTENT) { fprintf(stderr, "Mailbox %s already exists. Cannot specify -p.\n", argv[i]); exit(EC_USAGE); } free(intname); } /* None of them exist. Create them. */ for (i = optind; i < argc; i++) { /* Translate mailboxname */ char *intname = mboxname_from_external(argv[i], &recon_namespace, NULL); /* don't notify mailbox creation here */ r = mboxlist_createmailbox(intname, 0, start_part, 1, "cyrus", NULL, 0, 0, !xflag, 0, NULL); if (r) { fprintf(stderr, "could not create %s\n", argv[i]); } free(intname); } } /* Normal Operation */ if (optind == argc) { if (rflag || dousers) { fprintf(stderr, "please specify a mailbox to recurse from\n"); cyrus_done(); exit(EC_USAGE); } assert(!rflag); strlcpy(buf, "*", sizeof(buf)); mboxlist_findall(&recon_namespace, buf, 1, 0, 0, do_reconstruct, NULL); } for (i = optind; i < argc; i++) { if (dousers) { mboxlist_usermboxtree(argv[i], do_reconstruct_p, NULL, MBOXTREE_TOMBSTONES|MBOXTREE_DELETED); continue; } char *domain = NULL; /* save domain */ if (config_virtdomains) domain = strchr(argv[i], '@'); strlcpy(buf, argv[i], sizeof(buf)); /* reconstruct the first mailbox/pattern */ mboxlist_findall(&recon_namespace, buf, 1, 0, 0, do_reconstruct, fflag ? &discovered : NULL); if (rflag) { /* build a pattern for submailboxes */ char *p = strchr(buf, '@'); if (p) *p = '\0'; strlcat(buf, ".*", sizeof(buf)); /* append the domain */ if (domain) strlcat(buf, domain, sizeof(buf)); /* reconstruct the submailboxes */ mboxlist_findall(&recon_namespace, buf, 1, 0, 0, do_reconstruct, fflag ? &discovered : NULL); } } /* examine our list to see if we discovered anything */ while (discovered.count) { char *name = strarray_shift(&discovered); int r = 0; /* create p (database only) and reconstruct it */ /* partition is defined by the parent mailbox */ /* don't notify mailbox creation here */ r = mboxlist_createmailbox(name, 0, NULL, 1, "cyrus", NULL, 0, 0, !xflag, 0, NULL); if (r) { fprintf(stderr, "createmailbox %s: %s\n", name, error_message(r)); } else { mboxlist_findone(&recon_namespace, name, 1, 0, 0, do_reconstruct, &discovered); } /* may have added more things into our list */ free(name); } free_hash_table(&unqid_table, free); sync_log_done(); mboxlist_close(); mboxlist_done(); quotadb_close(); quotadb_done(); partlist_local_done(); #ifdef WITH_DAV webdav_done(); carddav_done(); caldav_done(); #endif cyrus_done(); strarray_fini(&discovered); return 0; }