diff options
Diffstat (limited to 'hw4/cgiprog/file_reader.c')
-rw-r--r-- | hw4/cgiprog/file_reader.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/hw4/cgiprog/file_reader.c b/hw4/cgiprog/file_reader.c new file mode 100644 index 0000000..dec8b30 --- /dev/null +++ b/hw4/cgiprog/file_reader.c @@ -0,0 +1,71 @@ +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define NL "\015\012" + +int main (int argc, char* argv[]) { + char* qs = getenv ("QUERY_STRING"); + if (qs == NULL || *qs == '\0') { + fputs ( + "HTTP/1.1 400 Bad Request" NL + "Content-Type: text/html" NL NL + "<html><head><title>400 Bad Request</title></head>" NL + "<body><p>Query string is missing</p>" + "</body></html>" NL, stdout); + return 1; + } + + if (strncmp (qs, "filename=", 9)) { + fputs ( + "HTTP/1.1 400 Bad Request" NL + "Content-Type: text/html" NL NL + "<html><head><title>400 Bad Request</title></head>" NL + "<body><p>Query string is not valid</p>" + "</body></html>" NL, stdout); + return 1; + } + + char* fn = qs + 9; + int fd = open (fn, O_RDONLY); + if (fd < 0) { + switch (errno) { + case ENOENT: + printf ( + "HTTP/1.1 404 Not Found" NL + "Content-Type: text/html" NL NL + "<html><head><title>404 Not Found</title></head>" NL + "<body><p>File `%s\' cannot be found on the system</p>" NL + "</body></html>" NL, fn); + return 2; + case EACCES: + printf ( + "HTTP/1.1 403 Forbidden" NL + "Content-Type: text/html" NL NL + "<html><head><title>403 Forbidden</title></head>" NL + "<body><p>Access to `%s\' is denied</p>" NL + "</body></html>" NL, fn); + return 3; + default: + printf ( + "HTTP/1.1 500 Internal Server Error" NL + "Content-Type: text/html" NL NL + "<html><head><title>500 Internal Server Error</title></head>" NL + "<body><p>%s</p>" NL + "</body></html>" NL, strerror (errno)); + return 4; + } + } + + fputs ("Content-Type: application/octet-stream" NL NL, stdout); + fflush (stdout); + + char buf[4096]; + ssize_t r; + for (; (r = read (fd, buf, 4096)) > 0; write (1, buf, r)); + + return 0; +} |