Impl. copying over "static-dir" files on generate
All checks were successful
Run Unit Tests / build-and-run-unit-tests (push) Successful in 34s

This commit is contained in:
Stephen Seo 2024-11-11 15:09:12 +09:00
parent 37e0c3a98b
commit 4784f83234
5 changed files with 194 additions and 2 deletions

View file

@ -24,7 +24,6 @@
// libc includes. // libc includes.
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <dirent.h>
#include <errno.h> #include <errno.h>
#include <libgen.h> #include <libgen.h>
@ -258,4 +257,11 @@ int c_simple_http_helper_mkdir_tree(const char *path) {
} }
} }
void c_simple_http_cleanup_DIR(DIR **fd) {
if (fd && *fd) {
closedir(*fd);
*fd = NULL;
}
}
// vim: et ts=2 sts=2 sw=2 // vim: et ts=2 sts=2 sw=2

View file

@ -23,6 +23,7 @@
// libc includes. // libc includes.
#include <time.h> #include <time.h>
#include <dirent.h>
// Local includes. // Local includes.
#include "config.h" #include "config.h"
@ -77,6 +78,8 @@ char *c_simple_http_helper_unescape_uri(const char *uri);
/// Other return values are errors. /// Other return values are errors.
int c_simple_http_helper_mkdir_tree(const char *dirpath); int c_simple_http_helper_mkdir_tree(const char *dirpath);
void c_simple_http_cleanup_DIR(DIR **fd);
#endif #endif
// vim: et ts=2 sts=2 sw=2 // vim: et ts=2 sts=2 sw=2

View file

@ -351,6 +351,7 @@ int main(int argc, char **argv) {
ConnectionContext ctx; ConnectionContext ctx;
ctx.args = &args; ctx.args = &args;
ctx.parsed = &parsed_config; ctx.parsed = &parsed_config;
printf("Generating html files to \"%s\"...\n", args.generate_dir);
if (simple_archiver_hash_map_iter(parsed_config.paths, if (simple_archiver_hash_map_iter(parsed_config.paths,
c_simple_http_generate_paths_fn, c_simple_http_generate_paths_fn,
&ctx)) { &ctx)) {
@ -358,6 +359,17 @@ int main(int argc, char **argv) {
return 1; return 1;
} }
puts("Finished generating."); puts("Finished generating.");
if (args.static_dir) {
puts("Static dir option specified, copying over static dir entries...");
if (c_simple_http_static_copy_over_dir(args.static_dir,
args.generate_dir,
(args.flags & 4) != 0 ? 1 : 0)
!= 0) {
fprintf(stderr, "ERROR during static-dir-entires copying!\n");
return 1;
}
puts("Finished copying over static-dir files.");
}
return 0; return 0;
} }

View file

@ -31,10 +31,17 @@
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <libgen.h>
// Third party includes. // Third party includes.
#include "SimpleArchiver/src/data_structures/linked_list.h"
#include "SimpleArchiver/src/helpers.h" #include "SimpleArchiver/src/helpers.h"
// Local includes.
#include "helpers.h"
char **environ; char **environ;
void internal_fd_cleanup_helper(int *fd) { void internal_fd_cleanup_helper(int *fd) {
@ -180,7 +187,9 @@ C_SIMPLE_HTTP_StaticFileInfo c_simple_http_get_file(
if (fd == NULL) { if (fd == NULL) {
fprintf( fprintf(
stderr, "WARNING Failed to open path \"%s\" in static dir!\n", path + idx); stderr,
"WARNING Failed to open path \"%s\" in static dir!\n",
path + idx);
file_info.result = STATIC_FILE_RESULT_404NotFound; file_info.result = STATIC_FILE_RESULT_404NotFound;
return file_info; return file_info;
} }
@ -331,4 +340,161 @@ int c_simple_http_static_validate_path(const char *path) {
return 0; return 0;
} }
int c_simple_http_static_copy_over_dir(const char *from,
const char *to,
uint_fast8_t overwrite_enabled) {
__attribute__((cleanup(c_simple_http_cleanup_DIR)))
DIR *from_fd = opendir(from);
if (!from_fd) {
fprintf(stderr, "ERROR Failed to open directory \"%s\"!\n", from);
return 1;
}
const unsigned long from_len = strlen(from);
const unsigned long to_len = strlen(to);
struct dirent *dir_entry = NULL;
do {
dir_entry = readdir(from_fd);
if (!dir_entry) {
break;
} else if (strcmp(dir_entry->d_name, ".") == 0
|| strcmp(dir_entry->d_name, "..") == 0) {
continue;
} else if (dir_entry->d_type == DT_DIR) {
// Dir entry is a directory.
__attribute__((cleanup(simple_archiver_list_free)))
SDArchiverLinkedList *string_parts = simple_archiver_list_init();
c_simple_http_add_string_part(string_parts, from, 0);
if (from_len > 0 && from[from_len - 1] != '/') {
c_simple_http_add_string_part(string_parts, "/", 0);
}
c_simple_http_add_string_part(string_parts, dir_entry->d_name, 0);
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
char *combined_from = c_simple_http_combine_string_parts(string_parts);
simple_archiver_list_free(&string_parts);
string_parts = simple_archiver_list_init();
c_simple_http_add_string_part(string_parts, to, 0);
if (to_len > 0 && to[to_len - 1] != '/') {
c_simple_http_add_string_part(string_parts, "/", 0);
}
c_simple_http_add_string_part(string_parts, dir_entry->d_name, 0);
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
char *combined_to = c_simple_http_combine_string_parts(string_parts);
int ret = c_simple_http_static_copy_over_dir(combined_from,
combined_to,
overwrite_enabled);
if (ret != 0) {
return ret;
}
} else if (dir_entry->d_type == DT_REG) {
// Dir entry is a file.
__attribute__((cleanup(simple_archiver_list_free)))
SDArchiverLinkedList *string_parts = simple_archiver_list_init();
c_simple_http_add_string_part(string_parts, from, 0);
if (from_len > 0 && from[from_len - 1] != '/') {
c_simple_http_add_string_part(string_parts, "/", 0);
}
c_simple_http_add_string_part(string_parts, dir_entry->d_name, 0);
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
char *combined_from = c_simple_http_combine_string_parts(string_parts);
simple_archiver_list_free(&string_parts);
string_parts = simple_archiver_list_init();
c_simple_http_add_string_part(string_parts, to, 0);
if (to_len > 0 && to[to_len - 1] != '/') {
c_simple_http_add_string_part(string_parts, "/", 0);
}
c_simple_http_add_string_part(string_parts, dir_entry->d_name, 0);
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
char *combined_to = c_simple_http_combine_string_parts(string_parts);
if (!overwrite_enabled) {
__attribute__((cleanup(simple_archiver_helper_cleanup_FILE)))
FILE *fd = fopen(combined_to, "rb");
if (fd) {
fprintf(
stderr,
"WARNING \"%s\" already exists and --generate-enable-overwrite not "
"specified, skipping!\n",
combined_to);
continue;
}
}
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
char *combined_to_dup = strdup(combined_to);
char *combined_to_dirname = dirname(combined_to_dup);
int ret = c_simple_http_helper_mkdir_tree(combined_to_dirname);
if (ret != 0 && ret != 1) {
fprintf(stderr,
"ERROR Failed to create directory \"%s\"!\n",
combined_to_dirname);
return 1;
}
__attribute__((cleanup(simple_archiver_helper_cleanup_FILE)))
FILE *from_file_fd = fopen(combined_from, "rb");
if (!from_file_fd) {
fprintf(stderr,
"ERROR Failed to open file \"%s\" for reading!\n",
combined_from);
return 1;
}
__attribute__((cleanup(simple_archiver_helper_cleanup_FILE)))
FILE *to_file_fd = fopen(combined_to, "wb");
if (!to_file_fd) {
fprintf(stderr,
"ERROR Failed to open file \"%s\" for writing!\n",
combined_to);
return 1;
}
char *buf[1024];
size_t fread_ret;
unsigned long fwrite_ret;
while (!feof(from_file_fd)
&& !ferror(from_file_fd)
&& !ferror(to_file_fd)) {
fread_ret = fread(buf, 1, 1024, from_file_fd);
if (fread_ret > 0) {
fwrite_ret = fwrite(buf, 1, fread_ret, to_file_fd);
if (fwrite_ret < fread_ret) {
fprintf(
stderr,
"ERROR Writing to file \"%s\" (not all bytes written)!\n",
combined_to);
return 1;
}
}
}
if (ferror(from_file_fd)) {
fprintf(stderr, "ERROR Reading from file \"%s\"!\n", combined_from);
return 1;
} else if (ferror(to_file_fd)) {
fprintf(stderr, "ERROR Writing to file \"%s\"!\n", combined_to);
return 1;
}
printf("%s -> %s\n", combined_from, combined_to);
} else {
fprintf(stderr,
"WARNING Non-dir and non-file \"%s/%s\", skipping...\n",
from,
dir_entry->d_name);
}
} while (dir_entry != NULL);
return 0;
}
// vim: et ts=2 sts=2 sw=2 // vim: et ts=2 sts=2 sw=2

View file

@ -51,6 +51,11 @@ C_SIMPLE_HTTP_StaticFileInfo c_simple_http_get_file(
/// Returns zero if OK. /// Returns zero if OK.
int c_simple_http_static_validate_path(const char *path); int c_simple_http_static_validate_path(const char *path);
/// Copies all files in "from" into "to". Returns non-zero on failure.
int c_simple_http_static_copy_over_dir(const char *from,
const char *to,
uint_fast8_t overwrite_enabled);
#endif #endif
// vim: et ts=2 sts=2 sw=2 // vim: et ts=2 sts=2 sw=2