Find below a patch that fixes a segfault when you attempt to save a new
Project in directory "/Project/project1" when "/Project" directory 
doesn't exist.  It implements a non-recursive
glade_util_ensure_directory_exists (in utils.c)
function which doesn't call glade_util_parent_directory, hence it would
obsolete glade_util_parent_directory which isn't called anywhere else in
glade.

Have fun,

John

--
John Wojtowicz, Secure Systems Engr.  ph:     (703) 318-7134
Trusted Computer Solutions, Inc.      fax:    (703) 318-5041
13873 Park Center Rd. Suite 225       e-mail: [EMAIL PROTECTED]
Herndon, VA 20171                     http://www.tcs-sec.com    

-- CUT--

--- utils.c     Thu Dec  7 15:51:39 2000
+++ utils.c.new Tue Dec 12 17:22:57 2000
@@ -1352,57 +1352,70 @@
 }
 
 
+/* Re-implemented in a non recursive manner. */
 GladeError*
 glade_util_ensure_directory_exists (const gchar *directory)
 {
+  gchar *realpath, *p;
   struct stat filestat;
 
-  if (stat (directory, &filestat) != 0)
+  /* Neither should happen, but be safe. */
+  if (directory == NULL || directory[0] == '\0') 
+     return glade_error_new_system (_("Couldn't create directory:\n  %s\n"), 
+         "<null>");
+
+  /* we're going to stomp on the string a bit, so we'll make a copy. */
+  realpath = g_strdup(directory);
+  if (realpath == NULL)
+    return glade_error_new_system (_("Couldn't create directory:\n  %s\n"), 
+         directory);
+
+  /* 
+   * We don't want to set the first character to '\0' so skip the 
+   * first character, on the chance that it is a G_DIR_SEPARATOR.
+   * 
+   * This should be just fine for _WIN32 as well.  We took care of the
+   * empty string (i.e. "") case above.
+   */
+  for (p = realpath + 1;;)
     {
-      /* If the directory doesn't exist, try to create it. */
-      if (errno == ENOENT)
-       {
-         GladeError *error;
-         gchar *parent_dir;
-
-         /* First make sure the parent directory exists. */
-         parent_dir = glade_util_parent_directory (directory);
-         error = glade_util_ensure_directory_exists (parent_dir);
-         g_free (parent_dir);
-         if (error)
-           return error;
 
+      /* Break the string at the next separator. */
+      p = strchr(p, G_DIR_SEPARATOR);
+      if (p != (char *) NULL)
+         *p = '\0';
+
+      /* if directory doesn't exist then attempt to make it. */
+      if (stat(realpath, &filestat) == -1)
+        {
 #ifdef _WIN32
-         if (mkdir (directory) != 0)
+         if (mkdir (realpath) != 0)
 #else
-         if (mkdir (directory, 0777) != 0)
-#endif
-           {
-#ifndef _WIN32
-/* This happens under WIN32 when stat is confused by the filename, but
this is
-   harmless, since we know that the directory exists after all. */
-             return glade_error_new_system (_("Couldn't create directory:\n
%s\n"), directory);
+         if (mkdir (realpath, 0777) != 0)
 #endif
-           }
-       }
-      else
-       {
-         return glade_error_new_system (_("Couldn't access directory:\n  %s\n"),
directory);
-       }
-    }
-#ifndef _WIN32
-  /* If the directory does exist, check it is a directory. */
-  else if (!S_ISDIR (filestat.st_mode))
-    {
-      return glade_error_new_general (GLADE_STATUS_INVALID_DIRECTORY,
-                                     _("Invalid directory:\n  %s\n"),
-                                     directory);
+            {
+              free(realpath);
+
+              return glade_error_new_system (_("Couldn't create
directory:\n  %s\n"), 
+                   strerror(errno));
+            }
+        } 
+
+        /* 
+         * If we don't have any more sub-directories to make then break,
+         * otherwise add the separator back into the string, and continue
+         * on to make the next lower level sub-directory.
+         */
+        if (p == (char *) NULL)
+          break;
+        else
+          *p++ = G_DIR_SEPARATOR;
     }
-#endif
 
-  return NULL;
-}
+    free(realpath);
 
+    return NULL;
+}
 
 /* Adds a filename onto a directory to make a complete pathname.
    The directory may or may not end in '/'. file must be a simple filename.
@@ -1703,38 +1716,6 @@
   base[len] = 0;
   
   return base;
-}
-
-
-/* This returns the parent directory of the given directory, which may or may
-   not end in a G_DIR_SEPARATOR. If there is no parent directory, NULL is
-   returned. The returned string should be freed. dir MUST be absolute. */
-gchar*
-glade_util_parent_directory    (const gchar        *dir)
-{
-  gchar *skipped_root, *parent_dir;
-  gint pos;
-
-  /* We handle the root dir specially. */
-  skipped_root = g_path_skip_root ((gchar*) dir);
-  if (*skipped_root == '\0')
-    return NULL;
-
-  /* Ignore any G_DIR_SEPARATOR at the end of dir (just by skipping the last
-     char), and step back to the previous G_DIR_SEPARATOR. */
-  pos = strlen (dir) - 2;
-  while (pos >= 0 && dir[pos] != G_DIR_SEPARATOR)
-    pos--;
-
-  /* This shouldn't really happen, since we dealt with the root dir above,
-     but just in case. */
-  if (pos < 0)
-    return NULL;
-
-  parent_dir = g_malloc (pos + 1);
-  strncpy (parent_dir, dir, pos);
-  parent_dir[pos] = '\0';
-  return parent_dir;
 }
--
John Wojtowicz, Secure Systems Engr.  ph:     (703) 318-7134
Trusted Computer Solutions, Inc.      fax:    (703) 318-5041
13873 Park Center Rd. Suite 225       e-mail: [EMAIL PROTECTED]
Herndon, VA 20171                     http://www.tcs-sec.com    

_______________________________________________
Glade-devel maillist  -  [EMAIL PROTECTED]
http://lists.helixcode.com/mailman/listinfo/glade-devel

Reply via email to