as per previous.
i've implemented semantics i feel generally ok for use by any parts of
wm, but tweak as needed.
i think i fscked up some whitespace things, would you please, carlos :)
>From 5f4420be79ab73258aaf85592003f8d05a8e8bcb Mon Sep 17 00:00:00 2001
From: Tamas TEVESZ <[email protected]>
Date: Mon, 15 Mar 2010 19:49:14 +0100
Subject: [PATCH] - add a new helper function, WMMkDirHier(), which creates
directory
hierarchies under $GNUSTEP_USER_ROOT
- make WMWritePropListToFile() use this
readily solves the "run dialog history vs nonexistent state dir" case.
if other consumers are found for this, just de-static and move the
prototype to WUtil.h or some other appropriate place.
---
WINGs/proplist.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 70 insertions(+), 0 deletions(-)
diff --git a/WINGs/proplist.c b/WINGs/proplist.c
index 79bb298..51329bc 100644
--- a/WINGs/proplist.c
+++ b/WINGs/proplist.c
@@ -50,6 +50,7 @@ static WMPropList *getPLData(PLData * pldata);
static WMPropList *getPLArray(PLData * pldata);
static WMPropList *getPLDictionary(PLData * pldata);
static WMPropList *getPropList(PLData * pldata);
+static int WMMkDirHier(char * path);
typedef unsigned (*hashFunc) (const void *);
typedef Bool(*isEqualFunc) (const void *, const void *);
@@ -1555,6 +1556,9 @@ Bool WMWritePropListToFile(WMPropList * plist, char
*path, Bool atomically)
char *desc;
FILE *theFile;
+ if (!WMMkDirHier(path))
+ return False;
+
if (atomically) {
#ifdef HAVE_MKSTEMP
int fd, mask;
@@ -1629,3 +1633,69 @@ Bool WMWritePropListToFile(WMPropList * plist, char
*path, Bool atomically)
return False;
}
+
+/*
+ * create a directory hierarchy
+ *
+ * if the last octet of `path' is `/', the full path is
+ * assumed to be a directory; otherwise path is assumed to be a
+ * file, and the last component is stripped off. the rest is the
+ * the hierarchy to be created.
+ *
+ * refuses to create anything outside $GNUSTEP_USER_ROOT
+ *
+ * returns 1 on success, 0 on failure
+ */
+int WMMkDirHier(char *path)
+{
+ char *t, *thePath = NULL, buf[1024];
+ size_t p, plen;
+ struct stat st;
+
+ /* Only create directories under $GNUSTEP_USER_ROOT */
+ if ((t = wusergnusteppath()) == NULL)
+ return 0;
+ if (strncmp(path, t, strlen(t)) != 0)
+ return 0;
+
+ thePath = wstrdup(path);
+ /* Strip the trailing component if it is a file */
+ p = strlen(thePath);
+ while (p && thePath[p] != '/')
+ thePath[p--] = '\0';
+
+ thePath[p] = '\0';
+
+ /* Shortcut if it already exists */
+ if (stat(thePath, &st) == 0) {
+ wfree(thePath);
+ if (S_ISDIR(st.st_mode)) {
+ /* Is a directory alright */
+ return 1;
+ } else {
+ /* Exists, but not a directory, the caller
+ * might just as well abort now */
+ return 0;
+ }
+ }
+
+ memset(buf, 0, sizeof(buf));
+ strncpy(buf, t, sizeof(buf) - 1);
+ p = strlen(buf);
+ plen = strlen(thePath);
+
+ do {
+ while (p++ < plen && thePath[p] != '/')
+ ;
+
+ strncpy(buf, thePath, p);
+ if (mkdir(buf, 0777) == -1) {
+ wsyserror(_("Could not create %s"), buf);
+ wfree(thePath);
+ return 0;
+ }
+ } while (p < plen);
+
+ wfree(thePath);
+ return 1;
+}
--
1.7.0
--
[-]
mkdir /nonexistentFrom 5f4420be79ab73258aaf85592003f8d05a8e8bcb Mon Sep 17 00:00:00 2001
From: Tamas TEVESZ <[email protected]>
Date: Mon, 15 Mar 2010 19:49:14 +0100
Subject: [PATCH] - add a new helper function, WMMkDirHier(), which creates directory
hierarchies under $GNUSTEP_USER_ROOT
- make WMWritePropListToFile() use this
readily solves the "run dialog history vs nonexistent state dir" case.
if other consumers are found for this, just de-static and move the
prototype to WUtil.h or some other appropriate place.
---
WINGs/proplist.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 70 insertions(+), 0 deletions(-)
diff --git a/WINGs/proplist.c b/WINGs/proplist.c
index 79bb298..51329bc 100644
--- a/WINGs/proplist.c
+++ b/WINGs/proplist.c
@@ -50,6 +50,7 @@ static WMPropList *getPLData(PLData * pldata);
static WMPropList *getPLArray(PLData * pldata);
static WMPropList *getPLDictionary(PLData * pldata);
static WMPropList *getPropList(PLData * pldata);
+static int WMMkDirHier(char * path);
typedef unsigned (*hashFunc) (const void *);
typedef Bool(*isEqualFunc) (const void *, const void *);
@@ -1555,6 +1556,9 @@ Bool WMWritePropListToFile(WMPropList * plist, char *path, Bool atomically)
char *desc;
FILE *theFile;
+ if (!WMMkDirHier(path))
+ return False;
+
if (atomically) {
#ifdef HAVE_MKSTEMP
int fd, mask;
@@ -1629,3 +1633,69 @@ Bool WMWritePropListToFile(WMPropList * plist, char *path, Bool atomically)
return False;
}
+
+/*
+ * create a directory hierarchy
+ *
+ * if the last octet of `path' is `/', the full path is
+ * assumed to be a directory; otherwise path is assumed to be a
+ * file, and the last component is stripped off. the rest is the
+ * the hierarchy to be created.
+ *
+ * refuses to create anything outside $GNUSTEP_USER_ROOT
+ *
+ * returns 1 on success, 0 on failure
+ */
+int WMMkDirHier(char *path)
+{
+ char *t, *thePath = NULL, buf[1024];
+ size_t p, plen;
+ struct stat st;
+
+ /* Only create directories under $GNUSTEP_USER_ROOT */
+ if ((t = wusergnusteppath()) == NULL)
+ return 0;
+ if (strncmp(path, t, strlen(t)) != 0)
+ return 0;
+
+ thePath = wstrdup(path);
+ /* Strip the trailing component if it is a file */
+ p = strlen(thePath);
+ while (p && thePath[p] != '/')
+ thePath[p--] = '\0';
+
+ thePath[p] = '\0';
+
+ /* Shortcut if it already exists */
+ if (stat(thePath, &st) == 0) {
+ wfree(thePath);
+ if (S_ISDIR(st.st_mode)) {
+ /* Is a directory alright */
+ return 1;
+ } else {
+ /* Exists, but not a directory, the caller
+ * might just as well abort now */
+ return 0;
+ }
+ }
+
+ memset(buf, 0, sizeof(buf));
+ strncpy(buf, t, sizeof(buf) - 1);
+ p = strlen(buf);
+ plen = strlen(thePath);
+
+ do {
+ while (p++ < plen && thePath[p] != '/')
+ ;
+
+ strncpy(buf, thePath, p);
+ if (mkdir(buf, 0777) == -1) {
+ wsyserror(_("Could not create %s"), buf);
+ wfree(thePath);
+ return 0;
+ }
+ } while (p < plen);
+
+ wfree(thePath);
+ return 1;
+}
--
1.7.0