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;
|
||||
}
|
||||
|
||||
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,
|
||||
size_t bufsize)
|
||||
{
|
||||
@ -162,8 +152,10 @@ int main(int argc, char *argv[])
|
||||
struct sockaddr_in6 paddr;
|
||||
socklen_t paddr_size = sizeof(paddr);
|
||||
int cfd;
|
||||
ssize_t n, slen;
|
||||
ssize_t n, slen, rlen;
|
||||
while (!exit_requested) {
|
||||
n = slen = rlen = 0;
|
||||
|
||||
/*
|
||||
* Accept incoming connection.
|
||||
*
|
||||
@ -283,7 +275,6 @@ int main(int argc, char *argv[])
|
||||
* endings is done with a buffered reading approach to
|
||||
* minimize syscalls (as opposed to using fgetc()).
|
||||
*/
|
||||
unsigned rpos = 0;
|
||||
while (true) {
|
||||
/* Fill fbuf from file. */
|
||||
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. */
|
||||
for (unsigned fpos = 0; fpos < n; ++fpos) {
|
||||
if (fbuf[fpos] == '\n') {
|
||||
if (RBUF_SIZE - rpos < 2) {
|
||||
if (RBUF_SIZE - rlen < 2) {
|
||||
fprintf(stderr, "Response buffer is too small");
|
||||
goto close_client_socket;
|
||||
}
|
||||
rbuf[rpos++] = '\r';
|
||||
rbuf[rpos++] = '\n';
|
||||
rbuf[rlen++] = '\r';
|
||||
rbuf[rlen++] = '\n';
|
||||
} else {
|
||||
if (RBUF_SIZE - rpos < 1) {
|
||||
if (RBUF_SIZE - rlen < 1) {
|
||||
fprintf(stderr, "Response buffer is too small");
|
||||
goto close_client_socket;
|
||||
}
|
||||
rbuf[rpos++] = fbuf[fpos];
|
||||
rbuf[rlen++] = fbuf[fpos];
|
||||
}
|
||||
}
|
||||
|
||||
if (feof(rf))
|
||||
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)) {
|
||||
/*
|
||||
* Open the directory.
|
||||
@ -390,24 +367,16 @@ int main(int argc, char *argv[])
|
||||
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,
|
||||
ent->d_name, &pbuf[srvroot_len], HOST, PORT);
|
||||
if (n >= RBUF_SIZE) {
|
||||
fprintf(stderr,
|
||||
"Response buffer was too small, skipping entry\n");
|
||||
continue;
|
||||
n = snprintf(&rbuf[rlen], RBUF_SIZE - rlen,
|
||||
"%1u%s\t%s\t%s\t%u\r\n", type, ent->d_name,
|
||||
&pbuf[srvroot_len], HOST, PORT);
|
||||
if (n >= RBUF_SIZE - rlen) {
|
||||
fprintf(stderr, "Response buffer was too small\n");
|
||||
goto close_client_socket;
|
||||
}
|
||||
if (retrying_write(cfd, rbuf, n) != 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;
|
||||
rlen += n;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -422,6 +391,24 @@ int main(int argc, char *argv[])
|
||||
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(cfd);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user