Files
blobchain/core/blobchain.c
T
2026-04-30 19:28:31 -04:00

128 lines
2.4 KiB
C

/*
* Copyright (c) 2026, Chloe M.
* Provided under the BSD-3 clause
*/
#define _DEFAULT_SOURCE
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include "blobchain/common.h"
#include "blobchain/stream.h"
/* Input directory path */
static char *input_dir = NULL;
static void
help(void)
{
printf("usage: ./blobchain <flags>\n");
printf("... [-h] Display this help menu\n");
printf("... [-v] Display the version\n");
printf("... [-i] Input directory\n");
}
static void
version(void)
{
printf("Version v%s\n", BLOBCHAIN_VERSION);
}
static void
pack_foreach(const char *input_dir)
{
char pathbuf[512];
struct dirent *dirent;
DIR *dir;
if (input_dir == NULL) {
return;
}
if ((dir = opendir(input_dir)) == NULL) {
perror("opendir");
return;
}
while ((dirent = readdir(dir)) != NULL) {
if (dirent->d_name[0] == '.') {
continue;
}
switch (dirent->d_type) {
case DT_DIR:
snprintf(pathbuf, sizeof(pathbuf), "%s/%s", input_dir, dirent->d_name);
pack_foreach(pathbuf);
printf("[d] %s\n", pathbuf);
break;
case DT_REG:
snprintf(pathbuf, sizeof(pathbuf), "%s/%s", input_dir, dirent->d_name);
printf("[r] %s\n", pathbuf);
break;
}
}
}
static void
pack_dir(void)
{
struct stat sb;
if (stat(input_dir, &sb) < 0) {
perror("stat");
return;
}
/* Must be a directory */
if (!S_ISDIR(sb.st_mode)) {
printf("fatal: given path is not a directory!\n");
return;
}
pack_foreach(input_dir);
}
int
main(int argc, char **argv)
{
int opt;
if (argc < 2) {
printf("fatal: too few arguments!\n");
help();
return -1;
}
while ((opt = getopt(argc, argv, "hvi:")) != -1) {
switch (opt) {
case 'h':
help();
return -1;
case 'v':
version();
return -1;
case 'i':
input_dir = strdup(optarg);
if (input_dir == NULL) {
printf("fatal: out of memory\n");
return -1;
}
break;
}
}
if (input_dir == NULL) {
printf("fatal: expected input directory\n");
help();
return -1;
}
pack_dir();
free(input_dir);
return 0;
}