From 143f5b64f187497af728a6d921c599dcc99ed807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=A6=8C=EA=A6=AB=EA=A6=B6=EA=A6=8F=EA=A7=80=EA=A6=A6?= =?UTF-8?q?=EA=A6=BF=EA=A6=A7=EA=A6=AE=EA=A6=91=EA=A6=A9=EA=A6=AD=EA=A7=80?= Date: Sun, 13 Jun 2021 15:41:54 +0800 Subject: Fix the way libcurl has been used --- admin.c | 4 +-- client.c | 18 +++++-------- configure.ac | 4 +-- icclient.h | 10 +++---- icclient/admin.h | 2 +- icclient/member.h | 4 +-- icclient/typedefs.h | 8 ++++-- login.c | 2 +- login.h | 4 +-- main.c | 58 +++++++++++++++++++++++++++++++++------- member.c | 8 +++--- ord.c | 2 +- request.c | 15 ++++++++--- request.h | 77 ++++++++++++++++++++++++----------------------------- 14 files changed, 129 insertions(+), 87 deletions(-) diff --git a/admin.c b/admin.c index 4e0fdf5..3ba9464 100644 --- a/admin.c +++ b/admin.c @@ -7,7 +7,7 @@ typedef struct icclient_admin icclient_admin; icclient_admin *icclient_admin_login(const char *username, const char *password, const char *successpage, const char *nextpage, const char *failpage, - icclient_handler handler) + void (*handler)(icclient_fetch_t *)) { icclient_admin *admin = malloc(sizeof(icclient_admin)); admin->name = NULL; @@ -19,7 +19,7 @@ icclient_admin *icclient_admin_login(const char *username, const char *password, void icclient_admin_newitem(const char *description, const char *comment, const char *price, const char *image_path) { - request(NULL, NULL, &(struct icclient_request_data){ 15, { + request(NULL, NULL, &(struct body){ 15, { { "mv_click", "process_filter" }, { "mv_data_fields", "sku description prod_group category comment inactive price wholesale image thumb image_large weight nontaxable gift_cert" }, { "mv_ui", "1" }, diff --git a/client.c b/client.c index aa2a1cc..4d8530a 100644 --- a/client.c +++ b/client.c @@ -2,18 +2,12 @@ #include "request.h" #include "icclient.h" -#ifdef __EMSCRIPTEN__ -extern void icclient_catalog_results(emscripten_fetch_t *); -#else -extern size_t icclient_catalog_results(void *, size_t, size_t, void *); -#endif - void icclient_init(const char *url, const char *certificate) { - icclient_request_init(url, certificate); + init(url, certificate); } -void icclient_results(const char *prod_group, void (*callback)(struct icclient_catalog *), icclient_handler handler) +void icclient_results(const char *prod_group, void (*callback)(struct icclient_catalog *), void (*handler)(icclient_fetch_t *)) { char nonspaced[strlen(prod_group) + 1]; strcpy(nonspaced, prod_group); @@ -23,12 +17,12 @@ void icclient_results(const char *prod_group, void (*callback)(struct icclient_c request(handler, (void *)callback, 0, "%s", nonspaced); } -void icclient_flypage(const char *sku, icclient_handler handler, struct icclient_product **productptr) +void icclient_flypage(const char *sku, void (*handler)(icclient_fetch_t *), struct icclient_product **productptr) { request(handler, (void *)productptr, 0, "%s", sku); } -void icclient_page(const char *path, icclient_handler handler, void **dataptr) +void icclient_page(const char *path, void (*handler)(icclient_fetch_t *), void **dataptr) { request(handler, (void *)dataptr, 0, "%s", path); } @@ -63,5 +57,7 @@ void icclient_free_catalog(struct icclient_catalog *catalog) void icclient_cleanup() { - icclient_request_cleanup(); +#ifndef __EMSCRIPTEN__ + cleanup(); +#endif } diff --git a/configure.ac b/configure.ac index 91d0b6d..ba95804 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,8 @@ AC_INIT([icclient], [0.0], [pt@darapsa.co.id]) AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AC_PROG_CC +AM_PROG_AR +LT_INIT AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([Makefile]) AC_CHECK_HEADER_STDBOOL @@ -10,8 +12,6 @@ AC_FUNC_MALLOC AC_FUNC_REALLOC AC_TYPE_SIZE_T AC_TYPE_SSIZE_T -AM_PROG_AR -LT_INIT AC_CANONICAL_HOST case $host_cpu in *wasm* ) wasm=true;; diff --git a/icclient.h b/icclient.h index fb13ef7..d537263 100644 --- a/icclient.h +++ b/icclient.h @@ -1,5 +1,5 @@ -#ifndef ICCLIENT_CLIENT_H -#define ICCLIENT_CLIENT_H +#ifndef ICCLIENT_H +#define ICCLIENT_H #include @@ -44,7 +44,7 @@ void icclient_init(const char *url, const char *certificate); * \param callback A pointer to the function that needs to be called after the catalog is ready. * \param handler A pointer to the function when a custom handler is needed to arrange the data into the catalog. */ -void icclient_results(const char *prod_group, void (*callback)(struct icclient_catalog *), icclient_handler handler); +void icclient_results(const char *prod_group, void (*callback)(struct icclient_catalog *), void (*handler)(icclient_fetch_t *)); /*! * \brief For fetching data about a specific product. @@ -52,9 +52,9 @@ void icclient_results(const char *prod_group, void (*callback)(struct icclient_c * \param handler A pointer to a cURL write function callback. * \param productptr A pointer to pointer to the product to store the data. */ -void icclient_flypage(const char *sku, icclient_handler handler, struct icclient_product **productptr); +void icclient_flypage(const char *sku, void (*handler)(icclient_fetch_t *), struct icclient_product **productptr); -void icclient_page(const char *path, icclient_handler handler, void **dataptr); +void icclient_page(const char *path, void (*handler)(icclient_fetch_t *), void **dataptr); void icclient_free_product(struct icclient_product *product); diff --git a/icclient/admin.h b/icclient/admin.h index 36ec0d6..cfc89da 100644 --- a/icclient/admin.h +++ b/icclient/admin.h @@ -15,7 +15,7 @@ extern "C" { struct icclient_admin *icclient_admin_login(const char *username, const char *password, const char *successpage, const char *nextpage, const char *failpage, - icclient_handler handler); + void (*handler)(icclient_fetch_t *)); void icclient_admin_newitem(const char *description, const char *comment, const char *price, const char *image_path); void icclient_admin_logout(struct icclient_admin *admin); diff --git a/icclient/member.h b/icclient/member.h index 1c0943a..feee6c3 100644 --- a/icclient/member.h +++ b/icclient/member.h @@ -62,10 +62,10 @@ extern "C" { struct icclient_member *icclient_member_newaccount(const char *username, const char *password, const char *verify, const char *successpage, - const char *nextpage, const char *failpage, icclient_handler handler); + const char *nextpage, const char *failpage, void (*handler)(icclient_fetch_t *)); struct icclient_member *icclient_member_login(const char *username, const char *password, const char *successpage, - const char *nextpage, const char *failpage, icclient_handler handler); + const char *nextpage, const char *failpage, void (*handler)(icclient_fetch_t *)); void icclient_member_account(const char *fname, const char *lname, const char *address1, const char *address2, const char *city, const char *state, const char *zip, const char *email, diff --git a/icclient/typedefs.h b/icclient/typedefs.h index 1b2f176..c45e260 100644 --- a/icclient/typedefs.h +++ b/icclient/typedefs.h @@ -3,9 +3,13 @@ #ifdef __EMSCRIPTEN__ #include -typedef void (*icclient_handler)(emscripten_fetch_t *); +typedef emscripten_fetch_t icclient_fetch_t; #else -typedef size_t (*icclient_handler)(void *, size_t, size_t, void *); +typedef struct { + void *userData; + char *data; + size_t numBytes; +} icclient_fetch_t; #endif #endif diff --git a/login.c b/login.c index 8beb856..5e97f4f 100644 --- a/login.c +++ b/login.c @@ -1,4 +1,4 @@ #include "login.h" extern inline void login(const char *, const char *, const char *, const char *, - const char *, const char *, const char *, icclient_handler, void *); + const char *, const char *, const char *, void (*)(icclient_fetch_t *), void *); diff --git a/login.h b/login.h index c11b634..9ef34f2 100644 --- a/login.h +++ b/login.h @@ -4,9 +4,9 @@ #include "request.h" inline void login(const char *username, const char *password, const char *verify, const char *click, - const char *successpage, const char *nextpage, const char *failpage, icclient_handler handler, void *user) + const char *successpage, const char *nextpage, const char *failpage, void (*handler)(icclient_fetch_t *), void *user) { - request(handler, user, &(struct icclient_request_data){ 7, { + request(handler, user, &(struct body){ 7, { { "mv_username", username }, { "mv_password", password }, { "mv_verify", verify }, diff --git a/main.c b/main.c index fb2e13b..45ec093 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include "icclient.h" #include "icclient/member.h" @@ -22,17 +24,55 @@ static void print_catalog(struct icclient_catalog *catalog) product->prod_group ); } - icclient_catalog_free(catalog); + icclient_free_catalog(catalog); } -static size_t print_user(void *contents, size_t size, size_t nmemb, void *userData) +static void handle_results(icclient_fetch_t *fetch) { - size_t realsize = size * nmemb; - char data[realsize + 1]; - memcpy(data, contents, realsize); - data[realsize] = '\0'; - printf("%s\n", data); - return realsize; + json_tokener *tokener = json_tokener_new(); + json_object *products = json_tokener_parse_ex(tokener, fetch->data, fetch->numBytes); + json_tokener_free(tokener); + size_t length = json_object_array_length(products); + struct icclient_catalog *catalog = malloc(sizeof(struct icclient_catalog) + sizeof(struct icclient_product *[length])); + catalog->length = length; + for (size_t i = 0; i < length; i++) { + catalog->products[i] = malloc(sizeof(struct icclient_product)); + struct icclient_product *product = catalog->products[i]; + memset(product, '\0', sizeof(struct icclient_product)); + json_object *object = json_object_array_get_idx(products, i); + struct json_object_iterator iterator = json_object_iter_begin(object); + struct json_object_iterator iterator_end = json_object_iter_end(object); + while (!json_object_iter_equal(&iterator, &iterator_end)) { + const char *key = json_object_iter_peek_name(&iterator); + json_object *val = json_object_iter_peek_value(&iterator); + if (!strcmp(key, "price")) + product->price = json_object_get_double(val); + else { + int len = json_object_get_string_len(val); + if (len) { + char *value = malloc(len + 1); + strcpy(value, json_object_get_string(val)); + if (!strcmp(key, "sku")) + product->sku = value; + else if (!strcmp(key, "thumb")) + product->thumb = value; + else if (!strcmp(key, "image")) + product->image = value; + else if (!strcmp(key, "description")) + product->description = value; + else if (!strcmp(key, "prod_group")) + product->prod_group = value; + } + } + json_object_iter_next(&iterator); + } + } + ((void (*)(struct icclient_catalog *))fetch->userData)(catalog); +} + +static void print_user(icclient_fetch_t *fetch) +{ + printf("%s\n", fetch->data); } int main(int argc, char *argv[]) @@ -48,7 +88,7 @@ int main(int argc, char *argv[]) icclient_init(url, NULL); free(url); - icclient_allproducts(print_catalog, NULL); + icclient_allproducts(print_catalog, handle_results); char *name_line = NULL; printf("\nName: "); diff --git a/member.c b/member.c index 9f64ed7..c5b5e42 100644 --- a/member.c +++ b/member.c @@ -60,7 +60,7 @@ icclient_member *initialise(const char *username, const char *password) icclient_member *icclient_member_newaccount(const char *username, const char *password, const char *verify, const char *successpage, const char *nextpage, - const char *failpage, icclient_handler handler) + const char *failpage, void (*handler)(icclient_fetch_t *)) { icclient_member *member = initialise(username, password); login(username, password, verify, "NewAccount", successpage, nextpage, failpage, handler, member); @@ -68,7 +68,7 @@ icclient_member *icclient_member_newaccount(const char *username, const char *pa } icclient_member *icclient_member_login(const char *username, const char *password, - const char *successpage, const char *nextpage, const char *failpage, icclient_handler handler) + const char *successpage, const char *nextpage, const char *failpage, void (*handler)(icclient_fetch_t *)) { icclient_member *member = initialise(username, password); login(username, password, NULL, "Login", successpage, nextpage, failpage, handler, member); @@ -79,7 +79,7 @@ void icclient_member_account(const char *fname, const char *lname, const char *a const char *address2, const char *city, const char *state, const char *zip, const char *email, const char *phone_day) { - request(NULL, NULL, &(struct icclient_request_data){ 13, { + request(NULL, NULL, &(struct body){ 13, { { "mv_form_profile", "account_change" }, { "mv_todo", "return" }, { "mv_nextpage", "member/account" }, @@ -98,7 +98,7 @@ void icclient_member_account(const char *fname, const char *lname, const char *a void icclient_member_changepassword(const char *password_old, const char *password, const char *verify) { - request(NULL, NULL, &(struct icclient_request_data){ 6, { + request(NULL, NULL, &(struct body){ 6, { { "mv_action", "return" }, { "mv_check", "Change_password" }, { "mv_successpage", "member/service" }, diff --git a/ord.c b/ord.c index 42a5aea..f102a45 100644 --- a/ord.c +++ b/ord.c @@ -86,7 +86,7 @@ void icclient_ord_order(const char *sku, const icclient_catalog *catalog, void icclient_ord_checkout(struct icclient_ord_order *order, struct icclient_member *member) { - request(NULL, NULL, &(struct icclient_request_data){ 14, { + request(NULL, NULL, &(struct body){ 14, { { "mv_todo", "submit" }, { "mv_action", "refresh" }, { "mv_order_profile", order->profile }, diff --git a/request.c b/request.c index 75c3073..835bf3a 100644 --- a/request.c +++ b/request.c @@ -5,8 +5,17 @@ emscripten_fetch_attr_t attr; #else CURL *curl; char *server_url; +size_t append(char *data, size_t size, size_t nmemb, icclient_fetch_t *fetch) +{ + size_t realsize = size * nmemb; + fetch->data = realloc(fetch->data, fetch->numBytes + realsize + 1); + memcpy(&(fetch->data[fetch->numBytes]), data, realsize); + fetch->numBytes += realsize; + fetch->data[fetch->numBytes] = '\0'; + return realsize; +} #endif -extern inline void icclient_request_init(const char *, const char *); -extern inline void request(icclient_handler, void *, struct icclient_request_data *, char *, ...); -extern inline void icclient_request_cleanup(); +extern inline void init(const char *, const char *); +extern inline void request(void (*)(icclient_fetch_t *), void *, struct body *, char *, ...); +extern inline void cleanup(); diff --git a/request.h b/request.h index 19ed118..dd19400 100644 --- a/request.h +++ b/request.h @@ -13,9 +13,9 @@ #endif #include "icclient/typedefs.h" -struct icclient_request_data { +struct body { size_t num_pairs; - struct icclient_request_pair { + struct pair { const char *key; const char *value; } pairs[16]; @@ -26,9 +26,10 @@ extern emscripten_fetch_attr_t attr; #else extern CURL *curl; extern char *server_url; +size_t append(char *, size_t, size_t, icclient_fetch_t *); #endif -inline void icclient_request_init(const char *url, const char *certificate) +inline void init(const char *url, const char *certificate) { #ifdef __EMSCRIPTEN__ emscripten_fetch_attr_init(&attr); @@ -36,25 +37,23 @@ inline void icclient_request_init(const char *url, const char *certificate) #else curl_global_init(CURL_GLOBAL_SSL); curl = curl_easy_init(); - if (curl) { - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ""); - if (certificate) - curl_easy_setopt(curl, CURLOPT_CAINFO, certificate); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ""); + if (certificate) + curl_easy_setopt(curl, CURLOPT_CAINFO, certificate); #ifdef DEBUG - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); #endif - size_t length = strlen(url); - size_t append = !(url[length - 1] == '/'); - server_url = malloc(length + append + 1); - strcpy(server_url, url); - if (append) - strcat(server_url, "/"); - } + size_t length = strlen(url); + size_t append = url[length - 1] != '/'; + server_url = malloc(length + append + 1); + strcpy(server_url, url); + if (append) + strcat(server_url, "/"); #endif } -inline void request(icclient_handler writefunction, void *writedata, struct icclient_request_data *body, char *fmt, ...) +inline void request(void (*handler)(icclient_fetch_t *), void *callback, struct body *body, char *fmt, ...) { va_list ap; char *p, *sval; @@ -89,7 +88,7 @@ inline void request(icclient_handler writefunction, void *writedata, struct iccl char url[length + 1]; #ifdef __EMSCRIPTEN__ - memset(url, 0, length + 1); + memset(url, '\0', length + 1); #else strcpy(url, server_url); #endif @@ -114,22 +113,19 @@ inline void request(icclient_handler writefunction, void *writedata, struct iccl va_end(ap); #ifdef __EMSCRIPTEN__ - attr.onsuccess = writefunction; - if (writedata) - attr.userData = writedata; + attr.onsuccess = handler; + attr.userData = callback; strcpy(attr.requestMethod, "GET"); emscripten_fetch(&attr, url); #else curl_easy_setopt(curl, CURLOPT_URL, url); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunction); - if (writedata) - curl_easy_setopt(curl, CURLOPT_WRITEDATA, writedata); - else - curl_easy_setopt(curl, CURLOPT_WRITEDATA, stdout); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, append); + icclient_fetch_t fetch = { .userData = callback, .numBytes = 0 }; + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fetch); struct curl_httppost *post, *last = NULL; if (body) { for (size_t i = 0; i < body->num_pairs; i++) { - struct icclient_request_pair pair = body->pairs[i]; + struct pair pair = body->pairs[i]; if (!pair.value) continue; curl_formadd(&post, &last, @@ -141,34 +137,31 @@ inline void request(icclient_handler writefunction, void *writedata, struct iccl curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); } else curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); -#ifdef DEBUG - CURLcode res = -#endif - curl_easy_perform(curl); + CURLcode res = curl_easy_perform(curl); if (post) curl_formfree(post); + if (res == CURLE_OK) + handler(&fetch); #ifdef DEBUG - if (res != CURLE_OK) { + else { const char *error = curl_easy_strerror(res); #ifdef __ANDROID__ - __android_log_print(ANDROID_LOG_ERROR, "libicclient.so", "%s: %s", __func__, error); + __android_log_print(ANDROID_LOG_ERROR, "libicclient.so", "%s", error); #else - fprintf(stderr, "%s: %s\n", __func__, error); -#endif + fprintf(stderr, "%s\n", error); #endif } #endif +#endif } -inline void icclient_request_cleanup() -{ #ifndef __EMSCRIPTEN__ - if (curl) { - free(server_url); - curl_easy_cleanup(curl); - } +inline void cleanup() +{ + free(server_url); + curl_easy_cleanup(curl); curl_global_cleanup(); -#endif } +#endif #endif -- cgit v1.2.3