/** * merge_avpl: * @param dst the avpl in which to merge the avps. * @param src the avpl from which to get the avps. * @param copy_avps whether avps should be copied instead of referenced. * * Adds the avps of src that are not existent in dst into dst. * * Return value: a pointer to the newly allocated string. * **/ extern void merge_avpl(AVPL* dst, AVPL* src, gboolean copy_avps) { AVPN* cd = NULL; AVPN* cs = NULL; ptrdiff_t c; AVP* copy; #ifdef _AVP_DEBUGGING dbg_print(dbg_avpl_op,3,dbg_fp,"merge_avpl: %X %X",dst,src); #endif cs = src->null.next; cd = dst->null.next; while(cs->avp) { if(cd->avp) { c = ADDRDIFF(cd->avp->n,cs->avp->n); } else { c = -1; } if (c > 0) { if (cd->avp) cd = cd->next; } else if (c < 0) { if (copy_avps) { copy = avp_copy(cs->avp); if ( ! insert_avp(dst,copy) ) { delete_avp(copy); } } else { insert_avp(dst,cs->avp); } cs = cs->next; } else { if ( ! cd->avp || ! (cd->avp->v == cs->avp->v) ) { if (copy_avps) { copy = avp_copy(cs->avp); if ( ! insert_avp(dst,copy) ) { delete_avp(copy); } } else { insert_avp(dst,cs->avp); } } cs = cs->next; if (cd->avp) cd = cd->next; } } #ifdef _AVP_DEBUGGING dbg_print(dbg_avpl_op,8,dbg_fp,"merge_avpl: done"); #endif return; }
/** * merge_avpl: * @param name the name of the new avpl. * @param avpl the avpl from which to get the avps. * @param copy_avps whether avps should be copied instead of referenced. * * Creates a new avpl containing the same avps as the given avpl * It will either reference or copie the avps. * * Return value: a pointer to the newly allocated string. * **/ extern AVPL* new_avpl_from_avpl(const gchar* name, AVPL* avpl, gboolean copy_avps) { AVPL* newavpl = new_avpl(name); void* cookie = NULL; AVP* avp; AVP* copy; #ifdef _AVP_DEBUGGING dbg_print(dbg_avpl_op,3,dbg_fp,"new_avpl_from_avpl: %X from=%X name='%s'",newavpl,avpl,name); #endif while(( avp = get_next_avp(avpl,&cookie) )) { if (copy_avps) { copy = avp_copy(avp); if ( ! insert_avp(newavpl,copy) ) { delete_avp(copy); } } else { insert_avp(newavpl,avp); } } #ifdef _AVP_DEBUGGING dbg_print(dbg_avpl_op,8,dbg_fp,"new_avpl_from_avpl: done"); #endif return newavpl; }
/** * delete_avpl: * @param avpl the avpl from which to try to extract the avp. * @param avps_too whether or not it should delete the avps as well. * * Destroys an avpl and releases the resources it uses. If told to do * so releases the avps as well. * **/ extern void delete_avpl(AVPL* avpl, gboolean avps_too) { AVP* avp; #ifdef _AVP_DEBUGGING dbg_print(dbg_avpl,3,dbg_fp,"delete_avpl: %X",avpl); #endif while(( avp = extract_last_avp(avpl))) { if (avps_too) { delete_avp(avp); } } scs_unsubscribe(avp_strings,avpl->name); g_slice_free(any_avp_type,(any_avp_type*)avpl); }
static void get_pdu_fields(gpointer k, gpointer v, gpointer p) { int hfid = *((int*) k); gchar* name = (gchar*) v; tmp_pdu_data* data = (tmp_pdu_data*) p; GPtrArray* fis; field_info* fi; guint i,j; mate_range* curr_range; guint start; guint end; AVP* avp; gchar* s; fis = proto_get_finfo_ptr_array(data->tree, hfid); if (fis) { for (i = 0; i < fis->len; i++) { fi = (field_info*) g_ptr_array_index(fis,i); start = fi->start; end = fi->start + fi->length; dbg_print(dbg_pdu,5,dbg_facility,"get_pdu_fields: found field %i-%i",start,end); for (j = 0; j < data->ranges->len; j++) { curr_range = (mate_range*) g_ptr_array_index(data->ranges,j); if (curr_range->end >= end && curr_range->start <= start) { avp = new_avp_from_finfo(name, fi); if (*dbg_pdu > 4) { s = avp_to_str(avp); dbg_print(dbg_pdu,0,dbg_facility,"get_pdu_fields: got %s",s); g_free(s); } if (! insert_avp(data->pdu->avpl,avp) ) { delete_avp(avp); } } } } } }
/** * new_avpl_loose_match: * @param name the name of the resulting avpl * @param src avpl to be matched agains an "op" avpl * @param op the "op" avpl that will be matched against the src avpl * @param copy_avps whether the avps in the resulting avpl should be copied * * creates an avp list containing any avps in src matching any avps in op * it will eventually create an empty list in none match * * Return value: a pointer to the newly created avpl containing the * matching avps. **/ extern AVPL* new_avpl_loose_match(const gchar* name, AVPL* src, AVPL* op, gboolean copy_avps) { AVPL* newavpl = new_avpl(scs_subscribe(avp_strings, name)); AVPN* co = NULL; AVPN* cs = NULL; ptrdiff_t c; AVP* m; AVP* copy; #ifdef _AVP_DEBUGGING dbg_print(dbg_avpl_op,3,dbg_fp,"new_avpl_loose_match: %X src=%X op=%X name='%s'",newavpl,src,op,name); #endif cs = src->null.next; co = op->null.next; while(1) { if (!co->avp) { return newavpl; } if (!cs->avp) { return newavpl; } c = ADDRDIFF(co->avp->n, cs->avp->n); if ( c > 0 ) { if (co->avp) co = co->next; } else if (c < 0) { if (cs->avp) cs = cs->next; } else { m = match_avp(cs->avp,co->avp); if(m) { if (copy_avps) { copy = avp_copy(m); if ( ! insert_avp(newavpl,copy) ) { delete_avp(copy); } } else { insert_avp(newavpl,m); } } if (cs->avp) cs = cs->next; } } #ifdef _AVP_DEBUGGING dbg_print(dbg_avpl_op,6,dbg_fp,"new_avpl_loose_match: done!"); #endif return NULL; }
/** * loal_from_file: * @param filename the file containing a loals text representation. * * Given a filename it will attempt to load a loal containing a copy of * the avpls represented in the file. * * Return value: if successful a pointer to the new populated loal, else NULL. * **/ extern LoAL* loal_from_file(gchar* filename) { FILE *fp = NULL; gchar c; int i = 0; guint32 linenum = 1; 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; enum _load_loal_states { START, BEFORE_NAME, IN_NAME, IN_VALUE, MY_IGNORE } state; #ifndef _WIN32 if (! getuid()) { return load_loal_error(fp,loal,curr,linenum,"MATE Will not run as root"); } #endif state = START; if (( fp = ws_fopen(filename,"r") )) { while(( c = (gchar) fgetc(fp) )){ if ( feof(fp) ) { if ( ferror(fp) ) { report_read_failure(filename,errno); return load_loal_error(fp,loal,curr,linenum,"Error while reading '%f'",filename); } break; } if ( c == '\n' ) { linenum++; } if ( i >= MAX_ITEM_LEN - 1 ) { return load_loal_error(fp,loal,curr,linenum,"Maximum item length exceeded"); } switch(state) { case MY_IGNORE: switch (c) { case '\n': state = START; i = 0; continue; default: continue; } case START: switch (c) { case ' ': case '\t': /* ignore whitespace at line start */ continue; case '\n': /* ignore empty lines */ i = 0; continue; case AVP_NAME_CHAR: state = IN_NAME; i = 0; name[i++] = c; name[i] = '\0'; g_snprintf(linenum_buf,sizeof(linenum_buf),"%s:%u",filename,linenum); curr = new_avpl(linenum_buf); continue; case '#': state = MY_IGNORE; continue; default: 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 = (gchar) fgetc(fp); if (c != '\n') ungetc(c,fp); continue; case ' ': case '\t': continue; case AVP_NAME_CHAR: state = IN_NAME; name[i++] = c; name[i] = '\0'; continue; case '\n': loal_append(loal,curr); state = START; continue; default: return load_loal_error(fp,loal,curr,linenum,"expecting name got: '%c'",c); } case IN_NAME: switch (c) { case ';': state = BEFORE_NAME; op = '?'; name[i] = '\0'; value[0] = '\0'; i = 0; avp = new_avp(name,value,op); if (! insert_avp(curr,avp) ) { delete_avp(avp); } continue; case AVP_OP_CHAR: name[i] = '\0'; i = 0; op = c; state = IN_VALUE; continue; case AVP_NAME_CHAR: name[i++] = c; continue; case '\n': return load_loal_error(fp,loal,curr,linenum,"operator expected found new line"); default: return load_loal_error(fp,loal,curr,linenum,"name or match operator expected found '%c'",c); } case IN_VALUE: switch (c) { case '\\': value[i++] = (gchar) fgetc(fp); continue; case ';': state = BEFORE_NAME; value[i] = '\0'; i = 0; avp = new_avp(name,value,op); if (! insert_avp(curr,avp) ) { delete_avp(avp); } continue; case '\n': return load_loal_error(fp,loal,curr,linenum,"';' expected found new line"); default: value[i++] = c; continue; } } } fclose (fp); return loal; } else { report_open_failure(filename,errno,FALSE); return load_loal_error(NULL,loal,NULL,0,"Cannot Open file '%s'",filename); } }
/** * new_avpl_exact_match: * @param name the name of the resulting avpl * @param src avpl to be matched agains an "op" avpl * @param op the "op" avpl that will be matched against the src avpl * @param copy_avps whether the avps in the resulting avpl should be copied * * creates an avp list containing every avp in src matching every avp in op * it will not create a list unless every avp in op is matched only once * to every avp in op. * * Return value: a pointer to the newly created avpl containing the * matching 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; ptrdiff_t c; AVP* m; 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 = ADDRDIFF(co->avp->n,cs->avp->n); if ( c > 0 ) { delete_avpl(newavpl,TRUE); return NULL; } else if (c < 0) { cs = cs->next; if (! cs->avp ) { delete_avpl(newavpl,TRUE); return NULL; } } else { m = match_avp(cs->avp,co->avp); if(m) { cs = cs->next; co = co->next; if (copy_avps) { copy = avp_copy(m); if ( ! insert_avp(newavpl,copy) ) { delete_avp(copy); } } else { insert_avp(newavpl,m); } if (!co->avp) { return newavpl; } if (!cs->avp) { delete_avpl(newavpl,TRUE); return NULL; } } else { delete_avpl(newavpl,TRUE); return NULL; } } } /* should never be reached */ return NULL; }
/** * new_avpl_every_match: * @param name the name of the resulting avpl * @param src avpl to be matched agains an "op" avpl * @param op the "op" avpl that will be matched against the src avpl * @param copy_avps whether the avps in the resulting avpl should be copied * * creates an avp list containing any avps in src matching every avp in op * it will not create a list if there is not a match for every attribute in op * * Return value: a pointer to the newly created avpl containing the * matching avps. **/ extern AVPL* new_avpl_every_match(const gchar* name, AVPL* src, AVPL* op, gboolean copy_avps) { AVPL* newavpl; AVPN* co = NULL; AVPN* cs = NULL; 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)); if (op->len == 0) return newavpl; matches = TRUE; cs = src->null.next; co = op->null.next; while(1) { if (!co->avp) { break; } if (!cs->avp) { break; } c = ADDRDIFF(co->avp->n,cs->avp->n); if ( c > 0 ) { delete_avpl(newavpl,TRUE); return NULL; } else if (c < 0) { cs = cs->next; if (! cs->avp ) { break; } } else { m = match_avp(cs->avp,co->avp); if(m) { matches++; cs = cs->next; co = co->next; if (copy_avps) { copy = avp_copy(m); if ( ! insert_avp(newavpl,copy) ) { delete_avp(copy); } } else { insert_avp(newavpl,m); } } else { cs = cs->next; } } } if (matches) { return newavpl; } else { delete_avpl(newavpl,TRUE); return NULL; } }