/* SAMHAIN file system integrity testing */ /* Copyright (C) 1999, 2000 Rainer Wichmann */ /* */ /* This program is free software; you can redistribute it */ /* and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* This program is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with this program; if not, write to the Free Software */ /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config_xor.h" #include #include #include #include #undef FIL__ #define FIL__ _("sh.fifo.c") #include "samhain.h" #include "sh_mem.h" #include "sh_unix.h" #if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK) #include #endif #define SH_FIFO_MAX 128 struct dlist { /*@null@*//*@dependent@*/ struct dlist * next; char * data; /*@null@*//*@dependent@*/ struct dlist * prev; }; typedef struct fifo_str { /*@null@*//*@dependent@*/ struct dlist * head_ptr; /*@null@*//*@dependent@*/ struct dlist * tail_ptr; int fifo_cts; } SH_FIFO; /* push an item on the head of the list */ int push_list (SH_FIFO * fifo, char * indat) { struct dlist * item; size_t len; SL_ENTER(_("push_list")); if (indat == NULL || fifo == NULL) { SL_RETURN((-1), _("push_list")); } if (fifo->fifo_cts > SH_FIFO_MAX) { SL_RETURN((-1), _("push_list")); } len = sl_strlen(indat); if (len == 0) { SL_RETURN((-1), _("push_list")); } item = SH_ALLOC(sizeof(struct dlist)); /*@i@*/ item->data = SH_ALLOC(len+1); if (NULL != sl_strstr (indat, _("LOGKEY"))) { MLOCK(item->data, (len+1)); ; } strcpy (item->data, indat); /* known to fit */ item->data[len] = '\0'; if (fifo->tail_ptr == NULL) { fifo->tail_ptr = item; item->prev = NULL; } else { /*@i@*/ fifo->head_ptr->prev = item; item->prev = NULL; } item->next = fifo->head_ptr; fifo->head_ptr = item; ++(fifo->fifo_cts); SL_RETURN((fifo->fifo_cts), _("push_list")); } /* push an item on the tail of the list */ int push_tail_list (SH_FIFO * fifo, char * indat) { struct dlist * item; size_t len; SL_ENTER(_("push_tail_list")); if (indat == NULL || fifo == NULL) { SL_RETURN((-1), _("push_tail_list")); } if (fifo->fifo_cts > SH_FIFO_MAX) { SL_RETURN((-1), _("push_tail_list")); } len = sl_strlen(indat); if (len == 0) { SL_RETURN((-1), _("push_list")); } item = SH_ALLOC(sizeof(struct dlist)); /*@i@*/item->data = SH_ALLOC(len+1); if (NULL != sl_strstr (indat, _("LOGKEY"))) { MLOCK(item->data, (len+1)); ; } strcpy (item->data, indat); /* known to fit */ item->data[len] = '\0'; if (fifo->head_ptr == NULL) { item->next = NULL; fifo->head_ptr = item; } else { item->next = NULL; fifo->tail_ptr->next = item; } item->prev = fifo->tail_ptr; fifo->tail_ptr = item; ++(fifo->fifo_cts); SL_RETURN((0), _("push_tail_list")); } /* pop an item from the tail of the list */ /*@null@*/ char * pop_list (SH_FIFO * fifo) { size_t len; struct dlist * getit; char * retval; SL_ENTER(_("pop_list")); if (fifo == NULL || fifo->tail_ptr == NULL) { SL_RETURN (NULL, _("pop_list")); } getit = fifo->tail_ptr; if (getit->prev == NULL) /* last element */ { fifo->tail_ptr = NULL; fifo->head_ptr = NULL; } else { fifo->tail_ptr = getit->prev; fifo->tail_ptr->next = getit->next; } len = sl_strlen(getit->data); retval = SH_ALLOC(len+1); strcpy (retval, getit->data); /* known to fit */ retval[len] = '\0'; memset(getit->data, 0, len); if (NULL != sl_strstr (retval, _("LOGKEY"))) { MUNLOCK(getit->data, (len+1)); ; } SH_FREE(getit->data); SH_FREE(getit); --(fifo->fifo_cts); SL_RETURN (retval, _("pop_list")); }