]> git.wh0rd.org Git - nano.git/commitdiff
in get_full_path(), don't return NULL when the current directory doesn't
authorDavid Lawrence Ramsey <pooka109@gmail.com>
Wed, 5 Jul 2006 14:14:06 +0000 (14:14 +0000)
committerDavid Lawrence Ramsey <pooka109@gmail.com>
Wed, 5 Jul 2006 14:14:06 +0000 (14:14 +0000)
exist, as we can still recover from that, and also add various cleanups

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@3752 35c25a1d-7b9e-4130-9fde-d3aeb78583b8

ChangeLog
src/files.c

index 94a71b5968bffc34f64d1e11052458997d8a15b7..137b5f2208f9c25db541245c4714daf963645af7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -55,6 +55,11 @@ CVS code -
          allocated, use null_at() to strip the directory from the
          string.  Also, return the stripped path instead of modifying
          path. (DLR)
+- files.c:
+  get_full_path()
+       - Don't return NULL when the current directory doesn't exist, as
+         we can still recover from that. (DLR, found by Mike Frysinger)
+       - Add various cleanups. (DLR)
 - help.c:
   do_help()
        - Simplify screen update handling and exiting. (DLR)
index 716ffa890732e9f5ea2000cbec5a6378e5e5c3bb..82f4f4e86ac77abefd8713f4e375f9f52ddc4536 100644 (file)
@@ -902,21 +902,28 @@ void do_insertfile_void(void)
  * able to go there. */
 char *get_full_path(const char *origpath)
 {
-    char *d_here, *d_there = NULL;
+    struct stat fileinfo;
+    char *d_here, *d_there, *d_there_file = NULL;
+    const char *last_slash;
+    bool path_only;
 
     if (origpath == NULL)
        return NULL;
 
-    /* Get the current directory. */
+    /* Get the current directory.  If it doesn't exist, back up and try
+     * again until we get a directory that does exist. */
     d_here = charalloc(PATH_MAX + 1);
     d_here = getcwd(d_here, PATH_MAX + 1);
 
-    if (d_here != NULL) {
-       const char *last_slash;
-       char *d_there_file = NULL;
-       bool path_only;
-       struct stat fileinfo;
+    while (d_here == NULL) {
+       if (chdir("..") == -1)
+           break;
+
+       d_here = getcwd(d_here, PATH_MAX + 1);
+    }
 
+    /* If we succeeded, canonicalize it in d_here. */
+    if (d_here != NULL) {
        align(&d_here);
 
        /* If the current directory isn't "/", tack a slash onto the end
@@ -925,89 +932,91 @@ char *get_full_path(const char *origpath)
            d_here = charealloc(d_here, strlen(d_here) + 2);
            strcat(d_here, "/");
        }
+    /* Otherwise, set d_here to "". */
+    } else
+       d_here = mallocstrcpy(NULL, "");
 
-       d_there = real_dir_from_tilde(origpath);
+    d_there = real_dir_from_tilde(origpath);
 
-       assert(d_there != NULL);
+    assert(d_there != NULL);
 
-       /* Stat d_there.  If stat() fails, assume that d_there refers to
-        * a new file that hasn't been saved to disk yet.  Set path_only
-        * to TRUE if d_there refers to a directory, and FALSE if
-        * d_there refers to a file. */
-       path_only = !stat(d_there, &fileinfo) &&
-               S_ISDIR(fileinfo.st_mode);
+    /* If stat()ing d_there fails, assume that d_there refers to a new
+     * file that hasn't been saved to disk yet.  Set path_only to TRUE
+     * if d_there refers to a directory, and FALSE otherwise. */
+    path_only = stat(d_there, &fileinfo) == 0 &&
+       S_ISDIR(fileinfo.st_mode);
 
-       /* If path_only is TRUE, make sure d_there ends in a slash. */
-       if (path_only) {
-           size_t d_there_len = strlen(d_there);
+    /* If path_only is TRUE, make sure d_there ends in a slash. */
+    if (path_only) {
+       size_t d_there_len = strlen(d_there);
 
-           if (d_there[d_there_len - 1] != '/') {
-               d_there = charealloc(d_there, d_there_len + 2);
-               strcat(d_there, "/");
-           }
+       if (d_there[d_there_len - 1] != '/') {
+           d_there = charealloc(d_there, d_there_len + 2);
+           strcat(d_there, "/");
        }
+    }
 
-       /* Search for the last slash in d_there. */
-       last_slash = strrchr(d_there, '/');
+    /* Search for the last slash in d_there. */
+    last_slash = strrchr(d_there, '/');
 
-       /* If we didn't find one, then make sure the answer is in the
-        * format "d_here/d_there". */
-       if (last_slash == NULL) {
-           assert(!path_only);
+    /* If we didn't find one, then make sure the answer is in the format
+     * "d_here/d_there". */
+    if (last_slash == NULL) {
+       assert(!path_only);
 
-           d_there_file = d_there;
-           d_there = d_here;
+       d_there_file = d_there;
+       d_there = d_here;
+    } else {
+       /* If path_only is FALSE, then save the filename portion of the
+        * answer (everything after the last slash) in d_there_file. */
+       if (!path_only)
+           d_there_file = mallocstrcpy(NULL, last_slash + 1);
+
+       /* And remove the filename portion of the answer from
+        * d_there. */
+       null_at(&d_there, last_slash - d_there + 1);
+
+       /* chdir() to the path specified in d_there. */
+       if (chdir(d_there) == -1) {
+           free(d_there);
+           d_there = NULL;
        } else {
-           /* If path_only is FALSE, then save the filename portion of
-            * the answer, everything after the last slash, in
-            * d_there_file. */
-           if (!path_only)
-               d_there_file = mallocstrcpy(NULL, last_slash + 1);
-
-           /* And remove the filename portion of the answer from
-            * d_there. */
-           null_at(&d_there, last_slash - d_there + 1);
-
-           /* Go to the path specified in d_there. */
-           if (chdir(d_there) == -1) {
-               free(d_there);
-               d_there = NULL;
-           } else {
-               /* Get the full path and save it in d_there. */
-               free(d_there);
+           free(d_there);
 
-               d_there = charalloc(PATH_MAX + 1);
-               d_there = getcwd(d_there, PATH_MAX + 1);
+           /* Get the full path. */
+           d_there = charalloc(PATH_MAX + 1);
+           d_there = getcwd(d_there, PATH_MAX + 1);
 
-               if (d_there != NULL) {
-                   align(&d_there);
+           /* If we succeeded, canonicalize it in d_there. */
+           if (d_there != NULL) {
+               align(&d_there);
 
-                   if (strcmp(d_there, "/") != 0) {
-                       /* Make sure d_there ends in a slash. */
-                       d_there = charealloc(d_there,
-                               strlen(d_there) + 2);
-                       strcat(d_there, "/");
-                   }
-               } else
-                   /* If we couldn't get the full path, set path_only
-                    * to TRUE so that we clean up correctly, free all
-                    * allocated memory, and return NULL. */
-                   path_only = TRUE;
-
-               /* Finally, go back to the path specified in d_here,
-                * where we were before. */
-               chdir(d_here);
-           }
+               /* If the current directory isn't "/", tack a slash onto
+                * the end of it. */
+               if (strcmp(d_there, "/") != 0) {
+                   d_there = charealloc(d_there, strlen(d_there) + 2);
+                   strcat(d_there, "/");
+               }
+           } else
+               /* Otherwise, set path_only to TRUE, so that we clean up
+                * correctly, free all allocated memory, and return
+                * NULL. */
+               path_only = TRUE;
+
+           /* Finally, go back to the path specified in d_here,
+            * where we were before.  We don't check for a chdir()
+            * error, since we can do nothing then. */
+           chdir(d_here);
 
            /* Free d_here, since we're done using it. */
            free(d_here);
        }
 
-       /* At this point, if path_only is FALSE and d_there exists,
+       /* At this point, if path_only is FALSE and d_there isn't NULL,
         * d_there contains the path portion of the answer and
         * d_there_file contains the filename portion of the answer.  If
-        * this is the case, tack d_there_file onto the end of
-        * d_there, so that d_there contains the complete answer. */
+        * this is the case, tack the latter onto the end of the former.
+        * d_there will then contain the complete answer. */
        if (!path_only && d_there != NULL) {
            d_there = charealloc(d_there, strlen(d_there) +
                strlen(d_there_file) + 1);