Compare commits
No commits in common. "37e0c3a98bd90d852674fea9baa2a892db4d9037" and "faa262ba95be60e47a072382749723583e6528c2" have entirely different histories.
37e0c3a98b
...
faa262ba95
7 changed files with 154 additions and 225 deletions
|
@ -13,7 +13,6 @@ set(c_simple_http_SOURCES
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/helpers.c"
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/helpers.c"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/html_cache.c"
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/html_cache.c"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/static.c"
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/static.c"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/generate.c"
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/SimpleArchiver/src/helpers.c"
|
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/SimpleArchiver/src/helpers.c"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/SimpleArchiver/src/data_structures/linked_list.c"
|
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/SimpleArchiver/src/data_structures/linked_list.c"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/SimpleArchiver/src/data_structures/hash_map.c"
|
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/SimpleArchiver/src/data_structures/hash_map.c"
|
||||||
|
|
4
Makefile
4
Makefile
|
@ -44,8 +44,7 @@ HEADERS = \
|
||||||
src/http_template.h \
|
src/http_template.h \
|
||||||
src/helpers.h \
|
src/helpers.h \
|
||||||
src/html_cache.h \
|
src/html_cache.h \
|
||||||
src/static.h \
|
src/static.h
|
||||||
src/generate.h
|
|
||||||
|
|
||||||
SOURCES = \
|
SOURCES = \
|
||||||
src/main.c \
|
src/main.c \
|
||||||
|
@ -60,7 +59,6 @@ SOURCES = \
|
||||||
src/helpers.c \
|
src/helpers.c \
|
||||||
src/html_cache.c \
|
src/html_cache.c \
|
||||||
src/static.c \
|
src/static.c \
|
||||||
src/generate.c \
|
|
||||||
third_party/SimpleArchiver/src/helpers.c \
|
third_party/SimpleArchiver/src/helpers.c \
|
||||||
third_party/SimpleArchiver/src/data_structures/linked_list.c \
|
third_party/SimpleArchiver/src/data_structures/linked_list.c \
|
||||||
third_party/SimpleArchiver/src/data_structures/hash_map.c \
|
third_party/SimpleArchiver/src/data_structures/hash_map.c \
|
||||||
|
|
|
@ -126,6 +126,7 @@ void internal_double_quote_decrement(uint_fast8_t *double_quote_count,
|
||||||
/// Returns non-zero if config should be returned.
|
/// Returns non-zero if config should be returned.
|
||||||
int internal_check_add_value(uint32_t *state,
|
int internal_check_add_value(uint32_t *state,
|
||||||
char **key_buf,
|
char **key_buf,
|
||||||
|
uint32_t *key_capacity,
|
||||||
uint32_t *key_idx,
|
uint32_t *key_idx,
|
||||||
char **value_buf,
|
char **value_buf,
|
||||||
uint32_t *value_capacity,
|
uint32_t *value_capacity,
|
||||||
|
@ -495,6 +496,7 @@ C_SIMPLE_HTTP_ParsedConfig c_simple_http_parse_config(
|
||||||
} else {
|
} else {
|
||||||
if (internal_check_add_value(&state,
|
if (internal_check_add_value(&state,
|
||||||
&key_buf,
|
&key_buf,
|
||||||
|
&key_capacity,
|
||||||
&key_idx,
|
&key_idx,
|
||||||
&value_buf,
|
&value_buf,
|
||||||
&value_capacity,
|
&value_capacity,
|
||||||
|
@ -518,6 +520,7 @@ C_SIMPLE_HTTP_ParsedConfig c_simple_http_parse_config(
|
||||||
|
|
||||||
if (internal_check_add_value(&state,
|
if (internal_check_add_value(&state,
|
||||||
&key_buf,
|
&key_buf,
|
||||||
|
&key_capacity,
|
||||||
&key_idx,
|
&key_idx,
|
||||||
&value_buf,
|
&value_buf,
|
||||||
&value_capacity,
|
&value_capacity,
|
||||||
|
|
175
src/generate.c
175
src/generate.c
|
@ -1,175 +0,0 @@
|
||||||
// ISC License
|
|
||||||
//
|
|
||||||
// Copyright (c) 2024 Stephen Seo
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||||
// copyright notice and this permission notice appear in all copies.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
||||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
||||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
||||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
||||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
// PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
#include "generate.h"
|
|
||||||
|
|
||||||
// Standard library includes.
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
// Linux/Unix includes.
|
|
||||||
#include <libgen.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
// Local includes.
|
|
||||||
#include "helpers.h"
|
|
||||||
#include "http_template.h"
|
|
||||||
|
|
||||||
// Third party includes.
|
|
||||||
#include <SimpleArchiver/src/helpers.h>
|
|
||||||
#include <SimpleArchiver/src/data_structures/hash_map.h>
|
|
||||||
#include <SimpleArchiver/src/data_structures/linked_list.h>
|
|
||||||
|
|
||||||
int c_simple_http_generate_paths_fn(const void *key,
|
|
||||||
size_t key_size,
|
|
||||||
__attribute__((unused)) const void *value,
|
|
||||||
void *ud) {
|
|
||||||
const char *path = key;
|
|
||||||
const ConnectionContext *ctx = ud;
|
|
||||||
const char *generate_dir = ctx->args->generate_dir;
|
|
||||||
|
|
||||||
const unsigned long path_len = key_size - 1;
|
|
||||||
const unsigned long generate_dir_len = strlen(generate_dir);
|
|
||||||
|
|
||||||
__attribute__((cleanup(simple_archiver_list_free)))
|
|
||||||
SDArchiverLinkedList *string_parts = simple_archiver_list_init();
|
|
||||||
|
|
||||||
// Add generate_dir as first path of paths to join.
|
|
||||||
c_simple_http_add_string_part(string_parts, generate_dir, 0);
|
|
||||||
|
|
||||||
// Ensure next character after generate_dir contains a '/' if generate_dir
|
|
||||||
// didn't contain one at the end.
|
|
||||||
if (generate_dir_len > 0 && generate_dir[generate_dir_len - 1] != '/') {
|
|
||||||
c_simple_http_add_string_part(string_parts, "/", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append the path.
|
|
||||||
if (strcmp(path, "/") != 0) {
|
|
||||||
// Is not root.
|
|
||||||
uint32_t idx = 0;
|
|
||||||
while (idx <= path_len && path[idx] == '/') {
|
|
||||||
++idx;
|
|
||||||
}
|
|
||||||
c_simple_http_add_string_part(string_parts, path + idx, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the final '/'.
|
|
||||||
if (path_len > 0 && path[path_len - 1] != '/') {
|
|
||||||
c_simple_http_add_string_part(string_parts, "/", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the ending "index.html".
|
|
||||||
c_simple_http_add_string_part(string_parts, "index.html", 0);
|
|
||||||
|
|
||||||
// Get the combined string.
|
|
||||||
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
|
|
||||||
char *generated_path = c_simple_http_combine_string_parts(string_parts);
|
|
||||||
if (!generated_path) {
|
|
||||||
fprintf(stderr, "ERROR Failed to get generated path (path: %s)!\n", path);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ctx->args->flags & 4) == 0) {
|
|
||||||
// Overwrite not enabled, check if file already exists.
|
|
||||||
FILE *fd = fopen(generated_path, "rb");
|
|
||||||
if (fd) {
|
|
||||||
fclose(fd);
|
|
||||||
fprintf(
|
|
||||||
stderr,
|
|
||||||
"WARNING Path \"%s\" exists and \"--generate-enable-overwrite\" not "
|
|
||||||
"specified, skipping!\n",
|
|
||||||
generated_path);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure the required dirs exist.
|
|
||||||
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
|
|
||||||
char *generated_path_dup = strdup(generated_path);
|
|
||||||
|
|
||||||
uint_fast8_t did_make_generated_path_dir = 0;
|
|
||||||
char *generated_path_dir = dirname(generated_path_dup);
|
|
||||||
if (generated_path_dir) {
|
|
||||||
DIR *fd = opendir(generated_path_dir);
|
|
||||||
if (!fd) {
|
|
||||||
if (errno == ENOENT) {
|
|
||||||
c_simple_http_helper_mkdir_tree(generated_path_dir);
|
|
||||||
did_make_generated_path_dir = 1;
|
|
||||||
} else {
|
|
||||||
fprintf(stderr,
|
|
||||||
"ERROR opendir on path dirname failed unexpectedly (path: %s)!"
|
|
||||||
"\n",
|
|
||||||
path);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Directory already exists.
|
|
||||||
closedir(fd);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fprintf(stderr,
|
|
||||||
"ERROR Failed to get dirname of generated path dir (path: %s)"
|
|
||||||
"!\n",
|
|
||||||
path);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate the html.
|
|
||||||
size_t html_buf_size = 0;
|
|
||||||
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
|
|
||||||
char *html_buf = c_simple_http_path_to_generated(path,
|
|
||||||
ctx->parsed,
|
|
||||||
&html_buf_size,
|
|
||||||
NULL);
|
|
||||||
if (!html_buf || html_buf_size == 0) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"WARNING Failed to generate html for generate (path: %s), "
|
|
||||||
"skipping!\n",
|
|
||||||
path);
|
|
||||||
if (did_make_generated_path_dir) {
|
|
||||||
if (rmdir(generated_path_dir) == -1) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"WARNING rmdir on generated_path_dir failed, errno: %d\n",
|
|
||||||
errno);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the html.
|
|
||||||
FILE *fd = fopen(generated_path, "wb");
|
|
||||||
if (!fd) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"WARNING Failed to open \"%s\" for writing, skipping!\n",
|
|
||||||
generated_path);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
unsigned long fwrite_ret = fwrite(html_buf, 1, html_buf_size, fd);
|
|
||||||
if (fwrite_ret < html_buf_size) {
|
|
||||||
fclose(fd);
|
|
||||||
unlink(generated_path);
|
|
||||||
fprintf(stderr,
|
|
||||||
"ERROR Unable to write entirely to \"%s\"!\n",
|
|
||||||
generated_path);
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
fclose(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
// ISC License
|
|
||||||
//
|
|
||||||
// Copyright (c) 2024 Stephen Seo
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||||
// copyright notice and this permission notice appear in all copies.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
||||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
||||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
||||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
||||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
// PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
#ifndef SEODISPARATE_COM_C_SIMPLE_HTTP_GENERATE_H_
|
|
||||||
#define SEODISPARATE_COM_C_SIMPLE_HTTP_GENERATE_H_
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/// See this function's usage in main.c.
|
|
||||||
int c_simple_http_generate_paths_fn(const void *key,
|
|
||||||
size_t key_size,
|
|
||||||
const void *value,
|
|
||||||
void *ud);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// vim: et ts=2 sts=2 sw=2
|
|
|
@ -21,23 +21,9 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
// libc includes.
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
// Local includes.
|
|
||||||
#include "config.h"
|
|
||||||
#include "arg_parse.h"
|
|
||||||
|
|
||||||
// Third-party includes.
|
// Third-party includes.
|
||||||
#include <SimpleArchiver/src/data_structures/linked_list.h>
|
#include <SimpleArchiver/src/data_structures/linked_list.h>
|
||||||
|
|
||||||
typedef struct ConnectionContext {
|
|
||||||
char *buf;
|
|
||||||
const Args *args;
|
|
||||||
C_SIMPLE_HTTP_ParsedConfig *parsed;
|
|
||||||
struct timespec current_time;
|
|
||||||
} ConnectionContext;
|
|
||||||
|
|
||||||
typedef struct C_SIMPLE_HTTP_String_Part {
|
typedef struct C_SIMPLE_HTTP_String_Part {
|
||||||
char *buf;
|
char *buf;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
152
src/main.c
152
src/main.c
|
@ -21,7 +21,10 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
// Linux/Unix includes.
|
// Linux/Unix includes.
|
||||||
|
#include <libgen.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <dirent.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
@ -43,7 +46,6 @@
|
||||||
#include "http_template.h"
|
#include "http_template.h"
|
||||||
#include "tcp_socket.h"
|
#include "tcp_socket.h"
|
||||||
#include "signal_handling.h"
|
#include "signal_handling.h"
|
||||||
#include "generate.h"
|
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
|
@ -78,6 +80,13 @@ typedef struct ConnectionItem {
|
||||||
struct in6_addr peer_addr;
|
struct in6_addr peer_addr;
|
||||||
} ConnectionItem;
|
} ConnectionItem;
|
||||||
|
|
||||||
|
typedef struct ConnectionContext {
|
||||||
|
char *buf;
|
||||||
|
const Args *args;
|
||||||
|
C_SIMPLE_HTTP_ParsedConfig *parsed;
|
||||||
|
struct timespec current_time;
|
||||||
|
} ConnectionContext;
|
||||||
|
|
||||||
void c_simple_http_cleanup_connection_item(void *data) {
|
void c_simple_http_cleanup_connection_item(void *data) {
|
||||||
ConnectionItem *citem = data;
|
ConnectionItem *citem = data;
|
||||||
if (citem) {
|
if (citem) {
|
||||||
|
@ -323,6 +332,145 @@ int c_simple_http_manage_connections(void *data, void *ud) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int generate_paths_fn(const void *key,
|
||||||
|
size_t key_size,
|
||||||
|
const void *value,
|
||||||
|
void *ud) {
|
||||||
|
const char *path = key;
|
||||||
|
const ConnectionContext *ctx = ud;
|
||||||
|
const char *generate_dir = ctx->args->generate_dir;
|
||||||
|
|
||||||
|
const unsigned long path_len = strlen(path);
|
||||||
|
const unsigned long generate_dir_len = strlen(generate_dir);
|
||||||
|
|
||||||
|
__attribute__((cleanup(simple_archiver_list_free)))
|
||||||
|
SDArchiverLinkedList *string_parts = simple_archiver_list_init();
|
||||||
|
|
||||||
|
// Add generate_dir as first path of paths to join.
|
||||||
|
c_simple_http_add_string_part(string_parts, generate_dir, 0);
|
||||||
|
|
||||||
|
// Ensure next character after generate_dir contains a '/' if generate_dir
|
||||||
|
// didn't contain one at the end.
|
||||||
|
if (generate_dir_len > 0 && generate_dir[generate_dir_len - 1] != '/') {
|
||||||
|
c_simple_http_add_string_part(string_parts, "/", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append the path.
|
||||||
|
if (strcmp(path, "/") != 0) {
|
||||||
|
// Is not root.
|
||||||
|
uint32_t idx = 0;
|
||||||
|
while (idx <= path_len && path[idx] == '/') {
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
c_simple_http_add_string_part(string_parts, path + idx, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the final '/'.
|
||||||
|
if (path_len > 0 && path[path_len - 1] != '/') {
|
||||||
|
c_simple_http_add_string_part(string_parts, "/", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the ending "index.html".
|
||||||
|
c_simple_http_add_string_part(string_parts, "index.html", 0);
|
||||||
|
|
||||||
|
// Get the combined string.
|
||||||
|
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
|
||||||
|
char *generated_path = c_simple_http_combine_string_parts(string_parts);
|
||||||
|
if (!generated_path) {
|
||||||
|
fprintf(stderr, "ERROR Failed to get generated path (path: %s)!\n", path);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ctx->args->flags & 4) == 0) {
|
||||||
|
// Overwrite not enabled, check if file already exists.
|
||||||
|
FILE *fd = fopen(generated_path, "rb");
|
||||||
|
if (fd) {
|
||||||
|
fclose(fd);
|
||||||
|
fprintf(
|
||||||
|
stderr,
|
||||||
|
"WARNING Path \"%s\" exists and \"--generate-enable-overwrite\" not "
|
||||||
|
"specified, skipping!\n",
|
||||||
|
generated_path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the required dirs exist.
|
||||||
|
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
|
||||||
|
char *generated_path_dup = strdup(generated_path);
|
||||||
|
|
||||||
|
uint_fast8_t did_make_generated_path_dir = 0;
|
||||||
|
char *generated_path_dir = dirname(generated_path_dup);
|
||||||
|
if (generated_path_dir) {
|
||||||
|
DIR *fd = opendir(generated_path_dir);
|
||||||
|
if (!fd) {
|
||||||
|
if (errno == ENOENT) {
|
||||||
|
c_simple_http_helper_mkdir_tree(generated_path_dir);
|
||||||
|
did_make_generated_path_dir = 1;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,
|
||||||
|
"ERROR opendir on path dirname failed unexpectedly (path: %s)!"
|
||||||
|
"\n",
|
||||||
|
path);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Directory already exists.
|
||||||
|
closedir(fd);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,
|
||||||
|
"ERROR Failed to get dirname of generated path dir (path: %s)"
|
||||||
|
"!\n",
|
||||||
|
path);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the html.
|
||||||
|
size_t html_buf_size = 0;
|
||||||
|
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
|
||||||
|
char *html_buf = c_simple_http_path_to_generated(path,
|
||||||
|
ctx->parsed,
|
||||||
|
&html_buf_size,
|
||||||
|
NULL);
|
||||||
|
if (!html_buf || html_buf_size == 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"WARNING Failed to generate html for generate (path: %s), "
|
||||||
|
"skipping!\n",
|
||||||
|
path);
|
||||||
|
if (did_make_generated_path_dir) {
|
||||||
|
if (rmdir(generated_path_dir) == -1) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"WARNING rmdir on generated_path_dir failed, errno: %d\n",
|
||||||
|
errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the html.
|
||||||
|
FILE *fd = fopen(generated_path, "wb");
|
||||||
|
if (!fd) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"WARNING Failed to open \"%s\" for writing, skipping!\n",
|
||||||
|
generated_path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
unsigned long fwrite_ret = fwrite(html_buf, 1, html_buf_size, fd);
|
||||||
|
if (fwrite_ret < html_buf_size) {
|
||||||
|
fclose(fd);
|
||||||
|
unlink(generated_path);
|
||||||
|
fprintf(stderr,
|
||||||
|
"ERROR Unable to write entirely to \"%s\"!\n",
|
||||||
|
generated_path);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
fclose(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
__attribute__((cleanup(c_simple_http_free_args)))
|
__attribute__((cleanup(c_simple_http_free_args)))
|
||||||
Args args = parse_args(argc, argv);
|
Args args = parse_args(argc, argv);
|
||||||
|
@ -352,7 +500,7 @@ int main(int argc, char **argv) {
|
||||||
ctx.args = &args;
|
ctx.args = &args;
|
||||||
ctx.parsed = &parsed_config;
|
ctx.parsed = &parsed_config;
|
||||||
if (simple_archiver_hash_map_iter(parsed_config.paths,
|
if (simple_archiver_hash_map_iter(parsed_config.paths,
|
||||||
c_simple_http_generate_paths_fn,
|
generate_paths_fn,
|
||||||
&ctx)) {
|
&ctx)) {
|
||||||
fprintf(stderr, "ERROR during generating!\n");
|
fprintf(stderr, "ERROR during generating!\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
|
Loading…
Reference in a new issue