Exemplo n.º 1
0
void shut_down(int code)
{
    /* free interpreter */
    if (interp) sieve_interp_free(&interp);

    /* close backend connection */
    if (backend) {
	backend_disconnect(backend);
	free(backend);
    }

    /* close mailboxes */
    mboxlist_close();
    mboxlist_done();

    /* cleanup */
    if (sieved_out) {
	prot_flush(sieved_out);
	prot_free(sieved_out);
    }
    if (sieved_in) prot_free(sieved_in);

    if (sieved_logfd != -1) close(sieved_logfd);

#ifdef HAVE_SSL
    tls_shutdown_serverengine();
#endif

    cyrus_done();

    cyrus_reset_stdio();
    
    /* done */
    exit(code);
}
Exemplo n.º 2
0
int main(int argc, char *argv[])
{
    extern char *optarg;
    int opt,r;
    char *alt_config = NULL;

    if ((geteuid()) == 0 && (become_cyrus() != 0)) {
	fatal("must run as the Cyrus user", EC_USAGE);
    }

    while ((opt = getopt(argc, argv, "C:")) != EOF) {
	switch (opt) {
	case 'C': /* alt config file */
	    alt_config = optarg;
	    break;

	default:
	    usage();
	    break;
	}
    }

    cyrus_init(alt_config, "tls_prune", 0);

    r = tls_prune_sessions();

    cyrus_done();

    return r;
}
Exemplo n.º 3
0
int main(int argc, char *argv[])
{
    extern char *optarg;
    int opt,r;
    char *alt_config = NULL;

    while ((opt = getopt(argc, argv, "C:")) != EOF) {
        switch (opt) {
        case 'C': /* alt config file */
            alt_config = optarg;
            break;

        default:
            usage();
            break;
        }
    }

    cyrus_init(alt_config, "tls_prune", 0, 0);

    r = tls_prune_sessions();

    cyrus_done();

    return r;
}
Exemplo n.º 4
0
int main(int argc, char **argv)
{
    int opt;
    char *alt_config = NULL;

    if ((geteuid()) == 0 && (become_cyrus(/*is_master*/0) != 0)) {
	fatal("must run as the Cyrus user", EC_USAGE);
    }

    while ((opt = getopt(argc, argv, "C:")) != EOF) {
	switch (opt) {
	case 'C': /* alt config file */
	    alt_config = optarg;
	    break;
	default:
	    usage();
	}
    }

    cyrus_init(alt_config, "syncnews", 0);

    if (!argv[optind] || argv[optind+1]) usage();

    readactive(argv[optind]);
    do_syncnews();

    cyrus_done();

    return code;
}
Exemplo n.º 5
0
int main(int argc, char *argv[])
{
    int option;
    char buf[MAX_MAILBOX_PATH+1];
    int i, r;
    char *alt_config = NULL;
    struct incremental_record irec;

    if ((geteuid()) == 0 && (become_cyrus(/*is_master*/0) != 0)) {
	fatal("must run as the Cyrus user", EC_USAGE);
    }

    while ((option = getopt(argc, argv, "vC:")) != EOF) {
	switch (option) {
	case 'v':
	    verbose++;
	    break;

	case 'C': /* alt config file */
	    alt_config = optarg;
	    break;

	default:
	    usage(argv[0]);
	    break;
	}
    }

    if (optind == argc) {
	usage(argv[0]);
    }

    cyrus_init(alt_config, "dump", 0, CONFIG_NEED_PARTITION_DATA);
    mboxlist_init(0);
    mboxlist_open(NULL);

    /* Set namespace -- force standard (internal) */
    if ((r = mboxname_init_namespace(&dump_namespace, 1)) != 0) {
	syslog(LOG_ERR, "%s", error_message(r));
	fatal(error_message(r), EC_CONFIG);
    }

    irec.incruid = 0;
    for (i = optind; i < argc; i++) {
	strlcpy(buf, argv[i], sizeof(buf));
	/* Translate any separators in mailboxname */
	mboxname_hiersep_tointernal(&dump_namespace, buf,
				    config_virtdomains ?
				    strcspn(buf, "@") : 0);
	(*dump_namespace.mboxlist_findall)(&dump_namespace, buf, 1, 0, 0,
					   dump_me, &irec);
    }

    mboxlist_close();
    mboxlist_done();

    cyrus_done();
    
    return 0;
}
Exemplo n.º 6
0
void shut_down(int code)
{
    cyrus_done();

    /* done */
    exit(code);
}
Exemplo n.º 7
0
EXPORTED void shut_down(int code)
{
    in_shutdown = 1;

    cyrus_done();

    /* done */
    exit(code);
}
Exemplo n.º 8
0
EXPORTED void fatal(const char *msg, int err)
{
    if (debugmode) fprintf(stderr, "dying with %s %d\n",msg,err);
    syslog(LOG_CRIT, "%s", msg);
    syslog(LOG_NOTICE, "exiting");

    cyrus_done();

    exit(err);
}
Exemplo n.º 9
0
static void shut_down(int ec)
{
    caldav_done();
    annotatemore_close();
    quotadb_close();
    quotadb_done();
    mboxlist_close();
    mboxlist_done();
    cyrus_done();
    exit(ec);
}
Exemplo n.º 10
0
void shut_down(int code)
{
    in_shutdown = 1;

    seen_done();
    mboxlist_close();
    mboxlist_done();
    closelog();
    cyrus_done();
    exit(code);
}
Exemplo n.º 11
0
void fatal(const char* s, int code)
{
    static int recurse_code = 0;
    
    if(recurse_code) exit(code);
    else recurse_code = 0;
    
    prot_printf(deliver_out,"421 4.3.0 deliver: %s\r\n", s);
    prot_flush(deliver_out);
    cyrus_done();
    exit(code);
}
Exemplo n.º 12
0
/* generic fatal() routine for command line utilities */
void fatal(const char *message, int code)
{
    static int recurse_code = 0;

    if (recurse_code) {
	exit(code);
    }

    recurse_code = code;
    fprintf(stderr, "fatal error: %s\n", message);
    cyrus_done();
    exit(code);
}
Exemplo n.º 13
0
static void shut_down(int code)
{
    if (running_daemon)
        search_stop_daemon(verbose);
    seen_done();
    mboxlist_close();
    mboxlist_done();
    annotatemore_close();
    annotate_done();

    cyrus_done();

    exit(code);
}
Exemplo n.º 14
0
static void shut_down(int code)
{
    in_shutdown = 1;

    seen_done();
    annotatemore_close();
    annotate_done();
    quotadb_close();
    quotadb_done();
    mboxlist_close();
    mboxlist_done();
    cyrus_done();
    exit(code);
}
Exemplo n.º 15
0
int main(int argc, char *argv[])
{
    int option;
    int i;
    char *alt_config = NULL;
    struct incremental_record irec;

    progname = basename(argv[0]);

    while ((option = getopt(argc, argv, "vC:")) != EOF) {
        switch (option) {
        case 'v':
            verbose++;
            break;

        case 'C': /* alt config file */
            alt_config = optarg;
            break;

        default:
            usage();
            break;
        }
    }

    if (optind == argc) {
        usage();
    }

    cyrus_init(alt_config, "dump", 0, CONFIG_NEED_PARTITION_DATA);

    search_attr_init();

    irec.incruid = 0;
    strarray_t *array = strarray_new();
    for (i = optind; i < argc; i++) {
        strarray_append(array, argv[i]);
    }
    if (array->count)
        mboxlist_findallmulti(NULL, array, 1, 0, 0, dump_me, &irec);

    strarray_free(array);

    cyrus_done();

    return 0;
}
Exemplo n.º 16
0
int main(int argc, char *argv[])
{
    extern char *optarg;
    int opt, r = 0, expire_days = 0;
    char *alt_config = NULL;

    if (geteuid() == 0) fatal("must run as the Cyrus user", EC_USAGE);

    while ((opt = getopt(argc, argv, "C:E:")) != EOF) {
	switch (opt) {
	case 'C': /* alt config file */
	    alt_config = optarg;
	    break;

	case 'E':
	    if (expire_days) usage();
	    expire_days = atoi(optarg);
	    break;

	default:
	    usage();
	    break;
	}
    }

    if (!expire_days) usage();

    cyrus_init(alt_config, "delivered_expire", 0);

    if (duplicate_init(NULL, 0) != 0) {
	fprintf(stderr, 
		"cyr_expire: unable to init duplicate delivery database\n");
	exit(1);
    }

    /* purge deliver.db entries of expired messages */
    r = duplicate_prune(expire_days, NULL);

    duplicate_done();
    cyrus_done();

    exit(r);
}
Exemplo n.º 17
0
int main(int argc, char *argv[])
{
    int opt, code = 0;
    char *alt_config = NULL;
    int meta = 0;

    if ((geteuid()) == 0 && (become_cyrus() != 0)) {
	fatal("must run as the Cyrus user", EC_USAGE);
    }

    while ((opt = getopt(argc, argv, "C:m")) != EOF) {
	switch (opt) {
	case 'C': /* alt config file */
	    alt_config = optarg;
	    break;

	case 'm': /* check metapartitions */
	    meta = 1;
	    break;

	default:
	    usage();
	}
    }

    cyrus_init(alt_config, "cyr_df", 0);

    printf("%-12s %12s %12s %12s %3s %s\n", "Partition",
	   "1k-blocks", "Used", "Available", "Use%", "Location");

    config_foreachoverflowstring(get_part_stats, &meta);

    cyrus_done();

    exit(code);
}
Exemplo n.º 18
0
int main(int argc, char **argv)
{
    int r = 0;
    int opt;
    int lmtpflag = 0;
    int ignorequota = 0;
    char *mailboxname = NULL;
    char *authuser = NULL;
    char *return_path = NULL;
    char buf[1024];
    char *alt_config = NULL;

    while ((opt = getopt(argc, argv, "C:df:r:m:a:F:eE:lqD")) != EOF) {
	switch(opt) {
	case 'C': /* alt config file */
	    alt_config = optarg;
	    break;

	case 'd':
	    /* Ignore -- /bin/mail compatibility flags */
	    break;

        case 'D':
	    logdebug = 1;
	    break;

	case 'r':
	case 'f':
	    return_path = optarg;
	    break;

	case 'm':
	    if (mailboxname) {
		fprintf(stderr, "deliver: multiple -m options\n");
		usage();
		/* NOTREACHED */
	    }
	    if (*optarg) mailboxname = optarg;
	    break;

	case 'a':
	    if (authuser) {
		fprintf(stderr, "deliver: multiple -a options\n");
		usage();
		/* NOTREACHED */
	    }
	    authuser = optarg;
	    break;

	case 'F': /* set IMAP flag. we no longer support this */
	    fprintf(stderr,"deliver: 'F' option no longer supported\n");
	    usage();
	    break;

	case 'e':
	    /* duplicate delivery. ignore */
	    break;

	case 'E':
	    fprintf(stderr,"deliver: 'E' option no longer supported\n");
	    usage();
	    break;

	case 'l':
	    lmtpflag = 1;
	    break;

	case 'q':
	    ignorequota = 1;
	    break;

	default:
	    usage();
	    /* NOTREACHED */
	}
    }

    deliver_in = prot_new(0, 0);
    deliver_out = prot_new(1, 1);
    prot_setflushonread(deliver_in, deliver_out);
    prot_settimeout(deliver_in, 300);

    cyrus_init(alt_config, "deliver", CYRUSINIT_NODB);

    sockaddr = config_getstring(IMAPOPT_LMTPSOCKET);
    if (!sockaddr) {	
	strlcpy(buf, config_dir, sizeof(buf));
	strlcat(buf, "/socket/lmtp", sizeof(buf));
	sockaddr = buf;
    }

    if (lmtpflag == 1) {
	struct backend *conn = init_net(sockaddr);

	pipe_through(conn);

	backend_disconnect(conn);
	free(conn);
    }
    else {
	if (return_path == NULL) {
	    uid_t me = getuid();
	    struct passwd *p = getpwuid(me);
	    return_path = p->pw_name;
	}

	/* deliver to users or global mailbox */
	r = deliver_msg(return_path,authuser, ignorequota,
			argv+optind, argc - optind, mailboxname);
    }

    cyrus_done();

    return r;
}
Exemplo n.º 19
0
int main(int argc, char *argv[])
{
    extern char *optarg;
    int opt;
    char *alt_config = NULL, *port = "119";
    const char *peer = NULL, *server = "localhost", *wildmat = "*";
    char *authname = NULL, *password = NULL;
    int psock = -1, ssock = -1;
    struct protstream *pin, *pout, *sin, *sout;
    char buf[BUFFERSIZE];
    char sfile[1024] = "";
    int fd = -1, i, offered, rejected, accepted, failed;
    time_t stamp;
    strarray_t resp = STRARRAY_INITIALIZER;
    int newnews = 1;
    char *datefmt = "%y%m%d %H%M%S";

    if ((geteuid()) == 0 && (become_cyrus(/*is_master*/0) != 0)) {
	fatal("must run as the Cyrus user", EC_USAGE);
    }

    while ((opt = getopt(argc, argv, "C:s:w:f:a:p:ny")) != EOF) {
	switch (opt) {
	case 'C': /* alt config file */
	    alt_config = optarg;
	    break;

	case 's': /* server */
	    server = xstrdup(optarg);
	    if ((port = strchr(server, ':')))
		*port++ = '\0';
	    else
		port = "119";
	    break;

	case 'w': /* wildmat */
	    wildmat = optarg;
	    break;

	case 'f': /* timestamp file */
	    snprintf(sfile, sizeof(sfile), "%s", optarg);
	    break;

	case 'a': /* authname */
	    authname = optarg;
	    break;

	case 'p': /* password */
	    password = optarg;
	    break;

	case 'n': /* no newnews */
	    newnews = 0;
	    break;

	case 'y': /* newsserver is y2k compliant */
	    datefmt = "%Y%m%d %H%M%S";
	    break;

	default:
	    usage();
	    /* NOTREACHED */
	}
    }
    if (argc - optind < 1) {
	usage();
	/* NOTREACHED */
    }

    peer = argv[optind++];

    cyrus_init(alt_config, "fetchnews", 0, 0);

    /* connect to the peer */
    /* xxx configurable port number? */
    if ((psock = init_net(peer, "119", &pin, &pout)) < 0) {
	fprintf(stderr, "connection to %s failed\n", peer);
	cyrus_done();
	exit(-1);
    }

    /* read the initial greeting */
    if (!prot_fgets(buf, sizeof(buf), pin) || strncmp("20", buf, 2)) {
	syslog(LOG_ERR, "peer not available");
	goto quit;
    }

    if (authname) {
	/* authenticate to peer */
	/* XXX this should be modified to support SASL and STARTTLS */

	prot_printf(pout, "AUTHINFO USER %s\r\n", authname);
	if (!prot_fgets(buf, sizeof(buf), pin)) {
	    syslog(LOG_ERR, "AUTHINFO USER terminated abnormally");
	    goto quit;
	}
	else if (!strncmp("381", buf, 3)) {
	    /* password required */
	    if (!password)
		password = cyrus_getpass("Please enter the password: "******"failed to get password\n");
		goto quit;
	    }

	    prot_printf(pout, "AUTHINFO PASS %s\r\n", password);
	    if (!prot_fgets(buf, sizeof(buf), pin)) {
		syslog(LOG_ERR, "AUTHINFO PASS terminated abnormally");
		goto quit;
	    }
	}

	if (strncmp("281", buf, 3)) {
	    /* auth failed */
	    goto quit;
	}
    }

    /* change to reader mode - not always necessary, so ignore result */
    prot_printf(pout, "MODE READER\r\n");
    prot_fgets(buf, sizeof(buf), pin);

    if (newnews) {
	struct tm ctime, *ptime;

	/* fetch the server's current time */
	prot_printf(pout, "DATE\r\n");

	if (!prot_fgets(buf, sizeof(buf), pin) || strncmp("111 ", buf, 4)) {
	    syslog(LOG_ERR, "error fetching DATE");
	    goto quit;
	}

	/* parse and normalize the server time */
	memset(&ctime, 0, sizeof(struct tm));
	sscanf(buf+4, "%4d%02d%02d%02d%02d%02d",
	       &ctime.tm_year, &ctime.tm_mon, &ctime.tm_mday,
	       &ctime.tm_hour, &ctime.tm_min, &ctime.tm_sec);
	ctime.tm_year -= 1900;
	ctime.tm_mon--;
	ctime.tm_isdst = -1;

	/* read the previous timestamp */
	if (!sfile[0]) {
	    char oldfile[1024];

	    snprintf(sfile, sizeof(sfile), "%s/fetchnews.stamp", config_dir);

	    /* upgrade from the old stamp filename to the new */
	    snprintf(oldfile, sizeof(oldfile), "%s/newsstamp", config_dir);
	    rename(oldfile, sfile);
	}

	if ((fd = open(sfile, O_RDWR | O_CREAT, 0644)) == -1) {
	    syslog(LOG_ERR, "cannot open %s", sfile);
	    goto quit;
	}
	if (lock_nonblocking(fd) == -1) {
	    syslog(LOG_ERR, "cannot lock %s: %m", sfile);
	    goto quit;
	}

	if (read(fd, &stamp, sizeof(stamp)) < (int) sizeof(stamp)) {
	    /* XXX do something better here */
	    stamp = 0;
	}

	/* ask for new articles */
	if (stamp) stamp -= 180; /* adjust back 3 minutes */
	ptime = gmtime(&stamp);
	ptime->tm_isdst = -1;
	strftime(buf, sizeof(buf), datefmt, ptime);
	prot_printf(pout, "NEWNEWS %s %s GMT\r\n", wildmat, buf);
	
	if (!prot_fgets(buf, sizeof(buf), pin) || strncmp("230", buf, 3)) {
	    syslog(LOG_ERR, "peer doesn't support NEWNEWS");
	    newnews = 0;
	}

	/* prepare server's current time as new timestamp */
	stamp = mktime(&ctime);
	/* adjust for local timezone

	   XXX  We need to do this because we use gmtime() above.
	   We can't change this, otherwise we'd be incompatible
	   with an old localtime timestamp.
	*/
	stamp += gmtoff_of(&ctime, stamp);
    }

    if (!newnews) {
	prot_printf(pout, "LIST ACTIVE %s\r\n", wildmat);
	
	if (!prot_fgets(buf, sizeof(buf), pin) || strncmp("215", buf, 3)) {
	    syslog(LOG_ERR, "peer doesn't support LIST ACTIVE");
	    goto quit;
	}
    }

    /* process the NEWNEWS/LIST ACTIVE list */
    while (prot_fgets(buf, sizeof(buf), pin)) {
	if (buf[0] == '.') break;
	strarray_append(&resp, buf);
    }
    if (buf[0] != '.') {
	syslog(LOG_ERR, "%s terminated abnormally",
	       newnews ? "NEWNEWS" : "LIST ACTIVE");
	goto quit;
    }

    if (!resp.count) {
	/* nothing matches our wildmat */
	goto quit;
    }

    /* connect to the server */
    if ((ssock = init_net(server, port, &sin, &sout)) < 0) {
	fprintf(stderr, "connection to %s failed\n", server);
	goto quit;
    }

    /* read the initial greeting */
    if (!prot_fgets(buf, sizeof(buf), sin) || strncmp("20", buf, 2)) {
	syslog(LOG_ERR, "server not available");
	goto quit;
    }

    /* fetch and store articles */
    offered = rejected = accepted = failed = 0;
    if (newnews) {
	/* response is a list of msgids */
	for (i = 0; i < resp.count; i++) {
	    /* find the end of the msgid */
	    *(strrchr(resp.data[i], '>') + 1) = '\0';

	    offered++;
	    if (fetch(resp.data[i], 1, pin, pout, sin, sout,
		      &rejected, &accepted, &failed)) {
		goto quit;
	    }
	}

	/* write the current timestamp */
	lseek(fd, 0, SEEK_SET);
	if (write(fd, &stamp, sizeof(stamp)) < (int) sizeof(stamp))
	    syslog(LOG_ERR, "error writing %s", sfile);
	lock_unlock(fd);
	close(fd);
    }
    else {
	char group[BUFFERSIZE], msgid[BUFFERSIZE], lastbuf[50];
	const char *data;
	unsigned long low, high, last, cur;
	int start;
	size_t datalen;
	struct txn *tid = NULL;

	newsrc_init(NULL, 0);

	/*
	 * response is a list of groups.
	 * select each group, and STAT each article we haven't seen yet.
	 */
	for (i = 0; i < resp.count; i++) {
	    /* parse the LIST ACTIVE response */
	    sscanf(resp.data[i], "%s %lu %lu", group, &high, &low);

	    last = 0;
	    if (!cyrusdb_fetchlock(newsrc_db, group, strlen(group),
			       &data, &datalen, &tid)) {
		last = strtoul(data, NULL, 10);
	    }
	    if (high <= last) continue;

	    /* select the group */
	    prot_printf(pout, "GROUP %s\r\n", group);
	    if (!prot_fgets(buf, sizeof(buf), pin)) {
		syslog(LOG_ERR, "GROUP terminated abnormally");
		continue;
	    }
	    else if (strncmp("211", buf, 3)) break;

	    for (start = 1, cur = low > last ? low : ++last;; cur++) {
		if (start) {
		    /* STAT the first article we haven't seen */
		    prot_printf(pout, "STAT %lu\r\n", cur);
		} else {
		    /* continue with the NEXT article */
		    prot_printf(pout, "NEXT\r\n");
		}

		if (!prot_fgets(buf, sizeof(buf), pin)) {
		    syslog(LOG_ERR, "STAT/NEXT terminated abnormally");
		    cur--;
		    break;
		}
		if (!strncmp("223", buf, 3)) {
		    /* parse the STAT/NEXT response */
		    sscanf(buf, "223 %lu %s", &cur, msgid);

		    /* find the end of the msgid */
		    *(strrchr(msgid, '>') + 1) = '\0';

		    if (fetch(msgid, 0, pin, pout, sin, sout,
			      &rejected, &accepted, &failed)) {
			cur--;
			break;
		    }
		    offered++;
		    start = 0;
		}

		/* have we reached the highwater mark? */
		if (cur >= high) break;
	    }

	    snprintf(lastbuf, sizeof(lastbuf), "%lu", cur);
	    cyrusdb_store(newsrc_db, group, strlen(group),
		      lastbuf, strlen(lastbuf)+1, &tid);
	}

	if (tid) cyrusdb_commit(newsrc_db, tid);
	newsrc_done();
    }

    syslog(LOG_NOTICE,
	   "fetchnews: %s offered %d; %s rejected %d, accepted %d, failed %d",
	   peer, offered, server, rejected, accepted, failed);

  quit:
    if (psock >= 0) {
	prot_printf(pout, "QUIT\r\n");
	prot_flush(pout);

	/* Flush the incoming buffer */
	prot_NONBLOCK(pin);
	prot_fill(pin);

	/* close/free socket & prot layer */
	close(psock);
    
	prot_free(pin);
	prot_free(pout);
    }

    if (ssock >= 0) {
	prot_printf(sout, "QUIT\r\n");
	prot_flush(sout);

	/* Flush the incoming buffer */
	prot_NONBLOCK(sin);
	prot_fill(sin);

	/* close/free socket & prot layer */
	close(psock);
    
	prot_free(sin);
	prot_free(sout);
    }

    cyrus_done();
    
    return 0;
}
Exemplo n.º 20
0
int main(int argc, char *argv[])
{
    const char *alt_config = NULL;
    unsigned maxval = 0;
    int flags = SEQ_MERGE;
    struct seqset *seq = NULL;
    int opt;
    unsigned num;
    char *res;
    const char *origlist = NULL;

    while ((opt = getopt(argc, argv, "C:m:o:s")) != EOF) {
	switch (opt) {
	case 'C': /* alt config file */
	    alt_config = optarg;
	    break;
	case 'm': /* maxval */
	    parseuint32(optarg, NULL, &maxval);
	    break;
	case 'o':
	    origlist = optarg;
	    break;
	case 's':
	    flags = SEQ_SPARSE;
	}
    }
	
    if ((argc - optind) < 1) usage(argv[0]);

    cyrus_init(alt_config, "cyr_sequence", 0);

    /* special case */
    if (!strcmp(argv[optind], "create")) {
	int i;
	seq = seqset_init(maxval, flags);
	for (i = optind + 1; i < argc; i++) {
	    char *ptr = argv[i];
	    int isadd = 1;
	    if (*ptr == '~') {
		isadd = 0;
		ptr++;
	    }
	    if (parseuint32(ptr, NULL, &num))
		printf("%s NAN\n", argv[i]);
	    else
		seqset_add(seq, num, isadd);
	}
	if (origlist) {
	    unsigned oldmax = seq_lastnum(origlist, NULL);
	    if (oldmax > maxval) {
		struct seqset *origseq = seqset_parse(origlist, NULL, oldmax);
		unsigned val;
		for (val = maxval + 1; val <= oldmax; val++)
		    seqset_add(seq, val, seqset_ismember(origseq, val));
		seqset_free(origseq);
	    }
	}
	res = seqset_cstring(seq);
	printf("%s\n", res);
	free(res);
    }
    else if (!strcmp(argv[optind], "parsed")) {
	unsigned i;
	seq = seqset_parse(argv[optind+1], NULL, maxval);
	printf("Sections: " SIZE_T_FMT "\n", seq->len);
	for (i = 0; i < seq->len; i++) {
	    if (seq->set[i].high == UINT_MAX)
		printf(" [%u, *]\n", seq->set[i].low);
	    else
		printf(" [%u, %u]\n", seq->set[i].low, seq->set[i].high);
	}
    }
    else if (!strcmp(argv[optind], "compress")) {
	seq = seqset_parse(argv[optind+1], NULL, maxval);
	res = seqset_cstring(seq);
	printf("%s\n", res);
	free(res);
    }
    else if (!strcmp(argv[optind], "members")) {
	seq = seqset_parse(argv[optind+1], NULL, maxval);
	while ((num = seqset_getnext(seq))) {
	    printf("%u\n", num);
	}
    }
    else if (!strcmp(argv[optind], "join")) {
	struct seqset *seq2;
	seq = seqset_parse(argv[optind+1], NULL, maxval);
	seq2 = seqset_parse(argv[optind+2], NULL, maxval);
	seqset_join(seq, seq2);
	res = seqset_cstring(seq);
	printf("%s\n", res);
	free(res);
    }
    else if (!strcmp(argv[optind], "ismember")) {
	int i;
	seq = seqset_parse(argv[optind+1], NULL, maxval);
	for (i = optind + 2; i < argc; i++) {
	    if (parseuint32(argv[i], NULL, &num))
		printf("%s NAN\n", argv[i]);
	    else
		printf("%d %s\n", num, seqset_ismember(seq, num) ? "Yes" : "No");
	}
    }
    else {
	printf("Unknown command %s", argv[optind]);
    }

    seqset_free(seq);

    cyrus_done();

    return 0;
}
Exemplo n.º 21
0
/*
 * Read a news active file, building the group list
 */
void readactive(char *active)
{
    FILE *active_file;
    char buf[1024];
    char *p;
    const char *newsprefix;
    int newsprefixlen = 0;
    int lineno = 0;

    newsprefix = config_getstring("newsprefix", 0);
    if (newsprefix) {
	newsprefixlen = strlen(newsprefix);
	if (newsprefix[newsprefixlen-1] == '.') {
	    newsprefixlen--;
	}
    }

    active_file = fopen(active, "r");
    if (!active_file) {
	perror(active);
	syslog(LOG_ERR, "cannot read active file %s: %m", active);
	cyrus_done();
	exit(EC_NOINPUT);
    }

    while (fgets(buf, sizeof(buf), active_file)) {
	lineno++;
	p = strchr(buf, ' ');	/* end of group */
	if (!p) goto badactive;
	*p++ = '\0';
	p = strchr(p, ' ');	/* start of min */
	if (!p) goto badactive;
	p = strchr(p+1, ' ');
	if (!p) goto badactive;
	p++;
	if (*p == 'y' || *p == 'm' || *p == 'n') {
	    /* Add group to list */
	    if (group_num == group_alloc) {
		/* Grow arrary */
		group_alloc += GROUPGROW;
		group = (char **) xrealloc((char *)group,
					   group_alloc * sizeof(char *));
		group_seen = (int *) xrealloc((char *)group_seen,
					     group_alloc * sizeof(int));
	    }

	    if (newsprefixlen) {
		group[group_num] = xmalloc(strlen(buf)+newsprefixlen+2);
		strcpy(group[group_num], newsprefix);
		group[group_num][newsprefixlen] = '.';
		strcpy(group[group_num]+newsprefixlen+1, buf);
	    }
	    else {
		group[group_num] = xstrdup(buf);
	    }
	    group_seen[group_num] = 0;
	    group_num++;
	}
    }

    if (ferror(active_file)) {
	fprintf(stderr, "syncnews: error reading active file\n");
	syslog(LOG_ERR, "error reading active file");
	cyrus_done();
	exit(EC_DATAERR);
    }
    fclose(active_file);

    if (group_num == 0) {
	fprintf(stderr, "syncnews: no groups in active file\n");
	syslog(LOG_ERR, "no groups in active file");
	cyrus_done();
	exit(EC_DATAERR);
    }

    qsort(group, group_num, sizeof(char *), (int (*)(const void *, const void *)) compare_group);
    return;

  badactive:
    fprintf(stderr, "syncnews: bad line %d in active file\n", lineno);
    syslog(LOG_ERR, "bad line %d in active file", lineno);
    cyrus_done();
    exit(EC_DATAERR);
    
}
Exemplo n.º 22
0
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);
}
Exemplo n.º 23
0
EXPORTED void fatal(const char *error, int code)
{
    fprintf(stderr, "fatal error: %s\n", error);
    cyrus_done();
    exit(code);
}
Exemplo n.º 24
0
int main(int argc, char *argv[])
{
    extern char *optarg;
    int opt, r = 0;
    char *alt_file = NULL;
    char *alt_config = NULL;
    char *days = NULL;
    int flag = 0;
    enum { DUMP, PRUNE, NONE } op = NONE;

    if (geteuid() == 0) fatal("must run as the Cyrus user", EC_USAGE);

    while ((opt = getopt(argc, argv, "C:drE:f:")) != EOF) {
	switch (opt) {
	case 'C': /* alt config file */
	    alt_config = optarg;
	    break;

	case 'd':
	    if (op == NONE) op = DUMP;
	    else usage();
	    break;

        case 'f':
            if (alt_file == NULL) alt_file = optarg;
            else usage ();
            break;

	case 'E':
	    if (op == NONE) op = PRUNE;
	    else usage();
	    /* deprecated, but we still support it */
	    days = optarg;
	    break;
	
	default:
	    usage();
	    break;
	}
    }

    switch (op) {
    case PRUNE: {
	char buf[4096];

	fprintf(stderr, "ctl_deliver -E is deprecated: "
		"using cyr_expire -E instead\n");

	r = snprintf(buf, sizeof(buf), "%s/cyr_expire", SERVICE_PATH);
	if(r < 0 || r >= sizeof(buf)) {
	    fatal("cyr_expire command buffer not sufficiently big", EC_CONFIG);
	}

	if (alt_config)
	    execl(buf, buf, "-C", alt_config, "-E", days, NULL);
	else
	    execl(buf, buf, "-E", days, NULL);

	break;
    }

    case DUMP:
	cyrus_init(alt_config, "ctl_deliver", 0);

	if (duplicate_init(alt_file, flag) != 0) {
	    fprintf(stderr, 
		    "ctl_deliver: unable to init duplicate delivery database\n");
	    exit(1);
	}

	printf("it is NOW: %d\n", (int) time(NULL));
	printf("got %d entries\n", duplicate_dump(stdout));

	r = 0;

	duplicate_done();
	cyrus_done();
	break;

    case NONE:
	r = 2;
	usage();
	break;
    }

    return r;
}
Exemplo n.º 25
0
void fatal(const char* s, int code)
{
    fprintf(stderr, "syncnews: %s\n", s);
    cyrus_done();
    exit(code);
}
Exemplo n.º 26
0
int main (int argc, char *argv[]) {
    int option;		/* getopt() returns an int */
    char buf[MAX_MAILBOX_PATH+1];
    char *alt_config = NULL;
    int r;

    if ((geteuid()) == 0 && (become_cyrus() != 0)) {
	fatal("must run as the Cyrus user", EC_USAGE);
    }

    while ((option = getopt(argc, argv, "C:rn")) != EOF) {
	switch (option) {
	case 'C': /* alt config file */
	    alt_config = optarg;
	    break;

	case 'r':
	    disinfect = 1;
	    break;

	case 'n':
	    notify = 1;
	    break;

	case 'h':
	default: usage(argv[0]);
	}
    }

    cyrus_init(alt_config, "cyr_virusscan", 0);

    if (!engine.name) {
	fatal("no virus scanner configured", EC_SOFTWARE);
    } else {
	if (verbose) printf("Using %s virus scanner\n", engine.name);
    }

    engine.state = engine.init();

    /* Set namespace -- force standard (internal) */
    if ((r = mboxname_init_namespace(&scan_namespace, 1)) != 0) {
	syslog(LOG_ERR, "%s", error_message(r));
	fatal(error_message(r), EC_CONFIG);
    }

    mboxlist_init(0);
    mboxlist_open(NULL);

    /* open the quota db, we'll need it for expunge */
    quotadb_init(0);
    quotadb_open(NULL);

    sync_log_init();

    if (optind == argc) { /* do the whole partition */
	strcpy(buf, "*");
	(*scan_namespace.mboxlist_findall)(&scan_namespace, buf, 1, 0, 0,
					   scan_me, NULL);
    } else {
	for (; optind < argc; optind++) {
	    strncpy(buf, argv[optind], MAX_MAILBOX_BUFFER);
	    /* Translate any separators in mailboxname */
	    mboxname_hiersep_tointernal(&scan_namespace, buf,
					config_virtdomains ?
					strcspn(buf, "@") : 0);
	    (*scan_namespace.mboxlist_findall)(&scan_namespace, buf, 1, 0, 0,
					       scan_me, NULL);
	}
    }

    if (notify) append_notifications();

    sync_log_done();

    quotadb_close();
    quotadb_done();

    mboxlist_close();
    mboxlist_done();

    engine.destroy(engine.state);

    cyrus_done();

    return 0;
}
Exemplo n.º 27
0
int
main(int argc, char **argv)
{
  char *path, *mpath;
  int rc, i, quiet = 0, stop_on_error=0, metadata=0;
  int opt;		/* getopt() returns an int */
  char *alt_config = NULL;
  char buf[MAX_MAILBOX_PATH+1];

  if (geteuid() == 0) fatal("must run as the Cyrus user", EC_USAGE);

  while ((opt = getopt(argc, argv, "C:qsm")) != EOF) {
    switch(opt) {
    case 'C': /* alt config file */
      alt_config = optarg;
      break;
    case 'q':
      quiet = 1;
      break;
    case 's':
      stop_on_error = 1;
      break;
    case 'm':
	metadata = 1;
	break;

    default:
      usage();
    }
  }

  cyrus_init(alt_config, "mbpath", 0);

  if ((rc = mboxname_init_namespace(&mbpath_namespace, 1)) != 0) {
    fatal(error_message(rc), -1);
  }

  mboxlist_init(0);
  mboxlist_open(NULL);

  for (i = optind; i < argc; i++) {
    (void)memset(&path, 0, sizeof(path));

    /* Translate mailboxname */
    (*mbpath_namespace.mboxname_tointernal)(&mbpath_namespace, argv[i], NULL, buf);

    if ((rc = mboxlist_detail(buf, NULL, &path, &mpath,
			      NULL, NULL, NULL)) == 0) {
      if (metadata && mpath) printf("%s\n", mpath);
      else printf("%s\n", path);
    } else {
      if (!quiet && (rc == IMAP_MAILBOX_NONEXISTENT)) {
	fprintf(stderr, "Invalid mailbox name: %s\n", argv[i]);
      }
      if (stop_on_error) {
	if (quiet) {
	  fatal("", -1);
	} else {
	  fatal("Error in processing mailbox. Stopping\n", -1);
	}
      }
    }
  }

  mboxlist_close();
  mboxlist_done();

  cyrus_done();

  return 0;
}
Exemplo n.º 28
0
int main(int argc,char **argv)
{
    int opt;
    int i;
    int fflag = 0;
    int r, code = 0;
    int do_report = 1;
    char *alt_config = NULL, *domain = NULL;

    if ((geteuid()) == 0 && (become_cyrus(/*is_master*/0) != 0)) {
	fatal("must run as the Cyrus user", EC_USAGE);
    }

    while ((opt = getopt(argc, argv, "C:d:fqZ")) != EOF) {
	switch (opt) {
	case 'C': /* alt config file */
	    alt_config = optarg;
	    break;

	case 'q':
	    do_report = 0;
	    break;

	case 'd':
	    domain = optarg;
	    break;

	case 'f':
	    fflag = 1;
	    break;

	/* deliberately undocumented option for testing */
	case 'Z':
	    test_sync_mode = 1;
	    break;

	default:
	    usage();
	}
    }

    /* always report if not fixing, otherwise we do nothing */
    if (!fflag)
	do_report = 1;

    cyrus_init(alt_config, "quota", 0, CONFIG_NEED_PARTITION_DATA);

    /* Set namespace -- force standard (internal) */
    if ((r = mboxname_init_namespace(&quota_namespace, 1)) != 0) {
	syslog(LOG_ERR, "%s", error_message(r));
	fatal(error_message(r), EC_CONFIG);
    }

    if (config_getswitch(IMAPOPT_IMPROVED_MBOXLIST_SORT))
	compar = bsearch_compare_mbox;
    else
	compar = strcmp;

    /*
     * Lock mailbox list to prevent mailbox creation/deletion
     * during work
     */
    mboxlist_init(0);
    mboxlist_open(NULL);

    quotadb_init(0);
    quotadb_open(NULL);

    quota_changelock();

    if (!r)
	r = buildquotalist(domain, argv+optind, argc-optind);

    if (!r && fflag)
	r = fixquotas(domain, argv+optind, argc-optind);

    quota_changelockrelease();

    if (r) code = convert_code(r);
    else if (do_report) reportquota();

    quotadb_close();
    quotadb_done();

    mboxlist_close();
    mboxlist_done();

    /* just for neatness */
    for (i = 0; i < quota_num; i++)
	free(quotaroots[i].name);
    free(quotaroots);

    cyrus_done();

    return code;
}
Exemplo n.º 29
0
int main(int argc, char **argv)
{
    int opt, r = 0;
    char *alt_config = NULL, *pub = NULL, *ver = NULL, *winfile = NULL;
    char prefix[2048];
    enum { REBUILD, WINZONES, NONE } op = NONE;

    if ((geteuid()) == 0 && (become_cyrus(/*ismaster*/0) != 0)) {
	fatal("must run as the Cyrus user", EC_USAGE);
    }

    while ((opt = getopt(argc, argv, "C:r:vw:")) != EOF) {
	switch (opt) {
	case 'C': /* alt config file */
	    alt_config = optarg;
	    break;

	case 'r':
	    if (op == NONE) {
		op = REBUILD;
		pub = optarg;
		ver = strchr(optarg, ':');
		if (ver) *ver++ = '\0';
		else usage();
	    }
	    else usage();
	    break;

	case 'v':
	    verbose = 1;
	    break;

	case 'w':
	    if (op == NONE) {
		op = WINZONES;
		winfile = optarg;
	    }
	    else usage();
	    break;

	default:
	    usage();
	}
    }

    cyrus_init(alt_config, "ctl_zoneinfo", 0, 0);

    signals_set_shutdown(&shut_down);
    signals_add_handlers(0);

    snprintf(prefix, sizeof(prefix), "%s%s", config_dir, FNAME_ZONEINFODIR);

    switch (op) {
    case REBUILD: {
	struct hash_table tzentries;
	struct zoneinfo *info;
	struct txn *tid = NULL;
	char buf[1024];
	FILE *fp;

	construct_hash_table(&tzentries, 500, 1);

	/* Add INFO record (overall lastmod and TZ DB source version) */
	info = xzmalloc(sizeof(struct zoneinfo));
	info->type = ZI_INFO;
	appendstrlist(&info->data, pub);
	appendstrlist(&info->data, ver);
	hash_insert(INFO_TZID, info, &tzentries);

	/* Add LEAP record (last updated and hash) */
	snprintf(buf, sizeof(buf), "%s%s", prefix, FNAME_LEAPSECFILE);
	if (verbose) printf("Processing leap seconds file %s\n", buf);
	if (!(fp = fopen(buf, "r"))) {
	    fprintf(stderr, "Could not open leap seconds file %s\n", buf);
	}
	else {
	    struct zoneinfo *leap = xzmalloc(sizeof(struct zoneinfo));
	    leap->type = ZI_INFO;

	    while(fgets(buf, sizeof(buf), fp)) {
		if (buf[0] == '#') {
		    /* comment line */

		    if (buf[1] == '$') {
			/* last updated */
			unsigned long last;

			sscanf(buf+2, "\t%lu", &last);
			leap->dtstamp = last - NIST_EPOCH_OFFSET;
		    }
		    else if (buf[1] == 'h') {
			/* hash */
			char *p, *hash = buf+3 /* skip "#h\t" */;

			/* trim trailing whitespace */
			for (p = hash + strlen(hash); isspace(*--p); *p = '\0');
			appendstrlist(&leap->data, hash);
		    }
		}
	    }
	    fclose(fp);

	    hash_insert(LEAP_TZID, leap, &tzentries);
	    info->dtstamp = leap->dtstamp;
	}

	/* Add ZONE/LINK records */
	do_zonedir(prefix, &tzentries, info);

	zoneinfo_open(NULL);

	/* Store records */
	hash_enumerate(&tzentries, &store_zoneinfo, &tid);

	zoneinfo_close(tid);

	free_hash_table(&tzentries, &free_zoneinfo);
	break;
    }

    case WINZONES: {
	xmlParserCtxtPtr ctxt;
	xmlDocPtr doc;
	xmlNodePtr node;
	struct buf tzidbuf = BUF_INITIALIZER;
	struct buf aliasbuf = BUF_INITIALIZER;

	if (verbose) printf("Processing Windows Zone file %s\n", winfile);

	/* Parse the XML file */
	ctxt = xmlNewParserCtxt();
	if (!ctxt) {
	    fprintf(stderr, "Failed to create XML parser context\n");
	    break;
	}

	doc = xmlCtxtReadFile(ctxt, winfile, NULL, 0);
	xmlFreeParserCtxt(ctxt);
	if (!doc) {
	    fprintf(stderr, "Failed to parse XML document\n");
	    break;
	}

	node = xmlDocGetRootElement(doc);
	if (!node || xmlStrcmp(node->name, BAD_CAST "supplementalData")) {
	    fprintf(stderr, "Incorrect root node\n");
	    goto done;
	}

	for (node = xmlFirstElementChild(node);
	     node && xmlStrcmp(node->name, BAD_CAST "windowsZones");
	     node = xmlNextElementSibling(node));
	if (!node) {
	    fprintf(stderr, "Missing windowsZones node\n");
	    goto done;
	}

	node = xmlFirstElementChild(node);
	if (!node || xmlStrcmp(node->name, BAD_CAST "mapTimezones")) {
	    fprintf(stderr, "Missing mapTimezones node\n");
	    goto done;
	}

	if (chdir(prefix)) {
	    fprintf(stderr, "chdir(%s) failed\n", prefix);
	    goto done;
	}

	for (node = xmlFirstElementChild(node);
	     node;
	     node = xmlNextElementSibling(node)) {
	    if (!xmlStrcmp(node->name, BAD_CAST "mapZone") &&
		!xmlStrcmp(xmlGetProp(node, BAD_CAST "territory"),
			   BAD_CAST "001")) {
		const char *tzid, *alias;

		buf_setcstr(&tzidbuf,
			    (const char *) xmlGetProp(node, BAD_CAST "type"));
		buf_appendcstr(&tzidbuf, ".ics");
		tzid = buf_cstring(&tzidbuf);
		buf_setcstr(&aliasbuf,
			    (const char *) xmlGetProp(node, BAD_CAST "other"));
		buf_appendcstr(&aliasbuf, ".ics");
		alias = buf_cstring(&aliasbuf);

		if (verbose) printf("\tLINK: %s -> %s\n", alias, tzid);

		if (symlink(tzid, alias)) {
		    if (errno == EEXIST) {
			struct stat sbuf;

			if (stat(alias, &sbuf)) {
			    fprintf(stderr, "stat(%s) failed: %s\n",
				    alias, strerror(errno));
			    errno = EEXIST;
			}
			else if (sbuf.st_mode & S_IFLNK) {
			    char link[MAX_MAILBOX_PATH+1];
			    int n = readlink(alias, link, MAX_MAILBOX_PATH);

			    if (n == -1) {
				fprintf(stderr, "readlink(%s) failed: %s\n",
					alias, strerror(errno));
				errno = EEXIST;
			    }
			    else if (n == (int) strlen(tzid) &&
				     !strncmp(tzid, link, n)) {
				errno = 0;
			    }
			}
		    }

		    if (errno) {
			fprintf(stderr, "symlink(%s, %s) failed: %s\n",
				tzid, alias, strerror(errno));
		    }
		}
	    }
	}

  done:
	buf_free(&aliasbuf);
	buf_free(&tzidbuf);
	xmlFreeDoc(doc);
	break;
    }

    case NONE:
	r = 2;
	usage();
	break;
    }

    cyrus_done();

    return r;
}
Exemplo n.º 30
0
int main(int argc, char *argv[])
{
    const char *OLDDB = NULL, *NEWDB = NULL;
    const char *old_db, *new_db;
    int i;
    int opt;
    char *alt_config = NULL;

    while ((opt = getopt(argc, argv, "C:")) != EOF) {
	switch (opt) {
	case 'C': /* alt config file */
	    alt_config = optarg;
	    break;
	}
    }

    if ((argc - optind) != 4) {
	strarray_t *backends = cyrusdb_backends();
	char sep;

	fprintf(stderr, "Usage: %s [-C altconfig] <old db> <old db backend> <new db> <new db backend>\n", argv[0]);
	fprintf(stderr, "Usable Backends:  ");

	for(i=0, sep = ':'; i < backends->count; i++) {
	    fprintf(stderr, "%c %s", sep, strarray_nth(backends, i));
	    sep = ',';
	}
	strarray_free(backends);

	fprintf(stderr, "\n");
	exit(-1);
    }

    old_db = argv[optind];
    new_db = argv[optind+2];

    if (old_db[0] != '/' || new_db[0] != '/') {
	printf("\nSorry, you cannot use this tool with relative path names.\n"
	       "This is because some database backends (mainly berkeley) do not\n"
	       "always do what you would expect with them.\n"
	       "\nPlease use absolute pathnames instead.\n\n");
	exit(EC_OSERR);
    }

    OLDDB = argv[optind+1];
    NEWDB = argv[optind+3];

    if (NEWDB == OLDDB) {
	fatal("no conversion required", EC_TEMPFAIL);
    }

    cyrus_init(alt_config, "cvt_cyrusdb", 0);

    printf("Converting from %s (%s) to %s (%s)\n", old_db, OLDDB,
	   new_db, NEWDB);

    cyrusdb_convert(old_db, new_db, OLDDB, NEWDB);

    cyrus_done();

    return 0;
}