/* config.c - Generates a nice Parsee config file * ============================================================ * Example of usage(for a blow.hole HS and a xmpp.blow.hole JCP): * tools/out/config \ * -d '/var/lib/parsee' \ * -m 'https://pmedia.blow.hole' \ * -H 'blow.hole' \ * -s 'The Dark Blowhole shared secret' \ * -J 'xmpp.blow.hole' * Under CC0, as its a rather useful example of a Parsee tool. * See LICENSE for more information about Parsee's licensing. */ #include #include #include #include #include #include #include #include #include #include static Uri * DelegateServer(char *raw) { HttpClientContext *ctx = NULL; Stream *stream = NULL; HashMap *reply = NULL; Uri *ret = NULL; if (!raw) { return NULL; } ctx = HttpRequest( HTTP_GET, HTTP_FLAG_TLS, 443, raw, "/.well-known/matrix/client" ); HttpRequestSendHeaders(ctx); switch (HttpRequestSend(ctx)) { case HTTP_OK: stream = HttpClientStream(ctx); reply = JsonDecode(stream); if (!reply) { goto end; } ret = UriParse(JsonValueAsString(JsonGet( reply, 2, "m.homeserver", "base_url" ))); break; default: /* TODO */ break; } if (ret && !ret->port && StrEquals(ret->proto, "https")) { ret->port = 443; } if (ret && !ret->port) { ret->port = 80; } end: HttpClientContextFree(ctx); JsonFree(reply); return ret; } int Main(Array *args, HashMap *env) { /* TODO: Not user friendly either. */ ArgParseState state; Uri *api_base; char *homeserver = NULL, *jcp = NULL, *jabber = NULL; char *data = NULL, *media = NULL, *listen = NULL; int flag, code = EXIT_FAILURE; int port = 5347; listen = "localhost"; ArgParseStateInit(&state); while ((flag = ArgParse(&state, args, "H:J:s:d:p:m:l:")) != -1) { switch (flag) { case 'H': homeserver = state.optArg; break; case 's': jcp = state.optArg; break; case 'm': Free(media); media = StrDuplicate(state.optArg); break; case 'J': jabber = state.optArg; break; case 'd': data = state.optArg; break; case 'l': listen = state.optArg; break; case 'p': port = strtol(state.optArg, NULL, 10); break; } } api_base = DelegateServer(homeserver); if (!api_base || !jcp || !jabber || !data || !listen) { Log(LOG_ERR, "Usage: %s " "-d [Database directory] " "-m " "-H [matrixserv.fed] " "-s [XMPP shared secret] " "-l [Host/IP to listen as] " "-p [XMPP component port=5347] " "-J [parsee.xmppserver.ex]", ArrayGet(args, 0) ); goto end; } if (!media) { char *s_port = StrInt(port); media = StrConcat(4, "http://", listen, ":", s_port); Free(s_port); } { HashMap *json = HashMapCreate(); Stream *file = StreamOpen("parsee.json", "w"); char *as_token, *hs_token; as_token = StrRandom(32); hs_token = StrRandom(32); UtilMkdir(data, 0755); JsonSet(json, JsonValueString(data), 1, "db"); JsonSet(json, JsonValueString(homeserver), 1, "hs_base"); JsonSet(json, JsonValueString(api_base->host), 1, "hs_host"); JsonSet(json, JsonValueInteger(api_base->port), 1, "hs_port"); JsonSet(json, JsonValueString(as_token), 1, "as_token"); JsonSet(json, JsonValueString(hs_token), 1, "hs_token"); JsonSet(json, JsonValueString("_p_"), 1, "namespace"); JsonSet(json, JsonValueString("_parsee"), 1, "sender"); JsonSet(json, JsonValueInteger(7642), 1, "port"); JsonSet(json, JsonValueString(jabber), 1, "component_host"); JsonSet(json, JsonValueInteger(port), 1, "component_port"); JsonSet(json, JsonValueString(jcp), 1, "shared_secret"); JsonSet(json, JsonValueString(media), 1, "media_base"); JsonSet(json, JsonValueString(listen), 1, "listen_as"); JsonEncode(json, file, JSON_PRETTY); StreamFlush(file); StreamClose(file); Log(LOG_INFO, "AS token=%s", as_token); Log(LOG_INFO, "HS token=%s", hs_token); Free(as_token); Free(hs_token); JsonFree(json); } code = EXIT_SUCCESS; end: UriFree(api_base); Free(media); return code; }