Blame src/list.c

Packit 762fc5
/* aide, Advanced Intrusion Detection Environment
Packit 762fc5
 *
Packit 762fc5
 * Copyright (C) 1999-2002,2005,2006,2010 Rami Lehti,Pablo Virolainen,
Packit 762fc5
 * Richard van den Berg, Hannes von Haugwitz
Packit 762fc5
 * $Header$
Packit 762fc5
 *
Packit 762fc5
 * This program is free software; you can redistribute it and/or
Packit 762fc5
 * modify it under the terms of the GNU General Public License as
Packit 762fc5
 * published by the Free Software Foundation; either version 2 of the
Packit 762fc5
 * License, or (at your option) any later version.
Packit 762fc5
 *
Packit 762fc5
 * This program is distributed in the hope that it will be useful, but
Packit 762fc5
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 762fc5
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Packit 762fc5
 * General Public License for more details.
Packit 762fc5
 *
Packit 762fc5
 * You should have received a copy of the GNU General Public License
Packit 762fc5
 * along with this program; if not, write to the Free Software
Packit 762fc5
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Packit 762fc5
 */
Packit 762fc5
Packit 762fc5
#include "aide.h"
Packit 762fc5
#include <stdlib.h>
Packit 762fc5
#include "list.h"
Packit 762fc5
#include "report.h"
Packit 762fc5
/*for locale support*/
Packit 762fc5
#include "locale-aide.h"
Packit 762fc5
/*for locale support*/
Packit 762fc5
Packit 762fc5
/* list
Packit 762fc5
 * limitations:
Packit 762fc5
 * Only the head knows where the tail is
Packit 762fc5
 * Every item knows where the head is
Packit 762fc5
 
Packit 762fc5
 * And that is not true anymore. 
Packit 762fc5
 * Now list has header which knows head and tail.
Packit 762fc5
 * Every item knows header.
Packit 762fc5
 
Packit 762fc5
 */
Packit 762fc5
Packit 762fc5
Packit 762fc5
/* list_sorted_insert()
Packit 762fc5
 * Adds an item in a sorted list:
Packit 762fc5
 *   - The first argument is the head of the list
Packit 762fc5
 *   - The second argument is the data to be added
Packit 762fc5
 *   - The third argument is the function pointer to the compare function to use
Packit 762fc5
 *   - Returns the head of the list
Packit 762fc5
 */
Packit 762fc5
list* list_sorted_insert(list* listp, void* data, int (*compare) (const void*, const void*)) {
Packit 762fc5
    list* newitem=NULL;
Packit 762fc5
    list* curitem=NULL;
Packit 762fc5
    newitem=(list*)malloc(sizeof(list));
Packit 762fc5
    if (newitem==NULL) {
Packit 762fc5
        error(0,"Not enough memory to add a new item to list.\n");
Packit 762fc5
        exit(EXIT_FAILURE);
Packit 762fc5
    }
Packit 762fc5
    if (listp==NULL){
Packit 762fc5
        list_header* header=(list_header*)malloc(sizeof(list_header));
Packit 762fc5
        if (header==NULL){
Packit 762fc5
            error(0,"Not enough memory for list header allocation\n");
Packit 762fc5
            exit(EXIT_FAILURE);
Packit 762fc5
        }
Packit 762fc5
        newitem->data=data;
Packit 762fc5
        newitem->header=header;
Packit 762fc5
        newitem->next=NULL;
Packit 762fc5
        newitem->prev=NULL;
Packit 762fc5
        header->head=newitem;
Packit 762fc5
        header->tail=newitem;
Packit 762fc5
        return newitem;
Packit 762fc5
    } else {
Packit 762fc5
        /* add element in sorted, non-empty list (use insertion sort) */
Packit 762fc5
        curitem = listp->header->head;
Packit 762fc5
        newitem->header=listp->header;
Packit 762fc5
        newitem->data=data;
Packit 762fc5
        if (compare(newitem->data,curitem->data) <= 0) {
Packit 762fc5
            /* new element is the new head */
Packit 762fc5
            listp->header->head=newitem;
Packit 762fc5
            curitem->prev=newitem;
Packit 762fc5
            newitem->next=curitem;
Packit 762fc5
            newitem->prev=NULL;
Packit 762fc5
            return newitem;
Packit 762fc5
        } else {
Packit 762fc5
            /* find position for new element */
Packit 762fc5
            while(compare(newitem->data, curitem->data) > 0 && curitem->next != NULL) {
Packit 762fc5
               curitem=curitem->next;
Packit 762fc5
            }
Packit 762fc5
            if (curitem->next == NULL && compare(newitem->data, curitem->data) > 0) {
Packit 762fc5
                /* new element is the new tail */
Packit 762fc5
                listp->header->tail=newitem;
Packit 762fc5
                curitem->next=newitem;
Packit 762fc5
                newitem->prev=curitem;
Packit 762fc5
                newitem->next=NULL;
Packit 762fc5
            } else {
Packit 762fc5
                /* new element is an inner element */
Packit 762fc5
                curitem->prev->next=newitem;
Packit 762fc5
                newitem->prev=curitem->prev;
Packit 762fc5
                curitem->prev=newitem;
Packit 762fc5
                newitem->next=curitem;
Packit 762fc5
            }
Packit 762fc5
        }
Packit 762fc5
        return listp;
Packit 762fc5
    }
Packit 762fc5
}
Packit 762fc5
Packit 762fc5
/* list_append()
Packit 762fc5
 * append an item to list
Packit 762fc5
 * returns the head
Packit 762fc5
 * The first argument is the head of the list
Packit 762fc5
 * The second argument is the data to be added
Packit 762fc5
 * Returns list head
Packit 762fc5
 */
Packit 762fc5
Packit 762fc5
Packit 762fc5
/* 
Packit 762fc5
 * Some way to handle mallocs failure would be nice.
Packit 762fc5
 */
Packit 762fc5
Packit 762fc5
list* list_append(list* listp,void*data)
Packit 762fc5
{
Packit 762fc5
  list* newitem=NULL;
Packit 762fc5
  newitem=(list*)malloc(sizeof(list));
Packit 762fc5
Packit 762fc5
  if (newitem==NULL) {
Packit 762fc5
    error(0,"Not enough memory to add a new item to list.\n");
Packit 762fc5
    exit(EXIT_FAILURE);
Packit 762fc5
  }
Packit 762fc5
  
Packit 762fc5
  if(listp==NULL){
Packit 762fc5
    list_header* header=(list_header*)malloc(sizeof(list_header));
Packit 762fc5
    
Packit 762fc5
    if (header==NULL){
Packit 762fc5
      error(0,"Not enough memory for list header allocation\n");
Packit 762fc5
      exit(EXIT_FAILURE);
Packit 762fc5
    }
Packit 762fc5
    
Packit 762fc5
    newitem->data=data;
Packit 762fc5
    newitem->header=header;
Packit 762fc5
    newitem->next=NULL;
Packit 762fc5
    newitem->prev=NULL;
Packit 762fc5
Packit 762fc5
    header->head=newitem;
Packit 762fc5
    header->tail=newitem;
Packit 762fc5
Packit 762fc5
    return newitem;
Packit 762fc5
  }else {
Packit 762fc5
    
Packit 762fc5
    /* We have nonempthy list.
Packit 762fc5
     * add to last
Packit 762fc5
     */
Packit 762fc5
    
Packit 762fc5
    newitem->prev=listp->header->tail;
Packit 762fc5
    newitem->next=NULL;
Packit 762fc5
    newitem->data=data;
Packit 762fc5
    newitem->header=listp->header;
Packit 762fc5
    
Packit 762fc5
    listp->header->tail->next=newitem;
Packit 762fc5
    listp->header->tail=newitem;
Packit 762fc5
    return listp;
Packit 762fc5
  }
Packit 762fc5
  /* Not reached */
Packit 762fc5
  return NULL;
Packit 762fc5
}
Packit 762fc5
Packit 762fc5
/*
Packit 762fc5
 * delete_list_item()
Packit 762fc5
 * delete a item from list
Packit 762fc5
 * returns head of a list.
Packit 762fc5
 */
Packit 762fc5
Packit 762fc5
list* list_delete_item(list* item){
Packit 762fc5
  list* r;
Packit 762fc5
Packit 762fc5
Packit 762fc5
  if (item==NULL) {
Packit 762fc5
    error(200,"Tried to remove from empthy list\n");
Packit 762fc5
    return item;
Packit 762fc5
  }
Packit 762fc5
  
Packit 762fc5
  if (item->header->head==item->header->tail) {
Packit 762fc5
    /*
Packit 762fc5
     * Ollaan poistamassa listan ainoaa alkiota.
Packit 762fc5
     * Tällöin palautetaan NULL
Packit 762fc5
     */
Packit 762fc5
    free(item->header);
Packit 762fc5
    free(item);
Packit 762fc5
    return NULL;
Packit 762fc5
  }
Packit 762fc5
  
Packit 762fc5
  /* 
Packit 762fc5
   * Nyt meillä on listassa ainakin kaksi alkiota 
Packit 762fc5
   *  
Packit 762fc5
   */
Packit 762fc5
Packit 762fc5
  /* poistetaan listan viimeistä alkiota */
Packit 762fc5
Packit 762fc5
  if (item==item->header->tail){
Packit 762fc5
    
Packit 762fc5
    r=item->prev;
Packit 762fc5
    item->header->tail=r;
Packit 762fc5
    r->next=NULL;
Packit 762fc5
    r=r->header->head;
Packit 762fc5
    free(item);
Packit 762fc5
    return r;
Packit 762fc5
  }
Packit 762fc5
Packit 762fc5
  /*
Packit 762fc5
   * Poistetaan listan ensimmäinen alkio.
Packit 762fc5
   */  
Packit 762fc5
  if (item==item->header->head) {
Packit 762fc5
    
Packit 762fc5
    r=item->next;
Packit 762fc5
    item->header->head=r;
Packit 762fc5
    r->prev=NULL;
Packit 762fc5
    r=r->header->head;
Packit 762fc5
    
Packit 762fc5
    free(item);
Packit 762fc5
    return r;
Packit 762fc5
  }
Packit 762fc5
  
Packit 762fc5
  r=item->prev;
Packit 762fc5
Packit 762fc5
  item->prev->next=item->next;
Packit 762fc5
  item->next->prev=item->prev;
Packit 762fc5
  
Packit 762fc5
  free(item);
Packit 762fc5
  r=r->header->head;
Packit 762fc5
  
Packit 762fc5
  return r;
Packit 762fc5
  
Packit 762fc5
}