/**
   \details Initialize the named properties database or return pointer
   to the existing one if already initialized/opened.

   \param mem_ctx pointer to the memory context
   \param ldb_ctx pointer on pointer to the ldb context the function
   returns

   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
 */
enum mapistore_error mapistore_namedprops_init(TALLOC_CTX *mem_ctx, struct ldb_context **_ldb_ctx)
{
	int			ret;
	struct stat		sb;
	struct ldb_context	*ldb_ctx = NULL;
	struct ldb_ldif		*ldif;
	char			*filename;
	FILE			*f;
	struct tevent_context	*ev;
	char			*database;

	/* Sanity checks */
	MAPISTORE_RETVAL_IF(!mem_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
	MAPISTORE_RETVAL_IF(!_ldb_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);

	ev = tevent_context_init(mem_ctx);
	MAPISTORE_RETVAL_IF(!ev, MAPISTORE_ERR_NO_MEMORY, NULL);

	database = talloc_asprintf(mem_ctx, "%s/%s", mapistore_get_mapping_path(), MAPISTORE_DB_NAMED);
	DEBUG(0, ("database = %s\n", database));

	/* Step 1. Stat the database and populate it if it doesn't exist */
	if (stat(database, &sb) == -1) {
		ldb_ctx = mapistore_ldb_wrap_connect(ldb_ctx, ev, database, 0);
		talloc_free(database);
		MAPISTORE_RETVAL_IF(!ldb_ctx, MAPISTORE_ERR_DATABASE_INIT, NULL);

		filename = talloc_asprintf(mem_ctx, "%s/mapistore_namedprops.ldif", 
					   mapistore_namedprops_get_ldif_path());
		f = fopen(filename, "r");
		talloc_free(filename);
		MAPISTORE_RETVAL_IF(!f, MAPISTORE_ERROR, NULL);
		
		ldb_transaction_start(ldb_ctx);

		while ((ldif = ldb_ldif_read_file(ldb_ctx, f))) {
			struct ldb_message *normalized_msg;
			ret = ldb_msg_normalize(ldb_ctx, mem_ctx, ldif->msg, &normalized_msg);
			MAPISTORE_RETVAL_IF(ret, MAPISTORE_ERR_DATABASE_INIT, NULL);
			ret = ldb_add(ldb_ctx, normalized_msg);
			talloc_free(normalized_msg);
			if (ret != LDB_SUCCESS) {
				fclose(f);
				MAPISTORE_RETVAL_IF(ret, MAPISTORE_ERR_DATABASE_INIT, NULL);
			}
			ldb_ldif_read_free(ldb_ctx, ldif);
		}

		ldb_transaction_commit(ldb_ctx);
		fclose(f);

	} else {
		ldb_ctx = mapistore_ldb_wrap_connect(ldb_ctx, ev, database, 0);
		talloc_free(database);
		MAPISTORE_RETVAL_IF(!ldb_ctx, MAPISTORE_ERR_DATABASE_INIT, NULL);
	}

	*_ldb_ctx = ldb_ctx;

	return MAPISTORE_SUCCESS;
}
Пример #2
0
/**
  \details Initialize the database and provision it

  \param conn pointer to the MySQL context
  \param schema_path pointer to the path holding schema files

  \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
 */
static enum mapistore_error initialize_database(MYSQL *conn, const char *schema_path)
{
	TALLOC_CTX		*mem_ctx;
	enum mapistore_error	retval = MAPISTORE_SUCCESS;
	struct ldb_context	*ldb_ctx;
	struct ldb_ldif		*ldif;
	struct ldb_message	*msg;
	int			ret;
	char			*filename;
	FILE			*f;
	bool			inserted;
	bool			schema_created;

	/* Sanity checks */
	MAPISTORE_RETVAL_IF(!conn, MAPISTORE_ERR_DATABASE_INIT, NULL);

	mem_ctx = talloc_named(NULL, 0, "initialize_database");
	MAPISTORE_RETVAL_IF(!mem_ctx, MAPISTORE_ERR_NO_MEMORY, NULL);

	filename = talloc_asprintf(mem_ctx, "%s/" NAMEDPROPS_MYSQL_SCHEMA,
				   schema_path ? schema_path : mapistore_namedprops_get_ldif_path());
	MAPISTORE_RETVAL_IF(!filename, MAPISTORE_ERR_NO_MEMORY, mem_ctx);
	schema_created = create_schema(conn, filename);
	if (!schema_created) {
		DEBUG(1, ("Failed named properties schema creation, "
			  "last mysql error was: `%s`\n", mysql_error(conn)));
		MAPISTORE_RETVAL_ERR(MAPISTORE_ERR_DATABASE_INIT, mem_ctx);
	}

	ldb_ctx = ldb_init(mem_ctx, NULL);
	MAPISTORE_RETVAL_IF(!ldb_ctx, MAPISTORE_ERR_BACKEND_INIT, mem_ctx);

	filename = talloc_asprintf(mem_ctx, "%s/mapistore_namedprops.ldif",
				   schema_path ? schema_path : mapistore_namedprops_get_ldif_path());
	MAPISTORE_RETVAL_IF(!filename, MAPISTORE_ERR_NO_MEMORY, mem_ctx);

	f = fopen(filename, "r");
	talloc_free(filename);
	MAPISTORE_RETVAL_IF(!f, MAPISTORE_ERR_BACKEND_INIT, mem_ctx);
	
	while ((ldif = ldb_ldif_read_file(ldb_ctx, f))) {
		ret = ldb_msg_normalize(ldb_ctx, mem_ctx, ldif->msg, &msg);
		if (ret) {
			retval = MAPISTORE_ERR_DATABASE_INIT;
			mapistore_set_errno(MAPISTORE_ERR_DATABASE_INIT);
			goto end;
		}

		inserted = insert_ldif_msg(conn, msg);
		ldb_ldif_read_free(ldb_ctx, ldif);
		if (!inserted) {
			retval = MAPISTORE_ERR_DATABASE_OPS;
			mapistore_set_errno(MAPISTORE_ERR_DATABASE_OPS);
			goto end;
		}
	}

end:
	talloc_free(mem_ctx);
	fclose(f);

	return retval;
}