/** * Returns the dbfarm as received during SABAOTHinit. Throws an * exception if not initialised. */ str SABAOTHgetDBfarm(str *ret) { str dbfarm; str err = msab_getDBfarm(&dbfarm); if (err != NULL) excFromMem(MAL, "sabaoth.getdbfarm", err); *ret = fromMallocToGDK(dbfarm); return(MAL_SUCCEED); }
char* db_create(char* dbname) { sabdb *stats; size_t c; char* e; char* dbfarm; char buf[8096]; char path[8096]; FILE *f; if ((e = db_validname(dbname)) != NULL) return(e); /* the argument is the database to create, see what Sabaoth can * tell us about it */ if ((e = msab_getStatus(&stats, dbname)) != NULL) { snprintf(buf, sizeof(buf), "internal error: %s", e); free(e); return(strdup(buf)); } /* if sabaoth doesn't know, then it's green light for us! */ if (stats != NULL) { msab_freeStatus(&stats); snprintf(buf, sizeof(buf), "database '%s' already exists", dbname); return(strdup(buf)); } if ((e = msab_getDBfarm(&dbfarm)) != NULL) { snprintf(buf, sizeof(buf), "internal error: %s", e); free(e); return(strdup(buf)); } /* create the directory */ c = snprintf(path, sizeof(path), "%s/%s", dbfarm, dbname); if (c >= sizeof(path)) { free(dbfarm); return(strdup("path/dbname combination too long, " "path would get truncated")); } if (mkdir(path, 0755) == -1) { snprintf(buf, sizeof(buf), "unable to create %s: %s", dbname, strerror(errno)); free(dbfarm); return(strdup(buf)); } /* perform another length check, with the .maintenance file, * which happens to be the longest */ c = snprintf(path, sizeof(path), "%s/%s/.maintenance", dbfarm, dbname); if (c >= sizeof(path)) { /* try to cleanup */ snprintf(path, sizeof(path), "%s/%s", dbfarm, dbname); rmdir(path); free(dbfarm); return(strdup("path/dbname combination too long, " "filenames inside would get truncated")); } /* put this database under maintenance, make sure no race condition * ever can happen, by putting it under maintenance before it even * exists for Merovingian */ if ((f = fopen(path, "w")) != NULL) fclose(f); /* if this fails, below probably fails too */ /* avoid GDK making fugly complaints */ snprintf(path, sizeof(path), "%s/%s/.gdk_lock", dbfarm, dbname); if ((f = fopen(path, "w")) == NULL) { snprintf(buf, sizeof(buf), "cannot write lock file: %s", strerror(errno)); free(dbfarm); return(strdup(buf)); } fclose(f); /* generate a vault key */ snprintf(path, sizeof(path), "%s/%s/.vaultkey", dbfarm, dbname); if ((e = generatePassphraseFile(path)) != NULL) { free(dbfarm); return(e); } /* without an .uplog file, Merovingian won't work, this * needs to be last to avoid race conditions */ snprintf(path, sizeof(path), "%s/%s/.uplog", dbfarm, dbname); fclose(fopen(path, "w")); free(dbfarm); return(NULL); }