#include <u.h>
#include <libc.h>
#include <String.h>
#include <bio.h>
#include "common.h"
#include "debug.h"
#include "string.h"
#include "collection.h"
#include "function.h"
#include "array.h"
#include "set.h"
#include "file.h"
#include "filepath.h"
#include "holemanager.h"
enum
{
DEBUG_HOLEMANAGER = false,
HOLEMANAGER_DUMPFILE_PERM = 0755L
};
struct HoleManager
{
Set *holes;
char *holefile;
bool isdirty;
};
static collection_do_ret holemanager_dump_holes_each(void *p, void *arg)
{
int result;
char *filename = (char *)p;
Biobuf *biohole = (Biobuf *)arg;
assert_valid(filename);
assert(strlen(filename) > 0);
assert_valid(biohole);
result = Bprint(biohole, "%s\n", filename);
if(result == Beof)
{
WARNING(DEBUG_HOLEMANAGER,
"holemanager_dump_holes_each failed to write to file");
}
// NOISE(DEBUG_HOLEMANAGER, "holemanager_dump_holes_each dumping %s", filename);
return COLLECTION_DO_CONTINUE;
}
static void holemanager_dump_holes(HoleManager *self)
{
int result;
Biobuf *biohole;
assert_valid(self);
biohole = Bopen(self->holefile, OWRITE);
if(biohole == nil)
{
WARNING(DEBUG_HOLEMANAGER,
"holemanager_dump_holes unable to open dump file");
return;
}
set_do(self->holes, holemanager_dump_holes_each, biohole);
result = Bterm(biohole);
NOISE(DEBUG_HOLEMANAGER, "holemanager_dump_holes total: %ud Bterm returns %d",
set_size(self->holes), result);
NOISE(DEBUG_HOLEMANAGER, "holemanager_dump_holes unsetting dirty bit");
self->isdirty = false;
}
static void holemanager_read_holes(HoleManager *self)
{
int result;
int fd;
char *filename;
Biobuf biohole;
assert_valid(self);
fd = file_open(self->holefile, OREAD);
if(!fd_isopen(fd))
{
NOISE(DEBUG_HOLEMANAGER,
"holemanager_read_holes unable to open hole file %s for reading",
self->holefile);
return;
}
result = Binit(&biohole, fd, OREAD);
NOISE(DEBUG_HOLEMANAGER, "holemanager_read_holes Binit returns %s", result);
while((filename = Brdstr(&biohole, '\n', 1)) != nil)
{
NOISE(DEBUG_HOLEMANAGER,
"holemanager_read_holes reading filename: %s len: %d",
filename, strlen(filename));
set_add(self->holes, filename);
}
result = Bterm(&biohole);
file_close(fd);
NOISE(DEBUG_HOLEMANAGER, "holemanager_dump_holes Bterm returns %d", result);
self->isdirty = false;
}
HoleManager *holemanager_new(char *holefile)
{
HoleManager *result = (HoleManager *)emalloc_fs(sizeof(*result));
result->holes = set_new(string_isequal, string_hash);
result->isdirty = false;
if(holefile != nil)
{
result->holefile = filepath_make_absolute_cstr(holefile);
holemanager_read_holes(result);
}
else
{
result->holefile = estrdup_fs("/tmp/holes");
}
NOISE(DEBUG_HOLEMANAGER, "holemanager_new holefile: %s", result->holefile);
return result;
}
void holemanager_free(HoleManager *self)
{
if(self == nil)
{
return;
}
free(self->holefile);
set_free_with(self->holes, free);
free(self);
}
void holemanager_add(HoleManager *self, char *holepath)
{
assert_valid(self);
assert_valid(holepath);
NOISE(DEBUG_HOLEMANAGER, "holemanager_add adding hole: %s", holepath);
set_add(self->holes, estrdup_fs(holepath));
NOISE(DEBUG_HOLEMANAGER, "holemanager_add setting dirty bit");
self->isdirty = true;
holemanager_dump_holes(self);
}
bool holemanager_includes(HoleManager *self, char *holepath)
{
bool result;
assert_valid(self);
assert_valid(holepath);
result = set_includes(self->holes, holepath);
NOISE(DEBUG_HOLEMANAGER, "holemanager_includes path: %s result: %d",
holepath, result);
return result;
}
void holemanager_remove(HoleManager *self, char *holepath)
{
bool result;
assert_valid(self);
assert_valid(holepath);
result = set_remove(self->holes, holepath);
NOISE(DEBUG_HOLEMANAGER,
"holemanager_remove removing: %s with result: %d", holepath, result);
self->isdirty = true;
NOISE(DEBUG_HOLEMANAGER, "holemanager_add setting dirty bit");
holemanager_dump_holes(self);
}
|