From 6c4949f31cb617675519a6f9f03748fcfa2faa1b Mon Sep 17 00:00:00 2001 From: Maxim Slipenko Date: Mon, 27 Nov 2023 08:40:40 +0300 Subject: [PATCH] init --- .gitignore | 2 + CMakeLists.txt | 12 ++++ cmake/modules/FindJsonC.cmake | 19 ++++++ cmake/modules/FindNeon.cmake | 19 ++++++ src/yandex_disk_api.c | 120 ++++++++++++++++++++++++++++++++++ src/yandex_disk_api.h | 26 ++++++++ 6 files changed, 198 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 cmake/modules/FindJsonC.cmake create mode 100644 cmake/modules/FindNeon.cmake create mode 100644 src/yandex_disk_api.c create mode 100644 src/yandex_disk_api.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ac6c48 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/.idea/ +/cmake-build-debug/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..9ec292f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.5) +project(YaDisk) + +set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules) +find_package(Neon REQUIRED) +find_package(JsonC REQUIRED) + +add_library(yadisk src/yandex_disk_api.c + tests/ctest.c) + +target_include_directories(yadisk PRIVATE ${NEON_INCLUDE_DIR} ${JSON_C_INCLUDE_DIR}) +target_link_libraries(yadisk ${NEON_LIBRARIES} ${JSON_C_LIBRARIES}) \ No newline at end of file diff --git a/cmake/modules/FindJsonC.cmake b/cmake/modules/FindJsonC.cmake new file mode 100644 index 0000000..2068725 --- /dev/null +++ b/cmake/modules/FindJsonC.cmake @@ -0,0 +1,19 @@ +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE(PkgConfig) +PKG_CHECK_MODULES(PKG_JSON_C json-c) + +FIND_PATH(JSON_C_INCLUDE_DIR json.h + PATHS + ${PKG_JSON_C_INCLUDE_DIRS} + /usr/include + /usr/local/include + PATH_SUFFIXES json-c +) + +FIND_LIBRARY(JSON_C_LIBRARIES json-c + ${PKG_JSON_C_LIBRARY_DIRS} + /usr/lib + /usr/local/lib +) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(JsonC DEFAULT_MSG JSON_C_LIBRARIES JSON_C_INCLUDE_DIR) diff --git a/cmake/modules/FindNeon.cmake b/cmake/modules/FindNeon.cmake new file mode 100644 index 0000000..53f9cfd --- /dev/null +++ b/cmake/modules/FindNeon.cmake @@ -0,0 +1,19 @@ +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE(PkgConfig) +PKG_CHECK_MODULES(PKG_NEON neon) + +FIND_PATH(NEON_INCLUDE_DIR ne_request.h + PATHS + ${PKG_NEON_INCLUDE_DIRS} + /usr/include + /usr/local/include + PATH_SUFFIXES neon +) + +FIND_LIBRARY(NEON_LIBRARIES neon + ${PKG_NEON_LIBRARY_DIRS} + /usr/lib + /usr/local/lib +) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Neon DEFAULT_MSG NEON_LIBRARIES NEON_INCLUDE_DIR) \ No newline at end of file diff --git a/src/yandex_disk_api.c b/src/yandex_disk_api.c new file mode 100644 index 0000000..b94d92e --- /dev/null +++ b/src/yandex_disk_api.c @@ -0,0 +1,120 @@ +// +// Created by maxim on 26.11.23. +// + +#include "yandex_disk_api.h" +#include "json.h" + +#define YANDEX_DISK_API_HOST "cloud-api.yandex.net" + +static int ssl_verify_callback(void *userdata, int failures, const ne_ssl_certificate *cert); +static int api_http_request( + yadisk_api_client *client, + const char* method, + const char* path, + char** output + ); + +void yadisk_get_disk(yadisk_api_client *client, yadisk_disk_info* info) { + char* output = NULL; + int result = api_http_request(client, "GET", "/v1/disk", &output); + json_object* root = json_tokener_parse(output); + free(output); + + if (!result) { + json_object_put(root); + return; + } + + json_object* total_space = NULL; + json_object_object_get_ex(root, "total_space", &total_space); + info->total_space = json_object_get_int64(total_space); + json_object_put(total_space); + + json_object_put(root); +} + +void yadisk_delete_disk_resources(yadisk_api_client *client) { + char* output = NULL; + int result = api_http_request(client, "DELETE", "/v1/disk/resource", &output); + + if (!result) { + // error + } + + free(output); +} + +static int ssl_verify_callback(void *userdata, int failures, const ne_ssl_certificate *cert) { + if (failures & NE_SSL_UNTRUSTED) { + return 0; + } + return 1; +}; + +static void +set_api_auth_header( + ne_request *req, + yadisk_api_client* client +) { + size_t str_size = 6 + strlen(client->token) + 1; + char *str = malloc(sizeof(char) * str_size); + snprintf(str, str_size, "OAuth %s", client->token); + ne_add_request_header(req, "Authorization", str); +} + +static int +api_http_request( + yadisk_api_client* client, + const char* method, + const char* path, + char** output + ) +{ + ne_session *sess; + ne_request *req; + sess = ne_session_create("https", YANDEX_DISK_API_HOST, 443); + ne_ssl_set_verify(sess, ssl_verify_callback, NULL); + + req = ne_request_create(sess, method, path); + + set_api_auth_header(req, client); + + char* result = malloc(1); + size_t currentSize = 1; // Текущий размер буфера result + + do { + int stat = ne_begin_request(req); + const ne_status* status = ne_get_status(req); + + if (stat != NE_OK) { + if (!status->code) { + return -1; + } + return -1; + } + + if (status->code != 200) { + return -2; + } + + char buffer[1024]; + ssize_t bytes; // Количество прочитанных байт + + while ((bytes = ne_read_response_block(req, buffer, 1024)) > 0) { + currentSize += bytes; + result = realloc(result, currentSize); + strncat(result, buffer, bytes); + } + } while (ne_end_request(req)); + + ne_request_destroy(req); + ne_session_destroy(sess); + ne_sock_exit(); + + *output = malloc(currentSize * sizeof(char)); + strcpy(*output, result); + free(result); + + return 0; +} \ No newline at end of file diff --git a/src/yandex_disk_api.h b/src/yandex_disk_api.h new file mode 100644 index 0000000..12bf5c8 --- /dev/null +++ b/src/yandex_disk_api.h @@ -0,0 +1,26 @@ +// +// Created by maxim on 26.11.23. +// + +#ifndef YANDEX_DISK_API_H +#define YANDEX_DISK_API_H + +#include +#include +#include +#include + +typedef struct yadisk_api_client +{ + char* token; +} yadisk_api_client; + +typedef struct yadisk_disk_info +{ + long total_space; +} yadisk_disk_info; + +void yadisk_get_disk(yadisk_api_client* client, yadisk_disk_info* info); +void yadisk_delete_disk_resources(yadisk_api_client *client); + +#endif //YANDEX_DISK_API_H