summaryrefslogtreecommitdiff
path: root/usr/src/cmd/zonecfg/zonecfg.c
diff options
context:
space:
mode:
authorGary Mills <gary_mills@fastmail.fm>2014-07-17 08:04:01 -0500
committerRobert Mustacchi <rm@joyent.com>2014-07-20 09:10:48 -0700
commit944b13ecd074fe0d43ed6f80c816ca862c3cd6eb (patch)
tree67724609f44855c1820eeea48cdc5378595a831f /usr/src/cmd/zonecfg/zonecfg.c
parente03914f9208eb53e6c8a6d5a436953ad983642b0 (diff)
downloadillumos-joyent-944b13ecd074fe0d43ed6f80c816ca862c3cd6eb.tar.gz
4956 zonecfg won't use a valid pager
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com> Reviewed by: Igor Kozhukhov <ikozhukhov@gmail.com> Approved by: Robert Mustacchi <rm@joyent.com>
Diffstat (limited to 'usr/src/cmd/zonecfg/zonecfg.c')
-rw-r--r--usr/src/cmd/zonecfg/zonecfg.c147
1 files changed, 109 insertions, 38 deletions
diff --git a/usr/src/cmd/zonecfg/zonecfg.c b/usr/src/cmd/zonecfg/zonecfg.c
index 5e14093358..3dbec383bf 100644
--- a/usr/src/cmd/zonecfg/zonecfg.c
+++ b/usr/src/cmd/zonecfg/zonecfg.c
@@ -22,6 +22,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2014 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2014 Gary Mills
*/
/*
@@ -909,6 +910,105 @@ long_help(int cmd_num)
}
/*
+ * Return the input filename appended to each component of the path
+ * or the filename itself if it is absolute.
+ * Parameters: path string, file name, output string.
+ */
+/* Copied almost verbatim from libtnfctl/prb_findexec.c */
+static const char *
+exec_cat(const char *s1, const char *s2, char *si)
+{
+ char *s;
+ /* Number of remaining characters in s */
+ int cnt = PATH_MAX + 1;
+
+ s = si;
+ while (*s1 && *s1 != ':') { /* Copy first component of path to si */
+ if (cnt > 0) {
+ *s++ = *s1++;
+ cnt--;
+ } else {
+ s1++;
+ }
+ }
+ if (si != s && cnt > 0) { /* Add slash if s2 is not absolute */
+ *s++ = '/';
+ cnt--;
+ }
+ while (*s2 && cnt > 0) { /* Copy s2 to si */
+ *s++ = *s2++;
+ cnt--;
+ }
+ *s = '\0'; /* Terminate the output string */
+ return (*s1 ? ++s1 : NULL); /* Return next path component or NULL */
+}
+
+/* Determine that a name exists in PATH */
+/* Copied with changes from libtnfctl/prb_findexec.c */
+static int
+path_find(const char *name)
+{
+ const char *pathstr;
+ char fname[PATH_MAX + 2];
+ const char *cp;
+ struct stat stat_buf;
+
+ if ((pathstr = getenv("PATH")) == NULL) {
+ if (geteuid() == 0 || getuid() == 0)
+ pathstr = "/usr/sbin:/usr/bin";
+ else
+ pathstr = "/usr/bin:";
+ }
+ cp = strchr(name, '/') ? (const char *) "" : pathstr;
+
+ do {
+ cp = exec_cat(cp, name, fname);
+ if (stat(fname, &stat_buf) != -1) {
+ /* successful find of the file */
+ return (0);
+ }
+ } while (cp != NULL);
+
+ return (-1);
+}
+
+static FILE *
+pager_open(void) {
+ FILE *newfp;
+ char *pager, *space;
+
+ pager = getenv("PAGER");
+ if (pager == NULL || *pager == '\0')
+ pager = PAGER;
+
+ space = strchr(pager, ' ');
+ if (space)
+ *space = '\0';
+ if (path_find(pager) == 0) {
+ if (space)
+ *space = ' ';
+ if ((newfp = popen(pager, "w")) == NULL)
+ zerr(gettext("PAGER open failed (%s)."),
+ strerror(errno));
+ return (newfp);
+ } else {
+ zerr(gettext("PAGER %s does not exist (%s)."),
+ pager, strerror(errno));
+ }
+ return (NULL);
+}
+
+static void
+pager_close(FILE *fp) {
+ int status;
+
+ status = pclose(fp);
+ if (status == -1)
+ zerr(gettext("PAGER close failed (%s)."),
+ strerror(errno));
+}
+
+/*
* Called with verbose TRUE when help is explicitly requested, FALSE for
* unexpected errors.
*/
@@ -919,28 +1019,13 @@ usage(boolean_t verbose, uint_t flags)
FILE *fp = verbose ? stdout : stderr;
FILE *newfp;
boolean_t need_to_close = B_FALSE;
- char *pager, *space;
int i;
- struct stat statbuf;
/* don't page error output */
if (verbose && interactive_mode) {
- if ((pager = getenv("PAGER")) == NULL)
- pager = PAGER;
-
- space = strchr(pager, ' ');
- if (space)
- *space = '\0';
- if (stat(pager, &statbuf) == 0) {
- if (space)
- *space = ' ';
- if ((newfp = popen(pager, "w")) != NULL) {
- need_to_close = B_TRUE;
- fp = newfp;
- }
- } else {
- zerr(gettext("PAGER %s does not exist (%s)."),
- pager, strerror(errno));
+ if ((newfp = pager_open()) != NULL) {
+ need_to_close = B_TRUE;
+ fp = newfp;
}
}
@@ -1274,7 +1359,7 @@ usage(boolean_t verbose, uint_t flags)
pt_to_str(PT_USER), pt_to_str(PT_AUTHS));
}
if (need_to_close)
- (void) pclose(fp);
+ (void) pager_close(fp);
}
static void
@@ -5343,12 +5428,10 @@ info_func(cmd_t *cmd)
{
FILE *fp = stdout;
boolean_t need_to_close = B_FALSE;
- char *pager, *space;
int type;
int res1, res2;
uint64_t swap_limit;
uint64_t locked_limit;
- struct stat statbuf;
assert(cmd != NULL);
@@ -5357,22 +5440,10 @@ info_func(cmd_t *cmd)
/* don't page error output */
if (interactive_mode) {
- if ((pager = getenv("PAGER")) == NULL)
- pager = PAGER;
- space = strchr(pager, ' ');
- if (space)
- *space = '\0';
- if (stat(pager, &statbuf) == 0) {
- if (space)
- *space = ' ';
- if ((fp = popen(pager, "w")) != NULL)
- need_to_close = B_TRUE;
- else
- fp = stdout;
- } else {
- zerr(gettext("PAGER %s does not exist (%s)."),
- pager, strerror(errno));
- }
+ if ((fp = pager_open()) != NULL)
+ need_to_close = B_TRUE;
+ else
+ fp = stdout;
setbuf(fp, NULL);
}
@@ -5562,7 +5633,7 @@ info_func(cmd_t *cmd)
cleanup:
if (need_to_close)
- (void) pclose(fp);
+ (void) pager_close(fp);
}
/*