From e5e4d4931647c9c1c52ac92f817aaa0e9685b185 Mon Sep 17 00:00:00 2001
From: Chris Allegretta <chrisa@asty.org>
Date: Tue, 23 Jan 2001 03:09:15 +0000
Subject: [PATCH] Rocco's groovy fixes to real_dir_from_tilde

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@502 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
---
 ChangeLog |  2 +-
 files.c   | 50 ++++++++++++++++++++++++++------------------------
 2 files changed, 27 insertions(+), 25 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 738e90f4..92b723bd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -13,7 +13,7 @@ General
   username_tab_completion()
 	- Optimization and removal of useless vars (Rocco).
   real_dir_from_tilde()
-	- Rewritten using getpwent (suggested by Adam).
+	- Rewritten using getpwent (suggested by Adam, much optimized by Rocco).
 - global.c:
 	- Don't define toggles global or toggle_init_one if using --tiny.
 - nano.c:
diff --git a/files.c b/files.c
index d7a1719a..554429e6 100644
--- a/files.c
+++ b/files.c
@@ -582,49 +582,51 @@ int do_writeout_void(void)
  */
 char *real_dir_from_tilde(char *buf)
 {
-    char *dirtmp = NULL;
-    int searchctr = 1;
+    char *dirtmp = NULL, *find_user = NULL;
+    int i = 1;
     struct passwd *userdata;
 
+    /* set a default value for dirtmp, in the case user home dir not found */
+    dirtmp = mallocstrcpy(dirtmp, buf);
+
     if (buf[0] == '~') {
-	if (buf[1] == '~')
-	    goto abort;		/* Handle ~~ without segfaulting =) */
-	else if (buf[1] == 0 || buf[1] == '/') {
+	if (buf[1] == 0 || buf[1] == '/') {
 	    if (getenv("HOME") != NULL) {
+
+		free(dirtmp);
 		dirtmp = nmalloc(strlen(buf) + 2 + strlen(getenv("HOME")));
 
-		if (strlen(buf) > 2)
-		    sprintf(dirtmp, "%s/%s", getenv("HOME"), &buf[2]);
-		else
-		    sprintf(dirtmp, "%s/", getenv("HOME"));
+		sprintf(dirtmp, "%s%s", getenv("HOME"), &buf[1]);
 
 	    }
-	} else if (buf[1] != 0) {
+	}
+	else {
 
 	    /* Figure how how much of of the str we need to compare */
-	    for (searchctr = 1; buf[searchctr] != '/' &&
-		 buf[searchctr] != 0; searchctr++);
+	    for (i = 1; buf[i] != '/' && buf[i] != 0; i++)
+		;
+
+	    find_user = mallocstrcpy(find_user, &buf[1]);
+	    find_user[i - 1] = 0;
 
 	    for (userdata = getpwent(); userdata != NULL && 
-		  strncmp(userdata->pw_name, &buf[1], searchctr - 1); 
+		  strcmp(userdata->pw_name, find_user); 
 		  userdata = getpwent());
 
-	    if (userdata == NULL) /* No such user or getpwent() failed */
-		goto abort;
+	    free(find_user);
+
+	    if (userdata != NULL) {  /* User found */
 
-	    /* Else copy the new string into the new buf */
-	    dirtmp = nmalloc(strlen(buf) + 2 + strlen(userdata->pw_dir));
+	        free(dirtmp);
+		dirtmp = nmalloc(strlen(buf) + 2 + strlen(userdata->pw_dir));
+		sprintf(dirtmp, "%s%s", userdata->pw_dir, &buf[i]);
+
+	    }
 
-	    sprintf(dirtmp, "%s%s", userdata->pw_dir, &buf[searchctr]);
 	    endpwent();
 	}
-    } else
-	dirtmp = mallocstrcpy(dirtmp, buf);
-
-    return dirtmp;
+    }
 
-  abort:
-    dirtmp = mallocstrcpy(dirtmp, buf);
     return dirtmp;
 }
 
-- 
GitLab