--- syslog-ng-1.4.11-orig/src/log.c Sun Feb 25 06:30:22 2001 +++ syslog-ng-1.4.11/src/log.c Fri Apr 27 16:28:32 2001 @@ -38,6 +38,9 @@ #include "log.h.x" #undef CLASS_DEFINE +static char aix_fwd_string[] = "Message forwarded from "; +static char repeat_msg_string[] = "last message repeated"; + static void parse_log_msg(struct log_info *lm, UINT32 length, UINT8 *data) { char *src; @@ -49,8 +52,11 @@ src = data; left = length; - + + /* Determine the priority of the message. Assume buffer starts + with '<' if there's one to read. */ if (left && src[0] == '<') { + /* Expected buffer format: .... */ src++; left--; pri = 0; @@ -72,21 +78,32 @@ left--; } } + /* No priority info in the buffer? Just assign a default. */ else { - lm->pri = LOG_USER | LOG_NOTICE; + lm->pri = LOG_USER | LOG_NOTICE; } - while (left && *src == ' ') { + + + while (left && *src == ' ') { /* Move past whitespace */ src++; left--; } + + /* If the next chars look like a date, then read them as a date. */ if (left >= 15) { - if (src[3] == ' ' && src[6] == ' ' && src[9] == ':' && src[12] == ':') { - struct tm tm, *nowtm; + /* Expected buffer format: MMM DD HH:MM:SS ... */ + + if (src[3] == ' ' && src[6] == ' ' && + src[9] == ':' && src[12] == ':') { + struct tm tm, *nowtm; + /* Just read the buffer data into a textual + datestamp. */ lm->date = c_format_cstring("%s", 15, src); src += 15; left -= 15; + /* And also make struct time timestamp for the msg */ nowtm = localtime(&now); memset(&tm, 0, sizeof(tm)); strptime(lm->date->data, "%b %e %H:%M:%S", &tm); @@ -97,54 +114,123 @@ lm->stamp = mktime(&tm); } } - - if (lm->date) { + + if (lm->date) { + /* Expected format: hostname program[pid]: */ + /* Possibly: Message forwarded from hostname: ... */ + char *hostname_start = NULL; + int hostname_len = 0; while (left && *src == ' ') { src++; /* skip whitespace */ left--; } - oldsrc = src; - oldleft = left; - while (left && *src != ' ' && *src != ':' && *src != '[') { - src++; - left--; + +/* fprintf(stderr, "DETECTING AIX FWD STRING. BUFFER:\n%s\n", src); */ + + /* Detect funny AIX syslogd forwarded message. */ + if (left >= (sizeof(aix_fwd_string) - 1) && + !memcmp(src, aix_fwd_string, sizeof(aix_fwd_string) - 1)) { + + oldsrc = src; + oldleft = left; + src += sizeof(aix_fwd_string) - 1; + left -= sizeof(aix_fwd_string) - 1; + hostname_start = src; + hostname_len = 0; + while (left && *src != ':') { + src++; + left--; + hostname_len++; + } + while (left && (*src == ' ' || *src == ':')) { + src++; /* skip whitespace */ + left--; + } } - if (left && *src == ' ') { - /* this was a hostname */ - lm->host = c_format_cstring("%s", oldleft - left, oldsrc); + +/* fprintf(stderr, "DETECTING LAST MSG REPEATED STRING. BUFFER:\n%s\n", src); */ + + /* Now, try to tell if it's a "last message repeated" line */ + if (left >= sizeof(repeat_msg_string) && + !memcmp(src, repeat_msg_string, + sizeof(repeat_msg_string) - 1)) { + ; /* It is. Do nothing since there's no hostname or + program name coming. */ } + /* It's a regular ol' message. */ else { + /* If we haven't already found the original hostname, + look for it now. */ + +/* fprintf(stderr, "DETECTING HOSTNAME. BUFFER:\n%s\n", src); */ + + oldsrc = src; + oldleft = left; + + while (left && *src != ' ' && *src != ':' + && *src != '[') { + src++; + left--; + } + + if (left && *src == ' ') { + /* This was a hostname. It came from a + syslog-ng, since syslogd doesn't send + hostnames. It's even better then the one + we got from the AIX fwd message, if we + did. */ + hostname_start = oldsrc; + hostname_len = oldleft - left; + } else { + src = oldsrc; + left = oldleft; + } + + /* Skip whitespace. */ + while (left && *src == ' ') { + src++; + left--; + } + + +/* fprintf(stderr, "DETECTING PROGRAM. BUFFER:\n%s\n", src); */ + + /* Try to extract a program name */ + oldsrc = src; + oldleft = left; + while (left && *src != ':' && *src != '[') { + src++; + left--; + } + if (left) { + lm->program = c_format_cstring("%s", + oldleft - left, oldsrc); + } + src = oldsrc; left = oldleft; } - while (left && *src == ' ') { - src++; /* skip whitespace */ - left--; - } - - oldsrc = src; - oldleft = left; - - while (left && *src != ':' && *src != '[') { - src++; - left--; - } - if (left) { - lm->program = c_format_cstring("%s", oldleft - left, oldsrc); - } - src = oldsrc; - left = oldleft; + /* If we did manage to find a hostname, store it. */ + if (hostname_start) + lm->host = c_format_cstring("%s", hostname_len, + hostname_start); } else { + /* Different format */ + oldsrc = src; oldleft = left; + /* A kernel message? Use 'kernel' as the program name. */ if ((lm->pri & LOG_FACMASK) == LOG_KERN) { lm->program = c_format_cstring("kernel"); } + /* No, not a kernel message. */ else { - while (left && *src != ' ' && *src != '[' && *src != ':' && - *src != '/' && *src != ',' && *src != '<') { + /* Capture the program name */ + while (left && *src != ' ' && *src != '[' + && *src != ':' && *src != '/' && + *src != ',' && *src != '<') { src++; left--; } @@ -157,10 +243,20 @@ lm->stamp = now; } + /* The rest of the buffer is the message body. But first, squash any + LFs or CRs! */ for (oldsrc = src, oldleft = left; oldleft >= 0; oldleft--, oldsrc++) { if (*oldsrc == '\n' || *oldsrc == '\r') *oldsrc = ' '; } lm->msg = c_format_cstring("%s", left, src); + +/* DEBUG */ +/* fprintf(stderr, "MESSAGE CONSTRUCTED:\nHOST(%s) PROG(%s) MSG(%s)\n", + lm->host ? lm->host->data : "NONE", + lm->program ? lm->program->data : "NONE", + lm->msg ? lm->msg->data : ""); */ +/* DEBUG -- zero out buffer so its easy to read during debugging... */ +/* bzero(data, length); */ } struct log_info *log_info_use(struct log_info *msg)