Page MenuHomePhorge

syslog.c
No OneTemporary

Authored By
Unknown
Size
7 KB
Referenced Files
None
Subscribers
None

syslog.c

/*
* Copyright (c) 1994-2011 Carnegie Mellon University. All rights reserved.
*
* 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.
*
* 3. The name "Carnegie Mellon University" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For permission or any legal
* details, please contact
* Carnegie Mellon University
* Center for Technology Transfer and Enterprise Creation
* 4615 Forbes Avenue
* Suite 302
* Pittsburgh, PA 15213
* (412) 268-7393, fax: (412) 268-7395
* innovation@andrew.cmu.edu
*
* 4. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by Computing Services
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
*
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <syslog.h>
#include <errno.h>
#include <unistd.h>
#include <regex.h>
#include <memory.h>
#include <CUnit/CUnit.h>
#include "cunit-syslog.h"
#if !HAVE___ATTRIBUTE__
#define __attribute__(x)
#endif
extern int verbose;
struct slmatch
{
const char *re; /* NULL => disabled */
unsigned int count;
regex_t cre; /* compiled regex */
};
#define MAX_SLMATCH 32
static unsigned int nslmatches = 0;
static struct slmatch slmatches[MAX_SLMATCH];
#if !defined(va_copy)
# if defined(__va_copy)
# define va_copy __va_copy
# else
# define va_copy(d,s) (d) = (s)
# endif
#endif
static char *match_error(struct slmatch *sl, int r)
{
static char buf[2048];
int n;
buf[0] = '\0';
if (sl->re)
snprintf(buf, sizeof(buf)-100, "/%s/: ", sl->re);
n = strlen(buf);
regerror(r, &sl->cre, buf+n, sizeof(buf)-n-1);
strcat(buf, "\n");
return buf;
}
static void vlog(int prio, const char *fmt, va_list args)
{
if (nslmatches) {
int e = errno; /* save errno Just In Case */
va_list args2;
unsigned int i;
int r;
char line[2048];
/* This only works for all cases because of the glibc
* extension which supports %m in printf() */
va_copy(args2, args);
vsnprintf(line, sizeof(line), fmt, args2);
va_end(args2);
for (i = 0 ; i < MAX_SLMATCH ; i++) {
if (!slmatches[i].re)
continue; /* empty slot */
r = regexec(&slmatches[i].cre, line, 0, NULL, 0);
if (!r) {
/* found */
if (verbose >= 2)
fprintf(stderr, "\nSYSLOG matched /%s/\n", slmatches[i].re);
slmatches[i].count++;
break;
}
if (r != REG_NOMATCH) {
/* error */
const char *msg = match_error(&slmatches[i], r);
CU_assertImplementation(0, __LINE__, msg, __FILE__, NULL, CU_TRUE);
/* NOTREACHED */
break;
}
}
errno = e;
}
/* glibc handles %m in vfprintf() so we don't need to do
* anything special to simulate that feature of syslog() */
/* TODO: find and expand %m on non-glibc platforms */
if (verbose < 2)
return;
fprintf(stderr, "\nSYSLOG %d[", prio & LOG_PRIMASK);
vfprintf(stderr, fmt, args);
fprintf(stderr, "]\n");
fflush(stderr);
}
#if defined(__GLIBC__)
/* Under some but not all combinations of options, glibc
* defines syslog() as an inline that calls this function */
void __syslog_chk(int prio, int whatever __attribute__((unused)),
const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vlog(prio, fmt, args);
va_end(args);
}
#endif
void syslog(int prio, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vlog(prio, fmt, args);
va_end(args);
}
unsigned int CU_syslogMatchBegin(const char *re, const char *filename,
unsigned int lineno)
{
unsigned int i;
int r;
/* find an empty slot */
for (i = 0 ; i < MAX_SLMATCH ; i++) {
if (!slmatches[i].re) {
/* found */
slmatches[i].re = re;
slmatches[i].count = 0;
r = regcomp(&slmatches[i].cre, re, REG_EXTENDED|REG_ICASE|REG_NOSUB);
if (r) {
const char *msg = match_error(&slmatches[i], r);
memset(&slmatches[i], 0, sizeof(slmatches[i]));
CU_assertImplementation(0, lineno, msg, filename, NULL, CU_TRUE);
/* NOTREACHED */
return 0;
}
nslmatches++;
return i+1;
}
}
CU_assertImplementation(0, lineno, "No free syslog match slots", filename, NULL, CU_TRUE);
/* NOTREACHED */
return 0;
}
unsigned int CU_syslogMatchEnd(unsigned int match, const char **sp)
{
unsigned int i;
unsigned int count = 0;
const char *s = NULL;
for (i = 0 ; i < MAX_SLMATCH ; i++) {
if (!slmatches[i].re)
continue; /* empty slot */
if (match && match != i+1)
continue; /* not the slot for @match */
if (!s)
s = slmatches[i].re;
else
s = "(multiple matches)";
count += slmatches[i].count;
regfree(&slmatches[i].cre);
memset(&slmatches[i], 0, sizeof(slmatches[i]));
nslmatches--;
if (match)
break; /* only looking for a single slot */
}
if (match && !s) {
s = "invalid match number";
count = ~0U;
}
if (sp)
*sp = s;
return count;
}
/* Meta-test code for CU_*SYSLOG* macros. */
#if 0
static void test_syslog(void)
{
int m1, m2;
// /* invalid regular expression, 1st macro fails */
// CU_SYSLOG_MATCH("[foo");
// syslog(LOG_ERR, "fnarp");
// CU_ASSERT_SYSLOG(/*all*/0, 0);
// /* no syslog messages => count is 0 */
// CU_SYSLOG_MATCH("foo.*baz");
// CU_ASSERT_SYSLOG(/*all*/0, 0);
// /* one syslog message which doesn't match => count is 0,
// * both macros succeed */
// CU_SYSLOG_MATCH("foo.*baz");
// syslog(LOG_ERR, "fnarp");
// CU_ASSERT_SYSLOG(/*all*/0, 0);
// /* one syslog message which does match => count is 1,
// * both macros succeed */
// CU_SYSLOG_MATCH("foo.*baz");
// syslog(LOG_ERR, "foo bar baz");
// CU_ASSERT_SYSLOG(/*all*/0, 1);
// /* one syslog message which does match => count is 1,
// * we check for 5, 2nd macro fails */
// CU_SYSLOG_MATCH("foo.*baz");
// syslog(LOG_ERR, "foo bar baz");
// CU_ASSERT_SYSLOG(/*all*/0, 5);
// /* one syslog message with multiple matches => count is 1,
// * all 3 macros succeed */
// CU_SYSLOG_MATCH("fuu.*bas");
// CU_SYSLOG_MATCH("bleah");
// syslog(LOG_ERR, "fuu bleah bas");
// CU_ASSERT_SYSLOG(/*all*/0, 1);
// /* one syslog message with multiple matches which are tracked
// * separately => count is 1, all 4 macros succeed */
// m1 = CU_SYSLOG_MATCH("fuu.*bas");
// m2 = CU_SYSLOG_MATCH("bleah");
// syslog(LOG_ERR, "fuu bleah bas");
// CU_ASSERT_SYSLOG(m1, 1);
// CU_ASSERT_SYSLOG(m2, 0);
}
#endif

File Metadata

Mime Type
text/x-c
Expires
Fri, Apr 24, 10:54 AM (1 w, 3 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18816291
Default Alt Text
syslog.c (7 KB)

Event Timeline