#include "common.h" #include "proc.h" #include #include #include #include #include #include #include #include #include #include bool procconn(server* svr, request* requestP, int maxfd){ int ret; struct sockaddr_in cliaddr; // used by accept() int clilen; int conn_fd; // fd for a new connection with client int file_fd; // fd for file that we open for reading // TODO: Add IO multiplexing // Check new connection clilen = sizeof(cliaddr); conn_fd = accept(svr->listen_fd, (struct sockaddr*)&cliaddr, (socklen_t*)&clilen); if (conn_fd < 0) { if (errno == EINTR || errno == EAGAIN) return true; // try again if (errno == ENFILE) { (void) fprintf(stderr, "out of file descriptor table ... (maxconn %d)\n", maxfd); return false; } e_err_exit("accept"); } requestP[conn_fd].conn_fd = conn_fd; strcpy(requestP[conn_fd].host, inet_ntoa(cliaddr.sin_addr)); fprintf(stderr, "getting a new request... fd %d from %s\n", conn_fd, requestP[conn_fd].host); file_fd = -1; do { ret = request_read(&requestP[conn_fd]); if (ret < 0) { fprintf(stderr, "bad request from %s\n", requestP[conn_fd].host); continue; } // requestP[conn_fd]->filename is guaranteed to be successfully set. if (file_fd == -1) { // open the file here. fprintf(stderr, "Opening file [%s]\n", requestP[conn_fd].filename); // TODO: Add lock // TODO: check if the request should be rejected. write(requestP[conn_fd].conn_fd, svr->accept_hdr, SVR_ACCEPT_HDR_LEN); file_fd = open(requestP[conn_fd].filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); } if (ret == 0) break; write(file_fd, requestP[conn_fd].buf, requestP[conn_fd].buf_len); } while (ret > 0); fprintf(stderr, "Done writing file [%s]\n", requestP[conn_fd].filename); if (file_fd >= 0) close(file_fd); close(requestP[conn_fd].conn_fd); request_free(&requestP[conn_fd], NULL); return true; }