add option -l to enable dirlisting, now disabled by default...
... alphasort direntries using scandir().
This commit is contained in:
parent
fa113f8b47
commit
19fbedc39a
1 changed files with 28 additions and 14 deletions
42
quark.c
42
quark.c
|
@ -76,7 +76,7 @@ static void die(const char *errstr, ...);
|
||||||
static int putresentry(int type, ...);
|
static int putresentry(int type, ...);
|
||||||
static void responsefiledata(int fd, off_t size);
|
static void responsefiledata(int fd, off_t size);
|
||||||
static void responsefile(void);
|
static void responsefile(void);
|
||||||
static void responsedirdata(DIR *d);
|
static void responsedirdata(struct dirent **e, int len);
|
||||||
static void responsedir(void);
|
static void responsedir(void);
|
||||||
static void responsecgi(void);
|
static void responsecgi(void);
|
||||||
static void response(void);
|
static void response(void);
|
||||||
|
@ -97,6 +97,7 @@ static char reqhost[256];
|
||||||
static char reqmod[256];
|
static char reqmod[256];
|
||||||
static int fd = -1;
|
static int fd = -1;
|
||||||
static Request req;
|
static Request req;
|
||||||
|
static int allowdirlist = 0;
|
||||||
|
|
||||||
char *
|
char *
|
||||||
tstamp(time_t t) {
|
tstamp(time_t t) {
|
||||||
|
@ -242,21 +243,21 @@ responsefile(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
responsedirdata(DIR *d) {
|
responsedirdata(struct dirent **e, int len) {
|
||||||
struct dirent *e;
|
int n;
|
||||||
|
|
||||||
if (putresentry(HEADER, HttpOk, tstamp(0))
|
if (putresentry(HEADER, HttpOk, tstamp(0))
|
||||||
|| putresentry(CONTENTTYPE, texthtml))
|
|| putresentry(CONTENTTYPE, texthtml))
|
||||||
return;
|
return;
|
||||||
status = 200;
|
status = 200;
|
||||||
if (req.type == GET) {
|
if (req.type == GET) {
|
||||||
if (writetext("\r\n<html><body><a href='..'>..</a><br>\r\n"))
|
if (writetext("\r\n<html><body><a href=\"..\">..</a><br/>\r\n"))
|
||||||
return;
|
return;
|
||||||
while ((e = readdir(d))) {
|
for(n = 0; n < len; n++) {
|
||||||
if (e->d_name[0] == '.') /* ignore hidden files, ., .. */
|
if (e[n]->d_name[0] == '.') /* ignore hidden files, ., .. */
|
||||||
continue;
|
continue;
|
||||||
if (snprintf(resbuf, MAXBUFLEN, "<a href='%s%s'>%s</a><br>\r\n",
|
if (snprintf(resbuf, MAXBUFLEN, "<a href=\"%s%s\">%s</a><br/>\r\n",
|
||||||
reqbuf, e->d_name, e->d_name) >= MAXBUFLEN)
|
reqbuf, e[n]->d_name, e[n]->d_name) >= MAXBUFLEN)
|
||||||
{
|
{
|
||||||
logerrmsg("snprintf failed, buffer sizeof exceeded");
|
logerrmsg("snprintf failed, buffer sizeof exceeded");
|
||||||
return;
|
return;
|
||||||
|
@ -271,7 +272,8 @@ responsedirdata(DIR *d) {
|
||||||
void
|
void
|
||||||
responsedir(void) {
|
responsedir(void) {
|
||||||
size_t len = strlen(reqbuf);
|
size_t len = strlen(reqbuf);
|
||||||
DIR *d;
|
struct dirent **namelist = NULL;
|
||||||
|
int n;
|
||||||
|
|
||||||
if (len > 0 && (reqbuf[len - 1] != '/') && (len + 1 < MAXBUFLEN)) {
|
if (len > 0 && (reqbuf[len - 1] != '/') && (len + 1 < MAXBUFLEN)) {
|
||||||
/* add directory terminator if necessary */
|
/* add directory terminator if necessary */
|
||||||
|
@ -291,11 +293,20 @@ responsedir(void) {
|
||||||
memcpy(reqbuf + len, docindex, strlen(docindex) + 1);
|
memcpy(reqbuf + len, docindex, strlen(docindex) + 1);
|
||||||
if (access(reqbuf, R_OK) == -1) { /* directory mode */
|
if (access(reqbuf, R_OK) == -1) { /* directory mode */
|
||||||
reqbuf[len] = 0; /* cut off docindex again */
|
reqbuf[len] = 0; /* cut off docindex again */
|
||||||
if ((d = opendir(reqbuf))) {
|
if(!allowdirlist) {
|
||||||
responsedirdata(d);
|
if (putresentry(HEADER, HttpForbidden, tstamp(0))
|
||||||
closedir(d);
|
|| putresentry(CONTENTTYPE, texthtml))
|
||||||
|
return;
|
||||||
|
status = 403;
|
||||||
|
if (req.type == GET)
|
||||||
|
writetext("\r\n<html><body>"HttpForbidden"</body></html>\r\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((n = scandir(reqbuf, &namelist, NULL, alphasort)) >= 0) {
|
||||||
|
responsedirdata(namelist, n);
|
||||||
|
free(namelist);
|
||||||
} else {
|
} else {
|
||||||
logerrmsg("client %s requests %s but opendir failed: %s\n",
|
logerrmsg("client %s requests %s but scandir failed: %s\n",
|
||||||
host, reqbuf, strerror(errno));
|
host, reqbuf, strerror(errno));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -544,7 +555,7 @@ sighandler(int sig) {
|
||||||
void
|
void
|
||||||
usage(void) {
|
usage(void) {
|
||||||
die("usage: %s [-c] [-d cgidir] [-e cgiscript] [-u user] [-g group] "
|
die("usage: %s [-c] [-d cgidir] [-e cgiscript] [-u user] [-g group] "
|
||||||
"[-i index] [-r docroot] [-s server] [-p port] [-v]\n", argv0);
|
"[-i index] [-l] [-r docroot] [-s server] [-p port] [-v]\n", argv0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -573,6 +584,9 @@ main(int argc, char *argv[]) {
|
||||||
case 'i':
|
case 'i':
|
||||||
docindex = EARGF(usage());
|
docindex = EARGF(usage());
|
||||||
break;
|
break;
|
||||||
|
case 'l':
|
||||||
|
allowdirlist = 1;
|
||||||
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
docroot = EARGF(usage());
|
docroot = EARGF(usage());
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue