/*----------------------------------------------------------- * Name: LL_InsertBefore() * Created: Fri Sep 2 03:14:46 1994 * Author: Jonathan DeKock <dekock@winter> * DESCR: inserts an element before another element * after is the element which will be "after" me. */ DATA_PTR LL_InsertBefore(LINKED_LIST *ll, DATA_PTR data, DATA_PTR after) { if (ll->attr & LL_Intrusive) { DATA_PTR before; if (after) { before = PrevP(ll, after); } else { before = ll->tail.data; } LLMacro_IntrPlaceBetween(ll, data, before, after); } else { LL_CONTAINER *before_cont, *after_cont, *cont; cont = irrd_malloc(sizeof(LL_CONTAINER)); if (!cont) { return(NULL); } if (after) { LLMacro_GetContainer(ll, after_cont, after); before_cont = after_cont->prev; } else { before_cont = ll->tail.cont; after_cont = NULL; } cont->data = data; LLMacro_ContPlaceBetween(ll, cont, before_cont, after_cont); ll->last = cont; } ll->count++; return(data); }
/*----------------------------------------------------------- * Name: LL_InsertAfter() * Created: Fri Sep 2 01:51:07 1994 * Author: Jonathan DeKock <dekock@winter> * DESCR: inserts a data element after another elt. * before is the item "before me" or * the item which i am to follow * i.e. i am the item after BEFORE */ DATA_PTR LL_InsertAfter(LINKED_LIST *ll, DATA_PTR data, DATA_PTR before) { if (ll->attr & LL_Intrusive) { DATA_PTR after; if (before) { after = NextP(ll, before); } else { /* if !before */ after = ll->head.data; } LLMacro_IntrPlaceBetween(ll, data, before, after); } else { /* Container */ LL_CONTAINER *after_cont, *before_cont, *cont; cont = irrd_malloc(sizeof(LL_CONTAINER)); if (!cont) { return(NULL); } if (before) { LLMacro_GetContainer(ll, before_cont, before); after_cont = before_cont->next; } else { after_cont = ll->head.cont; before_cont = NULL; } cont->data = data; LLMacro_ContPlaceBetween(ll, cont, before_cont, after_cont); ll->last = cont; } ll->count++; return(data); }
/*----------------------------------------------------------- * Name: LL_InsertSortedFn() * Created: Thu Sep 1 23:49:05 1994 * Author: Jonathan DeKock <dekock@winter> * DESCR: inserts an element into a sorted list by function compare */ DATA_PTR LL_InsertSortedFn(LINKED_LIST *ll, DATA_PTR data, LL_CompareProc compare) { DATA_PTR before, after; /* If the list is Intrusive */ if (ll->attr & LL_Intrusive) { /* Search backwards to find position */ for (after = NULL, before = ll->tail.data; before; after = before, before = PrevP(ll, before)) { if ((compare)(before, data) <= 0) break; /* Got it, insert between before and after */ } LLMacro_IntrPlaceBetween(ll, data, before, after); } else { /* Container */ LL_CONTAINER *before_cont, *after_cont, *cont; cont = irrd_malloc(sizeof(LL_CONTAINER)); if (!cont) { return(NULL); } /* Search backwards to find position */ for (after_cont = NULL, before_cont = ll->tail.cont; before_cont; after_cont = before_cont, before_cont = before_cont->prev) { if ((compare)(before_cont->data, data) <= 0) break; /* Got it, insert between before and after */ } cont->data = data; LLMacro_ContPlaceBetween(ll, cont, before_cont, after_cont); before = (before_cont) ? before_cont->data : NULL; after = (after_cont) ? after_cont->data : NULL; ll->last = cont; } ll->count++; return(data); }
/* called when indexes are stored in main memory hash */ int irr_spec_hash_store (irr_database_t *database, char *key, char *value) { hash_item_t *hash_item; hash_item = irrd_malloc(sizeof(hash_item_t)); hash_item->key = strdup (key); hash_item->value = value; g_hash_table_insert(database->hash_spec, hash_item->key, hash_item); return (1); }
statusfile_t * InitStatusFile (char *filename) { statusfile_t *sf; if ((sf = irrd_malloc(sizeof(statusfile_t))) != NULL) { sf->filename = strdup(filename); if (!(sf->hash_sections = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, (GDestroyNotify)HashSectionDestroy))) goto FAIL; ReadStatusFile(sf); pthread_mutex_init (&(sf->mutex_lock), NULL); } FAIL: return (sf); }
static int ProcessLine (statusfile_t *sf, char *section, char *line) { char tmp[BUFSIZE], *p, *q, *last; hash_item_t *h_var; h_var = irrd_malloc(sizeof(hash_item_t)); tmp[BUFSIZE-1] = '\0'; strncpy(tmp, line, BUFSIZE); if (VarTrim(tmp)) { /* Sanity check: no " before = */ p = strchr(tmp, '"'); q = strchr(tmp, '='); if (p && (p < q)) return (0); if ((p = strtok_r(tmp, "=", &last)) != NULL) { /* No " in the key */ if ((q = strchr(p, '"')) != NULL) return (0); h_var->key = strdup(p); if ((p = strtok_r(NULL, "=", &last)) != NULL) { /* The " must follow the = if any */ if ((q = strchr(p, '"')) != NULL) { if (q != p) return (0); /* Truncate the string at the next " */ p = q + 1; if ((q = strchr(p, '"')) != NULL) *q = '\0'; else return (0); } } h_var->value = strdup(p); return (InsertVar(sf, section, h_var)); } } /* Failure cases */ if (h_var->key) irrd_free(h_var->key); irrd_free(h_var); return (0); }
static int InsertVar (statusfile_t *sf, char *section, hash_item_t *h) { section_hash_t *h_sect; /* Find the proper section */ if ((h_sect = g_hash_table_lookup(sf->hash_sections, section)) == NULL) { h_sect = irrd_malloc(sizeof(section_hash_t)); h_sect->key = strdup(section); h_sect->hash_vars = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, (GDestroyNotify)HashItemDestroy); g_hash_table_insert(sf->hash_sections, h_sect->key, h_sect); } g_hash_table_insert(h_sect->hash_vars, h->key, h); return (1); }
static int populate_keyhash (irr_database_t *database) { int i; IRR.key_string_hash = g_hash_table_new(g_str_hash, g_str_equal); /* populate */ for (i = 0; i < IRR_MAX_KEYS; i++) { keystring_hash_t *keystring_item; if (strlen (key_info[i].name) <= 0) continue; keystring_item = irrd_malloc(sizeof(keystring_hash_t)); keystring_item->key = strdup (key_info[i].name); keystring_item->num = i; g_hash_table_insert(IRR.key_string_hash, keystring_item->key, keystring_item); } return (1); }
/*----------------------------------------------------------- * Name: LL_Prepend() * Created: Thu Sep 1 14:40:33 1994 * Author: Jonathan DeKock <dekock@winter> * DESCR: places data on the head of the list */ DATA_PTR LL_Prepend(LINKED_LIST *ll, DATA_PTR data) { if (ll->attr & LL_Intrusive) { LLMacro_IntrPlaceBetween(ll, data, NULL, ll->head.data); } else { LL_CONTAINER *NULL_CONT = NULL; /* Required to make macro work */ LL_CONTAINER *cont = irrd_malloc(sizeof(LL_CONTAINER)); if (!cont) { return(NULL); } cont->data = data; LLMacro_ContPlaceBetween(ll, cont, NULL_CONT, ll->head.cont); ll->last = cont; } ll->count++; return(data); }
int SetStatusString (statusfile_t *sf, char *section, char *variable, char *value) { hash_item_t *p_hi; int ret = 0; if (sf->filename == NULL) return (0); if (!pthread_mutex_lock(&(sf->mutex_lock))) { /* Do we delete the value? */ if (value == NULL) { DeleteVar(sf, section, variable); ret = 1; } /* See if its already in there. If it is, then replace the current val */ else if ((p_hi = LookupVar(sf, section, variable)) != NULL) { if ((p_hi->value != NULL) && strcmp(p_hi->value, value)) { free(p_hi->value); p_hi->value = strdup(value); } ret = 1; } /* If its not, add a new value */ else { p_hi = irrd_malloc(sizeof(hash_item_t)); p_hi->key = strdup(variable); p_hi->value = strdup(value); if (InsertVar(sf, section, p_hi)) ret = 1; } ret = WriteStatusFile(sf, NULL); pthread_mutex_unlock(&(sf->mutex_lock)); } return (ret); }
/*----------------------------------------------------------- * Name: LL_Create() * Created: Tue Aug 30 19:12:42 1994 * Author: Jonathan DeKock <dekock@winter> * DESCR: Creates and initilizes a linked list with var. args */ LINKED_LIST *LL_Create(int first, ...) { va_list ap; enum LL_ATTR attr; int val; DATA_PTR ptr; LINKED_LIST *ll; /* Create it */ if (!(ll = irrd_malloc(sizeof(LINKED_LIST)))) { return(NULL); } /* Initialize it */ ll->head.data = NULL; ll->head.cont = NULL; ll->tail.data = NULL; ll->tail.cont = NULL; ll->last = NULL; ll->find_fn = NULL; ll->comp_fn = NULL; ll->destroy_fn = NULL; ll->count = 0; ll->next_offset = 0; ll->prev_offset = sizeof(DATA_PTR); ll->attr = (enum LL_ATTR) 0; /* Process the Arguments */ va_start(ap, first); for (attr = (enum LL_ATTR)first; attr; attr = va_arg(ap, enum LL_ATTR)) { LLMacro_SetAttr(ll, attr, ap, val, ptr); if (!attr) break; /* something went wrong inside --> hit default, bad attribute*/ } va_end(ap); return(ll); }
int add_access_list (int num, int permit, prefix_t *prefix, prefix_t *wildcard, int exact, int refine) { condition_t *condition = NULL; if (num < 0 || num >= MAX_ALIST) return (-1); if (find_access_list (num, permit, prefix, wildcard, exact, refine)) return (0); if (access_list[num] == NULL) { access_list[num] = LL_Create (0); } condition = irrd_malloc(sizeof(condition_t)); condition->permit = permit; /* expects Ref_Prefix can handle even a case of prefix == NULL */ condition->prefix = Ref_Prefix (prefix); condition->wildcard = Ref_Prefix (wildcard); condition->exact = exact; condition->refine = refine; LL_Add (access_list[num], condition); return (LL_GetCount (access_list[num])); }
/* as-set/route-set expansion !ias-bar */ void irr_set_expand (irr_connection_t *irr, char *name) { irr_database_t *database; time_t start_time; GArray *array; GQueue *stack; GHashTable *hash_member_examined; member_examined_hash_t *member_examined_ptr; LINKED_LIST *ll_setlist; char *set_name, *last_set_name, *mstr, *db; char *range_op, abuf[BUFSIZE]; char *lasts = NULL; int i, first, dup, expand_flag = NO_EXPAND; hash_spec_t *hash_spec; if (strchr(name, ',') != NULL) { strtok_r(name, ",", &lasts); /* check if we are expanding a route-set */ if ( (set_name = strchr(name, ':')) != NULL) set_name++; else set_name = name; if (!strncasecmp (set_name, "rs-", 3)) expand_flag = ROUTE_SET_EXPAND; else expand_flag = OTHER_EXPAND; } start_time = time(NULL); convert_toupper (name); stack = g_queue_new(); hash_member_examined = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, (GDestroyNotify)HashMemberExaminedDestroy); ll_setlist = LL_Create (LL_DestroyFunction, free, NULL); mstr = rpsl_macro_expand_add (" ", name, irr, NULL); g_queue_push_head(stack, mstr); member_examined_ptr = irrd_malloc(sizeof(member_examined_hash_t)); member_examined_ptr->key = strdup(name); g_hash_table_insert(hash_member_examined, member_examined_ptr->key, member_examined_ptr); while (!g_queue_is_empty(stack)) { if ( IRR.expansion_timeout > 0 ) { if ( (time(NULL) - start_time) > IRR.expansion_timeout ) { trace (ERROR, default_trace, "irr_set_expand(): Set expansion timeout\n"); sprintf(abuf, "Expansion maximum CPU time exceeded: %d seconds", IRR.expansion_timeout); irr_send_error(irr, abuf); goto getout; } } mstr = (char *) g_queue_pop_head(stack); /* might want to check the examined list to see if this set name has been examined already */ first = 1; lasts = NULL; range_op = strtok_r (mstr, ",", &lasts); if (!strcmp (range_op, " ")) range_op = NULL; set_name = strtok_r (NULL, ",", &lasts); irr_lock_all(irr); /* lock db's while searching */ while ((db = strtok_r (NULL, ",", &lasts)) != NULL) { if ((database = find_database (db)) == NULL) { trace (ERROR, default_trace, "irr_set_expand(): Database not found %s\n", db); sprintf(abuf, "Database not found: %s", db); irr_send_error(irr, abuf); goto getout; } make_setobj_key (abuf, set_name); if ((hash_spec = fetch_hash_spec (database, abuf, UNPACK)) != NULL) { first = 0; update_members_list (database, range_op, AF_INET, expand_flag, hash_member_examined, ll_setlist, hash_spec->ll_1, stack, irr); mbrs_by_ref_set (database, range_op, AF_INET, expand_flag, ll_setlist, set_name, hash_spec->ll_2, irr); Delete_hash_spec (hash_spec); } if (first == 0) break; } irr_unlock_all(irr); free (mstr); } first = 1; dup = 0; i = 0; last_set_name = ""; array = g_array_sized_new(FALSE, TRUE, sizeof(char*), ll_setlist->count); LL_ContIterate (ll_setlist, set_name) { g_array_append_val(array, set_name); }