Read from template files with placeholder replacement
This commit is contained in:
parent
329dedc33b
commit
5b6f8e5083
7 changed files with 287 additions and 109 deletions
137
.clang-format
Normal file
137
.clang-format
Normal file
|
@ -0,0 +1,137 @@
|
|||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: Mozilla
|
||||
AccessModifierOffset: -2
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveMacros: false
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllConstructorInitializersOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: TopLevel
|
||||
AlwaysBreakAfterReturnType: TopLevel
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: true
|
||||
AfterControlStatement: false
|
||||
AfterEnum: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
AfterExternBlock: true
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Mozilla
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakInheritanceList: BeforeComma
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 80
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 2
|
||||
ContinuationIndentWidth: 2
|
||||
Cpp11BracedListStyle: false
|
||||
DeriveLineEnding: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: false
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 3
|
||||
SortPriority: 0
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IncludeIsMainSourceRegex: ''
|
||||
IndentCaseLabels: true
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentWidth: 2
|
||||
IndentWrappedFunctionNames: false
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: true
|
||||
ObjCSpaceBeforeProtocolList: false
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 200
|
||||
PointerAlignment: Left
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
SpaceBeforeSquareBrackets: false
|
||||
Standard: Latest
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TabWidth: 8
|
||||
UseCRLF: false
|
||||
UseTab: Never
|
||||
...
|
||||
|
|
@ -12,8 +12,8 @@ steps:
|
|||
image: debian
|
||||
commands:
|
||||
- cp quark /usr/local/bin
|
||||
- useradd web && su web && cd
|
||||
- mkdir -p web && cd web && echo "hello from quark" > index.html
|
||||
- useradd web
|
||||
- mkdir -p web && cd web && echo "hello from quark" > index.html
|
||||
- quark -p 9130 -h run -l -u web -g web
|
||||
detach: true
|
||||
|
||||
|
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
*.o
|
||||
.gdb_history
|
||||
config.h
|
||||
quark
|
|
@ -1,9 +1,5 @@
|
|||
#define HEADER_MAX 4096
|
||||
#define FIELD_MAX 200
|
||||
#define DIRL_HEADER "header.qhtml"
|
||||
#define DIRL_ENTRY "entry.qhtml"
|
||||
#define DIRL_FOOTER "footer.qhtml"
|
||||
#define DIRL_STYLE "dirlist.css"
|
||||
|
||||
/* mime-types */
|
||||
static const struct {
|
||||
|
|
239
dirl.c
239
dirl.c
|
@ -8,37 +8,106 @@
|
|||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "dirl.h"
|
||||
#include "http.h"
|
||||
#include "util.h"
|
||||
#include "config.h"
|
||||
|
||||
static char *suffix(int t) {
|
||||
static char*
|
||||
suffix(int t)
|
||||
{
|
||||
switch (t) {
|
||||
case DT_FIFO:
|
||||
return "|";
|
||||
case DT_DIR:
|
||||
return "/";
|
||||
case DT_LNK:
|
||||
return "@";
|
||||
case DT_SOCK:
|
||||
return "=";
|
||||
case DT_FIFO:
|
||||
return "|";
|
||||
case DT_DIR:
|
||||
return "/";
|
||||
case DT_LNK:
|
||||
return "@";
|
||||
case DT_SOCK:
|
||||
return "=";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
enum status
|
||||
dirl_header_default(int fd, const struct response *res) {
|
||||
static char*
|
||||
dirl_read_template(char* tpl)
|
||||
{
|
||||
/* Try find template in root (note that we are chroot'ed) */
|
||||
FILE* tpl_fp;
|
||||
char* tpl_abs;
|
||||
|
||||
tpl_abs = calloc(strlen(tpl)+2, sizeof(char));
|
||||
if(tpl_abs == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
tpl_abs[0] = '/';
|
||||
strcat(tpl_abs, tpl);
|
||||
|
||||
if (!(tpl_fp = fopen(tpl_abs, "r"))) {
|
||||
free(tpl_abs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
free(tpl_abs);
|
||||
|
||||
/* Get size of template */
|
||||
if (fseek(tpl_fp, 0L, SEEK_END) < 0) {
|
||||
fclose(tpl_fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
long tpl_size;
|
||||
if ((tpl_size = ftell(tpl_fp)) < 0) {
|
||||
fclose(tpl_fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rewind(tpl_fp);
|
||||
|
||||
/* Read template into tpl_buf */
|
||||
char* tpl_buf = (char*)malloc(sizeof(char) * tpl_size);
|
||||
|
||||
if (tpl_buf == NULL) {
|
||||
fclose(tpl_fp);
|
||||
free(tpl_buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fread(tpl_buf, 1, tpl_size, tpl_fp) < tpl_size) {
|
||||
if (feof(tpl_fp)) {
|
||||
warn("Reached end of template %s prematurely", tpl);
|
||||
} else if (ferror(tpl_fp)) {
|
||||
warn("Error while reading template %s", tpl);
|
||||
}
|
||||
|
||||
fclose(tpl_fp);
|
||||
free(tpl_buf);
|
||||
clearerr(tpl_fp);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return tpl_buf;
|
||||
}
|
||||
|
||||
static enum status
|
||||
dirl_header_default(int fd, const struct response* res)
|
||||
{
|
||||
char esc[PATH_MAX];
|
||||
html_escape(res->uri, esc, sizeof(esc));
|
||||
if (dprintf(fd,
|
||||
"<!DOCTYPE html>\n<html>\n\t<head>"
|
||||
"<title>Index of %s</title></head>\n"
|
||||
"\t<body>\n"
|
||||
"\t\t<h1>Index of %s</h1>\n"
|
||||
"\t\t\t<a href=\"..\">..</a>",
|
||||
esc, esc) < 0) {
|
||||
"<!DOCTYPE html>\n"
|
||||
"<html>\n"
|
||||
" <head>\n"
|
||||
" <link rel=\"stylesheet\" href=\"/"DIRL_STYLE"\">\n"
|
||||
" <title>Index of %s</title>\n"
|
||||
" </head>\n"
|
||||
" <body>\n"
|
||||
" <h1>Index of %s</h1>\n"
|
||||
" <a href=\"..\">..</a>",
|
||||
esc,
|
||||
esc) < 0) {
|
||||
return S_REQUEST_TIMEOUT;
|
||||
}
|
||||
|
||||
|
@ -46,45 +115,21 @@ dirl_header_default(int fd, const struct response *res) {
|
|||
}
|
||||
|
||||
enum status
|
||||
dirl_header(int fd, const struct response *res)
|
||||
dirl_header(int fd, const struct response* res)
|
||||
{
|
||||
char* tpl = dirl_read_template(DIRL_HEADER);
|
||||
|
||||
/* No header file defined, default */
|
||||
#ifndef DIRL_HEADER
|
||||
return dirl_header_default(fd, res);
|
||||
#endif
|
||||
|
||||
/* Try find header in root (note that we are chroot'ed) */
|
||||
int header_fd;
|
||||
if ( (header_fd = open(("/" DIRL_HEADER), O_RDONLY)) < 0 ) {
|
||||
return dirl_header_default(fd, res);
|
||||
}
|
||||
|
||||
/* Get size of header */
|
||||
struct stat header_stat;
|
||||
if (fstat(header_fd, &header_stat) < 0) {
|
||||
return dirl_header_default(fd, res);
|
||||
}
|
||||
|
||||
/* Allocate space for file */
|
||||
char *header = (char *) malloc(sizeof(char) * header_stat.st_size);
|
||||
if (header == NULL) {
|
||||
return dirl_header_default(fd, res);
|
||||
}
|
||||
|
||||
/* Read header into string for template replacement */
|
||||
if ( (read(header_fd, header, header_stat.st_size)) < 0) {
|
||||
free(header);
|
||||
if(tpl == NULL) {
|
||||
return dirl_header_default(fd, res);
|
||||
}
|
||||
|
||||
/* Replace placeholder */
|
||||
char *nhead = replace(header, "{idx}", "something");
|
||||
char* nhead = replace(tpl, "{idx}", "something");
|
||||
|
||||
/* Write header */
|
||||
write(fd, nhead, strlen(nhead));
|
||||
|
||||
free(header);
|
||||
free(tpl);
|
||||
free(nhead);
|
||||
|
||||
/* listing header */
|
||||
|
@ -92,12 +137,16 @@ dirl_header(int fd, const struct response *res)
|
|||
}
|
||||
|
||||
static enum status
|
||||
dirl_entry_default(int fd, const struct dirent* entry) {
|
||||
dirl_entry_default(int fd, const struct dirent* entry)
|
||||
{
|
||||
char esc[PATH_MAX];
|
||||
|
||||
html_escape(entry->d_name, esc, sizeof(esc));
|
||||
if (dprintf(fd, "<br />\n\t\t<a href=\"%s%s\">%s%s</a>", esc,
|
||||
(entry->d_type == DT_DIR) ? "/" : "", esc,
|
||||
if (dprintf(fd,
|
||||
"<br />\n\t\t<a href=\"%s%s\">%s%s</a>",
|
||||
esc,
|
||||
(entry->d_type == DT_DIR) ? "/" : "",
|
||||
esc,
|
||||
suffix(entry->d_type)) < 0) {
|
||||
return S_REQUEST_TIMEOUT;
|
||||
}
|
||||
|
@ -106,30 +155,33 @@ dirl_entry_default(int fd, const struct dirent* entry) {
|
|||
}
|
||||
|
||||
enum status
|
||||
dirl_entry(int fd, const struct dirent* entry) {
|
||||
/* Try find entry in root (note that we are chroot'ed) */
|
||||
int entry_fd;
|
||||
if ((entry_fd = open(("/" DIRL_ENTRY), O_RDONLY)) < 0) {
|
||||
dirl_entry(int fd, const struct dirent* entry)
|
||||
{
|
||||
char* tpl = dirl_read_template(DIRL_ENTRY);
|
||||
|
||||
if (tpl == NULL) {
|
||||
return dirl_entry_default(fd, entry);
|
||||
}
|
||||
|
||||
/* Get size of entry*/
|
||||
struct stat entry_stat;
|
||||
if (fstat(entry_fd, &entry_stat) < 0) {
|
||||
return dirl_entry_default(fd, entry);
|
||||
}
|
||||
/* Replace placeholder */
|
||||
char* nentry = replace(tpl, "{entry}", entry->d_name);
|
||||
|
||||
/* Write entry */
|
||||
if (sendfile(fd, entry_fd, NULL, entry_stat.st_size) < 0) {
|
||||
return dirl_entry_default(fd, entry);
|
||||
}
|
||||
write(fd, nentry, strlen(nentry));
|
||||
|
||||
free(tpl);
|
||||
free(nentry);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum status
|
||||
dirl_footer_default(int fd) {
|
||||
if (dprintf(fd, "\n\t</body>\n</html>\n") < 0) {
|
||||
dirl_footer_default(int fd)
|
||||
{
|
||||
if (dprintf(fd,
|
||||
"\n"
|
||||
" </body>\n"
|
||||
"</html>") < 0) {
|
||||
return S_REQUEST_TIMEOUT;
|
||||
}
|
||||
|
||||
|
@ -137,49 +189,32 @@ dirl_footer_default(int fd) {
|
|||
}
|
||||
|
||||
enum status
|
||||
dirl_footer(int fd) {
|
||||
/* Try find footer in root (note that we are chroot'ed) */
|
||||
int footer_fd;
|
||||
if ((footer_fd = open(("/" DIRL_FOOTER), O_RDONLY)) < 0) {
|
||||
dirl_footer(int fd)
|
||||
{
|
||||
char* tpl = dirl_read_template(DIRL_FOOTER);
|
||||
|
||||
if(tpl == NULL) {
|
||||
return dirl_footer_default(fd);
|
||||
}
|
||||
|
||||
/* Get size of footer */
|
||||
struct stat footer_stat;
|
||||
if (fstat(footer_fd, &footer_stat) < 0) {
|
||||
return dirl_footer_default(fd);
|
||||
}
|
||||
/* Replace placeholder */
|
||||
char* nfoot = replace(tpl, "{idx}", "something");
|
||||
|
||||
/* Write footer */
|
||||
if (sendfile(fd, footer_fd, NULL, footer_stat.st_size) < 0) {
|
||||
return dirl_footer_default(fd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dirl_skip(const char *name) {
|
||||
(void) name;
|
||||
#ifdef DIRL_HEADER
|
||||
if(!strcmp(name, DIRL_HEADER)) {
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
#ifdef DIRL_ENTRY
|
||||
if (!strcmp(name, DIRL_ENTRY)) {
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
#ifdef DIRL_FOOTER
|
||||
if (!strcmp(name, DIRL_FOOTER)) {
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
#ifdef DIRL_STYLE
|
||||
if (!strcmp(name, DIRL_STYLE)) {
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
write(fd, nfoot, strlen(nfoot));
|
||||
|
||||
free(tpl);
|
||||
free(nfoot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
dirl_skip(const char* name)
|
||||
{
|
||||
(void)name; // noop; avoid unused warning
|
||||
|
||||
return !strcmp(name, DIRL_HEADER) //
|
||||
|| !strcmp(name, DIRL_ENTRY) //
|
||||
|| !strcmp(name, DIRL_FOOTER) //
|
||||
|| !strcmp(name, DIRL_STYLE);
|
||||
}
|
||||
|
|
6
dirl.h
6
dirl.h
|
@ -8,6 +8,11 @@
|
|||
|
||||
#include "http.h"
|
||||
|
||||
#define DIRL_HEADER ".header.tpl"
|
||||
#define DIRL_ENTRY ".entry.tpl"
|
||||
#define DIRL_FOOTER ".footer.tpl"
|
||||
#define DIRL_STYLE "style.css"
|
||||
|
||||
struct dirl_env_entry {
|
||||
char *name;
|
||||
char *value;
|
||||
|
@ -22,6 +27,7 @@ struct dirl_env {
|
|||
* meaning. Skips header-, entry-, footer templates and dirlist style css.
|
||||
*/
|
||||
int dirl_skip(const char*);
|
||||
|
||||
enum status dirl_header(int, const struct response*);
|
||||
enum status dirl_entry(int, const struct dirent*);
|
||||
enum status dirl_footer(int);
|
||||
|
|
2
util.c
2
util.c
|
@ -199,7 +199,7 @@ replace(const char *src, const char *old, const char* new) {
|
|||
srcidx = srcidx_old+old_len;
|
||||
}
|
||||
|
||||
strcpy(bufidx, srcidx); // copy tail
|
||||
strncpy(bufidx, srcidx, strlen(srcidx)); // copy tail
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue