commit 5c327958e264377162cdd4326171fc7f4654a152 Author: SuperNovaa41 Date: Fri Jan 12 12:15:17 2024 -0500 initial commit diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f7f8a65 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +all: main.c + gcc main.c -lcurl -lcjson -o isbn -Wall diff --git a/a.out b/a.out new file mode 100755 index 0000000..1290597 Binary files /dev/null and b/a.out differ diff --git a/isbn b/isbn new file mode 100755 index 0000000..4b69e2d Binary files /dev/null and b/isbn differ diff --git a/main.c b/main.c new file mode 100644 index 0000000..d0ae1f6 --- /dev/null +++ b/main.c @@ -0,0 +1,179 @@ +#include +#include +#include +#include + +#include + +#define BASE_URL_SIZE 38 + +/** + * struct string_t + * char* buf - The buffer containing the string data + * size_t len - The length of the buffer + */ +typedef struct string_t { + char* buf; + size_t len; +} string; + +/** + * void init_string + * string* s - The string struct + * + * Initializes the string struct */ +void init_string (string* s) +{ + s->len = 0; + s->buf = malloc(s->len + 1); + + if (NULL == s->buf) { + fprintf(stderr, "malloc() failed\n"); + exit(EXIT_FAILURE); + } + s->buf[0] = '\0'; +} + +/** + * size_t writefunc + * + * The arguments come from CURLOPT_WRITEFUNCTION + * + * Writes the cURL get into the string struct + */ +size_t writefunc(void* ptr, size_t size, size_t nmemb, string* s) +{ + size_t new_len = s->len + (size * nmemb); + s->buf = realloc(s->buf, new_len + 1); + if (NULL == s->buf) { + fprintf(stderr, "realloc() failed\n"); + exit(EXIT_FAILURE); + } + + memcpy(s->buf + s->len, ptr, size * nmemb); + s->buf[new_len] = '\0'; + s->len = new_len; + + return size * nmemb; +} + +/** + * CURLcode perform_book_get + * char isbn_buf[14] - The ISBN + * string* s - The string struct to place the GET output in + * + * Perforrms a GET request with the ISBN + */ +CURLcode perform_book_get(char isbn_buf[14], string* s) +{ + CURL* handler; + char *base_url; + size_t finalurl_size = BASE_URL_SIZE + 15; + char finalurl[finalurl_size]; + CURLcode result; + + handler = curl_easy_init(); + if (!handler) { + fprintf(stderr, "cURL failed to initialize!\n"); + exit(EXIT_FAILURE); + } + + base_url = "https://openlibrary.org/search.json?q="; + /** + * Setup the URL for the request + */ + snprintf(finalurl, finalurl_size, "%s%s", base_url, isbn_buf); + + curl_easy_setopt(handler, CURLOPT_URL, finalurl); + curl_easy_setopt(handler, CURLOPT_HTTPGET, 1L); + curl_easy_setopt(handler, CURLOPT_WRITEFUNCTION, writefunc); + curl_easy_setopt(handler, CURLOPT_WRITEDATA, s); + + result = curl_easy_perform(handler); + + // Always clean up + curl_easy_cleanup(handler); + + return result; +} + +void parse_json(string* s) +{ + cJSON* json = cJSON_Parse(s->buf); + if (NULL == json) { + const char* error_ptr = cJSON_GetErrorPtr(); + if (NULL != error_ptr) + fprintf(stderr, "JSON error: %s\n", error_ptr); + cJSON_Delete(json); + exit(EXIT_FAILURE); + } + + cJSON* docs = cJSON_GetObjectItemCaseSensitive(json, "docs"); + cJSON* child = docs->child; // this is the JSON object that stores all of the books information + + printf("Title: %s\n", cJSON_GetObjectItemCaseSensitive(child, "title")->valuestring); + + cJSON* authors = cJSON_GetObjectItemCaseSensitive(child, "author_name"); + printf("Author(s): "); + if (cJSON_IsArray(authors)) { + cJSON* authorarr = authors->child; + while (NULL != authorarr->next) { + printf("%s, ", authorarr->valuestring); + authorarr = authorarr->next; + } + printf("%s\n", authorarr->valuestring); + } else { + printf("Author(s): %s\n", authors->valuestring); + } + + printf("Year of Publication: %d\n", cJSON_GetObjectItemCaseSensitive(child, "publish_year")->child->valueint); + printf("Page length: %d\n", cJSON_GetObjectItemCaseSensitive(child, "number_of_pages_median")->valueint); +} + +int main(int argc, char* argv[]) +{ + char isbn_buf[14]; + CURLcode res; + + if (2 != argc) { + printf("Usage: isbn [isbn]\n"); + return EXIT_FAILURE; + } + + /** + * We must initialize cURL + */ + curl_global_init(CURL_GLOBAL_ALL); + + /** + * Grab the ISBN from argv + */ + snprintf(isbn_buf, 14, "%s", argv[1]); + + /** + * Setup the output string + */ + string get_output; + init_string(&get_output); + + /** + * Perform the get request + */ res = perform_book_get(isbn_buf, &get_output); + if (0 != res) { + fprintf(stderr, "Failed to perform the get request!\n"); + return EXIT_FAILURE; + } + + /** + * Now we want to parse the JSON input + */ + parse_json(&get_output); + + /** + * We need to free this string + */ + free(get_output.buf); + + + return 0; +} diff --git a/test.c b/test.c new file mode 100644 index 0000000..f70a520 --- /dev/null +++ b/test.c @@ -0,0 +1,14 @@ +#include +#include + +int main(void) +{ + char* x = "Hello, "; + char* y = "world!"; + + size_t out_len = strlen(x) + strlen(y) + 1; + char out[out_len]; + snprintf(out, out_len, "%s%s", x, y); + puts(out); + return 0; +}