summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/rdar.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/core/rdar.c b/core/rdar.c
index a5f3b48..2cd1e66 100644
--- a/core/rdar.c
+++ b/core/rdar.c
@@ -4,13 +4,27 @@
*/
#define _DEFAULT_SOURCE
+#include <sys/queue.h>
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
+#include <stdlib.h>
#include <dirent.h>
#include <string.h>
+/* Forward declarations */
+struct idata_desc;
+
+/* Data descriptor constants */
+#define RDAR_MAX_PATHLEN 32
+#define RDAR_MAGIC ">RDAR!"
+#define RDAR_MAGIC_LEN 6
+
+/* Data descriptor file flags */
+#define DATA_ROOT (1 << 0) /* Is root data descriptor */
+#define DATA_AVL (1 << 1) /* Available to consumer software; not touched by us */
+
/* Version conversion macros */
#define VERSION_U16(MAJOR, MINOR) \
(((MINOR) << 8) | (MAJOR))
@@ -19,6 +33,10 @@
#define VERSION_MINOR(VERSION) \
(((VERSION) >> 8) & 0xFF)
+/* Pushes idata descriptor to table */
+#define IDATA_PUSH(IDATA_P) \
+ TAILQ_INSERT_TAIL(&d_desc_table, (IDATA_P), link);
+
/*
* Software version
*
@@ -33,6 +51,36 @@
/* Globals */
static const char *input_dir = NULL;
static const char *output_path = NULL;
+static TAILQ_HEAD(, idata_desc) d_desc_table;
+
+/*
+ * A data descriptor holds information about a specific
+ * file along with an offset to which it is located at
+ * in the offset.
+ *
+ * @magic: Format magic
+ * @path: File path
+ * @off: File data offset
+ * @flags: File flags
+ */
+struct data_desc {
+ char magic[RDAR_MAGIC_LEN];
+ char path[RDAR_MAX_PATHLEN];
+ off_t off;
+ uint16_t flags;
+};
+
+/*
+ * Internal data descriptor, used to hold data
+ * before being flushed to the archive
+ *
+ * @data: Actual data descriptor
+ * @link: TAILQ link
+ */
+struct idata_desc {
+ struct data_desc data;
+ TAILQ_ENTRY(idata_desc) link;
+};
static void
help(void)
@@ -54,11 +102,84 @@ version(void)
printf("Version v%d.%d\n", Major, Minor);
}
+/*
+ * Allocate an internal data descriptor
+ *
+ * @path: Path of file
+ */
+static struct idata_desc *
+idata_from_file(const char *path)
+{
+ struct idata_desc *idata_desc;
+ struct data_desc *data_desc;
+ size_t path_len;
+
+ path_len = strlen(path);
+ if (path_len >= RDAR_MAX_PATHLEN - 1) {
+ printf("fatal: path '%s' is too long!\n", path);
+ return NULL;
+ }
+
+ idata_desc = malloc(sizeof(*idata_desc));
+ if (idata_desc == NULL) {
+ printf("fatal: failed to allocate idata_desc\n");
+ printf("* last file processed: %s\n", path);
+ return NULL;
+ }
+
+ /* Initialize the data descriptor */
+ data_desc = &idata_desc->data;
+ memcpy(data_desc->magic, RDAR_MAGIC, RDAR_MAGIC_LEN);
+ memcpy(data_desc->path, path, path_len);
+ data_desc->path[path_len] = '\0';
+ data_desc->flags = 0;
+ data_desc->off = 0;
+ return idata_desc;
+}
+
+/*
+ * Push the root descriptor to the table.
+ *
+ * The root descriptor is to contain an offset into a special
+ * %root% file entry which contains data (e.g., version, file count)
+ * encoded within.
+ */
+static int
+idata_push_root(void)
+{
+ struct idata_desc *root;
+
+ root = idata_from_file("%root%");
+ if (root == NULL) {
+ return -1;
+ }
+
+ IDATA_PUSH(root);
+ return 0;
+}
+
+static void
+idata_table_destroy(void)
+{
+ struct idata_desc *desc, *next;
+
+ printf("* dumping idata_table\n");
+ desc = TAILQ_FIRST(&d_desc_table);
+ while (desc != NULL) {
+ printf("-- %s\n", desc->data.path);
+
+ next = TAILQ_NEXT(desc, link);
+ TAILQ_REMOVE(&d_desc_table, desc, link);
+ desc = next;
+ }
+}
+
static void
recurse_dir(const char *dirpath)
{
DIR *dir;
struct dirent *dirent;
+ struct idata_desc *idata_desc;
char pathbuf[264];
dir = opendir(dirpath);
@@ -77,6 +198,14 @@ recurse_dir(const char *dirpath)
case DT_REG:
snprintf(pathbuf, sizeof(pathbuf), "%s/%s", dirpath, dirent->d_name);
printf("[f] %s\n", pathbuf);
+
+ idata_desc = idata_from_file(pathbuf);
+ if (idata_desc == NULL) {
+ printf("warn: ignoring '%s'\n", pathbuf);
+ break;
+ }
+
+ IDATA_PUSH(idata_desc);
break;
case DT_DIR:
snprintf(pathbuf, sizeof(pathbuf), "%s/%s", dirpath, dirent->d_name);
@@ -137,6 +266,9 @@ main(int argc, char **argv)
output_path = FALLBACK_OUTPUT_PATH;
}
+ TAILQ_INIT(&d_desc_table);
+ idata_push_root();
recurse_dir(input_dir);
+ idata_table_destroy();
return 0;
}