Esempio n. 1
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;
}
Esempio n. 2
0
EXPORTED int cyrusdb_open(const char *backend, const char *fname,
		 int flags, struct db **ret)
{
    const char *realname;
    struct db *db = xzmalloc(sizeof(struct db));
    int r;

    if (!backend) backend = DEFAULT_BACKEND; /* not used yet, later */
    db->backend = cyrusdb_fromname(backend);

    /* This whole thing is a fricking critical section.  We don't have the API
     * in place for a safe rename of a locked database, so the choices are
     * basically:
     * a) convert each DB layer to support locked database renames while still
     *    in the transaction.  Best, but lots of work.
     * b) rename and hope... unreliable
     * c) global lock around this block of code.  Safest and least efficient.
     */

    /* check if it opens normally.  Horray */
    r = db->backend->open(fname, flags, &db->engine);
    if (r == CYRUSDB_NOTFOUND) goto done; /* no open flags */
    if (!r) goto done;

    /* magic time - we need to work out if the file was created by a different
     * backend and convert if possible */

    realname = cyrusdb_detect(fname);
    if (!realname) {
	syslog(LOG_ERR, "DBERROR: failed to detect DB type for %s (backend %s) (r was %d)",
	       fname, backend, r);
	/* r is still set */
	goto done;
    }

    /* different type */
    if (strcmp(realname, backend)) {
	if (flags & CYRUSDB_CONVERT) {
	    r = cyrusdb_convert(fname, fname, realname, backend);
	    if (r) {
		syslog(LOG_ERR, "DBERROR: failed to convert %s from %s to %s, maybe someone beat us",
		       fname, realname, backend);
	    }
	    else {
		syslog(LOG_NOTICE, "cyrusdb: converted %s from %s to %s",
		       fname, realname, backend);
	    }
	}
	else {
	    syslog(LOG_NOTICE, "cyrusdb: opening %s with backend %s (requested %s)",
		   fname, realname, backend);
	    db->backend = cyrusdb_fromname(realname);
	}
    }
    
    r = db->backend->open(fname, flags, &db->engine);

done:

    if (r) free(db);
    else *ret = db;

    return r;
}