summaryrefslogtreecommitdiffstats
path: root/hw4/cgiprog/file_reader.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw4/cgiprog/file_reader.c')
-rw-r--r--hw4/cgiprog/file_reader.c71
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;
+}