1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
|
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include "warnp.h"
static int initialized = 0;
static char * name = NULL;
static int use_syslog = 0;
static int syslog_priority = LOG_WARNING;
/* Free the name string and clean up writing to the syslog (if applicable). */
static void
warnp_atexit(void)
{
/* Clean up writing to the syslog (if applicable). */
if (use_syslog)
closelog();
free(name);
name = NULL;
}
/**
* warnp_setprogname(progname):
* Set the program name to be used by warn() and warnx() to ${progname}.
*/
void
warnp_setprogname(const char * progname)
{
const char * p;
/* Free the name if we already have one. */
free(name);
/* Find the last segment of the program name. */
for (p = progname; progname[0] != '\0'; progname++)
if (progname[0] == '/')
p = progname + 1;
/* Copy the name string. */
name = strdup(p);
/* If we haven't already done so, register our exit handler. */
if (initialized == 0) {
atexit(warnp_atexit);
initialized = 1;
}
}
/* This function will preserve errno. */
void
warn(const char * fmt, ...)
{
va_list ap;
char msgbuf[WARNP_SYSLOG_MAX_LINE + 1];
int saved_errno;
/* Save errno in case it gets clobbered. */
saved_errno = errno;
va_start(ap, fmt);
if (use_syslog == 0) {
#ifdef _MSC_VER
/* Print to stderr (no flockfile in Windows) */
fprintf(stderr, "%s", (name != NULL) ? name : "(unknown)");
if (fmt != NULL) {
fprintf(stderr, ": ");
vfprintf(stderr, fmt, ap);
}
fprintf(stderr, ": %s\n", strerror(saved_errno));
#else
/* Stop other threads writing to stderr. */
flockfile(stderr);
/* Print to stderr. */
fprintf(stderr, "%s", (name != NULL) ? name : "(unknown)");
if (fmt != NULL) {
fprintf(stderr, ": ");
vfprintf(stderr, fmt, ap);
}
fprintf(stderr, ": %s\n", strerror(saved_errno));
/* Allow other threads to write to stderr. */
funlockfile(stderr);
#endif
} else {
/* Print to syslog. */
if (fmt != NULL) {
/* No need to print "${name}: "; syslog does it. */
vsnprintf(msgbuf, WARNP_SYSLOG_MAX_LINE + 1, fmt, ap);
syslog(syslog_priority, "%s: %s\n", msgbuf,
strerror(saved_errno));
} else
syslog(syslog_priority, "%s\n", strerror(saved_errno));
}
va_end(ap);
/* Restore saved errno. */
errno = saved_errno;
}
/* This function will preserve errno. */
void
warnx(const char * fmt, ...)
{
va_list ap;
char msgbuf[WARNP_SYSLOG_MAX_LINE + 1];
int saved_errno;
/* Save errno in case it gets clobbered. */
saved_errno = errno;
va_start(ap, fmt);
if (use_syslog == 0) {
#ifdef _MSC_VER
/* Print to stderr (no flockfile in Windows) */
fprintf(stderr, "%s", (name != NULL) ? name : "(unknown)");
if (fmt != NULL) {
fprintf(stderr, ": ");
vfprintf(stderr, fmt, ap);
}
fprintf(stderr, "\n");
#else
/* Stop other threads writing to stderr. */
flockfile(stderr);
/* Print to stderr. */
fprintf(stderr, "%s", (name != NULL) ? name : "(unknown)");
if (fmt != NULL) {
fprintf(stderr, ": ");
vfprintf(stderr, fmt, ap);
}
fprintf(stderr, "\n");
/* Allow other threads to write to stderr. */
funlockfile(stderr);
#endif
} else {
/* Print to syslog. */
if (fmt != NULL) {
/* No need to print "${name}: "; syslog does it. */
vsnprintf(msgbuf, WARNP_SYSLOG_MAX_LINE + 1, fmt, ap);
syslog(syslog_priority, "%s\n", msgbuf);
} else
syslog(syslog_priority, "\n");
}
va_end(ap);
/* Restore saved errno. */
errno = saved_errno;
}
/**
* warnp_syslog(enable):
* Send future messages to syslog if ${enable} is non-zero. Messages to
* syslog will be truncated at WARNP_SYSLOG_MAX_LINE characters.
*/
void
warnp_syslog(int enable)
{
/* Clean up writing to the syslog (if applicable). */
if (use_syslog && !enable)
closelog();
use_syslog = enable;
}
/**
* warnp_syslog_priority(priority):
* Tag future syslog messages with priority ${priority}. Do not enable
* syslog messages; for that, use warnp_syslog().
*/
void
warnp_syslog_priority(int priority)
{
syslog_priority = priority;
}
|