--- orig.c	2001-04-21 19:13:13.000000000 -0500
+++ httpd.c	2014-10-04 23:22:58.512296668 -0400
@@ -4,17 +4,14 @@
  * CSE 4344 (Network concepts), Prof. Zeigler
  * University of Texas at Arlington
  */
-/* This program compiles for Sparc Solaris 2.6.
- * To compile for Linux:
- *  1) Comment out the #include <pthread.h> line.
- *  2) Comment out the line that defines the variable newthread.
- *  3) Comment out the two lines that run pthread_create().
- *  4) Uncomment the line that runs accept_request().
- *  5) Remove -lsocket from the Makefile.
- */
+/* PTHREAD only works on Sparc Solaris 2.6 */
+#define PTHREAD 0
+/* the CGI implementation doesn't seem to work and I don't have the
+ * patience to mess with it. */
+#define CGI 0
 #include <stdio.h>
-#include <sys/socket.h>
 #include <sys/types.h>
+#include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <unistd.h>
@@ -22,33 +19,35 @@
 #include <strings.h>
 #include <string.h>
 #include <sys/stat.h>
+#if PTHREAD
 #include <pthread.h>
+#endif
 #include <sys/wait.h>
 #include <stdlib.h>
 
 #define ISspace(x) isspace((int)(x))
 
-#define SERVER_STRING "Server: jdbhttpd/0.1.0\r\n"
+#define SERVER_STRING "Server: jdbhttpd-11/0.1.0\r\n"
 
-void accept_request(int);
-void bad_request(int);
-void cat(int, FILE *);
-void cannot_execute(int);
-void error_die(const char *);
-void execute_cgi(int, const char *, const char *, const char *);
-int get_line(int, char *, int);
-void headers(int, const char *);
-void not_found(int);
-void serve_file(int, const char *);
-int startup(u_short *);
-void unimplemented(int);
+void accept_request();
+void bad_request();
+void cat();
+void cannot_execute();
+void error_die();
+void execute_cgi();
+int get_line();
+void headers();
+void not_found();
+void serve_file();
+int startup();
+void unimplemented();
 
 /**********************************************************************/
 /* A request has caused a call to accept() on the server port to
  * return.  Process the request appropriately.
  * Parameters: the socket connected to the client */
 /**********************************************************************/
-void accept_request(int client)
+void accept_request(client)
 {
  char buf[1024];
  int numchars;
@@ -73,11 +72,21 @@
  if (strcasecmp(method, "GET") && strcasecmp(method, "POST"))
  {
   unimplemented(client);
+  close(client);
   return;
  }
 
- if (strcasecmp(method, "POST") == 0)
+ if (strcasecmp(method, "POST") == 0) {
+#if CGI
   cgi = 1;
+#else
+  unimplemented(client);
+  close(client);
+  /* XXX closing on a POST causes some browsers to report a connection
+   * reset error. */
+  return;
+#endif
+ }
 
  i = 0;
  while (ISspace(buf[j]) && (j < sizeof(buf)))
@@ -118,7 +127,7 @@
       (st.st_mode & S_IXGRP) ||
       (st.st_mode & S_IXOTH)    )
    cgi = 1;
-  if (!cgi)
+  if (!CGI || !cgi)
    serve_file(client, path);
   else
    execute_cgi(client, path, method, query_string);
@@ -127,24 +136,21 @@
  close(client);
 }
 
+#define SEND_LITERAL(client, buf) send(client, buf, sizeof (buf) - 1, 0)
+
 /**********************************************************************/
 /* Inform the client that a request it has made has a problem.
  * Parameters: client socket */
 /**********************************************************************/
-void bad_request(int client)
+void bad_request(client)
 {
  char buf[1024];
 
- sprintf(buf, "HTTP/1.0 400 BAD REQUEST\r\n");
- send(client, buf, sizeof(buf), 0);
- sprintf(buf, "Content-type: text/html\r\n");
- send(client, buf, sizeof(buf), 0);
- sprintf(buf, "\r\n");
- send(client, buf, sizeof(buf), 0);
- sprintf(buf, "<P>Your browser sent a bad request, ");
- send(client, buf, sizeof(buf), 0);
- sprintf(buf, "such as a POST without a Content-Length.\r\n");
- send(client, buf, sizeof(buf), 0);
+ SEND_LITERAL(client, "HTTP/1.0 400 BAD REQUEST\r\n");
+ SEND_LITERAL(client, "Content-type: text/html\r\n");
+ SEND_LITERAL(client, "\r\n");
+ SEND_LITERAL(client, "<P>Your browser sent a bad request, ");
+ SEND_LITERAL(client, "such as a POST without a Content-Length.\r\n");
 }
 
 /**********************************************************************/
@@ -154,7 +160,8 @@
  * Parameters: the client socket descriptor
  *             FILE pointer for the file to cat */
 /**********************************************************************/
-void cat(int client, FILE *resource)
+void cat(client, resource)
+	FILE *resource;
 {
  char buf[1024];
 
@@ -170,18 +177,14 @@
 /* Inform the client that a CGI script could not be executed.
  * Parameter: the client socket descriptor. */
 /**********************************************************************/
-void cannot_execute(int client)
+void cannot_execute(client)
 {
  char buf[1024];
 
- sprintf(buf, "HTTP/1.0 500 Internal Server Error\r\n");
- send(client, buf, strlen(buf), 0);
- sprintf(buf, "Content-type: text/html\r\n");
- send(client, buf, strlen(buf), 0);
- sprintf(buf, "\r\n");
- send(client, buf, strlen(buf), 0);
- sprintf(buf, "<P>Error prohibited CGI execution.\r\n");
- send(client, buf, strlen(buf), 0);
+ SEND_LITERAL(client, "HTTP/1.0 500 Internal Server Error\r\n");
+ SEND_LITERAL(client, "Content-type: text/html\r\n");
+ SEND_LITERAL(client, "\r\n");
+ SEND_LITERAL(client, "<P>Error prohibited CGI execution.\r\n");
 }
 
 /**********************************************************************/
@@ -189,7 +192,8 @@
  * on value of errno, which indicates system call errors) and exit the
  * program indicating an error. */
 /**********************************************************************/
-void error_die(const char *sc)
+void error_die(sc)
+	char *sc;
 {
  perror(sc);
  exit(1);
@@ -201,9 +205,10 @@
  * Parameters: client socket descriptor
  *             path to the CGI script */
 /**********************************************************************/
-void execute_cgi(int client, const char *path,
-                 const char *method, const char *query_string)
+void execute_cgi(client, path, method, query_string)
+	char *path, *method, *query_string;
 {
+#if CGI
  char buf[1024];
  int cgi_output[2];
  int cgi_input[2];
@@ -234,8 +239,7 @@
   }
  }
 
- sprintf(buf, "HTTP/1.0 200 OK\r\n");
- send(client, buf, strlen(buf), 0);
+ SEND_LITERAL(client, "HTTP/1.0 200 OK\r\n");
 
  if (pipe(cgi_output) < 0) {
   cannot_execute(client);
@@ -287,6 +291,9 @@
   close(cgi_input[1]);
   waitpid(pid, &status, 0);
  }
+#else
+ unimplemented(client);
+#endif
 }
 
 /**********************************************************************/
@@ -302,7 +309,8 @@
  *             the size of the buffer
  * Returns: the number of bytes stored (excluding null) */
 /**********************************************************************/
-int get_line(int sock, char *buf, int size)
+int get_line(sock, buf, size)
+	char *buf;
 {
  int i = 0;
  char c = '\0';
@@ -339,46 +347,34 @@
 /* Parameters: the socket to print the headers on
  *             the name of the file */
 /**********************************************************************/
-void headers(int client, const char *filename)
+void headers(client, filename)
+	char *filename;
 {
  char buf[1024];
  (void)filename;  /* could use filename to determine file type */
 
- strcpy(buf, "HTTP/1.0 200 OK\r\n");
- send(client, buf, strlen(buf), 0);
- strcpy(buf, SERVER_STRING);
- send(client, buf, strlen(buf), 0);
- sprintf(buf, "Content-Type: text/html\r\n");
- send(client, buf, strlen(buf), 0);
- strcpy(buf, "\r\n");
- send(client, buf, strlen(buf), 0);
+ SEND_LITERAL(client, "HTTP/1.0 200 OK\r\n");
+ SEND_LITERAL(client, SERVER_STRING);
+ SEND_LITERAL(client, "Content-Type: text/html\r\n");
+ SEND_LITERAL(client, "\r\n");
 }
 
 /**********************************************************************/
 /* Give a client a 404 not found status message. */
 /**********************************************************************/
-void not_found(int client)
+void not_found(client)
 {
  char buf[1024];
 
- sprintf(buf, "HTTP/1.0 404 NOT FOUND\r\n");
- send(client, buf, strlen(buf), 0);
- sprintf(buf, SERVER_STRING);
- send(client, buf, strlen(buf), 0);
- sprintf(buf, "Content-Type: text/html\r\n");
- send(client, buf, strlen(buf), 0);
- sprintf(buf, "\r\n");
- send(client, buf, strlen(buf), 0);
- sprintf(buf, "<HTML><TITLE>Not Found</TITLE>\r\n");
- send(client, buf, strlen(buf), 0);
- sprintf(buf, "<BODY><P>The server could not fulfill\r\n");
- send(client, buf, strlen(buf), 0);
- sprintf(buf, "your request because the resource specified\r\n");
- send(client, buf, strlen(buf), 0);
- sprintf(buf, "is unavailable or nonexistent.\r\n");
- send(client, buf, strlen(buf), 0);
- sprintf(buf, "</BODY></HTML>\r\n");
- send(client, buf, strlen(buf), 0);
+ SEND_LITERAL(client, "HTTP/1.0 404 NOT FOUND\r\n");
+ SEND_LITERAL(client, SERVER_STRING);
+ SEND_LITERAL(client, "Content-Type: text/html\r\n");
+ SEND_LITERAL(client, "\r\n");
+ SEND_LITERAL(client, "<HTML><TITLE>Not Found</TITLE>\r\n");
+ SEND_LITERAL(client, "<BODY><P>The server could not fulfill\r\n");
+ SEND_LITERAL(client, "your request because the resource specified\r\n");
+ SEND_LITERAL(client, "is unavailable or nonexistent.\r\n");
+ SEND_LITERAL(client, "</BODY></HTML>\r\n");
 }
 
 /**********************************************************************/
@@ -388,7 +384,8 @@
  *              file descriptor
  *             the name of the file to serve */
 /**********************************************************************/
-void serve_file(int client, const char *filename)
+void serve_file(client, filename)
+	char *filename;
 {
  FILE *resource = NULL;
  int numchars = 1;
@@ -417,7 +414,8 @@
  * Parameters: pointer to variable containing the port to connect on
  * Returns: the socket */
 /**********************************************************************/
-int startup(u_short *port)
+int startup(port)
+	u_short *port;
 {
  int httpd = 0;
  struct sockaddr_in name;
@@ -448,38 +446,32 @@
  * implemented.
  * Parameter: the client socket */
 /**********************************************************************/
-void unimplemented(int client)
+void unimplemented(client)
 {
  char buf[1024];
 
- sprintf(buf, "HTTP/1.0 501 Method Not Implemented\r\n");
- send(client, buf, strlen(buf), 0);
- sprintf(buf, SERVER_STRING);
- send(client, buf, strlen(buf), 0);
- sprintf(buf, "Content-Type: text/html\r\n");
- send(client, buf, strlen(buf), 0);
- sprintf(buf, "\r\n");
- send(client, buf, strlen(buf), 0);
- sprintf(buf, "<HTML><HEAD><TITLE>Method Not Implemented\r\n");
- send(client, buf, strlen(buf), 0);
- sprintf(buf, "</TITLE></HEAD>\r\n");
- send(client, buf, strlen(buf), 0);
- sprintf(buf, "<BODY><P>HTTP request method not supported.\r\n");
- send(client, buf, strlen(buf), 0);
- sprintf(buf, "</BODY></HTML>\r\n");
- send(client, buf, strlen(buf), 0);
+ SEND_LITERAL(client, "HTTP/1.0 501 Method Not Implemented\r\n");
+ SEND_LITERAL(client, SERVER_STRING);
+ SEND_LITERAL(client, "Content-Type: text/html\r\n");
+ SEND_LITERAL(client, "\r\n");
+ SEND_LITERAL(client, "<HTML><HEAD><TITLE>Method Not Implemented\r\n");
+ SEND_LITERAL(client, "</TITLE></HEAD>\r\n");
+ SEND_LITERAL(client, "<BODY><P>HTTP request method not supported.\r\n");
+ SEND_LITERAL(client, "</BODY></HTML>\r\n");
 }
 
 /**********************************************************************/
 
-int main(void)
+int main()
 {
  int server_sock = -1;
  u_short port = 0;
  int client_sock = -1;
  struct sockaddr_in client_name;
  int client_name_len = sizeof(client_name);
+#if PTHREAD
  pthread_t newthread;
+#endif
 
  server_sock = startup(&port);
  printf("httpd running on port %d\n", port);
@@ -491,9 +483,12 @@
                        &client_name_len);
   if (client_sock == -1)
    error_die("accept");
- /* accept_request(client_sock); */
+#if PTHREAD
  if (pthread_create(&newthread , NULL, accept_request, client_sock) != 0)
    perror("pthread_create");
+#else
+ accept_request(client_sock);
+#endif
  }
 
  close(server_sock);
