/* ringbuffer.c * Routines for packet capture windows * * $Id: ringbuffer.c,v 1.3 2002/06/23 20:30:01 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * 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. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_LIBPCAP #ifdef HAVE_IO_H #include #endif #ifdef HAVE_FCNTL_H #include #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #ifdef NEED_SNPRINTF_H #include "snprintf.h" #endif #include "wiretap/wtap.h" #include "ringbuffer.h" /* Win32 needs the O_BINARY flag for open() */ #ifndef O_BINARY #define O_BINARY 0 #endif /* Ringbuffer file structure */ typedef struct _rb_file { gchar* name; int fd; time_t creation_time; gboolean is_new; guint16 number; wtap_dumper* pdh; long start_pos; } rb_file; /* Ringbuffer data structure */ typedef struct _ringbuf_data { rb_file* files; guint num_files; /* Number of ringbuffer files */ guint curr_file_num; /* Number of the current file */ gchar* fprefix; /* Filename prefix */ gchar* fsuffix; /* Filename suffix */ } ringbuf_data; /* Create the ringbuffer data structure */ static ringbuf_data rb_data; /* * Initialize the ringbuffer data structure */ int ringbuf_init(const char *capfile_name, guint num_files) { int save_file_fd; unsigned int i; char *pfx; gchar *save_file; char save_file_num[3+1]; /* just to be sure ... */ if (num_files <= RINGBUFFER_MAX_NUM_FILES) { rb_data.num_files = num_files; } else { rb_data.num_files = RINGBUFFER_MAX_NUM_FILES; } /* Check file name */ if (capfile_name == NULL) { /* ringbuffer does not work with temporary files! */ return -1; } /* Open the initial file */ save_file_fd = open(capfile_name, O_RDWR|O_BINARY|O_TRUNC|O_CREAT, 0600); if (save_file_fd == -1) { /* open failed */ return -1; } /* allocate memory */ rb_data.files = (rb_file *)calloc(num_files, sizeof(rb_file)); if (rb_data.files == NULL) { /* could not allocate memory */ return -1; } /* initialize */ rb_data.fprefix = NULL; rb_data.fsuffix = NULL; for (i=0; isave_file = rb_data.files[next_file_num].name; cf->save_file_fd = rb_data.files[next_file_num].fd; (*pdh) = rb_data.files[next_file_num].pdh; /* mark the file as used */ rb_data.files[next_file_num].is_new = FALSE; /* finally set the current file number */ rb_data.curr_file_num = next_file_num; if (err_on_next) return FALSE; return TRUE; } /* * Calls wtap_dump_close() for all ringbuffer files */ gboolean ringbuf_wtap_dump_close(capture_file *cf, int *err) { gboolean ret_val; unsigned int i; gchar *new_name; char filenum[5+1]; char timestr[14+1]; FILE *fh; /* assume success */ ret_val = TRUE; /* close all files */ for (i=0; isave_file = rb_data.files[rb_data.curr_file_num].name; return ret_val; } /* * Frees all memory allocated by the ringbuffer */ void ringbuf_free() { unsigned int i; if (rb_data.files != NULL) { for (i=0; i < rb_data.num_files; i++) { g_free(rb_data.files[i].name); rb_data.files[i].name = NULL; } free(rb_data.files); rb_data.files = NULL; } g_free(rb_data.fprefix); g_free(rb_data.fsuffix); } /* * Frees all memory allocated by the ringbuffer */ void ringbuf_error_cleanup(void) { unsigned int i; if (rb_data.files == NULL) { ringbuf_free(); return; } for (i=0; i