Codebase list dnscat2 / a8318d6c-6d99-4df4-a4cd-6dab8bee4ca2/main client / libs / ll.c
a8318d6c-6d99-4df4-a4cd-6dab8bee4ca2/main

Tree @a8318d6c-6d99-4df4-a4cd-6dab8bee4ca2/main (Download .tar.gz)

ll.c @a8318d6c-6d99-4df4-a4cd-6dab8bee4ca2/mainraw · history · blame

/* ll.c
 * By Ron
 * Created January, 2010
 *
 * (See LICENSE.md)
 */

#include <stdio.h>

#include "libs/memory.h"

#if 0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define safe_malloc malloc
#define safe_free free
#define FALSE 0
#define TRUE 1
#endif

#include "ll.h"

ll_t *ll_create(cmpfunc_t *cmpfunc)
{
  ll_t *ll = (ll_t*) safe_malloc(sizeof(ll_t));
  ll->first = NULL;
  ll->cmpfunc = cmpfunc;

  return ll;
}

static ll_element_t *create_element(ll_index_t index, void *data)
{
  ll_element_t *element = (ll_element_t*) safe_malloc(sizeof(ll_element_t));
  element->index = index;
  element->data = data;

  return element;
}

static ll_element_t *destroy_element(ll_element_t *element)
{
  void *data = element->data;
  safe_free(element);
  return data;
}

void *ll_add(ll_t *ll, ll_index_t index, void *data)
{
  ll_element_t *element = create_element(index, data);
  void *old_data = ll_remove(ll, index);

  element->next = NULL;
  if(ll->first)
    element->next = (struct ll_element_t *)ll->first;
  ll->first     = element;

  return old_data;
}

static int compare(ll_t *ll, ll_index_t a, ll_index_t b)
{
  if(a.type != b.type)
    return FALSE;

  switch(a.type)
  {
    case LL_8:
      return a.value.u8 == b.value.u8;

    case LL_16:
      return a.value.u16 == b.value.u16;

    case LL_32:
      return a.value.u32 == b.value.u32;

    case LL_64:
      return a.value.u64 == b.value.u64;

    case LL_PTR:
      if(ll->cmpfunc)
        return ll->cmpfunc(a.value.ptr, b.value.ptr);
      else
        return a.value.ptr == a.value.ptr;
  }

  printf("We forgot to handle a linked-list type!\n");
  exit(1);
}

void *ll_remove(ll_t *ll, ll_index_t index)
{
  ll_element_t *prev = NULL;
  ll_element_t *cur = ll->first;

  while(cur)
  {
    if(compare(ll, cur->index, index))
    {
      if(prev)
        prev->next = cur->next;
      else
        ll->first = (ll_element_t *)cur->next;

      return destroy_element(cur);
    }
    prev = cur;
    cur = (ll_element_t*)prev->next;
  }

  return NULL;
}

void *ll_remove_first(ll_t *ll)
{
  ll_element_t *first = ll->first;

  if(first)
    ll->first = (ll_element_t *)first->next;

  return first ? first->data : NULL;
}

void *ll_find(ll_t *ll, ll_index_t index)
{
  ll_element_t *cur = ll->first;

  while(cur)
  {
    if(compare(ll, cur->index, index))
      return cur->data;
    cur = (ll_element_t *)cur->next;
  }

  return NULL;
}

void ll_destroy(ll_t *ll)
{
  ll_element_t *cur = ll->first;
  ll_element_t *next = NULL;

  while(cur)
  {
    next = (ll_element_t *)cur->next;
    destroy_element(cur);
    cur = next;
  }

  safe_free(ll);
}

ll_index_t ll_8(uint8_t value)
{
  ll_index_t index;
  index.type = LL_8;
  index.value.u8 = value;

  return index;
}

ll_index_t ll_16(uint16_t value)
{
  ll_index_t index;
  index.type = LL_16;
  index.value.u16 = value;

  return index;
}

ll_index_t ll_32(uint32_t value)
{
  ll_index_t index;
  index.type = LL_32;
  index.value.u32 = value;

  return index;
}

ll_index_t ll_64(uint64_t value)
{
  ll_index_t index;
  index.type = LL_64;
  index.value.u64 = value;

  return index;
}

ll_index_t ll_ptr(void *value)
{
  ll_index_t index;
  index.type = LL_PTR;
  index.value.ptr = value;

  return index;
}

#if 0
int my_strcmp(const void *a, const void *b)
{
  return strcmp((const char*)a, (const char*)b);
}

int main(int argc, const char *argv[])
{
  ll_t *ll = ll_create(NULL);

  printf("\n");
  printf("nil: %p\n", ll_find(ll, ll_16(0x123)));

  printf("\n");
  ll_add(ll, ll_16(0x12), (void*)0x32);
  printf("32:  %p\n", ll_find(ll, ll_16(0x12)));
  printf("nil: %p\n", ll_find(ll, ll_16(0x31)));
  printf("nil: %p\n", ll_find(ll, ll_32(0x12)));
  printf("nil: %p\n", ll_find(ll, ll_8(0x12)));

  printf("\n");
  ll_remove(ll, ll_16(0x123));
  printf("nil: %p\n", ll_find(ll, ll_16(0x123)));

  ll_add(ll, ll_8(1), "8");
  ll_add(ll, ll_16(1), "16");
  ll_add(ll, ll_32(1), "32");
  ll_add(ll, ll_64(1), "64");
  ll_add(ll, ll_ptr((void*)1), "ptr");

  printf("8:   %s\n", (char*)ll_find(ll, ll_8(1)));
  printf("16:  %s\n", (char*)ll_find(ll, ll_16(1)));
  printf("32:  %s\n", (char*)ll_find(ll, ll_32(1)));
  printf("64:  %s\n", (char*)ll_find(ll, ll_64(1)));
  printf("ptr: %s\n", (char*)ll_find(ll, ll_ptr((void*)1)));

  ll_remove(ll, ll_8(1));
  ll_remove(ll, ll_16(1));
  ll_remove(ll, ll_32(1));
  ll_remove(ll, ll_64(1));
  ll_remove(ll, ll_ptr((void*)1));

  printf("nil: %p\n", (char*)ll_find(ll, ll_8(1)));
  printf("nil: %p\n", (char*)ll_find(ll, ll_16(1)));
  printf("nil: %p\n", (char*)ll_find(ll, ll_32(1)));
  printf("nil: %p\n", (char*)ll_find(ll, ll_64(1)));
  printf("nil: %p\n", (char*)ll_find(ll, ll_ptr((void*)1)));

  ll_destroy(ll);

  return 0;
}
#endif