version 1.15, 2011/09/16 18:12:09 |
version 1.16, 2014/04/25 13:38:21 |
|
|
/* |
/* |
* Copyright (C) 1984-2011 Mark Nudelman |
* Copyright (C) 1984-2012 Mark Nudelman |
* |
* |
* You may distribute under the terms of either the GNU General Public |
* You may distribute under the terms of either the GNU General Public |
* License or the Less License, as specified in the README file. |
* License or the Less License, as specified in the README file. |
* |
* |
* For more information about less, or for information on how to |
* For more information, see the README file. |
* contact the author, see the README file. |
|
*/ |
*/ |
|
|
|
|
|
|
|
|
#endif /* HAVE_POPEN */ |
#endif /* HAVE_POPEN */ |
|
|
|
|
#if !SMALL |
#if !SMALL |
/* |
/* |
* Expand a filename, doing any system-specific metacharacter substitutions. |
* Expand a filename, doing any system-specific metacharacter substitutions. |
|
|
#endif /* !SMALL */ |
#endif /* !SMALL */ |
|
|
/* |
/* |
|
* Return number of %s escapes in a string. |
|
* Return a large number if there are any other % escapes besides %s. |
|
*/ |
|
static int |
|
num_pct_s(lessopen) |
|
char *lessopen; |
|
{ |
|
int num; |
|
|
|
for (num = 0;; num++) |
|
{ |
|
lessopen = strchr(lessopen, '%'); |
|
if (lessopen == NULL) |
|
break; |
|
if (*++lessopen != 's') |
|
return (999); |
|
} |
|
return (num); |
|
} |
|
|
|
/* |
* See if we should open a "replacement file" |
* See if we should open a "replacement file" |
* instead of the file we're about to open. |
* instead of the file we're about to open. |
*/ |
*/ |
|
|
return (NULL); |
return (NULL); |
#else |
#else |
char *lessopen; |
char *lessopen; |
char *cmd, *cp; |
char *cmd; |
|
size_t len; |
FILE *fd; |
FILE *fd; |
size_t i, len; |
|
int found; |
|
#if HAVE_FILENO |
#if HAVE_FILENO |
int returnfd = 0; |
int returnfd = 0; |
#endif |
#endif |
|
|
ch_ungetchar(-1); |
ch_ungetchar(-1); |
if ((lessopen = lgetenv("LESSOPEN")) == NULL) |
if ((lessopen = lgetenv("LESSOPEN")) == NULL) |
return (NULL); |
return (NULL); |
if (*lessopen == '|') |
while (*lessopen == '|') |
{ |
{ |
/* |
/* |
* If LESSOPEN starts with a |, it indicates |
* If LESSOPEN starts with a |, it indicates |
|
|
return (NULL); |
return (NULL); |
#else |
#else |
lessopen++; |
lessopen++; |
returnfd = 1; |
returnfd++; |
#endif |
#endif |
} |
} |
if (*lessopen == '-') { |
if (*lessopen == '-') { |
|
|
if (strcmp(filename, "-") == 0) |
if (strcmp(filename, "-") == 0) |
return (NULL); |
return (NULL); |
} |
} |
|
if (num_pct_s(lessopen) > 1) |
|
{ |
|
error("Invalid LESSOPEN variable", NULL_PARG); |
|
return (NULL); |
|
} |
|
|
/* strlen(filename) is guaranteed to be > 0 */ |
len = strlen(lessopen) + strlen(filename) + 2; |
len = strlen(lessopen) + strlen(filename); |
|
cmd = (char *) ecalloc(len, sizeof(char)); |
cmd = (char *) ecalloc(len, sizeof(char)); |
for (cp = cmd, i = 0, found = 0; i < strlen(lessopen); i++) { |
SNPRINTF1(cmd, len, lessopen, filename); |
if (!found && lessopen[i] == '%' && lessopen[i + 1] == 's') { |
|
found = 1; |
|
strlcat(cmd, filename, len); |
|
cp += strlen(filename); |
|
i++; |
|
} else |
|
*cp++ = lessopen[i]; |
|
} |
|
fd = shellcmd(cmd); |
fd = shellcmd(cmd); |
free(cmd); |
free(cmd); |
if (fd == NULL) |
if (fd == NULL) |
|
|
if (read(f, &c, 1) != 1) |
if (read(f, &c, 1) != 1) |
{ |
{ |
/* |
/* |
* Pipe is empty. This means there is no alt file. |
* Pipe is empty. |
|
* If more than 1 pipe char was specified, |
|
* the exit status tells whether the file itself |
|
* is empty, or if there is no alt file. |
|
* If only one pipe char, just assume no alt file. |
*/ |
*/ |
pclose(fd); |
int status = pclose(fd); |
|
if (returnfd > 1 && status == 0) { |
|
*pfd = NULL; |
|
*pf = -1; |
|
return (save(FAKE_EMPTYFILE)); |
|
} |
return (NULL); |
return (NULL); |
} |
} |
ch_ungetchar(c); |
ch_ungetchar(c); |
|
|
#if HAVE_POPEN |
#if HAVE_POPEN |
char *lessclose; |
char *lessclose; |
FILE *fd; |
FILE *fd; |
char *cmd, *cp; |
char *cmd; |
size_t i, len; |
size_t len; |
int found; |
|
|
|
if (secure) |
if (secure) |
return; |
return; |
|
|
} |
} |
if ((lessclose = lgetenv("LESSCLOSE")) == NULL) |
if ((lessclose = lgetenv("LESSCLOSE")) == NULL) |
return; |
return; |
/* strlen(filename) is guaranteed to be > 0 */ |
if (num_pct_s(lessclose) > 2) |
len = strlen(lessclose) + strlen(filename) + strlen(altfilename); |
{ |
cmd = (char *) ecalloc(len, sizeof(char)); |
error("Invalid LESSCLOSE variable"); |
for (cp = cmd, i = 0, found = 0; i < strlen(lessclose); i++) { |
return; |
if (found < 2 && lessclose[i] == '%' && lessclose[i + 1] == 's') { |
|
if (++found == 1) { |
|
strlcat(cmd, filename, len); |
|
cp += strlen(filename); |
|
} else { |
|
strlcat(cmd, altfilename, len); |
|
cp += strlen(altfilename); |
|
} |
|
i++; |
|
} else |
|
*cp++ = lessclose[i]; |
|
} |
} |
|
len = strlen(lessclose) + strlen(filename) + strlen(altfilename) + 2; |
|
cmd = (char *) ecalloc(len, sizeof(char)); |
|
SNPRINTF2(cmd, len, lessclose, filename, altfilename); |
fd = shellcmd(cmd); |
fd = shellcmd(cmd); |
free(cmd); |
free(cmd); |
if (fd != NULL) |
if (fd != NULL) |