split into library and applications

This commit is contained in:
Florian Stinglmayr 2019-06-25 14:52:38 +02:00
parent 8972538d13
commit 05694d2611
23 changed files with 359 additions and 260 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build/

View File

@ -8,40 +8,7 @@ PKG_CHECK_MODULES(CURL REQUIRED libcurl)
PKG_CHECK_MODULES(EVENT REQUIRED libevent libevent_pthreads) PKG_CHECK_MODULES(EVENT REQUIRED libevent libevent_pthreads)
PKG_CHECK_MODULES(GLIB2 REQUIRED glib-2.0) PKG_CHECK_MODULES(GLIB2 REQUIRED glib-2.0)
SET(TARGET "ncdc")
SET(SOURCES
"include/ncdc/account.h"
"include/ncdc/api.h"
"include/ncdc/apisync.h"
"include/ncdc/ncdc.h"
"include/ncdc/refable.h"
"src/account.c"
"src/api.c"
"src/apisync.c"
"src/ncdc.c"
"src/refable.c"
)
ADD_DEFINITIONS("-Wall -Werror -std=c11 -D_GNU_SOURCE") ADD_DEFINITIONS("-Wall -Werror -std=c11 -D_GNU_SOURCE")
INCLUDE_DIRECTORIES("include" ADD_SUBDIRECTORY(libdc)
${JANSSON_INCLUDE_DIRS} ADD_SUBDIRECTORY(ncdc)
${CURL_INCLUDE_DIRS}
${EVENT_INCLUDE_DIRS}
${GLIB2_INCLUDE_DIRS}
)
LINK_DIRECTORIES(${JANSSON_LIBRARY_DIRS}
${CURL_LIBRARY_DIRS}
${EVENT_LIBRARY_DIRS}
${GLIB2_LIBRARY_DIRS}
)
ADD_EXECUTABLE(${TARGET} ${SOURCES})
TARGET_LINK_LIBRARIES(${TARGET}
${JANSSON_LIBRARIES}
${CURL_LIBRARIES}
${EVENT_LIBRARIES}
${GLIB2_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
)

View File

@ -1,25 +0,0 @@
#ifndef NCDC_ACCOUNT_H
#define NCDC_ACCOUNT_H
#include <ncdc/ncdc.h>
struct ncdc_account_;
typedef struct ncdc_account_ *ncdc_account_t;
ncdc_account_t ncdc_account_new(void);
ncdc_account_t ncdc_account_new2(char const *email, char const *pass);
void ncdc_account_set_email(ncdc_account_t a, char const *email);
char const *ncdc_account_email(ncdc_account_t a);
void ncdc_account_set_password(ncdc_account_t a, char const *password);
char const *ncdc_account_password(ncdc_account_t a);
void ncdc_account_set_id(ncdc_account_t a, char const *id);
char const *ncdc_account_id(ncdc_account_t a);
void ncdc_account_set_token(ncdc_account_t a, char const *token);
char const *ncdc_account_token(ncdc_account_t a);
bool ncdc_account_has_token(ncdc_account_t a);
#endif

View File

@ -1,34 +0,0 @@
#ifndef NCDC_API_H
#define NCDC_API_H
#include <ncdc/ncdc.h>
#include <ncdc/apisync.h>
#include <ncdc/account.h>
struct ncdc_api_;
typedef struct ncdc_api_ *ncdc_api_t;
ncdc_api_t ncdc_api_new(void);
void ncdc_api_set_curl_multi(ncdc_api_t api, CURLM *curl);
void ncdc_api_set_event_base(ncdc_api_t api, struct event_base *base);
/* call this function in case the MULTI has told us that some
* transfer has finished.
*/
void ncdc_api_signal(ncdc_api_t api, CURL *easy, int code);
/* internal curl stuff
*/
ncdc_api_sync_t ncdc_api_call(ncdc_api_t api, char const *token,
char const *method, json_t *j);
json_t *ncdc_api_call_sync(ncdc_api_t api, char const *token,
char const *method, json_t *j);
bool ncdc_api_authenticate(ncdc_api_t api, ncdc_account_t account);
bool ncdc_api_userinfo(ncdc_api_t api, ncdc_account_t logion,
ncdc_account_t user);
#endif

View File

@ -1,20 +0,0 @@
#ifndef NCDC_API_ASYNC_H
#define NCDC_API_ASYNC_H
#include <ncdc/ncdc.h>
struct ncdc_api_sync_;
typedef struct ncdc_api_sync_ *ncdc_api_sync_t;
ncdc_api_sync_t ncdc_api_sync_new(CURLM *curl, CURL *easy);
FILE *ncdc_api_sync_stream(ncdc_api_sync_t sync);
char const *ncdc_api_sync_data(ncdc_api_sync_t sync);
size_t ncdc_api_sync_datalen(ncdc_api_sync_t sync);
int ncdc_api_sync_code(ncdc_api_sync_t sync);
struct curl_slist *ncdc_api_sync_list(ncdc_api_sync_t sync);
bool ncdc_api_sync_wait(ncdc_api_sync_t sync);
void ncdc_api_sync_finish(ncdc_api_sync_t sync, int code);
#endif

View File

@ -1,16 +0,0 @@
#ifndef NCDC_REFABLE_H
#define NCDC_REFABLE_H
#include <ncdc/ncdc.h>
typedef void (*cleanup_t)(void *);
typedef struct {
int ref;
cleanup_t cleanup;
} ncdc_refable_t;
void *ncdc_ref(void *);
void ncdc_unref(void *);
#endif

42
libdc/CMakeLists.txt Normal file
View File

@ -0,0 +1,42 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
SET(TARGET "dc")
SET(DC_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include" CACHE STRING
"Discord API include directories"
)
SET(DC_LIBRARIES "${TARGET}" CACHE STRING "Discord API libraries")
SET(SOURCES
"include/dc/account.h"
"include/dc/api.h"
"include/dc/apisync.h"
"include/dc/refable.h"
"include/dc/util.h"
"src/account.c"
"src/api.c"
"src/apisync.c"
"src/refable.c"
"src/util.c"
)
INCLUDE_DIRECTORIES("include"
${JANSSON_INCLUDE_DIRS}
${CURL_INCLUDE_DIRS}
${EVENT_INCLUDE_DIRS}
${GLIB2_INCLUDE_DIRS}
)
LINK_DIRECTORIES(${JANSSON_LIBRARY_DIRS}
${CURL_LIBRARY_DIRS}
${EVENT_LIBRARY_DIRS}
${GLIB2_LIBRARY_DIRS}
)
ADD_LIBRARY(${TARGET} SHARED ${SOURCES})
TARGET_LINK_LIBRARIES(${TARGET}
${JANSSON_LIBRARIES}
${CURL_LIBRARIES}
${EVENT_LIBRARIES}
${GLIB2_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
)

View File

@ -0,0 +1,26 @@
#ifndef DC_ACCOUNT_H
#define DC_ACCOUNT_H
#include <stdint.h>
#include <stdbool.h>
struct dc_account_;
typedef struct dc_account_ *dc_account_t;
dc_account_t dc_account_new(void);
dc_account_t dc_account_new2(char const *email, char const *pass);
void dc_account_set_email(dc_account_t a, char const *email);
char const *dc_account_email(dc_account_t a);
void dc_account_set_password(dc_account_t a, char const *password);
char const *dc_account_password(dc_account_t a);
void dc_account_set_id(dc_account_t a, char const *id);
char const *dc_account_id(dc_account_t a);
void dc_account_set_token(dc_account_t a, char const *token);
char const *dc_account_token(dc_account_t a);
bool dc_account_has_token(dc_account_t a);
#endif

37
libdc/include/dc/api.h Normal file
View File

@ -0,0 +1,37 @@
#ifndef NCDC_API_H
#define NCDC_API_H
#include <dc/apisync.h>
#include <dc/account.h>
#include <stdbool.h>
#include <jansson.h>
#include <event.h>
struct dc_api_;
typedef struct dc_api_ *dc_api_t;
dc_api_t dc_api_new(void);
void dc_api_set_curl_multi(dc_api_t api, CURLM *curl);
void dc_api_set_event_base(dc_api_t api, struct event_base *base);
/* call this function in case the MULTI has told us that some
* transfer has finished.
*/
void dc_api_signal(dc_api_t api, CURL *easy, int code);
/* internal curl stuff
*/
dc_api_sync_t dc_api_call(dc_api_t api, char const *token,
char const *method, json_t *j);
json_t *dc_api_call_sync(dc_api_t api, char const *token,
char const *method, json_t *j);
bool dc_api_authenticate(dc_api_t api, dc_account_t account);
bool dc_api_userinfo(dc_api_t api, dc_account_t logion,
dc_account_t user);
#endif

View File

@ -0,0 +1,23 @@
#ifndef DC_API_ASYNC_H
#define DC_API_ASYNC_H
#include <curl/curl.h>
#include <stdio.h>
#include <stdbool.h>
struct dc_api_sync_;
typedef struct dc_api_sync_ *dc_api_sync_t;
dc_api_sync_t dc_api_sync_new(CURLM *curl, CURL *easy);
FILE *dc_api_sync_stream(dc_api_sync_t sync);
char const *dc_api_sync_data(dc_api_sync_t sync);
size_t dc_api_sync_datalen(dc_api_sync_t sync);
int dc_api_sync_code(dc_api_sync_t sync);
struct curl_slist *dc_api_sync_list(dc_api_sync_t sync);
bool dc_api_sync_wait(dc_api_sync_t sync);
void dc_api_sync_finish(dc_api_sync_t sync, int code);
#endif

View File

@ -0,0 +1,14 @@
#ifndef DC_REFABLE_H
#define DC_REFABLE_H
typedef void (*dc_cleanup_t)(void *);
typedef struct {
int ref;
dc_cleanup_t cleanup;
} dc_refable_t;
void *dc_ref(void *);
void dc_unref(void *);
#endif

8
libdc/include/dc/util.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef NCDC_UTIL_H
#define NCDC_UTIL_H
#include <jansson.h>
void ncdc_util_dump_json(json_t *j);
#endif

View File

@ -1,13 +1,15 @@
#include <ncdc/account.h> #include <dc/account.h>
#include <ncdc/refable.h> #include <dc/refable.h>
#include "internal.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
struct ncdc_account_ struct dc_account_
{ {
ncdc_refable_t ref; /* do not move anything above ref */ dc_refable_t ref; /* do not move anything above ref */
char *email; char *email;
char *password; char *password;
@ -21,7 +23,7 @@ struct ncdc_account_
char *token; char *token;
}; };
static void ncdc_account_free(ncdc_account_t ptr) static void dc_account_free(dc_account_t ptr)
{ {
return_if_true(ptr == NULL,); return_if_true(ptr == NULL,);
@ -31,28 +33,28 @@ static void ncdc_account_free(ncdc_account_t ptr)
free(ptr); free(ptr);
} }
ncdc_account_t ncdc_account_new(void) dc_account_t dc_account_new(void)
{ {
ncdc_account_t ptr = calloc(1, sizeof(struct ncdc_account_)); dc_account_t ptr = calloc(1, sizeof(struct dc_account_));
ptr->ref.cleanup = (cleanup_t)ncdc_account_free; ptr->ref.cleanup = (dc_cleanup_t)dc_account_free;
return ncdc_ref(ptr); return dc_ref(ptr);
} }
ncdc_account_t ncdc_account_new2(char const *email, char const *pass) dc_account_t dc_account_new2(char const *email, char const *pass)
{ {
ncdc_account_t ptr = ncdc_account_new(); dc_account_t ptr = dc_account_new();
if (ptr != NULL) { if (ptr != NULL) {
ncdc_account_set_email(ptr, email); dc_account_set_email(ptr, email);
ncdc_account_set_password(ptr, pass); dc_account_set_password(ptr, pass);
} }
return ptr; return ptr;
} }
void ncdc_account_set_email(ncdc_account_t a, char const *email) void dc_account_set_email(dc_account_t a, char const *email)
{ {
return_if_true(a == NULL,); return_if_true(a == NULL,);
return_if_true(email == NULL,); return_if_true(email == NULL,);
@ -61,13 +63,13 @@ void ncdc_account_set_email(ncdc_account_t a, char const *email)
a->email = strdup(email); a->email = strdup(email);
} }
char const *ncdc_account_email(ncdc_account_t a) char const *dc_account_email(dc_account_t a)
{ {
return_if_true(a == NULL, NULL); return_if_true(a == NULL, NULL);
return a->email; return a->email;
} }
void ncdc_account_set_password(ncdc_account_t a, char const *password) void dc_account_set_password(dc_account_t a, char const *password)
{ {
return_if_true(a == NULL,); return_if_true(a == NULL,);
return_if_true(password == NULL,); return_if_true(password == NULL,);
@ -76,13 +78,13 @@ void ncdc_account_set_password(ncdc_account_t a, char const *password)
a->password = strdup(password); a->password = strdup(password);
} }
char const *ncdc_account_password(ncdc_account_t a) char const *dc_account_password(dc_account_t a)
{ {
return_if_true(a == NULL, NULL); return_if_true(a == NULL, NULL);
return a->password; return a->password;
} }
void ncdc_account_set_token(ncdc_account_t a, char const *token) void dc_account_set_token(dc_account_t a, char const *token)
{ {
return_if_true(a == NULL,); return_if_true(a == NULL,);
@ -94,27 +96,27 @@ void ncdc_account_set_token(ncdc_account_t a, char const *token)
} }
} }
char const *ncdc_account_token(ncdc_account_t a) char const *dc_account_token(dc_account_t a)
{ {
return_if_true(a == NULL, NULL); return_if_true(a == NULL, NULL);
return a->token; return a->token;
} }
bool ncdc_account_has_token(ncdc_account_t a) bool dc_account_has_token(dc_account_t a)
{ {
return_if_true(a == NULL, false); return_if_true(a == NULL, false);
return_if_true(a->token == NULL, false); return_if_true(a->token == NULL, false);
return true; return true;
} }
void ncdc_account_set_id(ncdc_account_t a, char const *id) void dc_account_set_id(dc_account_t a, char const *id)
{ {
return_if_true(a == NULL,); return_if_true(a == NULL,);
free(a->id); free(a->id);
a->id = strdup(id); a->id = strdup(id);
} }
char const *ncdc_account_id(ncdc_account_t a) char const *dc_account_id(dc_account_t a)
{ {
return_if_true(a == NULL,NULL); return_if_true(a == NULL,NULL);
return a->id; return a->id;

View File

@ -1,14 +1,15 @@
#include <ncdc/api.h> #include <dc/api.h>
#include <ncdc/refable.h> #include <dc/refable.h>
#include "internal.h"
#define DISCORD_URL "https://discordapp.com/api/v6" #define DISCORD_URL "https://discordapp.com/api/v6"
#define DISCORD_USERAGENT "Mozilla/5.0 (X11; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0" #define DISCORD_USERAGENT "Mozilla/5.0 (X11; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0"
#define DISCORD_API_AUTH "auth/login" #define DISCORD_API_AUTH "auth/login"
struct ncdc_api_ struct dc_api_
{ {
ncdc_refable_t ref; dc_refable_t ref;
struct event_base *base; struct event_base *base;
CURLM *curl; CURLM *curl;
@ -18,7 +19,7 @@ struct ncdc_api_
char *cookie; char *cookie;
}; };
static void ncdc_api_free(ncdc_api_t ptr) static void dc_api_free(dc_api_t ptr)
{ {
return_if_true(ptr == NULL,); return_if_true(ptr == NULL,);
@ -30,25 +31,25 @@ static void ncdc_api_free(ncdc_api_t ptr)
free(ptr); free(ptr);
} }
ncdc_api_t ncdc_api_new(void) dc_api_t dc_api_new(void)
{ {
ncdc_api_t ptr = calloc(1, sizeof(struct ncdc_api_)); dc_api_t ptr = calloc(1, sizeof(struct dc_api_));
return_if_true(ptr == NULL, NULL); return_if_true(ptr == NULL, NULL);
ptr->ref.cleanup = (cleanup_t)ncdc_api_free; ptr->ref.cleanup = (dc_cleanup_t)dc_api_free;
ptr->syncs = g_hash_table_new_full(g_direct_hash, g_direct_equal, ptr->syncs = g_hash_table_new_full(g_direct_hash, g_direct_equal,
NULL, ncdc_unref NULL, dc_unref
); );
if (ptr->syncs == NULL) { if (ptr->syncs == NULL) {
free(ptr); free(ptr);
return NULL; return NULL;
} }
return ncdc_ref(ptr); return dc_ref(ptr);
} }
void ncdc_api_set_curl_multi(ncdc_api_t api, CURLM *curl) void dc_api_set_curl_multi(dc_api_t api, CURLM *curl)
{ {
return_if_true(api == NULL,); return_if_true(api == NULL,);
return_if_true(curl == NULL,); return_if_true(curl == NULL,);
@ -56,7 +57,7 @@ void ncdc_api_set_curl_multi(ncdc_api_t api, CURLM *curl)
api->curl = curl; api->curl = curl;
} }
void ncdc_api_set_event_base(ncdc_api_t api, struct event_base *base) void dc_api_set_event_base(dc_api_t api, struct event_base *base)
{ {
return_if_true(api == NULL,); return_if_true(api == NULL,);
return_if_true(base == NULL,); return_if_true(base == NULL,);
@ -64,16 +65,16 @@ void ncdc_api_set_event_base(ncdc_api_t api, struct event_base *base)
api->base = base; api->base = base;
} }
void ncdc_api_signal(ncdc_api_t api, CURL *easy, int code) void dc_api_signal(dc_api_t api, CURL *easy, int code)
{ {
ncdc_api_sync_t sync = NULL; dc_api_sync_t sync = NULL;
return_if_true(api == NULL,); return_if_true(api == NULL,);
return_if_true(easy == NULL,); return_if_true(easy == NULL,);
sync = g_hash_table_lookup(api->syncs, easy); sync = g_hash_table_lookup(api->syncs, easy);
if (sync != NULL) { if (sync != NULL) {
ncdc_api_sync_finish(sync, code); dc_api_sync_finish(sync, code);
g_hash_table_remove(api->syncs, easy); g_hash_table_remove(api->syncs, easy);
} }
} }
@ -99,7 +100,7 @@ static int debug_callback(CURL *handle, curl_infotype type,
} }
#endif #endif
static int header_callback(char *data, size_t sz, size_t num, ncdc_api_t api) static int header_callback(char *data, size_t sz, size_t num, dc_api_t api)
{ {
char *ptr = NULL; char *ptr = NULL;
@ -118,7 +119,7 @@ static int header_callback(char *data, size_t sz, size_t num, ncdc_api_t api)
return sz * num; return sz * num;
} }
static ncdc_api_sync_t ncdc_api_post(ncdc_api_t api, static dc_api_sync_t dc_api_post(dc_api_t api,
char const *url, char const *url,
char const *token, char const *token,
char const *data, int64_t len) char const *data, int64_t len)
@ -129,7 +130,7 @@ static ncdc_api_sync_t ncdc_api_post(ncdc_api_t api,
CURL *c = NULL; CURL *c = NULL;
bool ret = false; bool ret = false;
ncdc_api_sync_t sync = NULL; dc_api_sync_t sync = NULL;
struct curl_slist *l = NULL; struct curl_slist *l = NULL;
char *tmp = NULL; char *tmp = NULL;
int ptr = 0; int ptr = 0;
@ -137,12 +138,12 @@ static ncdc_api_sync_t ncdc_api_post(ncdc_api_t api,
c = curl_easy_init(); c = curl_easy_init();
goto_if_true(c == NULL, cleanup); goto_if_true(c == NULL, cleanup);
sync = ncdc_api_sync_new(api->curl, c); sync = dc_api_sync_new(api->curl, c);
goto_if_true(c == NULL, cleanup); goto_if_true(c == NULL, cleanup);
curl_easy_setopt(c, CURLOPT_URL, url); curl_easy_setopt(c, CURLOPT_URL, url);
curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, fwrite); curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, fwrite);
curl_easy_setopt(c, CURLOPT_WRITEDATA, ncdc_api_sync_stream(sync)); curl_easy_setopt(c, CURLOPT_WRITEDATA, dc_api_sync_stream(sync));
curl_easy_setopt(c, CURLOPT_HEADERFUNCTION, header_callback); curl_easy_setopt(c, CURLOPT_HEADERFUNCTION, header_callback);
curl_easy_setopt(c, CURLOPT_HEADERDATA, api); curl_easy_setopt(c, CURLOPT_HEADERDATA, api);
@ -150,7 +151,7 @@ static ncdc_api_sync_t ncdc_api_post(ncdc_api_t api,
curl_easy_setopt(c, CURLOPT_COOKIE, api->cookie); curl_easy_setopt(c, CURLOPT_COOKIE, api->cookie);
} }
l = ncdc_api_sync_list(sync); l = dc_api_sync_list(sync);
if (data != NULL) { if (data != NULL) {
curl_slist_append(l, "Content-Type: application/json"); curl_slist_append(l, "Content-Type: application/json");
} }
@ -189,7 +190,7 @@ static ncdc_api_sync_t ncdc_api_post(ncdc_api_t api,
goto cleanup; goto cleanup;
} }
g_hash_table_insert(api->syncs, c, ncdc_ref(sync)); g_hash_table_insert(api->syncs, c, dc_ref(sync));
curl_multi_socket_action(api->curl, CURL_SOCKET_TIMEOUT, 0, &ptr); curl_multi_socket_action(api->curl, CURL_SOCKET_TIMEOUT, 0, &ptr);
ret = true; ret = true;
@ -197,19 +198,19 @@ static ncdc_api_sync_t ncdc_api_post(ncdc_api_t api,
cleanup: cleanup:
if (!ret) { if (!ret) {
ncdc_unref(sync); dc_unref(sync);
sync = NULL; sync = NULL;
} }
return sync; return sync;
} }
ncdc_api_sync_t ncdc_api_call(ncdc_api_t api, char const *token, dc_api_sync_t dc_api_call(dc_api_t api, char const *token,
char const *method, json_t *j) char const *method, json_t *j)
{ {
char *data = NULL; char *data = NULL;
char *url = NULL; char *url = NULL;
ncdc_api_sync_t s = NULL; dc_api_sync_t s = NULL;
asprintf(&url, "%s/%s", DISCORD_URL, method); asprintf(&url, "%s/%s", DISCORD_URL, method);
goto_if_true(url == NULL, cleanup); goto_if_true(url == NULL, cleanup);
@ -219,7 +220,7 @@ ncdc_api_sync_t ncdc_api_call(ncdc_api_t api, char const *token,
goto_if_true(data == NULL, cleanup); goto_if_true(data == NULL, cleanup);
} }
s = ncdc_api_post(api, url, token, data, -1); s = dc_api_post(api, url, token, data, -1);
goto_if_true(s == NULL, cleanup); goto_if_true(s == NULL, cleanup);
cleanup: cleanup:
@ -233,37 +234,37 @@ cleanup:
return s; return s;
} }
json_t *ncdc_api_call_sync(ncdc_api_t api, char const *token, json_t *dc_api_call_sync(dc_api_t api, char const *token,
char const *method, json_t *j) char const *method, json_t *j)
{ {
ncdc_api_sync_t s = NULL; dc_api_sync_t s = NULL;
json_t *reply = NULL; json_t *reply = NULL;
s = ncdc_api_call(api, token, method, j); s = dc_api_call(api, token, method, j);
goto_if_true(s == NULL, cleanup); goto_if_true(s == NULL, cleanup);
if (!ncdc_api_sync_wait(s)) { if (!dc_api_sync_wait(s)) {
goto cleanup; goto cleanup;
} }
#ifdef DEBUG #ifdef DEBUG
printf("api_call_sync: %d\n", ncdc_api_sync_code(s)); printf("api_call_sync: %d\n", dc_api_sync_code(s));
#endif #endif
reply = json_loadb(ncdc_api_sync_data(s), reply = json_loadb(dc_api_sync_data(s),
ncdc_api_sync_datalen(s), dc_api_sync_datalen(s),
0, NULL 0, NULL
); );
cleanup: cleanup:
ncdc_unref(s); dc_unref(s);
s = NULL; s = NULL;
return reply; return reply;
} }
static bool ncdc_api_error(json_t *j, int *code, char const **message) static bool dc_api_error(json_t *j, int *code, char const **message)
{ {
return_if_true(j == NULL, false); return_if_true(j == NULL, false);
@ -289,22 +290,22 @@ static bool ncdc_api_error(json_t *j, int *code, char const **message)
return error; return error;
} }
bool ncdc_api_authenticate(ncdc_api_t api, ncdc_account_t account) bool dc_api_authenticate(dc_api_t api, dc_account_t account)
{ {
json_t *j = json_object(), *reply = NULL, *token = NULL; json_t *j = json_object(), *reply = NULL, *token = NULL;
bool ret = false; bool ret = false;
json_object_set_new(j, "email", json_object_set_new(j, "email",
json_string(ncdc_account_email(account)) json_string(dc_account_email(account))
); );
json_object_set_new(j, "password", json_object_set_new(j, "password",
json_string(ncdc_account_password(account)) json_string(dc_account_password(account))
); );
reply = ncdc_api_call_sync(api, NULL, DISCORD_API_AUTH, j); reply = dc_api_call_sync(api, NULL, DISCORD_API_AUTH, j);
goto_if_true(reply == NULL, cleanup); goto_if_true(reply == NULL, cleanup);
if (ncdc_api_error(j, NULL, NULL)) { if (dc_api_error(j, NULL, NULL)) {
return false; return false;
} }
@ -313,7 +314,7 @@ bool ncdc_api_authenticate(ncdc_api_t api, ncdc_account_t account)
goto cleanup; goto cleanup;
} }
ncdc_account_set_token(account, json_string_value(token)); dc_account_set_token(account, json_string_value(token));
ret = true; ret = true;
cleanup: cleanup:
@ -331,8 +332,8 @@ cleanup:
return ret; return ret;
} }
bool ncdc_api_userinfo(ncdc_api_t api, ncdc_account_t login, bool dc_api_userinfo(dc_api_t api, dc_account_t login,
ncdc_account_t user) dc_account_t user)
{ {
char *url = NULL; char *url = NULL;
json_t *reply = NULL; json_t *reply = NULL;
@ -342,9 +343,9 @@ bool ncdc_api_userinfo(ncdc_api_t api, ncdc_account_t login,
return_if_true(login == NULL, false); return_if_true(login == NULL, false);
return_if_true(user == NULL, false); return_if_true(user == NULL, false);
asprintf(&url, "users/%s", ncdc_account_id(user)); asprintf(&url, "users/%s", dc_account_id(user));
reply = ncdc_api_call_sync(api, ncdc_account_token(login), url, NULL); reply = dc_api_call_sync(api, dc_account_token(login), url, NULL);
goto_if_true(reply == NULL, cleanup); goto_if_true(reply == NULL, cleanup);
/* TODO: parse json and store info in user /* TODO: parse json and store info in user

View File

@ -1,9 +1,11 @@
#include <ncdc/apisync.h> #include <dc/apisync.h>
#include <ncdc/refable.h> #include <dc/refable.h>
struct ncdc_api_sync_ #include "internal.h"
struct dc_api_sync_
{ {
ncdc_refable_t ref; dc_refable_t ref;
int code; int code;
@ -19,7 +21,7 @@ struct ncdc_api_sync_
struct curl_slist *list; struct curl_slist *list;
}; };
static void ncdc_api_sync_free(ncdc_api_sync_t s) static void dc_api_sync_free(dc_api_sync_t s)
{ {
return_if_true(s == NULL,); return_if_true(s == NULL,);
@ -46,13 +48,13 @@ static void ncdc_api_sync_free(ncdc_api_sync_t s)
free(s); free(s);
} }
ncdc_api_sync_t ncdc_api_sync_new(CURLM *curl, CURL *easy) dc_api_sync_t dc_api_sync_new(CURLM *curl, CURL *easy)
{ {
ncdc_api_sync_t ptr = calloc(1, sizeof(struct ncdc_api_sync_)); dc_api_sync_t ptr = calloc(1, sizeof(struct dc_api_sync_));
return_if_true(ptr == NULL, NULL); return_if_true(ptr == NULL, NULL);
ptr->easy = easy; ptr->easy = easy;
ptr->ref.cleanup = (cleanup_t)ncdc_api_sync_free; ptr->ref.cleanup = (dc_cleanup_t)dc_api_sync_free;
ptr->stream = open_memstream(&ptr->buffer, &ptr->bufferlen); ptr->stream = open_memstream(&ptr->buffer, &ptr->bufferlen);
if (ptr->stream == NULL) { if (ptr->stream == NULL) {
@ -65,40 +67,40 @@ ncdc_api_sync_t ncdc_api_sync_new(CURLM *curl, CURL *easy)
ptr->list = curl_slist_append(NULL, ""); ptr->list = curl_slist_append(NULL, "");
return ncdc_ref(ptr); return dc_ref(ptr);
} }
struct curl_slist *ncdc_api_sync_list(ncdc_api_sync_t sync) struct curl_slist *dc_api_sync_list(dc_api_sync_t sync)
{ {
return_if_true(sync == NULL, NULL); return_if_true(sync == NULL, NULL);
return sync->list; return sync->list;
} }
FILE *ncdc_api_sync_stream(ncdc_api_sync_t sync) FILE *dc_api_sync_stream(dc_api_sync_t sync)
{ {
return_if_true(sync == NULL, NULL); return_if_true(sync == NULL, NULL);
return sync->stream; return sync->stream;
} }
char const *ncdc_api_sync_data(ncdc_api_sync_t sync) char const *dc_api_sync_data(dc_api_sync_t sync)
{ {
return_if_true(sync == NULL, NULL); return_if_true(sync == NULL, NULL);
return sync->buffer; return sync->buffer;
} }
size_t ncdc_api_sync_datalen(ncdc_api_sync_t sync) size_t dc_api_sync_datalen(dc_api_sync_t sync)
{ {
return_if_true(sync == NULL, 0L); return_if_true(sync == NULL, 0L);
return sync->bufferlen; return sync->bufferlen;
} }
int ncdc_api_sync_code(ncdc_api_sync_t sync) int dc_api_sync_code(dc_api_sync_t sync)
{ {
return_if_true(sync == NULL, 0L); return_if_true(sync == NULL, 0L);
return sync->code; return sync->code;
} }
bool ncdc_api_sync_wait(ncdc_api_sync_t sync) bool dc_api_sync_wait(dc_api_sync_t sync)
{ {
return_if_true(sync == NULL, false); return_if_true(sync == NULL, false);
@ -113,7 +115,7 @@ bool ncdc_api_sync_wait(ncdc_api_sync_t sync)
return (sync->stream == NULL && sync->buffer != NULL); return (sync->stream == NULL && sync->buffer != NULL);
} }
void ncdc_api_sync_finish(ncdc_api_sync_t sync, int code) void dc_api_sync_finish(dc_api_sync_t sync, int code)
{ {
return_if_true(sync == NULL,); return_if_true(sync == NULL,);

29
libdc/src/internal.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef DC_INTERNAL_H
#define DC_INTERNAL_H
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <errno.h>
#include <pthread.h>
#include <curl/curl.h>
#include <jansson.h>
#include <glib.h>
#include <event.h>
#include <event2/thread.h>
//#define DEBUG
#define return_if_true(v,r) do { if (v) return r; } while(0)
#define goto_if_true(v,l) do { if (v) goto l; } while(0)
#endif

6
libdc/src/loop.c Normal file
View File

@ -0,0 +1,6 @@
#include <dc/loop.h>
struct nc_loop_
{
nc_refable_t ref;
};

27
libdc/src/refable.c Normal file
View File

@ -0,0 +1,27 @@
#include <dc/refable.h>
#include "internal.h"
void *dc_ref(void *arg)
{
dc_refable_t *ptr = NULL;
return_if_true(arg == NULL,NULL);
ptr = (dc_refable_t *)arg;
++ptr->ref;
return arg;
}
void dc_unref(void *arg)
{
dc_refable_t *ptr = NULL;
return_if_true(arg == NULL,);
ptr = (dc_refable_t *)arg;
if ((--ptr->ref) <= 0 && ptr->cleanup != NULL) {
ptr->cleanup(arg);
}
}

12
libdc/src/util.c Normal file
View File

@ -0,0 +1,12 @@
#include <dc/util.h>
#include "internal.h"
void ncdc_util_dump_json(json_t *j)
{
return_if_true(j == NULL,);
char *str = json_dumps(j, JSON_COMPACT);
printf("%s\n", str);
free(str);
}

22
ncdc/CMakeLists.txt Normal file
View File

@ -0,0 +1,22 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
SET(TARGET "ncdc")
SET(SOURCES
"src/ncdc.c"
)
INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}/include
${DC_INCLUDE_DIRS}
${JANSSON_INCLUDE_DIRS}
${CURL_INCLUDE_DIRS}
${EVENT_INCLUDE_DIRS}
${GLIB2_INCLUDE_DIRS}
)
ADD_EXECUTABLE(${TARGET} ${SOURCES})
TARGET_LINK_LIBRARIES(${TARGET}
${DC_LIBRARIES}
${GLIB2_LIBRARIES}
)

View File

@ -1,5 +1,5 @@
#include <ncdc/ncdc.h> #include <ncdc/ncdc.h>
#include <ncdc/api.h> #include <dc/api.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
@ -15,8 +15,8 @@ struct event *timer = NULL;
static bool done = false; static bool done = false;
static pthread_t looper; static pthread_t looper;
char *ncdc_private_dir = NULL; char *dc_private_dir = NULL;
char *ncdc_config_file = NULL; char *dc_config_file = NULL;
static GKeyFile *config = NULL; static GKeyFile *config = NULL;
@ -24,7 +24,7 @@ static GKeyFile *config = NULL;
*/ */
CURLM *curl = NULL; CURLM *curl = NULL;
ncdc_api_t api = NULL; dc_api_t api = NULL;
static void handle_multi_info(void); static void handle_multi_info(void);
@ -158,16 +158,16 @@ static bool init_everything(void)
/* initialise event /* initialise event
*/ */
api = ncdc_api_new(); api = dc_api_new();
return_if_true(api == NULL, false); return_if_true(api == NULL, false);
ncdc_api_set_event_base(api, base); dc_api_set_event_base(api, base);
ncdc_api_set_curl_multi(api, curl); dc_api_set_curl_multi(api, curl);
config = g_key_file_new(); config = g_key_file_new();
return_if_true(config == NULL, false); return_if_true(config == NULL, false);
g_key_file_load_from_file(config, ncdc_config_file, 0, NULL); g_key_file_load_from_file(config, dc_config_file, 0, NULL);
return true; return true;
} }
@ -187,7 +187,7 @@ static void handle_multi_info(void)
} }
} }
if (msg->msg == CURLMSG_DONE) { if (msg->msg == CURLMSG_DONE) {
ncdc_api_signal(api, msg->easy_handle, msg->data.result); dc_api_signal(api, msg->easy_handle, msg->data.result);
} }
} else { } else {
usleep(10 * 1000); usleep(10 * 1000);
@ -210,7 +210,7 @@ static void *loop_thread(void *arg)
return NULL; return NULL;
} }
static ncdc_account_t account_from_config(void) static dc_account_t account_from_config(void)
{ {
char const *email = NULL; char const *email = NULL;
char const *password = NULL; char const *password = NULL;
@ -221,8 +221,8 @@ static ncdc_account_t account_from_config(void)
return_if_true(email == NULL || password == NULL, NULL); return_if_true(email == NULL || password == NULL, NULL);
ptr = ncdc_account_new2(email, password); ptr = dc_account_new2(email, password);
ncdc_account_set_id(ptr, "@me"); dc_account_set_id(ptr, "@me");
return ptr; return ptr;
} }
@ -240,16 +240,16 @@ int main(int ac, char **av)
return 3; return 3;
} }
asprintf(&ncdc_private_dir, "%s/.ncdc", getenv("HOME")); asprintf(&dc_private_dir, "%s/.ncdc", getenv("HOME"));
if (mkdir(ncdc_private_dir, 0755) < 0) { if (mkdir(dc_private_dir, 0755) < 0) {
if (errno != EEXIST) { if (errno != EEXIST) {
fprintf(stderr, "failed to make %s: %s\n", ncdc_private_dir, fprintf(stderr, "failed to make %s: %s\n", dc_private_dir,
strerror(errno)); strerror(errno));
return 3; return 3;
} }
} }
asprintf(&ncdc_config_file, "%s/config", ncdc_private_dir); asprintf(&dc_config_file, "%s/config", dc_private_dir);
if (!init_everything()) { if (!init_everything()) {
return 3; return 3;
@ -260,18 +260,18 @@ int main(int ac, char **av)
return 3; return 3;
} }
ncdc_account_t a = account_from_config(); dc_account_t a = account_from_config();
if (a == NULL) { if (a == NULL) {
fprintf(stderr, "no account specified in config file; sho-sho!\n"); fprintf(stderr, "no account specified in config file; sho-sho!\n");
return 3; return 3;
} }
if (!ncdc_api_authenticate(api, a)) { if (!dc_api_authenticate(api, a)) {
fprintf(stderr, "authentication failed, wrong password?\n"); fprintf(stderr, "authentication failed, wrong password?\n");
return 3; return 3;
} }
if (!ncdc_api_userinfo(api, a, a)) { if (!dc_api_userinfo(api, a, a)) {
fprintf(stderr, "failed to get user information\n"); fprintf(stderr, "failed to get user information\n");
return 3; return 3;
} }

View File

@ -1,25 +0,0 @@
#include <ncdc/refable.h>
void *ncdc_ref(void *arg)
{
ncdc_refable_t *ptr = NULL;
return_if_true(arg == NULL,NULL);
ptr = (ncdc_refable_t *)arg;
++ptr->ref;
return arg;
}
void ncdc_unref(void *arg)
{
ncdc_refable_t *ptr = NULL;
return_if_true(arg == NULL,);
ptr = (ncdc_refable_t *)arg;
if ((--ptr->ref) <= 0 && ptr->cleanup != NULL) {
ptr->cleanup(arg);
}
}