Coding style
This commit is contained in:
parent
f915f82a40
commit
10416a352b
1 changed files with 109 additions and 118 deletions
227
quark.c
227
quark.c
|
@ -55,11 +55,11 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *resentry[] = {
|
static const char *resentry[] = {
|
||||||
[HEADER] = "HTTP/1.1 %s\r\nConnection: close\r\nDate: %s\r\nServer: quark-"VERSION"\r\n",
|
[HEADER] = "HTTP/1.1 %s\r\nConnection: close\r\nDate: %s\r\nServer: quark-"VERSION"\r\n",
|
||||||
[CONTENTLEN] = "Content-Length: %lu\r\n",
|
[CONTENTLEN] = "Content-Length: %lu\r\n",
|
||||||
[LOCATION] = "Location: %s%s\r\n",
|
[LOCATION] = "Location: %s%s\r\n",
|
||||||
[CONTENTTYPE] = "Content-Type: %s\r\n",
|
[CONTENTTYPE] = "Content-Type: %s\r\n",
|
||||||
[MODIFIED] = "Last-Modified: %s\r\n"
|
[MODIFIED] = "Last-Modified: %s\r\n"
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t writetext(const char *buf);
|
static ssize_t writetext(const char *buf);
|
||||||
|
@ -97,8 +97,8 @@ ssize_t
|
||||||
writedata(const char *buf, size_t buf_len) {
|
writedata(const char *buf, size_t buf_len) {
|
||||||
ssize_t r, offset;
|
ssize_t r, offset;
|
||||||
|
|
||||||
for(offset = 0; offset < buf_len; offset += r) {
|
for (offset = 0; offset < buf_len; offset += r) {
|
||||||
if((r = write(req.fd, buf + offset, buf_len - offset)) == -1) {
|
if ((r = write(req.fd, buf + offset, buf_len - offset)) == -1) {
|
||||||
logerrmsg("client %s closed connection\n", host);
|
logerrmsg("client %s closed connection\n", host);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -116,10 +116,8 @@ atomiclog(int fd, const char *errstr, va_list ap) {
|
||||||
static char buf[512];
|
static char buf[512];
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
/*
|
/* assemble the message in buf and write it in one pass
|
||||||
assemble the message in buf and write it in one pass
|
to avoid interleaved concurrent writes on a shared fd. */
|
||||||
to avoid interleaved concurrent writes on a shared fd.
|
|
||||||
*/
|
|
||||||
n = snprintf(buf, sizeof buf, "%s: ", tstamp());
|
n = snprintf(buf, sizeof buf, "%s: ", tstamp());
|
||||||
n += vsnprintf(buf + n, sizeof buf - n, errstr, ap);
|
n += vsnprintf(buf + n, sizeof buf - n, errstr, ap);
|
||||||
if (n >= sizeof buf)
|
if (n >= sizeof buf)
|
||||||
|
@ -160,7 +158,7 @@ putresentry(int type, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, type);
|
va_start(ap, type);
|
||||||
if(vsnprintf(resbuf, MAXBUFLEN, resentry[type], ap) >= MAXBUFLEN) {
|
if (vsnprintf(resbuf, MAXBUFLEN, resentry[type], ap) >= MAXBUFLEN) {
|
||||||
logerrmsg("vsnprintf failed, buffer size exceeded");
|
logerrmsg("vsnprintf failed, buffer size exceeded");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -173,10 +171,10 @@ responsefiledata(int fd, off_t size) {
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
|
|
||||||
for(; (n = read(fd, buf, MIN(size, sizeof buf))) > 0; size -= n)
|
for (; (n = read(fd, buf, MIN(size, sizeof buf))) > 0; size -= n)
|
||||||
if(write(req.fd, buf, n) != n)
|
if (write(req.fd, buf, n) != n)
|
||||||
logerrmsg("error writing to client %s at %ls: %s\n", host, n, strerror(errno));
|
logerrmsg("error writing to client %s at %ls: %s\n", host, n, strerror(errno));
|
||||||
if(n == -1)
|
if (n == -1)
|
||||||
logerrmsg("error reading from file: %s\n", strerror(errno));
|
logerrmsg("error reading from file: %s\n", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,39 +187,38 @@ responsefile(void) {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
time_t t;
|
time_t t;
|
||||||
|
|
||||||
if((r = stat(reqbuf, &st)) == -1 || (ffd = open(reqbuf, O_RDONLY)) == -1) {
|
if ((r = stat(reqbuf, &st)) == -1 || (ffd = open(reqbuf, O_RDONLY)) == -1) {
|
||||||
/* file not found */
|
/* file not found */
|
||||||
logerrmsg("%s requests unknown file %s\n", host, reqbuf);
|
logerrmsg("%s requests unknown file %s\n", host, reqbuf);
|
||||||
if(putresentry(HEADER, HttpNotFound, tstamp())
|
if (putresentry(HEADER, HttpNotFound, tstamp())
|
||||||
|| putresentry(CONTENTTYPE, texthtml))
|
|| putresentry(CONTENTTYPE, texthtml))
|
||||||
return;
|
return;
|
||||||
if(req.type == GET)
|
if (req.type == GET)
|
||||||
writetext("\r\n<html><body>404 Not Found</body></html>\r\n");
|
writetext("\r\n<html><body>404 Not Found</body></html>\r\n");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
/* check if modified */
|
/* check if modified */
|
||||||
t = st.st_mtim.tv_sec;
|
t = st.st_mtim.tv_sec;
|
||||||
memcpy(mod, asctime(gmtime(&t)), 24);
|
memcpy(mod, asctime(gmtime(&t)), 24);
|
||||||
mod[24] = 0;
|
mod[24] = 0;
|
||||||
if(!strcmp(reqmod, mod) && !putresentry(HEADER, HttpNotModified, tstamp())) {
|
if (!strcmp(reqmod, mod) && !putresentry(HEADER, HttpNotModified, tstamp())) {
|
||||||
/* not modified, we're done here*/
|
/* not modified, we're done here*/
|
||||||
} else {
|
} else {
|
||||||
/* determine mime-type */
|
/* determine mime-type */
|
||||||
if((p = strrchr(reqbuf, '.'))) {
|
if ((p = strrchr(reqbuf, '.'))) {
|
||||||
p++;
|
p++;
|
||||||
for(i = 0; i < LENGTH(servermimes); i++)
|
for (i = 0; i < LENGTH(servermimes); i++)
|
||||||
if(!strcmp(servermimes[i].extension, p)) {
|
if (!strcmp(servermimes[i].extension, p)) {
|
||||||
mimetype = servermimes[i].mimetype;
|
mimetype = servermimes[i].mimetype;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* serve file */
|
/* serve file */
|
||||||
if(putresentry(HEADER, HttpOk, tstamp())
|
if (putresentry(HEADER, HttpOk, tstamp())
|
||||||
|| putresentry(MODIFIED, mod)
|
|| putresentry(MODIFIED, mod)
|
||||||
|| putresentry(CONTENTLEN, st.st_size)
|
|| putresentry(CONTENTLEN, st.st_size)
|
||||||
|| putresentry(CONTENTTYPE, mimetype))
|
|| putresentry(CONTENTTYPE, mimetype))
|
||||||
return;
|
return;
|
||||||
if(req.type == GET && !writetext("\r\n"))
|
if (req.type == GET && !writetext("\r\n"))
|
||||||
responsefiledata(ffd, st.st_size);
|
responsefiledata(ffd, st.st_size);
|
||||||
}
|
}
|
||||||
close(ffd);
|
close(ffd);
|
||||||
|
@ -232,22 +229,22 @@ void
|
||||||
responsedirdata(DIR *d) {
|
responsedirdata(DIR *d) {
|
||||||
struct dirent *e;
|
struct dirent *e;
|
||||||
|
|
||||||
if(putresentry(HEADER, HttpOk, tstamp())
|
if (putresentry(HEADER, HttpOk, tstamp())
|
||||||
|| putresentry(CONTENTTYPE, texthtml))
|
|| putresentry(CONTENTTYPE, texthtml))
|
||||||
return;
|
return;
|
||||||
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))) {
|
while ((e = readdir(d))) {
|
||||||
if(e->d_name[0] == '.') /* ignore hidden files, ., .. */
|
if (e->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->d_name, e->d_name) >= MAXBUFLEN)
|
||||||
{
|
{
|
||||||
logerrmsg("snprintf failed, buffer sizeof exceeded");
|
logerrmsg("snprintf failed, buffer sizeof exceeded");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(writetext(resbuf))
|
if (writetext(resbuf))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
writetext("</body></html>\r\n");
|
writetext("</body></html>\r\n");
|
||||||
|
@ -259,32 +256,32 @@ responsedir(void) {
|
||||||
ssize_t len = strlen(reqbuf);
|
ssize_t len = strlen(reqbuf);
|
||||||
DIR *d;
|
DIR *d;
|
||||||
|
|
||||||
if((reqbuf[len - 1] != '/') && (len + 1 < MAXBUFLEN)) {
|
if ((reqbuf[len - 1] != '/') && (len + 1 < MAXBUFLEN)) {
|
||||||
/* add directory terminator if necessary */
|
/* add directory terminator if necessary */
|
||||||
reqbuf[len++] = '/';
|
reqbuf[len++] = '/';
|
||||||
reqbuf[len] = 0;
|
reqbuf[len] = 0;
|
||||||
logmsg("redirecting %s to %s%s\n", host, location, reqbuf);
|
logmsg("redirecting %s to %s%s\n", host, location, reqbuf);
|
||||||
if(putresentry(HEADER, HttpMoved, tstamp())
|
if (putresentry(HEADER, HttpMoved, tstamp())
|
||||||
|| putresentry(LOCATION, location, reqbuf)
|
|| putresentry(LOCATION, location, reqbuf)
|
||||||
|| putresentry(CONTENTTYPE, texthtml))
|
|| putresentry(CONTENTTYPE, texthtml))
|
||||||
return;
|
return;
|
||||||
if(req.type == GET)
|
if (req.type == GET)
|
||||||
writetext("\r\n<html><body>301 Moved Permanently</a></body></html>\r\n");
|
writetext("\r\n<html><body>301 Moved Permanently</a></body></html>\r\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(len + strlen(docindex) + 1 < MAXBUFLEN)
|
if (len + strlen(docindex) + 1 < MAXBUFLEN)
|
||||||
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 ((d = opendir(reqbuf))) {
|
||||||
responsedirdata(d);
|
responsedirdata(d);
|
||||||
closedir(d);
|
closedir(d);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
logerrmsg("client %s requests %s but opendir failed: %s\n", host, reqbuf, strerror(errno));
|
logerrmsg("client %s requests %s but opendir failed: %s\n", host, reqbuf, strerror(errno));
|
||||||
}
|
}
|
||||||
else
|
} else {
|
||||||
responsefile(); /* docindex */
|
responsefile(); /* docindex */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -292,36 +289,35 @@ responsecgi(void) {
|
||||||
FILE *cgi;
|
FILE *cgi;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if(req.type == GET)
|
if (req.type == GET)
|
||||||
setenv("REQUEST_METHOD", "GET", 1);
|
setenv("REQUEST_METHOD", "GET", 1);
|
||||||
else if(req.type == HEAD)
|
else if (req.type == HEAD)
|
||||||
setenv("REQUEST_METHOD", "HEAD", 1);
|
setenv("REQUEST_METHOD", "HEAD", 1);
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
if(*reqhost)
|
if (*reqhost)
|
||||||
setenv("SERVER_NAME", reqhost, 1);
|
setenv("SERVER_NAME", reqhost, 1);
|
||||||
setenv("SCRIPT_NAME", cgi_script, 1);
|
setenv("SCRIPT_NAME", cgi_script, 1);
|
||||||
setenv("REQUEST_URI", reqbuf, 1);
|
setenv("REQUEST_URI", reqbuf, 1);
|
||||||
logmsg("CGI SERVER_NAME=%s SCRIPT_NAME=%s REQUEST_URI=%s\n", reqhost, cgi_script, reqbuf);
|
logmsg("CGI SERVER_NAME=%s SCRIPT_NAME=%s REQUEST_URI=%s\n", reqhost, cgi_script, reqbuf);
|
||||||
if(chdir(cgi_dir) == -1)
|
if (chdir(cgi_dir) == -1)
|
||||||
logerrmsg("chdir to cgi directory %s failed: %s\n", cgi_dir, strerror(errno));
|
logerrmsg("chdir to cgi directory %s failed: %s\n", cgi_dir, strerror(errno));
|
||||||
if((cgi = popen(cgi_script, "r"))) {
|
if ((cgi = popen(cgi_script, "r"))) {
|
||||||
if(putresentry(HEADER, HttpOk, tstamp()))
|
if (putresentry(HEADER, HttpOk, tstamp()))
|
||||||
return;
|
return;
|
||||||
while((r = fread(resbuf, 1, MAXBUFLEN, cgi)) > 0) {
|
while ((r = fread(resbuf, 1, MAXBUFLEN, cgi)) > 0) {
|
||||||
if(writedata(resbuf, r)) {
|
if (writedata(resbuf, r)) {
|
||||||
pclose(cgi);
|
pclose(cgi);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pclose(cgi);
|
pclose(cgi);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
logerrmsg("%s requests %s, but cannot run cgi script %s\n", host, cgi_script, reqbuf);
|
logerrmsg("%s requests %s, but cannot run cgi script %s\n", host, cgi_script, reqbuf);
|
||||||
if(putresentry(HEADER, HttpNotFound, tstamp())
|
if (putresentry(HEADER, HttpNotFound, tstamp())
|
||||||
|| putresentry(CONTENTTYPE, texthtml))
|
|| putresentry(CONTENTTYPE, texthtml))
|
||||||
return;
|
return;
|
||||||
if(req.type == GET)
|
if (req.type == GET)
|
||||||
writetext("\r\n<html><body>404 Not Found</body></html>\r\n");
|
writetext("\r\n<html><body>404 Not Found</body></html>\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,23 +327,21 @@ response(void) {
|
||||||
char *p;
|
char *p;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
for(p = reqbuf; *p; p++)
|
for (p = reqbuf; *p; p++)
|
||||||
if(*p == '\\' || (*p == '/' && *(p + 1) == '.')) { /* don't serve bogus or hidden files */
|
if (*p == '\\' || (*p == '/' && *(p + 1) == '.')) { /* don't serve bogus or hidden files */
|
||||||
logerrmsg("%s requests bogus or hidden file %s\n", host, reqbuf);
|
logerrmsg("%s requests bogus or hidden file %s\n", host, reqbuf);
|
||||||
if(putresentry(HEADER, HttpUnauthorized, tstamp())
|
if (putresentry(HEADER, HttpUnauthorized, tstamp())
|
||||||
|| putresentry(CONTENTTYPE, texthtml))
|
|| putresentry(CONTENTTYPE, texthtml))
|
||||||
;
|
|
||||||
else
|
|
||||||
return;
|
return;
|
||||||
if(req.type == GET)
|
if (req.type == GET)
|
||||||
writetext("\r\n<html><body>401 Unauthorized</body></html>\r\n");
|
writetext("\r\n<html><body>401 Unauthorized</body></html>\r\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
logmsg("%s requests: %s\n", host, reqbuf);
|
logmsg("%s requests: %s\n", host, reqbuf);
|
||||||
if(cgi_mode)
|
if (cgi_mode) {
|
||||||
responsecgi();
|
responsecgi();
|
||||||
else {
|
} else {
|
||||||
if(stat(reqbuf, &st) != -1 && S_ISDIR(st.st_mode))
|
if (stat(reqbuf, &st) != -1 && S_ISDIR(st.st_mode))
|
||||||
responsedir();
|
responsedir();
|
||||||
else
|
else
|
||||||
responsefile();
|
responsefile();
|
||||||
|
@ -358,14 +352,14 @@ int
|
||||||
getreqentry(char *name, char *target, size_t targetlen, char *breakchars) {
|
getreqentry(char *name, char *target, size_t targetlen, char *breakchars) {
|
||||||
char *p, *res;
|
char *p, *res;
|
||||||
|
|
||||||
if((res = strstr(reqbuf, name))) {
|
if ((res = strstr(reqbuf, name))) {
|
||||||
for(res = res + strlen(name); *res && (*res == ' ' || *res == '\t'); ++res);
|
for (res = res + strlen(name); *res && (*res == ' ' || *res == '\t'); ++res);
|
||||||
if(!*res)
|
if (!*res)
|
||||||
return 1;
|
return 1;
|
||||||
for(p = res; *p && !strchr(breakchars, *p); ++p);
|
for (p = res; *p && !strchr(breakchars, *p); ++p);
|
||||||
if(!*p)
|
if (!*p)
|
||||||
return 1;
|
return 1;
|
||||||
if((size_t)(p - res) >= targetlen)
|
if ((size_t)(p - res) >= targetlen)
|
||||||
return 1;
|
return 1;
|
||||||
memcpy(target, res, p - res);
|
memcpy(target, res, p - res);
|
||||||
target[p - res] = 0;
|
target[p - res] = 0;
|
||||||
|
@ -380,14 +374,14 @@ request(void) {
|
||||||
int r;
|
int r;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
|
|
||||||
/* read request into reqbuf */
|
/* read request into reqbuf (MAXBUFLEN byte of reqbuf is emergency 0 terminator */
|
||||||
for( ; r > 0 && offset < MAXBUFLEN && (!strstr(reqbuf, "\r\n") || !strstr(reqbuf, "\n")); ) {
|
for (; r > 0 && offset < MAXBUFLEN && (!strstr(reqbuf, "\r\n") || !strstr(reqbuf, "\n"));) {
|
||||||
if((r = read(req.fd, reqbuf + offset, MAXBUFLEN - offset)) == -1) {
|
if ((r = read(req.fd, reqbuf + offset, MAXBUFLEN - offset)) == -1) {
|
||||||
logerrmsg("read: %s\n", strerror(errno));
|
logerrmsg("read: %s\n", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
offset += r;
|
offset += r;
|
||||||
reqbuf[offset] = 0; /* MAXBUFLEN byte of reqbuf is emergency 0 terminator */
|
reqbuf[offset] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* extract host and mod */
|
/* extract host and mod */
|
||||||
|
@ -397,13 +391,13 @@ request(void) {
|
||||||
goto invalid_request;
|
goto invalid_request;
|
||||||
|
|
||||||
/* extract method */
|
/* extract method */
|
||||||
for(p = reqbuf; *p && *p != '\r' && *p != '\n'; p++);
|
for (p = reqbuf; *p && *p != '\r' && *p != '\n'; p++);
|
||||||
if(*p == '\r' || *p == '\n') {
|
if (*p == '\r' || *p == '\n') {
|
||||||
*p = 0;
|
*p = 0;
|
||||||
/* check command */
|
/* check command */
|
||||||
if(!strncmp(reqbuf, "GET ", 4) && reqbuf[4] == '/')
|
if (!strncmp(reqbuf, "GET ", 4) && reqbuf[4] == '/')
|
||||||
req.type = GET;
|
req.type = GET;
|
||||||
else if(!strncmp(reqbuf, "HEAD ", 5) && reqbuf[5] == '/')
|
else if (!strncmp(reqbuf, "HEAD ", 5) && reqbuf[5] == '/')
|
||||||
req.type = HEAD;
|
req.type = HEAD;
|
||||||
else
|
else
|
||||||
goto invalid_request;
|
goto invalid_request;
|
||||||
|
@ -412,11 +406,11 @@ request(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* determine path */
|
/* determine path */
|
||||||
for(res = reqbuf + req.type; *res && *(res + 1) == '/'; res++); /* strip '/' */
|
for (res = reqbuf + req.type; *res && *(res + 1) == '/'; res++); /* strip '/' */
|
||||||
if(!*res)
|
if (!*res)
|
||||||
goto invalid_request;
|
goto invalid_request;
|
||||||
for(p = res; *p && *p != ' ' && *p != '\t'; p++);
|
for (p = res; *p && *p != ' ' && *p != '\t'; p++);
|
||||||
if(!*p)
|
if (!*p)
|
||||||
goto invalid_request;
|
goto invalid_request;
|
||||||
*p = 0;
|
*p = 0;
|
||||||
memmove(reqbuf, res, (p - res) + 1);
|
memmove(reqbuf, res, (p - res) + 1);
|
||||||
|
@ -432,28 +426,29 @@ serve(int fd) {
|
||||||
socklen_t salen;
|
socklen_t salen;
|
||||||
struct sockaddr sa;
|
struct sockaddr sa;
|
||||||
|
|
||||||
while(running) {
|
while (running) {
|
||||||
salen = sizeof sa;
|
salen = sizeof sa;
|
||||||
if((req.fd = accept(fd, &sa, &salen)) == -1) {
|
if ((req.fd = accept(fd, &sa, &salen)) == -1) {
|
||||||
/* el cheapo socket release */
|
/* el cheapo socket release */
|
||||||
logerrmsg("cannot accept: %s, sleep a second...\n", strerror(errno));
|
logerrmsg("cannot accept: %s, sleep a second...\n", strerror(errno));
|
||||||
sleep(1);
|
sleep(1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
result = fork();
|
result = fork();
|
||||||
if(result == 0) {
|
if (result == 0) {
|
||||||
close(fd);
|
close(fd);
|
||||||
host[0] = 0;
|
host[0] = 0;
|
||||||
getnameinfo(&sa, salen, host, sizeof host, NULL, 0, NI_NOFQDN);
|
getnameinfo(&sa, salen, host, sizeof host, NULL, 0, NI_NOFQDN);
|
||||||
result = request();
|
result = request();
|
||||||
shutdown(req.fd, SHUT_RD);
|
shutdown(req.fd, SHUT_RD);
|
||||||
if(result == 0)
|
if (result == 0)
|
||||||
response();
|
response();
|
||||||
shutdown(req.fd, SHUT_WR);
|
shutdown(req.fd, SHUT_WR);
|
||||||
close(req.fd);
|
close(req.fd);
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
} else if (result == -1)
|
} else if (result == -1) {
|
||||||
logerrmsg("fork failed: %s\n", strerror(errno));
|
logerrmsg("fork failed: %s\n", strerror(errno));
|
||||||
|
}
|
||||||
close(req.fd);
|
close(req.fd);
|
||||||
}
|
}
|
||||||
logmsg("shutting down\n");
|
logmsg("shutting down\n");
|
||||||
|
@ -495,12 +490,10 @@ main(int argc, char *argv[]) {
|
||||||
} ARGEND;
|
} ARGEND;
|
||||||
|
|
||||||
/* sanity checks */
|
/* sanity checks */
|
||||||
if(user)
|
if (user && !(upwd = getpwnam(user)))
|
||||||
if(!(upwd = getpwnam(user)))
|
die("error: invalid user %s\n", user);
|
||||||
die("error: invalid user %s\n", user);
|
if (group && !(gpwd = getgrnam(group)))
|
||||||
if(group)
|
die("error: invalid group %s\n", group);
|
||||||
if(!(gpwd = getgrnam(group)))
|
|
||||||
die("error: invalid group %s\n", group);
|
|
||||||
|
|
||||||
signal(SIGCHLD, sighandler);
|
signal(SIGCHLD, sighandler);
|
||||||
signal(SIGHUP, sighandler);
|
signal(SIGHUP, sighandler);
|
||||||
|
@ -515,48 +508,46 @@ main(int argc, char *argv[]) {
|
||||||
hints.ai_family = AF_INET;
|
hints.ai_family = AF_INET;
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
hints.ai_flags = AI_PASSIVE;
|
hints.ai_flags = AI_PASSIVE;
|
||||||
if((i = getaddrinfo(servername, serverport, &hints, &ai)))
|
if ((i = getaddrinfo(servername, serverport, &hints, &ai)))
|
||||||
die("error: getaddrinfo: %s\n", gai_strerror(i));
|
die("error: getaddrinfo: %s\n", gai_strerror(i));
|
||||||
if((fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) == -1) {
|
if ((fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) == -1) {
|
||||||
freeaddrinfo(ai);
|
freeaddrinfo(ai);
|
||||||
die("error: socket: %s\n", strerror(errno));
|
die("error: socket: %s\n", strerror(errno));
|
||||||
}
|
}
|
||||||
if(bind(fd, ai->ai_addr, ai->ai_addrlen) == -1) {
|
if (bind(fd, ai->ai_addr, ai->ai_addrlen) == -1) {
|
||||||
close(fd);
|
close(fd);
|
||||||
freeaddrinfo(ai);
|
freeaddrinfo(ai);
|
||||||
die("error: bind: %s\n", strerror(errno));
|
die("error: bind: %s\n", strerror(errno));
|
||||||
}
|
}
|
||||||
if(listen(fd, SOMAXCONN) == -1) {
|
if (listen(fd, SOMAXCONN) == -1) {
|
||||||
close(fd);
|
close(fd);
|
||||||
freeaddrinfo(ai);
|
freeaddrinfo(ai);
|
||||||
die("error: listen: %s\n", strerror(errno));
|
die("error: listen: %s\n", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!strcmp(serverport, "80"))
|
if (!strcmp(serverport, "80"))
|
||||||
i = snprintf(location, sizeof location, "http://%s", servername);
|
i = snprintf(location, sizeof location, "http://%s", servername);
|
||||||
else
|
else
|
||||||
i = snprintf(location, sizeof location, "http://%s:%s", servername, serverport);
|
i = snprintf(location, sizeof location, "http://%s:%s", servername, serverport);
|
||||||
if(i >= sizeof location) {
|
if (i >= sizeof location) {
|
||||||
close(fd);
|
close(fd);
|
||||||
freeaddrinfo(ai);
|
freeaddrinfo(ai);
|
||||||
die("error: location too long\n");
|
die("error: location too long\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(chdir(docroot) == -1)
|
if (chdir(docroot) == -1)
|
||||||
die("error: chdir %s: %s\n", docroot, strerror(errno));
|
die("error: chdir %s: %s\n", docroot, strerror(errno));
|
||||||
if(chroot(".") == -1)
|
if (chroot(".") == -1)
|
||||||
die("error: chroot .: %s\n", strerror(errno));
|
die("error: chroot .: %s\n", strerror(errno));
|
||||||
|
|
||||||
if(gpwd)
|
if (gpwd && setgid(gpwd->gr_gid) == -1)
|
||||||
if(setgid(gpwd->gr_gid) == -1)
|
die("error: cannot set group id\n");
|
||||||
die("error: cannot set group id\n");
|
if (upwd && setuid(upwd->pw_uid) == -1)
|
||||||
if(upwd)
|
die("error: cannot set user id\n");
|
||||||
if(setuid(upwd->pw_uid) == -1)
|
|
||||||
die("error: cannot set user id\n");
|
|
||||||
|
|
||||||
if(getuid() == 0)
|
if (getuid() == 0)
|
||||||
die("error: won't run with root permissions, choose another user\n");
|
die("error: won't run with root permissions, choose another user\n");
|
||||||
if(getgid() == 0)
|
if (getgid() == 0)
|
||||||
die("error: won't run with root permissions, choose another group\n");
|
die("error: won't run with root permissions, choose another group\n");
|
||||||
|
|
||||||
logmsg("listening on %s:%s using %s as root directory\n", servername, serverport, docroot);
|
logmsg("listening on %s:%s using %s as root directory\n", servername, serverport, docroot);
|
||||||
|
|
Loading…
Reference in a new issue