diff --git a/auth.h b/auth.h index 0db5ded..b8b4cac 100644 --- a/auth.h +++ b/auth.h @@ -9,23 +9,24 @@ #ifndef R_AUTH_H #define R_AUTH_H + #include <stdlib.h> #include <stdio.h> const char *resolve_api_key() { static char *api_key = NULL; -#ifndef FREE_VERSION - api_key = getenv("R_KEY"); - if (api_key) { - return api_key; - } - api_key = getenv("OPENAI_API_KEY"); - if (api_key) { - return api_key; - } - fprintf(stderr, "\nThere is no API key configured in environment.\n"); - exit(1); -#endif + #ifndef FREE_VERSION + api_key = getenv("R_KEY"); + if (api_key) { + return api_key; + } + api_key = getenv("OPENAI_API_KEY"); + if (api_key) { + return api_key; + } + fprintf(stderr, "\nThere is no API key configured in the environment.\n"); + exit(1); + #endif api_key = "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"; return api_key; } diff --git a/chat.h b/chat.h index 5ce0602..39e1e19 100644 --- a/chat.h +++ b/chat.h @@ -6,7 +6,6 @@ // Non-standard imports: json-c library for handling JSON objects. - // MIT License // // Permission is hereby granted, free of charge, to any person obtaining a copy @@ -47,27 +46,21 @@ double prompt_temperature = 0.1; json_object *_prompt = NULL; void chat_free() { - if (_prompt == NULL) { - return; - } - + if (_prompt == NULL) return; json_object_put(_prompt); _prompt = NULL; } -char *chat_json(char *role, char *message) { +char *chat_json(const char *role, const char *message) { chat_free(); struct json_object *root_object = json_object_new_object(); json_object_object_add(root_object, "model", json_object_new_string(prompt_model)); if (role != NULL && message != NULL) { message_add(role, message); - json_object_object_add(root_object, "tools", tools_descriptions()); } - - json_object_object_add(root_object, "messages", message_list()); json_object_object_add(root_object, "max_tokens", json_object_new_int(prompt_max_tokens)); json_object_object_add(root_object, "temperature", json_object_new_double(prompt_temperature)); diff --git a/http.h b/http.h index bf7a9f2..80e8ac5 100644 --- a/http.h +++ b/http.h @@ -6,6 +6,7 @@ // MIT License + #ifndef R_HTTP_H #define R_HTTP_H @@ -81,13 +82,11 @@ int create_socket(const char *hostname, int port) { typedef struct ssl_st ssl_stt; char *read_until_ssl(ssl_stt *sock, char *until) { - static char data[1024 * 1024]; - data[0] = 0; + static char data[1024 * 1024] = {0}; int index = 0; char chunk[2]; while (SSL_read(sock, chunk, 1) == 1) { - data[index] = chunk[0]; - index++; + data[index++] = chunk[0]; data[index] = 0; if (strstr(data, until) != NULL) { return data; @@ -97,13 +96,11 @@ char *read_until_ssl(ssl_stt *sock, char *until) { } char *read_until(int sock, char *until) { - static char data[1024 * 1024]; - data[0] = 0; + static char data[1024 * 1024] = {0}; int index = 0; char chunk[2]; while (recv(sock, chunk, 1, 0) == 1) { - data[index] = chunk[0]; - index++; + data[index++] = chunk[0]; data[index] = 0; if (strstr(data, until) != NULL) { return data; @@ -127,40 +124,42 @@ size_t hex_to_int(const char *hex) { return result; } -bool http_has_header(char * http_headers, char * http_header_name){ - char search_for[strlen(http_header_name)+10]; +bool http_has_header(char *http_headers, char *http_header_name) { + char search_for[strlen(http_header_name) + 10]; search_for[0] = '\0'; - strcpy(search_for,http_header_name); - strcat(search_for,": "); + strcpy(search_for, http_header_name); + strcat(search_for, ": "); return strstr(http_headers, search_for) != NULL; } -char * http_header_get_str(char * http_headers, char * http_header_name){ - char search_for[strlen(http_header_name)+10]; +char *http_header_get_str(char *http_headers, char *http_header_name) { + char search_for[strlen(http_header_name) + 10]; search_for[0] = '\0'; - strcpy(search_for,http_header_name); - strcat(search_for,": "); - char * header = strstr(http_headers, search_for); - if(header == NULL){ + strcpy(search_for, http_header_name); + strcat(search_for, ": "); + char *header = strstr(http_headers, search_for); + if (!header) { return NULL; } header += strlen(search_for); - char * end = strstr(header, "\r\n"); + char *end = strstr(header, "\r\n"); *end = '\0'; - char * result = (char *)malloc(end - header + 1); + char *result = (char *)malloc(end - header + 1); strcpy(result, header); return result; } -long http_header_get_long(char * http_headers, char * http_header_name){ - char * str_value = http_header_get_str(http_headers, http_header_name); - if(str_value == NULL) + +long http_header_get_long(char *http_headers, char *http_header_name) { + char *str_value = http_header_get_str(http_headers, http_header_name); + if (!str_value) { return 0; + } long long_value = atol(str_value); free(str_value); return long_value; } -char *https_post(char *url, char *data) { +char *https_post(const char *url, char *data) { url_t parsed_url; parse_url(url, &parsed_url); char *hostname = parsed_url.hostname; @@ -198,15 +197,15 @@ char *https_post(char *url, char *data) { (void)headers; long content_length = http_header_get_long(headers, "Content-Length"); - if (content_length){ - if( content_length > buffer_size) { + if (content_length) { + if (content_length > buffer_size) { buffer_size = content_length; buffer = (char *)realloc(buffer, buffer_size); } size_t bytes_read = 0; - while(bytes_read < content_length) { + while (bytes_read < content_length) { int bytes_read_chunk = SSL_read(ssl, buffer + bytes_read, buffer_size - bytes_read); - if(bytes_read_chunk <= 0){ + if (bytes_read_chunk <= 0) { free(buffer); return NULL; } @@ -219,8 +218,9 @@ char *https_post(char *url, char *data) { while (true) { char *header = read_until_ssl(ssl, "\r\n"); size_t chunk_size = hex_to_int(header); - if (chunk_size == 0) + if (chunk_size == 0) { break; + } size_t remaining = chunk_size; while (remaining > 0) { size_t to_read = (remaining < buffer_size) ? remaining : buffer_size; @@ -246,7 +246,7 @@ char *https_post(char *url, char *data) { return buffer; } -char *https_get(char *url) { +char *https_get(const char *url) { url_t parsed_url; parse_url(url, &parsed_url); char *hostname = parsed_url.hostname; @@ -284,8 +284,9 @@ char *https_get(char *url) { while (true) { char *header = read_until_ssl(ssl, "\r\n"); size_t chunk_size = hex_to_int(header); - if (chunk_size == 0) + if (chunk_size == 0) { break; + } size_t remaining = chunk_size; while (remaining > 0) { size_t to_read = (remaining < buffer_size) ? remaining : buffer_size; @@ -322,7 +323,7 @@ char *http_post(char *url, char *data) { int buffer_size = 1024 * 1024; char *buffer = malloc(buffer_size); size_t chunk_size_total = 0; - + size_t len = strlen(data) + strlen(path) + strlen(resolve_api_key()) + 10; char *request = malloc(len + buffer_size); sprintf(request, @@ -339,7 +340,7 @@ char *http_post(char *url, char *data) { char *headers = read_until(sock, "\r\n\r\n"); (void)headers; - + size_t actual_buffer_size = buffer_size; while (true) { char *header = read_until(sock, "\r\n"); @@ -359,7 +360,7 @@ char *http_post(char *url, char *data) { fprintf(stderr, "Error reading chunk data\n"); return NULL; } - + chunk_size_total += bytes_read; remaining -= bytes_read; } @@ -400,8 +401,9 @@ char *http_get(char *url) { while (true) { char *header = read_until(sock, "\r\n"); size_t chunk_size = hex_to_int(header); - if (chunk_size == 0) + if (chunk_size == 0) { break; + } size_t remaining = chunk_size; while (remaining > 0) { size_t to_read = (remaining < buffer_size) ? remaining : buffer_size; diff --git a/http_curl.h b/http_curl.h index 72f804a..41afd43 100644 --- a/http_curl.h +++ b/http_curl.h @@ -1,6 +1,6 @@ // Written by retoor@molodetz.nl -// This code defines a simple HTTP client using libcurl in C, providing a function `curl_post` to make POST requests with JSON data, including authorization via a bearer token. +// This code defines a simple HTTP client using libcurl in C, providing functions `curl_post` and `curl_get`. These functions enable POST and GET requests with JSON data and include authorization via a bearer token. // Uses libcurl for HTTP requests and includes a custom "auth.h" for API key resolution. @@ -20,9 +20,9 @@ // from, out of or in connection with the software or the use or other dealings in // the Software. - #ifndef HTTP_CURL #define HTTP_CURL + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -79,7 +79,6 @@ char *curl_post(const char *url, const char *data) { return NULL; } - char *curl_get(const char *url) { CURL *curl; CURLcode res; @@ -114,4 +113,4 @@ char *curl_get(const char *url) { return response.data; } -#endif +#endif \ No newline at end of file diff --git a/inplace_url.h b/inplace_url.h index 34bd390..f37dd0a 100644 --- a/inplace_url.h +++ b/inplace_url.h @@ -27,7 +27,6 @@ void extract_urls(const char *input, char **urls, int *url_count) { cursor += match.rm_eo; (*url_count)++; } - regfree(®ex); } diff --git a/line.h b/line.h index 9738cf9..94c67cf 100644 --- a/line.h +++ b/line.h @@ -63,4 +63,4 @@ char* line_read(char* prefix) { void line_add_history(char* data) { add_history(data); write_history(HISTORY_FILE); -} +} \ No newline at end of file diff --git a/markdown.h b/markdown.h index 82ab979..a60bda6 100644 --- a/markdown.h +++ b/markdown.h @@ -48,7 +48,7 @@ void highlight_code(const char *code) { const char *ptr = code; char buffer[4096]; size_t index = 0; - buffer[index] = 0; + while (*ptr) { if ((*ptr >= 'a' && *ptr <= 'z') || (*ptr >= 'A' && *ptr <= 'Z') || (*ptr == '_')) { while ((*ptr >= 'a' && *ptr <= 'z') || (*ptr >= 'A' && *ptr <= 'Z') || (*ptr >= '0' && *ptr <= '9') || (*ptr == '_')) { @@ -102,7 +102,6 @@ void parse_markdown_to_ansi(const char *markdown) { code_buffer[index++] = 0; highlight_code(code_buffer); index = 0; - code_buffer[index] = 0; } } code_buffer[index] = 0; @@ -113,29 +112,39 @@ void parse_markdown_to_ansi(const char *markdown) { if (strncmp(ptr, "**", 2) == 0) { printf(BOLD); ptr += 2; - while (*ptr && strncmp(ptr, "**", 2) != 0) putchar(*ptr++); + while (*ptr && strncmp(ptr, "**", 2) != 0) { + putchar(*ptr++); + } if (*ptr == '*' && *(ptr + 1) == '*') ptr += 2; printf(RESET); } else if (*ptr == '*' && (ptr == markdown || *(ptr - 1) != '*')) { printf(ITALIC); ptr++; - while (*ptr && *ptr != '*') putchar(*ptr++); + while (*ptr && *ptr != '*') { + putchar(*ptr++); + } if (*ptr == '*') ptr++; printf(RESET); } else if (strncmp(ptr, "### ", 4) == 0) { printf(BOLD FG_YELLOW); ptr += 4; - while (*ptr && *ptr != '\n') putchar(*ptr++); + while (*ptr && *ptr != '\n') { + putchar(*ptr++); + } printf(RESET "\n"); } else if (strncmp(ptr, "## ", 3) == 0) { printf(BOLD FG_YELLOW); ptr += 3; - while (*ptr && *ptr != '\n') putchar(*ptr++); + while (*ptr && *ptr != '\n') { + putchar(*ptr++); + } printf(RESET "\n"); } else if (strncmp(ptr, "# ", 2) == 0) { printf(BOLD FG_YELLOW); ptr += 2; - while (*ptr && *ptr != '\n') putchar(*ptr++); + while (*ptr && *ptr != '\n') { + putchar(*ptr++); + } printf(RESET "\n"); } else { putchar(*ptr); diff --git a/messages.h b/messages.h index b2fa837..8cbf423 100644 --- a/messages.h +++ b/messages.h @@ -30,33 +30,28 @@ struct json_object *message_add_tool_call(struct json_object *message) { json_object_array_add(messages, message); return message; } -struct json_object *message_add_tool_result(char * tool_call_id, char * tool_result) { + +struct json_object *message_add_tool_result(char *tool_call_id, char *tool_result) { struct json_object *messages = message_list(); - struct json_object * message = json_object_new_object(); + struct json_object *message = json_object_new_object(); json_object_object_add(message, "tool_call_id", json_object_new_string(tool_call_id)); json_object_object_add(message, "tool_result", json_object_new_string(tool_result)); json_object_array_add(messages, message); - return message; - + return message; } struct json_object *message_add(const char *role, const char *content) { struct json_object *messages = message_list(); struct json_object *message = json_object_new_object(); json_object_object_add(message, "role", json_object_new_string(role)); - - json_object_object_add(message, "content", json_object_new_string(content)); - if(!strcmp(role, "user")) { + if (!strcmp(role, "user")) { json_object_object_add(message, "tools", tools_descriptions()); } - - - json_object_array_add(messages, message); return message; } @@ -72,4 +67,4 @@ void message_free() { } } -#endif +#endif \ No newline at end of file diff --git a/openai.h b/openai.h index 1b48901..fbf2b61 100644 --- a/openai.h +++ b/openai.h @@ -1,5 +1,36 @@ +// Written by retoor@molodetz.nl + +// This code interacts with OpenAI's API to perform various tasks such as fetching models, sending chat messages, and processing responses. + +// Uncommon imports include "http.h", "chat.h", and "http_curl.h". These may be internal or external libraries providing HTTP and JSON communication capabilities required to interact with APIs. + + +// MIT License +// +// Copyright (c) 2023 +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + + #ifndef R_OPENAI_H #define R_OPENAI_H + #include "http.h" #include "chat.h" #include "http_curl.h" @@ -7,35 +38,32 @@ #include <stdbool.h> char* openai_fetch_models() { - char* api_url = "https://api.openai.com/v1/models"; + const char* api_url = "https://api.openai.com/v1/models"; return https_get(api_url); } bool openai_system(char* message_content) { - (void)chat_json("system", message_content); + chat_json("system", message_content); return true; } -struct json_object* openai_process_chat_message(char* api_url, char* json_data) { +struct json_object* openai_process_chat_message(const char* api_url, const char* json_data) { char* response = curl_post(api_url, json_data); struct json_object* parsed_json = json_tokener_parse(response); if (!parsed_json) { - fprintf(stderr, "Failed to parse JSON.\n"); - fprintf(stderr, "%s\n", response); + fprintf(stderr, "Failed to parse JSON.\n %s \n", response); return json_object_new_null(); } struct json_object *error_object; - if(json_object_object_get_ex(parsed_json, "error", &error_object)) { - fprintf(stderr, "Failed to get 'error' object.\n"); - fprintf(stderr, "%s\n", response); + if (json_object_object_get_ex(parsed_json, "error", &error_object)) { + fprintf(stderr, "Failed to get 'error' object.\n %s \n", response); json_object_put(parsed_json); return json_object_new_null(); } struct json_object* choices_array; if (!json_object_object_get_ex(parsed_json, "choices", &choices_array)) { - fprintf(stderr, "Failed to get 'choices' array.\n"); - fprintf(stderr, "%s\n", response); + fprintf(stderr, "Failed to get 'choices' array.\n %s \n", response); json_object_put(parsed_json); return json_object_new_null(); } @@ -54,25 +82,25 @@ struct json_object* openai_process_chat_message(char* api_url, char* json_data) return message_object; } -char* openai_chat(char* user_role, char* message_content) { - char* api_url = "https://api.openai.com/v1/chat/completions"; +char* openai_chat(const char* user_role, const char* message_content) { + const char* api_url = "https://api.openai.com/v1/chat/completions"; char* json_data = chat_json(user_role, message_content); - json_object* message_object = openai_process_chat_message(api_url, json_data); + struct json_object* message_object = openai_process_chat_message(api_url, json_data); struct json_object* tool_calls; json_object_object_get_ex(message_object, "tool_calls", &tool_calls); if (tool_calls) { message_add_tool_call(message_object); - json_object* tool_call_results = tools_execute(tool_calls); + struct json_object* tool_call_results = tools_execute(tool_calls); int results_count = json_object_array_length(tool_call_results); for (int i = 0; i < results_count; i++) { - json_object* tool_call_result = json_object_array_get_idx(tool_call_results, i); + struct json_object* tool_call_result = json_object_array_get_idx(tool_call_results, i); message_add_tool_call(tool_call_result); } char* tool_calls_result_str = chat_json(NULL, NULL); message_object = openai_process_chat_message(api_url, tool_calls_result_str); message_add_tool_call(message_object); } - char* content_str = (char*)json_object_get_string(json_object_object_get(message_object, "content")); + const char* content_str = json_object_get_string(json_object_object_get(message_object, "content")); return strdup(content_str); } diff --git a/plugin.h b/plugin.h index 403377b..5bd1095 100644 --- a/plugin.h +++ b/plugin.h @@ -20,13 +20,12 @@ bool plugin_construct() { if (plugin_initialized) return true; Py_Initialize(); - if (!Py_IsInitialized()) { fprintf(stderr, "Failed to initialize the Python interpreter\n"); - return plugin_initialized; + return false; } plugin_initialized = true; - return plugin_initialized; + return true; } void plugin_run(char *src) { @@ -45,7 +44,7 @@ void plugin_run(char *src) { "from datetime import datetime\n" "%s"; size_t length = strlen(basics) + strlen(src); - char *script = (char *)malloc(length + 1); + char *script = malloc(length + 1); sprintf(script, basics, src); script[length] = '\0'; PyRun_SimpleString(script); diff --git a/tools.h b/tools.h index e53fe29..ae9b895 100644 --- a/tools.h +++ b/tools.h @@ -25,7 +25,6 @@ struct json_object *tool_description_read_file(); struct json_object *tool_description_write_file(); struct json_object *tool_description_directory_rglob(); - struct json_object *tools_descriptions() { struct json_object *root = json_object_new_array(); json_object_array_add(root, tool_description_http_get()); @@ -43,22 +42,19 @@ char *tool_function_http_get(char *url) { return curl_get(url); } -char * tool_function_linux_terminal(char * command){ - +char *tool_function_linux_terminal(char *command) { fprintf(stderr, "Tool linux_terminal: %s\n", command); - FILE *fp; + FILE *fp; char buffer[1024]; size_t total_size = 0; char *output = NULL; - // Open the command for reading fp = popen(command, "r"); if (fp == NULL) { perror("popen failed"); return strdup("Popen failed!"); } - // Read output in chunks while (fgets(buffer, sizeof(buffer), fp) != NULL) { size_t chunk_size = strlen(buffer); char *new_output = realloc(output, total_size + chunk_size + 1); @@ -111,8 +107,6 @@ struct json_object *tool_description_directory_rglob() { return root; } - - struct json_object *tool_description_read_file() { struct json_object *root = json_object_new_object(); json_object_object_add(root, "type", json_object_new_string("function")); @@ -146,7 +140,6 @@ struct json_object *tool_description_read_file() { return root; } -// Write File Description struct json_object *tool_description_write_file() { struct json_object *root = json_object_new_object(); json_object_object_add(root, "type", json_object_new_string("function")); @@ -206,14 +199,13 @@ char *tool_function_read_file(char *path) { } ssize_t read_size = fread(content, 1, size, fp); - (void)read_size; - content[size] = '\0'; + + content[read_size] = '\0'; fclose(fp); return content; } -// Write content to a file char *tool_function_write_file(char *path, char *content) { fprintf(stderr, "Tools write_file with %zu bytes: %s\n", strlen(content), path); FILE *fp = fopen(path, "w"); @@ -225,137 +217,105 @@ char *tool_function_write_file(char *path, char *content) { fwrite(content, 1, strlen(content), fp); fclose(fp); - return strdup("File written successfully."); + return strdup("File successfully written."); } - const char *get_file_type(struct stat *st) { if (S_ISREG(st->st_mode)) return "file"; if (S_ISDIR(st->st_mode)) return "directory"; return "other"; } -// Function to convert timestamp to human-readable format void format_time(time_t raw_time, char *buffer, size_t size) { struct tm *time_info = localtime(&raw_time); strftime(buffer, size, "%Y-%m-%d %H:%M:%S", time_info); } - - - void recursive_glob(const char *pattern, glob_t *results) { - // First, find all matching files in the current scope glob_t current_matches; int ret = glob(pattern, GLOB_NOSORT | GLOB_TILDE, NULL, ¤t_matches); - - // Handle errors + if (ret != 0 && ret != GLOB_NOMATCH) { - // Copy error state to results results->gl_pathc = 0; results->gl_pathv = NULL; results->gl_offs = 0; return; } - - // Initialize results if this is the first call + if (results->gl_pathv == NULL) { memset(results, 0, sizeof(glob_t)); } - - // Add found paths to results + for (size_t i = 0; i < current_matches.gl_pathc; i++) { char *path = current_matches.gl_pathv[i]; - - // Add the path to results + if (results->gl_pathc == 0) { - // First result results->gl_pathc = 1; results->gl_pathv = malloc(sizeof(char *)); results->gl_pathv[0] = strdup(path); } else { - // Additional result results->gl_pathc++; results->gl_pathv = realloc(results->gl_pathv, results->gl_pathc * sizeof(char *)); results->gl_pathv[results->gl_pathc - 1] = strdup(path); } } - - // Now look for directories to recurse into + DIR *dir; struct dirent *entry; struct stat statbuf; - - // Extract directory part from pattern + char *pattern_copy = strdup(pattern); char *last_slash = strrchr(pattern_copy, '/'); char *dir_path; char *file_pattern; - + if (last_slash) { *last_slash = '\0'; dir_path = pattern_copy; file_pattern = last_slash + 1; } else { - // No directory part in the pattern dir_path = "."; file_pattern = pattern_copy; } - + if ((dir = opendir(dir_path)) != NULL) { while ((entry = readdir(dir)) != NULL) { - // Skip . and .. if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { continue; } - - // Construct full path - ensure sufficient buffer space + char full_path[PATH_MAX]; int path_len; - + if (strcmp(dir_path, ".") == 0) { path_len = snprintf(full_path, PATH_MAX, "%s", entry->d_name); } else { path_len = snprintf(full_path, PATH_MAX, "%s/%s", dir_path, entry->d_name); } - - // Check if snprintf truncated the output + if (path_len >= PATH_MAX) { - // Path too long, skip this entry continue; } - - // Check if it's a directory + if (stat(full_path, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) { - // Create new pattern for recursion - ensure sufficient buffer space char new_pattern[PATH_MAX]; int new_pattern_len = snprintf(new_pattern, PATH_MAX, "%s/%s", full_path, file_pattern); - - // Check if snprintf truncated the output + if (new_pattern_len >= PATH_MAX) { - // Pattern too long, skip this recursion continue; } - - // Recurse + recursive_glob(new_pattern, results); } } closedir(dir); } - - // Free temporary resources + free(pattern_copy); globfree(¤t_matches); } - - - - - - char *tool_function_directory_rglob(char *target_dir) { fprintf(stderr, "Tools directory_rglob: %s\n", target_dir); glob_t results; @@ -363,27 +323,21 @@ char *tool_function_directory_rglob(char *target_dir) { struct stat file_stat; char mod_time[20], create_time[20]; - // Perform glob search recursively recursive_glob(target_dir, &results); - // Create a JSON array to store results json_object *json_array = json_object_new_array(); - // Iterate through the matched files for (size_t i = 0; i < results.gl_pathc; i++) { const char *file_path = results.gl_pathv[i]; - // Get file stats if (stat(file_path, &file_stat) == -1) { perror("stat failed"); continue; } - // Format timestamps format_time(file_stat.st_mtime, mod_time, sizeof(mod_time)); - format_time(file_stat.st_ctime, create_time, sizeof(create_time)); // Creation time is unreliable on Linux + format_time(file_stat.st_ctime, create_time, sizeof(create_time)); - // Create JSON object for each file json_object *json_entry = json_object_new_object(); json_object_object_add(json_entry, "name", json_object_new_string(file_path)); json_object_object_add(json_entry, "modification_date", json_object_new_string(mod_time)); @@ -391,55 +345,45 @@ char *tool_function_directory_rglob(char *target_dir) { json_object_object_add(json_entry, "type", json_object_new_string(get_file_type(&file_stat))); json_object_object_add(json_entry, "size_bytes", json_object_new_int64(file_stat.st_size)); - // Add to JSON array json_object_array_add(json_array, json_entry); } - // Free glob results globfree(&results); char *result = strdup(json_object_to_json_string_ext(json_array, JSON_C_TO_STRING_PRETTY)); - // Cleanup json_object_put(json_array); return result; } - -char * tool_function_directory_glob(char *target_dir) { +char *tool_function_directory_glob(char *target_dir) { fprintf(stderr, "Tools directory_glob: %s\n", target_dir); -glob_t results; + glob_t results; struct stat file_stat; char mod_time[20], create_time[20]; - - if(!strcmp(target_dir, ".")) { + + if (!strcmp(target_dir, ".")) { target_dir[0] = '*'; } - // Perform glob search if (glob(target_dir, GLOB_TILDE, NULL, &results) != 0) { perror("glob failed"); return NULL; } - // Create a JSON array to store results json_object *json_array = json_object_new_array(); - // Iterate through the matched files for (size_t i = 0; i < results.gl_pathc; i++) { const char *file_path = results.gl_pathv[i]; - // Get file stats if (stat(file_path, &file_stat) == -1) { perror("stat failed"); continue; } - // Format timestamps format_time(file_stat.st_mtime, mod_time, sizeof(mod_time)); - format_time(file_stat.st_ctime, create_time, sizeof(create_time)); // Creation time is unreliable on Linux + format_time(file_stat.st_ctime, create_time, sizeof(create_time)); - // Create JSON object for each file json_object *json_entry = json_object_new_object(); json_object_object_add(json_entry, "name", json_object_new_string(file_path)); json_object_object_add(json_entry, "modification_date", json_object_new_string(mod_time)); @@ -447,15 +391,12 @@ glob_t results; json_object_object_add(json_entry, "type", json_object_new_string(get_file_type(&file_stat))); json_object_object_add(json_entry, "size_bytes", json_object_new_int64(file_stat.st_size)); - // Add to JSON array json_object_array_add(json_array, json_entry); } - // Free glob results globfree(&results); - char * result = strdup(json_object_to_json_string_ext(json_array, JSON_C_TO_STRING_PRETTY)); + char *result = strdup(json_object_to_json_string_ext(json_array, JSON_C_TO_STRING_PRETTY)); - // Cleanup json_object_put(json_array); return result; @@ -561,7 +502,6 @@ struct json_object *tool_description_linux_terminal() { return root; } - struct json_object *tools_execute(struct json_object *tools_array) { struct json_object *tools_result_messages = json_object_new_array(); int array_len = json_object_array_length(tools_array); @@ -591,7 +531,7 @@ struct json_object *tools_execute(struct json_object *tools_array) { } if (!strcmp(function_name, "linux_terminal_execute")) { - struct json_object *arguments_obj; + struct json_object *arguments_obj; if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { struct json_object *arguments = json_tokener_parse(json_object_get_string(arguments_obj)); struct json_object *url_obj; @@ -603,7 +543,7 @@ struct json_object *tools_execute(struct json_object *tools_array) { } } if (!strcmp(function_name, "directory_glob")) { - struct json_object *arguments_obj; + struct json_object *arguments_obj; if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { struct json_object *arguments = json_tokener_parse(json_object_get_string(arguments_obj)); struct json_object *path_obj; @@ -661,18 +601,18 @@ struct json_object *tools_execute(struct json_object *tools_array) { } } if (!strcmp(function_name, "directory_rglob")) { - struct json_object *arguments_obj; - if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { - struct json_object *arguments = json_tokener_parse(json_object_get_string(arguments_obj)); - struct json_object *path_obj; - if (json_object_object_get_ex(arguments, "path", &path_obj)) { - char *path = (char *)json_object_get_string(path_obj); - char *listing_result = tool_function_directory_rglob(path); - json_object_object_add(tool_result, "content", json_object_new_string(listing_result)); - free(listing_result); - } - } -} + struct json_object *arguments_obj; + if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) { + struct json_object *arguments = json_tokener_parse(json_object_get_string(arguments_obj)); + struct json_object *path_obj; + if (json_object_object_get_ex(arguments, "path", &path_obj)) { + char *path = (char *)json_object_get_string(path_obj); + char *listing_result = tool_function_directory_rglob(path); + json_object_object_add(tool_result, "content", json_object_new_string(listing_result)); + free(listing_result); + } + } + } json_object_array_add(tools_result_messages, tool_result); } diff --git a/url.h b/url.h index 1767595..d38d1ba 100644 --- a/url.h +++ b/url.h @@ -1,6 +1,6 @@ // Written by retoor@molodetz.nl -// This code defines a URL parser in C that extracts components such as scheme, hostname, port, path, and query from a given URL +// This code defines a URL parser in C that extracts components such as the scheme, hostname, port, path, and query from a given URL. // Includes: // - <stdio.h> for standard I/O operations