/* * Kangaroo Punch MultiPlayer Game Server Mark II * Copyright (C) 2020-2021 Scott Duensing * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include #include #include #include "os.h" #include "rest.h" #include "array.h" #include "console.h" typedef struct RestResponseS { uint64_t length; char *data; } RestResponseT; static char *_restURL = NULL; static char *_restUser = NULL; static char *_restPass = NULL; static pthread_mutex_t *_restMutexBuffer = NULL; static void restMutexLocker(int mode, int n, const char *file, int line); static size_t restResponseWrite(void *ptr, size_t size, size_t nmemb, RestResponseT *s); static unsigned long restThreadtIdGet(void); static json_object *restUrlPost(json_object *request); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" // It's used, but the compiler isn't picking it up because it's via a callback. static void restMutexLocker(int mode, int n, const char *file, int line) { (void)file; (void)line; if (mode & CRYPTO_LOCK) { pthread_mutex_lock(&_restMutexBuffer[n]); } else { pthread_mutex_unlock(&_restMutexBuffer[n]); } } #pragma GCC diagnostic pop void restRelease(json_object *object) { json_object_put(object); } json_object *restRequest(char *command, char *format, ...) { va_list args = { 0 }; json_object *request = json_object_new_object(); json_object *response = NULL; char *key = NULL; char *string = NULL; uint8_t result = 0; json_object_object_add(request, "command", json_object_new_string(command)); va_start(args, format); if (format) { while (*format != 0) { key = va_arg(args, char *); switch (*format) { case 's': json_object_object_add(request, key, json_object_new_string(va_arg(args, char *))); break; case 'i': json_object_object_add(request, key, json_object_new_int64(va_arg(args, int64_t))); break; default: utilDie("restRequest: Unknown format option '%c'.\n", *format); break; } format++; } } va_end(args); //logWrite("Request: %s\n", json_object_to_json_string_ext(request, JSON_C_TO_STRING_PRETTY)); response = restUrlPost(request); json_object_put(request); //logWrite("Response: %s\n", json_object_to_json_string_ext(response, JSON_C_TO_STRING_PRETTY)); if (response) { string = (char *)json_object_get_string(json_object_object_get(response, "result")); result = (string[0] == 't' || string[0] == 'T') ? 1 : 0; if (!result) { logWrite("restRequest: %s\n", json_object_get_string(json_object_object_get(response, "reason"))); json_object_put(response); response = NULL; } } return response; } static size_t restResponseWrite(void *ptr, size_t size, size_t nmemb, RestResponseT *s) { size_t newLength = s->length + size * nmemb; s->data = realloc(s->data, newLength + 1); if (s->data == NULL) { utilDie("restResponseWrite: realloc() failed.\n"); } memcpy(s->data + s->length, ptr, size*nmemb); s->data[newLength] = 0; s->length = newLength; return size * nmemb; } void restShutdown(void) { uint64_t i; DEL(_restPass); DEL(_restUser); DEL(_restURL); if (_restMutexBuffer) { CRYPTO_set_id_callback(NULL); CRYPTO_set_locking_callback(NULL); for (i=0; i