int main(int argc, char **argv) { int opt; char *alt_config = NULL; int r = IMAP_NOTFOUND; strarray_t mboxnames = STRARRAY_INITIALIZER; const char *query = NULL; int background = 1; const char *channel = "squatter"; const char *synclogfile = NULL; int init_flags = CYRUSINIT_PERROR; int multi_folder = 0; int user_mode = 0; int compact_flags = 0; const char *fromfile = NULL; strarray_t *srctiers = NULL; const char *desttier = NULL; enum { UNKNOWN, INDEXER, INDEXFROM, SEARCH, ROLLING, SYNCLOG, START_DAEMON, STOP_DAEMON, RUN_DAEMON, COMPACT } mode = UNKNOWN; if ((geteuid()) == 0 && (become_cyrus(/*is_master*/0) != 0)) { fatal("must run as the Cyrus user", EC_USAGE); } setbuf(stdout, NULL); while ((opt = getopt(argc, argv, "C:I:N:RAXT:S:Fc:de:f:mn:rsiavz:t:ou")) != EOF) { switch (opt) { case 'C': /* alt config file */ alt_config = optarg; break; case 'A': compact_flags |= SEARCH_COMPACT_AUDIT; break; case 'F': compact_flags |= SEARCH_COMPACT_FILTER; break; case 'X': compact_flags |= SEARCH_COMPACT_REINDEX; break; case 'N': name_starts_from = optarg; break; case 'I': /* indexer, using specified mbox/uids in file */ if (mode != UNKNOWN && mode != INDEXFROM) usage(argv[0]); fromfile = optarg; mode = INDEXFROM; break; case 'R': /* rolling indexer */ if (mode != UNKNOWN) usage(argv[0]); mode = ROLLING; incremental_mode = 1; /* always incremental if rolling */ break; case 'S': /* sleep time in seconds */ sleepmicroseconds = (atof(optarg) * 1000000); break; case 'T': /* temporary root directory for search */ temp_root_dir = optarg; break; /* This option is deliberately undocumented, for testing only */ case 'c': /* daemon control mode */ if (mode != UNKNOWN) usage(argv[0]); if (!strcmp(optarg, "start")) mode = START_DAEMON; else if (!strcmp(optarg, "stop")) mode = STOP_DAEMON; else if (!strcmp(optarg, "run")) mode = RUN_DAEMON; else usage(argv[0]); break; case 'd': /* foreground (with -R) */ background = 0; break; /* This option is deliberately undocumented, for testing only */ case 'e': /* add a search term */ if (mode != UNKNOWN && mode != SEARCH) usage(argv[0]); query = optarg; mode = SEARCH; break; case 'f': /* alternate synclogfile used in SYNCLOG mode */ synclogfile = optarg; mode = SYNCLOG; break; /* This option is deliberately undocumented, for testing only */ case 'm': /* multi-folder in SEARCH mode */ if (mode != UNKNOWN && mode != SEARCH) usage(argv[0]); multi_folder = 1; mode = SEARCH; break; case 'n': /* sync channel name (with -R) */ channel = optarg; break; case 'o': /* copy one DB rather than compressing */ compact_flags |= SEARCH_COMPACT_COPYONE; break; case 'v': /* verbose */ verbose++; break; case 'r': /* recurse */ if (mode != UNKNOWN && mode != INDEXER) usage(argv[0]); recursive_flag = 1; mode = INDEXER; break; case 'i': /* incremental mode */ incremental_mode = 1; break; case 'a': /* use /squat annotation */ if (mode != UNKNOWN && mode != INDEXER) usage(argv[0]); annotation_flag = 1; mode = INDEXER; break; case 'z': if (mode != UNKNOWN && mode != COMPACT) usage(argv[0]); desttier = optarg; mode = COMPACT; break; case 't': if (mode != UNKNOWN && mode != COMPACT) usage(argv[0]); srctiers = strarray_split(optarg, ",", 0); mode = COMPACT; break; case 'u': user_mode = 1; break; default: usage("squatter"); } } compact_flags |= SEARCH_VERBOSE(verbose); if (mode == UNKNOWN) mode = INDEXER; /* fork and close fds if required */ if (mode == ROLLING && background) { become_daemon(); init_flags &= ~CYRUSINIT_PERROR; } if (mode == COMPACT && (!desttier || !srctiers)) { /* need both src and dest for compact */ usage("squatter"); } cyrus_init(alt_config, "squatter", init_flags, CONFIG_NEED_PARTITION_DATA); /* Set namespace -- force standard (internal) */ if ((r = mboxname_init_namespace(&squat_namespace, 1)) != 0) { fatal(error_message(r), EC_CONFIG); } annotate_init(NULL, NULL); annotatemore_open(); mboxlist_init(0); mboxlist_open(NULL); if (mode == ROLLING || mode == SYNCLOG) { signals_set_shutdown(&shut_down); signals_add_handlers(0); } switch (mode) { case UNKNOWN: break; case INDEXER: /* -r requires at least one mailbox */ if (recursive_flag && optind == argc) usage(argv[0]); expand_mboxnames(&mboxnames, argc-optind, (const char **)argv+optind, user_mode); syslog(LOG_NOTICE, "indexing mailboxes"); r = do_indexer(&mboxnames); syslog(LOG_NOTICE, "done indexing mailboxes"); break; case INDEXFROM: syslog(LOG_NOTICE, "indexing messages"); r = do_indexfrom(fromfile); syslog(LOG_NOTICE, "done indexing messages"); break; case SEARCH: if (recursive_flag && optind == argc) usage(argv[0]); expand_mboxnames(&mboxnames, argc-optind, (const char **)argv+optind, user_mode); r = do_search(query, !multi_folder, &mboxnames); break; case ROLLING: do_rolling(channel); /* never returns */ break; case SYNCLOG: r = do_synclogfile(synclogfile); break; case START_DAEMON: if (optind != argc) usage("squatter"); search_start_daemon(verbose); break; case STOP_DAEMON: if (optind != argc) usage("squatter"); search_stop_daemon(verbose); break; case RUN_DAEMON: if (optind != argc) usage("squatter"); do_run_daemon(); break; case COMPACT: if (recursive_flag && optind == argc) usage(argv[0]); expand_mboxnames(&mboxnames, argc-optind, (const char **)argv+optind, user_mode); r = do_compact(&mboxnames, srctiers, desttier, compact_flags); break; } strarray_fini(&mboxnames); shut_down(r ? EC_TEMPFAIL : 0); }
int main(int argc, char **argv) { int opt; pid_t pid; char *alt_config = NULL; time_t runattime = 0; int upgrade = 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:dt:U")) != EOF) { switch (opt) { case 'C': /* alt config file */ alt_config = optarg; break; case 'd': /* don't fork. debugging mode */ debugmode = 1; break; case 't': /* run a single scan at this time */ runattime = atoi(optarg); break; case 'U': upgrade = 1; break; default: fprintf(stderr, "invalid argument\n"); exit(EC_USAGE); break; } } cyrus_init(alt_config, "calalarmd", 0, 0); mboxlist_init(0); mboxlist_open(NULL); quotadb_init(0); quotadb_open(NULL); annotatemore_open(); caldav_init(); mboxevent_init(); if (upgrade) { caldav_alarm_upgrade(); shut_down(0); } if (runattime) { caldav_alarm_process(runattime); shut_down(0); } signals_set_shutdown(shut_down); signals_add_handlers(0); /* fork unless we were given the -d option or we're running as a daemon */ if (debugmode == 0 && !getenv("CYRUS_ISDAEMON")) { pid = fork(); if (pid == -1) { perror("fork"); exit(1); } if (pid != 0) { /* parent */ exit(0); } } /* child */ for (;;) { struct timeval start, end; double totaltime; int tosleep; signals_poll(); gettimeofday(&start, 0); caldav_alarm_process(0); gettimeofday(&end, 0); signals_poll(); totaltime = timesub(&start, &end); tosleep = 10 - (int) (totaltime + 0.5); /* round to nearest int */ if (tosleep > 0) sleep(tosleep); } /* NOTREACHED */ shut_down(1); }