Skip to content

Commit

Permalink
Add file output buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
dragorn committed Jan 14, 2018
1 parent d036267 commit 8d6c5ca
Show file tree
Hide file tree
Showing 3 changed files with 226 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Makefile.in
Expand Up @@ -59,7 +59,7 @@ KAITAI_PARSERS = \
kaitai_parsers/dot11_ie_221_dji_droneid.cc.o

PSO = util.cc.o cygwin_utils.cc.o globalregistry.cc.o \
pollabletracker.cc.o ringbuf2.cc.o chainbuf.cc.o buffer_handler.cc.o \
pollabletracker.cc.o ringbuf2.cc.o chainbuf.cc.o filewritebuf.cc.o buffer_handler.cc.o \
packet.cc.o messagebus.cc.o configfile.cc.o getopt.cc.o filtercore.cc.o \
psutils.cc.o battery.cc.o kismet_json.cc.o \
tcpserver2.cc.o tcpclient2.cc.o serialclient2.cc.o pipeclient.cc.o ipc_remote2.cc.o \
Expand Down
136 changes: 136 additions & 0 deletions filewritebuf.cc
@@ -0,0 +1,136 @@
/*
This file is part of Kismet
Kismet 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.
Kismet 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 Kismet; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#include <stdio.h>

#include "util.h"
#include "filewritebuf.h"

FileWritebuf::FileWritebuf(std::string in_filename, size_t in_chunk) {
filename = in_filename;
chunk_sz = in_chunk;

reserve_chunk = NULL;
free_commit = false;

if ((backfile = fopen(in_filename.c_str(), "wb")) == NULL) {
throw std::runtime_error("Unable to open file " + in_filename + ":" +
kis_strerror_r(errno));
return;
}

reserve_chunk = new uint8_t[chunk_sz];
}

FileWritebuf::~FileWritebuf() {
local_eol_locker lock(&write_mutex);

if (backfile != NULL) {
fflush(backfile);
fclose(backfile);
backfile = NULL;
}

if (reserve_chunk != NULL)
delete[] reserve_chunk;

}

void FileWritebuf::clear() {
local_locker lock(&write_mutex);

if (backfile != NULL) {
if (ftruncate(fileno(backfile), 0) < 0) {
fflush(backfile);
fclose(backfile);
backfile = NULL;
}
}
}

size_t FileWritebuf::used() {
local_locker lock(&write_mutex);

if (backfile != NULL)
return (size_t) ftell(backfile);

return 0;
}

size_t FileWritebuf::total() {
local_locker lock(&write_mutex);

if (backfile != NULL)
return (size_t) ftell(backfile);

return 0;
}

ssize_t FileWritebuf::write(uint8_t *in_data, size_t in_sz) {
local_locker lock(&write_mutex);

if (backfile == NULL)
return -1;

return (ssize_t) fwrite(in_data, in_sz, 1, backfile);
}

ssize_t FileWritebuf::reserve(unsigned char **data, size_t in_sz) {
local_eol_locker lock(&write_mutex);

if (write_reserved) {
throw std::runtime_error("filebuf already reserved");
}

if (in_sz < chunk_sz) {
*data = reserve_chunk;
free_commit = false;
return in_sz;
}

*data = new unsigned char[in_sz];
free_commit = true;
return in_sz;

}

ssize_t FileWritebuf::zero_copy_reserve(unsigned char **data, size_t in_sz) {
return reserve(data, in_sz);
}

bool FileWritebuf::commit(unsigned char *data, size_t in_sz) {
local_unlocker unwritelock(&write_mutex);

if (!write_reserved)
throw std::runtime_error("filebuf no pending commit");

if (backfile == NULL)
throw std::runtime_error("filebuf could not open " + filename);

write_reserved = false;

size_t written = fwrite(data, in_sz, 1, backfile);

if (free_commit) {
free_commit = false;
delete[] data;
}

return written == in_sz;
}

89 changes: 89 additions & 0 deletions filewritebuf.h
@@ -0,0 +1,89 @@
/*
This file is part of Kismet
Kismet 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.
Kismet 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 Kismet; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#ifndef __FILEBUF_H__
#define __FILEBUF_H__

#include <stdint.h>
#include <unistd.h>
#include <pthread.h>
#include <mutex>
#include "buffer_handler.h"

// Direct file IO buffer for writing logs via the buffer API
//
// MAY THROW EXCEPTIONS on construction if the file cannot be opened

class FileWritebuf : public CommonBuffer {
public:
// Specify a file and a block size
FileWritebuf(std::string in_path, size_t chunk_sz);
virtual ~FileWritebuf();

virtual void clear();

virtual ssize_t size() {
return chunk_sz;
}

virtual ssize_t available() {
return chunk_sz;
}

virtual size_t used();

virtual size_t total();

// Write-only buffer, we don't allow peeking
virtual ssize_t peek(unsigned char **ret_data, size_t in_sz) {
return -1;
}

virtual ssize_t zero_copy_peek(unsigned char **ret_data, size_t in_sz) {
return -1;
}

virtual void peek_free(unsigned char *in_data) {
return;
}

// Write amount to buffer, arbitrarily allocating new chunks
virtual ssize_t write(unsigned char *in_data, size_t in_sz);

virtual ssize_t reserve(unsigned char **data, size_t in_sz);
virtual ssize_t zero_copy_reserve(unsigned char **data, size_t in_sz);
virtual bool commit(unsigned char *data, size_t in_sz);

// Consume from buffer
size_t consume(size_t in_sz) {
return 0;
}

protected:
size_t chunk_sz;
uint8_t *reserve_chunk;

bool free_commit;

std::string filename;

FILE *backfile;
};

#endif

0 comments on commit 8d6c5ca

Please sign in to comment.