Impl. copying over "static-dir" files on generate
All checks were successful
Run Unit Tests / build-and-run-unit-tests (push) Successful in 34s
All checks were successful
Run Unit Tests / build-and-run-unit-tests (push) Successful in 34s
This commit is contained in:
parent
37e0c3a98b
commit
4784f83234
5 changed files with 194 additions and 2 deletions
|
@ -24,7 +24,6 @@
|
|||
// libc includes.
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.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
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
// libc includes.
|
||||
#include <time.h>
|
||||
#include <dirent.h>
|
||||
|
||||
// Local includes.
|
||||
#include "config.h"
|
||||
|
@ -77,6 +78,8 @@ char *c_simple_http_helper_unescape_uri(const char *uri);
|
|||
/// Other return values are errors.
|
||||
int c_simple_http_helper_mkdir_tree(const char *dirpath);
|
||||
|
||||
void c_simple_http_cleanup_DIR(DIR **fd);
|
||||
|
||||
#endif
|
||||
|
||||
// vim: et ts=2 sts=2 sw=2
|
||||
|
|
12
src/main.c
12
src/main.c
|
@ -351,6 +351,7 @@ int main(int argc, char **argv) {
|
|||
ConnectionContext ctx;
|
||||
ctx.args = &args;
|
||||
ctx.parsed = &parsed_config;
|
||||
printf("Generating html files to \"%s\"...\n", args.generate_dir);
|
||||
if (simple_archiver_hash_map_iter(parsed_config.paths,
|
||||
c_simple_http_generate_paths_fn,
|
||||
&ctx)) {
|
||||
|
@ -358,6 +359,17 @@ int main(int argc, char **argv) {
|
|||
return 1;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
168
src/static.c
168
src/static.c
|
@ -31,10 +31,17 @@
|
|||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <libgen.h>
|
||||
|
||||
// Third party includes.
|
||||
#include "SimpleArchiver/src/data_structures/linked_list.h"
|
||||
#include "SimpleArchiver/src/helpers.h"
|
||||
|
||||
// Local includes.
|
||||
#include "helpers.h"
|
||||
|
||||
char **environ;
|
||||
|
||||
void internal_fd_cleanup_helper(int *fd) {
|
||||
|
@ -180,7 +187,9 @@ C_SIMPLE_HTTP_StaticFileInfo c_simple_http_get_file(
|
|||
|
||||
if (fd == NULL) {
|
||||
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;
|
||||
return file_info;
|
||||
}
|
||||
|
@ -331,4 +340,161 @@ int c_simple_http_static_validate_path(const char *path) {
|
|||
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
|
||||
|
|
|
@ -51,6 +51,11 @@ C_SIMPLE_HTTP_StaticFileInfo c_simple_http_get_file(
|
|||
/// Returns zero if OK.
|
||||
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
|
||||
|
||||
// vim: et ts=2 sts=2 sw=2
|
||||
|
|
Loading…
Reference in a new issue