summaryrefslogtreecommitdiffstats
path: root/contrib/less/filename.c
diff options
context:
space:
mode:
authortjr <tjr@FreeBSD.org>2004-04-17 07:16:34 +0000
committertjr <tjr@FreeBSD.org>2004-04-17 07:16:34 +0000
commit44c4d557e2436dfbb703a9fc3e78fac79c574d4b (patch)
treef46d7e51d83360c5b6bdacf5b08e16a415ed61b5 /contrib/less/filename.c
parentc0c85bc41cb6c023adae56cf0a7e3495bd528cb2 (diff)
downloadFreeBSD-src-44c4d557e2436dfbb703a9fc3e78fac79c574d4b.zip
FreeBSD-src-44c4d557e2436dfbb703a9fc3e78fac79c574d4b.tar.gz
Import less v381.
Diffstat (limited to 'contrib/less/filename.c')
-rw-r--r--contrib/less/filename.c487
1 files changed, 245 insertions, 242 deletions
diff --git a/contrib/less/filename.c b/contrib/less/filename.c
index bfbbfdb..0b56bdc 100644
--- a/contrib/less/filename.c
+++ b/contrib/less/filename.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1984-2000 Mark Nudelman
+ * Copyright (C) 1984-2002 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
@@ -50,6 +50,7 @@
extern int force_open;
extern int secure;
+extern int use_lessopen;
extern IFILE curr_ifile;
extern IFILE old_ifile;
#if SPACES_IN_FILENAMES
@@ -61,24 +62,157 @@ extern char closequote;
* Remove quotes around a filename.
*/
public char *
-unquote_file(str)
+shell_unquote(str)
char *str;
{
-#if SPACES_IN_FILENAMES
char *name;
char *p;
- if (*str != openquote)
- return (save(str));
- name = (char *) ecalloc(strlen(str), sizeof(char));
- strcpy(name, str+1);
- p = name + strlen(name) - 1;
- if (*p == closequote)
- *p = '\0';
+ name = p = (char *) ecalloc(strlen(str)+1, sizeof(char));
+ if (*str == openquote)
+ {
+ str++;
+ while (*str != '\0')
+ {
+ if (*str == closequote)
+ {
+ if (str[1] != closequote)
+ break;
+ str++;
+ }
+ *p++ = *str++;
+ }
+ } else
+ {
+ char *esc = get_meta_escape();
+ int esclen = strlen(esc);
+ while (*str != '\0')
+ {
+ if (esclen > 0 && strncmp(str, esc, esclen) == 0)
+ str += esclen;
+ *p++ = *str++;
+ }
+ }
+ *p = '\0';
return (name);
-#else
- return (save(str));
-#endif
+}
+
+/*
+ * Get the shell's escape character.
+ */
+ public char *
+get_meta_escape()
+{
+ char *s;
+
+ s = lgetenv("LESSMETAESCAPE");
+ if (s == NULL)
+ s = DEF_METAESCAPE;
+ return (s);
+}
+
+/*
+ * Get the characters which the shell considers to be "metacharacters".
+ */
+ static char *
+metachars()
+{
+ static char *mchars = NULL;
+
+ if (mchars == NULL)
+ {
+ mchars = lgetenv("LESSMETACHARS");
+ if (mchars == NULL)
+ mchars = DEF_METACHARS;
+ }
+ return (mchars);
+}
+
+/*
+ * Is this a shell metacharacter?
+ */
+ static int
+metachar(c)
+ char c;
+{
+ return (strchr(metachars(), c) != NULL);
+}
+
+/*
+ * Insert a backslash before each metacharacter in a string.
+ */
+ public char *
+shell_quote(s)
+ char *s;
+{
+ char *p;
+ char *newstr;
+ int len;
+ char *esc = get_meta_escape();
+ int esclen = strlen(esc);
+ int use_quotes = 0;
+ int have_quotes = 0;
+
+ /*
+ * Determine how big a string we need to allocate.
+ */
+ len = 1; /* Trailing null byte */
+ for (p = s; *p != '\0'; p++)
+ {
+ len++;
+ if (*p == openquote || *p == closequote)
+ have_quotes = 1;
+ if (metachar(*p))
+ {
+ if (esclen == 0)
+ {
+ /*
+ * We've got a metachar, but this shell
+ * doesn't support escape chars. Use quotes.
+ */
+ use_quotes = 1;
+ } else
+ {
+ /*
+ * Allow space for the escape char.
+ */
+ len += esclen;
+ }
+ }
+ }
+ if (use_quotes)
+ {
+ if (have_quotes)
+ /*
+ * We can't quote a string that contains quotes.
+ */
+ return (NULL);
+ len = strlen(s) + 3;
+ }
+ /*
+ * Allocate and construct the new string.
+ */
+ newstr = p = (char *) ecalloc(len, sizeof(char));
+ if (use_quotes)
+ {
+ sprintf(newstr, "%c%s%c", openquote, s, closequote);
+ } else
+ {
+ while (*s != '\0')
+ {
+ if (metachar(*s))
+ {
+ /*
+ * Add the escape char.
+ */
+ strcpy(p, esc);
+ p += esclen;
+ }
+ *p++ = *s++;
+ }
+ *p = '\0';
+ }
+ return (newstr);
}
/*
@@ -107,7 +241,7 @@ dirfile(dirname, filename)
/*
* Make sure the file exists.
*/
- qpathname = unquote_file(pathname);
+ qpathname = shell_unquote(pathname);
f = open(qpathname, OPEN_READ);
if (f < 0)
{
@@ -274,6 +408,7 @@ fcomplete(s)
char *s;
{
char *fpat;
+ char *qs;
if (secure)
return (NULL);
@@ -303,17 +438,19 @@ fcomplete(s)
fpat = (char *) ecalloc(strlen(s)+2, sizeof(char));
sprintf(fpat, "%s*", s);
#endif
- s = lglob(fpat);
+ qs = lglob(fpat);
+ s = shell_unquote(qs);
if (strcmp(s,fpat) == 0)
{
/*
* The filename didn't expand.
*/
- free(s);
- s = NULL;
+ free(qs);
+ qs = NULL;
}
+ free(s);
free(fpat);
- return (s);
+ return (qs);
}
#endif
@@ -398,108 +535,6 @@ readfd(fd)
return (buf);
}
-#if HAVE_SHELL
-
-/*
- * Get the shell's escape character.
- */
- static char *
-get_meta_escape()
-{
- char *s;
-
- s = lgetenv("LESSMETAESCAPE");
- if (s == NULL)
- s = DEF_METAESCAPE;
- return (s);
-}
-
-/*
- * Is this a shell metacharacter?
- */
- static int
-metachar(c)
- char c;
-{
- static char *metachars = NULL;
-
- if (metachars == NULL)
- {
- metachars = lgetenv("LESSMETACHARS");
- if (metachars == NULL)
- metachars = DEF_METACHARS;
- }
- return (strchr(metachars, c) != NULL);
-}
-
-/*
- * Insert a backslash before each metacharacter in a string.
- */
- public char *
-esc_metachars(s)
- char *s;
-{
- char *p;
- char *newstr;
- int len;
- char *esc;
- int esclen;
-
- /*
- * Determine how big a string we need to allocate.
- */
- esc = get_meta_escape();
- esclen = strlen(esc);
- len = 1; /* Trailing null byte */
- for (p = s; *p != '\0'; p++)
- {
- len++;
- if (metachar(*p))
- {
- if (*esc == '\0')
- {
- /*
- * We've got a metachar, but this shell
- * doesn't support escape chars. Give up.
- */
- return (NULL);
- }
- /*
- * Allow space for the escape char.
- */
- len += esclen;
- }
- }
- /*
- * Allocate and construct the new string.
- */
- newstr = p = (char *) ecalloc(len, sizeof(char));
- while (*s != '\0')
- {
- if (metachar(*s))
- {
- /*
- * Add the escape char.
- */
- strcpy(p, esc);
- p += esclen;
- }
- *p++ = *s++;
- }
- *p = '\0';
- return (newstr);
-}
-
-#else /* HAVE_SHELL */
-
- public char *
-esc_metachars(s)
- char *s;
-{
- return (save(s));
-}
-
-#endif /* HAVE_SHELL */
#if HAVE_POPEN
@@ -526,43 +561,32 @@ shellcmd(cmd)
char *esccmd;
/*
- * Try to escape any metacharacters in the command.
- * If we can't do that, just put the command in quotes.
- * (But that doesn't work well if the command itself
- * contains quotes.)
+ * Read the output of <$SHELL -c cmd>.
+ * Escape any metacharacters in the command.
*/
- if ((esccmd = esc_metachars(cmd)) == NULL)
+ esccmd = shell_quote(cmd);
+ if (esccmd == NULL)
{
- /*
- * Cannot escape the metacharacters, so use quotes.
- * Read the output of <$SHELL -c "cmd">.
- */
- scmd = (char *) ecalloc(strlen(shell) + strlen(cmd) + 7,
- sizeof(char));
- sprintf(scmd, "%s -c \"%s\"", shell, cmd);
+ fd = popen(cmd, "r");
} else
{
- /*
- * Read the output of <$SHELL -c cmd>.
- * No quotes; use the escaped cmd.
- */
scmd = (char *) ecalloc(strlen(shell) + strlen(esccmd) + 5,
sizeof(char));
- sprintf(scmd, "%s -c %s", shell, esccmd);
+ sprintf(scmd, "%s %s %s", shell, shell_coption(), esccmd);
free(esccmd);
+ fd = popen(scmd, "r");
+ free(scmd);
}
- fd = popen(scmd, "r");
- free(scmd);
} else
#endif
{
fd = popen(cmd, "r");
- /*
- * Redirection in `popen' might have messed with the
- * standard devices. Restore binary input mode.
- */
- SET_BINARY(0);
}
+ /*
+ * Redirection in `popen' might have messed with the
+ * standard devices. Restore binary input mode.
+ */
+ SET_BINARY(0);
return (fd);
}
@@ -582,7 +606,7 @@ lglob(filename)
ofilename = fexpand(filename);
if (secure)
return (ofilename);
- filename = unquote_file(ofilename);
+ filename = shell_unquote(ofilename);
#ifdef DECL_GLOB_LIST
{
@@ -591,6 +615,7 @@ lglob(filename)
*/
int length;
char *p;
+ char *qfilename;
DECL_GLOB_LIST(list)
GLOB_LIST(filename, list);
@@ -603,23 +628,23 @@ lglob(filename)
for (SCAN_GLOB_LIST(list, p))
{
INIT_GLOB_LIST(list, p);
- length += strlen(p) + 1;
-#if SPACES_IN_FILENAMES
- if (strchr(p, ' ') != NULL)
- length += 2; /* Allow for quotes */
-#endif
+ qfilename = shell_quote(p);
+ if (qfilename != NULL)
+ {
+ length += strlen(qfilename) + 1;
+ free(qfilename);
+ }
}
gfilename = (char *) ecalloc(length, sizeof(char));
for (SCAN_GLOB_LIST(list, p))
{
INIT_GLOB_LIST(list, p);
-#if SPACES_IN_FILENAMES
- if (strchr(p, ' ') != NULL)
- sprintf(gfilename + strlen(gfilename), "%c%s%c ",
- openquote, p, closequote);
- else
-#endif
- sprintf(gfilename + strlen(gfilename), "%s ", p);
+ qfilename = shell_quote(p);
+ if (qfilename != NULL)
+ {
+ sprintf(gfilename + strlen(gfilename), "%s ", qfilename);
+ free(qfilename);
+ }
}
/*
* Overwrite the final trailing space with a null terminator.
@@ -637,9 +662,8 @@ lglob(filename)
register char *p;
register int len;
register int n;
-#if SPACES_IN_FILENAMES
- register int spaces_in_file;
-#endif
+ char *pathname;
+ char *qpathname;
DECL_GLOB_NAME(fnd,drive,dir,fname,ext,handle)
GLOB_FIRST_NAME(filename, &fnd, handle);
@@ -655,36 +679,32 @@ lglob(filename)
p = gfilename;
do {
n = strlen(drive) + strlen(dir) + strlen(fnd.GLOB_NAME) + 1;
-#if SPACES_IN_FILENAMES
- spaces_in_file = 0;
- if (strchr(fnd.GLOB_NAME, ' ') != NULL ||
- strchr(filename, ' ') != NULL)
- {
- spaces_in_file = 1;
- n += 2;
- }
-#endif
- while (p - gfilename + n+2 >= len)
+ pathname = (char *) ecalloc(n, sizeof(char));
+ sprintf(pathname, "%s%s%s", drive, dir, fnd.GLOB_NAME);
+ qpathname = shell_quote(pathname);
+ free(pathname);
+ if (qpathname != NULL)
{
- /*
- * No room in current buffer. Allocate a bigger one.
- */
- len *= 2;
- *p = '\0';
- p = (char *) ecalloc(len, sizeof(char));
- strcpy(p, gfilename);
- free(gfilename);
- gfilename = p;
- p = gfilename + strlen(gfilename);
+ n = strlen(qpathname);
+ while (p - gfilename + n + 2 >= len)
+ {
+ /*
+ * No room in current buffer.
+ * Allocate a bigger one.
+ */
+ len *= 2;
+ *p = '\0';
+ p = (char *) ecalloc(len, sizeof(char));
+ strcpy(p, gfilename);
+ free(gfilename);
+ gfilename = p;
+ p = gfilename + strlen(gfilename);
+ }
+ strcpy(p, qpathname);
+ free(qpathname);
+ p += n;
+ *p++ = ' ';
}
-#if SPACES_IN_FILENAMES
- if (spaces_in_file)
- sprintf(p, "%c%s%s%s%c ", openquote,
- drive, dir, fnd.GLOB_NAME, closequote);
- else
-#endif
- sprintf(p, "%s%s%s ", drive, dir, fnd.GLOB_NAME);
- p += n;
} while (GLOB_NEXT_NAME(handle, &fnd) == 0);
/*
@@ -704,30 +724,30 @@ lglob(filename)
char *s;
char *lessecho;
char *cmd;
+ char *esc;
- lessecho = lgetenv("LESSECHO");
- if (lessecho == NULL || *lessecho == '\0')
- lessecho = "lessecho";
- s = esc_metachars(filename);
- if (s == NULL)
+ esc = get_meta_escape();
+ if (strlen(esc) == 0)
+ esc = "-";
+ esc = shell_quote(esc);
+ if (esc == NULL)
{
- /*
- * There may be dangerous metachars in this name.
- * We can't risk passing it to the shell.
- * {{ For example, do "!;TAB" when the first file
- * in the dir is named "rm". }}
- */
free(filename);
return (ofilename);
}
+ lessecho = lgetenv("LESSECHO");
+ if (lessecho == NULL || *lessecho == '\0')
+ lessecho = "lessecho";
/*
* Invoke lessecho, and read its output (a globbed list of filenames).
*/
- cmd = (char *) ecalloc(strlen(lessecho) + strlen(s) + 24, sizeof(char));
- sprintf(cmd, "%s -p0x%x -d0x%x -- %s",
- lessecho, openquote, closequote, s);
+ cmd = (char *) ecalloc(strlen(lessecho) + strlen(ofilename) + (7*strlen(metachars())) + 24, sizeof(char));
+ sprintf(cmd, "%s -p0x%x -d0x%x -e%s ", lessecho, openquote, closequote, esc);
+ free(esc);
+ for (s = metachars(); *s != '\0'; s++)
+ sprintf(cmd + strlen(cmd), "-n0x%x ", *s);
+ sprintf(cmd + strlen(cmd), "-- %s", ofilename);
fd = shellcmd(cmd);
- free(s);
free(cmd);
if (fd == NULL)
{
@@ -774,14 +794,13 @@ open_altfile(filename, pf, pfd)
return (NULL);
#else
char *lessopen;
- char *gfilename;
char *cmd;
FILE *fd;
#if HAVE_FILENO
int returnfd = 0;
#endif
- if (secure)
+ if (!use_lessopen || secure)
return (NULL);
ch_ungetchar(-1);
if ((lessopen = lgetenv("LESSOPEN")) == NULL)
@@ -803,19 +822,10 @@ open_altfile(filename, pf, pfd)
#endif
}
- gfilename = esc_metachars(filename);
- if (gfilename == NULL)
- {
- /*
- * Cannot escape metacharacters.
- */
- return (NULL);
- }
- cmd = (char *) ecalloc(strlen(lessopen) + strlen(gfilename) + 2,
+ cmd = (char *) ecalloc(strlen(lessopen) + strlen(filename) + 2,
sizeof(char));
- sprintf(cmd, lessopen, gfilename);
+ sprintf(cmd, lessopen, filename);
fd = shellcmd(cmd);
- free(gfilename);
free(cmd);
if (fd == NULL)
{
@@ -850,14 +860,14 @@ open_altfile(filename, pf, pfd)
return (save("-"));
}
#endif
- gfilename = readfd(fd);
+ cmd = readfd(fd);
pclose(fd);
- if (*gfilename == '\0')
+ if (*cmd == '\0')
/*
* Pipe is empty. This means there is no alt file.
*/
return (NULL);
- return (gfilename);
+ return (cmd);
#endif /* HAVE_POPEN */
}
@@ -872,8 +882,6 @@ close_altfile(altfilename, filename, pipefd)
{
#if HAVE_POPEN
char *lessclose;
- char *gfilename;
- char *galtfilename;
FILE *fd;
char *cmd;
@@ -892,23 +900,10 @@ close_altfile(altfilename, filename, pipefd)
}
if ((lessclose = lgetenv("LESSCLOSE")) == NULL)
return;
- gfilename = esc_metachars(filename);
- if (gfilename == NULL)
- {
- return;
- }
- galtfilename = esc_metachars(altfilename);
- if (galtfilename == NULL)
- {
- free(gfilename);
- return;
- }
- cmd = (char *) ecalloc(strlen(lessclose) + strlen(gfilename) +
- strlen(galtfilename) + 2, sizeof(char));
- sprintf(cmd, lessclose, gfilename, galtfilename);
+ cmd = (char *) ecalloc(strlen(lessclose) + strlen(filename) +
+ strlen(altfilename) + 2, sizeof(char));
+ sprintf(cmd, lessclose, filename, altfilename);
fd = shellcmd(cmd);
- free(galtfilename);
- free(gfilename);
free(cmd);
if (fd != NULL)
pclose(fd);
@@ -924,7 +919,7 @@ is_dir(filename)
{
int isdir = 0;
- filename = unquote_file(filename);
+ filename = shell_unquote(filename);
#if HAVE_STAT
{
int r;
@@ -960,15 +955,15 @@ bad_file(filename)
{
register char *m = NULL;
- filename = unquote_file(filename);
+ filename = shell_unquote(filename);
if (is_dir(filename))
{
- static char is_dir[] = " is a directory";
+ static char is_a_dir[] = " is a directory";
- m = (char *) ecalloc(strlen(filename) + sizeof(is_dir),
+ m = (char *) ecalloc(strlen(filename) + sizeof(is_a_dir),
sizeof(char));
strcpy(m, filename);
- strcat(m, is_dir);
+ strcat(m, is_a_dir);
} else
{
#if HAVE_STAT
@@ -1020,3 +1015,11 @@ filesize(f)
return (seek_filesize(f));
}
+/*
+ *
+ */
+ public char *
+shell_coption()
+{
+ return ("-c");
+}
OpenPOWER on IntegriCloud