X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=sources%2Fwwwd.c;h=0b6dfde9a9be2ca3e0ba4d2dcf04ee149e530083;hp=9fceda5330c020cf5635f43f2a36bdb914e56b76;hb=fa15a3f1ecd64efd8440e46d398fd9976abc3d25;hpb=d5df702be171519375f3e260cffb7ee93ab656f4 diff --git a/sources/wwwd.c b/sources/wwwd.c index 9fceda5..0b6dfde 100644 --- a/sources/wwwd.c +++ b/sources/wwwd.c @@ -26,51 +26,57 @@ * * Usage: wwwd -h give all info * - * $Id$ - * ****************************************************************/ /* * Include needed headers */ #define _GNU_SOURCE -#include /* error strings */ -#include /* predefined types */ -#include /* include unix standard library */ -#include /* IP addresses conversion utiliites */ -#include /* socket library */ -#include /* include standard I/O library */ -#include +#include /* primitive system data types */ +#include /* file characteristics constants and functions */ +#include /* C standard library */ +#include /* standard I/O library */ +#include /* unix standard library */ +#include /* IP addresses conversion utilities */ +#include /* socket constants, types and functions */ +#include /* date and time constants, types and functions */ #include /* syslog system functions */ -#include /* signal functions */ -#include /* error code */ -#include +#include /* signal constants, types and functions */ +#include /* error definitions and routines */ +#include /* C strings library */ +#include /* directory operation constants and functions */ #include "Gapil.h" +/* + * Function and globals definitions + */ #define BACKLOG 10 #define MAXLINE 256 int demonize = 1; /* daemon use option: default is daemon */ int debugging = 0; /* debug info printing option: default is no debug */ +struct code_page { + char * code; + char * name; + char * body; +}; -/* Subroutines declaration */ 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); +void print_headers(FILE *file, struct code_page code); +void print_error(FILE *file, struct code_page page, char * string); -/* Program beginning */ -int main(int argc, char *argv[]) +/* + * Main program + */int main(int argc, char *argv[]) { -/* - * Variables definition - */ + /* + * Variables definition + */ int list_fd, conn_fd; - int waiting = 0; int compat = 0; int reroot = 0; + int reuse = 1; char * rootdir; pid_t pid; struct sockaddr_in cli_add; @@ -82,7 +88,7 @@ int main(int argc, char *argv[]) */ int i; opterr = 0; /* don't want writing to stderr */ - while ( (i = getopt(argc, argv, "hdicw:r:")) != -1) { + while ( (i = getopt(argc, argv, "hwdicr:")) != -1) { switch (i) { /* * Handling options @@ -102,10 +108,9 @@ int main(int argc, char *argv[]) debugging = 1; break; case 'w': - waiting = strtol(optarg, NULL, 10); + reuse = 0; break; case 'r': - printf("chroot\n"); reroot = 1; rootdir = optarg; break; @@ -130,12 +135,12 @@ int main(int argc, char *argv[]) SignalRestart(SIGCHLD, HandSigCHLD); /* restarting handler */ } /* create and bind socket */ - if ( (list_fd = sockbind2(argv[optind], "www", 6, SOCK_STREAM)) < 0) { + if ( (list_fd = sockbindopt(argv[optind], "www", 6, + SOCK_STREAM, reuse)) < 0) { return 1; } /* chroot if requested */ if (reroot) { - printf("chroot to %s\n", rootdir); if (chdir(rootdir)) { perror("Cannot find directory to chroot"); exit(1); @@ -166,7 +171,6 @@ int main(int argc, char *argv[]) PrintErr("listen error"); exit(1); } - if (waiting) sleep(waiting); /* handle echo to client */ while (1) { /* accept connection */ @@ -217,12 +221,12 @@ void usage(void) { printf("Elementary echo server\n"); printf("Usage:\n"); - printf(" echod [-h] \n"); + printf(" wwwd [-h] \n"); printf(" -h print this help\n"); printf(" -d write debug info\n"); printf(" -i use interactively\n"); printf(" -c disable BSD semantics\n"); - printf(" -w N wait N sec. before calling accept\n"); + printf(" -r /path chroot on /path\n"); exit(1); } /* @@ -234,16 +238,21 @@ void ServPage(int sockfd) char outbuf[1024]; FILE *sock, *file; char *line, *copy, *method, *ptr, *filename, *version; - char *methods[] = { "GET", "PUT", NULL }; - char *codes[] = { - "200 OK", - "400 Bad Request", - "404 Not Found", - "500 Internal Server Error", - NULL + char *methods[] = { "GET", "HEAD", NULL }; + struct code_page codes[] = { + { "200", "OK", "%s"}, + { "400", "Bad Request", + "Your browser sent a request that this server could not understand." + "

The request line

%s

is invalid following the protocol

"}, + { "404", "Not Found", + "The requested URL %s was not found on this server.

"}, + { "500", "Internal Server Error", + "We got an error processing your request.

Error is: %s

"}, + { "405", "Method Not Allowed", "Method %s not allowed.

"}, + { "403", "Forbidden", "You cannot access %s.

"} }; int nleft; - int i, j; + int i; sock = fdopen(sockfd, "w+"); /* main loop, reading 0 char means client close connection */ @@ -255,21 +264,18 @@ void ServPage(int sockfd) /* parsing first line, getting method and filename */ copy = strndupa(line, MAXLINE); if ((method = strtok_r(copy, " ", &ptr)) == NULL) { - fprintf(sock, "HTTP/1.0 %s\n", codes[2]); - print_headers(sock); - print_err400(sock, line); + print_headers(sock, codes[1]); + print_error(sock, codes[1], line); return; } if ((filename = strtok_r(NULL, " ", &ptr)) == NULL) { - fprintf(sock, "HTTP/1.0 %s\n", codes[2]); - print_headers(sock); - print_err400(sock, line); + print_headers(sock, codes[1]); + print_error(sock, codes[1], line); return; } if ((version = strtok_r(NULL, " ", &ptr)) == NULL) { - fprintf(sock, "HTTP/1.0 %s\n", codes[2]); - print_headers(sock); - print_err400(sock, line); + print_headers(sock, codes[1]); + print_error(sock, codes[1], line); return; } i = 0; @@ -280,9 +286,8 @@ void ServPage(int sockfd) i++; } if (i>=2) { - fprintf(sock, "HTTP/1.0 %s\n", codes[2]); - print_headers(sock); - print_err400(sock, line); + print_headers(sock, codes[4]); + print_error(sock, codes[4], method); return; } @@ -291,31 +296,30 @@ void ServPage(int sockfd) } if ( (file = fopen(filename, "r")) == NULL) { - fprintf(sock, "HTTP/1.0 %s\n", codes[2]); - print_headers(sock); - print_err404(sock, filename); + if ( (errno == EACCES)||(errno == EPERM) ) { + print_headers(sock, codes[5]); + print_error(sock, codes[5], filename); + } else { + print_headers(sock, codes[2]); + print_error(sock, codes[2], filename); + } return; } - fprintf(sock, "HTTP/1.0 %s\n", codes[0]); - print_headers(sock); - - j = 0; + print_headers(sock, codes[0]); while (!feof(file)) { if ( (nleft = full_fread(file, outbuf, 1024)) != 0) { if (ferror(file)) { - fprintf(sock, "HTTP/1.0 %s\n", codes[3]); - print_headers(sock); - snprintf(buffer, MAXLINE, "reading %s", filename); - print_err500(sock, buffer); + strncpy(buffer, strerror(errno), MAXLINE); + print_headers(sock, codes[3]); + print_error(sock, codes[3], buffer); return; } } if (full_fwrite(sock, outbuf, 1024-nleft) != 0) { if (ferror(file)) { - fprintf(sock, "HTTP/1.0 %s\n", codes[3]); - print_headers(sock); - snprintf(buffer, MAXLINE, "writing"); - print_err500(sock, buffer); + strncpy(buffer, strerror(errno), MAXLINE); + print_headers(sock, codes[3]); + print_error(sock, codes[3], buffer); return; } } @@ -337,10 +341,11 @@ void PrintErr(char * error) return; } -void print_headers(FILE *file) +void print_headers(FILE *file, struct code_page code) { time_t tempo; + fprintf(file, "HTTP/1.0 %s %s \n", code.code, code.name); time(&tempo); fprintf(file, "Date: %s", ctime(&tempo)); fprintf(file, "Server: WWWd test server\n"); @@ -350,33 +355,13 @@ void print_headers(FILE *file) return; } -void print_err404(FILE *file, char *filename) -{ - fprintf(file, "404 Not Found\n"); - fprintf(file, "

Not Found

\nThe requested "); - fprintf(file, "URL %s was not found on this server.


", filename); - fprintf(file, "
WWWd by Simone Piccardi
"); - return; -} - -void print_err400(FILE *file, char *string) +void print_error(FILE *file, struct code_page page, char * string) { - fprintf(file, "404 Bad Request\n"); - fprintf(file, "

Bad Request

\n "); - fprintf(file, "Your browser sent a request that this server could not "); - fprintf(file, "understand.

The request line

%s

", string); - fprintf(file, "is invalid following the protocol


"); - fprintf(file, "
WWWd by Simone Piccardi
"); + fprintf(file, "%s %s\n", + page.code, page.name); + fprintf(file, "

%s

\n", page.name); + fprintf(file, page.body, string); + fprintf(file, "
WWWd by S. Piccardi
"); return; } - -void print_err500(FILE *file, char *string) -{ - fprintf(file, "500 Internal Server Error\n"); - fprintf(file, "

Internal Server Error

\n "); - fprintf(file, "We got an error processing your request.

"); - fprintf(file, "Error is: %s


\n", string); - fprintf(file, "
WWWd by Simone Piccardi
"); - return; -}