restore parent link in autoindex and add comments
This commit is contained in:
parent
189803ab52
commit
55042768e5
4 changed files with 42 additions and 15 deletions
5
Makefile
5
Makefile
|
@ -10,7 +10,10 @@ CFLAGS += -pedantic -Wall -Wextra -Wmissing-prototypes \
|
|||
all: vger
|
||||
|
||||
clean:
|
||||
rm -f vger *.core *.o
|
||||
find . -name vger -o \
|
||||
-name \*\.o -o \
|
||||
-name \*\.core \
|
||||
-delete
|
||||
|
||||
vger: main.o mimes.o utils.o opts.h
|
||||
${CC} ${CFLAGS} -o $@ main.o mimes.o utils.o
|
||||
|
|
48
main.c
48
main.c
|
@ -76,13 +76,16 @@ drop_privileges(const char *user, const char *path)
|
|||
} else {
|
||||
eunveil(path, "r");
|
||||
}
|
||||
/* permission to execute what's inside cgipath */
|
||||
if (strlen(cgibin) > 0) {
|
||||
/* first, build the full path of cgi (not in chroot) */
|
||||
char cgifullpath[PATH_MAX] = {'\0'};
|
||||
estrlcpy(cgifullpath, path, sizeof(cgifullpath));
|
||||
estrlcat(cgifullpath, cgibin, sizeof(cgifullpath));
|
||||
|
||||
eunveil(cgifullpath, "rx");
|
||||
}
|
||||
/* no more unveil later */
|
||||
/* forbid more unveil */
|
||||
eunveil(NULL, NULL);
|
||||
|
||||
/*
|
||||
|
@ -90,6 +93,7 @@ drop_privileges(const char *user, const char *path)
|
|||
* write to stdio
|
||||
*/
|
||||
if (strlen(cgibin) > 0) {
|
||||
/* cgi need execlp() (exec) and fork() (proc) */
|
||||
epledge("stdio rpath exec proc", NULL);
|
||||
} else {
|
||||
epledge("stdio rpath", NULL);
|
||||
|
@ -121,6 +125,7 @@ display_file(const char *uri)
|
|||
char *buffer[BUFSIZ];
|
||||
char target[FILENAME_MAX] = {'\0'};
|
||||
char fp[PATH_MAX] = {'\0'};
|
||||
char tmp[PATH_MAX] = {'\0'}; /* used to build temporary path */
|
||||
|
||||
/* build file path inside chroot */
|
||||
estrlcpy(fp, chroot_dir, sizeof(fp));
|
||||
|
@ -141,21 +146,19 @@ display_file(const char *uri)
|
|||
if (S_ISDIR(sb.st_mode) != 0) {
|
||||
if (fp[strlen(fp) -1 ] != '/') {
|
||||
/* no ending "/", redirect to "path/" */
|
||||
char new_uri[PATH_MAX] = {'\0'};
|
||||
estrlcpy(new_uri, uri, sizeof(new_uri));
|
||||
estrlcat(new_uri, "/", sizeof(new_uri));
|
||||
status_redirect(31, new_uri);
|
||||
estrlcpy(tmp, uri, sizeof(tmp));
|
||||
estrlcat(tmp, "/", sizeof(tmp));
|
||||
status_redirect(31, tmp);
|
||||
return;
|
||||
|
||||
} else {
|
||||
/* there is a leading "/", display index.gmi */
|
||||
char index_path[PATH_MAX] = {'\0'};
|
||||
estrlcpy(index_path, fp, sizeof(index_path));
|
||||
estrlcat(index_path, "index.gmi", sizeof(index_path));
|
||||
estrlcpy(tmp, fp, sizeof(tmp));
|
||||
estrlcat(tmp, "index.gmi", sizeof(tmp));
|
||||
|
||||
/* check if index.gmi exists or show autoindex */
|
||||
if (stat(index_path, &sb) == 0) {
|
||||
estrlcpy(fp, index_path, sizeof(fp));
|
||||
if (stat(tmp, &sb) == 0) {
|
||||
estrlcpy(fp, tmp, sizeof(fp));
|
||||
} else if (doautoidx != 0) {
|
||||
autoindex(fp);
|
||||
return;
|
||||
|
@ -172,7 +175,7 @@ display_file(const char *uri)
|
|||
|
||||
status(20, file_mime);
|
||||
|
||||
/* read the file and write it to stdout */
|
||||
/* read the file byte after byte in buffer and write it to stdout */
|
||||
while ((nread = fread(buffer, 1, sizeof(buffer), fd)) != 0)
|
||||
fwrite(buffer, 1, nread, stdout);
|
||||
goto closefd;
|
||||
|
@ -205,22 +208,41 @@ void
|
|||
autoindex(const char *path)
|
||||
{
|
||||
int n = 0;
|
||||
struct dirent **namelist;
|
||||
char *pos = NULL;
|
||||
struct dirent **namelist; /* this must be freed at last */
|
||||
|
||||
|
||||
syslog(LOG_DAEMON, "autoindex: %s", path);
|
||||
|
||||
status(20, "text/gemini");
|
||||
|
||||
/* display link to parent */
|
||||
char parent[PATH_MAX] = {'\0'};
|
||||
/* parent is "path" without chroot_dir */
|
||||
estrlcpy(parent, path+strlen(chroot_dir), sizeof(parent));
|
||||
/* remove ending '/' */
|
||||
while (parent[strlen(parent)-1] == '/') {
|
||||
parent[strlen(parent)-1] = '\0';
|
||||
}
|
||||
/* remove last part after '/' */
|
||||
pos = strrchr(parent, '/');
|
||||
if (pos != NULL) {
|
||||
pos[1] = '\0'; /* at worse, parent is now "/" */
|
||||
}
|
||||
printf("=> %s ../\n", parent);
|
||||
|
||||
/* use alphasort to always have the same order on every system */
|
||||
if ((n = scandir(path, &namelist, NULL, alphasort)) < 0) {
|
||||
status(51, "text/gemini");
|
||||
errlog("Can't scan %s", path);
|
||||
} else {
|
||||
for(int j = 0; j < n; j++) {
|
||||
/* skip self and parent */
|
||||
if ((strcmp(namelist[j]->d_name, ".") == 0) ||
|
||||
(strcmp(namelist[j]->d_name, "..") == 0)) {
|
||||
continue;
|
||||
}
|
||||
/* add "/" at the end of a directory path */
|
||||
if (namelist[j]->d_type == DT_DIR) {
|
||||
printf("=> ./%s/ %s/\n", namelist[j]->d_name, namelist[j]->d_name);
|
||||
} else {
|
||||
|
@ -239,6 +261,7 @@ cgi(const char *cgicmd)
|
|||
int pipedes[2] = {0};
|
||||
pid_t pid;
|
||||
|
||||
/* get a pipe to get stdout */
|
||||
if (pipe(pipedes) != 0) {
|
||||
status(42, "text/gemini");
|
||||
err(1, "pipe failed");
|
||||
|
@ -414,6 +437,7 @@ main(int argc, char **argv)
|
|||
if ((strlen(cgibin) > 0) &&
|
||||
(strncmp(uri, cgibin, strlen(cgibin)) == 0)) {
|
||||
|
||||
/* cgipath with chroot_dir at the beginning */
|
||||
char cgipath[PATH_MAX] = {'\0'};
|
||||
estrlcpy(cgipath, chroot_dir, sizeof(cgipath));
|
||||
estrlcat(cgipath, uri, sizeof(cgipath));
|
||||
|
|
|
@ -72,7 +72,7 @@ if ! [ $OUT = "874f5e1af67eff6b93bedf8ac8033066" ] ; then echo "error" ; exit 1
|
|||
|
||||
# auto index in directory
|
||||
OUT=$(printf "gemini://host.name/autoidx/\r\n" | ../vger -d var/gemini/ -i | tee /dev/stderr | $MD5)
|
||||
if ! [ $OUT = "988160d1908a9dcd0cadc21262de4490" ] ; then echo "error" ; exit 1 ; fi
|
||||
if ! [ $OUT = "515bcb4ba5f8869360f53afe2841e044" ] ; then echo "error" ; exit 1 ; fi
|
||||
|
||||
# cgi simple script
|
||||
OUT=$(printf "gemini://host.name/cgi-bin/test.cgi\r\n" | ../vger -d var/gemini/ -c /cgi-bin | tee /dev/stderr | $MD5)
|
||||
|
|
2
utils.c
2
utils.c
|
@ -34,7 +34,7 @@ estrlcpy(char *dst, const char *src, size_t dstsize)
|
|||
|
||||
n = strlcpy(dst, src, dstsize);
|
||||
if (n >= dstsize) {
|
||||
err(1, "strlcyp failed for %s = %s", dst, src);
|
||||
err(1, "strlcpy failed for %s = %s", dst, src);
|
||||
}
|
||||
|
||||
return n;
|
||||
|
|
Loading…
Reference in a new issue