Compare commits
2 Commits
01468670e3
...
4e08375748
Author | SHA1 | Date | |
---|---|---|---|
4e08375748 | |||
912bf616b6 |
@ -81,7 +81,7 @@ BreakBeforeTernaryOperators: true
|
|||||||
BreakConstructorInitializers: BeforeColon
|
BreakConstructorInitializers: BeforeColon
|
||||||
BreakInheritanceList: BeforeColon
|
BreakInheritanceList: BeforeColon
|
||||||
BreakStringLiterals: true
|
BreakStringLiterals: true
|
||||||
ColumnLimit: 120
|
ColumnLimit: 80
|
||||||
CommentPragmas: '^ IWYU pragma:'
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
CompactNamespaces: false
|
CompactNamespaces: false
|
||||||
ConstructorInitializerIndentWidth: 4
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
35
doc/.clang-tidy
Normal file
35
doc/.clang-tidy
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
---
|
||||||
|
# "gnu-zero-variadic-macro-arguments" ignored because we are using GNU99
|
||||||
|
# standart
|
||||||
|
|
||||||
|
# "clang-diagnostic-language-extension-token" is ignored because we need the
|
||||||
|
# asm() extension token
|
||||||
|
|
||||||
|
# "DeprecatedOrUnsafeBufferHandling" ignored because C11 "_s" functions are not
|
||||||
|
# secure either
|
||||||
|
Checks: >-
|
||||||
|
clang-diagnostic-*,
|
||||||
|
-clang-diagnostic-gnu-zero-variadic-macro-arguments,
|
||||||
|
-clang-diagnostic-language-extension-token,
|
||||||
|
clang-analyzer-*,
|
||||||
|
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
|
||||||
|
portability-*,
|
||||||
|
performance-*,
|
||||||
|
WarningsAsErrors: '*'
|
||||||
|
HeaderFileExtensions:
|
||||||
|
- ''
|
||||||
|
- h
|
||||||
|
- hh
|
||||||
|
- hpp
|
||||||
|
- hxx
|
||||||
|
ImplementationFileExtensions:
|
||||||
|
- c
|
||||||
|
- cc
|
||||||
|
- cpp
|
||||||
|
- cxx
|
||||||
|
HeaderFilterRegex: '.*'
|
||||||
|
ExcludeHeaderFilterRegex: ''
|
||||||
|
FormatStyle: file
|
||||||
|
SystemHeaders: false
|
||||||
|
...
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
FROM ghcr.io/ngn13/ctorm:1.7
|
FROM ghcr.io/ngn13/ctorm:1.8.1
|
||||||
|
|
||||||
WORKDIR /doc
|
WORKDIR /doc
|
||||||
|
|
||||||
|
@ -26,10 +26,13 @@ $(DISTDIR)/%.o: src/%.c
|
|||||||
format:
|
format:
|
||||||
clang-format -i -style=file $(CSRCS) $(HSRCS)
|
clang-format -i -style=file $(CSRCS) $(HSRCS)
|
||||||
|
|
||||||
|
lint:
|
||||||
|
clang-tidy --warnings-as-errors --config= $(CSRCS) $(HSRCS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(DISTDIR)
|
rm -rf $(DISTDIR)
|
||||||
|
|
||||||
run:
|
run:
|
||||||
./doc.elf
|
./doc.elf
|
||||||
|
|
||||||
.PHONY: format clean run
|
.PHONY: format lint clean run
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"title": "privacy",
|
|
||||||
"desc": "Learn how I respect your privacy"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"title": "gizlilik",
|
|
||||||
"desc": "Gizliliğinize nasıl önem verdiğimi öğrenin"
|
|
||||||
}
|
|
@ -3,13 +3,13 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "file.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
util_file_t *file;
|
file_t *file;
|
||||||
char name[NAME_MAX + 1];
|
char name[NAME_MAX + 1];
|
||||||
char *lang;
|
char *lang;
|
||||||
} docs_t;
|
} docs_t;
|
||||||
|
|
||||||
bool docs_init(docs_t *docs, char *dir);
|
bool docs_init(docs_t *docs, char *dir);
|
||||||
|
10
doc/inc/file.h
Normal file
10
doc/inc/file.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *content;
|
||||||
|
int64_t size;
|
||||||
|
} file_t;
|
||||||
|
|
||||||
|
file_t *file_load(int dirfd, char *path);
|
||||||
|
void file_free(file_t *file);
|
@ -4,16 +4,8 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
typedef struct {
|
#define util_toupper(str) \
|
||||||
char *content;
|
for (char *c = str; *c != 0; c++) \
|
||||||
uint64_t size;
|
|
||||||
} util_file_t;
|
|
||||||
|
|
||||||
#define util_toupper(str) \
|
|
||||||
for (char *c = str; *c != 0; c++) \
|
|
||||||
*c = toupper(*c)
|
*c = toupper(*c)
|
||||||
uint64_t util_endswith(char *str, char *suf);
|
uint64_t util_endswith(char *str, char *suf);
|
||||||
void util_send(ctorm_res_t *res, uint16_t code, cJSON *json);
|
void util_send(ctorm_res_t *res, uint16_t code, cJSON *json);
|
||||||
util_file_t *util_file_load(int dirfd, char *path);
|
|
||||||
void util_file_free(util_file_t *file);
|
|
||||||
bool util_parse_doc_name(char *name, char **lang, const char *ext);
|
|
||||||
|
4
doc/pages/privacy.en.json
Normal file
4
doc/pages/privacy.en.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"title": "privacy",
|
||||||
|
"desc": "Privacy policy"
|
||||||
|
}
|
4
doc/pages/privacy.tr.json
Normal file
4
doc/pages/privacy.tr.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"title": "gizlilik",
|
||||||
|
"desc": "Gizlilik ilkesi"
|
||||||
|
}
|
@ -11,22 +11,25 @@
|
|||||||
|
|
||||||
option_t options[] = {
|
option_t options[] = {
|
||||||
// name value requied
|
// name value requied
|
||||||
{"host", "0.0.0.0:7003", true }, // host the server should listen on
|
{"host", "0.0.0.0:7003", true }, // host the server should listen on
|
||||||
{"docs_dir", "./docs", true }, // documentation directory
|
{"dir", "./pages", true }, // documentation pages directory
|
||||||
{"", NULL, false},
|
{"", NULL, false},
|
||||||
};
|
};
|
||||||
|
|
||||||
bool config_load(config_t *conf) {
|
bool config_load(config_t *conf) {
|
||||||
bzero(conf, sizeof(*conf));
|
memset(conf, 0, sizeof(*conf));
|
||||||
|
|
||||||
char name_env[OPT_NAME_MAX + 10], name_copy[OPT_NAME_MAX], *value = NULL;
|
char name_env[OPT_NAME_MAX + 10], name_copy[OPT_NAME_MAX], *value = NULL;
|
||||||
conf->options = options;
|
conf->options = options;
|
||||||
|
|
||||||
for (option_t *opt = conf->options; opt->value != NULL; opt++, conf->count++) {
|
for (option_t *opt = conf->options; opt->value != NULL;
|
||||||
strcpy(name_copy, opt->name);
|
opt++, conf->count++) {
|
||||||
|
// convert option name to environment variable name
|
||||||
|
strncpy(name_copy, opt->name, OPT_NAME_MAX);
|
||||||
util_toupper(name_copy);
|
util_toupper(name_copy);
|
||||||
snprintf(name_env, sizeof(name_env), "WEBSITE_%s", name_copy);
|
snprintf(name_env, sizeof(name_env), "WEBSITE_%s", name_copy);
|
||||||
|
|
||||||
|
// attempt to load the value from the environment
|
||||||
if ((value = getenv(name_env)) != NULL)
|
if ((value = getenv(name_env)) != NULL)
|
||||||
opt->value = value;
|
opt->value = value;
|
||||||
|
|
||||||
@ -36,7 +39,9 @@ bool config_load(config_t *conf) {
|
|||||||
if (!opt->required || NULL != opt->value)
|
if (!opt->required || NULL != opt->value)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ctorm_fail("please specify a value for the required config option: %s (%s)", opt->name, name_env);
|
ctorm_fail("please specify a value for the required config option: %s (%s)",
|
||||||
|
opt->name,
|
||||||
|
name_env);
|
||||||
errno = EFAULT;
|
errno = EFAULT;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <linux/limits.h>
|
#include <linux/limits.h>
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#define DOCS_LANG_CODE_LEN 2
|
#define DOCS_LANG_CODE_LEN 2
|
||||||
|
|
||||||
bool __docs_parse_name(docs_t *docs, char *ext) {
|
bool _docs_parse_name(docs_t *docs, char *ext) {
|
||||||
// check the extension
|
// check the extension
|
||||||
uint64_t ext_pos = util_endswith(docs->name, ext);
|
uint64_t ext_pos = util_endswith(docs->name, ext);
|
||||||
|
|
||||||
@ -22,7 +22,8 @@ bool __docs_parse_name(docs_t *docs, char *ext) {
|
|||||||
// example.en\0json\0
|
// example.en\0json\0
|
||||||
// |
|
// |
|
||||||
// `--- find this
|
// `--- find this
|
||||||
for (docs->lang = docs->name; *docs->lang != 0 && *docs->lang != '.'; docs->lang++)
|
for (docs->lang = docs->name; *docs->lang != 0 && *docs->lang != '.';
|
||||||
|
docs->lang++)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (*docs->lang != '.')
|
if (*docs->lang != '.')
|
||||||
@ -39,11 +40,11 @@ bool __docs_parse_name(docs_t *docs, char *ext) {
|
|||||||
return strlen(docs->lang) == DOCS_LANG_CODE_LEN && *docs->name != 0;
|
return strlen(docs->lang) == DOCS_LANG_CODE_LEN && *docs->name != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __docs_clean(docs_t *docs) {
|
void _docs_clean(docs_t *docs) {
|
||||||
if (NULL == docs->file)
|
if (NULL == docs->file)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
util_file_free(docs->file);
|
file_free(docs->file);
|
||||||
docs->file = NULL;
|
docs->file = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +54,7 @@ bool docs_init(docs_t *docs, char *dir) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bzero(docs, sizeof(*docs));
|
memset(docs, 0, sizeof(*docs));
|
||||||
return NULL != (docs->dir = opendir(dir));
|
return NULL != (docs->dir = opendir(dir));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,15 +65,15 @@ char *docs_next(docs_t *docs, char *name, bool content) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct dirent *ent = NULL;
|
struct dirent *ent = NULL;
|
||||||
__docs_clean(docs);
|
_docs_clean(docs);
|
||||||
|
|
||||||
while (NULL != (ent = readdir(docs->dir))) {
|
while (NULL != (ent = readdir(docs->dir))) {
|
||||||
if (*ent->d_name == '.')
|
if (*ent->d_name == '.')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
strcpy(docs->name, ent->d_name);
|
strncpy(docs->name, ent->d_name, NAME_MAX);
|
||||||
|
|
||||||
if (!__docs_parse_name(docs, content ? ".md" : ".json"))
|
if (!_docs_parse_name(docs, content ? ".md" : ".json"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (NULL == name || strncmp(docs->name, name, NAME_MAX) == 0)
|
if (NULL == name || strncmp(docs->name, name, NAME_MAX) == 0)
|
||||||
@ -84,7 +85,7 @@ char *docs_next(docs_t *docs, char *name, bool content) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL == (docs->file = util_file_load(dirfd(docs->dir), ent->d_name)))
|
if (NULL == (docs->file = file_load(dirfd(docs->dir), ent->d_name)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return docs->file->content;
|
return docs->file->content;
|
||||||
@ -99,8 +100,8 @@ void docs_free(docs_t *docs) {
|
|||||||
if (NULL == docs)
|
if (NULL == docs)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
__docs_clean(docs);
|
_docs_clean(docs);
|
||||||
closedir(docs->dir);
|
closedir(docs->dir);
|
||||||
|
|
||||||
bzero(docs, sizeof(*docs));
|
memset(docs, 0, sizeof(*docs));
|
||||||
}
|
}
|
||||||
|
56
doc/src/file.c
Normal file
56
doc/src/file.c
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "file.h"
|
||||||
|
|
||||||
|
file_t *file_load(int dirfd, char *path) {
|
||||||
|
if (NULL == path) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
file_t *file = NULL;
|
||||||
|
int fd = -1;
|
||||||
|
|
||||||
|
// open the taarget file
|
||||||
|
if ((fd = openat(dirfd, path, O_RDONLY)) < 0)
|
||||||
|
goto end; // errno set by open
|
||||||
|
|
||||||
|
// allocate a new file structure
|
||||||
|
if (NULL == (file = calloc(1, sizeof(file_t))))
|
||||||
|
goto end; // errno set by malloc
|
||||||
|
|
||||||
|
// calculate the file size
|
||||||
|
if ((file->size = lseek(fd, 0, SEEK_END)) < 0)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
// memory map the file
|
||||||
|
if (NULL ==
|
||||||
|
(file->content = mmap(0, file->size, PROT_READ, MAP_PRIVATE, fd, 0)))
|
||||||
|
goto end; // errno set by mmap
|
||||||
|
|
||||||
|
end:
|
||||||
|
if (fd != -1)
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
if (NULL != file && NULL == file->content) {
|
||||||
|
free(file);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
void file_free(file_t *file) {
|
||||||
|
if (NULL == file)
|
||||||
|
return;
|
||||||
|
|
||||||
|
munmap(file->content, file->size);
|
||||||
|
free(file);
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
#include <ctorm/app.h>
|
||||||
#include <ctorm/ctorm.h>
|
#include <ctorm/ctorm.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@ -19,25 +20,28 @@ int main() {
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initialize the app config
|
||||||
ctorm_config_new(&app_config);
|
ctorm_config_new(&app_config);
|
||||||
app_config.disable_logging = true;
|
app_config.disable_logging = true;
|
||||||
app = ctorm_app_new(&app_config);
|
|
||||||
|
// create a new app
|
||||||
|
app = ctorm_app_new(&app_config);
|
||||||
|
|
||||||
// middlewares
|
// middlewares
|
||||||
MIDDLEWARE_ALL(app, "/*", route_cors);
|
ALL(app, "/*", route_cors);
|
||||||
MIDDLEWARE_ALL(app, "/*/*", route_cors);
|
ALL(app, "/*/*", route_cors);
|
||||||
|
|
||||||
// routes
|
// routes
|
||||||
GET(app, "/list", route_list);
|
GET(app, "/list", route_list);
|
||||||
GET(app, "/get/:name", route_get);
|
GET(app, "/get/:name", route_get);
|
||||||
|
|
||||||
ctorm_app_all(app, route_notfound);
|
ctorm_app_default(app, route_notfound);
|
||||||
ctorm_app_local(app, "config", &conf);
|
ctorm_app_local(app, "config", &conf);
|
||||||
|
|
||||||
ctorm_info("starting the web server on %s", host);
|
ctorm_info("starting the web server on %s", host);
|
||||||
|
|
||||||
if (!ctorm_app_run(app, host))
|
if (!ctorm_app_run(app, host))
|
||||||
ctorm_fail("failed to start the app: %s", ctorm_geterror());
|
ctorm_fail("failed to start the app: %s", ctorm_error());
|
||||||
|
|
||||||
ctorm_app_free(app);
|
ctorm_app_free(app);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
void route_cors(ctorm_req_t *req, ctorm_res_t *res) {
|
void route_cors(ctorm_req_t *req, ctorm_res_t *res) {
|
||||||
RES_SET("Access-Control-Allow-Origin", "*");
|
RES_SET("Access-Control-Allow-Origin", "*");
|
||||||
RES_SET("Access-Control-Allow-Headers",
|
RES_SET("Access-Control-Allow-Headers",
|
||||||
"Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, "
|
"Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, "
|
||||||
|
"Authorization, accept, origin, Cache-Control, "
|
||||||
"X-Requested-With");
|
"X-Requested-With");
|
||||||
RES_SET("Access-Control-Allow-Methods", "PUT, DELETE, GET");
|
RES_SET("Access-Control-Allow-Methods", "PUT, DELETE, GET");
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,30 @@
|
|||||||
#include <cjson/cJSON.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <linux/limits.h>
|
#include <linux/limits.h>
|
||||||
|
#include <cjson/cJSON.h>
|
||||||
#include <ctorm/ctorm.h>
|
#include <ctorm/ctorm.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <dirent.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "routes.h"
|
#include "routes.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "util.h"
|
||||||
#include "docs.h"
|
#include "docs.h"
|
||||||
|
|
||||||
void route_get(ctorm_req_t *req, ctorm_res_t *res) {
|
void route_get(ctorm_req_t *req, ctorm_res_t *res) {
|
||||||
config_t *conf = REQ_LOCAL("config");
|
config_t *conf = REQ_LOCAL("config");
|
||||||
char *doc_name = REQ_PARAM("name");
|
char *name = REQ_PARAM("name");
|
||||||
char *docs_dir = config_get(conf, "docs_dir"), *doc_data = NULL;
|
char *dir = config_get(conf, "dir"), *doc_data = NULL;
|
||||||
cJSON *json = NULL, *doc_json = NULL;
|
cJSON *json = NULL, *doc_json = NULL;
|
||||||
docs_t docs;
|
docs_t docs;
|
||||||
|
|
||||||
if (NULL == doc_name) {
|
if (NULL == name) {
|
||||||
ctorm_fail("documentation name not specified (how did that even happend)");
|
ctorm_fail("documentation name not specified (how did that even happend)");
|
||||||
util_send(res, 500, NULL);
|
util_send(res, 500, NULL);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!docs_init(&docs, docs_dir)) {
|
if (!docs_init(&docs, dir)) {
|
||||||
ctorm_fail("docs_init failed: %s", ctorm_geterror());
|
ctorm_fail("docs_init failed: %s", ctorm_error());
|
||||||
util_send(res, 500, NULL);
|
util_send(res, 500, NULL);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@ -36,7 +35,7 @@ void route_get(ctorm_req_t *req, ctorm_res_t *res) {
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (NULL != (doc_data = docs_next(&docs, doc_name, false))) {
|
while (NULL != (doc_data = docs_next(&docs, name, false))) {
|
||||||
if (NULL == (doc_json = cJSON_Parse(doc_data))) {
|
if (NULL == (doc_json = cJSON_Parse(doc_data))) {
|
||||||
ctorm_fail("failed to parse JSON: %s (%s)", docs.name, docs.lang);
|
ctorm_fail("failed to parse JSON: %s (%s)", docs.name, docs.lang);
|
||||||
continue;
|
continue;
|
||||||
@ -53,7 +52,7 @@ void route_get(ctorm_req_t *req, ctorm_res_t *res) {
|
|||||||
|
|
||||||
docs_reset(&docs);
|
docs_reset(&docs);
|
||||||
|
|
||||||
while (NULL != (doc_data = docs_next(&docs, doc_name, true))) {
|
while (NULL != (doc_data = docs_next(&docs, name, true))) {
|
||||||
if (NULL == (doc_json = cJSON_GetObjectItem(json, docs.lang)))
|
if (NULL == (doc_json = cJSON_GetObjectItem(json, docs.lang)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -3,21 +3,21 @@
|
|||||||
#include <ctorm/ctorm.h>
|
#include <ctorm/ctorm.h>
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "routes.h"
|
#include "routes.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "util.h"
|
||||||
#include "docs.h"
|
#include "docs.h"
|
||||||
|
|
||||||
void route_list(ctorm_req_t *req, ctorm_res_t *res) {
|
void route_list(ctorm_req_t *req, ctorm_res_t *res) {
|
||||||
config_t *conf = REQ_LOCAL("config");
|
config_t *conf = REQ_LOCAL("config");
|
||||||
char *docs_dir = config_get(conf, "docs_dir"), *doc_data = NULL;
|
char *dir = config_get(conf, "dir"), *doc_data = NULL;
|
||||||
cJSON *array = NULL, *json = NULL, *doc_json = NULL;
|
cJSON *array = NULL, *json = NULL, *doc_json = NULL;
|
||||||
docs_t docs;
|
docs_t docs;
|
||||||
|
|
||||||
if (!docs_init(&docs, docs_dir)) {
|
if (!docs_init(&docs, dir)) {
|
||||||
ctorm_fail("docs_init failed: %s", ctorm_geterror());
|
ctorm_fail("docs_init failed: %s", ctorm_error());
|
||||||
util_send(res, 500, NULL);
|
util_send(res, 500, NULL);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@ -31,7 +31,8 @@ void route_list(ctorm_req_t *req, ctorm_res_t *res) {
|
|||||||
while (NULL != (doc_data = docs_next(&docs, NULL, false))) {
|
while (NULL != (doc_data = docs_next(&docs, NULL, false))) {
|
||||||
if (NULL == (array = cJSON_GetObjectItem(json, docs.lang)) &&
|
if (NULL == (array = cJSON_GetObjectItem(json, docs.lang)) &&
|
||||||
NULL == (array = cJSON_AddArrayToObject(json, docs.lang))) {
|
NULL == (array = cJSON_AddArrayToObject(json, docs.lang))) {
|
||||||
ctorm_fail("failed to create an array object for the language %s", docs.lang);
|
ctorm_fail(
|
||||||
|
"failed to create an array object for the language %s", docs.lang);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,8 @@
|
|||||||
#include <linux/limits.h>
|
#include <linux/limits.h>
|
||||||
#include <ctorm/ctorm.h>
|
#include <ctorm/ctorm.h>
|
||||||
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <dirent.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@ -57,45 +48,3 @@ void util_send(ctorm_res_t *res, uint16_t code, cJSON *json) {
|
|||||||
|
|
||||||
RES_JSON(json);
|
RES_JSON(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
util_file_t *util_file_load(int dirfd, char *path) {
|
|
||||||
if (NULL == path) {
|
|
||||||
errno = EINVAL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
util_file_t *file = NULL;
|
|
||||||
struct stat buf;
|
|
||||||
int fd = -1;
|
|
||||||
|
|
||||||
if (NULL == (file = malloc(sizeof(util_file_t))))
|
|
||||||
goto end; // errno set by malloc
|
|
||||||
|
|
||||||
if ((fd = openat(dirfd, path, O_RDONLY)) < 0)
|
|
||||||
goto end; // errno set by open
|
|
||||||
|
|
||||||
if (fstat(fd, &buf) < 0)
|
|
||||||
goto end; // errno set by fstat
|
|
||||||
|
|
||||||
if (NULL == (file->content = mmap(0, (file->size = buf.st_size), PROT_READ, MAP_PRIVATE, fd, 0)))
|
|
||||||
goto end; // errno set by mmap
|
|
||||||
|
|
||||||
end:
|
|
||||||
if (fd != -1)
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
if (NULL == file->content) {
|
|
||||||
free(file);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
void util_file_free(util_file_t *file) {
|
|
||||||
if (NULL == file)
|
|
||||||
return;
|
|
||||||
|
|
||||||
munmap(file->content, file->size);
|
|
||||||
free(file);
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user