00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00039 #include "xdasd_parse.h"
00040 #include "xdasd_list.h"
00041 #include "xdasd_log.h"
00042
00043 #include <stdio.h>
00044 #include <string.h>
00045 #include <malloc.h>
00046
00060 static int prs_check_key_fields(Parsed * parsed)
00061 {
00062 static const struct keys { char key[5]; int field; } keys[] =
00063 {
00064 {"HDR:", 0}, {"ORG:", 10}, {"INT:", 17}, {"TGT:", 21},
00065 {"SRC:", 28}, {"EVT:", 30}, {"END\0",32},
00066 };
00067 unsigned i;
00068
00069 for (i = 0; i < sizeof(keys)/sizeof(*keys); i++)
00070 {
00071 int fldnum = keys[i].field;
00072 size_t fldsz = parsed->parsed[fldnum + 1] - parsed->parsed[fldnum];
00073 if (fldsz != sizeof(keys[i].key) - 1
00074 || memcmp(keys[i].key, parsed->parsed[fldnum], fldsz) != 0)
00075 {
00076 xdasd_log(1, "prs_check_key_fields: %s field missing in event.\n",
00077 keys[i].key);
00078 return 0;
00079 }
00080 }
00081 return 1;
00082 }
00083
00090 static void log_parsed_message(int level, Parsed * pp)
00091 {
00092
00093 if (level <= xdasd_log_level())
00094 {
00095 char * buf;
00096 unsigned psz = strlen(pp->msg);
00097
00098
00099 if ((buf = (char *)malloc(psz + 32 * 6 + 1)) == 0)
00100 xdasd_log(0, "Out of memory in log_parsed_message, %s(%d)\n",
00101 __FILE__, __LINE__);
00102 else
00103 {
00104 int i;
00105 char * bp = buf;
00106 for (i = 0; i < 32; i++)
00107 bp += sprintf(bp, "%3d:\"%.*s\"", i,
00108 (pp->parsed[i + 1] - pp->parsed[i]), pp->parsed[i]);
00109 xdasd_log(level, "xdasd_parse_message: structsz = %u, "
00110 "flags = %08X, severity = %d, parsed fields: [%s]\n",
00111 pp->structsz, pp->flags, pp->severity, buf);
00112 }
00113 }
00114 }
00115
00148 int xdasd_parse_message(unsigned flags, size_t msgsz, const char * msg,
00149 Parsed ** parsedp)
00150 {
00151 unsigned i;
00152 Parsed * pp;
00153 char * cp, * limit;
00154 size_t allocsz = offsetof(Parsed, msg) + msgsz + 1;
00155
00156 if ((pp = (Parsed *)malloc(allocsz)) == 0)
00157 return -1;
00158 memset(pp, 0, offsetof(Parsed, parsed));
00159
00160
00161 pp->structsz = allocsz;
00162 pp->flags = flags;
00163 memcpy(pp->msg, msg, msgsz);
00164 pp->msg[msgsz] = 0;
00165
00166
00167 cp = pp->msg;
00168 limit = cp + msgsz;
00169 for (i = 0; i < XDAS_FIELD_COUNT && cp < limit; i++)
00170 {
00171 pp->parsed[i] = cp;
00172 while (cp < limit && (*cp != ':' || cp > pp->msg && cp[-1] == '%'))
00173 cp++;
00174 cp++;
00175 }
00176 pp->parsed[i] = cp;
00177
00178
00179 if (i < XDAS_FIELD_COUNT || !prs_check_key_fields(pp))
00180 {
00181 free(pp);
00182 if (i < XDAS_FIELD_COUNT)
00183 xdasd_log(1, "xdasd_parse_message: insufficient fields in event.");
00184 return -2;
00185 }
00186
00187 log_parsed_message(15, pp);
00188
00189
00190 *parsedp = pp;
00191 return 0;
00192 }
00193
00205 void xdasd_parse_set_log_state(Parsed * parsed, int state)
00206 {
00207 if (state != 0)
00208 parsed->flags |= PMF_LOG;
00209 else
00210 parsed->flags &= ~PMF_LOG;
00211 }
00212
00221 void xdasd_parse_set_alarm_severity(Parsed * parsed, int severity)
00222 {
00223 if (severity > 0)
00224 parsed->flags |= PMF_ALARM;
00225 else
00226 parsed->flags &= ~PMF_ALARM;
00227 parsed->severity = severity;
00228 }
00229
00239 int xdasd_parse_set_trigger(Parsed * parsed, const char * script)
00240 {
00241 parsed->flags |= PMF_TRIGGER;
00242 if (script)
00243 {
00244 Trigger * t;
00245 size_t scriptsz = strlen(script) + 1;
00246
00247
00248 if ((t = (Trigger *)malloc(offsetof(Trigger, script) + scriptsz)) == 0)
00249 return -1;
00250
00251
00252 memcpy(t->script, script, scriptsz);
00253
00254
00255 xdasd_list_link_tail(&parsed->triggers, (XDLItem *)t);
00256 }
00257 return 0;
00258 }
00259
00269 void xdasd_parse_clear_actions(Parsed * parsed)
00270 {
00271 XDLItem * ip = parsed->triggers.head;
00272 while (ip)
00273 {
00274 XDLItem * del = ip;
00275 ip = ip->next;
00276 free(del);
00277 }
00278 memset(&parsed->triggers, 0, sizeof(parsed->triggers));
00279 parsed->severity = 0;
00280 parsed->flags &= ~(PMF_LOG | PMF_ALARM | PMF_TRIGGER);
00281 }
00282
00289 void xdasd_parse_free(Parsed * parsed)
00290 {
00291 xdasd_parse_clear_actions(parsed);
00292 free(parsed);
00293 }
00294
00295
00296
00297 #ifdef XDASD_PARSE_TEST
00298
00305 void xdasd_log(int level, const char * fmt, ... )
00306 {
00307 #ifdef LOG_TO_STDOUT
00308 va_list args;
00309 va_start(args, fmt);
00310 vprintf(fmt, args);
00311 va_end(args);
00312 #else
00313 (void)fmt;
00314 #endif
00315 }
00316
00323 int xdasd_log_level(void) { return 0; }
00324
00338 int main(int argc, char ** argv)
00339 {
00340 static char msg[] =
00341 "HDR:"
00342 "00A8:"
00343 "OX1:"
00344 "1F883AD5:"
00345 ":"
00346 ":"
00347 "time.nist.gov:"
00348 "MST7MDT:"
00349 "0x10000001:"
00350 "0:"
00351 "ORG:"
00352 "org_location_name:"
00353 "http%:\\org.location.address:"
00354 "org_service_type:"
00355 "org_auth_authority:"
00356 "org_principal_name:"
00357 "org_principal_id:"
00358 "INT:"
00359 "int_auth_authority:"
00360 "int_domain_specific_name:"
00361 "int_domain_specific_id:"
00362 "TGT:"
00363 "tgt_location_name:"
00364 "http%:\\tgt.location.address:"
00365 "tgt_service_type:"
00366 "tgt_auth_authority:"
00367 "tgt_principal_name:"
00368 "tgt_principal_id:"
00369 "SRC:"
00370 "pointer_to_source_domain:"
00371 "EVT:"
00372 "event_specific_information:"
00373 "END";
00374
00375 Parsed * parsed;
00376 int i, err, rv = 0;
00377 unsigned flags = 0;
00378
00379 (void)argc;
00380 (void)argv;
00381
00382 if ((err = xdasd_parse_message(flags, sizeof(msg) - 1, msg, &parsed)) != 0)
00383 return err;
00384
00385 rv = 0;
00386 if (parsed->structsz != offsetof(Parsed, msg) + sizeof(msg))
00387 rv++;
00388
00389 if (parsed->flags != flags)
00390 rv++;
00391
00392 if (memcmp(parsed->msg, msg, sizeof(msg)) != 0)
00393 rv++;
00394
00395 for (i = 0; i < XDAS_FIELD_COUNT + 1; i++)
00396 if (parsed->parsed[i] < parsed->msg
00397 || parsed->parsed[i] > parsed->msg + sizeof(msg) + 1)
00398 rv++;
00399
00400 xdasd_parse_free(parsed);
00401 return rv;
00402 }
00403
00404 #endif
00405