diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..95d63a5 --- /dev/null +++ b/.clang-format @@ -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 +... + diff --git a/.drone.yml b/.drone.yml index e0a18e0..02cdb2c 100644 --- a/.drone.yml +++ b/.drone.yml @@ -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 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..78eb9d8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.o +.gdb_history +config.h +quark \ No newline at end of file diff --git a/config.def.h b/config.def.h index 7197ca8..6d7f690 100644 --- a/config.def.h +++ b/config.def.h @@ -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 { diff --git a/dirl.c b/dirl.c index d047b4e..90364bb 100644 --- a/dirl.c +++ b/dirl.c @@ -8,37 +8,106 @@ #include #include +#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, - "\n\n\t" - "Index of %s\n" - "\t\n" - "\t\t

Index of %s

\n" - "\t\t\t..", - esc, esc) < 0) { + "\n" + "\n" + " \n" + " \n" + " Index of %s\n" + " \n" + " \n" + "

Index of %s

\n" + " ..", + 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, "
\n\t\t%s%s", esc, - (entry->d_type == DT_DIR) ? "/" : "", esc, + if (dprintf(fd, + "
\n\t\t%s%s", + 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\n\n") < 0) { +dirl_footer_default(int fd) +{ + if (dprintf(fd, + "\n" + " \n" + "") < 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); +} diff --git a/dirl.h b/dirl.h index d8df880..f147106 100644 --- a/dirl.h +++ b/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); diff --git a/util.c b/util.c index 487b94a..65e80e6 100644 --- a/util.c +++ b/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; }