about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorThomas E. Dickey <dickey@invisible-island.net>2006-11-13 01:11:22 -0500
committerThomas E. Dickey <dickey@invisible-island.net>2006-11-13 01:11:22 -0500
commit9bdb7e3f3d8fb762919e6d55aaea5e7263dd970d (patch)
tree5ca794151f77eca9b75b3c9ac8d51c29274cb0de /src
parentf255f8da2e6a2a8b53639ea2264d5db3c3760b23 (diff)
downloadlynx-snapshots-9bdb7e3f3d8fb762919e6d55aaea5e7263dd970d.tar.gz
snapshot of project "lynx", label v2-8-7dev_3
Diffstat (limited to 'src')
-rw-r--r--src/HTInit.c14
-rw-r--r--src/LYGetFile.c40
-rw-r--r--src/LYLocal.c32
-rw-r--r--src/LYMain.c48
-rw-r--r--src/LYMainLoop.c6
-rw-r--r--src/LYOptions.c10
-rw-r--r--src/LYReadCFG.c12
-rw-r--r--src/LYStrings.c18
-rw-r--r--src/LYUtils.c102
-rw-r--r--src/LYUtils.h7
10 files changed, 149 insertions, 140 deletions
diff --git a/src/HTInit.c b/src/HTInit.c
index 2691bb8a..6ede0f3f 100644
--- a/src/HTInit.c
+++ b/src/HTInit.c
@@ -161,15 +161,10 @@ void HTFormatInit(void)
     /*
      * Load the local maps.
      */
-    if (IsOurFile(personal_type_map)
+    if (IsOurFile(LYAbsOrHomePath(&personal_type_map))
 	&& LYCanReadFile(personal_type_map)) {
 	/* These should override everything else. */
 	HTLoadTypesConfigFile(personal_type_map, mediaUSR);
-    } else {
-	char buffer[LY_MAXPATH];
-
-	LYAddPathToHome(buffer, sizeof(buffer), personal_type_map);
-	HTLoadTypesConfigFile(buffer, mediaUSR);
     }
 
     /*
@@ -1341,15 +1336,10 @@ void HTFileInit(void)
     /*
      * Load the local maps.
      */
-    if (IsOurFile(personal_extension_map)
+    if (IsOurFile(LYAbsOrHomePath(&personal_extension_map))
 	&& LYCanReadFile(personal_extension_map)) {
 	/* These should override everything else. */
 	HTLoadExtensionsConfigFile(personal_extension_map);
-    } else {
-	char buffer[LY_MAXPATH];
-
-	LYAddPathToHome(buffer, sizeof(buffer), personal_extension_map);
-	HTLoadExtensionsConfigFile(buffer);
     }
 }
 
diff --git a/src/LYGetFile.c b/src/LYGetFile.c
index 248ffa17..b3429fa3 100644
--- a/src/LYGetFile.c
+++ b/src/LYGetFile.c
@@ -465,15 +465,9 @@ int getfile(DocInfo *doc, int *target)
 		/*
 		 * Convert '~' to $HOME.
 		 */
-		if ((cp = strchr(doc->address, '~'))) {
-		    HTSprintf0(&p, "%.*s%s%s",
-			       cp - doc->address,
-			       doc->address,
-			       wwwName(Home_Dir()),
-			       cp + 1);
-		} else {
-		    StrAllocCopy(p, doc->address);
-		}
+		StrAllocCopy(p, doc->address);
+		LYTildeExpand(&p, TRUE);
+
 		/*
 		 * Show URL before executing it.
 		 */
@@ -785,33 +779,7 @@ int getfile(DocInfo *doc, int *target)
 	     * was entered, simplifying, and eliminating any residual
 	     * relative elements.  - FM
 	     */
-	    if (((cp = HTParse(doc->address, "",
-			       PARSE_PATH + PARSE_ANCHOR + PARSE_PUNCTUATION))
-		 != NULL) &&
-		!strncmp(cp, "/~", 2)) {
-		char *cp1 = strstr(doc->address, "/~");
-		char *cp2;
-
-		CTRACE((tfp, "getfile: URL '%s'\n",
-			doc->address));
-		*cp1 = '\0';
-		cp1 += 2;
-		StrAllocCopy(temp, doc->address);
-		StrAllocCopy(cp, wwwName(Home_Dir()));
-		if (!LYIsHtmlSep(*cp))
-		    LYAddHtmlSep(&temp);
-		StrAllocCat(temp, cp);
-		if ((cp2 = strchr(cp1, '/')) != NULL) {
-		    LYTrimRelFromAbsPath(cp2);
-		    StrAllocCat(temp, cp2);
-		}
-		StrAllocCopy(doc->address, temp);
-		FREE(temp);
-		CTRACE((tfp, "  changed to '%s'\n",
-			doc->address));
-		WWWDoc.address = doc->address;
-	    }
-	    FREE(cp);
+	    LYTildeExpand(&(doc->address), TRUE);
 	}
 	CTRACE_SLEEP(MessageSecs);
 	user_message(WWW_WAIT_MESSAGE, doc->address);
diff --git a/src/LYLocal.c b/src/LYLocal.c
index 7eb77c70..dc705be4 100644
--- a/src/LYLocal.c
+++ b/src/LYLocal.c
@@ -734,7 +734,7 @@ static int modify_tagged(char *testpath)
 	/*
 	 * Replace ~/ references to the home directory.
 	 */
-	if (!strncmp(tmpbuf, "~/", 2)) {
+	if (LYIsTilde(tmpbuf[0]) && LYIsPathSep(tmpbuf[1])) {
 	    char *cp1 = NULL;
 
 	    StrAllocCopy(cp1, Home_Dir());
@@ -913,8 +913,8 @@ static int modify_location(char *testpath)
 	/*
 	 * Allow ~/ references to the home directory.
 	 */
-	if (!strncmp(tmpbuf, "~/", 2)
-	    || !strcmp(tmpbuf, "~")) {
+	if (LYIsTilde(tmpbuf[0])
+	    && (tmpbuf[1] == '\0' || LYIsPathSep(tmpbuf[1]))) {
 	    StrAllocCopy(newpath, Home_Dir());
 	    StrAllocCat(newpath, (tmpbuf + 1));
 	    LYstrncpy(tmpbuf, newpath, sizeof(tmpbuf) - 1);
@@ -1029,6 +1029,10 @@ int local_modify(DocInfo *doc, char **newpath)
     return 0;
 }
 
+#define BadChars() ((!no_dotfiles && show_dotfiles) \
+		    ? "~/" \
+		    : ".~/")
+
 /*
  * Create a new empty file in the current directory.
  */
@@ -1037,19 +1041,14 @@ static int create_file(char *current_location)
     int code = FALSE;
     char tmpbuf[DIRED_MAXBUF];
     char *testpath = NULL;
-    const char *bad_chars = ".~/";
 
     tmpbuf[0] = '\0';
     if (get_filename(gettext("Enter name of file to create: "),
 		     tmpbuf, sizeof(tmpbuf)) != NULL) {
 
-	if (!no_dotfiles && show_dotfiles) {
-	    bad_chars = "~/";
-	}
-
 	if (strstr(tmpbuf, "//") != NULL) {
 	    HTAlert(gettext("Illegal redirection \"//\" found! Request ignored."));
-	} else if (strlen(tmpbuf) && strchr(bad_chars, tmpbuf[0]) == NULL) {
+	} else if (strlen(tmpbuf) && strchr(BadChars(), tmpbuf[0]) == NULL) {
 	    StrAllocCopy(testpath, current_location);
 	    LYAddPathSep(&testpath);
 
@@ -1078,19 +1077,14 @@ static int create_directory(char *current_location)
     int code = FALSE;
     char tmpbuf[DIRED_MAXBUF];
     char *testpath = NULL;
-    const char *bad_chars = ".~/";
 
     tmpbuf[0] = '\0';
     if (get_filename(gettext("Enter name for new directory: "),
 		     tmpbuf, sizeof(tmpbuf)) != NULL) {
 
-	if (!no_dotfiles && show_dotfiles) {
-	    bad_chars = "~/";
-	}
-
 	if (strstr(tmpbuf, "//") != NULL) {
 	    HTAlert(gettext("Illegal redirection \"//\" found! Request ignored."));
-	} else if (strlen(tmpbuf) && strchr(bad_chars, tmpbuf[0]) == NULL) {
+	} else if (strlen(tmpbuf) && strchr(BadChars(), tmpbuf[0]) == NULL) {
 	    StrAllocCopy(testpath, current_location);
 	    LYAddPathSep(&testpath);
 
@@ -2280,11 +2274,11 @@ BOOLEAN local_install(char *destpath,
     }
 
     /* deal with ~/ or /~/ at the beginning - kw */
-    if (destpath[0] == '~' &&
-	(destpath[1] == '/' || destpath[1] == '\0')) {
+    if (LYIsTilde(destpath[0]) &&
+	(LYIsPathSep(destpath[1]) || destpath[1] == '\0')) {
 	cp = &destpath[1];
-    } else if (destpath[0] == '/' && destpath[1] == '~' &&
-	       (destpath[2] == '/' || destpath[2] == '\0')) {
+    } else if (LYIsPathSep(destpath[0]) && LYIsTilde(destpath[1]) &&
+	       (LYIsPathSep(destpath[2]) || destpath[2] == '\0')) {
 	cp = &destpath[2];
     }
     if (cp) {
diff --git a/src/LYMain.c b/src/LYMain.c
index 4c0916dc..ff13d362 100644
--- a/src/LYMain.c
+++ b/src/LYMain.c
@@ -856,37 +856,6 @@ static void FixCharacters(void)
 }
 #endif /* EBCDIC */
 
-static void tildeExpand(char **pathname,
-			BOOLEAN embedded)
-{
-    char *temp = *pathname;
-
-    if (embedded) {
-	if (temp != NULL) {
-	    temp = strstr(*pathname, "/~");
-	    if (temp != 0)
-		temp++;
-	    else
-		temp = *pathname;
-	}
-    }
-
-    if (temp != NULL
-	&& temp[0] == '~') {
-	if (temp[1] == '/'
-	    && temp[2] != '\0') {
-	    temp = NULL;
-	    StrAllocCopy(temp, *pathname + 2);
-	    StrAllocCopy(*pathname, wwwName(Home_Dir()));
-	    LYAddPathSep(pathname);
-	    StrAllocCat(*pathname, temp);
-	    FREE(temp);
-	} else if (temp[1] == '\0') {
-	    StrAllocCopy(*pathname, wwwName(Home_Dir()));
-	}
-    }
-}
-
 static BOOL GetStdin(char **buf,
 		     BOOL marker)
 {
@@ -967,6 +936,7 @@ static void SetLocale(void)
 #if defined(HAVE_LIBINTL_H) || defined(HAVE_LIBGETTEXT_H)
     {
 	char *cp;
+
 	if ((cp = LYGetEnv("LYNX_LOCALEDIR")) == 0)
 	    cp = LOCALEDIR;
 	bindtextdomain("lynx", cp);
@@ -1213,7 +1183,7 @@ int main(int argc,
 #ifdef WIN_EX			/* for Windows 2000 ... 1999/08/23 (Mon) 08:24:35 */
     if (access(lynx_temp_space, 0) != 0)
 #endif
-	tildeExpand(&lynx_temp_space, TRUE);
+	LYTildeExpand(&lynx_temp_space, TRUE);
 
     if ((cp = strstr(lynx_temp_space, "$USER")) != NULL) {
 	char *cp1;
@@ -1411,14 +1381,14 @@ int main(int argc,
      * Open command-script, if specified
      */
     if (lynx_cmd_script != 0) {
-	tildeExpand(&lynx_cmd_script, TRUE);
+	LYTildeExpand(&lynx_cmd_script, TRUE);
 	LYOpenCmdScript();
     }
     /*
      * Open command-logging, if specified
      */
     if (lynx_cmd_logfile != 0) {
-	tildeExpand(&lynx_cmd_logfile, TRUE);
+	LYTildeExpand(&lynx_cmd_logfile, TRUE);
 	LYOpenCmdLogfile(argc, argv);
     }
 #endif
@@ -1457,7 +1427,7 @@ int main(int argc,
 	StrAllocCopy(lynx_cfg_file, LYNX_CFG_FILE);
 
 #ifndef _WINDOWS		/* avoid the whole ~ thing for now */
-    tildeExpand(&lynx_cfg_file, FALSE);
+    LYTildeExpand(&lynx_cfg_file, FALSE);
 #endif
 
     /*
@@ -1574,7 +1544,7 @@ int main(int argc,
     if (!lynx_lss_file)
 	StrAllocCopy(lynx_lss_file, LYNX_LSS_FILE);
 
-    tildeExpand(&lynx_lss_file, TRUE);
+    LYTildeExpand(&lynx_lss_file, TRUE);
 
     /*
      * If the lynx-style file is not available, inform the user and exit.
@@ -1692,14 +1662,14 @@ int main(int argc,
 
 	    LYAddPathToHome(LYCookieFile, LY_MAXPATH, COOKIE_FILE);
 	} else {
-	    tildeExpand(&LYCookieFile, FALSE);
+	    LYTildeExpand(&LYCookieFile, FALSE);
 	}
 	LYLoadCookies(LYCookieFile);
     }
 
     /* tilde-expand LYCookieSaveFile */
     if (LYCookieSaveFile != NULL) {
-	tildeExpand(&LYCookieSaveFile, FALSE);
+	LYTildeExpand(&LYCookieSaveFile, FALSE);
     }
 
     /*
@@ -1738,7 +1708,7 @@ int main(int argc,
 	FREE(lynx_save_space);
     }
     if (lynx_save_space) {
-	tildeExpand(&lynx_save_space, TRUE);
+	LYTildeExpand(&lynx_save_space, TRUE);
 #ifdef VMS
 	LYLowerCase(lynx_save_space);
 	if (strchr(lynx_save_space, '/') != NULL) {
diff --git a/src/LYMainLoop.c b/src/LYMainLoop.c
index 226e565f..38440fda 100644
--- a/src/LYMainLoop.c
+++ b/src/LYMainLoop.c
@@ -1736,7 +1736,7 @@ static void handle_LYK_COMMENT(BOOLEAN *refresh_screen,
 
 		if (temp != NULL) {
 		    HTUnEscape(temp);
-		    if (*temp == '~' && strlen(temp) > 1) {
+		    if (LYIsTilde(*temp) && strlen(temp) > 1) {
 			/*
 			 * It's a ~user URL so guess user@host.  - FM
 			 */
@@ -5008,9 +5008,7 @@ void handle_LYK_CHDIR(void)
 	return;
     }
 
-    if (*buf == '~' && !buf[1]) {
-	StrAllocCopy(p, Home_Dir());
-    } else if (*buf == '~') {
+    if (LYIsTilde(*buf) && (LYIsPathSep(buf[1]) || buf[1] == '\0')) {
 	HTSprintf0(&p, "%s%s", Home_Dir(), buf + 1);
     } else {
 	StrAllocCopy(p, buf);
diff --git a/src/LYOptions.c b/src/LYOptions.c
index bbbd49ee..c5776a42 100644
--- a/src/LYOptions.c
+++ b/src/LYOptions.c
@@ -336,7 +336,7 @@ void LYoptions(void)
     /*
      * If the user changes the display we need memory to put it in.
      */
-    char display_option[256];
+    char display_option[MAX_LINE];
     char *choices[MAXCHOICES];
     int CurrentCharSet = current_char_set;
     int CurrentAssumeCharSet = UCLYhndl_for_unspec;
@@ -1772,8 +1772,7 @@ void edit_bookmarks(void)
 
 #define MULTI_OFFSET 8
     int a;			/* misc counter */
-    char MBM_tmp_line[256];	/* buffer for LYgetstr */
-    char ehead_buffer[265];
+    char MBM_tmp_line[LY_MAXPATH];	/* buffer for LYgetstr */
 
     /*
      * We need (MBM_V_MAXFILES + MULTI_OFFSET) lines to display the whole list
@@ -1801,8 +1800,11 @@ void edit_bookmarks(void)
     LYmove(0, 5);
     lynx_start_h1_color();
     if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) {
-	sprintf(ehead_buffer, MULTIBOOKMARKS_EHEAD_MASK, MBM_current);
+	char *ehead_buffer = 0;
+
+	HTSprintf0(&ehead_buffer, MULTIBOOKMARKS_EHEAD_MASK, MBM_current);
 	LYaddstr(ehead_buffer);
+	FREE(ehead_buffer);
     } else {
 	LYaddstr(MULTIBOOKMARKS_EHEAD);
     }
diff --git a/src/LYReadCFG.c b/src/LYReadCFG.c
index b34041e0..3ed09d89 100644
--- a/src/LYReadCFG.c
+++ b/src/LYReadCFG.c
@@ -801,12 +801,10 @@ static int cern_rulesfile_fun(char *value)
     StrAllocCopy(rulesfile1, value);
     LYTrimLeading(value);
     LYTrimTrailing(value);
-    if (!strncmp(value, "~/", 2)) {
-	StrAllocCopy(rulesfile2, Home_Dir());
-	StrAllocCat(rulesfile2, value + 1);
-    } else {
-	StrAllocCopy(rulesfile2, value);
-    }
+
+    StrAllocCopy(rulesfile2, value);
+    LYTildeExpand(&rulesfile2, FALSE);
+
     if (strcmp(rulesfile1, rulesfile2) &&
 	HTLoadRules(rulesfile2) >= 0) {
 	FREE(rulesfile1);
@@ -1650,7 +1648,7 @@ static char *actual_filename(const char *cfg_filename,
 
     if (!LYisAbsPath(cfg_filename)
 	&& !(parent_filename == 0 && LYCanReadFile(cfg_filename))) {
-	if (!strncmp(cfg_filename, "~/", 2)) {
+	if (LYIsTilde(cfg_filename[0]) && LYIsPathSep(cfg_filename[1])) {
 	    HTSprintf0(&my_filename, "%s%s", Home_Dir(), cfg_filename + 1);
 	} else {
 	    if (parent_filename != 0) {
diff --git a/src/LYStrings.c b/src/LYStrings.c
index aa8d3baa..ca9e18c5 100644
--- a/src/LYStrings.c
+++ b/src/LYStrings.c
@@ -731,6 +731,7 @@ int LYmbcsstrlen(const char *str,
 static int myGetCharNodelay(void)
 {
     int c = wgetch(LYwin);
+
     if (c == -1)
 	c = 0;
 
@@ -1665,6 +1666,7 @@ static int LYgetch_for(int code)
  * LYgetch() translates some escape sequences and may fake noecho.
  */
 #define found_CSI(first,second) ((second) == '[' || (first) == 155)
+#define found_TLD(value)	((value) == '~')
 
 static int LYgetch_for(int code)
 {
@@ -1880,18 +1882,18 @@ static int LYgetch_for(int code)
 		c = '0';	/* keypad 0 */
 	    break;
 	case '1':		/* VTxxx  Find  */
-	    if (found_CSI(c, b) && (d = GetChar()) == '~')
+	    if (found_CSI(c, b) && found_TLD(d = GetChar()))
 		c = FIND_KEY;
 	    else
 		done_esc = FALSE;	/* we have another look below - kw */
 	    break;
 	case '2':
 	    if (found_CSI(c, b)) {
-		if ((d = GetChar()) == '~')	/* VTxxx Insert */
+		if (found_TLD(d = GetChar()))	/* VTxxx Insert */
 		    c = INSERT_KEY;
 		else if ((d == '8' ||
 			  d == '9') &&
-			 GetChar() == '~') {
+			 found_TLD(GetChar())) {
 		    if (d == '8')	/* VTxxx   Help */
 			c = F1;
 		    else if (d == '9')	/* VTxxx    Do  */
@@ -1902,25 +1904,25 @@ static int LYgetch_for(int code)
 		done_esc = FALSE;	/* we have another look below - kw */
 	    break;
 	case '3':			     /** VTxxx Delete **/
-	    if (found_CSI(c, b) && (d = GetChar()) == '~')
+	    if (found_CSI(c, b) && found_TLD(d = GetChar()))
 		c = REMOVE_KEY;
 	    else
 		done_esc = FALSE;	/* we have another look below - kw */
 	    break;
 	case '4':			     /** VTxxx Select **/
-	    if (found_CSI(c, b) && (d = GetChar()) == '~')
+	    if (found_CSI(c, b) && found_TLD(d = GetChar()))
 		c = SELECT_KEY;
 	    else
 		done_esc = FALSE;	/* we have another look below - kw */
 	    break;
 	case '5':			     /** VTxxx PrevScreen **/
-	    if (found_CSI(c, b) && (d = GetChar()) == '~')
+	    if (found_CSI(c, b) && found_TLD(d = GetChar()))
 		c = PGUP;
 	    else
 		done_esc = FALSE;	/* we have another look below - kw */
 	    break;
 	case '6':			     /** VTxxx NextScreen **/
-	    if (found_CSI(c, b) && (d = GetChar()) == '~')
+	    if (found_CSI(c, b) && found_TLD(d = GetChar()))
 		c = PGDOWN;
 	    else
 		done_esc = FALSE;	/* we have another look below - kw */
@@ -1944,7 +1946,7 @@ static int LYgetch_for(int code)
 	    CTRACE_SLEEP(MessageSecs);
 	    break;
 	}
-	if (isdigit(a) && found_CSI(c, b) && d != -1 && d != '~')
+	if (isdigit(a) && found_CSI(c, b) && d != -1 && !found_TLD(d))
 	    d = GetChar();
 	if (!done_esc && (a & ~0xFF) == 0) {
 	    if (a == b && !found_CSI(c, b) && c == CH_ESC) {
diff --git a/src/LYUtils.c b/src/LYUtils.c
index 356b61b9..c4b3a9f1 100644
--- a/src/LYUtils.c
+++ b/src/LYUtils.c
@@ -2762,7 +2762,7 @@ BOOLEAN inlocaldomain(void)
     char *cp, *mytty = NULL;
 
     if ((cp = ttyname(0)))
-	mytty = strrchr(cp, '/');
+	mytty = LYLastPathSep(cp);
 
     if (mytty && (fp = fopen(UTMP_FILE, "r")) != NULL) {
 	mytty++;
@@ -3974,7 +3974,7 @@ void LYConvertToURL(char **AllocatedString,
 
 	$DESCRIPTOR(url_file_dsc, url_file);
 	$DESCRIPTOR(file_name_dsc, file_name);
-	if (*old_string == '~') {
+	if (LYIsTilde(*old_string)) {
 	    /*
 	     * On VMS, we'll accept '~' on the command line as Home_Dir(), and
 	     * assume the rest of the path, if any, has SHELL syntax.
@@ -4142,7 +4142,7 @@ void LYConvertToURL(char **AllocatedString,
 #endif
 	else
 #endif /* USE_DOS_DRIVES */
-	if (*old_string == '~') {
+	if (LYIsTilde(*old_string)) {
 	    /*
 	     * On Unix, convert '~' to Home_Dir().
 	     */
@@ -4371,7 +4371,7 @@ void LYConvertToURL(char **AllocatedString,
 	    CTRACE((tfp, "Converted '%s' to '%s'\n",
 		    old_string, *AllocatedString));
 #endif /* VMS */
-	} else if (old_string[1] == '~') {
+	} else if (LYIsTilde(old_string[1])) {
 	    /*
 	     * Has a Home_Dir() reference.  Handle it as if there weren't a
 	     * lead slash.  - FM
@@ -5197,9 +5197,9 @@ BOOLEAN LYPathOffHomeOK(char *fbuffer,
 	}
     }
 #endif /* VMS */
-    if (*cp == '~') {
-	if (*(cp + 1) == '/') {
-	    if (*(cp + 2) != '\0') {
+    if (LYIsTilde(cp[0])) {
+	if (LYIsPathSep(cp[1])) {
+	    if (cp[2] != '\0') {
 		if ((cp1 = strchr((cp + 2), '/')) != NULL) {
 		    /*
 		     * Convert "~/subdir(s)/file" to "./subdir(s)/file".  - FM
@@ -5317,6 +5317,89 @@ BOOLEAN LYPathOffHomeOK(char *fbuffer,
 }
 
 /*
+ * Search for a leading tilde, optionally embedded.  If found, return a pointer
+ * to the tilde.  If not found, return the original parameter.
+ */
+static char *FindLeadingTilde(char *pathname, BOOL embedded)
+{
+    char *result = pathname;
+
+    if (pathname != NULL) {
+	if (embedded) {
+	    while (pathname[0] != '\0') {
+		if (LYIsPathSep(pathname[0])) {
+		    if (LYIsTilde(pathname[1])) {
+			++pathname;
+			break;
+		    }
+		}
+		++pathname;
+	    }
+	}
+	if (LYIsTilde(*pathname))
+	    result = pathname;
+    }
+    return result;
+}
+
+/*
+ * Convert a non-absolute path to one which is off the home directory.  Expand
+ * tildes as a side-effect.  Return a pointer to the converted result.
+ */
+char *LYAbsOrHomePath(char **fname)
+{
+    if (!LYisAbsPath(*fname)) {
+	if (LYIsTilde((*fname)[0])) {
+	    LYTildeExpand(fname, FALSE);
+	} else {
+	    char temp[LY_MAXPATH];
+
+	    LYAddPathToHome(temp, sizeof(temp), *fname);
+	    StrAllocCopy(*fname, temp);
+	}
+    }
+    return *fname;
+}
+
+/*
+ * Expand a "leading" tilde into the user's home directory in WWW format.  If
+ * "embedded" is true, allow that "leading" tilde to follow a path separator.
+ */
+char *LYTildeExpand(char **pathname,
+		    BOOL embedded)
+{
+    char *temp = FindLeadingTilde(*pathname, embedded);
+
+    if (temp != NULL
+	&& LYIsTilde(temp[0])) {
+
+	CTRACE((tfp, "LYTildeExpand %s\n", *pathname));
+	if (LYIsPathSep(temp[1])
+	    && temp[2] != '\0') {
+	    char *first = NULL;
+	    char *second = NULL;
+
+	    StrAllocCopy(first, *pathname);
+	    first[temp - *pathname] = '\0';
+
+	    StrAllocCopy(second, temp + 2);
+
+	    StrAllocCopy(*pathname, first);
+	    StrAllocCat(*pathname, wwwName(Home_Dir()));
+	    LYAddPathSep(pathname);
+	    StrAllocCat(*pathname, second);
+
+	    FREE(first);
+	    FREE(second);
+	} else if (temp[1] == '\0') {
+	    StrAllocCopy(*pathname, wwwName(Home_Dir()));
+	}
+	CTRACE((tfp, "expanded path %s\n", *pathname));
+    }
+    return *pathname;
+}
+
+/*
  * This function appends fname to the home path and returns the full path and
  * filename.  The fname string can be just a filename (e.g.,
  * "lynx_bookmarks.html"), or include a subdirectory off the home directory, in
@@ -5800,7 +5883,8 @@ BOOL IsOurFile(const char *name)
     BOOL result = FALSE;
     struct stat data;
 
-    if (lstat(name, &data) == 0
+    if (!LYIsTilde(name[0])
+	&& lstat(name, &data) == 0
 	&& S_ISREG(data.st_mode)
 	&& (data.st_mode & (S_IWOTH | S_IWGRP)) == 0
 	&& data.st_nlink == 1
@@ -6666,7 +6750,7 @@ BOOLEAN LYValidateFilename(char *result,
 	return TRUE;
     }
 #endif
-    if ((cp = strchr(given, '~')) != 0
+    if ((cp = FindLeadingTilde(given, TRUE)) != 0
 	&& (cp2 = wwwName(Home_Dir())) != 0
 	&& strlen(cp2) + strlen(given) < LY_MAXPATH) {
 	*(cp++) = '\0';
diff --git a/src/LYUtils.h b/src/LYUtils.h
index f2239f5c..bc5da5ab 100644
--- a/src/LYUtils.h
+++ b/src/LYUtils.h
@@ -96,6 +96,7 @@ extern "C" {
 #define LYIsListpageTitle(name) \
     (!strcmp((name), LIST_PAGE_TITLE))
 #endif
+#define LYIsTilde(ch)     ((ch) == '~')
 #define LYIsHtmlSep(ch) ((ch) == '/')
 #define findPoundSelector(address) strchr(address, '#')
 #define restorePoundSelector(pound) if ((pound) != NULL) *(pound) = '#'
@@ -107,8 +108,8 @@ extern "C" {
     extern BOOLEAN LYCanWriteFile(const char *name);
     extern BOOLEAN LYCloseInput(FILE *fp);
     extern BOOLEAN LYCloseOutput(FILE *fp);
-    extern BOOLEAN LYExpandHostForURL(char **AllocatedString, char
-				      *prefix_list, char *suffix_list);
+    extern BOOLEAN LYExpandHostForURL(char **AllocatedString,
+				      char *prefix_list, char *suffix_list);
     extern BOOLEAN LYFixCursesOnForAccess(const char *addr, const char *physical);
     extern BOOLEAN LYPathOffHomeOK(char *fbuffer, size_t fbuffer_size);
     extern BOOLEAN LYValidateFilename(char *result, char *given);
@@ -127,10 +128,12 @@ extern "C" {
     extern FILE *LYOpenTempRewrite(char *result, const char *suffix, const char *mode);
     extern FILE *LYReopenTemp(char *name);
     extern char *Current_Dir(char *pathname);
+    extern char *LYAbsOrHomePath(char **fname);
     extern char *LYAddPathToSave(char *fname);
     extern char *LYGetEnv(const char *name);
     extern char *LYLastPathSep(const char *path);
     extern char *LYPathLeaf(char *pathname);
+    extern char *LYTildeExpand(char **pathname, BOOL embedded);
     extern char *LYgetXDisplay(void);
     extern char *strip_trailing_slash(char *my_dirname);
     extern char *trimPoundSelector(char *address);