diff --git a/include/curl_utils.h b/include/curl_utils.h new file mode 100644 index 0000000..38fab8d --- /dev/null +++ b/include/curl_utils.h @@ -0,0 +1,9 @@ +#include "e621.h" + +typedef struct { + char *key; + char **value; + int count; +} curl_url_peram_t; + +char *CurlGet(char *path, curl_url_peram_t *perams, int peram_count, e6_auth_t auth); \ No newline at end of file diff --git a/src/curl_utils.c b/src/curl_utils.c new file mode 100644 index 0000000..f641c53 --- /dev/null +++ b/src/curl_utils.c @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include "curl_utils.h" + + +struct curl_buffer { + char *data; + size_t size; +}; + + + +struct curl_slist *MakeHeaders(e6_auth_t auth) { + struct curl_slist *headers = NULL; + + char auth_buf[256]; + char base64_buf[128]; + snprintf(auth_buf, sizeof(auth_buf), "%s:%s", auth.username, auth.api_key); + EVP_EncodeBlock((unsigned char*)base64_buf, (unsigned char*)auth_buf, strlen(auth_buf)); + memset(auth_buf, 0, sizeof(auth_buf)); + snprintf(auth_buf, sizeof(base64_buf), "Authorization: Basic %s", base64_buf); + headers = curl_slist_append(headers, auth_buf); + + char user_agent_buf[256]; + snprintf(user_agent_buf, sizeof(user_agent_buf), "User-Agent: %s/%f (by %s on e621)", auth.project_name, auth.project_ver, auth.username); + headers = curl_slist_append(headers, user_agent_buf); + + return headers; +} + + +static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userdata) { + size_t total = size * nmemb; + struct curl_buffer *mem = (struct curl_buffer *)userdata; + + char *ptr = realloc(mem->data, mem->size + total + 1); + if (!ptr) + return 0; + + mem->data = ptr; + memcpy(&(mem->data[mem->size]), contents, total); + mem->size += total; + mem->data[mem->size] = '\0'; + + return total; +} + + +char *MakeUrl(char *path, curl_url_peram_t *perams, int peram_count) { + char *url = (char *)malloc(E621_URL_BUF_SIZE); + strncpy(url, E621_HOST, E621_URL_BUF_SIZE); + strncat(url, path, strlen(path)); + strcat(url, "?"); + + for (int i=0; i < peram_count; i++){ + strncat(url, perams[i].key, strlen(perams[i].key)); + strcat(url, "="); + + for (int j = 0; j < perams[i].count; j++) { + strncat(url, perams[i].value[j], strlen(perams[i].value[j])); + if (j != perams[i].count - 1) { + strcat(url, "+"); + } + } + + if(i < peram_count-1){ + strcat(url, "&"); + } + } + return url; +} + + +char *CurlGet(char *path, curl_url_peram_t *perams, int peram_count, e6_auth_t auth) { + CURL *curl = curl_easy_init(); + CURLcode result; + + struct curl_buffer buffer; + buffer.data = malloc(1); + buffer.size = 0; + + if(!curl){ + fprintf(stderr, "Failed to initialize CURL"); + exit(EXIT_FAILURE); + } + + char *url = MakeUrl(path, perams, peram_count); + + struct curl_slist *headers = MakeHeaders(auth); + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&buffer); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + result = curl_easy_perform(curl); + + if (result != CURLE_OK) { + fprintf(stderr, "CURL error: %s", curl_easy_strerror(result)); + return NULL; + } + + return buffer.data; +} \ No newline at end of file diff --git a/src/e621.c b/src/e621.c index 2558386..ce4f5d3 100644 --- a/src/e621.c +++ b/src/e621.c @@ -5,93 +5,28 @@ #include #include #include "e621.h" - -struct Memory { - char *data; - size_t size; -}; - -struct curl_slist *MakeHeaders(e6_auth_t auth) { - struct curl_slist *headers = NULL; - - char auth_buf[256]; - char base64_buf[128]; - snprintf(auth_buf, sizeof(auth_buf), "%s:%s", auth.username, auth.api_key); - EVP_EncodeBlock((unsigned char*)base64_buf, (unsigned char*)auth_buf, strlen(auth_buf)); - memset(auth_buf, 0, sizeof(auth_buf)); - snprintf(auth_buf, sizeof(base64_buf), "Authorization: Basic %s", base64_buf); - headers = curl_slist_append(headers, auth_buf); - - char user_agent_buf[256]; - snprintf(user_agent_buf, sizeof(user_agent_buf), "User-Agent: %s/%f (by %s on e621)", auth.project_name, auth.project_ver, auth.username); - headers = curl_slist_append(headers, user_agent_buf); - - return headers; -} - -static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userdata) -{ - size_t total = size * nmemb; - struct Memory *mem = (struct Memory *)userdata; - - char *ptr = realloc(mem->data, mem->size + total + 1); - if (!ptr) - return 0; - - mem->data = ptr; - memcpy(&(mem->data[mem->size]), contents, total); - mem->size += total; - mem->data[mem->size] = '\0'; - - return total; -} +#include "curl_utils.h" e6_post_t *E6List(e6_auth_t auth, char **tags, int tags_count, unsigned int page, unsigned int limit) { - CURL *curl = curl_easy_init(); - CURLcode result; - struct Memory read_buffer; - read_buffer.data = malloc(1); - read_buffer.size = 0; + char *path = "/posts.json"; + curl_url_peram_t perams[3]; - if (curl) { - char *url = (char *)malloc(E621_URL_BUF_SIZE); - strncpy(url, E621_HOST, E621_URL_BUF_SIZE); - strcat(url, "/posts.json?tags="); + perams[0].key = "page"; + perams[0].value = (char *[]){ malloc(10) } ; + sprintf(perams[0].value[0], "%u", page); + perams[0].count = 1; - for (int i = 0; i < tags_count; i++) { - char *tag = tags[i]; - strncat(url, tag, strlen(tag)); - strcat(url, "+"); - } + perams[1].key = "limit"; + perams[1].value = (char *[]){ malloc(10) }; + sprintf(perams[1].value[0], "%u", limit); + perams[1].count = 1; - char page_buf[15]; - snprintf(page_buf, sizeof(page_buf), "&page=%d", page); - strncat(url, page_buf, strlen(page_buf)); + perams[2].key = "tags"; + perams[2].value = tags; + perams[2].count = tags_count; - char limit_buf[15]; - snprintf(limit_buf, sizeof(limit_buf), "&limit=%d", limit); - strncat(url, limit_buf, strlen(limit_buf)); - - struct curl_slist *headers = MakeHeaders(auth); - - curl_easy_setopt(curl, CURLOPT_URL, url); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&read_buffer); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); - result = curl_easy_perform(curl); - - } else { - fprintf(stderr, "Failed to initialize CURL"); - exit(EXIT_FAILURE); - } - - if (result != CURLE_OK) { - fprintf(stderr, "CURL error: %s", curl_easy_strerror(result)); - return NULL; - } - - // Temp (testing purposes) - printf(read_buffer.data); + char *data = CurlGet(path, perams, 3, auth); + printf("%s\n", data); return NULL; } \ No newline at end of file