Terminate and send response outside of file/dir branch
This commit is contained in:
parent
120a97189f
commit
58c7b6feab
81
main.c
81
main.c
@ -56,16 +56,6 @@ void handle_exit_signal(int signum)
|
|||||||
exit_requested = true;
|
exit_requested = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int retrying_write(int fd, const char *buf, size_t len)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
do {
|
|
||||||
errno = 0;
|
|
||||||
n = write(fd, buf, len);
|
|
||||||
} while (errno == EINTR);
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int append_selector_part(const char *part, size_t partlen, char *buf,
|
static int append_selector_part(const char *part, size_t partlen, char *buf,
|
||||||
size_t bufsize)
|
size_t bufsize)
|
||||||
{
|
{
|
||||||
@ -162,8 +152,10 @@ int main(int argc, char *argv[])
|
|||||||
struct sockaddr_in6 paddr;
|
struct sockaddr_in6 paddr;
|
||||||
socklen_t paddr_size = sizeof(paddr);
|
socklen_t paddr_size = sizeof(paddr);
|
||||||
int cfd;
|
int cfd;
|
||||||
ssize_t n, slen;
|
ssize_t n, slen, rlen;
|
||||||
while (!exit_requested) {
|
while (!exit_requested) {
|
||||||
|
n = slen = rlen = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Accept incoming connection.
|
* Accept incoming connection.
|
||||||
*
|
*
|
||||||
@ -283,7 +275,6 @@ int main(int argc, char *argv[])
|
|||||||
* endings is done with a buffered reading approach to
|
* endings is done with a buffered reading approach to
|
||||||
* minimize syscalls (as opposed to using fgetc()).
|
* minimize syscalls (as opposed to using fgetc()).
|
||||||
*/
|
*/
|
||||||
unsigned rpos = 0;
|
|
||||||
while (true) {
|
while (true) {
|
||||||
/* Fill fbuf from file. */
|
/* Fill fbuf from file. */
|
||||||
n = fread(fbuf, sizeof(*fbuf), FBUF_SIZE, rf);
|
n = fread(fbuf, sizeof(*fbuf), FBUF_SIZE, rf);
|
||||||
@ -295,38 +286,24 @@ int main(int argc, char *argv[])
|
|||||||
/* Copy from fbuf to rbuf, replacing LF with CRLF. */
|
/* Copy from fbuf to rbuf, replacing LF with CRLF. */
|
||||||
for (unsigned fpos = 0; fpos < n; ++fpos) {
|
for (unsigned fpos = 0; fpos < n; ++fpos) {
|
||||||
if (fbuf[fpos] == '\n') {
|
if (fbuf[fpos] == '\n') {
|
||||||
if (RBUF_SIZE - rpos < 2) {
|
if (RBUF_SIZE - rlen < 2) {
|
||||||
fprintf(stderr, "Response buffer is too small");
|
fprintf(stderr, "Response buffer is too small");
|
||||||
goto close_client_socket;
|
goto close_client_socket;
|
||||||
}
|
}
|
||||||
rbuf[rpos++] = '\r';
|
rbuf[rlen++] = '\r';
|
||||||
rbuf[rpos++] = '\n';
|
rbuf[rlen++] = '\n';
|
||||||
} else {
|
} else {
|
||||||
if (RBUF_SIZE - rpos < 1) {
|
if (RBUF_SIZE - rlen < 1) {
|
||||||
fprintf(stderr, "Response buffer is too small");
|
fprintf(stderr, "Response buffer is too small");
|
||||||
goto close_client_socket;
|
goto close_client_socket;
|
||||||
}
|
}
|
||||||
rbuf[rpos++] = fbuf[fpos];
|
rbuf[rlen++] = fbuf[fpos];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (feof(rf))
|
if (feof(rf))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Terminate and send the response.
|
|
||||||
*/
|
|
||||||
if (RBUF_SIZE - rpos < RESP_TERM_LEN) {
|
|
||||||
fprintf(stderr, "Response buffer is too small");
|
|
||||||
goto close_client_socket;
|
|
||||||
}
|
|
||||||
memcpy(&rbuf[rpos], RESP_TERM, RESP_TERM_LEN);
|
|
||||||
rpos += RESP_TERM_LEN;
|
|
||||||
if (retrying_write(cfd, rbuf, rpos) == -1) {
|
|
||||||
fprintf(stderr, "Failed to write response to client\n");
|
|
||||||
goto close_client_socket;
|
|
||||||
}
|
|
||||||
} else if (S_ISDIR(rstat.st_mode)) {
|
} else if (S_ISDIR(rstat.st_mode)) {
|
||||||
/*
|
/*
|
||||||
* Open the directory.
|
* Open the directory.
|
||||||
@ -390,24 +367,16 @@ int main(int argc, char *argv[])
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Format and send response line for current entry.
|
* Format response line for current entry.
|
||||||
*/
|
*/
|
||||||
n = snprintf(rbuf, RBUF_SIZE, "%1u%s\t%s\t%s\t%u\r\n", type,
|
n = snprintf(&rbuf[rlen], RBUF_SIZE - rlen,
|
||||||
ent->d_name, &pbuf[srvroot_len], HOST, PORT);
|
"%1u%s\t%s\t%s\t%u\r\n", type, ent->d_name,
|
||||||
if (n >= RBUF_SIZE) {
|
&pbuf[srvroot_len], HOST, PORT);
|
||||||
fprintf(stderr,
|
if (n >= RBUF_SIZE - rlen) {
|
||||||
"Response buffer was too small, skipping entry\n");
|
fprintf(stderr, "Response buffer was too small\n");
|
||||||
continue;
|
goto close_client_socket;
|
||||||
}
|
}
|
||||||
if (retrying_write(cfd, rbuf, n) != n) {
|
rlen += n;
|
||||||
fprintf(stderr, "Error sending respose line to client\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (retrying_write(cfd, ".\r\n", 3) != 3) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Error sending response terminator to client\n");
|
|
||||||
goto close_client_socket;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -422,6 +391,24 @@ int main(int argc, char *argv[])
|
|||||||
goto close_client_socket;
|
goto close_client_socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Terminate and send the response.
|
||||||
|
*/
|
||||||
|
if (RBUF_SIZE - rlen < RESP_TERM_LEN) {
|
||||||
|
fprintf(stderr, "Response buffer is too small");
|
||||||
|
goto close_client_socket;
|
||||||
|
}
|
||||||
|
memcpy(&rbuf[rlen], RESP_TERM, RESP_TERM_LEN);
|
||||||
|
rlen += RESP_TERM_LEN;
|
||||||
|
do {
|
||||||
|
errno = 0;
|
||||||
|
n = write(cfd, rbuf, rlen);
|
||||||
|
} while (errno == EINTR);
|
||||||
|
if (n == -1) {
|
||||||
|
fprintf(stderr, "Failed to write response to client\n");
|
||||||
|
goto close_client_socket;
|
||||||
|
}
|
||||||
|
|
||||||
close_client_socket:
|
close_client_socket:
|
||||||
close(cfd);
|
close(cfd);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user