878 lines
16 KiB
C
878 lines
16 KiB
C
|
/*
|
||
|
einfo.c
|
||
|
Gentoo informational functions
|
||
|
Copyright 2007 Gentoo Foundation
|
||
|
*/
|
||
|
|
||
|
#include <sys/types.h>
|
||
|
#include <sys/ioctl.h>
|
||
|
#include <sys/stat.h>
|
||
|
#include <errno.h>
|
||
|
#include <limits.h>
|
||
|
#include <stdarg.h>
|
||
|
#include <stdbool.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <syslog.h>
|
||
|
#include <unistd.h>
|
||
|
|
||
|
#include "einfo.h"
|
||
|
#include "rc.h"
|
||
|
#include "rc-misc.h"
|
||
|
|
||
|
/* Incase we cannot work out how many columns from ioctl, supply a default */
|
||
|
#define DEFAULT_COLS 80
|
||
|
|
||
|
#define OK "ok"
|
||
|
#define NOT_OK "!!"
|
||
|
|
||
|
#define CHECK_VERBOSE if (! is_env ("RC_VERBOSE", "yes")) return 0
|
||
|
|
||
|
/* Number of spaces for an indent */
|
||
|
#define INDENT_WIDTH 2
|
||
|
|
||
|
/* How wide can the indent go? */
|
||
|
#define INDENT_MAX 40
|
||
|
|
||
|
#define EBUFFER_LOCK RC_SVCDIR "ebuffer/.lock"
|
||
|
|
||
|
/* A cheat sheet of colour capable terminals
|
||
|
This is taken from DIR_COLORS from GNU coreutils
|
||
|
We embed it here as we shouldn't depend on coreutils */
|
||
|
static const char *colour_terms[] =
|
||
|
{
|
||
|
"Eterm",
|
||
|
"ansi",
|
||
|
"color-xterm",
|
||
|
"con132x25",
|
||
|
"con132x30",
|
||
|
"con132x43",
|
||
|
"con132x60",
|
||
|
"con80x25",
|
||
|
"con80x28",
|
||
|
"con80x30",
|
||
|
"con80x43",
|
||
|
"con80x50",
|
||
|
"con80x60",
|
||
|
"cons25",
|
||
|
"console",
|
||
|
"cygwin",
|
||
|
"dtterm",
|
||
|
"gnome",
|
||
|
"konsole",
|
||
|
"kterm",
|
||
|
"linux",
|
||
|
"linux-c",
|
||
|
"mach-color",
|
||
|
"mlterm",
|
||
|
"putty",
|
||
|
"rxvt",
|
||
|
"rxvt-cygwin",
|
||
|
"rxvt-cygwin-native",
|
||
|
"rxvt-unicode",
|
||
|
"screen",
|
||
|
"screen-bce",
|
||
|
"screen-w",
|
||
|
"screen.linux",
|
||
|
"vt100",
|
||
|
"xterm",
|
||
|
"xterm-256color",
|
||
|
"xterm-color",
|
||
|
"xterm-debian",
|
||
|
NULL
|
||
|
};
|
||
|
|
||
|
static bool is_env (const char *var, const char *val)
|
||
|
{
|
||
|
char *v;
|
||
|
|
||
|
if (! var)
|
||
|
return (false);
|
||
|
|
||
|
v = getenv (var);
|
||
|
if (! v)
|
||
|
return (val == NULL ? true : false);
|
||
|
|
||
|
return (strcasecmp (v, val) == 0 ? true : false);
|
||
|
}
|
||
|
|
||
|
bool colour_terminal (void)
|
||
|
{
|
||
|
static int in_colour = -1;
|
||
|
int i = 0;
|
||
|
char *term;
|
||
|
|
||
|
if (in_colour == 0)
|
||
|
return (false);
|
||
|
if (in_colour == 1)
|
||
|
return (true);
|
||
|
|
||
|
term = getenv ("TERM");
|
||
|
/* If $TERM isn't set then the chances are we're in single user mode */
|
||
|
if (! term)
|
||
|
return (true);
|
||
|
|
||
|
while (colour_terms[i])
|
||
|
{
|
||
|
if (strcmp (colour_terms[i], term) == 0)
|
||
|
{
|
||
|
in_colour = 1;
|
||
|
return (true);
|
||
|
}
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
in_colour = 0;
|
||
|
return (false);
|
||
|
}
|
||
|
|
||
|
static int get_term_columns (void)
|
||
|
{
|
||
|
#ifdef TIOCGSIZE /* BSD */
|
||
|
struct ttysize ts;
|
||
|
|
||
|
if (ioctl(0, TIOCGSIZE, &ts) == 0)
|
||
|
return (ts.ts_cols);
|
||
|
#elif TIOCGWINSZ /* Linux */
|
||
|
struct winsize ws;
|
||
|
|
||
|
if (ioctl(0, TIOCGWINSZ, &ws) == 0)
|
||
|
return (ws.ws_col);
|
||
|
#endif
|
||
|
|
||
|
return (DEFAULT_COLS);
|
||
|
}
|
||
|
|
||
|
static int ebuffer (const char *cmd, int retval, const char *fmt, va_list ap)
|
||
|
{
|
||
|
char *file = getenv ("RC_EBUFFER");
|
||
|
FILE *fp;
|
||
|
char buffer[RC_LINEBUFFER];
|
||
|
int l = 1;
|
||
|
|
||
|
if (! file || ! cmd || strlen (cmd) < 4)
|
||
|
return (0);
|
||
|
|
||
|
if (! (fp = fopen (file, "a")))
|
||
|
{
|
||
|
fprintf (stderr, "fopen `%s': %s\n", file, strerror (errno));
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
fprintf (fp, "%s %d ", cmd, retval);
|
||
|
|
||
|
if (fmt)
|
||
|
{
|
||
|
l = vsnprintf (buffer, sizeof (buffer), fmt, ap);
|
||
|
fprintf (fp, "%d %s\n", l, buffer);
|
||
|
}
|
||
|
else
|
||
|
fprintf (fp, "0\n");
|
||
|
|
||
|
fclose (fp);
|
||
|
return (l);
|
||
|
}
|
||
|
|
||
|
typedef struct func
|
||
|
{
|
||
|
const char *name;
|
||
|
int (*efunc) (const char *fmt, ...);
|
||
|
int (*eefunc) (int retval, const char *fmt, ...);
|
||
|
void (*eind) (void);
|
||
|
} func_t;
|
||
|
|
||
|
static const func_t funcmap[] = {
|
||
|
{ "einfon", &einfon, NULL, NULL },
|
||
|
{ "ewarnn", &ewarnn, NULL, NULL},
|
||
|
{ "eerrorn", &eerrorn, NULL, NULL},
|
||
|
{ "einfo", &einfo, NULL, NULL },
|
||
|
{ "ewarn", &ewarn, NULL, NULL },
|
||
|
{ "eerror", &eerror, NULL, NULL },
|
||
|
{ "ebegin", &ebegin, NULL, NULL },
|
||
|
{ "eend", NULL, &eend, NULL },
|
||
|
{ "ewend", NULL, &ewend, NULL },
|
||
|
{ "eindent", NULL, NULL, &eindent },
|
||
|
{ "eoutdent", NULL, NULL, &eoutdent },
|
||
|
{ "veinfon", &veinfon, NULL, NULL },
|
||
|
{ "vewarnn", &vewarnn, NULL, NULL },
|
||
|
{ "veinfo", &veinfo, NULL, NULL },
|
||
|
{ "vewarn", &vewarn, NULL, NULL },
|
||
|
{ "vebegin", &vebegin, NULL, NULL },
|
||
|
{ "veend", NULL, &veend, NULL },
|
||
|
{ "vewend", NULL, &vewend, NULL },
|
||
|
{ "veindent" ,NULL, NULL, &veindent },
|
||
|
{ "veoutdent", NULL, NULL, &veoutdent },
|
||
|
{ NULL, NULL, NULL, NULL },
|
||
|
};
|
||
|
|
||
|
void eflush (void)
|
||
|
{
|
||
|
FILE *fp;
|
||
|
char *file = getenv ("RC_EBUFFER");
|
||
|
char buffer[RC_LINEBUFFER];
|
||
|
char *cmd;
|
||
|
int retval = 0;
|
||
|
int length = 0;
|
||
|
char *token;
|
||
|
char *p;
|
||
|
struct stat buf;
|
||
|
pid_t pid;
|
||
|
char newfile[PATH_MAX];
|
||
|
int i = 1;
|
||
|
|
||
|
if (! file|| (stat (file, &buf) != 0))
|
||
|
{
|
||
|
errno = 0;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Find a unique name for our file */
|
||
|
while (true)
|
||
|
{
|
||
|
snprintf (newfile, sizeof (newfile), "%s.%d", file, i);
|
||
|
if (stat (newfile, &buf) != 0)
|
||
|
{
|
||
|
if (rename (file, newfile))
|
||
|
fprintf (stderr, "rename `%s' `%s': %s\n", file, newfile,
|
||
|
strerror (errno));
|
||
|
break;
|
||
|
}
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
/* We fork a child process here so we don't hold anything up */
|
||
|
if ((pid = fork ()) == -1)
|
||
|
{
|
||
|
fprintf (stderr, "fork: %s", strerror (errno));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (pid != 0)
|
||
|
return;
|
||
|
|
||
|
/* Spin until we can lock the ebuffer */
|
||
|
while (true)
|
||
|
{
|
||
|
struct timeval tv;
|
||
|
tv.tv_sec = 0;
|
||
|
tv.tv_usec = 20000;
|
||
|
select (0, NULL, NULL, NULL, &tv);
|
||
|
errno = 0;
|
||
|
if (link (newfile, EBUFFER_LOCK) == 0)
|
||
|
break;
|
||
|
if (errno != EEXIST)
|
||
|
fprintf (stderr, "link `%s' `%s': %s\n", newfile, EBUFFER_LOCK,
|
||
|
strerror (errno));
|
||
|
}
|
||
|
|
||
|
if (! (fp = fopen (newfile, "r")))
|
||
|
{
|
||
|
fprintf (stderr, "fopen `%s': %s\n", newfile, strerror (errno));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
unsetenv ("RC_EBUFFER");
|
||
|
|
||
|
memset (buffer, 0, RC_LINEBUFFER);
|
||
|
while (fgets (buffer, RC_LINEBUFFER, fp))
|
||
|
{
|
||
|
i = strlen (buffer) - 1;
|
||
|
if (i < 1)
|
||
|
continue;
|
||
|
|
||
|
if (buffer[i] == '\n')
|
||
|
buffer[i] = 0;
|
||
|
|
||
|
p = buffer;
|
||
|
cmd = strsep (&p, " ");
|
||
|
token = strsep (&p, " ");
|
||
|
if (sscanf (token, "%d", &retval) != 1)
|
||
|
{
|
||
|
fprintf (stderr, "eflush `%s': not a number", token);
|
||
|
continue;
|
||
|
}
|
||
|
token = strsep (&p, " ");
|
||
|
if (sscanf (token, "%d", &length) != 1)
|
||
|
{
|
||
|
fprintf (stderr, "eflush `%s': not a number", token);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
i = 0;
|
||
|
while (funcmap[i].name)
|
||
|
{
|
||
|
if (strcmp (funcmap[i].name, cmd) == 0)
|
||
|
{
|
||
|
if (funcmap[i].efunc)
|
||
|
{
|
||
|
if (p)
|
||
|
funcmap[i].efunc ("%s", p);
|
||
|
else
|
||
|
funcmap[i].efunc (NULL, NULL);
|
||
|
}
|
||
|
else if (funcmap[i].eefunc)
|
||
|
{
|
||
|
if (p)
|
||
|
funcmap[i].eefunc (retval, "%s", p);
|
||
|
else
|
||
|
funcmap[i].eefunc (retval, NULL, NULL);
|
||
|
}
|
||
|
else if (funcmap[i].eind)
|
||
|
funcmap[i].eind ();
|
||
|
else
|
||
|
fprintf (stderr, "eflush `%s': no function defined\n", cmd);
|
||
|
break;
|
||
|
}
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
if (! funcmap[i].name)
|
||
|
fprintf (stderr, "eflush `%s': invalid function\n", cmd);
|
||
|
}
|
||
|
fclose (fp);
|
||
|
|
||
|
if (unlink (EBUFFER_LOCK))
|
||
|
fprintf (stderr, "unlink `%s': %s", EBUFFER_LOCK, strerror (errno));
|
||
|
|
||
|
if (unlink (newfile))
|
||
|
fprintf (stderr, "unlink `%s': %s", newfile, strerror (errno));
|
||
|
|
||
|
_exit (EXIT_SUCCESS);
|
||
|
}
|
||
|
|
||
|
#define EBUFFER(_cmd, _retval, _fmt, _ap) \
|
||
|
{ \
|
||
|
int _i = ebuffer (_cmd, _retval, _fmt, _ap); \
|
||
|
if (_i) \
|
||
|
return (_i); \
|
||
|
}
|
||
|
|
||
|
static void elog (int level, const char *fmt, va_list ap)
|
||
|
{
|
||
|
char *e = getenv ("RC_ELOG");
|
||
|
|
||
|
if (e)
|
||
|
{
|
||
|
closelog ();
|
||
|
openlog (e, LOG_PID, LOG_DAEMON);
|
||
|
vsyslog (level, fmt, ap);
|
||
|
}
|
||
|
}
|
||
|
static int _eindent (FILE *stream)
|
||
|
{
|
||
|
char *env = getenv ("RC_EINDENT");
|
||
|
int amount = 0;
|
||
|
char indent[INDENT_MAX];
|
||
|
|
||
|
if (env)
|
||
|
{
|
||
|
errno = 0;
|
||
|
amount = strtol (env, NULL, 0);
|
||
|
if (errno != 0 || amount < 0)
|
||
|
amount = 0;
|
||
|
else if (amount > INDENT_MAX)
|
||
|
amount = INDENT_MAX;
|
||
|
|
||
|
if (amount > 0)
|
||
|
memset (indent, ' ', amount);
|
||
|
}
|
||
|
|
||
|
/* Terminate it */
|
||
|
memset (indent + amount, 0, 1);
|
||
|
|
||
|
return (fprintf (stream, "%s", indent));
|
||
|
}
|
||
|
|
||
|
#define VEINFON(_file, _colour) \
|
||
|
if (colour_terminal ()) \
|
||
|
fprintf (_file, " " _colour "*" EINFO_NORMAL " "); \
|
||
|
else \
|
||
|
fprintf (_file, " * "); \
|
||
|
retval += _eindent (_file); \
|
||
|
retval += vfprintf (_file, fmt, ap) + 3; \
|
||
|
if (colour_terminal ()) \
|
||
|
fprintf (_file, "\033[K");
|
||
|
|
||
|
static int _veinfon (const char *fmt, va_list ap)
|
||
|
{
|
||
|
int retval = 0;
|
||
|
|
||
|
VEINFON (stdout, EINFO_GOOD);
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
static int _vewarnn (const char *fmt, va_list ap)
|
||
|
{
|
||
|
int retval = 0;
|
||
|
|
||
|
VEINFON (stdout, EINFO_WARN);
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
static int _veerrorn (const char *fmt, va_list ap)
|
||
|
{
|
||
|
int retval = 0;
|
||
|
|
||
|
VEINFON (stderr, EINFO_BAD);
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
int einfon (const char *fmt, ...)
|
||
|
{
|
||
|
int retval;
|
||
|
va_list ap;
|
||
|
|
||
|
if (! fmt || is_env ("RC_QUIET", "yes"))
|
||
|
return (0);
|
||
|
|
||
|
va_start (ap, fmt);
|
||
|
if (! (retval = ebuffer ("einfon", 0, fmt, ap)))
|
||
|
retval = _veinfon (fmt, ap);
|
||
|
va_end (ap);
|
||
|
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
int ewarnn (const char *fmt, ...)
|
||
|
{
|
||
|
int retval;
|
||
|
va_list ap;
|
||
|
|
||
|
if (! fmt || is_env ("RC_QUIET", "yes"))
|
||
|
return (0);
|
||
|
|
||
|
va_start (ap, fmt);
|
||
|
if (! (retval = ebuffer ("ewarnn", 0, fmt, ap)))
|
||
|
retval = _vewarnn (fmt, ap);
|
||
|
va_end (ap);
|
||
|
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
int eerrorn (const char *fmt, ...)
|
||
|
{
|
||
|
int retval;
|
||
|
va_list ap;
|
||
|
|
||
|
va_start (ap, fmt);
|
||
|
if (! (retval = ebuffer ("eerrorn", 0, fmt, ap)))
|
||
|
retval = _veerrorn (fmt, ap);
|
||
|
va_end (ap);
|
||
|
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
int einfo (const char *fmt, ...)
|
||
|
{
|
||
|
int retval;
|
||
|
va_list ap;
|
||
|
|
||
|
if (! fmt || is_env ("RC_QUIET", "yes"))
|
||
|
return (0);
|
||
|
|
||
|
va_start (ap, fmt);
|
||
|
if (! (retval = ebuffer ("einfo", 0, fmt, ap)))
|
||
|
{
|
||
|
retval = _veinfon (fmt, ap);
|
||
|
retval += printf ("\n");
|
||
|
}
|
||
|
va_end (ap);
|
||
|
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
int ewarn (const char *fmt, ...)
|
||
|
{
|
||
|
int retval;
|
||
|
va_list ap;
|
||
|
|
||
|
if (! fmt || is_env ("RC_QUIET", "yes"))
|
||
|
return (0);
|
||
|
|
||
|
va_start (ap, fmt);
|
||
|
elog (LOG_WARNING, fmt, ap);
|
||
|
if (! (retval = ebuffer ("ewarn", 0, fmt, ap)))
|
||
|
{
|
||
|
retval = _vewarnn (fmt, ap);
|
||
|
retval += printf ("\n");
|
||
|
}
|
||
|
va_end (ap);
|
||
|
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
void ewarnx (const char *fmt, ...)
|
||
|
{
|
||
|
int retval;
|
||
|
va_list ap;
|
||
|
|
||
|
if (fmt && ! is_env ("RC_QUIET", "yes"))
|
||
|
{
|
||
|
va_start (ap, fmt);
|
||
|
elog (LOG_WARNING, fmt, ap);
|
||
|
retval = _vewarnn (fmt, ap);
|
||
|
va_end (ap);
|
||
|
retval += printf ("\n");
|
||
|
}
|
||
|
exit (EXIT_FAILURE);
|
||
|
}
|
||
|
|
||
|
int eerror (const char *fmt, ...)
|
||
|
{
|
||
|
int retval;
|
||
|
va_list ap;
|
||
|
|
||
|
if (! fmt)
|
||
|
return (0);
|
||
|
|
||
|
va_start (ap, fmt);
|
||
|
elog (LOG_ERR, fmt, ap);
|
||
|
retval = _veerrorn (fmt, ap);
|
||
|
va_end (ap);
|
||
|
retval += fprintf (stderr, "\n");
|
||
|
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
void eerrorx (const char *fmt, ...)
|
||
|
{
|
||
|
va_list ap;
|
||
|
|
||
|
if (fmt)
|
||
|
{
|
||
|
va_start (ap, fmt);
|
||
|
elog (LOG_ERR, fmt, ap);
|
||
|
_veerrorn (fmt, ap);
|
||
|
va_end (ap);
|
||
|
printf ("\n");
|
||
|
}
|
||
|
exit (EXIT_FAILURE);
|
||
|
}
|
||
|
|
||
|
int ebegin (const char *fmt, ...)
|
||
|
{
|
||
|
int retval;
|
||
|
va_list ap;
|
||
|
|
||
|
if (! fmt || is_env ("RC_QUIET", "yes"))
|
||
|
return (0);
|
||
|
|
||
|
va_start (ap, fmt);
|
||
|
if ((retval = ebuffer ("ebegin", 0, fmt, ap)))
|
||
|
{
|
||
|
va_end (ap);
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
retval = _veinfon (fmt, ap);
|
||
|
va_end (ap);
|
||
|
retval += printf (" ...");
|
||
|
if (colour_terminal ())
|
||
|
retval += printf ("\n");
|
||
|
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
static void _eend (int col, einfo_color_t color, const char *msg)
|
||
|
{
|
||
|
FILE *fp = stdout;
|
||
|
int i;
|
||
|
int cols;
|
||
|
|
||
|
if (! msg)
|
||
|
return;
|
||
|
|
||
|
if (color == einfo_bad)
|
||
|
fp = stderr;
|
||
|
|
||
|
cols = get_term_columns () - (strlen (msg) + 6);
|
||
|
|
||
|
if (cols > 0 && colour_terminal ())
|
||
|
{
|
||
|
fprintf (fp, "\033[A\033[%dC %s[ ", cols, EINFO_BRACKET);
|
||
|
switch (color)
|
||
|
{
|
||
|
case einfo_good:
|
||
|
fprintf (fp, EINFO_GOOD);
|
||
|
break;
|
||
|
case einfo_warn:
|
||
|
fprintf (fp, EINFO_WARN);
|
||
|
break;
|
||
|
case einfo_bad:
|
||
|
fprintf (fp, EINFO_BAD);
|
||
|
break;
|
||
|
case einfo_hilite:
|
||
|
fprintf (fp, EINFO_HILITE);
|
||
|
break;
|
||
|
case einfo_bracket:
|
||
|
fprintf (fp, EINFO_BRACKET);
|
||
|
break;
|
||
|
case einfo_normal:
|
||
|
fprintf (fp, EINFO_NORMAL);
|
||
|
break;
|
||
|
}
|
||
|
fprintf (fp, "%s%s ]%s\n", msg, EINFO_BRACKET, EINFO_NORMAL);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for (i = -1; i < cols - col; i++)
|
||
|
fprintf (fp, " ");
|
||
|
fprintf (fp, "[ %s ]\n", msg);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static int _do_eend (const char *cmd, int retval, const char *fmt, va_list ap)
|
||
|
{
|
||
|
int col = 0;
|
||
|
FILE *fp;
|
||
|
|
||
|
if (ebuffer (cmd, retval, fmt, ap))
|
||
|
return (retval);
|
||
|
|
||
|
if (fmt && retval != 0)
|
||
|
{
|
||
|
if (strcmp (cmd, "ewend") == 0)
|
||
|
{
|
||
|
col = _vewarnn (fmt, ap);
|
||
|
fp = stdout;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
col = _veerrorn (fmt, ap);
|
||
|
fp = stderr;
|
||
|
}
|
||
|
if (colour_terminal ())
|
||
|
fprintf (fp, "\n");
|
||
|
}
|
||
|
|
||
|
_eend (col, retval == 0 ? einfo_good : einfo_bad, retval == 0 ? OK : NOT_OK);
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
int eend (int retval, const char *fmt, ...)
|
||
|
{
|
||
|
va_list ap;
|
||
|
|
||
|
if (is_env ("RC_QUIET", "yes"))
|
||
|
return (retval);
|
||
|
|
||
|
va_start (ap, fmt);
|
||
|
_do_eend ("eend", retval, fmt, ap);
|
||
|
va_end (ap);
|
||
|
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
int ewend (int retval, const char *fmt, ...)
|
||
|
{
|
||
|
va_list ap;
|
||
|
|
||
|
if (is_env ("RC_QUIET", "yes"))
|
||
|
return (retval);
|
||
|
|
||
|
va_start (ap, fmt);
|
||
|
_do_eend ("ewend", retval, fmt, ap);
|
||
|
va_end (ap);
|
||
|
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
void ebracket (int col, einfo_color_t color, const char *msg)
|
||
|
{
|
||
|
_eend (col, color, msg);
|
||
|
}
|
||
|
|
||
|
void eindent (void)
|
||
|
{
|
||
|
char *env = getenv ("RC_EINDENT");
|
||
|
int amount = 0;
|
||
|
char num[10];
|
||
|
|
||
|
if (ebuffer ("eindent", 0, NULL, NULL))
|
||
|
return;
|
||
|
|
||
|
if (env)
|
||
|
{
|
||
|
errno = 0;
|
||
|
amount = strtol (env, NULL, 0);
|
||
|
if (errno != 0)
|
||
|
amount = 0;
|
||
|
}
|
||
|
|
||
|
amount += INDENT_WIDTH;
|
||
|
if (amount > INDENT_MAX)
|
||
|
amount = INDENT_MAX;
|
||
|
|
||
|
snprintf (num, 10, "%08d", amount);
|
||
|
setenv ("RC_EINDENT", num, 1);
|
||
|
}
|
||
|
|
||
|
void eoutdent (void)
|
||
|
{
|
||
|
char *env = getenv ("RC_EINDENT");
|
||
|
int amount = 0;
|
||
|
char num[10];
|
||
|
|
||
|
if (ebuffer ("eoutdent", 0, NULL, NULL))
|
||
|
return;
|
||
|
|
||
|
if (! env)
|
||
|
return;
|
||
|
|
||
|
errno = 0;
|
||
|
amount = strtol (env, NULL, 0);
|
||
|
if (errno != 0)
|
||
|
amount = 0;
|
||
|
else
|
||
|
amount -= INDENT_WIDTH;
|
||
|
|
||
|
if (amount <= 0)
|
||
|
unsetenv ("RC_EINDENT");
|
||
|
else
|
||
|
{
|
||
|
snprintf (num, 10, "%08d", amount);
|
||
|
setenv ("RC_EINDENT", num, 1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int veinfon (const char *fmt, ...)
|
||
|
{
|
||
|
int retval;
|
||
|
va_list ap;
|
||
|
|
||
|
CHECK_VERBOSE;
|
||
|
|
||
|
if (! fmt)
|
||
|
return (0);
|
||
|
|
||
|
va_start (ap, fmt);
|
||
|
if (! (retval = ebuffer ("veinfon", 0, fmt, ap)))
|
||
|
retval = _veinfon (fmt, ap);
|
||
|
va_end (ap);
|
||
|
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
int vewarnn (const char *fmt, ...)
|
||
|
{
|
||
|
int retval;
|
||
|
va_list ap;
|
||
|
|
||
|
CHECK_VERBOSE;
|
||
|
|
||
|
if (! fmt)
|
||
|
return (0);
|
||
|
|
||
|
va_start (ap, fmt);
|
||
|
if (! (retval = ebuffer ("vewarnn", 0, fmt, ap)))
|
||
|
retval = _vewarnn (fmt, ap);
|
||
|
va_end (ap);
|
||
|
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
int veinfo (const char *fmt, ...)
|
||
|
{
|
||
|
int retval;
|
||
|
va_list ap;
|
||
|
|
||
|
CHECK_VERBOSE;
|
||
|
|
||
|
if (! fmt)
|
||
|
return (0);
|
||
|
|
||
|
va_start (ap, fmt);
|
||
|
if (! (retval = ebuffer ("veinfo", 0, fmt, ap)))
|
||
|
{
|
||
|
retval = _veinfon (fmt, ap);
|
||
|
retval += printf ("\n");
|
||
|
}
|
||
|
va_end (ap);
|
||
|
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
int vewarn (const char *fmt, ...)
|
||
|
{
|
||
|
int retval;
|
||
|
va_list ap;
|
||
|
|
||
|
CHECK_VERBOSE;
|
||
|
|
||
|
if (! fmt)
|
||
|
return (0);
|
||
|
|
||
|
va_start (ap, fmt);
|
||
|
if (! (retval = ebuffer ("vewarn", 0, fmt, ap)))
|
||
|
{
|
||
|
retval = _vewarnn (fmt, ap);
|
||
|
retval += printf ("\n");
|
||
|
}
|
||
|
va_end (ap);
|
||
|
retval += printf ("\n");
|
||
|
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
int vebegin (const char *fmt, ...)
|
||
|
{
|
||
|
int retval;
|
||
|
va_list ap;
|
||
|
|
||
|
CHECK_VERBOSE;
|
||
|
|
||
|
if (! fmt)
|
||
|
return (0);
|
||
|
|
||
|
va_start (ap, fmt);
|
||
|
if (! (retval = ebuffer ("vewarn", 0, fmt, ap)))
|
||
|
{
|
||
|
retval = _veinfon (fmt, ap);
|
||
|
retval += printf (" ...");
|
||
|
if (colour_terminal ())
|
||
|
retval += printf ("\n");
|
||
|
}
|
||
|
va_end (ap);
|
||
|
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
int veend (int retval, const char *fmt, ...)
|
||
|
{
|
||
|
va_list ap;
|
||
|
|
||
|
CHECK_VERBOSE;
|
||
|
|
||
|
va_start (ap, fmt);
|
||
|
_do_eend ("veend", retval, fmt, ap);
|
||
|
va_end (ap);
|
||
|
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
int vewend (int retval, const char *fmt, ...)
|
||
|
{
|
||
|
va_list ap;
|
||
|
|
||
|
CHECK_VERBOSE;
|
||
|
|
||
|
va_start (ap, fmt);
|
||
|
_do_eend ("vewend", retval, fmt, ap);
|
||
|
va_end (ap);
|
||
|
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
void veindent (void)
|
||
|
{
|
||
|
if (is_env ("RC_VERBOSE", "yes"))
|
||
|
eindent ();
|
||
|
}
|
||
|
|
||
|
void veoutdent (void)
|
||
|
{
|
||
|
if (is_env ("RC_VERBOSE", "yes"))
|
||
|
eoutdent ();
|
||
|
}
|