Project update.
This commit is contained in:
parent
ab254abb4b
commit
48a543b56e
6
auth.h
6
auth.h
@ -1,8 +1,8 @@
|
||||
// Written by retoor@molodetz.nl
|
||||
|
||||
// This source code declares a constant character pointer variable that retrieves an API key from environment variables or falls back to a hardcoded key if not found.
|
||||
// This source code retrieves an API key from environment variables or defaults to a hardcoded key if none are found.
|
||||
|
||||
// Uses standard library functions from stdlib.h and stdio.h to manage environment variables and output error messages.
|
||||
// Uses the C standard library functions from stdlib.h for environment management and stdio.h for error handling.
|
||||
|
||||
// MIT License
|
||||
|
||||
@ -26,7 +26,7 @@ const char *resolve_api_key() {
|
||||
}
|
||||
fprintf(stderr, "\nThere is no API key configured in the environment.\n");
|
||||
exit(1);
|
||||
#endif
|
||||
#endif
|
||||
api_key = "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";
|
||||
return api_key;
|
||||
}
|
||||
|
14
chat.h
14
chat.h
@ -35,14 +35,14 @@
|
||||
#include "messages.h"
|
||||
|
||||
#ifdef FREE_VERSION
|
||||
char *prompt_model = "gpt-3.5-turbo";
|
||||
static char *prompt_model = "gpt-3.5-turbo";
|
||||
#else
|
||||
char *prompt_model = "gpt-4o-mini";
|
||||
static char *prompt_model = "gpt-4o-mini";
|
||||
#endif
|
||||
int prompt_max_tokens = 2048;
|
||||
double prompt_temperature = 0.1;
|
||||
static int prompt_max_tokens = 2048;
|
||||
static double prompt_temperature = 0.1;
|
||||
|
||||
json_object *_prompt = NULL;
|
||||
static json_object *_prompt = NULL;
|
||||
|
||||
void chat_free() {
|
||||
if (_prompt == NULL) return;
|
||||
@ -52,7 +52,7 @@ void chat_free() {
|
||||
|
||||
char *chat_json(const char *role, const char *message) {
|
||||
chat_free();
|
||||
struct json_object *root_object = json_object_new_object();
|
||||
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) {
|
||||
@ -67,4 +67,4 @@ char *chat_json(const char *role, const char *message) {
|
||||
return (char *)json_object_to_json_string_ext(root_object, JSON_C_TO_STRING_PRETTY);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
21
http_curl.h
21
http_curl.h
@ -1,6 +1,6 @@
|
||||
// Written by retoor@molodetz.nl
|
||||
|
||||
// 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.
|
||||
// This code defines a simple HTTP client using libcurl in C. It provides functions for executing POST and GET HTTP requests with JSON data, including authorization via a bearer token. The functions `curl_post` and `curl_get` handle these operations and return the server's response as a string.
|
||||
|
||||
// Uses libcurl for HTTP requests and includes a custom "auth.h" for API key resolution.
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
// from, out of or in connection with the software or the use or other dealings in
|
||||
// the Software.
|
||||
|
||||
|
||||
#ifndef HTTP_CURL
|
||||
#define HTTP_CURL
|
||||
|
||||
@ -52,18 +53,18 @@ static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *use
|
||||
char *curl_post(const char *url, const char *data) {
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct ResponseBuffer response;
|
||||
response.data = malloc(1);
|
||||
response.size = 0;
|
||||
struct ResponseBuffer response = {malloc(1), 0};
|
||||
|
||||
if (!response.data) return NULL;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if (curl) {
|
||||
struct curl_slist *headers = NULL;
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
headers = curl_slist_append(headers, "Content-Type: application/json");
|
||||
char *bearer_header = malloc(1337);
|
||||
char bearer_header[1337];
|
||||
sprintf(bearer_header, "Authorization: Bearer %s", resolve_api_key());
|
||||
headers = curl_slist_append(headers, bearer_header);
|
||||
free(bearer_header);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
|
||||
@ -91,25 +92,19 @@ char *curl_get(const char *url) {
|
||||
struct curl_slist *headers = NULL;
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
headers = curl_slist_append(headers, "Content-Type: application/json");
|
||||
|
||||
char *bearer_header = malloc(1337);
|
||||
char bearer_header[1337];
|
||||
sprintf(bearer_header, "Authorization: Bearer %s", resolve_api_key());
|
||||
headers = curl_slist_append(headers, bearer_header);
|
||||
free(bearer_header);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
if (res != CURLE_OK) {
|
||||
fprintf(stderr, "An error occurred: %s\n", curl_easy_strerror(res));
|
||||
}
|
||||
|
||||
curl_slist_free_all(headers);
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return response.data;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
// This source code extracts URLs from an input string and replaces them inline with their respective content in Markdown style.
|
||||
|
||||
// Imports used: regex.h for regular expression operations, http.h and url.h for HTTP and URL-related utility functions.
|
||||
// Imports used: regex.h for regular expression operations, http.h and url.h for HTTP and URL-related utility functions.
|
||||
|
||||
// MIT License
|
||||
|
||||
|
8
line.h
8
line.h
@ -1,6 +1,6 @@
|
||||
// Written by retoor@molodetz.nl
|
||||
|
||||
// This source code provides command-line input functionalities with autocomplete and history features using readline library functionalities. It allows users to complete commands and manage input history.
|
||||
// This source code provides command-line input functionalities with autocomplete and history features using the readline library. It allows users to complete commands and manage input history.
|
||||
|
||||
// External includes:
|
||||
// - <readline/readline.h>
|
||||
@ -52,9 +52,7 @@ void line_init() {
|
||||
char* line_read(char* prefix) {
|
||||
char* data = readline(prefix);
|
||||
if (!(data && *data)) {
|
||||
if (data) {
|
||||
free(data);
|
||||
}
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
return data;
|
||||
@ -63,4 +61,4 @@ char* line_read(char* prefix) {
|
||||
void line_add_history(char* data) {
|
||||
add_history(data);
|
||||
write_history(HISTORY_FILE);
|
||||
}
|
||||
}
|
11
messages.h
11
messages.h
@ -25,12 +25,11 @@ struct json_object *message_list() {
|
||||
return message_array;
|
||||
}
|
||||
|
||||
|
||||
void messages_remove_last(){
|
||||
void messages_remove_last() {
|
||||
struct json_object *messages = message_list();
|
||||
int size = json_object_array_length(messages);
|
||||
if(size){
|
||||
json_object_array_del_idx(messages, size - 1,1);
|
||||
if (size) {
|
||||
json_object_array_del_idx(messages, size - 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,7 +39,7 @@ struct json_object *message_add_tool_call(struct json_object *message) {
|
||||
return message;
|
||||
}
|
||||
|
||||
struct json_object *message_add_tool_result(char *tool_call_id, char *tool_result) {
|
||||
struct json_object *message_add_tool_result(const char *tool_call_id, const char *tool_result) {
|
||||
struct json_object *messages = message_list();
|
||||
struct json_object *message = json_object_new_object();
|
||||
|
||||
@ -76,4 +75,4 @@ void message_free() {
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
23
openai.h
23
openai.h
@ -1,10 +1,9 @@
|
||||
// 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.
|
||||
// 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
|
||||
@ -50,16 +49,16 @@ struct json_object* openai_process_chat_message(const char* api_url, const char*
|
||||
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 %s \n", response);
|
||||
fprintf(stderr, "Failed to parse JSON.\n%s\n", response);
|
||||
return 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 %s \n", response);
|
||||
fprintf(stderr, "Failed to get 'error' object.\n%s\n", response);
|
||||
json_object_put(parsed_json);
|
||||
char * all_messages = (char *)json_object_to_json_string(message_array);
|
||||
char *all_messages = (char *)json_object_to_json_string(message_array);
|
||||
fprintf(stderr, "Messages: ");
|
||||
fwrite(all_messages,strlen(all_messages),1, stderr);
|
||||
fwrite(all_messages, strlen(all_messages), 1, stderr);
|
||||
fprintf(stderr, "\n");
|
||||
free(all_messages);
|
||||
messages_remove_last();
|
||||
@ -69,7 +68,7 @@ struct json_object* openai_process_chat_message(const char* api_url, const char*
|
||||
|
||||
struct json_object* choices_array;
|
||||
if (!json_object_object_get_ex(parsed_json, "choices", &choices_array)) {
|
||||
fprintf(stderr, "Failed to get 'choices' array.\n %s \n", response);
|
||||
fprintf(stderr, "Failed to get 'choices' array.\n%s\n", response);
|
||||
json_object_put(parsed_json);
|
||||
return NULL;
|
||||
}
|
||||
@ -92,9 +91,9 @@ 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);
|
||||
struct json_object* message_object = openai_process_chat_message(api_url, json_data);
|
||||
if(message_object == NULL) {
|
||||
if (message_object == NULL) {
|
||||
printf("ERROR + NULL IS SUCCESS\n");
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
struct json_object* tool_calls;
|
||||
json_object_object_get_ex(message_object, "tool_calls", &tool_calls);
|
||||
@ -108,8 +107,8 @@ char* openai_chat(const char* user_role, const char* message_content) {
|
||||
}
|
||||
char* tool_calls_result_str = chat_json(NULL, NULL);
|
||||
message_object = openai_process_chat_message(api_url, tool_calls_result_str);
|
||||
if(message_object == NULL) {
|
||||
return NULL;
|
||||
if (message_object == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
message_add_tool_call(message_object);
|
||||
}
|
||||
@ -117,4 +116,4 @@ char* openai_chat(const char* user_role, const char* message_content) {
|
||||
return strdup(content_str);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
357
tools.h
357
tools.h
@ -18,16 +18,16 @@
|
||||
#include <time.h>
|
||||
#include <glob.h>
|
||||
|
||||
struct json_object *tool_description_http_get();
|
||||
struct json_object *tool_description_linux_terminal();
|
||||
struct json_object *tool_description_directory_glob();
|
||||
struct json_object *tool_description_read_file();
|
||||
struct json_object *tool_description_write_file();
|
||||
struct json_object *tool_description_directory_rglob();
|
||||
struct json_object *tool_description_linux_terminal_interactive();
|
||||
struct json_object* tool_description_http_get();
|
||||
struct json_object* tool_description_linux_terminal();
|
||||
struct json_object* tool_description_directory_glob();
|
||||
struct json_object* tool_description_read_file();
|
||||
struct json_object* tool_description_write_file();
|
||||
struct json_object* tool_description_directory_rglob();
|
||||
struct json_object* tool_description_linux_terminal_interactive();
|
||||
|
||||
struct json_object *tools_descriptions() {
|
||||
struct json_object *root = json_object_new_array();
|
||||
struct json_object* tools_descriptions() {
|
||||
struct json_object* root = json_object_new_array();
|
||||
json_object_array_add(root, tool_description_http_get());
|
||||
json_object_array_add(root, tool_description_linux_terminal());
|
||||
json_object_array_add(root, tool_description_directory_glob());
|
||||
@ -38,17 +38,17 @@ struct json_object *tools_descriptions() {
|
||||
return root;
|
||||
}
|
||||
|
||||
char *tool_function_http_get(char *url) {
|
||||
char* tool_function_http_get(char* url) {
|
||||
fprintf(stderr, "Tool http_get: %s\n", 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;
|
||||
char* output = NULL;
|
||||
|
||||
fp = popen(command, "r");
|
||||
if (fp == NULL) {
|
||||
@ -58,7 +58,7 @@ char *tool_function_linux_terminal(char *command) {
|
||||
|
||||
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
|
||||
size_t chunk_size = strlen(buffer);
|
||||
char *new_output = (char *)realloc(output, total_size + chunk_size + 1);
|
||||
char* new_output = realloc(output, total_size + chunk_size + 1);
|
||||
if (new_output == NULL) {
|
||||
perror("realloc failed");
|
||||
free(output);
|
||||
@ -74,41 +74,41 @@ char *tool_function_linux_terminal(char *command) {
|
||||
return output ? output : strdup("");
|
||||
}
|
||||
|
||||
char *tool_function_linux_terminal_interactive(char *command) {
|
||||
char* tool_function_linux_terminal_interactive(char* command) {
|
||||
fprintf(stderr, "Tool linux_terminal_interactive: %s\n", command);
|
||||
|
||||
int result_code = system(command);
|
||||
|
||||
char * result = (char *)malloc(100);
|
||||
char* result = malloc(100);
|
||||
result[0] = 0;
|
||||
sprintf(result, "Command exited with status code %d.", result_code);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct json_object *tool_description_linux_terminal_interactive() {
|
||||
struct json_object *root = json_object_new_object();
|
||||
struct json_object* tool_description_linux_terminal_interactive() {
|
||||
struct json_object* root = json_object_new_object();
|
||||
json_object_object_add(root, "type", json_object_new_string("function"));
|
||||
|
||||
struct json_object *function = json_object_new_object();
|
||||
struct json_object* function = json_object_new_object();
|
||||
json_object_object_add(function, "name", json_object_new_string("linux_terminal_execute_interactive"));
|
||||
json_object_object_add(function, "description", json_object_new_string("Executes interactive terminal for user. You will not be able to read the result. Do not use if you need to know output."));
|
||||
|
||||
struct json_object *parameters = json_object_new_object();
|
||||
struct json_object* parameters = json_object_new_object();
|
||||
json_object_object_add(parameters, "type", json_object_new_string("object"));
|
||||
|
||||
struct json_object *properties = json_object_new_object();
|
||||
struct json_object *path = json_object_new_object();
|
||||
struct json_object* properties = json_object_new_object();
|
||||
struct json_object* path = json_object_new_object();
|
||||
json_object_object_add(path, "type", json_object_new_string("string"));
|
||||
json_object_object_add(path, "description", json_object_new_string("Executable with parameters to execute interactive."));;
|
||||
json_object_object_add(path, "description", json_object_new_string("Executable with parameters to execute interactively."));
|
||||
json_object_object_add(properties, "command", path);
|
||||
|
||||
json_object_object_add(parameters, "properties", properties);
|
||||
|
||||
struct json_object *required = json_object_new_array();
|
||||
struct json_object* required = json_object_new_array();
|
||||
json_object_array_add(required, json_object_new_string("command"));
|
||||
json_object_object_add(parameters, "required", required);
|
||||
|
||||
|
||||
json_object_object_add(parameters, "additionalProperties", json_object_new_boolean(0));
|
||||
|
||||
json_object_object_add(function, "parameters", parameters);
|
||||
@ -119,30 +119,27 @@ struct json_object *tool_description_linux_terminal_interactive() {
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
struct json_object *tool_description_directory_rglob() {
|
||||
struct json_object *root = json_object_new_object();
|
||||
struct json_object* tool_description_directory_rglob() {
|
||||
struct json_object* root = json_object_new_object();
|
||||
json_object_object_add(root, "type", json_object_new_string("function"));
|
||||
|
||||
struct json_object *function = json_object_new_object();
|
||||
struct json_object* function = json_object_new_object();
|
||||
json_object_object_add(function, "name", json_object_new_string("directory_rglob"));
|
||||
json_object_object_add(function, "description", json_object_new_string("Recursively list the contents of a specified directory in glob format. "
|
||||
"Result is a json array containing objects with keys: name, modification_date(iso), creation_date(iso), type and size_bytes."));
|
||||
"Result is a JSON array containing objects with keys: name, modification_date(iso), creation_date(iso), type, and size_bytes."));
|
||||
|
||||
struct json_object *parameters = json_object_new_object();
|
||||
struct json_object* parameters = json_object_new_object();
|
||||
json_object_object_add(parameters, "type", json_object_new_string("object"));
|
||||
|
||||
struct json_object *properties = json_object_new_object();
|
||||
struct json_object *directory = json_object_new_object();
|
||||
struct json_object* properties = json_object_new_object();
|
||||
struct json_object* directory = json_object_new_object();
|
||||
json_object_object_add(directory, "type", json_object_new_string("string"));
|
||||
json_object_object_add(directory, "description", json_object_new_string("Path to the directory to list in glob format."));
|
||||
json_object_object_add(properties, "path", directory);
|
||||
|
||||
json_object_object_add(parameters, "properties", properties);
|
||||
|
||||
struct json_object *required = json_object_new_array();
|
||||
struct json_object* required = json_object_new_array();
|
||||
json_object_array_add(required, json_object_new_string("path"));
|
||||
json_object_object_add(parameters, "required", required);
|
||||
|
||||
@ -156,29 +153,29 @@ struct json_object *tool_description_directory_rglob() {
|
||||
return root;
|
||||
}
|
||||
|
||||
struct json_object *tool_description_read_file() {
|
||||
struct json_object *root = json_object_new_object();
|
||||
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"));
|
||||
|
||||
struct json_object *function = json_object_new_object();
|
||||
struct json_object* function = json_object_new_object();
|
||||
json_object_object_add(function, "name", json_object_new_string("read_file"));
|
||||
json_object_object_add(function, "description", json_object_new_string("Reads / opens / loads a file and returns its contents as a string."));
|
||||
|
||||
struct json_object *parameters = json_object_new_object();
|
||||
struct json_object* parameters = json_object_new_object();
|
||||
json_object_object_add(parameters, "type", json_object_new_string("object"));
|
||||
|
||||
struct json_object *properties = json_object_new_object();
|
||||
struct json_object *path = json_object_new_object();
|
||||
struct json_object* properties = json_object_new_object();
|
||||
struct json_object* path = json_object_new_object();
|
||||
json_object_object_add(path, "type", json_object_new_string("string"));
|
||||
json_object_object_add(path, "description", json_object_new_string("Path to the file to read / open / load."));
|
||||
json_object_object_add(properties, "path", path);
|
||||
|
||||
json_object_object_add(parameters, "properties", properties);
|
||||
|
||||
struct json_object *required = json_object_new_array();
|
||||
struct json_object* required = json_object_new_array();
|
||||
json_object_array_add(required, json_object_new_string("path"));
|
||||
json_object_object_add(parameters, "required", required);
|
||||
|
||||
|
||||
json_object_object_add(parameters, "additionalProperties", json_object_new_boolean(0));
|
||||
|
||||
json_object_object_add(function, "parameters", parameters);
|
||||
@ -189,36 +186,36 @@ struct json_object *tool_description_read_file() {
|
||||
return root;
|
||||
}
|
||||
|
||||
struct json_object *tool_description_write_file() {
|
||||
struct json_object *root = json_object_new_object();
|
||||
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"));
|
||||
|
||||
struct json_object *function = json_object_new_object();
|
||||
struct json_object* function = json_object_new_object();
|
||||
json_object_object_add(function, "name", json_object_new_string("write_file"));
|
||||
json_object_object_add(function, "description", json_object_new_string("Writes / saves / stores content to a file."));
|
||||
|
||||
struct json_object *parameters = json_object_new_object();
|
||||
struct json_object* parameters = json_object_new_object();
|
||||
json_object_object_add(parameters, "type", json_object_new_string("object"));
|
||||
|
||||
struct json_object *properties = json_object_new_object();
|
||||
|
||||
struct json_object *path = json_object_new_object();
|
||||
struct json_object* properties = json_object_new_object();
|
||||
|
||||
struct json_object* path = json_object_new_object();
|
||||
json_object_object_add(path, "type", json_object_new_string("string"));
|
||||
json_object_object_add(path, "description", json_object_new_string("Path to the file to write / save / store."));
|
||||
json_object_object_add(properties, "path", path);
|
||||
|
||||
struct json_object *content = json_object_new_object();
|
||||
struct json_object* content = json_object_new_object();
|
||||
json_object_object_add(content, "type", json_object_new_string("string"));
|
||||
json_object_object_add(content, "description", json_object_new_string("Content to write / save / store into the file."));
|
||||
json_object_object_add(properties, "content", content);
|
||||
|
||||
json_object_object_add(parameters, "properties", properties);
|
||||
|
||||
struct json_object *required = json_object_new_array();
|
||||
struct json_object* required = json_object_new_array();
|
||||
json_object_array_add(required, json_object_new_string("path"));
|
||||
json_object_array_add(required, json_object_new_string("content"));
|
||||
json_object_object_add(parameters, "required", required);
|
||||
|
||||
|
||||
json_object_object_add(parameters, "additionalProperties", json_object_new_boolean(0));
|
||||
|
||||
json_object_object_add(function, "parameters", parameters);
|
||||
@ -229,9 +226,9 @@ struct json_object *tool_description_write_file() {
|
||||
return root;
|
||||
}
|
||||
|
||||
char *tool_function_read_file(char *path) {
|
||||
char* tool_function_read_file(char* path) {
|
||||
fprintf(stderr, "Tools read_file: %s\n", path);
|
||||
FILE *fp = fopen(path, "r");
|
||||
FILE* fp = fopen(path, "r");
|
||||
if (fp == NULL) {
|
||||
perror("fopen failed");
|
||||
return strdup("Failed to open file for reading!");
|
||||
@ -241,23 +238,23 @@ char *tool_function_read_file(char *path) {
|
||||
long size = ftell(fp);
|
||||
rewind(fp);
|
||||
|
||||
char *content = (char *)malloc(size + 1);
|
||||
char* content = malloc(size + 1);
|
||||
if (content == NULL) {
|
||||
fclose(fp);
|
||||
return strdup("Memory allocation failed!");
|
||||
}
|
||||
|
||||
ssize_t read_size = fread(content, 1, size, fp);
|
||||
|
||||
|
||||
content[read_size] = '\0';
|
||||
fclose(fp);
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
char *tool_function_write_file(char *path, char *content) {
|
||||
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");
|
||||
FILE* fp = fopen(path, "w");
|
||||
if (fp == NULL) {
|
||||
perror("fopen failed");
|
||||
return strdup("Failed to open file for writing!");
|
||||
@ -269,18 +266,18 @@ char *tool_function_write_file(char *path, char *content) {
|
||||
return strdup("File successfully written.");
|
||||
}
|
||||
|
||||
const char *get_file_type(struct stat *st) {
|
||||
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";
|
||||
}
|
||||
|
||||
void format_time(time_t raw_time, char *buffer, size_t size) {
|
||||
struct tm *time_info = localtime(&raw_time);
|
||||
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) {
|
||||
void recursive_glob(const char* pattern, glob_t* results) {
|
||||
glob_t current_matches;
|
||||
int ret = glob(pattern, GLOB_NOSORT | GLOB_TILDE, NULL, ¤t_matches);
|
||||
|
||||
@ -296,28 +293,28 @@ void recursive_glob(const char *pattern, glob_t *results) {
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < current_matches.gl_pathc; i++) {
|
||||
char *path = current_matches.gl_pathv[i];
|
||||
char* path = current_matches.gl_pathv[i];
|
||||
|
||||
if (results->gl_pathc == 0) {
|
||||
results->gl_pathc = 1;
|
||||
results->gl_pathv = malloc(sizeof(char *));
|
||||
results->gl_pathv = malloc(sizeof(char*));
|
||||
results->gl_pathv[0] = strdup(path);
|
||||
} else {
|
||||
results->gl_pathc++;
|
||||
results->gl_pathv = realloc(results->gl_pathv,
|
||||
results->gl_pathc * sizeof(char *));
|
||||
results->gl_pathv = realloc(results->gl_pathv,
|
||||
results->gl_pathc * sizeof(char*));
|
||||
results->gl_pathv[results->gl_pathc - 1] = strdup(path);
|
||||
}
|
||||
}
|
||||
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
DIR* dir;
|
||||
struct dirent* entry;
|
||||
struct stat statbuf;
|
||||
|
||||
char *pattern_copy = strdup(pattern);
|
||||
char *last_slash = strrchr(pattern_copy, '/');
|
||||
char *dir_path;
|
||||
char *file_pattern;
|
||||
char* pattern_copy = strdup(pattern);
|
||||
char* last_slash = strrchr(pattern_copy, '/');
|
||||
char* dir_path;
|
||||
char* file_pattern;
|
||||
|
||||
if (last_slash) {
|
||||
*last_slash = '\0';
|
||||
@ -365,7 +362,7 @@ void recursive_glob(const char *pattern, glob_t *results) {
|
||||
globfree(¤t_matches);
|
||||
}
|
||||
|
||||
char *tool_function_directory_rglob(char *target_dir) {
|
||||
char* tool_function_directory_rglob(char* target_dir) {
|
||||
fprintf(stderr, "Tools directory_rglob: %s\n", target_dir);
|
||||
glob_t results;
|
||||
results.gl_pathc = 0;
|
||||
@ -374,10 +371,10 @@ char *tool_function_directory_rglob(char *target_dir) {
|
||||
|
||||
recursive_glob(target_dir, &results);
|
||||
|
||||
json_object *json_array = json_object_new_array();
|
||||
json_object* json_array = json_object_new_array();
|
||||
|
||||
for (size_t i = 0; i < results.gl_pathc; i++) {
|
||||
const char *file_path = results.gl_pathv[i];
|
||||
const char* file_path = results.gl_pathv[i];
|
||||
|
||||
if (stat(file_path, &file_stat) == -1) {
|
||||
perror("stat failed");
|
||||
@ -387,7 +384,7 @@ char *tool_function_directory_rglob(char *target_dir) {
|
||||
format_time(file_stat.st_mtime, mod_time, sizeof(mod_time));
|
||||
format_time(file_stat.st_ctime, create_time, sizeof(create_time));
|
||||
|
||||
json_object *json_entry = json_object_new_object();
|
||||
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));
|
||||
json_object_object_add(json_entry, "creation_date", json_object_new_string(create_time));
|
||||
@ -398,14 +395,14 @@ char *tool_function_directory_rglob(char *target_dir) {
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
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;
|
||||
struct stat file_stat;
|
||||
@ -420,10 +417,10 @@ char *tool_function_directory_glob(char *target_dir) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
json_object *json_array = json_object_new_array();
|
||||
json_object* json_array = json_object_new_array();
|
||||
|
||||
for (size_t i = 0; i < results.gl_pathc; i++) {
|
||||
const char *file_path = results.gl_pathv[i];
|
||||
const char* file_path = results.gl_pathv[i];
|
||||
|
||||
if (stat(file_path, &file_stat) == -1) {
|
||||
perror("stat failed");
|
||||
@ -433,7 +430,7 @@ char *tool_function_directory_glob(char *target_dir) {
|
||||
format_time(file_stat.st_mtime, mod_time, sizeof(mod_time));
|
||||
format_time(file_stat.st_ctime, create_time, sizeof(create_time));
|
||||
|
||||
json_object *json_entry = json_object_new_object();
|
||||
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));
|
||||
json_object_object_add(json_entry, "creation_date", json_object_new_string(create_time));
|
||||
@ -444,67 +441,67 @@ char *tool_function_directory_glob(char *target_dir) {
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
json_object_put(json_array);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct json_object *tool_description_http_get() {
|
||||
struct json_object *root = json_object_new_object();
|
||||
struct json_object* tool_description_http_get() {
|
||||
struct json_object* root = json_object_new_object();
|
||||
json_object_object_add(root, "type", json_object_new_string("function"));
|
||||
|
||||
struct json_object *function = json_object_new_object();
|
||||
|
||||
struct json_object* function = json_object_new_object();
|
||||
json_object_object_add(function, "name", json_object_new_string("http_fetch"));
|
||||
json_object_object_add(function, "description", json_object_new_string("Get the contents of a URL."));
|
||||
|
||||
struct json_object *parameters = json_object_new_object();
|
||||
|
||||
struct json_object* parameters = json_object_new_object();
|
||||
json_object_object_add(parameters, "type", json_object_new_string("object"));
|
||||
|
||||
struct json_object *properties = json_object_new_object();
|
||||
struct json_object *url = json_object_new_object();
|
||||
|
||||
struct json_object* properties = json_object_new_object();
|
||||
struct json_object* url = json_object_new_object();
|
||||
json_object_object_add(url, "type", json_object_new_string("string"));
|
||||
json_object_object_add(url, "description", json_object_new_string("Fetch URL contents."));
|
||||
json_object_object_add(properties, "url", url);
|
||||
|
||||
|
||||
json_object_object_add(parameters, "properties", properties);
|
||||
|
||||
struct json_object *required = json_object_new_array();
|
||||
|
||||
struct json_object* required = json_object_new_array();
|
||||
json_object_array_add(required, json_object_new_string("url"));
|
||||
json_object_object_add(parameters, "required", required);
|
||||
|
||||
|
||||
json_object_object_add(parameters, "additionalProperties", json_object_new_boolean(0));
|
||||
|
||||
|
||||
json_object_object_add(function, "parameters", parameters);
|
||||
json_object_object_add(function, "strict", json_object_new_boolean(1));
|
||||
|
||||
|
||||
json_object_object_add(root, "function", function);
|
||||
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
struct json_object *tool_description_directory_glob() {
|
||||
struct json_object *root = json_object_new_object();
|
||||
struct json_object* tool_description_directory_glob() {
|
||||
struct json_object* root = json_object_new_object();
|
||||
json_object_object_add(root, "type", json_object_new_string("function"));
|
||||
|
||||
struct json_object *function = json_object_new_object();
|
||||
struct json_object* function = json_object_new_object();
|
||||
json_object_object_add(function, "name", json_object_new_string("directory_glob"));
|
||||
json_object_object_add(function, "description", json_object_new_string("List the contents of a specified directory in glob format. "
|
||||
"Result is a json array containing objects with keys: name, modification_date(iso), creation_date(iso), type and size_bytes."));
|
||||
json_object_object_add(function, "description", json_object_new_string("List the contents of a specified directory in glob format. "
|
||||
"Result is a JSON array containing objects with keys: name, modification_date(iso), creation_date(iso), type, and size_bytes."));
|
||||
|
||||
struct json_object *parameters = json_object_new_object();
|
||||
struct json_object* parameters = json_object_new_object();
|
||||
json_object_object_add(parameters, "type", json_object_new_string("object"));
|
||||
|
||||
struct json_object *properties = json_object_new_object();
|
||||
struct json_object *directory = json_object_new_object();
|
||||
struct json_object* properties = json_object_new_object();
|
||||
struct json_object* directory = json_object_new_object();
|
||||
json_object_object_add(directory, "type", json_object_new_string("string"));
|
||||
json_object_object_add(directory, "description", json_object_new_string("Path to the directory to list in glob format."));
|
||||
json_object_object_add(properties, "path", directory);
|
||||
|
||||
json_object_object_add(parameters, "properties", properties);
|
||||
|
||||
struct json_object *required = json_object_new_array();
|
||||
struct json_object* required = json_object_new_array();
|
||||
json_object_array_add(required, json_object_new_string("path"));
|
||||
json_object_object_add(parameters, "required", required);
|
||||
|
||||
@ -518,159 +515,159 @@ struct json_object *tool_description_directory_glob() {
|
||||
return root;
|
||||
}
|
||||
|
||||
struct json_object *tool_description_linux_terminal() {
|
||||
struct json_object *root = json_object_new_object();
|
||||
struct json_object* tool_description_linux_terminal() {
|
||||
struct json_object* root = json_object_new_object();
|
||||
json_object_object_add(root, "type", json_object_new_string("function"));
|
||||
|
||||
struct json_object *function = json_object_new_object();
|
||||
|
||||
struct json_object* function = json_object_new_object();
|
||||
json_object_object_add(function, "name", json_object_new_string("linux_terminal_execute"));
|
||||
json_object_object_add(function, "description", json_object_new_string("Execute a linux_terminal command on user terminal."));
|
||||
|
||||
struct json_object *parameters = json_object_new_object();
|
||||
|
||||
struct json_object* parameters = json_object_new_object();
|
||||
json_object_object_add(parameters, "type", json_object_new_string("object"));
|
||||
|
||||
struct json_object *properties = json_object_new_object();
|
||||
struct json_object *url = json_object_new_object();
|
||||
|
||||
struct json_object* properties = json_object_new_object();
|
||||
struct json_object* url = json_object_new_object();
|
||||
json_object_object_add(url, "type", json_object_new_string("string"));
|
||||
json_object_object_add(url, "description", json_object_new_string("Bash command to execute."));
|
||||
json_object_object_add(properties, "command", url);
|
||||
|
||||
|
||||
json_object_object_add(parameters, "properties", properties);
|
||||
|
||||
struct json_object *required = json_object_new_array();
|
||||
|
||||
struct json_object* required = json_object_new_array();
|
||||
json_object_array_add(required, json_object_new_string("command"));
|
||||
json_object_object_add(parameters, "required", required);
|
||||
|
||||
|
||||
json_object_object_add(parameters, "additionalProperties", json_object_new_boolean(0));
|
||||
|
||||
|
||||
json_object_object_add(function, "parameters", parameters);
|
||||
json_object_object_add(function, "strict", json_object_new_boolean(1));
|
||||
|
||||
|
||||
json_object_object_add(root, "function", function);
|
||||
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
struct json_object *tools_execute(struct json_object *tools_array) {
|
||||
struct json_object *tools_result_messages = json_object_new_array();
|
||||
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);
|
||||
|
||||
|
||||
for (int i = 0; i < array_len; i++) {
|
||||
struct json_object *obj = json_object_array_get_idx(tools_array, i);
|
||||
struct json_object *tool_result = json_object_new_object();
|
||||
|
||||
json_object_object_add(tool_result, "tool_call_id",
|
||||
struct json_object* obj = json_object_array_get_idx(tools_array, i);
|
||||
struct json_object* tool_result = json_object_new_object();
|
||||
|
||||
json_object_object_add(tool_result, "tool_call_id",
|
||||
json_object_new_string(json_object_get_string(
|
||||
json_object_object_get(obj, "id"))));
|
||||
json_object_object_add(tool_result, "role", json_object_new_string("tool"));
|
||||
|
||||
struct json_object *type_obj;
|
||||
|
||||
struct json_object* type_obj;
|
||||
if (json_object_object_get_ex(obj, "type", &type_obj)) {
|
||||
if (strcmp(json_object_get_string(type_obj), "function")) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
struct json_object *function_obj;
|
||||
|
||||
struct json_object* function_obj;
|
||||
if (json_object_object_get_ex(obj, "function", &function_obj)) {
|
||||
struct json_object *name_obj;
|
||||
char *function_name = NULL;
|
||||
struct json_object* name_obj;
|
||||
char* function_name = NULL;
|
||||
if (json_object_object_get_ex(function_obj, "name", &name_obj)) {
|
||||
function_name = (char *)json_object_get_string(name_obj);
|
||||
function_name = (char*)json_object_get_string(name_obj);
|
||||
}
|
||||
|
||||
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;
|
||||
struct json_object* arguments = json_tokener_parse(json_object_get_string(arguments_obj));
|
||||
struct json_object* url_obj;
|
||||
if (json_object_object_get_ex(arguments, "command", &url_obj)) {
|
||||
char *command = (char *)json_object_get_string(url_obj);
|
||||
char *terminal_result = tool_function_linux_terminal(command);
|
||||
char* command = (char*)json_object_get_string(url_obj);
|
||||
char* terminal_result = tool_function_linux_terminal(command);
|
||||
json_object_object_add(tool_result, "content", json_object_new_string(terminal_result));
|
||||
free(terminal_result);
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(function_name, "linux_terminal_execute_interactive")) {
|
||||
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;
|
||||
struct json_object* arguments = json_tokener_parse(json_object_get_string(arguments_obj));
|
||||
struct json_object* url_obj;
|
||||
if (json_object_object_get_ex(arguments, "command", &url_obj)) {
|
||||
char *command = (char *)json_object_get_string(url_obj);
|
||||
char *terminal_result = tool_function_linux_terminal_interactive(command);
|
||||
char* command = (char*)json_object_get_string(url_obj);
|
||||
char* terminal_result = tool_function_linux_terminal_interactive(command);
|
||||
json_object_object_add(tool_result, "content", json_object_new_string(terminal_result));
|
||||
free(terminal_result);
|
||||
}
|
||||
}
|
||||
}else if (!strcmp(function_name, "directory_glob")) {
|
||||
struct json_object *arguments_obj;
|
||||
} else if (!strcmp(function_name, "directory_glob")) {
|
||||
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;
|
||||
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_glob(path);
|
||||
char* path = (char*)json_object_get_string(path_obj);
|
||||
char* listing_result = tool_function_directory_glob(path);
|
||||
json_object_object_add(tool_result, "content", json_object_new_string(listing_result));
|
||||
free(listing_result);
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(function_name, "http_fetch")) {
|
||||
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;
|
||||
struct json_object* arguments = json_tokener_parse(json_object_get_string(arguments_obj));
|
||||
struct json_object* url_obj;
|
||||
if (json_object_object_get_ex(arguments, "url", &url_obj)) {
|
||||
char *url = (char *)json_object_get_string(url_obj);
|
||||
char *http_result = tool_function_http_get(url);
|
||||
char* url = (char*)json_object_get_string(url_obj);
|
||||
char* http_result = tool_function_http_get(url);
|
||||
json_object_object_add(tool_result, "content", json_object_new_string(http_result));
|
||||
free(http_result);
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(function_name, "read_file")) {
|
||||
struct json_object *arguments_obj;
|
||||
struct json_object* arguments_obj;
|
||||
if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) {
|
||||
struct json_object *path_obj;
|
||||
|
||||
struct json_object *arguments = json_tokener_parse(json_object_get_string(arguments_obj));
|
||||
struct json_object* path_obj;
|
||||
|
||||
struct json_object* arguments = json_tokener_parse(json_object_get_string(arguments_obj));
|
||||
|
||||
if (json_object_object_get_ex(arguments, "path", &path_obj)) {
|
||||
char *path = (char *)json_object_get_string(path_obj);
|
||||
char *file_content = tool_function_read_file(path);
|
||||
char* path = (char*)json_object_get_string(path_obj);
|
||||
char* file_content = tool_function_read_file(path);
|
||||
json_object_object_add(tool_result, "content", json_object_new_string(file_content));
|
||||
free(file_content);
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(function_name, "write_file")) {
|
||||
struct json_object *arguments_obj;
|
||||
struct json_object* arguments_obj;
|
||||
if (json_object_object_get_ex(function_obj, "arguments", &arguments_obj)) {
|
||||
struct json_object *path_obj, *content_obj;
|
||||
struct json_object* path_obj, * content_obj;
|
||||
|
||||
struct json_object *arguments = json_tokener_parse(json_object_get_string(arguments_obj));
|
||||
struct json_object* arguments = json_tokener_parse(json_object_get_string(arguments_obj));
|
||||
|
||||
if (json_object_object_get_ex(arguments, "path", &path_obj) &&
|
||||
json_object_object_get_ex(arguments, "content", &content_obj)) {
|
||||
char *path = (char *)json_object_get_string(path_obj);
|
||||
char *content = (char *)json_object_get_string(content_obj);
|
||||
char *write_result = tool_function_write_file(path, content);
|
||||
char* path = (char*)json_object_get_string(path_obj);
|
||||
char* content = (char*)json_object_get_string(content_obj);
|
||||
char* write_result = tool_function_write_file(path, content);
|
||||
json_object_object_add(tool_result, "content", json_object_new_string(write_result));
|
||||
free(write_result);
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(function_name, "directory_rglob")) {
|
||||
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;
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
fprintf(stderr, "Unkown function: %s\n", function_name);
|
||||
} else {
|
||||
fprintf(stderr, "Unknown function: %s\n", function_name);
|
||||
json_object_object_add(tool_result, "content", json_object_new_string("Error: function not found."));
|
||||
}
|
||||
|
||||
@ -680,4 +677,4 @@ struct json_object *tools_execute(struct json_object *tools_array) {
|
||||
return tools_result_messages;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
47
utils.h
Normal file
47
utils.h
Normal file
@ -0,0 +1,47 @@
|
||||
// Written by retoor@molodetz.nl
|
||||
|
||||
// This header file contains utility functions for manipulating file system paths, focusing primarily on expanding paths starting with '~' to the home directory.
|
||||
|
||||
// This code uses standard libraries: stdio.h, stdlib.h, and string.h, and conditionally includes the posix libraries pwd.h and unistd.h when expanding the home directory manually.
|
||||
|
||||
// MIT License
|
||||
//
|
||||
// Permission is granted to use, copy, modify, merge, distribute, sublicense, and/or sell copies of the Software.
|
||||
// The license includes conditions about providing a copy of the license and the limitation of liability and warranty.
|
||||
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
char* expand_home_directory(const char* path) {
|
||||
if (path == NULL) return NULL;
|
||||
|
||||
if (path[0] == '~' && path[1] == '/') {
|
||||
const char* home_dir = getenv("HOME");
|
||||
if (home_dir == NULL) {
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
struct passwd* pw = getpwuid(getuid());
|
||||
if (pw == NULL) return NULL;
|
||||
home_dir = pw->pw_dir;
|
||||
}
|
||||
|
||||
size_t home_len = strlen(home_dir);
|
||||
size_t path_len = strlen(path) - 1;
|
||||
char* expanded_path = malloc(home_len + path_len + 1);
|
||||
|
||||
if (expanded_path == NULL) return NULL;
|
||||
|
||||
strcpy(expanded_path, home_dir);
|
||||
strcat(expanded_path, path + 1);
|
||||
|
||||
return expanded_path;
|
||||
} else {
|
||||
return strdup(path);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user