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
