core: Build offset queue + create output file
Signed-off-by: Ian Moffett <ian@mirocom.org>
This commit is contained in:
106
src/main.c
106
src/main.c
@@ -1,7 +1,9 @@
|
||||
#define _DEFAULT_SOURCE
|
||||
#include <sys/queue.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
@@ -9,27 +11,66 @@
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAGIC_SIZE 5
|
||||
#define CAV_PASSES 3
|
||||
#define CAV_VERSION "0.0.1"
|
||||
|
||||
#define CAV_OFF_INDEX(INDEX) \
|
||||
((INDEX) * sizeof(struct cav_offset))
|
||||
|
||||
static const char *input_name = NULL;
|
||||
static const char *output_name = "out.cav";
|
||||
|
||||
/* Forward declarations */
|
||||
struct cav_offdesc;
|
||||
|
||||
/*
|
||||
* Represents the consume and vomit state machine
|
||||
*
|
||||
* @dir_fd: Input directory file descriptor
|
||||
* @out_fd: Output file descriptor
|
||||
* @dir: Opened directory
|
||||
* @pass_count: Number of passes made in file
|
||||
* @file_count: Number of files encountered including subdirectories
|
||||
* @cur_off: Current offset tracker
|
||||
* @offq: Offset queue
|
||||
*/
|
||||
struct cav_state {
|
||||
int dir_fd;
|
||||
int out_fd;
|
||||
DIR *dir;
|
||||
uint8_t pass_count;
|
||||
size_t file_count;
|
||||
uint32_t cur_off;
|
||||
TAILQ_HEAD(, cav_offdesc) offq;
|
||||
};
|
||||
|
||||
/*
|
||||
* Represents an entry in the offset table
|
||||
*
|
||||
* @magic: Must be "BLUGH"
|
||||
* @off: Placement offset
|
||||
* @size: File size in bytes
|
||||
* @link: Queue link [XXX: must be at the end]
|
||||
*/
|
||||
struct cav_offset {
|
||||
char magic[MAGIC_SIZE];
|
||||
uint32_t off;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
/*
|
||||
* Represents an offset descriptor used before holding
|
||||
* offset entries before it is entered into the file
|
||||
*
|
||||
* @path: Path of file
|
||||
* @off: Offset entry to push
|
||||
* @link: Queue link
|
||||
*/
|
||||
struct cav_offdesc {
|
||||
char *path;
|
||||
struct cav_offset off;
|
||||
TAILQ_ENTRY(cav_offdesc) link;
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -81,6 +122,26 @@ get_file_size(const char *path)
|
||||
return sb.st_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate an offset descriptor
|
||||
*/
|
||||
static struct cav_offdesc *
|
||||
offset_alloc(void)
|
||||
{
|
||||
struct cav_offdesc *off_desc;
|
||||
struct cav_offset *off;
|
||||
|
||||
off_desc = malloc(sizeof(*off_desc));
|
||||
if (off_desc == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(off_desc, 0, sizeof(*off_desc));
|
||||
off = &off_desc->off;
|
||||
memcpy(off->magic, "BLUGH", MAGIC_SIZE);
|
||||
return off_desc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the cav state machine
|
||||
*
|
||||
@@ -102,12 +163,20 @@ state_init(struct cav_state *state)
|
||||
return -1;
|
||||
}
|
||||
|
||||
state->dir = fdopendir(state->dir_fd);
|
||||
if (state->dir == NULL) {
|
||||
state->out_fd = open(output_name, O_WRONLY | O_CREAT, 0600);
|
||||
if (state->out_fd < 0) {
|
||||
close(state->dir_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
state->dir = fdopendir(state->dir_fd);
|
||||
if (state->dir == NULL) {
|
||||
close(state->dir_fd);
|
||||
close(state->out_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
TAILQ_INIT(&state->offq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -119,12 +188,23 @@ state_init(struct cav_state *state)
|
||||
static void
|
||||
state_destroy(struct cav_state *state)
|
||||
{
|
||||
struct cav_offdesc *off;
|
||||
|
||||
if (state == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
off = TAILQ_FIRST(&state->offq);
|
||||
while (off != NULL) {
|
||||
TAILQ_REMOVE(&state->offq, off, link);
|
||||
free(off->path);
|
||||
free(off);
|
||||
off = TAILQ_FIRST(&state->offq);
|
||||
}
|
||||
|
||||
closedir(state->dir);
|
||||
close(state->dir_fd);
|
||||
close(state->out_fd);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -134,6 +214,8 @@ state_destroy(struct cav_state *state)
|
||||
static void
|
||||
consume_scan(const char *dir_path, struct cav_state *state, DIR *subdir)
|
||||
{
|
||||
struct cav_offdesc *off_desc;
|
||||
struct cav_offset *off;
|
||||
struct dirent *dirent;
|
||||
char buf[256];
|
||||
DIR *dir;
|
||||
@@ -161,7 +243,20 @@ consume_scan(const char *dir_path, struct cav_state *state, DIR *subdir)
|
||||
closedir(subdir);
|
||||
break;
|
||||
default:
|
||||
if ((off_desc = offset_alloc()) == NULL) {
|
||||
printf("fatal: failed to allocate offset entry\n");
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/%s", dir_path, dirent->d_name);
|
||||
off_desc->path = strdup(buf);
|
||||
|
||||
/* Initialize the offset descriptor */
|
||||
off = &off_desc->off;
|
||||
off->size = get_file_size(buf);
|
||||
off->off = state->cur_off;
|
||||
TAILQ_INSERT_TAIL(&state->offq, off_desc, link);
|
||||
|
||||
++state->file_count;
|
||||
state->cur_off += get_file_size(buf);
|
||||
break;
|
||||
@@ -177,6 +272,8 @@ consume_scan(const char *dir_path, struct cav_state *state, DIR *subdir)
|
||||
static void
|
||||
consume_pass(struct cav_state *state)
|
||||
{
|
||||
struct cav_offdesc *off;
|
||||
|
||||
if (state == NULL) {
|
||||
return;
|
||||
}
|
||||
@@ -190,6 +287,11 @@ consume_pass(struct cav_state *state)
|
||||
state->file_count,
|
||||
state->cur_off
|
||||
);
|
||||
|
||||
TAILQ_FOREACH(off, &state->offq, link) {
|
||||
printf("[*] %s\n", off->path);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user