diff options
author | Iru Cai <mytbk920423@gmail.com> | 2018-06-27 22:56:25 +0800 |
---|---|---|
committer | Iru Cai <mytbk920423@gmail.com> | 2018-06-27 22:56:25 +0800 |
commit | e6d9edc048efb5b19d79bbe7871b2ff779d72311 (patch) | |
tree | 8d9eedd599f09d7aa9b64ab6251b9b9a092fce91 | |
download | matrix-curl-e6d9edc048efb5b19d79bbe7871b2ff779d72311.tar.xz |
initial code
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | api.c | 130 | ||||
-rw-r--r-- | session.c | 120 | ||||
-rw-r--r-- | session.h | 23 | ||||
-rw-r--r-- | util.c | 36 | ||||
-rw-r--r-- | util.h | 39 |
6 files changed, 352 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d4b6daa --- /dev/null +++ b/Makefile @@ -0,0 +1,4 @@ +LDLIBS=-lcurl -ljson-c +CFLAGS=-g -Wall + +api: api.o session.o util.o @@ -0,0 +1,130 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <curl/curl.h> +#include <json-c/json.h> +#include "session.h" +#include "util.h" + +/* logout: return 1 if success, 0 if failed */ +int matrix_logout(matrix_session *sess) +{ + char requrl[1000]; /* FIXME */ + sprintf(requrl, "%s/_matrix/client/r0/logout?access_token=%s", sess->url, sess->token); + CURLcode res = _curl_post(sess->curl, requrl, "", NULL); + if (res == CURLE_OK) + return 1; + else + return 0; +} + +json_object * matrix_joined_rooms(matrix_session *sess) +{ + char requrl[1000]; + json_object *resp; + sprintf(requrl, "%s/_matrix/client/r0/joined_rooms?access_token=%s", + sess->url, sess->token); + _curl_get(sess->curl, requrl, &resp); + return resp; +} + +const char * matrix_create_room(matrix_session *sess) +{ + char requrl[1000]; + json_object *resp; + + sprintf(requrl, "%s/_matrix/client/r0/createRoom?access_token=%s", + sess->url, sess->token); + _curl_post(sess->curl, requrl, "{\"preset\": \"private_chat\"}", &resp); + if (resp != NULL) { + const char *roomid = json_gets(resp, "room_id"); + if (roomid) { + const char *r = copy_str(roomid); + json_object_put(resp); + return r; + } + } + json_object_put(resp); + return NULL; +} + +const char * matrix_resolv_alias(matrix_session *sess, const char *alias) +{ + char requrl[1000]; + json_object *resp; + const char *_alias = alias; + if (alias[0] == '#') + _alias = curl_easy_escape(sess->curl, alias, strlen(alias)); + + sprintf(requrl, "%s/_matrix/client/r0/directory/room/%s", sess->url, _alias); + if (_alias != alias) + curl_free(_alias); + + _curl_get(sess->curl, requrl, &resp); + if (resp) { + const char *roomid = json_gets(resp, "room_id"); + if (roomid) { + const char *r = copy_str(roomid); + json_object_put(resp); + return r; + } + } + json_object_put(resp); + return NULL; +} + +int main() +{ + curl_global_init(CURL_GLOBAL_ALL); + char url[1000], user[1000], passwd[1000], token[1000]; + scanf("%s%s%s", url, user, passwd); + matrix_session *sess = matrix_login_pass(url, user, passwd, "Matrix C Client"); + + if (sess) { + printf("hs: %s, mxid: %s, dev: %s, token: %s\n", sess->servername, + sess->mxid, sess->dev_id, sess->token); + + /* store access token */ + FILE *fp = fopen("credential.txt", "w"); + fprintf(fp, "%s %s\n", url, sess->token); + fclose(fp); + } else { + puts("login error!\n"); + } + + strcpy(token, sess->token); + matrix_session_free(sess); + + // scanf("%s%s", url, token); + sess = matrix_access_token(url, token); + if (sess) { + printf("I'm %s\n", sess->mxid); + } else { + puts("login error!\n"); + } + + json_object *joined_rooms = matrix_joined_rooms(sess); + printf("%s\n", json_object_to_json_string(joined_rooms)); + + const char *roomid = matrix_resolv_alias(sess, "#hello:my.domain.name"); + if (roomid == NULL) + puts("fail to resolv #hello:my.domain.name"); + + free(roomid); + + /* create a room */ + roomid = matrix_create_room(sess); + if (roomid == NULL) + puts("fail to create room!"); + else + printf("create room %s\n", roomid); + + free(roomid); + + if (matrix_logout(sess)) + puts("logout!"); + + if (matrix_whoami(sess)) { + puts("error: not logged out!"); + } +} diff --git a/session.c b/session.c new file mode 100644 index 0000000..bd9deb0 --- /dev/null +++ b/session.c @@ -0,0 +1,120 @@ +#include "session.h" +#include "util.h" + +matrix_session* +matrix_session_new(const char *url) +{ + matrix_session *sess = (matrix_session*)malloc(sizeof(matrix_session)); + memset(sess, 0, sizeof(matrix_session)); + sess->curl = curl_easy_init(); + if (sess->curl) { + sess->url = copy_str(url); + return sess; + } else { + free(sess); + return NULL; + } +} + +#define SAFE_FREE(x) if (x) free(x); + +void +matrix_session_free(matrix_session *sess) +{ + SAFE_FREE(sess->url); + SAFE_FREE(sess->servername); + SAFE_FREE(sess->mxid); + SAFE_FREE(sess->token); + SAFE_FREE(sess->dev_id); + + curl_easy_cleanup(sess->curl); + free(sess); +} + +matrix_session* +matrix_login_pass(const char *url, const char *user, const char *passwd, const char *devname) +{ + CURLcode res; + + matrix_session *sess = matrix_session_new(url); + + json_object *reqobj = json_object_new_object(); + char requrl[1000]; /* FIXME */ + json_object *resp = NULL; + + sprintf(requrl, "%s%s", url, "/_matrix/client/r0/login"); + + json_add_string(reqobj, "type", "m.login.password"); + json_add_string(reqobj, "user", user); + json_add_string(reqobj, "password", passwd); + if (devname != NULL) + json_add_string(reqobj, "initial_device_display_name", devname); + + res = _curl_post(sess->curl, requrl, json_object_to_json_string(reqobj), &resp); + json_object_put(reqobj); + + /* save mxid, token, dev_id*/ + if (resp != NULL) { + const char *mxid = json_gets(resp, "user_id"); + const char *token = json_gets(resp, "access_token"); + const char *devid = json_gets(resp, "device_id"); + const char *hs = json_gets(resp, "home_server"); + + if (mxid && token && devid && hs) { + sess->mxid = copy_str(mxid); + sess->token = copy_str(token); + sess->dev_id = copy_str(devid); + sess->servername = copy_str(hs); + json_object_put(resp); + return sess; + } else { + json_object_put(resp); + matrix_session_free(sess); + return NULL; + } + } + return NULL; +} + +matrix_session* +matrix_access_token(const char *url, const char *token) +{ + matrix_session *sess = matrix_session_new(url); + sess->token = copy_str(token); + char *mxid = matrix_whoami(sess); + + if (mxid) { + sess->mxid = mxid; + return sess; + } else { + matrix_session_free(sess); + return NULL; + } +} + +/* return an alloc'd string of MXID */ +char *matrix_whoami(matrix_session *sess) +{ + char requrl[1000]; /* FIXME */ + char *uid; + CURLcode res; + json_object *resp = NULL; + + sprintf(requrl, "%s/_matrix/client/r0/account/whoami?access_token=%s", + sess->url, sess->token); + res = _curl_get(sess->curl, requrl, &resp); + + if (resp != NULL) { + const char *mxid = json_gets(resp, "user_id"); + if (mxid) { + uid = copy_str(mxid); + json_object_put(resp); + return uid; + } else { + json_object_put(resp); + return NULL; + } + } else { + return NULL; + } +} diff --git a/session.h b/session.h new file mode 100644 index 0000000..53c0bc7 --- /dev/null +++ b/session.h @@ -0,0 +1,23 @@ +#ifndef MATRIX_CURL_SESSION_H +#define MATRIX_CURL_SESSION_H + +#include <curl/curl.h> + +typedef struct +{ + CURL *curl; + char *url; + char *servername; + char *mxid; + char *token; + char *dev_id; +} matrix_session; + +char *matrix_whoami(matrix_session *sess); +matrix_session* matrix_access_token(const char *url, const char *token); +matrix_session* matrix_login_pass(const char *url, + const char *user, const char *passwd, + const char *devname); +void matrix_session_free(matrix_session *sess); + +#endif @@ -0,0 +1,36 @@ +#include "util.h" + +static size_t get_json_callback(void *contents, size_t size, size_t nmemb, void *userp) +{ + size_t realsize = size * nmemb; + + json_tokener *tok = json_tokener_new(); + if (userp != NULL) + *((json_object **)userp) = json_tokener_parse_ex(tok, contents, realsize); + + json_tokener_free(tok); + + return realsize; +} + +CURLcode +_curl_get(CURL *curl, const char *url, json_object **resp) +{ + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, get_json_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)resp); + + return curl_easy_perform(curl); +} + +CURLcode +_curl_post(CURL *curl, const char *url, const char *postdata, json_object **resp) +{ + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postdata); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, get_json_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)resp); + + return curl_easy_perform(curl); +} @@ -0,0 +1,39 @@ +#ifndef MATRIX_CURL_UTIL_H +#define MATRIX_CURL_UTIL_H + +#include <curl/curl.h> +#include <json-c/json.h> +#include <string.h> + +CURLcode _curl_get(CURL *curl, const char *url, json_object **resp); +CURLcode _curl_post(CURL *curl, const char *url, const char *postdata, + json_object **resp); + +static inline int +json_add_string(json_object *j, const char *k, const char *v) +{ + return json_object_object_add(j, k, json_object_new_string(v)); +} + +static inline +const char *json_gets(json_object *j, const char *key) +{ + json_object *val; + + if (json_object_object_get_ex(j, key, &val)) { + if (json_object_is_type(val, json_type_string)) + return json_object_get_string(val); + } + return NULL; +} + +static inline +char* copy_str(const char *s) +{ + size_t l = strlen(s)+1; + char *ss = (char*)malloc(l); + memcpy(ss, s, l); + return ss; +} + +#endif |