>From 4397b9a33db1d38ddf3e387aa4f0aa0191b7744f Mon Sep 17 00:00:00 2001
From: Tamas TEVESZ <[email protected]>
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.
---
 WINGs/WINGs/WUtil.h |    3 +
 WINGs/findfile.c    |    2 +-
 WINGs/proplist.c    |   62 ++++++++++++++-
 src/misc.c          |    1 -
 util/getstyle.c     |  219 +++------------------------------------------------
 5 files changed, 76 insertions(+), 211 deletions(-)

diff --git a/WINGs/WINGs/WUtil.h b/WINGs/WINGs/WUtil.h
index ef6df84..f133524 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 d5699e6..9aad1d7 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 fe26661..ea8c9af 100644
--- a/WINGs/proplist.c
+++ b/WINGs/proplist.c
@@ -9,6 +9,8 @@
 #include <unistd.h>
 #include <ctype.h>
 
+#include <fts.h>
+
 #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] = 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 9058a83..c063f18 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 8f519d2..452183d 100644
--- a/util/getstyle.c
+++ b/util/getstyle.c
@@ -177,196 +177,11 @@ void abortar(char *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;
@@ -405,30 +220,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 +311,6 @@ char *makeThemePack(WMPropList * style, char *themeName)
                        }
                }
        }
-
-       return themeDir;
 }
 
 int main(int argc, char **argv)
-- 
1.7.0


-- 
[-]

mkdir /nonexistent
From 4397b9a33db1d38ddf3e387aa4f0aa0191b7744f Mon Sep 17 00:00:00 2001
From: Tamas TEVESZ <[email protected]>
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.
---
 WINGs/WINGs/WUtil.h |    3 +
 WINGs/findfile.c    |    2 +-
 WINGs/proplist.c    |   62 ++++++++++++++-
 src/misc.c          |    1 -
 util/getstyle.c     |  219 +++------------------------------------------------
 5 files changed, 76 insertions(+), 211 deletions(-)

diff --git a/WINGs/WINGs/WUtil.h b/WINGs/WINGs/WUtil.h
index ef6df84..f133524 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 d5699e6..9aad1d7 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 fe26661..ea8c9af 100644
--- a/WINGs/proplist.c
+++ b/WINGs/proplist.c
@@ -9,6 +9,8 @@
 #include <unistd.h>
 #include <ctype.h>
 
+#include <fts.h>
+
 #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] = 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 9058a83..c063f18 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 8f519d2..452183d 100644
--- a/util/getstyle.c
+++ b/util/getstyle.c
@@ -177,196 +177,11 @@ void abortar(char *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;
@@ -405,30 +220,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 +311,6 @@ char *makeThemePack(WMPropList * style, char *themeName)
 			}
 		}
 	}
-
-	return themeDir;
 }
 
 int main(int argc, char **argv)
-- 
1.7.0

Reply via email to