#include <libintl.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "librsc.h"
#include "adm.h"
#include "event_mess.h"
#define TAB '\t'
#define BACKSLASH_ESCAPE '\\'
static char *
getEventLogMessage(int eventId)
{
int category;
int event;
char **alertCategory;
char *alertMessage;
category = eventId >> 16;
event = eventId &0x0000ffff;
alertCategory = rsc_alerts[category];
if (alertCategory) {
alertMessage = alertCategory[event];
} else {
return (NULL);
}
if (alertMessage) {
return (alertMessage);
} else {
return (NULL);
}
}
static char *
getNextEventLogParam(char *mess)
{
char *p = mess;
do {
if ((p != mess) && (*(p-1) == BACKSLASH_ESCAPE)) {
p++;
continue;
}
if ((*p == TAB) && (*(p+1) == TAB)) {
return (NULL);
}
p++;
} while (*p != TAB);
p++;
return (p);
}
static int
expandEventLogMessage(int eventId, char *messParams, size_t messParamsLen,
char *buf)
{
char *alertMessage;
char *s;
char *d;
char *param;
alertMessage = getEventLogMessage(eventId);
if (alertMessage == NULL) {
(void) strcpy(buf, "Unknown alert");
return (strlen("Unknown alert"));
}
if (messParamsLen == 0) {
(void) strcpy(buf, alertMessage);
return (strlen(buf));
}
if (strstr(alertMessage, "%s")) {
s = alertMessage;
d = buf;
param = messParams;
do {
if ((*s == '%') && (*(s+1) == 's')) {
if (param) {
char *p = param;
while ((*p) && (*p != TAB)) {
*d++ = *p++;
}
}
param = getNextEventLogParam(param);
s += 2;
}
} while ((*d++ = *s++));
} else {
(void) strcpy(buf, alertMessage);
}
return (strlen(buf));
}
static void
ADM_Process_old_event_log()
{
char timebuf[32];
char messBuff[256];
char eventMsgBuf[256];
rscp_msg_t Message;
struct timespec Timeout;
dp_get_event_log_r_t *rscReply;
char *datap;
dp_event_log_entry_t entry;
int i, len, entryhdrsize;
ADM_Start();
Message.type = DP_GET_EVENT_LOG;
Message.len = 0;
Message.data = NULL;
ADM_Send(&Message);
Timeout.tv_nsec = 0;
Timeout.tv_sec = ADM_TIMEOUT;
ADM_Recv(&Message, &Timeout,
DP_GET_EVENT_LOG_R, sizeof (*rscReply));
rscReply = (dp_get_event_log_r_t *)Message.data;
datap = (char *)rscReply->data;
for (i = 0; i < rscReply->entry_count; i++) {
entryhdrsize = sizeof (entry) - sizeof (entry.param);
(void) memcpy(&entry, datap, entryhdrsize);
datap += entryhdrsize;
(void) memcpy(&entry.param, datap, entry.paramLen);
(void) strftime(timebuf, sizeof (timebuf), "%b %d %H:%M:%S",
gmtime((time_t *)&entry.eventTime));
(void) sprintf(messBuff, "%s : %08lx: \"", timebuf,
entry.eventId);
len = expandEventLogMessage(entry.eventId, entry.param,
entry.paramLen, eventMsgBuf);
(void) strncat(messBuff, eventMsgBuf, len);
(void) strcat(messBuff, "\"\r\n");
(void) printf(messBuff);
datap += entry.paramLen;
}
ADM_Free(&Message);
}
static int
ADM_Process_new_event_log(int all)
{
char timebuf[32];
char messBuff[256];
char eventMsgBuf[256];
rscp_msg_t Message;
struct timespec Timeout;
dp_get_event_log2_r_t *rscReply;
char *datap;
dp_event_log_entry_t entry;
int i, len, entryhdrsize, sent_ok;
rsci64 events_remaining, seqno;
rsci16 request_size, returned_events;
dp_get_event_log2_t rscCmd;
ADM_Start();
rscCmd.start_seq = 0;
rscCmd.length = 0;
Message.type = DP_GET_EVENT_LOG2;
Message.len = sizeof (rscCmd);
Message.data = (char *)&rscCmd;
if (ADM_Send_ret(&Message) != 0) {
return (1);
}
Timeout.tv_nsec = 0;
Timeout.tv_sec = ADM_TIMEOUT;
ADM_Recv(&Message, &Timeout,
DP_GET_EVENT_LOG2_R, sizeof (*rscReply));
rscReply = (dp_get_event_log2_r_t *)Message.data;
if ((all == 0) &&
(rscReply->remaining_log_events > DEFAULT_NUM_EVENTS)) {
events_remaining = DEFAULT_NUM_EVENTS;
seqno = (rscReply->remaining_log_events +
rscReply->next_seq) - events_remaining;
} else {
events_remaining = rscReply->remaining_log_events;
seqno = rscReply->next_seq;
}
request_size = sizeof (rscReply->buffer);
ADM_Free(&Message);
while (events_remaining) {
rscCmd.start_seq = seqno;
rscCmd.length = request_size;
Message.type = DP_GET_EVENT_LOG2;
Message.len = sizeof (rscCmd);
Message.data = (char *)&rscCmd;
ADM_Send(&Message);
Timeout.tv_nsec = 0;
Timeout.tv_sec = ADM_TIMEOUT;
ADM_Recv(&Message, &Timeout,
DP_GET_EVENT_LOG2_R, sizeof (*rscReply));
rscReply = (dp_get_event_log2_r_t *)Message.data;
returned_events = rscReply->num_events;
if (returned_events == 0) {
ADM_Free(&Message);
break;
}
if (seqno + returned_events < rscReply->next_seq) {
printf(gettext("\nscadm: lost %d events\n"),
rscReply->next_seq - (seqno + returned_events));
}
seqno = rscReply->next_seq;
events_remaining -= returned_events;
datap = rscReply->buffer;
for (i = 0; i < returned_events; i++) {
entryhdrsize = sizeof (entry) - sizeof (entry.param);
(void) memcpy(&entry, datap, entryhdrsize);
datap += entryhdrsize;
(void) memcpy(&entry.param, datap, entry.paramLen);
(void) strftime(timebuf, sizeof (timebuf),
"%b %d %H:%M:%S",
gmtime((time_t *)&entry.eventTime));
(void) sprintf(messBuff, "%s : %08lx: \"", timebuf,
entry.eventId);
len = expandEventLogMessage(entry.eventId, entry.param,
entry.paramLen, eventMsgBuf);
(void) strncat(messBuff, eventMsgBuf, len);
(void) strcat(messBuff, "\"\r\n");
(void) printf(messBuff);
datap += entry.paramLen;
}
ADM_Free(&Message);
}
return (0);
}
void
ADM_Process_event_log(int all)
{
if (ADM_Process_new_event_log(all) != 0) {
ADM_Process_old_event_log();
}
}