Update.
This commit is contained in:
		
							parent
							
								
									2f8701fef3
								
							
						
					
					
						commit
						bee172c6eb
					
				
							
								
								
									
										219
									
								
								tools.h
									
									
									
									
									
								
							
							
						
						
									
										219
									
								
								tools.h
									
									
									
									
									
								
							| @ -23,6 +23,8 @@ struct json_object *tool_description_linux_terminal(); | |||||||
| struct json_object *tool_description_directory_glob(); | struct json_object *tool_description_directory_glob(); | ||||||
| struct json_object *tool_description_read_file(); | struct json_object *tool_description_read_file(); | ||||||
| struct json_object *tool_description_write_file(); | struct json_object *tool_description_write_file(); | ||||||
|  | struct json_object *tool_description_directory_rglob(); | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| struct json_object *tools_descriptions() { | struct json_object *tools_descriptions() { | ||||||
|     struct json_object *root = json_object_new_array(); |     struct json_object *root = json_object_new_array(); | ||||||
| @ -31,7 +33,7 @@ struct json_object *tools_descriptions() { | |||||||
|     json_object_array_add(root, tool_description_directory_glob()); |     json_object_array_add(root, tool_description_directory_glob()); | ||||||
|     json_object_array_add(root, tool_description_read_file()); |     json_object_array_add(root, tool_description_read_file()); | ||||||
|     json_object_array_add(root, tool_description_write_file()); |     json_object_array_add(root, tool_description_write_file()); | ||||||
|      |     json_object_array_add(root, tool_description_directory_rglob()); | ||||||
| 
 | 
 | ||||||
|     return root; |     return root; | ||||||
| } | } | ||||||
| @ -75,6 +77,42 @@ char * tool_function_linux_terminal(char * command){ | |||||||
|     return output ? output : strdup(""); |     return output ? output : strdup(""); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 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(); | ||||||
|  |     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.")); | ||||||
|  | 
 | ||||||
|  |     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); | ||||||
|  |     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_read_file() { | struct json_object *tool_description_read_file() { | ||||||
|     struct json_object *root = json_object_new_object(); |     struct json_object *root = json_object_new_object(); | ||||||
|     json_object_object_add(root, "type", json_object_new_string("function")); |     json_object_object_add(root, "type", json_object_new_string("function")); | ||||||
| @ -203,6 +241,171 @@ void format_time(time_t raw_time, char *buffer, size_t size) { | |||||||
|     strftime(buffer, size, "%Y-%m-%d %H:%M:%S", time_info); |     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; | ||||||
|  |     results.gl_pathc = 0; | ||||||
|  |     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
 | ||||||
|  | 
 | ||||||
|  |         // 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)); | ||||||
|  |         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)); | ||||||
|  | 
 | ||||||
|  |         // 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); |     fprintf(stderr, "Tools directory_glob: %s\n", target_dir); | ||||||
| glob_t results; | glob_t results; | ||||||
| @ -457,6 +660,20 @@ 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); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|             json_object_array_add(tools_result_messages, tool_result); |             json_object_array_add(tools_result_messages, tool_result); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user