/*
    ettercap -- Virtual Buffer for dissectors

    Copyright (C) 2001  ALoR <alor@users.sourceforge.net>, NaGA <crwm@freemail.it>

    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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

    $Id: ec_vbuf.c,v 1.2 2002/04/22 19:47:25 alor Exp $
*/

#include "include/ec_main.h"

#include "include/ec_vbuf.h"

#include <stdarg.h>

// protos...

void vbuf_create(vbuf_p vbuf, u_char *buf, size_t len);
int vbuf_seek(vbuf_p vbuf, int offset, char whence);
int vbuf_memcpy(vbuf_p vbuf, void *dst, size_t len);
int vbuf_strcpy(vbuf_p vbuf, char *dst);
char * vbuf_strdup(vbuf_p vbuf);
int vbuf_put(vbuf_p vbuf, const void *src, size_t len);
int vbuf_printf(vbuf_p vbuf, const char *fmt, ...);
int vbuf_search(vbuf_p vbuf, const u_char *str, size_t len);   /* straightforward */
int vbuf_rsearch(vbuf_p vbuf, const u_char *str, size_t len);  /* reverse */
int vbuf_cmp(vbuf_p vbuf, const void *src, size_t len);


// ----------------------------


void vbuf_create(vbuf_p vbuf, u_char *buf, size_t len)
{
   vbuf->base = buf;
   vbuf->offset = 0;
   vbuf->size = len;
}


int vbuf_seek(vbuf_p vbuf, int offset, char whence)
{
   if (whence == SEEK_SET && (offset >= 0 && offset <= vbuf->size)) {
      vbuf->offset = offset;
   } else if (whence == SEEK_CUR && (vbuf->offset + offset <= vbuf->size)) {
      vbuf->offset += offset;
   } else 
      return (-1);
   
   return (vbuf->offset);
}


int vbuf_memcpy(vbuf_p vbuf, void *dst, size_t len)
{
   int i;
   u_char *p;

   p = dst;

   if ( vbuf_len(vbuf) < len)  /* no space available */
      return (-1);

   for (i = 0; i < len; i++)
      p[i] = vbuf->base[vbuf->offset + i];

   vbuf_move(vbuf, len);

   return (len);
}


int vbuf_strcpy(vbuf_p vbuf, char *dst)
{
   int i;
   
   i = strlen(vbuf_ptr(vbuf));
   
   if ( i > vbuf_len(vbuf))
      return (-1);

   strcpy(dst, vbuf_ptr(vbuf));

   vbuf_move(vbuf, i + 1);  /* skip the string a point to the NULL */
   
   return (i);
}


char * vbuf_strdup(vbuf_p vbuf)
{
   char *p;
   int i;

   i = strlen(vbuf_ptr(vbuf));
   
   if ( i > vbuf_len(vbuf))
      return NULL;

   p = calloc( i + 1, 1);
   if (p == NULL)
      ERROR_MSG("calloc()");

   strcpy(p, vbuf_ptr(vbuf));

   p[i] = '\0';

   vbuf_move(vbuf, i + 1);  /* skip the string a point to the NULL */
   
   return p;
}


int vbuf_put(vbuf_p vbuf, const void *src, size_t len)
{

   if (vbuf->offset + len > vbuf->size)
      return (-1);

   memcpy(vbuf_ptr(vbuf), src, len);

   vbuf_move(vbuf, len);
   
   return (len);
}


int vbuf_printf(vbuf_p vbuf, const char *fmt, ...)
{
   va_list ap;
   int i;

   va_start(ap, fmt);
   i = vsnprintf(vbuf_ptr(vbuf), vbuf_len(vbuf), fmt, ap);
   va_end(ap);
   
   vbuf_move(vbuf, i);
 
   return (i);
}


int vbuf_search(vbuf_p vbuf, const u_char *str, size_t len)
{
   u_char *p, *q;
  
   p = vbuf_ptr(vbuf);
   q = p + vbuf_len(vbuf);
   
   for (; q - p >= len; p++) {
      if (memcmp(p, str, len) == 0)
         return (p - vbuf_ptr(vbuf));
   }
   
   return (-1);
}


int vbuf_rsearch(vbuf_p vbuf, const u_char *str, size_t len)
{
   u_char *p, *q;
  
   p = vbuf_ptr(vbuf) + vbuf_len(vbuf) - len;
   q = vbuf_ptr(vbuf);
   
   for (; p > q; p--) {
      if (memcmp(p, str, len) == 0)
         return (p - q);
   }
   
   return (-1);
}


int vbuf_cmp(vbuf_p vbuf, const void *src, size_t len)
{

   if (vbuf_len(vbuf) < len)
      return (-1);

   return (memcmp(vbuf_ptr(vbuf), src, len));
}


/* EOF */


// vim:ts=3:expandtab

