core: Generate output source file
This commit reduces the amount of passes required to 2 as well as generating the actual output file. Signed-off-by: Ian Moffett <ian@mirocom.org>
This commit is contained in:
98
src/main.c
98
src/main.c
@@ -1,4 +1,5 @@
|
||||
#define _DEFAULT_SOURCE
|
||||
#include <sys/mman.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
@@ -12,7 +13,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#define MAGIC_SIZE 5
|
||||
#define CAV_PASSES 3
|
||||
#define CAV_PASSES 2
|
||||
#define CAV_VERSION "0.0.1"
|
||||
|
||||
#define CAV_OFF_INDEX(INDEX) \
|
||||
@@ -57,7 +58,7 @@ struct cav_offset {
|
||||
char magic[MAGIC_SIZE];
|
||||
uint32_t off;
|
||||
size_t size;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* Represents an offset descriptor used before holding
|
||||
@@ -163,7 +164,7 @@ state_init(struct cav_state *state)
|
||||
return -1;
|
||||
}
|
||||
|
||||
state->out_fd = open(output_name, O_WRONLY | O_CREAT, 0600);
|
||||
state->out_fd = open(output_name, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
if (state->out_fd < 0) {
|
||||
close(state->dir_fd);
|
||||
return -1;
|
||||
@@ -264,6 +265,79 @@ consume_scan(const char *dir_path, struct cav_state *state, DIR *subdir)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* File a file segment within the archive
|
||||
*
|
||||
* @state: Cav state
|
||||
* @desc: Offset descriptor
|
||||
*/
|
||||
static void
|
||||
fill_segment(struct cav_state *state, struct cav_offdesc *desc)
|
||||
{
|
||||
struct cav_offset *off;
|
||||
void *mem;
|
||||
int fd;
|
||||
|
||||
if (state == NULL || desc == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
off = &desc->off;
|
||||
fd = open(desc->path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
perror("open");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Map the file */
|
||||
mem = mmap(
|
||||
NULL,
|
||||
off->size,
|
||||
PROT_READ,
|
||||
MAP_SHARED,
|
||||
fd,
|
||||
0
|
||||
);
|
||||
|
||||
/* File name goes before file contents */
|
||||
write(state->out_fd, desc->path, strlen(desc->path) + 1);
|
||||
write(state->out_fd, mem, off->size);
|
||||
|
||||
/* Clean up */
|
||||
munmap(mem, off->size);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct the on-disk offset table
|
||||
*
|
||||
* @state: Cav state
|
||||
*/
|
||||
static void
|
||||
build_offtab(struct cav_state *state)
|
||||
{
|
||||
struct cav_offdesc *off_desc;
|
||||
struct cav_offset *off;
|
||||
|
||||
if (state == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* First, write out the offset table */
|
||||
TAILQ_FOREACH(off_desc, &state->offq, link) {
|
||||
off = &off_desc->off;
|
||||
off->off = state->cur_off;
|
||||
|
||||
state->cur_off += off->size;
|
||||
write(state->out_fd, off, sizeof(*off));
|
||||
}
|
||||
|
||||
/* Next, write out the segments */
|
||||
TAILQ_FOREACH(off_desc, &state->offq, link) {
|
||||
fill_segment(state, off_desc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Consume a single pass in our yummy yummy consumption
|
||||
* process only to be thrown up again along with stomach
|
||||
@@ -272,8 +346,6 @@ 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;
|
||||
}
|
||||
@@ -287,11 +359,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;
|
||||
case 1:
|
||||
printf("[pass 1] building offset table + segments...\n");
|
||||
state->cur_off = CAV_OFF_INDEX(state->file_count);
|
||||
build_offtab(state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -333,9 +405,9 @@ main(int argc, char **argv)
|
||||
/*
|
||||
* There are three passes required in the consumption operation
|
||||
*
|
||||
* pass 0): Obtain number of files for offset table creation
|
||||
* pass 1): Construct an offset table using what we know
|
||||
* pass 2): Construct the archive segments
|
||||
* pass 0): Obtain number of files for offset table creation.
|
||||
* pass 1): Construct an offset table using what we know and
|
||||
* populate file entries.
|
||||
*/
|
||||
for (int i = 0; i < CAV_PASSES; ++i) {
|
||||
consume_pass(&state);
|
||||
|
||||
Reference in New Issue
Block a user