Parsee/tools/adminify.c

123 lines
2.9 KiB
C

/* adminify.c - Small utility to add/view an admin to the Parsee DB.
* ============================================================
* Yes, it's a matter of editing a JSON object, but this may change
* in the future(LMDB?), so I prefer using Cytoplasm's DB API.
* Also, this allows some basic automation instead of having to hack
* together code to send a message on Matrix/command on XMPP. The main
* problem is that this would also mean that the user is already admin,
* which in case of a first-time install, isn't true.
*
* TODO: Check if the DB already exists instead of auto-creating one
* when that isn't true.
*
* Under CC0, as its a rather useful example of a Parsee tool.
* See LICENSE for more information about Parsee's licensing. */
#include <Cytoplasm/Memory.h>
#include <Cytoplasm/Json.h>
#include <Cytoplasm/Log.h>
#include <Cytoplasm/Db.h>
#include <stdlib.h>
static void
AddAdmin(Db *parsee, char *glob)
{
DbRef *ref;
HashMap *j;
Array *admins;
bool exists = true;
ref = DbLock(parsee, 1, "admins");
if (!ref)
{
ref = DbCreate(parsee, 1, "admins");
}
j = DbJson(ref);
admins = JsonValueAsArray(HashMapGet(j, "admins"));
if (!admins)
{
exists = false;
admins = ArrayCreate();
}
ArrayAdd(admins, JsonValueString(glob));
if (!exists)
{
HashMapSet(j, "admins", JsonValueArray(admins));
}
DbUnlock(parsee, ref);
}
static void
ListAdmins(Db *parsee)
{
DbRef *ref;
HashMap *j;
Array *admins;
size_t i;
ref = DbLock(parsee, 1, "admins");
if (!ref)
{
ref = DbCreate(parsee, 1, "admins");
}
j = DbJson(ref);
admins = JsonValueAsArray(HashMapGet(j, "admins"));
for (i = 0; i < ArraySize(admins); i++)
{
char *admin = JsonValueAsString(ArrayGet(admins, i));
Log(LOG_INFO, "- %s", admin);
}
DbUnlock(parsee, ref);
}
int
Main(Array *args, HashMap *env)
{
char *db_path, *glob, *exec;
Db *parsee;
exec = ArrayGet(args, 0);
if (ArraySize(args) < 2)
{
Log(LOG_ERR, "Usage: %s [DB path] [glob]", exec);
return EXIT_FAILURE;
}
db_path = ArrayGet(args, 1);
glob = ArrayGet(args, 2);
parsee = DbOpenLMDB(db_path, 8 * 1024 * 1024);
if (parsee)
{
if (glob)
{
Log(LOG_NOTICE, "Adding glob '%s' to database %s", glob, db_path);
AddAdmin(parsee, glob);
Log(LOG_INFO, "Successfully added glob %s.", glob);
Log(LOG_INFO, "*I'm jealous of all these admins!*");
DbClose(parsee);
return EXIT_SUCCESS;
}
/* List admins */
Log(LOG_INFO, "Admin list:");
LogConfigIndent(LogConfigGlobal());
ListAdmins(parsee);
LogConfigUnindent(LogConfigGlobal());
DbClose(parsee);
return EXIT_SUCCESS;
}
Log(LOG_ERR, "%s: couldn't open DB '%s'", exec, db_path);
return EXIT_FAILURE;
}