core: Build offset queue + create output file

Signed-off-by: Ian Moffett <ian@mirocom.org>
This commit is contained in:
2026-02-09 18:29:33 -05:00
parent 2bbb15f4d1
commit b93394bef4

View File

@@ -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;
}
}