diff options
author | Gary Mills <gary_mills@fastmail.fm> | 2014-07-17 08:04:01 -0500 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2014-07-20 09:10:48 -0700 |
commit | 944b13ecd074fe0d43ed6f80c816ca862c3cd6eb (patch) | |
tree | 67724609f44855c1820eeea48cdc5378595a831f /usr/src/cmd/zonecfg/zonecfg.c | |
parent | e03914f9208eb53e6c8a6d5a436953ad983642b0 (diff) | |
download | illumos-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.c | 147 |
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); } /* |