From 48981be8a872c7a0191d2519793205276fdc423a Mon Sep 17 00:00:00 2001 From: William Hubbs Date: Wed, 16 Oct 2013 12:55:37 -0500 Subject: Revert "Make einfo routines private" This reverts commit de88aff0a839844526ae262f8961ec4372fed238. I was advised that splashutils links to libeinfo, so we do have a consumer for this library. --- src/rc/einfo.c | 1016 -------------------------------------------------------- 1 file changed, 1016 deletions(-) delete mode 100644 src/rc/einfo.c (limited to 'src/rc/einfo.c') diff --git a/src/rc/einfo.c b/src/rc/einfo.c deleted file mode 100644 index 306e7885..00000000 --- a/src/rc/einfo.c +++ /dev/null @@ -1,1016 +0,0 @@ -/* - einfo.c - Informational functions -*/ - -/* - * Copyright (c) 2007-2008 Roy Marples - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -const char libeinfo_copyright[] = "Copyright (c) 2007-2008 Roy Marples"; - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_TERMCAP -# include -#endif -#include - -#include "einfo.h" -#include "helpers.h" - -/* Incase we cannot work out how many columns from ioctl, supply a default */ -#define DEFAULT_COLS 80 - -#define OK "ok" -#define NOT_OK "!!" - -/* Number of spaces for an indent */ -#define INDENT_WIDTH 2 - -/* How wide can the indent go? */ -#define INDENT_MAX 40 - -/* Default colours */ -#define GOOD 2 -#define WARN 3 -#define BAD 1 -#define HILITE 6 -#define BRACKET 4 - -/* We fallback to these escape codes if termcap isn't available - * like say /usr isn't mounted */ -#define AF "\033[3%dm" -#define CE "\033[K" -#define CH "\033[%dC" -#define MD "\033[1m" -#define ME "\033[m" -#define UP "\033[A" - -#define _GET_CAP(_d, _c) strlcpy(_d, tgoto(_c, 0, 0), sizeof(_d)); -#define _ASSIGN_CAP(_v) do { \ - _v = p; \ - p += strlcpy(p, tmp, sizeof(ebuffer) - (p - ebuffer)) + 1; \ - } while (0) - -/* A pointer to a string to prefix to einfo/ewarn/eerror messages */ -static const char *_eprefix = NULL; - -/* Buffers and structures to hold the final colours */ -static char ebuffer[100]; -struct ecolor { - ECOLOR color; - int def; - const char *name; -}; -static char nullstr = '\0'; - -static const struct ecolor ecolors[] = { - { ECOLOR_GOOD, GOOD, "good" }, - { ECOLOR_WARN, WARN, "warn" }, - { ECOLOR_BAD, BAD, "bad" }, - { ECOLOR_HILITE, HILITE, "hilite" }, - { ECOLOR_BRACKET, BRACKET, "bracket" }, - { ECOLOR_NORMAL, 0, NULL }, -}; -static const char *ecolors_str[ARRAY_SIZE(ecolors)]; - -static char *flush = NULL; -static char *up = NULL; -static char *goto_column = NULL; - -static const char *term = NULL; -static bool term_is_cons25 = false; - -/* Termcap buffers and pointers - * Static buffers suck hard, but some termcap implementations require them */ -#ifdef HAVE_TERMCAP -static char termcapbuf[2048]; -static char tcapbuf[512]; -#else -/* No curses support, so we hardcode a list of colour capable terms - * Only terminals without "color" in the name need to be explicitly listed */ -static const char *const color_terms[] = { - "Eterm", - "ansi", - "con132x25", - "con132x30", - "con132x43", - "con132x60", - "con80x25", - "con80x28", - "con80x30", - "con80x43", - "con80x50", - "con80x60", - "cons25", - "console", - "cygwin", - "dtterm", - "gnome", - "konsole", - "kterm", - "linux", - "linux-c", - "mlterm", - "putty", - "rxvt", - "rxvt-cygwin", - "rxvt-cygwin-native", - "rxvt-unicode", - "screen", - "screen-bce", - "screen-w", - "screen.linux", - "vt100", - "vt220", - "wsvt25", - "xterm", - "xterm-debian", - NULL -}; -#endif - -/* strlcat and strlcpy are nice, shame glibc does not define them */ -#ifdef __GLIBC__ -# if ! defined (__UCLIBC__) && ! defined (__dietlibc__) -static size_t -strlcat(char *dst, const char *src, size_t size) -{ - char *d = dst; - const char *s = src; - size_t src_n = size; - size_t dst_n; - - while (src_n-- != 0 && *d != '\0') - d++; - dst_n = d - dst; - src_n = size - dst_n; - - if (src_n == 0) - return dst_n + strlen(src); - - while (*s != '\0') { - if (src_n != 1) { - *d++ = *s; - src_n--; - } - s++; - } - *d = '\0'; - - return dst_n + (s - src); -} -# endif -#endif - -static bool -yesno(const char *value) -{ - if (!value) { - errno = ENOENT; - return false; - } - - if (strcasecmp(value, "yes") == 0 || - strcasecmp(value, "y") == 0 || - strcasecmp(value, "true") == 0 || - strcasecmp(value, "on") == 0 || - strcasecmp(value, "1") == 0) - return true; - - if (strcasecmp(value, "no") != 0 && - strcasecmp(value, "n") != 0 && - strcasecmp(value, "false") != 0 && - strcasecmp(value, "off") != 0 && - strcasecmp(value, "0") != 0) - errno = EINVAL; - - return false; -} - -static bool -noyes(const char *value) -{ - int serrno = errno; - bool retval; - - errno = 0; - retval = yesno(value); - if (errno == 0) { - retval = !retval; - errno = serrno; - } - - return retval; -} - -static bool -is_quiet(void) -{ - return yesno(getenv("EINFO_QUIET")); -} - -static bool -is_really_quiet(void) -{ - return yesno(getenv("EERROR_QUIET")); -} - -static bool -is_verbose(void) -{ - return yesno(getenv ("EINFO_VERBOSE")); -} - -/* Fake tgoto call - very crapy, but works for our needs */ -#ifndef HAVE_TERMCAP -static char * -tgoto(const char *cap, int col, int line) -{ - static char buf[20]; - char *p, *e, c, dbuf[6]; - int oncol = 0, which = line, i; - - p = buf; - e = p + sizeof(buf); - while ((c = *cap++)) { - if (c != '%' || ((c = *cap++) == '%')) { - *p++ = c; - if (p >= e) { - errno = E2BIG; - return NULL; - } - continue; - } - switch (c) { - case '3': - case '2': - case 'd': - i = 0; - do - dbuf[i++] = which % 10 | '0'; - while ((which /= 10)); - if (c != 'd') { - c -= '0'; - if (i > c) { - errno = EINVAL; - return NULL; - } - while (i < c) - dbuf[i++] = '0'; - } - if (p + i >= e) { - errno = E2BIG; - return NULL; - } - do - *p++ = dbuf[--i]; - while (i); - break; - case 'r': - oncol = 0; - break; - case 'i': - col++; - line++; - which++; - continue; - default: - errno = EINVAL; - return NULL; - } - - oncol = 1 - oncol; - which = oncol ? col : line; - } - *p = '\0'; - return buf; -} -#endif - -static bool -colour_terminal(FILE *f) -{ - static int in_colour = -1; - char *e, *ee, *end, *d, *p; - int c; - const char *_af = NULL, *_ce = NULL, *_ch = NULL; - const char *_md = NULL, *_me = NULL, *_up = NULL; - const char *bold; - char tmp[100]; - unsigned int i = 0; -#ifdef HAVE_TERMCAP - char *bp; -#endif - - if (f && !isatty(fileno(f))) - return false; - - if (noyes(getenv("EINFO_COLOR"))) - return false; - - if (in_colour == 0) - return false; - if (in_colour == 1) - return true; - - term_is_cons25 = false; - if (!term) { - term = getenv("TERM"); - if (!term) - return false; - } - if (strcmp(term, "cons25") == 0) - term_is_cons25 = true; - -#ifdef HAVE_TERMCAP - /* Check termcap to see if we can do colour or not */ - if (tgetent(termcapbuf, term) == 1) { - bp = tcapbuf; - _af = tgetstr("AF", &bp); - _ce = tgetstr("ce", &bp); - _ch = tgetstr("ch", &bp); - /* Our ch use also works with RI .... for now */ - if (!_ch) - _ch = tgetstr("RI", &bp); - _md = tgetstr("md", &bp); - _me = tgetstr("me", &bp); - _up = tgetstr("up", &bp); - } - - /* Cheat here as vanilla BSD has the whole termcap info in /usr - * which is not available to us when we boot */ - if (term_is_cons25 || strcmp(term, "wsvt25") == 0) { -#else - if (strstr(term, "color")) - in_colour = 1; - - while (color_terms[i] && in_colour != 1) { - if (strcmp(color_terms[i], term) == 0) { - in_colour = 1; - } - i++; - } - - if (in_colour != 1) { - in_colour = 0; - return false; - } -#endif - if (!_af) - _af = AF; - if (!_ce) - _ce = CE; - if (!_ch) - _ch = CH; - if (!_md) - _md = MD; - if (!_me) - _me = ME; - if (!_up) - _up = UP; -#ifdef HAVE_TERMCAP - } - - if (!_af || !_ce || !_me || !_md || !_up) { - in_colour = 0; - return false; - } - - /* Many termcap databases don't have ch or RI even though they - * do work */ - if (!_ch) - _ch = CH; -#endif - - /* Now setup our colours */ - p = ebuffer; - for (i = 0; i < ARRAY_SIZE(ecolors); ++i) { - tmp[0] = '\0'; - if (ecolors[i].name) { - bold = _md; - c = ecolors[i].def; - - /* See if the user wants to override the colour - * We use a :col;bold: format like 2;1: for bold green - * and 1;0: for a normal red */ - if ((e = getenv("EINFO_COLOR"))) { - ee = strstr(e, ecolors[i].name); - if (ee) - ee += strlen(ecolors[i].name); - - if (ee && *ee == '=') { - d = strdup(ee + 1); - if (d) { - end = strchr(d, ':'); - if (end) - *end = '\0'; - c = atoi(d); - end = strchr(d, ';'); - if (end && *++end == '0') - bold = _me; - free(d); - } - } - } - strlcpy(tmp, tgoto(bold, 0, 0), sizeof(tmp)); - strlcat(tmp, tgoto(_af, 0, c & 0x07), sizeof(tmp)); - } else - _GET_CAP(tmp, _me); - - if (tmp[0]) - _ASSIGN_CAP(ecolors_str[i]); - else - ecolors_str[i] = &nullstr; - } - - _GET_CAP(tmp, _ce); - _ASSIGN_CAP(flush); - _GET_CAP(tmp, _up); - _ASSIGN_CAP(up); - strlcpy(tmp, _ch, sizeof(tmp)); - _ASSIGN_CAP(goto_column); - - in_colour = 1; - return true; -} - -static int -get_term_columns(FILE *stream) -{ - struct winsize ws; - char *env = getenv("COLUMNS"); - char *p; - int i; - - if (env) { - i = strtoimax(env, &p, 10); - if (!*p) - return i; - } - - if (ioctl(fileno(stream), TIOCGWINSZ, &ws) == 0) - return ws.ws_col; - - return DEFAULT_COLS; -} - -void -eprefix(const char *prefix) -{ - _eprefix = prefix; -} - -static void EINFO_PRINTF(2, 0) -elogv(int level, const char *fmt, va_list ap) -{ - char *e = getenv("EINFO_LOG"); - va_list apc; - - if (fmt && e) { - closelog(); - openlog(e, LOG_PID, LOG_DAEMON); - va_copy(apc, ap); - vsyslog(level, fmt, apc); - va_end(apc); - closelog(); - } -} - -void -elog(int level, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - elogv(level, fmt, ap); - va_end(ap); -} - -static int -_eindent(FILE *stream) -{ - char *env = getenv("EINFO_INDENT"); - int amount = 0; - char indent[INDENT_MAX]; - - if (env) { - errno = 0; - amount = strtoimax(env, NULL, 0); - if (errno != 0 || amount < 0) - amount = 0; - else if (amount > INDENT_MAX) - amount = INDENT_MAX; - - if (amount > 0) - memset(indent, ' ', (size_t)amount); - } - - /* Terminate it */ - memset(indent + amount, 0, 1); - return fprintf(stream, "%s", indent); -} - -static const char * -_ecolor(FILE *f, ECOLOR color) -{ - unsigned int i; - - if (!colour_terminal(f)) - return ""; - - for (i = 0; i < ARRAY_SIZE(ecolors); ++i) - if (ecolors[i].color == color) - return ecolors_str[i]; - return ""; -} - -const char * -ecolor(ECOLOR color) -{ - FILE *f = stdout; - - /* Try and guess a valid tty */ - if (!isatty(fileno(f))) { - f = stderr; - if (!isatty(fileno(f))) { - f = stdin; - if (!isatty(fileno(f))) - f = NULL; - } - } - - return _ecolor(f, color); -} - -#define LASTCMD(_cmd) { \ - unsetenv("EINFO_LASTCMD"); \ - setenv("EINFO_LASTCMD", _cmd, 1); \ - } - -static int EINFO_PRINTF(3, 0) - _einfo(FILE *f, ECOLOR color, const char *fmt, va_list va) -{ - int retval = 0; - char *last = getenv("EINFO_LASTCMD"); - va_list ap; - - if (last && - !colour_terminal(f) && - strcmp(last, "ewarn") != 0 && - last[strlen(last) - 1] == 'n') - fprintf(f, "\n"); - if (_eprefix) - fprintf(f, "%s%s%s|", _ecolor(f, color), _eprefix, _ecolor(f, ECOLOR_NORMAL)); - fprintf(f, " %s*%s ", _ecolor(f, color), _ecolor(f, ECOLOR_NORMAL)); - retval += _eindent(f); - va_copy(ap, va); - retval += vfprintf(f, fmt, ap) + 3; - va_end(ap); \ - if (colour_terminal(f)) - fprintf(f, "%s", flush); - return retval; -} - -#define _einfovn(fmt, ap) _einfo(stdout, ECOLOR_GOOD, fmt, ap) -#define _ewarnvn(fmt, ap) _einfo(stderr, ECOLOR_WARN, fmt, ap) -#define _eerrorvn(fmt, ap) _einfo(stderr, ECOLOR_BAD, fmt, ap) - -int -einfon(const char *fmt, ...) -{ - int retval; - va_list ap; - - if (!fmt || is_quiet()) - return 0; - va_start(ap, fmt); - retval = _einfovn(fmt, ap); - va_end(ap); - LASTCMD("einfon"); - return retval; -} - -int -ewarnn(const char *fmt, ...) -{ - int retval; - va_list ap; - - if (!fmt || is_quiet()) - return 0; - va_start(ap, fmt); - retval = _ewarnvn(fmt, ap); - va_end(ap); - LASTCMD("ewarnn"); - return retval; -} - -int -eerrorn(const char *fmt, ...) -{ - int retval; - va_list ap; - - if (!fmt || is_really_quiet()) - return 0; - va_start(ap, fmt); - retval = _eerrorvn(fmt, ap); - va_end(ap); - LASTCMD("errorn"); - return retval; -} - -int -einfo(const char *fmt, ...) -{ - int retval; - va_list ap; - - if (!fmt || is_quiet()) - return 0; - va_start(ap, fmt); - retval = _einfovn(fmt, ap); - retval += printf("\n"); - va_end(ap); - LASTCMD("einfo"); - return retval; -} - -int -ewarn(const char *fmt, ...) -{ - int retval; - va_list ap; - - if (!fmt || is_quiet()) - return 0; - va_start(ap, fmt); - elogv(LOG_WARNING, fmt, ap); - retval = _ewarnvn(fmt, ap); - retval += fprintf(stderr, "\n"); - va_end(ap); - LASTCMD("ewarn"); - return retval; -} - -void -ewarnx(const char *fmt, ...) -{ - int retval; - va_list ap; - - if (fmt && !is_quiet()) { - va_start(ap, fmt); - elogv(LOG_WARNING, fmt, ap); - retval = _ewarnvn(fmt, ap); - va_end(ap); - retval += fprintf(stderr, "\n"); - } - exit(EXIT_FAILURE); -} - -int -eerror(const char *fmt, ...) -{ - int retval; - va_list ap; - - if (!fmt || is_really_quiet()) - return 0; - va_start(ap, fmt); - elogv(LOG_ERR, fmt, ap); - retval = _eerrorvn(fmt, ap); - va_end(ap); - retval += fprintf(stderr, "\n"); - LASTCMD("eerror"); - return retval; -} - -void -eerrorx(const char *fmt, ...) -{ - va_list ap; - - if (fmt && !is_really_quiet()) { - va_start(ap, fmt); - elogv(LOG_ERR, fmt, ap); - _eerrorvn(fmt, ap); - va_end(ap); - fprintf(stderr, "\n"); - } - exit(EXIT_FAILURE); -} - -int -ebegin(const char *fmt, ...) -{ - int retval; - va_list ap; - - if (!fmt || is_quiet()) - return 0; - va_start(ap, fmt); - retval = _einfovn(fmt, ap); - va_end(ap); - retval += printf(" ..."); - if (colour_terminal(stdout)) - retval += printf("\n"); - LASTCMD("ebegin"); - return retval; -} - -static void -_eend(FILE *fp, int col, ECOLOR color, const char *msg) -{ - int i; - int cols; - - if (!msg) - return; - - cols = get_term_columns(fp) - (strlen(msg) + 5); - - /* cons25 is special - we need to remove one char, otherwise things - * do not align properly at all. */ - if (!term) { - term = getenv("TERM"); - if (term && strcmp(term, "cons25") == 0) - term_is_cons25 = true; - else - term_is_cons25 = false; - } - if (term_is_cons25) - cols--; - - if (cols > 0 && colour_terminal(fp)) { - fprintf(fp, "%s%s %s[%s %s %s]%s\n", up, tgoto(goto_column, 0, cols), - ecolor(ECOLOR_BRACKET), ecolor(color), msg, - ecolor(ECOLOR_BRACKET), ecolor(ECOLOR_NORMAL)); - } else { - if (col > 0) - for (i = 0; i < cols - col; i++) - fprintf(fp, " "); - fprintf(fp, " [ %s ]\n", msg); - } -} - -static int EINFO_PRINTF(3, 0) -_do_eend(const char *cmd, int retval, - const char *fmt, va_list ap) -{ - int col = 0; - FILE *fp = stdout; - va_list apc; - - if (fmt && *fmt != '\0' && retval != 0) { - fp = stderr; - va_copy(apc, ap); - if (strcmp(cmd, "ewend") == 0) - col = _ewarnvn(fmt, apc); - else - col = _eerrorvn(fmt, apc); - col += fprintf(fp, "\n"); - va_end(apc); - } - _eend(fp, col, - retval == 0 ? ECOLOR_GOOD : ECOLOR_BAD, - retval == 0 ? OK : NOT_OK); - return retval; -} - -int -eend(int retval, const char *fmt, ...) -{ - va_list ap; - - if (is_quiet()) - return retval; - va_start(ap, fmt); - _do_eend("eend", retval, fmt, ap); - va_end(ap); - LASTCMD("eend"); - return retval; -} - -int -ewend(int retval, const char *fmt, ...) -{ - va_list ap; - - if (is_quiet()) - return retval; - va_start(ap, fmt); - _do_eend("ewend", retval, fmt, ap); - va_end(ap); - LASTCMD("ewend"); - return retval; -} - -void -ebracket(int col, ECOLOR color, const char *msg) -{ - _eend(stdout, col, color, msg); -} - -void -eindent(void) -{ - char *env = getenv("EINFO_INDENT"); - int amount = 0; - char num[10]; - - if (env) { - errno = 0; - amount = strtoimax(env, NULL, 0); - if (errno != 0) - amount = 0; - } - amount += INDENT_WIDTH; - if (amount > INDENT_MAX) - amount = INDENT_MAX; - snprintf(num, 10, "%08d", amount); - setenv("EINFO_INDENT", num, 1); -} - -void eoutdent(void) -{ - char *env = getenv("EINFO_INDENT"); - int amount = 0; - char num[10]; - int serrno = errno; - - if (!env) - return; - errno = 0; - amount = strtoimax(env, NULL, 0); - if (errno != 0) - amount = 0; - else - amount -= INDENT_WIDTH; - if (amount <= 0) - unsetenv("EINFO_INDENT"); - else { - snprintf(num, 10, "%08d", amount); - setenv("EINFO_INDENT", num, 1); - } - errno = serrno; -} - -int -einfovn(const char *fmt, ...) -{ - int retval; - va_list ap; - - if (!fmt || !is_verbose()) - return 0; - va_start(ap, fmt); - retval = _einfovn(fmt, ap); - va_end(ap); - LASTCMD("einfovn"); - return retval; -} - -int -ewarnvn(const char *fmt, ...) -{ - int retval; - va_list ap; - - if (!fmt || !is_verbose()) - return 0; - va_start(ap, fmt); - retval = _ewarnvn(fmt, ap); - va_end(ap); - LASTCMD("ewarnvn"); - return retval; -} - -int -einfov(const char *fmt, ...) -{ - int retval; - va_list ap; - - if (!fmt || !is_verbose()) - return 0; - va_start(ap, fmt); - retval = _einfovn(fmt, ap); - retval += printf("\n"); - va_end(ap); - LASTCMD("einfov"); - return retval; -} - -int -ewarnv(const char *fmt, ...) -{ - int retval; - va_list ap; - - if (!fmt || !is_verbose()) - return 0; - va_start(ap, fmt); - retval = _ewarnvn(fmt, ap); - retval += printf("\n"); - va_end(ap); - LASTCMD("ewarnv"); - return retval; -} - -int -ebeginv(const char *fmt, ...) -{ - int retval; - va_list ap; - - if (!fmt || !is_verbose()) - return 0; - - va_start(ap, fmt); - retval = _einfovn(fmt, ap); - retval += printf(" ..."); - if (colour_terminal(stdout)) - retval += printf("\n"); - va_end(ap); - LASTCMD("ebeginv"); - return retval; -} - -int -eendv(int retval, const char *fmt, ...) -{ - va_list ap; - - if (!is_verbose()) - return 0; - va_start(ap, fmt); - _do_eend("eendv", retval, fmt, ap); - va_end(ap); - LASTCMD("eendv"); - return retval; -} - -int -ewendv(int retval, const char *fmt, ...) -{ - va_list ap; - - if (!is_verbose()) - return 0; - va_start(ap, fmt); - _do_eend("ewendv", retval, fmt, ap); - va_end(ap); - LASTCMD("ewendv"); - return retval; -} - -void -eindentv(void) -{ - if (is_verbose()) - eindent(); -} - -void -eoutdentv(void) -{ - if (is_verbose()) - eoutdent(); -} -- cgit v1.2.3