From 9f7aaa8aedfe38172cfc3de4bfc61bb4af309e83 Mon Sep 17 00:00:00 2001 From: Tamas TEVESZ Date: Wed, 17 Mar 2010 22:46:19 +0100 Subject: [PATCH] Some rework on getstyle - make it use wings functions, remove duplicated code from getstyle - de-static necessary functions in wings - add new wrmdirhier to wings - rename WMMkDirHier to wmkdirhier (fits better) - remove calling shell from getstyle (what were they thinking?) i couldn't quite test getstyle (no idea about themes), but it still basically works. do back your ~/G dir up... wrmdirhier might eat it! definitely needs testing, especially by people who have any idea how themes work. Some more getstyle - missed a shell invocation - maybe copyFile should be in wutils too...? [crmafra: Folded second patch into the first] --- WINGs/WINGs/WUtil.h | 3 + WINGs/findfile.c | 2 +- WINGs/proplist.c | 62 +++++++++++- src/misc.c | 1 - util/getstyle.c | 271 +++++++++++----------------------------------------- 5 files changed, 120 insertions(+), 219 deletions(-) diff --git a/WINGs/WINGs/WUtil.h b/WINGs/WINGs/WUtil.h index ef6df844..f1335243 100644 --- a/WINGs/WINGs/WUtil.h +++ b/WINGs/WINGs/WUtil.h @@ -244,6 +244,9 @@ char* wfindfileinarray(WMPropList* array, char *file); char* wexpandpath(char *path); +int wmkdirhier(const char *path); +int wrmdirhier(const char *path); + /* don't free the returned string */ char* wgethomedir(); diff --git a/WINGs/findfile.c b/WINGs/findfile.c index d5699e6f..9aad1d74 100644 --- a/WINGs/findfile.c +++ b/WINGs/findfile.c @@ -53,7 +53,7 @@ char *wgethomedir() } } -static char *getuserhomedir(char *username) +static char *getuserhomedir(const char *username) { struct passwd *user; diff --git a/WINGs/proplist.c b/WINGs/proplist.c index fe266617..f4d9c765 100644 --- a/WINGs/proplist.c +++ b/WINGs/proplist.c @@ -9,6 +9,8 @@ #include #include +#include + #include "WUtil.h" #include "wconfig.h" @@ -51,7 +53,6 @@ static WMPropList *getPLData(PLData * pldata); static WMPropList *getPLArray(PLData * pldata); static WMPropList *getPLDictionary(PLData * pldata); static WMPropList *getPropList(PLData * pldata); -static int WMMkDirHier(const char *path); typedef unsigned (*hashFunc) (const void *); typedef Bool(*isEqualFunc) (const void *, const void *); @@ -1560,7 +1561,7 @@ Bool WMWritePropListToFile(WMPropList * plist, char *path) int fd, mask; #endif - if (!WMMkDirHier(path)) + if (!wmkdirhier(path)) return False; /* Use the path name of the destination file as a prefix for the @@ -1636,7 +1637,7 @@ Bool WMWritePropListToFile(WMPropList * plist, char *path) * * returns 1 on success, 0 on failure */ -static int WMMkDirHier(const char *path) +int wmkdirhier(const char *path) { char *t, *thePath = NULL, buf[1024]; size_t p, plen; @@ -1690,3 +1691,58 @@ static int WMMkDirHier(const char *path) wfree(thePath); return 1; } + +/* + * remove a directory hierarchy + * + * refuses to remove anything outside $GNUSTEP_USER_ROOT + * + * returns 1 on success, 0 on failure + * + * TODO: revisit what's error and what's not + * + * with inspirations from OpenBSD's bin/rm/rm.c + */ +int wrmdirhier(const char *path) +{ + FTS *fts; + FTSENT *p; + char *t; + struct stat st; + char *ptree[2]; + + /* Only remove directories under $GNUSTEP_USER_ROOT */ + if ((t = wusergnusteppath()) == NULL) + return 0; + if (strncmp(path, t, strlen(t)) != 0) + return 0; + + /* Shortcut if it doesn't exist to begin with */ + if (stat(path, &st) == -1) + return 0; + + ptree[0] = (char *)path; + ptree[1] = NULL; + + if (!(fts = fts_open(ptree, FTS_PHYSICAL, NULL))) + return 0; + + while ((p = fts_read(fts)) != NULL) { + switch(p->fts_info) { + case FTS_D: + continue; + break; + case FTS_DP: + rmdir(p->fts_path); + continue; + break; + case FTS_F: + unlink(p->fts_path); + continue; + break; + default: continue; + } + + } + +} diff --git a/src/misc.c b/src/misc.c index 9058a830..c063f187 100644 --- a/src/misc.c +++ b/src/misc.c @@ -158,7 +158,6 @@ char *MakeCPPArgs(char *path) if (buf[0] != '~') { strcpy(fullpath, buf); } else { - char *wgethomedir(); /* home is statically allocated. Don't free it! */ char *home = wgethomedir(); diff --git a/util/getstyle.c b/util/getstyle.c index 8f519d2b..23935ba4 100644 --- a/util/getstyle.c +++ b/util/getstyle.c @@ -22,6 +22,10 @@ #define PROG_VERSION "getstyle (Window Maker) 0.6" +#include +#include + +#include #include #include #include @@ -30,6 +34,7 @@ #include #include #include +#include #include #ifndef PATH_MAX @@ -171,202 +176,14 @@ char *defaultsPathForDomain(char *domain) void abortar(char *reason) { - char buffer[4000]; - printf("%s: %s\n", ProgName, reason); - if (ThemePath) { printf("Removing unfinished theme pack\n"); - sprintf(buffer, "/bin/rm -fr \"%s\"", ThemePath); - - if (system(buffer) != 0) { - printf("%s: could not execute command %s\n", ProgName, buffer); - } + (void)wrmdirhier(ThemePath); } exit(1); } -char *wgethomedir() -{ - char *home = getenv("HOME"); - struct passwd *user; - - if (home) - return home; - - user = getpwuid(getuid()); - if (!user) { - char buffer[80]; - - sprintf(buffer, "could not get password entry for UID %i", getuid()); - perror(buffer); - return "/"; - } - if (!user->pw_dir) { - return "/"; - } else { - return user->pw_dir; - } -} - -static char *getuserhomedir(char *username) -{ - struct passwd *user; - - user = getpwnam(username); - if (!user) { - char buffer[100]; - - sprintf(buffer, "could not get password entry for user %s", username); - perror(buffer); - return NULL; - } - if (!user->pw_dir) { - return "/"; - } else { - return user->pw_dir; - } -} - -char *wexpandpath(char *path) -{ - char buffer2[PATH_MAX + 2]; - char buffer[PATH_MAX + 2]; - int i; - - memset(buffer, 0, PATH_MAX + 2); - - if (*path == '~') { - char *home; - - path++; - if (*path == '/' || *path == 0) { - home = wgethomedir(); - strcat(buffer, home); - } else { - int j; - j = 0; - while (*path != 0 && *path != '/') { - buffer2[j++] = *path; - buffer2[j] = 0; - path++; - } - home = getuserhomedir(buffer2); - if (!home) - return NULL; - strcat(buffer, home); - } - } - - i = strlen(buffer); - - while (*path != 0) { - char *tmp; - - if (*path == '$') { - int j = 0; - path++; - /* expand $(HOME) or $HOME style environment variables */ - if (*path == '(') { - path++; - while (*path != 0 && *path != ')') { - buffer2[j++] = *(path++); - buffer2[j] = 0; - } - if (*path == ')') - path++; - tmp = getenv(buffer2); - if (!tmp) { - buffer[i] = 0; - strcat(buffer, "$("); - strcat(buffer, buffer2); - strcat(buffer, ")"); - i += strlen(buffer2) + 3; - } else { - strcat(buffer, tmp); - i += strlen(tmp); - } - } else { - while (*path != 0 && *path != '/') { - buffer2[j++] = *(path++); - buffer2[j] = 0; - } - tmp = getenv(buffer2); - if (!tmp) { - strcat(buffer, "$"); - strcat(buffer, buffer2); - i += strlen(buffer2) + 1; - } else { - strcat(buffer, tmp); - i += strlen(tmp); - } - } - } else { - buffer[i++] = *path; - path++; - } - } - - return wstrdup(buffer); -} - -char *wfindfileinarray(WMPropList * paths, char *file) -{ - int i; - char *path; - int len, flen; - char *fullpath; - - if (!file) - return NULL; - - if (*file == '/' || *file == '~' || !paths || !WMIsPLArray(paths) - || WMGetPropListItemCount(paths) == 0) { - if (access(file, R_OK) < 0) { - fullpath = wexpandpath(file); - if (!fullpath) - return NULL; - - if (access(fullpath, R_OK) < 0) { - free(fullpath); - return NULL; - } else { - return fullpath; - } - } else { - return wstrdup(file); - } - } - - flen = strlen(file); - for (i = 0; i < WMGetPropListItemCount(paths); i++) { - WMPropList *tmp; - char *dir; - - tmp = WMGetFromPLArray(paths, i); - if (!WMIsPLString(tmp) || !(dir = WMGetFromPLString(tmp))) - continue; - - len = strlen(dir); - path = wmalloc(len + flen + 2); - path = memcpy(path, dir, len); - path[len] = 0; - strcat(path, "/"); - strcat(path, file); - /* expand tilde */ - fullpath = wexpandpath(path); - free(path); - if (fullpath) { - /* check if file is readable */ - if (access(fullpath, R_OK) == 0) { - return fullpath; - } - free(fullpath); - } - } - return NULL; -} - static Bool isFontOption(char *option) { int i; @@ -380,14 +197,48 @@ static Bool isFontOption(char *option) return False; } +/* + * it is more or less assumed that this function will only + * copy reasonably-sized files + */ void copyFile(char *dir, char *file) { - char buffer[4000]; - - sprintf(buffer, "/bin/cp \"%s\" \"%s\"", file, dir); - if (system(buffer) != 0) { - printf("%s: could not copy file %s\n", ProgName, file); + int from_fd, to_fd; + size_t block, len; + char buf[4096]; + struct stat st; + char *dst; + + /* only to a directory */ + if (stat(dir, &st) != 0 || !S_ISDIR(st.st_mode)) + return; + /* only copy files */ + if (stat(file, &st) != 0 || !S_ISREG(st.st_mode)) + return; + + len = strlen(dir) + 1 /* / */ + strlen(file) + 1 /* '\0' */; + dst = wmalloc(len); + snprintf(dst, len, "%s/%s", dir, basename(file)); + buf[len] = '\0'; + + if ((to_fd = open(dst, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1) { + wfree(dst); + return; + } + wfree(dst); + if ((from_fd = open(file, O_RDONLY)) == -1) { + (void)close(to_fd); + return; } + + /* XXX: signal handling */ + while ((block = read(from_fd, &buf, sizeof(buf))) > 0) + write(to_fd, &buf, block); + + (void)fsync(to_fd); + (void)fchmod(to_fd, st.st_mode); + (void)close(to_fd); + (void)close(from_fd); } void findCopyFile(char *dir, char *file) @@ -405,30 +256,24 @@ void findCopyFile(char *dir, char *file) free(fullPath); } -char *makeThemePack(WMPropList * style, char *themeName) +void makeThemePack(WMPropList * style, char *themeName) { WMPropList *keys; WMPropList *key; WMPropList *value; int i; - char *themeDir; - - themeDir = wmalloc(strlen(themeName) + 50); - sprintf(themeDir, "%s.themed", themeName); + size_t themeNameLen; + char *themeDir, *t; + + if ((t = wusergnusteppath()) == NULL) + return; + themeNameLen = strlen(t) + 1 /* / */ + strlen(themeName) + 8 /* ".themed/" */ + 1 /* '\0' */; + themeDir = wmalloc(themeNameLen); + snprintf(themeDir, themeNameLen, "%s/%s.themed/", t, themeName); ThemePath = themeDir; - { - char *tmp; - - tmp = wmalloc(strlen(themeDir) + 20); - sprintf(tmp, "/bin/mkdir \"%s\"", themeDir); - if (system(tmp) != 0) { - printf - ("%s: could not create directory %s. Probably there's already a theme with that name in this directory.\n", - ProgName, themeDir); - exit(1); - } - free(tmp); - } + if (!wmkdirhier(themeDir)) + return; + keys = WMGetPLDictionaryKeys(style); for (i = 0; i < WMGetPropListItemCount(keys); i++) { @@ -502,8 +347,6 @@ char *makeThemePack(WMPropList * style, char *themeName) } } } - - return themeDir; } int main(int argc, char **argv) -- 2.11.4.GIT