xdasd_parse.c

Go to the documentation of this file.
00001 /*----------------------------------------------------------------------------
00002  * Copyright (c) 2006, Novell, Inc.
00003  * All rights reserved.
00004  * 
00005  * Redistribution and use in source and binary forms, with or without 
00006  * modification, are permitted provided that the following conditions are 
00007  * met:
00008  * 
00009  *     * Redistributions of source code must retain the above copyright 
00010  *       notice, this list of conditions and the following disclaimer.
00011  *     * Redistributions in binary form must reproduce the above copyright 
00012  *       notice, this list of conditions and the following disclaimer in the 
00013  *       documentation and/or other materials provided with the distribution.
00014  *     * Neither the name of the Novell nor the names of its contributors 
00015  *       may be used to endorse or promote products derived from this 
00016  *       software without specific prior written permission.
00017  * 
00018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
00019  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00020  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
00021  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
00022  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00023  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
00024  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
00025  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
00026  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
00027  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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;   /* True: all key fields present and accounted for. */
00082 }
00083 
00090 static void log_parsed_message(int level, Parsed * pp)
00091 {
00092    /* don't waste the effort if the level isn't high enough... */
00093    if (level <= xdasd_log_level())
00094    {
00095       char * buf;
00096       unsigned psz = strlen(pp->msg);
00097 
00098       /* 32 fields * 6 extra chars per field + 1 null terminator */
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));  /* clear all fields to parsed */
00159 
00160    /* copy message into end of parsed buffer */
00161    pp->structsz = allocsz;
00162    pp->flags = flags;
00163    memcpy(pp->msg, msg, msgsz);
00164    pp->msg[msgsz] = 0;     /* null-terminate message */
00165 
00166    /* parse the message into field pointers */
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++;                /* move past the colon delimiter */
00175    }
00176    pp->parsed[i] = cp;
00177 
00178    /* see if all fields are accounted for */
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    /* return the allocated Parsed structure, and success */
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       /* allocate an action structure long enough to hold the script */
00248       if ((t = (Trigger *)malloc(offsetof(Trigger, script) + scriptsz)) == 0)
00249          return -1;
00250    
00251       /* copy data into action structure */
00252       memcpy(t->script, script, scriptsz);
00253    
00254       /* link new action node into parsed message. */
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    /*  0 */ "HDR:"
00342    /*  1 */ "00A8:"
00343    /*  2 */ "OX1:"
00344    /*  3 */ "1F883AD5:"
00345    /*  4 */ ":"
00346    /*  5 */ ":"
00347    /*  6 */ "time.nist.gov:"
00348    /*  7 */ "MST7MDT:"
00349    /*  8 */ "0x10000001:"
00350    /*  9 */ "0:"
00351    /* 10 */ "ORG:"
00352    /* 11 */ "org_location_name:"
00353    /* 12 */ "http%:\\org.location.address:"
00354    /* 13 */ "org_service_type:"
00355    /* 14 */ "org_auth_authority:"
00356    /* 15 */ "org_principal_name:"
00357    /* 16 */ "org_principal_id:"
00358    /* 17 */ "INT:"
00359    /* 18 */ "int_auth_authority:"
00360    /* 19 */ "int_domain_specific_name:"
00361    /* 20 */ "int_domain_specific_id:"
00362    /* 21 */ "TGT:"
00363    /* 22 */ "tgt_location_name:"
00364    /* 23 */ "http%:\\tgt.location.address:"
00365    /* 24 */ "tgt_service_type:"
00366    /* 25 */ "tgt_auth_authority:"
00367    /* 26 */ "tgt_principal_name:"
00368    /* 27 */ "tgt_principal_id:"
00369    /* 28 */ "SRC:"
00370    /* 29 */ "pointer_to_source_domain:"
00371    /* 30 */ "EVT:"
00372    /* 31 */ "event_specific_information:"
00373    /* 32 */ "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 

Generated on Thu Aug 20 22:33:06 2009 for OpenXDAS by  doxygen 1.5.6