Tolta opzione inutile dal web server e messa opzione per far andare bene
[gapil.git] / sources / wwwd.c
index 3379486e08a431d0e8febd3f003632e369120537..f144eb0bcaff90face8eb8a429a2c5ccddc52f3d 100644 (file)
@@ -57,6 +57,9 @@ void usage(void);
 void ServPage(int sockfd);
 void PrintErr(char * error);
 void print_headers(FILE *file);
+void print_err404(FILE *file, char *filename);
+void print_err400(FILE *file, char *string);
+void print_err500(FILE *file, char *string);
 
 /* Program beginning */
 int main(int argc, char *argv[])
@@ -65,8 +68,9 @@ int main(int argc, char *argv[])
  * Variables definition  
  */
     int list_fd, conn_fd;
-    int waiting = 0;
     int compat = 0;
+    int reroot = 0;
+    char * rootdir;
     pid_t pid;
     struct sockaddr_in cli_add;
     socklen_t len;
@@ -77,7 +81,7 @@ int main(int argc, char *argv[])
      */
     int i;
     opterr = 0;         /* don't want writing to stderr */
-    while ( (i = getopt(argc, argv, "hdicw:")) != -1) {
+    while ( (i = getopt(argc, argv, "hdicw:r:")) != -1) {
        switch (i) {
        /* 
         * Handling options 
@@ -96,8 +100,9 @@ int main(int argc, char *argv[])
        case 'd':
            debugging = 1;
            break;
-       case 'w':
-           waiting = strtol(optarg, NULL, 10);
+       case 'r':
+           reroot = 1;
+           rootdir = optarg;
            break;
        case '?':   /* unrecognized options */
            printf("Unrecognized options -%c\n",optopt);
@@ -123,6 +128,17 @@ int main(int argc, char *argv[])
     if ( (list_fd = sockbind2(argv[optind], "www", 6, SOCK_STREAM)) < 0) {
        return 1;
     }   
+    /* chroot if requested */
+    if (reroot) {
+       if (chdir(rootdir)) {
+           perror("Cannot find directory to chroot");
+           exit(1);
+       }
+       if (chroot(rootdir)) {
+           perror("Cannot chroot");
+           exit(1);
+       }
+    }
     /* release privileges and go daemon */
     if (setgid(65534) !=0) { /* first give away group privileges */
        perror("cannot give away group privileges");
@@ -144,7 +160,6 @@ int main(int argc, char *argv[])
        PrintErr("listen error");
        exit(1);
     }
-    if (waiting) sleep(waiting);
     /* handle echo to client */
     while (1) {
        /* accept connection */
@@ -215,7 +230,9 @@ void ServPage(int sockfd)
     char *methods[] = { "GET", "PUT", NULL };
     char *codes[] = {
        "200 OK",
+       "400 Bad Request",
        "404 Not Found",
+       "500 Internal Server Error",
        NULL
     };
     int nleft;
@@ -224,25 +241,30 @@ void ServPage(int sockfd)
     sock = fdopen(sockfd, "w+");
     /* main loop, reading 0 char means client close connection */
     line = fgets(buffer, MAXLINE, sock);
-    copy = strndupa(line, MAXLINE);
-
     if (line == NULL) {
        PrintErr("Errore in lettura");
        return;
     }
+    /* parsing first line, getting method and filename */
+    copy = strndupa(line, MAXLINE);
     if ((method = strtok_r(copy, " ", &ptr)) == NULL) {
-       PrintErr("Non ho trovato il metodo");
+       fprintf(sock, "HTTP/1.0 %s\n", codes[2]);
+       print_headers(sock);
+       print_err400(sock, line);
        return;
     }
     if ((filename = strtok_r(NULL, " ", &ptr)) == NULL) {
-       PrintErr("Non ho trovato il file");
+       fprintf(sock, "HTTP/1.0 %s\n", codes[2]);
+       print_headers(sock);
+       print_err400(sock, line);
        return;
     }
     if ((version = strtok_r(NULL, " ", &ptr)) == NULL) {
-       PrintErr("Non ho trovato la versione");
+       fprintf(sock, "HTTP/1.0 %s\n", codes[2]);
+       print_headers(sock);
+       print_err400(sock, line);
        return;
     }
-    printf("metodo %s -- file %s -- versione %s\n", method, filename, version);
     i = 0;
     while ( (ptr = methods[i]) != NULL) {
        if ( (strncmp(ptr, method, strlen(ptr)) == 0)) {
@@ -251,45 +273,46 @@ void ServPage(int sockfd)
        i++;
     }
     if (i>=2) {
-       printf("No method %s found\n", method);
+       fprintf(sock, "HTTP/1.0 %s\n", codes[2]);
+       print_headers(sock);
+       print_err400(sock, line);
        return;
     }
 
     while (strcmp(line,"\r\n")) {
-       line =  fgets(buffer, MAXLINE, sock);
-       printf("letto: %s\n", line);
+       line = fgets(buffer, MAXLINE, sock);
     }
 
     if ( (file = fopen(filename, "r")) == NULL) {
-       printf("file %s", filename);
-       perror("Error opening");
-       fprintf(sock, "HTTP/1.0 %s\n", codes[1]);
+       fprintf(sock, "HTTP/1.0 %s\n", codes[2]);
        print_headers(sock);
+       print_err404(sock, filename);
        return;
     }
     fprintf(sock, "HTTP/1.0 %s\n", codes[0]);
-    //PrintHeader(sock);
     print_headers(sock);
 
     j = 0;
     while (!feof(file)) {
-       printf("Loop %d\n", j++);
        if ( (nleft = full_fread(file, outbuf, 1024)) != 0) {
            if (ferror(file)) {
-               printf("Errore in lettura");
+               fprintf(sock, "HTTP/1.0 %s\n", codes[3]);
+               print_headers(sock);
+               snprintf(buffer, MAXLINE, "reading %s", filename);
+               print_err500(sock, buffer);
                return;
            }
        }
-       printf("Loop %d rimasti %d\n", j, nleft);
        if (full_fwrite(sock, outbuf, 1024-nleft) != 0) {
            if (ferror(file)) {
-               printf("Errore in scrittura");
+               fprintf(sock, "HTTP/1.0 %s\n", codes[3]);
+               print_headers(sock);
+               snprintf(buffer, MAXLINE, "writing");
+               print_err500(sock, buffer);
                return;
            }   
        }
     }
-    printf("Ok fin qui!");
-//    line = fgets(buffer, MAXLINE, sock);
     fclose(file);
     fclose(sock);
     return;
@@ -317,10 +340,36 @@ void print_headers(FILE *file)
     fprintf(file, "Connection: close\n");
     fprintf(file, "Content-Type: text/html; charset=iso-8859-1\n");
     fprintf(file, "\n");
-    printf("Date: %s", ctime(&tempo));
-    printf("Server: WWWd test server\n");
-    printf("Connection: close\n");
-    printf("Content-Type: text/html; charset=iso-8859-1\n");
-    printf("\n");
+    return;
+}
+
+void print_err404(FILE *file, char *filename)
+{
+    fprintf(file, "<HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD>\n");
+    fprintf(file, "<BODY><H1>Not Found</H1>\nThe requested ");
+    fprintf(file, "URL %s was not found on this server.<P><HR>", filename);
+    fprintf(file, "<ADDRESS>WWWd by Simone Piccardi</ADDRESS></BODY></HTML>");
+    return;
+}
+
+void print_err400(FILE *file, char *string)
+{
+    fprintf(file, "<HTML><HEAD><TITLE>404 Bad Request</TITLE></HEAD>\n");
+    fprintf(file, "<BODY><H1>Bad Request</H1>\n ");
+    fprintf(file, "Your browser sent a request that this server could not ");
+    fprintf(file, "understand.<P>The request line<P> %s <P>", string);
+    fprintf(file, "is invalid following the protocol<p><HR>");
+    fprintf(file, "<ADDRESS>WWWd by Simone Piccardi </ADDRESS></BODY></HTML>");
+    return;
+}
+
+
+void print_err500(FILE *file, char *string)
+{
+    fprintf(file, "<HTML><HEAD><TITLE>500 Internal Server Error</TITLE>\n");
+    fprintf(file, "</HEAD><BODY><H1>Internal Server Error</H1>\n ");
+    fprintf(file, "We got an error processing your request.<P>");
+    fprintf(file, "Error is: %s <P><HR>\n", string);
+    fprintf(file, "<ADDRESS>WWWd by Simone Piccardi </ADDRESS></BODY></HTML>");
     return;
 }