Mercurial > hg > th-libs
view th_file.c @ 184:b256db93cf25
Initial import of th_file module.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 20 Jan 2016 16:40:05 +0200 |
parents | |
children | 5c7de25666e7 |
line wrap: on
line source
/* * File, directory etc helper functions * Programmed and designed by Matti 'ccr' Hamalainen * (C) Copyright 2016 Tecnic Software productions (TNSP) * * Please read file 'COPYING' for information on license and distribution. */ #include "th_file.h" #include "th_string.h" #include <unistd.h> //#include <fcntl.h> #ifdef TH_PLAT_WINDOWS # include <shlwapi.h> # include <shfolder.h> #else //# include <sys/wait.h> # include <sys/stat.h> # include <sys/types.h> #endif char * th_get_home_dir() { #if defined(TH_PLAT_WINDOWS) char tmpPath[MAX_PATH]; if (SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, tmpPath) == S_OK) return th_strdup(tmpPath); #endif return th_strdup(getenv("HOME")); } char * th_get_data_dir() { #if defined(TH_PLAT_WINDOWS) char tmpPath[MAX_PATH]; if (SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, tmpPath) == S_OK) return th_strdup(tmpPath); #endif return th_strdup(getenv("HOME")); } char * th_get_config_dir() { #if defined(TH_PLAT_WINDOWS) // For Windows, we just use the appdata directory return th_get_data_dir(); #elif defined(USE_XDG) const char *xdgConfigDir = getenv("XDG_CONFIG_HOME"); // If XDG is enabled, try the environment variable first if (xdgConfigDir != NULL && strcmp(xdgConfigDir, "")) return th_strdup_printf("%s" TH_DIR_SEPARATOR "%s" TH_DIR_SEPARATOR, xdgConfigDir, SET_XDG_CONFIG_DIR); else // Nope, try the obvious alternative return th_strdup_printf("%s" TH_DIR_SEPARATOR ".config" TH_DIR_SEPARATOR "%s" TH_DIR_SEPARATOR, setHomeDir, SET_XDG_CONFIG_DIR); #else // XDG not enabled return th_get_data_dir(); #endif } BOOL th_stat_path(const char *path, int *flags) { *flags = 0; #ifdef TH_PLAT_WINDOWS DWORD attr = GetFileAttributes(path); *flags |= (attr & FILE_ATTRIBUTE_DIRECTORY) ? TH_IS_DIR : 0; *flags |= (attr & FILE_ATTRIBUTE_READONLY) ? 0 : TH_IS_WRITABLE; *flags |= TH_IS_READABLE; #else uid_t id = geteuid(); struct stat sb; if (stat(path, &sb) < 0) return FALSE; *flags |= S_ISDIR(sb.st_mode) ? TH_IS_DIR : 0; *flags |= (id == sb.st_uid && (sb.st_mode & S_IWUSR)) ? TH_IS_WRITABLE : 0; *flags |= (id == sb.st_uid && (sb.st_mode & S_IRUSR)) ? TH_IS_READABLE : 0; #endif return TRUE; } BOOL th_mkdir_path(const char *cpath, int mode) { char save, *path = th_strdup(cpath); size_t start = 0, end; BOOL res = FALSE; // If mode is 0, default to something sensible if (mode == 0) mode = 0711; // Start creating the directory stucture do { // Split foremost path element out for (save = 0, end = start; path[end] != 0; end++) if (path[end] == TH_DIR_SEPARATOR) { save = path[end]; path[end] = 0; break; } // If the element is there, create it if (path[start] != 0) { int flags; BOOL exists = th_stat_path(path, &flags); if (exists && (flags & TH_IS_DIR) == 0) goto error; if (!exists) { #ifdef TH_PLAT_WINDOWS if (!CreateDirectory(path, NULL)) goto error; #else if (mkdir(path, mode) < 0) goto error; #endif } } // Restore separator character and jump to next element path[end] = save; start = end + 1; } while (save != 0); res = TRUE; error: th_free(path); return res; }