Fix merge leftovers, add attribution footer by default

This commit is contained in:
Armin Friedl 2020-08-30 18:07:23 +02:00
parent e262166522
commit 2a3e25dc6b
4 changed files with 99 additions and 76 deletions

59
data.c
View file

@ -26,64 +26,6 @@ compareent(const struct dirent **d1, const struct dirent **d2)
return strcmp((*d1)->d_name, (*d2)->d_name);
}
static char *
suffix(int t)
{
switch (t) {
case DT_FIFO: return "|";
case DT_DIR: return "/";
case DT_LNK: return "@";
case DT_SOCK: return "=";
}
return "";
}
static void
html_escape(const char *src, char *dst, size_t dst_siz)
{
const struct {
char c;
char *s;
} escape[] = {
{ '&', "&" },
{ '<', "&lt;" },
{ '>', "&gt;" },
{ '"', "&quot;" },
{ '\'', "&#x27;" },
};
size_t i, j, k, esclen;
for (i = 0, j = 0; src[i] != '\0'; i++) {
for (k = 0; k < LEN(escape); k++) {
if (src[i] == escape[k].c) {
break;
}
}
if (k == LEN(escape)) {
/* no escape char at src[i] */
if (j == dst_siz - 1) {
/* silent truncation */
break;
} else {
dst[j++] = src[i];
}
} else {
/* escape char at src[i] */
esclen = strlen(escape[k].s);
if (j >= dst_siz - esclen) {
/* silent truncation */
break;
} else {
memcpy(&dst[j], escape[k].s, esclen);
j += esclen;
}
}
}
dst[j] = '\0';
}
enum status
data_send_dirlisting(int fd, const struct response *res)
{
@ -91,7 +33,6 @@ data_send_dirlisting(int fd, const struct response *res)
struct dirent **e;
size_t i;
int dirlen;
char esc[PATH_MAX /* > NAME_MAX */ * 6]; /* strlen("&...;") <= 6 */
/* read directory */
if ((dirlen = scandir(res->path, &e, NULL, compareent)) < 0) {

84
dirl.c
View file

@ -2,11 +2,13 @@
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include "config.h"
@ -31,6 +33,49 @@ suffix(int t)
return "";
}
static void
html_escape(const char* src, char* dst, size_t dst_siz)
{
const struct
{
char c;
char* s;
} escape[] = {
{ '&', "&amp;" }, { '<', "&lt;" }, { '>', "&gt;" },
{ '"', "&quot;" }, { '\'', "&#x27;" },
};
size_t i, j, k, esclen;
for (i = 0, j = 0; src[i] != '\0'; i++) {
for (k = 0; k < LEN(escape); k++) {
if (src[i] == escape[k].c) {
break;
}
}
if (k == LEN(escape)) {
/* no escape char at src[i] */
if (j == dst_siz - 1) {
/* silent truncation */
break;
} else {
dst[j++] = src[i];
}
} else {
/* escape char at src[i] */
esclen = strlen(escape[k].s);
if (j >= dst_siz - esclen) {
/* silent truncation */
break;
} else {
memcpy(&dst[j], escape[k].s, esclen);
j += esclen;
}
}
}
dst[j] = '\0';
}
/* Try to find templates up until root
*
* Iterates the directory hierarchy upwards. Returns the closest path containing
@ -44,8 +89,8 @@ dirl_find_templ_dir(const char* start_path)
char* path_buf = calloc(sizeof(char), strlen(start_path));
strcat(path_buf, start_path);
if(path_buf[strlen(path_buf)-1] == '/') {
// don't read last dir twice
if(strlen(path_buf) > 1 && path_buf[strlen(path_buf)-1] == '/') {
// don't read last dir twice, except at root
path_buf[strlen(path_buf)-1] = '\0';
}
@ -123,8 +168,8 @@ enum status
dirl_header(int fd, const struct response* res, const struct dirl_templ* templ)
{
/* Replace placeholder */
char* nhead = calloc(sizeof(char), strlen(templ->header));
memcpy(nhead, templ->header, strlen(templ->header));
char* nhead = calloc(sizeof(char), strlen(templ->header)+1);
memcpy(nhead, templ->header, strlen(templ->header)+1);
replace(&nhead, "{uri}", res->uri);
/* Write header */
@ -139,12 +184,34 @@ dirl_header(int fd, const struct response* res, const struct dirl_templ* templ)
enum status
dirl_entry(int fd, const struct dirent* entry, const struct dirl_templ* templ)
{
struct stat stat_buf;
lstat(entry->d_name, &stat_buf);
char* nentry = calloc(sizeof(char), strlen(templ->entry)+1);
//strcat(nentry, templ->entry);
memcpy(nentry, templ->entry, strlen(templ->entry)+1);
/* Replace placeholder */
char* nentry = calloc(sizeof(char), strlen(templ->entry));
memcpy(nentry, templ->entry, strlen(templ->entry));
char esc[PATH_MAX * 6];
html_escape(entry->d_name, esc, PATH_MAX*6);
replace(&nentry, "{entry}", entry->d_name);
replace(&nentry, "{suffix}", suffix(entry->d_type));
char size_buf[1024];
if(entry->d_type == DT_REG) {
snprintf(size_buf, 1024, "%ld", stat_buf.st_size);
} else {
sprintf(size_buf, "-");
}
replace(&nentry, "{size}", size_buf);
char time_buf[1024];
struct tm tm;
gmtime_r(&stat_buf.st_mtim.tv_sec, &tm);
strftime(time_buf, 1024, "%F %H:%m", &tm);
replace(&nentry, "{modified}", time_buf);
/* Write entry */
write(fd, nentry, strlen(nentry));
@ -157,9 +224,8 @@ enum status
dirl_footer(int fd, const struct dirl_templ* templ)
{
/* Replace placeholder */
char* nfoot = calloc(sizeof(char), strlen(templ->footer));
memcpy(nfoot, templ->footer, strlen(templ->footer));
replace(&nfoot, "{idx}", "something");
char* nfoot = calloc(sizeof(char), strlen(templ->footer)+1);
memcpy(nfoot, templ->footer, strlen(templ->footer)+1);
/* Write footer */
write(fd, nfoot, strlen(nfoot));

25
dirl.h
View file

@ -26,15 +26,30 @@
" </head>\n" \
" <body>\n" \
" <h1>Index of {uri}</h1>\n" \
" <hr />" \
" <a href=\"..\">..</a>\n"
" <p><a href=\"..\">&crarr; Parent Directory</a></p>\n" \
" <hr />\n" \
" <table>\n" \
" <tr><th>Name</th><th>Modified</th><th>Size</th></tr>"
#define DIRL_ENTRY_DEFAULT \
" <br />\n" \
" <a href=\"{entry}\">{entry}{suffix}</a>\n"
" <tr>\n" \
" <td><a href=\"{entry}\">{entry}{suffix}</a>\n" \
" <td>{modified}</td>\n" \
" <td>{size}</td>\n" \
" </tr>\n"
#define DIRL_FOOTER_DEFAULT \
" <hr />" \
" </table>\n" \
" <hr />\n" \
" <p>" \
"Served by" \
" <a href=\"http://tools.suckless.org/quark/\">quark</a>" \
" and" \
" <a href=" \
"\"https://git.friedl.net/playground/suckless-quark/src/branch/dirlist\">" \
"dirl" \
"</a>" \
"</p>\n" \
"</body>\n" \
"</html>"

5
util.c
View file

@ -138,7 +138,8 @@ replace(char **src, const char *old, const char* new) {
}
/* Allocate enough space for the new string */
char *buf = calloc( sizeof(char), src_len + replc*(abs(new_len-old_len)) + 1);
size_t buf_size = src_len + replc * (new_len - old_len) + 1;
char* buf = calloc(sizeof(char), buf_size);
/* Now start replacing */
const char *srcidx = *src;
@ -192,7 +193,7 @@ read_file(const char* path){
return NULL;
}
if (fread(tpl_buf, 1, tpl_size, tpl_fp) < tpl_size) {
if (fread(tpl_buf, 1, tpl_size, tpl_fp) < (size_t) tpl_size) {
if (feof(tpl_fp)) {
warn("Reached end of file %s prematurely", path);
} else if (ferror(tpl_fp)) {