Logo Search packages:      
Sourcecode: iacd version File versions  Download package

util.c

#define _GNU_SOURCE

#include "config.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <syslog.h>
#include <stdarg.h>
#include "util.h"
#include "log.h"

#ifndef HAVE_STRDUP
char *
strdup(const char *s)
{
    char *d = NULL;
    d = (char *) calloc ( strlen(s)+1, 1 );
    memcpy(d, s, strlen(s)+1);
    return d;
}
#endif

#ifndef HAVE_VASPRINTF
int
vasprintf(char **strp, const char *fmt, va_list ap)
{
    char str[4096];
    memset(str, 0, sizeof(str));

    vsnprintf(str, sizeof(str), fmt, ap);

    *strp = strdup(str);
    return strlen(str);
}
#endif

#ifndef HAVE_ASPRINTF
int
asprintf(char **strp, const char *fmt, ...)
{
    va_list args;
    char str[4096];

    memset(str, 0, sizeof(str));

    va_start(args, fmt);
    vsnprintf(str, sizeof(str), fmt, args);
    va_end(args);

    *strp = strdup(str);

    return strlen(str);
}
#endif
    

int
iac_match_mask(const char *mask, const char *str)
{
    int i; /* index for mask */
    int n; /* index for str */
    char c;

    if (!mask || !str)
        return 0;

    for (i=0,n=0; mask[i] != '\0'; i++,n++) {

        if (mask[i] == '*') {
            c = rl_tolower(mask[i+1]);

            if (c == '\0') {
                /*
                 * blah* will match everything that begins with blah
                 */
                return 1;
            }

            /*
             * nananana
             */
            if (c == '+')
                c = ' ';

            /*
             * look for c in str, c is the character after the
             * wildcard in mask
             */
            for (; rl_tolower(str[n]) != c; n++) {

                if ( str[n] == '\0') {
                    /*
                     * str ends but the required character after *
                     * was not found -> mismatch
                     */
                    return 0;
                }
            }

            n--;
        } else if (mask[i] == '+') {
            if (str[n] !=  ' ')
                return 0;

        /*
         * mask[i] is not a special character, thus both, mask
         * and str, must match at the current index
         */
        } else if ( rl_tolower(mask[i]) != rl_tolower(str[n]) ) {
            return 0;
        }
    }

    /*
     * mask ends, if str ends as well -> match
     */
    if (str[n] == '\0')
        return 1;
    else
        return 0;
}


int
rs_parse_match_fword(const char *str, const char *word)
{
    if ( str && word )
    {
        int i;

        /*
         * go thru string
         */
        for (i=0; str[i] != '\0'; i++)
        {
            /*
             * it does match if wer are still in the loop (=all chars matched
             * until now) the word is at the end and the string is a space
             */
            if ( word[i] == '\0' && str[i] == ' ' )
                return 1;

            /*
             * exit loop if chars don't match
             */
            if ( rl_tolower(str[i]) != rl_tolower(word[i]) )
                return 0;
        }

            if ( word[i] == '\0' && str[i] == '\0')
                  return 1;
    }


    return 0;
}

__inline__ char *
ti_tolower(char *str)
{
    int i;
    for (i=0; str[i] != '\0'; i++) str[i] = rl_tolower(str[i]);
    return str;
}

char *
ti_trim(char *str)
{
    int len;
    for ( len = strlen(str)-1 ; len >= 0 ; len-- ) {
        if (str[len] == ' ')
            str[len] = '\0';
        else
            break;
    }

    return str;
}




int
rl_stricmp(const char *str1, const char *str2)
{
    int c, q;

    if (!str1)
        return -1;

    if (!str2)
        return 1;

    while ((c = rl_tolower(*str1)) == (q = rl_tolower(*str2))) {

        /*
         * why not check for c and q?
         * because the only case that c or q is '\0' when
         * both are '\0' otherwise the while loop would be
         * false before
         */
        if (c == 0)
            return 0;

        str1++;
        str2++;
    }

    if (c < q)
        return -1;
    else
        return 1;
}


__inline__ int rl_tolower(int f)
{
    if (f > 64 && f < 91)
      {
            f+=32;
      }
    return f;
}

void
rl_remove_eol(char *s)
{
    int i = strlen(s);
    if (s[i-1] == '\n')
        s[i-1] = '\0';
    i = strlen(s);
    if (s[i-1] == '\r')
        s[i-1] = '\0';
}


rl_list_t *
rl_list_new(void)
{
    rl_list_t *nl;
    RL_MALLOC(nl, rl_list_t, 1);
    memset(nl, 0, sizeof(rl_list_t));

    nl->rl_list_start = NULL;
    nl->rl_list_end = NULL;
    nl->rl_current = NULL;

    return nl;
}

void
rl_list_del(rl_list_t *l)
{
    rl_list_item_t *li, *t;

    ERRCHECK(l);
    
    for (li = l->rl_list_start; li != NULL; li = t) {
        t = li->rli_next;
        if (li->rli_freeable)
            RL_FREE(li->rli_data);
        RL_FREE(li);
    }

    RL_FREE(l);
}

void
rl_list_add(rl_list_t *l, void *data, int freeable)
{
    rl_list_item_t *li, *t;

    ERRCHECK(l);

    RL_MALLOC(li, rl_list_item_t, 1);
    memset(li, 0, sizeof(rl_list_item_t));

    li->rli_data = data;
    li->rli_next = NULL;
    li->rli_prev = NULL;
    li->rli_freeable = freeable;

    if (!l->rl_list_start) {
        l->rl_list_start = li;
        l->rl_list_end   = li;
    } else {
        for (t=l->rl_list_start; t->rli_next != NULL; t=t->rli_next);
        t->rli_next = li;
        li->rli_prev = t;
        l->rl_list_end = li;
    }
}

void
rl_list_rem(rl_list_t *l, void *d)
{
    rl_list_item_t *t, *last = NULL;
    ERRCHECK(l);

    for (t = l->rl_list_start; t != NULL; t=t->rli_next) {
        if (t->rli_data == d) {
            if (last)
                last->rli_next = t->rli_next;
            else
                l->rl_list_start = t->rli_next;

            if (!t->rli_next)
                l->rl_list_end = last;
            else
                t->rli_next->rli_prev = last;

            if (t->rli_freeable)
                RL_FREE(t->rli_data);
            RL_FREE(t);
            
            return;
        }
        last = t;
    }
}


rl_htable_t *
rl_hashtable_new(unsigned int size, unsigned int multiplier, int flags)
{
   rl_htable_t *nht;
   
   RL_MALLOC(nht, rl_htable_t, 1);
   memset(nht, 0, sizeof(rl_htable_t));

   RL_MALLOC(nht->rh_symtab, rl_htable_chain_t, size);
   memset(nht->rh_symtab, 0, sizeof(rl_htable_chain_t) * size);

   nht->rh_multiplier = multiplier;
   nht->rh_stsize = size;
   nht->rh_entries = 0;
   nht->rh_free_data = TRUE;

   if (flags & RL_HTABLE_DONT_FREE_DATA) {
       nht->rh_free_data = FALSE;
   }
   
   return nht;
}


void
rl_hashtable_del(rl_htable_t *htable)
{
   rl_htable_entry_t *te, *next;
   unsigned int i;

   ERRCHECK(htable);

   for (i = 0; i < htable->rh_stsize; i++) {
      for (te = htable->rh_symtab[i].rhc_el; te != NULL; te = next) {
         next = te->rhe_next;
         RL_FREE(te->rhe_key);
         if (htable->rh_free_data)
             RL_FREE(te->rhe_data);
         RL_FREE(te);
      }
   }

   RL_FREE(htable->rh_symtab);
   RL_FREE(htable);
}


void *
rl_hashtable_get(rl_htable_t *htable, const char *id)
{
   unsigned int key;
   rl_htable_entry_t *te = NULL;

   ERRCHECK(htable);
   ERRCHECK(id);

   key = rl_hashtable_hash(htable, id);

   for (te = htable->rh_symtab[key].rhc_el; te != NULL; te = te->rhe_next)
      if (strcmp(id, te->rhe_key) == 0)
         return te->rhe_data;

   return NULL;
}

void
rl_hashtable_add(rl_htable_t *htable, const char *id, void *data)
{
   unsigned int key;
   rl_htable_entry_t *entry = NULL;
   
   ERRCHECK(htable);
   ERRCHECK(id);
   
   RL_MALLOC(entry, rl_htable_entry_t, 1);
   memset(entry, 0, sizeof(rl_htable_entry_t));
  
   entry->rhe_key = strdup(id);
   key = rl_hashtable_hash(htable, entry->rhe_key);
   entry->rhe_data = data;

   entry->rhe_next = htable->rh_symtab[key].rhc_el;
   htable->rh_symtab[key].rhc_el = entry;

   htable->rh_entries++;
}

int
rl_hashtable_rem(rl_htable_t *htable, const char *id)
{
    rl_htable_entry_t *e = NULL;
    rl_htable_entry_t *last = NULL;
    int i;

    ERRCHECK(htable);
    ERRCHECK(id);

    for (i=0; i < htable->rh_stsize; i++) {
        for (e = htable->rh_symtab[i].rhc_el; e != NULL; e = e->rhe_next) {
            if (strcmp(e->rhe_key, id) == 0) {
                if (last)
                    last->rhe_next = e->rhe_next;
                else
                    htable->rh_symtab[i].rhc_el = e->rhe_next;

                RL_FREE(e->rhe_key);
                if (htable->rh_free_data) {
                    RL_FREE(e->rhe_data);
                }
                RL_FREE(e);
                htable->rh_entries--;
                return 0;
            }
            last = e;
        }
            last = NULL;
    }

    return 1;
}

unsigned int
rl_hashtable_hash(rl_htable_t *htable, const char *id)
{
   unsigned int h = 0;
   unsigned char *p = NULL;
   
   ERRCHECK(htable);
   ERRCHECK(id);
   
   for (p = (unsigned char *) id; *p != '\0'; p++)
      h = htable->rh_multiplier * h + *p;
   
   return h % htable->rh_stsize;
}

rl_token_list_t *rl_token_new_token_list(void);
rl_token_list_item_t *rl_token_new_list_item(void);

rl_token_list_t *
rl_token_split(char *str, char *fmt)
{
    rl_token_list_t *tl = NULL;
    rl_token_list_item_t *c = NULL;
    rl_token_list_item_t *tmp = NULL;

    int i, n;
    char *prev = NULL;

    tl = rl_token_new_token_list();

    prev = &(str[0]);

    for (i=0,n=0;;i++) {

        if (str[i] == fmt[n] || str[i] == '\0') {
            
            tmp = rl_token_new_list_item();

            if (c) c->rtli_next = tmp;
            c = tmp;

            if (!tl->rtl_list) {
                tl->rtl_list = tmp;
                tl->rtl_current = tmp;
            }

            c->rtli_val = prev;
            prev = &(str[i+1]);

            tl->rtl_ntokens++;

            if (str[i] == '\0')
                break;

            if (fmt[n] == '\0') {
                break;
            } else {
                str[i] = '\0';
            }

            n++;
        }
    }

    return tl;
}

char *
rl_token_get_next(rl_token_list_t *l)
{
    char *r = l->rtl_current->rtli_val;

    if (l->rtl_current->rtli_next)
        l->rtl_current = l->rtl_current->rtli_next;
    else
        l->rtl_current = l->rtl_list;

    return r;
}

rl_token_list_t *
rl_token_new_token_list(void)
{
    rl_token_list_t *tl;

    RL_MALLOC(tl, rl_token_list_t, 1);
    memset(tl, 0, sizeof(rl_token_list_t));

    tl->rtl_list = NULL;
    tl->rtl_ntokens = 0;
    tl->rtl_current = NULL;

    return tl;
}

void
rl_token_del_token_list(rl_token_list_t *list)
{
    rl_token_list_item_t *li, *t;
    li = list->rtl_list;

    while (li) {
        t = li->rtli_next;
        RL_FREE(li);
        li = t;
    }
    
    RL_FREE(list);
}

rl_token_list_item_t *rl_token_new_list_item(void)
{
    rl_token_list_item_t *tli;

    RL_MALLOC(tli, rl_token_list_item_t, 1);
    memset(tli, 0, sizeof(rl_token_list_item_t));

    tli->rtli_val = NULL;
    tli->rtli_next = NULL;

    return tli;
}

char *
iac_safe_strncpy(char *dest, const char *src, size_t len)
{
    char *s = strncpy(dest, src, len);
    if (len > 1)
        dest[len-1] = '\0';
    return s;
}

char *
iac_astrcat(char **dest, const char *src)
{
    int i, n;

    if ( !(*dest) ) {
        *dest = (char *) calloc( 1, strlen(src) + 1 );
    } else {
        i = strlen(src);
        n = strlen(*dest);

        *dest = (char *) realloc(*dest, ( n + i + 1 ) );
    }

    strcat(*dest, src);
    return *dest;
}

Generated by  Doxygen 1.6.0   Back to index