/* plumb.c - Small utility to manage plumbings from a shutoff instance. * ============================================================ * TODO: write other commands, and move some code to common.h * * Under CC0, as its a rather useful example of a Parsee tool. * See LICENSE for more information about Parsee's licensing. */ #include "common.h" #include static void DeletePlumbID(Db *parsee, char *chat_id) { DbRef *chat_id_ref = DbLockIntent(parsee, DB_HINT_READONLY, 2, "chats", chat_id); DbRef *chats = DbLock(parsee, 1, "chats"); char *matrix_id = GrabString(DbJson(chat_id_ref), 1, "room_id"); char *jabber_id = GrabString(DbJson(chat_id_ref), 1, "jabber_id"); HashMap *rooms = GrabObject(DbJson(chats), 1, "rooms"); HashMap *mucs = GrabObject(DbJson(chats), 1, "mucs"); JsonValueFree(HashMapDelete(rooms, matrix_id)); JsonValueFree(HashMapDelete(mucs, jabber_id)); DbUnlock(parsee, chat_id_ref); DbUnlock(parsee, chats); DbDelete(parsee, 2, "chats", chat_id); } static void DeletePlumb(Db *parsee, char *potential_id) { if (!parsee || !potential_id) { return; } if (!strncmp(potential_id, "xmpp:", 5)) { DbRef *ref; HashMap *mucs; char *chat_id; /* Try to parse it as an XMPP address */ potential_id += 5; ref = DbLockIntent(parsee, DB_HINT_READONLY, 1, "chats"); mucs = GrabObject(DbJson(ref), 1, "mucs"); chat_id = StrDuplicate(GrabString(mucs, 1, potential_id)); DbUnlock(parsee, ref); DeletePlumbID(parsee, chat_id); Free(chat_id); return; } if (*potential_id == '!') { /* Try to parse it as a Matrix room ID */ DbRef *ref; HashMap *rooms; char *chat_id; ref = DbLockIntent(parsee, DB_HINT_READONLY, 1, "chats"); rooms = GrabObject(DbJson(ref), 1, "rooms"); chat_id = StrDuplicate(GrabString(rooms, 1, potential_id)); DbUnlock(parsee, ref); DeletePlumbID(parsee, chat_id); Free(chat_id); return; } /* Try to parse it as a chat ID */ DeletePlumbID(parsee, potential_id); } static void ListPlumbs(Db *parsee) { DbRef *ref; HashMap *mucs; char *muc; JsonValue *value; if (!parsee) { return; } ref = DbLockIntent(parsee, DB_HINT_READONLY, 1, "chats"); mucs = GrabObject(DbJson(ref), 1, "mucs"); while (HashMapIterate(mucs, &muc, (void **) &value)) { char *chat_id = JsonValueAsString(value); DbRef *chat_id_ref = DbLockIntent(parsee, DB_HINT_READONLY, 2, "chats", chat_id); char *matrix_id = GrabString(DbJson(chat_id_ref), 1, "room_id"); /* TODO */ Log(LOG_INFO, "- Plumb xmpp:%s <=> %s", muc, matrix_id); Log(LOG_INFO, " - ID=%s", chat_id); DbUnlock(parsee, chat_id_ref); } DbUnlock(parsee, ref); } int Main(Array *args, HashMap *env) { char *db_path, *action, *exec; int ret = EXIT_SUCCESS; Db *parsee; exec = ArrayGet(args, 0); if (ArraySize(args) < 3) { Log(LOG_ERR, "Usage: %s [config] [action] ", exec); return EXIT_FAILURE; } db_path = ArrayGet(args, 1); action = ArrayGet(args, 2); parsee = GetDB(db_path); if (!parsee) { Log(LOG_ERR, "%s: couldn't open config '%s' or couldnt edit DB", exec, db_path); return EXIT_FAILURE; } if (StrEquals(action, "list") || StrEquals(action, "ls")) { ListPlumbs(parsee); } else if (StrEquals(action, "del")) { if (ArraySize(args) != 4) { Log(LOG_ERR, "%s: please show a !roomid:matrix.org, xmpp:mucid@jabber.org, or local hash", exec); ret = EXIT_FAILURE; goto end; } DeletePlumb(parsee, ArrayGet(args, 3)); } end: DbClose(parsee); return ret; }