neocities.h

a C library for interacting with Neocities' API
git clone https://github.com/tanguyandreani/neocities.h
Log | Files | Refs | README | LICENSE

commit 6c74683a4eb785714839512716ad63331dfcc5e3
Author: Tanguy Andreani <dev@tanguy.space>
Date:   Thu, 21 Feb 2019 06:15:08 +0100

birthday!

Diffstat:
A.gitignore | 3+++
Aapikey.h.example | 2++
Aexample.c | 33+++++++++++++++++++++++++++++++++
Aneocities.h | 171+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 209 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1,2 @@ +apikey.h +a.out+ \ No newline at end of file diff --git a/apikey.h.example b/apikey.h.example @@ -0,0 +1 @@ +#define APIKEY "hello"+ \ No newline at end of file diff --git a/example.c b/example.c @@ -0,0 +1,33 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <curl/curl.h> +#include <json-c/json.h> + +#include "neocities.h" + +int main(void) +{ + json_object *obj = NULL; + + curl_global_init(CURL_GLOBAL_SSL); + + +// obj = neocities_api(APIKEY, INFO, "lainzine"); + obj = neocities_api(APIKEY, INFO, ""); + printf("%s\n", + json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PRETTY)); + json_object_put(obj); + + + obj = neocities_api(APIKEY, UPLOAD, "neocities.h"); + printf("%s\n", + json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PRETTY)); + json_object_put(obj); + + + curl_global_cleanup(); + + return 0; +} diff --git a/neocities.h b/neocities.h @@ -0,0 +1,171 @@ +#ifndef NEOCITIES_H +#define NEOCITIES_H + +#include "apikey.h" + +#define BASEURL "https://neocities.org/api/" + +/* POST */ +#define UPLOAD BASEURL "upload" +#define DELETE BASEURL "delete" + +/* GET */ +#define LIST BASEURL "list" +#define INFO BASEURL "info" +#define KEY BASEURL "key" + +typedef struct Neocities_ { + char *buf; + int size; + int pos; +} Neocities; + +void neocities_init(Neocities * neocities, size_t size) +{ + neocities->buf = malloc(sizeof(char) * size); + neocities->size = size; + neocities->pos = 0; + + return; +} + +void neocities_destroy(Neocities * neocities) +{ + free(neocities->buf); + + return; +} + +void neocities_dump(Neocities * neocities) +{ + int i = 0; + + while (i < neocities->pos) { + fputc(neocities->buf[i], stderr); + i++; + } + + return; +} + +size_t write_data(void *buffer, size_t size, size_t nmemb, + Neocities * neocities) +{ + int i = 0; + while (i < nmemb) { + + if (neocities->pos >= neocities->size) { + neocities->size += nmemb; + neocities->buf = + realloc(neocities->buf, sizeof(char) * neocities->size); + } + + neocities->buf[neocities->pos] = *(char *) (buffer + i); + + (neocities->pos)++; + i++; + } + + return i; +} + +json_object *neocities_api(const char *apikey, const char *action, + const char *params) +{ + Neocities neocities; + + struct curl_slist *headers; + + CURL *curl; + + curl_mime *form = NULL; + curl_mimepart *field = NULL; + + json_object *empty_error = + json_object_new_string("neocities_api() failed somewhere."); + + json_tokener *tok = json_tokener_new(); + json_object *obj = NULL; + + char url_with_get_params[500]; + + headers = NULL; + + curl = curl_easy_init(); + + if (!curl) { + fprintf(stderr, "couldn't initialize an easy handle.\n"); + return empty_error; + } + + if (strcmp(action, UPLOAD) == 0) { + + form = curl_mime_init(curl); + + field = curl_mime_addpart(form); + curl_mime_name(field, "sendfile"); + curl_mime_filedata(field, params); + + field = curl_mime_addpart(form); + curl_mime_name(field, "filename"); + curl_mime_data(field, params, CURL_ZERO_TERMINATED); + + headers = curl_slist_append(headers, "Expect:"); + + curl_easy_setopt(curl, CURLOPT_MIMEPOST, form); + curl_easy_setopt(curl, CURLOPT_URL, action); + + } else if (strcmp(action, DELETE) == 0) { + + fprintf(stderr, "DELETE is currently unsupported.\n"); + return empty_error; + + } else if (strcmp(action, INFO) == 0 || strcmp(action, LIST) == 0 + || strcmp(action, KEY) == 0) { + + strcpy(&url_with_get_params[0], action); + + if (strcmp(action, INFO) == 0 && strcmp(params, "") != 0) + strcat(url_with_get_params, "?sitename="); + else if (strcmp(action, LIST) == 0 && strcmp(params, "") != 0) + strcat(url_with_get_params, "?path="); + + strcat(url_with_get_params, params); + curl_easy_setopt(curl, CURLOPT_URL, url_with_get_params); + + } else { + + fprintf(stderr, "bad action.\n"); + return empty_error; + + } + + char auth_bearer[22 + 32 + 1] = "Authorization: Bearer "; + strcat(auth_bearer, apikey); + + neocities_init(&neocities, 700); + + headers = curl_slist_append(headers, auth_bearer); + + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, ((Neocities *) & neocities)); + + if (curl_easy_perform(curl) != CURLE_OK) { + fprintf(stderr, "curl failed.\n"); + return empty_error; + } + + curl_slist_free_all(headers); + curl_mime_free(form); + curl_easy_cleanup(curl); + + obj = + json_tokener_parse_ex(tok, (char *) neocities.buf, neocities.pos); + + neocities_destroy(&neocities); + + return obj; +} + +#endif