+#include <stdio.h>\r
+#include <stdarg.h>\r
+\r
+#include <mjson.h>\r
+#include <matrix.h>\r
+\r
+#define SERVER "https://matrix.org"\r
+#define ACCESS_TOKEN "syt_cHNjaG8_yBvTjVTquGCikvsAenOJ_49mBMO"\r
+#define DEVICE_ID "MAZNCCZLBR"\r
+#define USER_ID "@pscho:matrix.org"\r
+#define ROOM_ID "!XKFUjAsGrSSrpDFIxB:matrix.org"\r
+\r
+#define BUFFER_SIZE 1024\r
+#define NUMBER_ARGS 10\r
+\r
+void\r
+GetCommand(\r
+ char * cmd,\r
+ int * nargs,\r
+ char ** args\r
+) {\r
+ int index = 0;\r
+ int c;\r
+\r
+ *nargs = 0;\r
+\r
+ printf("> ");\r
+ while ((c = getchar()), c != ' ' && c != '\n')\r
+ cmd[index++] = c;\r
+ cmd[index] = '\0';\r
+\r
+ if (c == '\n')\r
+ return;\r
+ \r
+ *nargs = 1;\r
+ index = 0;\r
+ char * arg = args[0];\r
+ while ((c = getchar()), c != '\n') {\r
+ if (c == ' ') {\r
+ arg[index] = '\0';\r
+ arg = args[(*nargs)++];\r
+ index = 0;\r
+ continue;\r
+ }\r
+ arg[index++] = c;\r
+ }\r
+ arg[index] = '\0';\r
+}\r
+\r
+bool\r
+CheckCommand(\r
+ const char * cmd,\r
+ const char * str\r
+) {\r
+ if (strlen(cmd) != strlen(str))\r
+ return false;\r
+ \r
+ for (size_t i = 0; i < strlen(cmd); i++) {\r
+ if (cmd[i] != str[i])\r
+ return false;\r
+ }\r
+ return true;\r
+}\r
+\r
+void\r
+Usage(\r
+ const char * cmd,\r
+ const char * args\r
+) {\r
+ printf("Usage: %s %s\n", cmd, args);\r
+}\r
+\r
+void\r
+ExecuteCommand(\r
+ MatrixClient * client,\r
+ const char * cmd,\r
+ int nargs, char ** args\r
+) {\r
+ /**/ if (CheckCommand(cmd, "devicekey")) {\r
+ printf("%s\n", client->deviceKey);\r
+ }\r
+ else if (CheckCommand(cmd, "genkeys")) {\r
+ if (nargs != 1) {\r
+ Usage(cmd, "<number of keys>");\r
+ return;\r
+ }\r
+ MatrixClientGenerateOnetimeKeys(client, atoi(args[0]));\r
+ }\r
+ else if (CheckCommand(cmd, "uploadkeys")) {\r
+ MatrixClientUploadOnetimeKeys(client);\r
+ }\r
+ else if (CheckCommand(cmd, "onetimekeys")) {\r
+ static char buffer[1024];\r
+ olm_account_one_time_keys(client->olmAccount.account, buffer, 1024);\r
+ printf("%s\n", buffer);\r
+ }\r
+ else if (CheckCommand(cmd, "getkeys")) {\r
+ MatrixClientRequestDeviceKeys(client);\r
+ for (int i = 0; i < client->numDevices; i++)\r
+ printf("id: %s key: %s\n",\r
+ client->devices[i].deviceId,\r
+ client->devices[i].deviceKey);\r
+ }\r
+ else if (CheckCommand(cmd, "todevice")) {\r
+ static char buffer[30000];\r
+ MatrixClientSync(client,\r
+ buffer, 30000);\r
+ const char * todevice;\r
+ int todeviceLen;\r
+ mjson_find(buffer, 30000,\r
+ "$.to_device",\r
+ &todevice, &todeviceLen);\r
+ static char prettyBuffer[10000];\r
+ struct mjson_fixedbuf fb = { prettyBuffer, 10000, 0 };\r
+ mjson_pretty(todevice, todeviceLen,\r
+ " ", mjson_print_fixed_buf, &fb);\r
+ printf("%.*s\n", fb.len, fb.ptr);\r
+ }\r
+}\r
+\r
+int\r
+main(void)\r
+{\r
+ MatrixClient client;\r
+ MatrixClientInit(&client,\r
+ SERVER);\r
+ \r
+ MatrixHttpInit(&client);\r
+\r
+ MatrixClientSetAccessToken(&client,\r
+ ACCESS_TOKEN);\r
+ MatrixClientSetDeviceId(&client,\r
+ DEVICE_ID);\r
+ MatrixClientSetUserId(&client,\r
+ USER_ID);\r
+\r
+ static char cmd[BUFFER_SIZE];\r
+ static char args_[BUFFER_SIZE][NUMBER_ARGS];\r
+ char * args[NUMBER_ARGS];\r
+ for (int i = 0; i < NUMBER_ARGS; i++)\r
+ args[i] = args_[i];\r
+ int nargs;\r
+ do {\r
+ GetCommand(cmd, &nargs, args);\r
+\r
+ ExecuteCommand(&client, cmd, nargs, args);\r
+ \r
+ } while (strcmp(cmd, "exit") != 0);\r
+ \r
+ MatrixHttpDeinit(&client);\r
+\r
+ return 0;\r
+}\r