X-Git-Url: http://git.samba.org/samba.git/?p=obnox%2Fwireshark%2Fwip.git;a=blobdiff_plain;f=plugins%2Fmate%2Fmate_util.c;h=4b6755ef090fb453c382685762e26a5ee1682495;hp=3ffc0c76ffc8225e6e22593752b60f1fac123136;hb=896b6923efcad36f5590a2f15c026358d4d2e047;hpb=028173bf650144e8a0dd8c8d0386a49fda13d3e2 diff --git a/plugins/mate/mate_util.c b/plugins/mate/mate_util.c index 3ffc0c76ff..4b6755ef09 100644 --- a/plugins/mate/mate_util.c +++ b/plugins/mate/mate_util.c @@ -2,12 +2,12 @@ * MATE -- Meta Analysis Tracing Engine * Utility Library: Single Copy Strings and Attribute Value Pairs * -* Copyright 2004, Luis E. Garcia Ontanon +* Copyright 2004, Luis E. Garcia Ontanon * * $Id$ * -* Ethereal - Network traffic analyzer -* By Gerald Combs +* Wireshark - Network traffic analyzer +* By Gerald Combs * Copyright 1998 Gerald Combs * * This program is free software; you can redistribute it and/or @@ -25,27 +25,18 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "config.h" -#include -#include -#include #include "mate.h" #include "mate_util.h" +#include -/* TODO: -+ fix debug_print levels -+ chunks for scs_strings (do I realy need em??) - + checking bounds in (almost) every operator -- operators - + rethink '&' operator - - bounds check on op_match() - ? change &{} into [] - ? add {xxx} to get avps named xxxx from the src avpl - ? add (yyy) to do aaa+31 or and similar stuff - - add perlre operator? - - transform - + map (N->M hash) -*/ +/*************************************************************************** +* ADDRDIFF +*************************************************************************** +* This is a macro that computes the difference between the raw address +* values of two pointers (rather than the difference between the pointers) +* as a ptrdiff_t. +***************************************************************************/ +#define ADDRDIFF(p,q) (((char *)(void *)(p)) - ((char *)(void *)(q))) /*************************************************************************** @@ -61,8 +52,8 @@ * fmt, ...: what to print */ -void dbg_print(const guint* which, guint how, FILE* where, guint8* fmt, ... ) { - static guint8 debug_buffer[DEBUG_BUFFER_SIZE]; +void dbg_print(const gint* which, gint how, FILE* where, const gchar* fmt, ... ) { + static gchar debug_buffer[DEBUG_BUFFER_SIZE]; va_list list; if ( ! which || *which < how ) return; @@ -72,9 +63,10 @@ void dbg_print(const guint* which, guint how, FILE* where, guint8* fmt, ... ) { va_end( list ); if (! where) { - g_message(debug_buffer); + g_message("%s", debug_buffer); } else { fputs(debug_buffer,where); + fputs("\n",where); } } @@ -83,58 +75,37 @@ void dbg_print(const guint* which, guint how, FILE* where, guint8* fmt, ... ) { /*************************************************************************** * single copy strings *************************************************************************** - * In order to save memory and since strings repeat more often than don't, + * Strings repeat more often than don't. In order to save memory * we'll keep only one copy of each as key to a hash with a count of * subscribers as value. ***************************************************************************/ -/* FIXME: use hash fom glib 1.X not 2.X */ /** * scs_init: - * @collection: the scs hash * * Initializes the scs hash. **/ -/* Don't call variables "small" or "huge". They are keywords for the MSVC compiler. Rename them to "mate_small" and "mate_huge"*/ struct _scs_collection { GHashTable* hash; /* key: a string value: guint number of subscribers */ - GMemChunk* ctrs; - GMemChunk* mate_small; - GMemChunk* mate_medium; - GMemChunk* mate_large; - GMemChunk* mate_huge; }; -extern void destroy_scs_collection(SCS_collection* c) { - if ( c->ctrs ) g_mem_chunk_destroy(c->ctrs); - if ( c->mate_small ) g_mem_chunk_destroy(c->mate_small); - if ( c->mate_medium ) g_mem_chunk_destroy(c->mate_medium); - if ( c->mate_large ) g_mem_chunk_destroy(c->mate_large); - if ( c->mate_huge ) g_mem_chunk_destroy(c->mate_huge); - - if (c->hash) g_hash_table_destroy(c->hash); +/* ToDo? free any string,ctr entries pointed to by the hash table ?? + * XXX: AFAIKT destroy_scs_collection() might be called only when reading a + * mate config file. Since reading a new config file can apparently currently + * only be done once after starting Wireshark, in theory this fcn + * currently should never be called since there will never be an existing + * scs_collection to be destroyed. + */ +static void destroy_scs_collection(SCS_collection* c) { + if (c->hash) g_hash_table_destroy(c->hash); } -extern SCS_collection* scs_init(void) { +static SCS_collection* scs_init(void) { SCS_collection* c = g_malloc(sizeof(SCS_collection)); c->hash = g_hash_table_new(g_str_hash,g_str_equal); - - c->ctrs = g_mem_chunk_new("ints_scs_chunk", sizeof(guint), - sizeof(guint) * SCS_SMALL_CHUNK_SIZE, G_ALLOC_AND_FREE); - - c->mate_small = g_mem_chunk_new("small_scs_chunk", SCS_SMALL_SIZE, - SCS_SMALL_SIZE * SCS_SMALL_CHUNK_SIZE, G_ALLOC_AND_FREE); - - c->mate_medium = g_mem_chunk_new("medium_scs_chunk", SCS_MEDIUM_SIZE, - SCS_MEDIUM_SIZE * SCS_MEDIUM_CHUNK_SIZE, G_ALLOC_AND_FREE); - - c->mate_large = g_mem_chunk_new("large_scs_chunk", SCS_LARGE_SIZE, - SCS_LARGE_SIZE * SCS_LARGE_CHUNK_SIZE, G_ALLOC_AND_FREE); - - c->mate_huge = g_mem_chunk_new("huge_scs_chunk", SCS_HUGE_SIZE, - SCS_HUGE_SIZE * SCS_HUGE_CHUNK_SIZE, G_ALLOC_AND_FREE); + return c; } @@ -151,43 +122,37 @@ extern SCS_collection* scs_init(void) { * * Return value: a pointer to the subscribed string. **/ -guint8* scs_subscribe(SCS_collection* c, guint8* s) { - guint8* orig = NULL; +gchar* scs_subscribe(SCS_collection* c, const gchar* s) { + gchar* orig = NULL; guint* ip = NULL; size_t len = 0; - GMemChunk* chunk = NULL; - - g_hash_table_lookup_extended(c->hash,s,(gpointer*)&orig,(gpointer*)&ip); + + g_hash_table_lookup_extended(c->hash,(gconstpointer)s,(gpointer)&orig,(gpointer)&ip); if (ip) { (*ip)++; } else { - ip = g_mem_chunk_alloc(c->ctrs); + ip = g_slice_new(guint); *ip = 0; - + len = strlen(s) + 1; - + if (len <= SCS_SMALL_SIZE) { - chunk = c->mate_small; len = SCS_SMALL_SIZE; } else if (len <= SCS_MEDIUM_SIZE) { - chunk = c->mate_medium; len = SCS_MEDIUM_SIZE; } else if (len <= SCS_LARGE_SIZE) { - chunk = c->mate_large; len = SCS_LARGE_SIZE; } else if (len < SCS_HUGE_SIZE) { - chunk = c->mate_huge; len = SCS_HUGE_SIZE; } else { - chunk = c->mate_huge; len = SCS_HUGE_SIZE; - g_warning("mate SCS: string truncated to huge size"); + g_warning("mate SCS: string truncated due to huge size"); } - - orig = g_mem_chunk_alloc(chunk); - strncpy(orig,s,len); - + + orig = g_slice_alloc(len); + g_strlcpy(orig,s,len); + g_hash_table_insert(c->hash,orig,ip); } @@ -202,38 +167,37 @@ guint8* scs_subscribe(SCS_collection* c, guint8* s) { * decreases the count of subscribers, if zero frees the internal copy of * the string. **/ -void scs_unsubscribe(SCS_collection* c, guint8* s) { - guint8* orig = NULL; +void scs_unsubscribe(SCS_collection* c, gchar* s) { + gchar* orig = NULL; guint* ip = NULL; size_t len = 0xffff; - GMemChunk* chunk = NULL; - - g_hash_table_lookup_extended(c->hash,s,(gpointer*)&orig,(gpointer*)&ip); + + g_hash_table_lookup_extended(c->hash,(gconstpointer)s,(gpointer)&orig,(gpointer)&ip); if (ip) { if (*ip == 0) { g_hash_table_remove(c->hash,orig); - + len = strlen(orig); - + if (len < SCS_SMALL_SIZE) { - chunk = c->mate_small; + len = SCS_SMALL_SIZE; } else if (len < SCS_MEDIUM_SIZE) { - chunk = c->mate_medium; + len = SCS_MEDIUM_SIZE; } else if (len < SCS_LARGE_SIZE) { - chunk = c->mate_large; + len = SCS_LARGE_SIZE; } else { - chunk = c->mate_huge; - } - - g_mem_chunk_free(chunk,orig); - g_mem_chunk_free(c->ctrs,ip); + len = SCS_HUGE_SIZE; + } + + g_slice_free1(len, orig); + g_slice_free(guint,ip); } else { (*ip)--; } } else { - g_warning("unsusbcribe: already deleted: '%s'?",s); + g_warning("unsubscribe: not subscribed"); } } @@ -246,38 +210,22 @@ void scs_unsubscribe(SCS_collection* c, guint8* s) { * Return value: the stored copy of the formated string. * **/ -extern guint8* scs_subscribe_printf(SCS_collection* c, guint8* fmt, ...) { +gchar* scs_subscribe_printf(SCS_collection* c, gchar* fmt, ...) { va_list list; - static guint8 buf[SCS_HUGE_SIZE]; - + static gchar buf[SCS_HUGE_SIZE]; + va_start( list, fmt ); - g_vsnprintf(buf, SCS_HUGE_SIZE-1 ,fmt, list); + g_vsnprintf(buf, SCS_HUGE_SIZE, fmt, list); va_end( list ); return scs_subscribe(c,buf); } -extern guint8* scs_subscribe_int(SCS_collection* c, int i) { - static guint8 buf[SCS_SMALL_SIZE]; - - g_snprintf(buf, SCS_SMALL_SIZE-1 ,"%i", i); - - return scs_subscribe(c,buf); -} - -extern guint8* scs_subscribe_float(SCS_collection* c, float f) { - static guint8 buf[SCS_SMALL_SIZE]; - - g_snprintf(buf, SCS_SMALL_SIZE-1 ,"%f", f); - - return scs_subscribe(c,buf); -} - /*************************************************************************** * AVPs & Co. *************************************************************************** * The Thing operates mainly on avps, avpls and loals -* - attribute value pairs (two strings: the name and the value and an opeartor) +* - attribute value pairs (two strings: the name and the value and an operator) * - avp lists a somehow sorted list of avps * - loal (list of avp lists) an arbitrarily sorted list of avpls * @@ -294,7 +242,6 @@ typedef union _any_avp_type { } any_avp_type; -static GMemChunk* avp_chunk = NULL; static SCS_collection* avp_strings = NULL; #ifdef _AVP_DEBUGGING @@ -324,7 +271,7 @@ static int* dbg_avpl_op = &dbg_avpl_op_level; * @avpl: a pointer to the level of debugging of facility "avpl" * @avpl_op: a pointer to the level of debugging of facility "avpl_op" * - * (If enabled set's up the debug facilities for the avp library. + * If enabled sets up the debug facilities for the avp library. * **/ extern void setup_avp_debug(FILE* fp, int* general, int* avp, int* avp_op, int* avpl, int* avpl_op) { @@ -340,26 +287,17 @@ extern void setup_avp_debug(FILE* fp, int* general, int* avp, int* avp_op, int* /** * avp_init: - * @chunk_size: the initial chunk's size. * * (Re)Initializes the avp library. * **/ extern void avp_init(void) { + if (avp_strings) destroy_scs_collection(avp_strings); avp_strings = scs_init(); - - if ( avp_chunk ) { - g_mem_chunk_destroy(avp_chunk); - } - - avp_chunk = g_mem_chunk_new("avp_chunk", sizeof(any_avp_type), - AVP_CHUNK_SIZE, G_ALLOC_AND_FREE); - } - /** * new_avp_from_finfo: * @name: the name the avp will have. @@ -370,26 +308,16 @@ extern void avp_init(void) { * Return value: a pointer to the newly created avp. * **/ -extern AVP* new_avp_from_finfo(guint8* name, field_info* finfo) { - AVP* new = g_mem_chunk_alloc(avp_chunk); - guint8* value; - +extern AVP* new_avp_from_finfo(const gchar* name, field_info* finfo) { + AVP* new = (AVP*)g_slice_new(any_avp_type); + gchar* value; + new->n = scs_subscribe(avp_strings, name); - if (finfo->value.ftype->get_value_integer) { - value = scs_subscribe_int(avp_strings, fvalue_get_integer(&finfo->value)); -#ifdef _AVP_DEBUGGING - dbg_print (dbg_avp,2,dbg_fp,"new_avp_from_finfo: from integer: %s",value); -#endif - } else if (finfo->value.ftype->val_to_string_repr) { + if (finfo->value.ftype->val_to_string_repr) { value = scs_subscribe(avp_strings, fvalue_to_string_repr(&finfo->value,FTREPR_DISPLAY,NULL)); #ifdef _AVP_DEBUGGING dbg_print (dbg_avp,2,dbg_fp,"new_avp_from_finfo: from string: %s",value); -#endif - } else if (finfo->value.ftype->get_value_floating) { - value = scs_subscribe_float(avp_strings, (float) fvalue_get_floating(&finfo->value)); -#ifdef _AVP_DEBUGGING - dbg_print (dbg_avp,2,dbg_fp,"new_avp_from_finfo: from float: %s",value); #endif } else { #ifdef _AVP_DEBUGGING @@ -421,8 +349,8 @@ extern AVP* new_avp_from_finfo(guint8* name, field_info* finfo) { * Return value: a pointer to the newly created avp. * **/ -extern AVP* new_avp(guint8* name, guint8* value, guint8 o) { - AVP* new = g_mem_chunk_alloc(avp_chunk); +extern AVP* new_avp(const gchar* name, const gchar* value, gchar o) { + AVP* new = (AVP*)g_slice_new(any_avp_type); new->n = scs_subscribe(avp_strings, name); new->v = scs_subscribe(avp_strings, value); @@ -449,7 +377,7 @@ extern void delete_avp(AVP* avp) { scs_unsubscribe(avp_strings, avp->n); scs_unsubscribe(avp_strings, avp->v); - g_mem_chunk_free(avp_chunk,avp); + g_slice_free(any_avp_type,(any_avp_type*)avp); } @@ -457,13 +385,13 @@ extern void delete_avp(AVP* avp) { * avp_copy: * @from: the avp to be copied. * - * Creates an avp whose name op and value are copyes of the given one. + * Creates an avp whose name op and value are copies of the given one. * * Return value: a pointer to the newly created avp. * **/ extern AVP* avp_copy(AVP* from) { - AVP* new = g_mem_chunk_alloc(avp_chunk); + AVP* new = (AVP*)g_slice_new(any_avp_type); new->n = scs_subscribe(avp_strings, from->n); new->v = scs_subscribe(avp_strings, from->v); @@ -476,13 +404,6 @@ extern AVP* avp_copy(AVP* from) { return new; } - -extern void rename_avp(AVP* avp, guint8* name) { - guint8* s = avp->n; - avp->n = scs_subscribe(avp_strings,name); - scs_unsubscribe(avp_strings,s); -} - /** * new_avpl: * @name: the name the avpl will have. @@ -492,24 +413,24 @@ extern void rename_avp(AVP* avp, guint8* name) { * Return value: a pointer to the newly created avpl. * **/ -extern AVPL* new_avpl(guint8* name) { - AVPL* new_avpl = g_mem_chunk_alloc(avp_chunk); +extern AVPL* new_avpl(const gchar* name) { + AVPL* new_avpl_p = (AVPL*)g_slice_new(any_avp_type); #ifdef _AVP_DEBUGGING - dbg_print(dbg_avpl_op,7,dbg_fp,"new_avpl: %X name=%s",new_avpl,name); + dbg_print(dbg_avpl_op,7,dbg_fp,"new_avpl_p: %X name=%s",new_avpl_p,name); #endif - new_avpl->name = scs_subscribe(avp_strings, name); - new_avpl->len = 0; - new_avpl->null.avp = NULL; - new_avpl->null.next = &new_avpl->null; - new_avpl->null.prev = &new_avpl->null; + new_avpl_p->name = name ? scs_subscribe(avp_strings, name) : scs_subscribe(avp_strings, ""); + new_avpl_p->len = 0; + new_avpl_p->null.avp = NULL; + new_avpl_p->null.next = &new_avpl_p->null; + new_avpl_p->null.prev = &new_avpl_p->null; - return new_avpl; + return new_avpl_p; } -extern void rename_avpl(AVPL* avpl, guint8* name) { +extern void rename_avpl(AVPL* avpl, gchar* name) { scs_unsubscribe(avp_strings,avpl->name); avpl->name = scs_subscribe(avp_strings,name); } @@ -527,7 +448,7 @@ extern void rename_avpl(AVPL* avpl, guint8* name) { * it is not inserted. **/ extern gboolean insert_avp(AVPL* avpl, AVP* avp) { - AVPN* new = g_mem_chunk_alloc(avp_chunk); + AVPN* new = (AVPN*)g_slice_new(any_avp_type); AVPN* c; new->avp = avp; @@ -551,7 +472,7 @@ extern gboolean insert_avp(AVPL* avpl, AVP* avp) { #ifdef _AVP_DEBUGGING dbg_print(dbg_avpl_op,7,dbg_fp,"delete_avpn: %X",new); #endif - g_mem_chunk_free(avp_chunk,new); + g_slice_free(any_avp_type,(any_avp_type*)new); return FALSE; } } @@ -592,7 +513,7 @@ extern gboolean insert_avp(AVPL* avpl, AVP* avp) { * Return value: a pointer to the next matching avp if there's one, else NULL. * **/ -extern AVP* get_avp_by_name(AVPL* avpl, guint8* name, void** cookie) { +extern AVP* get_avp_by_name(AVPL* avpl, gchar* name, void** cookie) { AVPN* curr; AVPN* start = (AVPN*) *cookie; @@ -631,7 +552,7 @@ extern AVP* get_avp_by_name(AVPL* avpl, guint8* name, void** cookie) { * Return value: a pointer to extracted avp if there's one, else NULL. * **/ -extern AVP* extract_avp_by_name(AVPL* avpl, guint8* name) { +extern AVP* extract_avp_by_name(AVPL* avpl, gchar* name) { AVPN* curr; AVP* avp = NULL; @@ -656,7 +577,7 @@ extern AVP* extract_avp_by_name(AVPL* avpl, guint8* name) { avp = curr->avp; - g_mem_chunk_free(avp_chunk,curr); + g_slice_free(any_avp_type,(any_avp_type*)curr); (avpl->len)--; @@ -697,7 +618,7 @@ extern AVP* extract_first_avp(AVPL* avpl) { avp = node->avp; if (avp) { - g_mem_chunk_free(avp_chunk,node); + g_slice_free(any_avp_type,(any_avp_type*)node); (avpl->len)--; #ifdef _AVP_DEBUGGING dbg_print(dbg_avpl,4,dbg_fp,"avpl: %X new len: %i",avpl,avpl->len); @@ -734,7 +655,7 @@ extern AVP* extract_last_avp(AVPL* avpl) { avp = node->avp; if (avp) { - g_mem_chunk_free(avp_chunk,node); + g_slice_free(any_avp_type,(any_avp_type*)node); (avpl->len)--; #ifdef _AVP_DEBUGGING dbg_print(dbg_avpl,4,dbg_fp,"avpl: %X new len: %i",avpl,avpl->len); @@ -772,7 +693,7 @@ extern void delete_avpl(AVPL* avpl, gboolean avps_too) { } scs_unsubscribe(avp_strings,avpl->name); - g_mem_chunk_free(avp_chunk,avpl); + g_slice_free(any_avp_type,(any_avp_type*)avpl); } @@ -818,15 +739,15 @@ extern AVP* get_next_avp(AVPL* avpl, void** cookie) { * Return value: a pointer to the newly allocated string. * **/ -guint8* avpl_to_str(AVPL* avpl) { +gchar* avpl_to_str(AVPL* avpl) { AVPN* c; GString* s = g_string_new(""); - guint8* avp_s; - guint8* r; + gchar* avp_s; + gchar* r; for(c=avpl->null.next; c->avp; c = c->next) { avp_s = avp_to_str(c->avp); - g_string_sprintfa(s," %s;",avp_s); + g_string_append_printf(s," %s;",avp_s); g_free(avp_s); } @@ -837,15 +758,15 @@ guint8* avpl_to_str(AVPL* avpl) { return r; } -extern guint8* avpl_to_dotstr(AVPL* avpl) { +extern gchar* avpl_to_dotstr(AVPL* avpl) { AVPN* c; GString* s = g_string_new(""); - guint8* avp_s; - guint8* r; + gchar* avp_s; + gchar* r; for(c=avpl->null.next; c->avp; c = c->next) { avp_s = avp_to_str(c->avp); - g_string_sprintfa(s," .%s;",avp_s); + g_string_append_printf(s," .%s;",avp_s); g_free(avp_s); } @@ -870,7 +791,7 @@ extern guint8* avpl_to_dotstr(AVPL* avpl) { extern void merge_avpl(AVPL* dst, AVPL* src, gboolean copy_avps) { AVPN* cd = NULL; AVPN* cs = NULL; - gint c; + ptrdiff_t c; AVP* copy; #ifdef _AVP_DEBUGGING @@ -883,7 +804,7 @@ extern void merge_avpl(AVPL* dst, AVPL* src, gboolean copy_avps) { while(cs->avp) { if(cd->avp) { - c = (guint) cd->avp->n - (guint) cs->avp->n; + c = ADDRDIFF(cd->avp->n,cs->avp->n); } else { c = -1; } @@ -937,7 +858,7 @@ extern void merge_avpl(AVPL* dst, AVPL* src, gboolean copy_avps) { * Return value: a pointer to the newly allocated string. * **/ -extern AVPL* new_avpl_from_avpl(guint8* name, AVPL* avpl, gboolean copy_avps) { +extern AVPL* new_avpl_from_avpl(const gchar* name, AVPL* avpl, gboolean copy_avps) { AVPL* newavpl = new_avpl(name); void* cookie = NULL; AVP* avp; @@ -965,106 +886,6 @@ extern AVPL* new_avpl_from_avpl(guint8* name, AVPL* avpl, gboolean copy_avps) { return newavpl; } - -#define TRANS_NUM '-': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '0' - -/* BROKEN, makes no sense right now */ -/* FIXME: Use subscribe/unsubscribe */ -#if 0 -static AVP* avp_transform(AVP* src, AVP* op) { - unsigned int i; - guint8 c; - - GString* replace_str = NULL; - GString* num_str = NULL; - GString* return_str = NULL; - guint8* v; - long num = 0; - - enum _tranf_state { - START, - IN_NUM, - IN_REPLACE, - END - } state; - - state = START; - - for(i = 0; i < strlen(op->v); i++) { - c= op->v[i]; - - if (state == END) break; - - switch(state) { - case START: - switch(c) { - case '{': - num_str = g_string_new(""); - state = IN_NUM; - continue; - default: - continue; - }; - case IN_NUM: - switch(c) { - case TRANS_NUM: - g_string_append_c(num_str,c); - continue; - case ':': - num = strtol(num_str->str,NULL,10); - g_string_free(num_str,TRUE); - replace_str = g_string_new(""); - state = IN_REPLACE; - continue; - default: - /* will ignore any char that is not a number */ - continue; - }; - case IN_REPLACE: - switch(c) { - case '\\': - continue; - case '}': - state = END; - continue; - default : - g_string_append_c(replace_str,c); - continue; - } - case END: - /* it will never reach */ - continue; - } - - } - - v = src->v; - - if (num > 0) { - return_str = g_string_new(v); - g_string_erase(return_str,0,num); - g_string_prepend(return_str,replace_str->str); - } else if (num < 0) { - return_str = g_string_new(v); - g_string_truncate(return_str,return_str->len+num); - g_string_append(return_str,replace_str->str); - - } else { - return_str = g_string_new(replace_str->str); - } - - g_mem_chunk_free(avp_chunk,v); - g_string_free(replace_str,TRUE); - - src->o = '='; - src->v = return_str->str; - g_string_free(return_str,FALSE); - - return src; -} - -#endif - /** * match_avp: * @src: an src to be compared agains an "op" avp @@ -1117,6 +938,7 @@ extern AVP* match_avp(AVP* src, AVP* op) { case AVP_OP_LOWER: lower = TRUE; + /* FALLTHRU */ case AVP_OP_HIGHER: fs = (float) strtod(src->v, NULL); @@ -1131,8 +953,8 @@ extern AVP* match_avp(AVP* src, AVP* op) { } case AVP_OP_ENDS: /* does this work? */ - ls = strlen(src->v); - lo = strlen(op->v); + ls = (guint) strlen(src->v); + lo = (guint) strlen(op->v); if ( ls < lo ) { return NULL; @@ -1167,7 +989,7 @@ extern AVP* match_avp(AVP* src, AVP* op) { * Return value: a pointer to the newly created avpl containing the * matching avps. **/ -extern AVPL* new_avpl_loose_match(guint8* name, +extern AVPL* new_avpl_loose_match(const gchar* name, AVPL* src, AVPL* op, gboolean copy_avps) { @@ -1175,7 +997,7 @@ extern AVPL* new_avpl_loose_match(guint8* name, AVPL* newavpl = new_avpl(scs_subscribe(avp_strings, name)); AVPN* co = NULL; AVPN* cs = NULL; - gint c; + ptrdiff_t c; AVP* m; AVP* copy; @@ -1197,7 +1019,7 @@ extern AVPL* new_avpl_loose_match(guint8* name, } - c = (guint) co->avp->n - (guint) cs->avp->n; + c = ADDRDIFF(co->avp->n, cs->avp->n); if ( c > 0 ) { if (co->avp) co = co->next; @@ -1245,19 +1067,26 @@ extern AVPL* new_avpl_loose_match(guint8* name, * Return value: a pointer to the newly created avpl containing the * matching avps. **/ -extern AVPL* new_avpl_every_match(guint8* name, AVPL* src, AVPL* op, gboolean copy_avps) { - AVPL* newavpl = new_avpl(scs_subscribe(avp_strings, name)); +extern AVPL* new_avpl_every_match(const gchar* name, AVPL* src, AVPL* op, gboolean copy_avps) { + AVPL* newavpl; AVPN* co = NULL; AVPN* cs = NULL; - gint c; + ptrdiff_t c; AVP* m; AVP* copy; + gboolean matches; #ifdef _AVP_DEBUGGING dbg_print(dbg_avpl_op,3,dbg_fp,"new_avpl_every_match: %X src=%X op=%X name='%s'",newavpl,src,op,name); #endif + if (src->len == 0) return NULL; + + newavpl = new_avpl(scs_subscribe(avp_strings, name)); - gboolean matches = TRUE; + if (op->len == 0) + return newavpl; + + matches = TRUE; cs = src->null.next; co = op->null.next; @@ -1271,7 +1100,7 @@ extern AVPL* new_avpl_every_match(guint8* name, AVPL* src, AVPL* op, gboolean co break; } - c = (guint) co->avp->n - (guint) cs->avp->n; + c = ADDRDIFF(co->avp->n,cs->avp->n); if ( c > 0 ) { delete_avpl(newavpl,TRUE); @@ -1329,23 +1158,31 @@ extern AVPL* new_avpl_every_match(guint8* name, AVPL* src, AVPL* op, gboolean co * Return value: a pointer to the newly created avpl containing the * matching avps. **/ -extern AVPL* new_avpl_exact_match(guint8* name,AVPL* src, AVPL* op, gboolean copy_avps) { +extern AVPL* new_avpl_exact_match(const gchar* name,AVPL* src, AVPL* op, gboolean copy_avps) { AVPL* newavpl = new_avpl(name); AVPN* co = NULL; AVPN* cs = NULL; - gint c; + ptrdiff_t c; AVP* m; - AVP* copy; + AVP* copy; #ifdef _AVP_DEBUGGING dbg_print(dbg_avpl_op,3,dbg_fp,"new_avpl_every_match: %X src=%X op=%X name='%s'",newavpl,src,op,name); #endif + if (op->len == 0) + return newavpl; + + if (src->len == 0) { + delete_avpl(newavpl,FALSE); + return NULL; + } + cs = src->null.next; co = op->null.next; while(1) { - c = (guint) co->avp->n - (guint) cs->avp->n; + c = ADDRDIFF(co->avp->n,cs->avp->n); if ( c > 0 ) { delete_avpl(newavpl,TRUE); @@ -1392,9 +1229,9 @@ extern AVPL* new_avpl_exact_match(guint8* name,AVPL* src, AVPL* op, gboolean cop return NULL; } -extern AVPL* new_avpl_from_match(avpl_match_mode mode, guint8* name,AVPL* src, AVPL* op, gboolean copy_avps) { +extern AVPL* new_avpl_from_match(avpl_match_mode mode, const gchar* name,AVPL* src, AVPL* op, gboolean copy_avps) { AVPL* avpl = NULL; - + switch (mode) { case AVPL_STRICT: avpl = new_avpl_exact_match(name,src,op,copy_avps); @@ -1410,42 +1247,10 @@ extern AVPL* new_avpl_from_match(avpl_match_mode mode, guint8* name,AVPL* src, A merge_avpl(avpl, op, copy_avps); break; } - - return avpl; -} -/** - * new_avpl_transform: - * - * creates an empty avpl transformation - * - * Return value: a pointer to the newly created avpl transformation - **/ -extern AVPL_Transf* new_avpl_transform(guint8* name, AVPL* mixed, avpl_match_mode match_mode, avpl_replace_mode replace_mode) { - AVPL_Transf* t = g_malloc(sizeof(AVPL_Transf)); - AVP* avp; - - t->name = g_strdup(name); - t->match = new_avpl("match"); - t->replace = new_avpl("replace"); - t->match_mode = match_mode; - t->replace_mode = replace_mode; - t->next = NULL; - t->map = NULL; - - while (( avp = extract_first_avp(mixed) )) { - if (*(avp->n) == '.') { - rename_avp(avp,((avp->n)+1)); - insert_avp(t->replace, avp); - } else { - insert_avp(t->match, avp); - } - } - - return t; + return avpl; } - /** * delete_avpl_transform: * @it: a pointer to the avpl transformation object @@ -1497,7 +1302,7 @@ extern void avpl_transform(AVPL* src, AVPL_Transf* op) { #endif for ( ; op ; op = op->next) { - + avpl = new_avpl_from_match(op->match_mode, src->name,src, op->match, TRUE); if (avpl) { @@ -1518,7 +1323,7 @@ extern void avpl_transform(AVPL* src, AVPL_Transf* op) { cs->prev->next = cs->next; cs->next->prev = cs->prev; - g_mem_chunk_free(avp_chunk,cs); + g_slice_free(any_avp_type,(any_avp_type*)cs); cs = n; cm = cm->next; @@ -1544,23 +1349,23 @@ extern void avpl_transform(AVPL* src, AVPL_Transf* op) { * * Return value: a pointer to the newly created loal. **/ -extern LoAL* new_loal(guint8* name) { - LoAL* new_loal = g_mem_chunk_alloc(avp_chunk); +extern LoAL* new_loal(const gchar* name) { + LoAL* new_loal_p = (LoAL*)g_slice_new(any_avp_type); if (! name) { name = "anonymous"; } #ifdef _AVP_DEBUGGING - dbg_print(dbg_avpl_op,3,dbg_fp,"new_loal: %X name=%s",new_loal,name); + dbg_print(dbg_avpl_op,3,dbg_fp,"new_loal_p: %X name=%s",new_loal_p,name); #endif - new_loal->name = scs_subscribe(avp_strings,name); - new_loal->null.avpl = NULL; - new_loal->null.next = &new_loal->null; - new_loal->null.prev = &new_loal->null; - - return new_loal; + new_loal_p->name = scs_subscribe(avp_strings,name); + new_loal_p->null.avpl = NULL; + new_loal_p->null.next = &new_loal_p->null; + new_loal_p->null.prev = &new_loal_p->null; + new_loal_p->len = 0; + return new_loal_p; } /** @@ -1572,7 +1377,7 @@ extern LoAL* new_loal(guint8* name) { * **/ extern void loal_append(LoAL* loal, AVPL* avpl) { - LoALnode* node = g_mem_chunk_alloc(avp_chunk); + LoALnode* node = (LoALnode*)g_slice_new(any_avp_type); #ifdef _AVP_DEBUGGING dbg_print(dbg_avpl_op,3,dbg_fp,"new_loal_node: %X",node); @@ -1584,6 +1389,7 @@ extern void loal_append(LoAL* loal, AVPL* avpl) { loal->null.prev->next = node; loal->null.prev = node; + loal->len++; } @@ -1614,7 +1420,7 @@ extern AVPL* extract_first_avpl(LoAL* loal) { avpl = node->avpl; if ( avpl ) { - g_mem_chunk_free(avp_chunk,node); + g_slice_free(any_avp_type,(any_avp_type*)node); #ifdef _AVP_DEBUGGING dbg_print(dbg_avpl_op,3,dbg_fp,"extract_first_avpl: got %s",avpl->name); @@ -1648,7 +1454,7 @@ extern AVPL* extract_last_avpl(LoAL* loal){ avpl = node->avpl; if ( avpl ) { - g_mem_chunk_free(avp_chunk,node); + g_slice_free(any_avp_type,(any_avp_type*)node); #ifdef _AVP_DEBUGGING dbg_print(dbg_avpl_op,3,dbg_fp,"delete_loal_node: %X",node); #endif @@ -1709,7 +1515,7 @@ extern void delete_loal(LoAL* loal, gboolean avpls_too, gboolean avps_too) { } scs_unsubscribe(avp_strings,loal->name); - g_mem_chunk_free(avp_chunk,loal); + g_slice_free(any_avp_type,(any_avp_type*)loal); } @@ -1722,27 +1528,32 @@ extern void delete_loal(LoAL* loal, gboolean avpls_too, gboolean avps_too) { * load_loal_error: * Used by loal_from_file to handle errors while loading. **/ -void load_loal_error(FILE* fp, LoAL* loal, AVPL* curr, int linenum, guint8* fmt, ...) { +static LoAL* load_loal_error(FILE* fp, LoAL* loal, AVPL* curr, int linenum, const gchar* fmt, ...) { va_list list; - guint8* desc; - + gchar* desc; + LoAL* ret = NULL; + gchar* err; va_start( list, fmt ); desc = g_strdup_vprintf(fmt, list); va_end( list ); + + err = g_strdup_printf("Error Loading LoAL from file: in %s at line: %i, %s",loal->name,linenum,desc); + ret = new_loal(err); + + g_free(desc); + g_free(err); + if (fp) fclose(fp); if (loal) delete_loal(loal,TRUE,TRUE); if (curr) delete_avpl(curr,TRUE); - g_warning("Error Loading LoAL from file: at line: %i, %s",linenum,desc); - g_free(desc); - - return; + return ret; } -/* the maximum lenght allowed for a line */ +/* the maximum length allowed for a line */ #define MAX_ITEM_LEN 8192 /* this two ugly things are used for tokenizing */ @@ -1767,14 +1578,15 @@ case '7': case '8': case '9': case '.' * Return value: if successful a pointer to the new populated loal, else NULL. * **/ -extern LoAL* loal_from_file(guint8* filename) { - FILE *fp; - guint8 c; +extern LoAL* loal_from_file(gchar* filename) { + FILE *fp = NULL; + gchar c; int i = 0; guint32 linenum = 1; - guint8 name[MAX_ITEM_LEN]; - guint8 value[MAX_ITEM_LEN]; - guint8 op = '?'; + gchar linenum_buf[MAX_ITEM_LEN]; + gchar name[MAX_ITEM_LEN]; + gchar value[MAX_ITEM_LEN]; + gchar op = '?'; LoAL *loal = new_loal(filename); AVPL* curr = NULL; AVP* avp; @@ -1789,20 +1601,19 @@ extern LoAL* loal_from_file(guint8* filename) { #ifndef _WIN32 if (! getuid()) { - g_warning( "MATE Will not run as root"); - return NULL; + return load_loal_error(fp,loal,curr,linenum,"MATE Will not run as root"); } #endif state = START; - if (( fp = fopen(filename,"r") )) { - while(( c = (guint8) fgetc(fp) )){ + if (( fp = ws_fopen(filename,"r") )) { + while(( c = (gchar) fgetc(fp) )){ if ( feof(fp) ) { if ( ferror(fp) ) { - load_loal_error(fp,loal,curr,linenum,"Error while reading '%f'",filename); - return NULL; + report_read_failure(filename,errno); + return load_loal_error(fp,loal,curr,linenum,"Error while reading '%f'",filename); } break; } @@ -1812,8 +1623,7 @@ extern LoAL* loal_from_file(guint8* filename) { } if ( i >= MAX_ITEM_LEN - 1 ) { - load_loal_error(fp,loal,curr,linenum,"Maximum item lenght exceeded"); - return NULL; + return load_loal_error(fp,loal,curr,linenum,"Maximum item length exceeded"); } switch(state) { @@ -1826,7 +1636,6 @@ extern LoAL* loal_from_file(guint8* filename) { default: continue; } - continue; case START: switch (c) { case ' ': case '\t': @@ -1841,22 +1650,21 @@ extern LoAL* loal_from_file(guint8* filename) { i = 0; name[i++] = c; name[i] = '\0'; - - curr = new_avpl(""); + g_snprintf(linenum_buf,sizeof(linenum_buf),"%s:%u",filename,linenum); + curr = new_avpl(linenum_buf); continue; case '#': state = MY_IGNORE; continue; default: - load_loal_error(fp,loal,curr,linenum,"expecting name got: '%c'",c); - return NULL; + return load_loal_error(fp,loal,curr,linenum,"expecting name got: '%c'",c); } case BEFORE_NAME: i = 0; name[0] = '\0'; switch (c) { case '\\': - c = fgetc(fp); + c = (gchar) fgetc(fp); if (c != '\n') ungetc(c,fp); continue; case ' ': @@ -1873,8 +1681,7 @@ extern LoAL* loal_from_file(guint8* filename) { state = START; continue; default: - load_loal_error(fp,loal,curr,linenum,"expecting name got: '%c'",c); - return NULL; + return load_loal_error(fp,loal,curr,linenum,"expecting name got: '%c'",c); } case IN_NAME: switch (c) { @@ -1903,16 +1710,14 @@ extern LoAL* loal_from_file(guint8* filename) { name[i++] = c; continue; case '\n': - load_loal_error(fp,loal,curr,linenum,"operator expected found new line"); - return NULL; + return load_loal_error(fp,loal,curr,linenum,"operator expected found new line"); default: - load_loal_error(fp,loal,curr,linenum,"name or match operator expected found '%c'",c); - return NULL; + return load_loal_error(fp,loal,curr,linenum,"name or match operator expected found '%c'",c); } case IN_VALUE: switch (c) { case '\\': - value[i++] = fgetc(fp); + value[i++] = (gchar) fgetc(fp); continue; case ';': state = BEFORE_NAME; @@ -1927,8 +1732,7 @@ extern LoAL* loal_from_file(guint8* filename) { } continue; case '\n': - load_loal_error(fp,loal,curr,linenum,"';' expected found new line"); - return NULL; + return load_loal_error(fp,loal,curr,linenum,"';' expected found new line"); default: value[i++] = c; continue; @@ -1940,7 +1744,7 @@ extern LoAL* loal_from_file(guint8* filename) { return loal; } else { - load_loal_error(NULL,loal,NULL,0,"Cannot Open file '%s'",filename); - return NULL; + report_open_failure(filename,errno,FALSE); + return load_loal_error(NULL,loal,NULL,0,"Cannot Open file '%s'",filename); } }