// 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 #include #include #ifdef _WIN32 #include #else #include #include #include #endif void get_current_directory() { char buffer[PATH_MAX]; #ifdef _WIN32 DWORD length = GetCurrentDirectory(PATH_MAX, buffer); if (length > 0 && length < PATH_MAX) { printf("Current Directory: %s\n", buffer); } else { printf("Error getting current directory.\n"); } #else if (getcwd(buffer, sizeof(buffer)) != NULL) { printf("Current Directory: %s\n", buffer); } else { perror("Error getting current directory"); } #endif } char *expand_home_directory(const char *path) { if (path[0] != '~') { return strdup(path); // Return the original path if it doesn't start with ~ } char *home_dir; #ifdef _WIN32 home_dir = getenv("USERPROFILE"); // Get home directory on Windows #else struct passwd *pw = getpwuid(getuid()); home_dir = pw->pw_dir; // Get home directory on Linux #endif if (home_dir == NULL) { return NULL; // Error getting home directory } size_t home_len = strlen(home_dir); size_t path_len = strlen(path + 1); size_t expanded_size = home_len + path_len + 1; char *expanded_path = (char *)malloc(expanded_size); if (expanded_path == NULL) { return NULL; } memcpy(expanded_path, home_dir, home_len); memcpy(expanded_path + home_len, path + 1, path_len); expanded_path[home_len + path_len] = '\0'; return expanded_path; } unsigned long hash(const char *str) { unsigned long hash = 5381; // Starting value int c; while ((c = *str++)) { hash = ((hash << 5) + hash) + c; // hash * 33 + c } return hash; } char *joinpath(const char *base_url, const char *path) { static char result[4096]; size_t base_len = strlen(base_url); size_t pos = 0; if (base_len >= sizeof(result) - 2) { base_len = sizeof(result) - 2; } memcpy(result, base_url, base_len); pos = base_len; if (pos > 0 && result[pos - 1] != '/') { result[pos++] = '/'; } if (path[0] == '/') { path++; } size_t path_len = strlen(path); if (pos + path_len >= sizeof(result)) { path_len = sizeof(result) - pos - 1; } memcpy(result + pos, path, path_len); result[pos + path_len] = '\0'; return result; } char *read_file(const char *path) { char *expanded_path = expand_home_directory(path); if (expanded_path == NULL) { return NULL; } FILE *file = fopen(expanded_path, "r"); free(expanded_path); if (file == NULL) { return NULL; } fseek(file, 0, SEEK_END); long size = ftell(file); fseek(file, 0, SEEK_SET); char *buffer = (char *)malloc(size + 1); size_t read = fread(buffer, 1, size, file); if (read == 0) { free(buffer); return NULL; } fclose(file); buffer[read] = '\0'; return buffer; } #endif