564 lines
21 KiB
C
564 lines
21 KiB
C
|
|
// retoor <retoor@molodetz.nl>
|
||
|
|
|
||
|
|
#include "tool.h"
|
||
|
|
#include "r_config.h"
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <stdlib.h>
|
||
|
|
#include <string.h>
|
||
|
|
#include <sys/stat.h>
|
||
|
|
#include <unistd.h>
|
||
|
|
#include <dirent.h>
|
||
|
|
#include <glob.h>
|
||
|
|
#include <errno.h>
|
||
|
|
#include <time.h>
|
||
|
|
#include <limits.h>
|
||
|
|
|
||
|
|
static char *expand_home_directory(const char *path);
|
||
|
|
static const char *get_file_type(struct stat *st);
|
||
|
|
static void format_time(time_t raw_time, char *buffer, size_t size);
|
||
|
|
|
||
|
|
static struct json_object *read_file_get_description(void);
|
||
|
|
static char *read_file_execute(tool_t *self, struct json_object *args);
|
||
|
|
static void read_file_print_action(const char *name, struct json_object *args);
|
||
|
|
|
||
|
|
static struct json_object *write_file_get_description(void);
|
||
|
|
static char *write_file_execute(tool_t *self, struct json_object *args);
|
||
|
|
static void write_file_print_action(const char *name, struct json_object *args);
|
||
|
|
|
||
|
|
static struct json_object *directory_glob_get_description(void);
|
||
|
|
static char *directory_glob_execute(tool_t *self, struct json_object *args);
|
||
|
|
static void directory_glob_print_action(const char *name, struct json_object *args);
|
||
|
|
|
||
|
|
static struct json_object *mkdir_get_description(void);
|
||
|
|
static char *mkdir_execute(tool_t *self, struct json_object *args);
|
||
|
|
static void mkdir_print_action(const char *name, struct json_object *args);
|
||
|
|
|
||
|
|
static struct json_object *chdir_get_description(void);
|
||
|
|
static char *chdir_execute(tool_t *self, struct json_object *args);
|
||
|
|
static void chdir_print_action(const char *name, struct json_object *args);
|
||
|
|
|
||
|
|
static struct json_object *getpwd_get_description(void);
|
||
|
|
static char *getpwd_execute(tool_t *self, struct json_object *args);
|
||
|
|
static void getpwd_print_action(const char *name, struct json_object *args);
|
||
|
|
|
||
|
|
static const tool_vtable_t read_file_vtable = {
|
||
|
|
.get_description = read_file_get_description,
|
||
|
|
.execute = read_file_execute,
|
||
|
|
.print_action = read_file_print_action
|
||
|
|
};
|
||
|
|
|
||
|
|
static const tool_vtable_t write_file_vtable = {
|
||
|
|
.get_description = write_file_get_description,
|
||
|
|
.execute = write_file_execute,
|
||
|
|
.print_action = write_file_print_action
|
||
|
|
};
|
||
|
|
|
||
|
|
static const tool_vtable_t directory_glob_vtable = {
|
||
|
|
.get_description = directory_glob_get_description,
|
||
|
|
.execute = directory_glob_execute,
|
||
|
|
.print_action = directory_glob_print_action
|
||
|
|
};
|
||
|
|
|
||
|
|
static const tool_vtable_t mkdir_vtable = {
|
||
|
|
.get_description = mkdir_get_description,
|
||
|
|
.execute = mkdir_execute,
|
||
|
|
.print_action = mkdir_print_action
|
||
|
|
};
|
||
|
|
|
||
|
|
static const tool_vtable_t chdir_vtable = {
|
||
|
|
.get_description = chdir_get_description,
|
||
|
|
.execute = chdir_execute,
|
||
|
|
.print_action = chdir_print_action
|
||
|
|
};
|
||
|
|
|
||
|
|
static const tool_vtable_t getpwd_vtable = {
|
||
|
|
.get_description = getpwd_get_description,
|
||
|
|
.execute = getpwd_execute,
|
||
|
|
.print_action = getpwd_print_action
|
||
|
|
};
|
||
|
|
|
||
|
|
static tool_t read_file_tool = { .vtable = &read_file_vtable, .name = "read_file" };
|
||
|
|
static tool_t write_file_tool = { .vtable = &write_file_vtable, .name = "write_file" };
|
||
|
|
static tool_t directory_glob_tool = { .vtable = &directory_glob_vtable, .name = "directory_glob" };
|
||
|
|
static tool_t mkdir_tool = { .vtable = &mkdir_vtable, .name = "mkdir" };
|
||
|
|
static tool_t chdir_tool = { .vtable = &chdir_vtable, .name = "chdir" };
|
||
|
|
static tool_t getpwd_tool = { .vtable = &getpwd_vtable, .name = "getpwd" };
|
||
|
|
|
||
|
|
tool_t *tool_read_file_create(void) { return &read_file_tool; }
|
||
|
|
tool_t *tool_write_file_create(void) { return &write_file_tool; }
|
||
|
|
tool_t *tool_directory_glob_create(void) { return &directory_glob_tool; }
|
||
|
|
tool_t *tool_mkdir_create(void) { return &mkdir_tool; }
|
||
|
|
tool_t *tool_chdir_create(void) { return &chdir_tool; }
|
||
|
|
tool_t *tool_getpwd_create(void) { return &getpwd_tool; }
|
||
|
|
|
||
|
|
static char *expand_home_directory(const char *path) {
|
||
|
|
if (!path) return NULL;
|
||
|
|
if (path[0] != '~') return strdup(path);
|
||
|
|
|
||
|
|
const char *home_dir = getenv("HOME");
|
||
|
|
if (!home_dir) home_dir = getenv("USERPROFILE");
|
||
|
|
if (!home_dir) return strdup(path);
|
||
|
|
|
||
|
|
size_t home_len = strlen(home_dir);
|
||
|
|
size_t path_len = strlen(path);
|
||
|
|
char *expanded = malloc(home_len + path_len);
|
||
|
|
if (!expanded) return NULL;
|
||
|
|
|
||
|
|
strcpy(expanded, home_dir);
|
||
|
|
strcat(expanded, path + 1);
|
||
|
|
return expanded;
|
||
|
|
}
|
||
|
|
|
||
|
|
static 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";
|
||
|
|
}
|
||
|
|
|
||
|
|
static 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);
|
||
|
|
}
|
||
|
|
|
||
|
|
static char *make_dir_recursive(const char *path) {
|
||
|
|
char temp[4096];
|
||
|
|
char *p = NULL;
|
||
|
|
size_t len = strlen(path);
|
||
|
|
|
||
|
|
if (len >= sizeof(temp)) return strdup("Path too long!");
|
||
|
|
|
||
|
|
memcpy(temp, path, len + 1);
|
||
|
|
if (temp[len - 1] == '/') temp[len - 1] = '\0';
|
||
|
|
|
||
|
|
for (p = temp + 1; *p; p++) {
|
||
|
|
if (*p == '/') {
|
||
|
|
*p = '\0';
|
||
|
|
if (mkdir(temp, 0777) != 0 && errno != EEXIST) {
|
||
|
|
return strdup("Failed to create directory!");
|
||
|
|
}
|
||
|
|
*p = '/';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (mkdir(temp, 0777) != 0 && errno != EEXIST) {
|
||
|
|
return strdup("Failed to create directory!");
|
||
|
|
}
|
||
|
|
return strdup("Directory successfully created.");
|
||
|
|
}
|
||
|
|
|
||
|
|
static void ensure_parent_directory_exists(const char *path_including_file_name) {
|
||
|
|
if (!path_including_file_name) return;
|
||
|
|
|
||
|
|
char *path = strdup(path_including_file_name);
|
||
|
|
if (!path) return;
|
||
|
|
|
||
|
|
char *last_slash = strrchr(path, '/');
|
||
|
|
if (last_slash) {
|
||
|
|
*last_slash = '\0';
|
||
|
|
char *result = make_dir_recursive(path);
|
||
|
|
free(result);
|
||
|
|
}
|
||
|
|
free(path);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void read_file_print_action(const char *name, struct json_object *args) {
|
||
|
|
(void)name;
|
||
|
|
if (!args) return;
|
||
|
|
struct json_object *path;
|
||
|
|
if (json_object_object_get_ex(args, "path", &path)) {
|
||
|
|
fprintf(stderr, " -> Reading file: %s\n", json_object_get_string(path));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static char *read_file_execute(tool_t *self, struct json_object *args) {
|
||
|
|
(void)self;
|
||
|
|
struct json_object *path_obj;
|
||
|
|
if (!json_object_object_get_ex(args, "path", &path_obj)) {
|
||
|
|
return strdup("Error: missing 'path' argument");
|
||
|
|
}
|
||
|
|
|
||
|
|
char *expanded_path = expand_home_directory(json_object_get_string(path_obj));
|
||
|
|
if (!expanded_path) return strdup("Failed to expand path!");
|
||
|
|
|
||
|
|
FILE *fp = fopen(expanded_path, "r");
|
||
|
|
free(expanded_path);
|
||
|
|
if (!fp) return strdup("Failed to open file for reading!");
|
||
|
|
|
||
|
|
fseek(fp, 0, SEEK_END);
|
||
|
|
long size = ftell(fp);
|
||
|
|
if (size < 0) {
|
||
|
|
fclose(fp);
|
||
|
|
return strdup("Failed to determine file size!");
|
||
|
|
}
|
||
|
|
rewind(fp);
|
||
|
|
|
||
|
|
char *content = malloc((size_t)size + 1);
|
||
|
|
if (!content) {
|
||
|
|
fclose(fp);
|
||
|
|
return strdup("Memory allocation failed!");
|
||
|
|
}
|
||
|
|
|
||
|
|
size_t read_size = fread(content, 1, (size_t)size, fp);
|
||
|
|
content[read_size] = '\0';
|
||
|
|
fclose(fp);
|
||
|
|
return content;
|
||
|
|
}
|
||
|
|
|
||
|
|
static struct json_object *read_file_get_description(void) {
|
||
|
|
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();
|
||
|
|
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();
|
||
|
|
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();
|
||
|
|
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();
|
||
|
|
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);
|
||
|
|
|
||
|
|
r_config_handle cfg = r_config_get_instance();
|
||
|
|
if (r_config_use_strict(cfg)) {
|
||
|
|
json_object_object_add(function, "strict", json_object_new_boolean(1));
|
||
|
|
}
|
||
|
|
|
||
|
|
json_object_object_add(root, "function", function);
|
||
|
|
return root;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void write_file_print_action(const char *name, struct json_object *args) {
|
||
|
|
(void)name;
|
||
|
|
if (!args) return;
|
||
|
|
struct json_object *path;
|
||
|
|
if (json_object_object_get_ex(args, "path", &path)) {
|
||
|
|
fprintf(stderr, " -> Writing file: %s\n", json_object_get_string(path));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static char *write_file_execute(tool_t *self, struct json_object *args) {
|
||
|
|
(void)self;
|
||
|
|
struct json_object *path_obj, *content_obj;
|
||
|
|
|
||
|
|
if (!json_object_object_get_ex(args, "path", &path_obj)) {
|
||
|
|
return strdup("Error: missing 'path' argument");
|
||
|
|
}
|
||
|
|
if (!json_object_object_get_ex(args, "content", &content_obj)) {
|
||
|
|
return strdup("Error: missing 'content' argument");
|
||
|
|
}
|
||
|
|
|
||
|
|
const char *path = json_object_get_string(path_obj);
|
||
|
|
const char *content = json_object_get_string(content_obj);
|
||
|
|
|
||
|
|
ensure_parent_directory_exists(path);
|
||
|
|
|
||
|
|
FILE *fp = fopen(path, "w+");
|
||
|
|
if (!fp) return strdup("Failed to open file for writing!");
|
||
|
|
|
||
|
|
fwrite(content, 1, strlen(content), fp);
|
||
|
|
fclose(fp);
|
||
|
|
return strdup("File successfully written.");
|
||
|
|
}
|
||
|
|
|
||
|
|
static struct json_object *write_file_get_description(void) {
|
||
|
|
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();
|
||
|
|
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. Content should be in plain format, not json encoded."));
|
||
|
|
|
||
|
|
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();
|
||
|
|
json_object_object_add(path, "type", json_object_new_string("string"));
|
||
|
|
json_object_object_add(path, "description",
|
||
|
|
json_object_new_string("Path to the plain file to write / save / store."));
|
||
|
|
json_object_object_add(properties, "path", path);
|
||
|
|
|
||
|
|
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("Plain 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();
|
||
|
|
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);
|
||
|
|
|
||
|
|
r_config_handle cfg = r_config_get_instance();
|
||
|
|
if (r_config_use_strict(cfg)) {
|
||
|
|
json_object_object_add(function, "strict", json_object_new_boolean(1));
|
||
|
|
}
|
||
|
|
|
||
|
|
json_object_object_add(root, "function", function);
|
||
|
|
return root;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void directory_glob_print_action(const char *name, struct json_object *args) {
|
||
|
|
(void)name;
|
||
|
|
if (!args) return;
|
||
|
|
struct json_object *path;
|
||
|
|
if (json_object_object_get_ex(args, "path", &path)) {
|
||
|
|
fprintf(stderr, " -> Listing: %s\n", json_object_get_string(path));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static char *directory_glob_execute(tool_t *self, struct json_object *args) {
|
||
|
|
(void)self;
|
||
|
|
struct json_object *path_obj;
|
||
|
|
if (!json_object_object_get_ex(args, "path", &path_obj)) {
|
||
|
|
return strdup("Error: missing 'path' argument");
|
||
|
|
}
|
||
|
|
|
||
|
|
char target_dir[PATH_MAX];
|
||
|
|
strncpy(target_dir, json_object_get_string(path_obj), PATH_MAX - 1);
|
||
|
|
target_dir[PATH_MAX - 1] = '\0';
|
||
|
|
|
||
|
|
if (strcmp(target_dir, ".") == 0) {
|
||
|
|
target_dir[0] = '*';
|
||
|
|
target_dir[1] = '\0';
|
||
|
|
}
|
||
|
|
|
||
|
|
glob_t results;
|
||
|
|
struct stat file_stat;
|
||
|
|
char mod_time[20], create_time[20];
|
||
|
|
|
||
|
|
if (glob(target_dir, GLOB_TILDE, NULL, &results) != 0) {
|
||
|
|
return strdup("[]");
|
||
|
|
}
|
||
|
|
|
||
|
|
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];
|
||
|
|
|
||
|
|
if (stat(file_path, &file_stat) == -1) continue;
|
||
|
|
|
||
|
|
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_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));
|
||
|
|
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));
|
||
|
|
|
||
|
|
json_object_array_add(json_array, json_entry);
|
||
|
|
}
|
||
|
|
|
||
|
|
globfree(&results);
|
||
|
|
char *result = strdup(json_object_to_json_string_ext(json_array, JSON_C_TO_STRING_PRETTY));
|
||
|
|
json_object_put(json_array);
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
static struct json_object *directory_glob_get_description(void) {
|
||
|
|
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();
|
||
|
|
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."));
|
||
|
|
|
||
|
|
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();
|
||
|
|
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();
|
||
|
|
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);
|
||
|
|
|
||
|
|
r_config_handle cfg = r_config_get_instance();
|
||
|
|
if (r_config_use_strict(cfg)) {
|
||
|
|
json_object_object_add(function, "strict", json_object_new_boolean(1));
|
||
|
|
}
|
||
|
|
|
||
|
|
json_object_object_add(root, "function", function);
|
||
|
|
return root;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void mkdir_print_action(const char *name, struct json_object *args) {
|
||
|
|
(void)name;
|
||
|
|
if (!args) return;
|
||
|
|
struct json_object *path;
|
||
|
|
if (json_object_object_get_ex(args, "path", &path)) {
|
||
|
|
fprintf(stderr, " -> Creating directory: %s\n", json_object_get_string(path));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static char *mkdir_execute(tool_t *self, struct json_object *args) {
|
||
|
|
(void)self;
|
||
|
|
struct json_object *path_obj;
|
||
|
|
if (!json_object_object_get_ex(args, "path", &path_obj)) {
|
||
|
|
return strdup("Error: missing 'path' argument");
|
||
|
|
}
|
||
|
|
return make_dir_recursive(json_object_get_string(path_obj));
|
||
|
|
}
|
||
|
|
|
||
|
|
static struct json_object *mkdir_get_description(void) {
|
||
|
|
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();
|
||
|
|
json_object_object_add(function, "name", json_object_new_string("mkdir"));
|
||
|
|
json_object_object_add(function, "description",
|
||
|
|
json_object_new_string("Creates a new directory with the specified path."));
|
||
|
|
|
||
|
|
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();
|
||
|
|
json_object_object_add(path, "type", json_object_new_string("string"));
|
||
|
|
json_object_object_add(path, "description",
|
||
|
|
json_object_new_string("Path of the directory to create."));
|
||
|
|
json_object_object_add(properties, "path", path);
|
||
|
|
|
||
|
|
json_object_object_add(parameters, "properties", properties);
|
||
|
|
|
||
|
|
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);
|
||
|
|
|
||
|
|
r_config_handle cfg = r_config_get_instance();
|
||
|
|
if (r_config_use_strict(cfg)) {
|
||
|
|
json_object_object_add(function, "strict", json_object_new_boolean(1));
|
||
|
|
}
|
||
|
|
|
||
|
|
json_object_object_add(root, "function", function);
|
||
|
|
return root;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void chdir_print_action(const char *name, struct json_object *args) {
|
||
|
|
(void)name;
|
||
|
|
if (!args) return;
|
||
|
|
struct json_object *path;
|
||
|
|
if (json_object_object_get_ex(args, "path", &path)) {
|
||
|
|
fprintf(stderr, " -> Changing directory: %s\n", json_object_get_string(path));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static char *chdir_execute(tool_t *self, struct json_object *args) {
|
||
|
|
(void)self;
|
||
|
|
struct json_object *path_obj;
|
||
|
|
if (!json_object_object_get_ex(args, "path", &path_obj)) {
|
||
|
|
return strdup("Error: missing 'path' argument");
|
||
|
|
}
|
||
|
|
|
||
|
|
if (chdir(json_object_get_string(path_obj)) != 0) {
|
||
|
|
return strdup("Failed to change directory!");
|
||
|
|
}
|
||
|
|
return strdup("Directory successfully changed.");
|
||
|
|
}
|
||
|
|
|
||
|
|
static struct json_object *chdir_get_description(void) {
|
||
|
|
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();
|
||
|
|
json_object_object_add(function, "name", json_object_new_string("chdir"));
|
||
|
|
json_object_object_add(function, "description",
|
||
|
|
json_object_new_string("Changes the current working directory to the specified path. Call this function when `cd` is prompted."));
|
||
|
|
|
||
|
|
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();
|
||
|
|
json_object_object_add(path, "type", json_object_new_string("string"));
|
||
|
|
json_object_object_add(path, "description",
|
||
|
|
json_object_new_string("Path to change the current working directory to."));
|
||
|
|
json_object_object_add(properties, "path", path);
|
||
|
|
|
||
|
|
json_object_object_add(parameters, "properties", properties);
|
||
|
|
|
||
|
|
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);
|
||
|
|
|
||
|
|
r_config_handle cfg = r_config_get_instance();
|
||
|
|
if (r_config_use_strict(cfg)) {
|
||
|
|
json_object_object_add(function, "strict", json_object_new_boolean(1));
|
||
|
|
}
|
||
|
|
|
||
|
|
json_object_object_add(root, "function", function);
|
||
|
|
return root;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void getpwd_print_action(const char *name, struct json_object *args) {
|
||
|
|
(void)name;
|
||
|
|
(void)args;
|
||
|
|
fprintf(stderr, " -> Getting current directory\n");
|
||
|
|
}
|
||
|
|
|
||
|
|
static char *getpwd_execute(tool_t *self, struct json_object *args) {
|
||
|
|
(void)self;
|
||
|
|
(void)args;
|
||
|
|
|
||
|
|
char *cwd = malloc(PATH_MAX);
|
||
|
|
if (!cwd) return strdup("Failed to allocate memory for current working directory!");
|
||
|
|
|
||
|
|
if (!getcwd(cwd, PATH_MAX)) {
|
||
|
|
free(cwd);
|
||
|
|
return strdup("Failed to get current working directory!");
|
||
|
|
}
|
||
|
|
return cwd;
|
||
|
|
}
|
||
|
|
|
||
|
|
static struct json_object *getpwd_get_description(void) {
|
||
|
|
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();
|
||
|
|
json_object_object_add(function, "name", json_object_new_string("getpwd"));
|
||
|
|
json_object_object_add(function, "description",
|
||
|
|
json_object_new_string("Returns the current working directory as a string."));
|
||
|
|
|
||
|
|
json_object_object_add(function, "parameters", json_object_new_null());
|
||
|
|
json_object_object_add(root, "function", function);
|
||
|
|
return root;
|
||
|
|
}
|