X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=sources%2Fwwwd.c;h=0b6dfde9a9be2ca3e0ba4d2dcf04ee149e530083;hp=3379486e08a431d0e8febd3f003632e369120537;hb=26f7a8bb19c6cb198c213757a97b6ac79e40db4b;hpb=ff8c324d1cdb252eebc1ad3c419bca5b7ac940f3 diff --git a/sources/wwwd.c b/sources/wwwd.c index 3379486..0b6dfde 100644 --- a/sources/wwwd.c +++ b/sources/wwwd.c @@ -26,47 +26,58 @@ * * 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_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; socklen_t len; @@ -77,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:")) != -1) { + while ( (i = getopt(argc, argv, "hwdicr:")) != -1) { switch (i) { /* * Handling options @@ -97,7 +108,11 @@ int main(int argc, char *argv[]) debugging = 1; break; case 'w': - waiting = strtol(optarg, NULL, 10); + reuse = 0; + break; + case 'r': + reroot = 1; + rootdir = optarg; break; case '?': /* unrecognized options */ printf("Unrecognized options -%c\n",optopt); @@ -120,9 +135,21 @@ 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) { + 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 +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 */ @@ -195,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); } /* @@ -212,37 +238,46 @@ 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", - "404 Not Found", - 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 */ 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"); + print_headers(sock, codes[1]); + print_error(sock, codes[1], line); return; } if ((filename = strtok_r(NULL, " ", &ptr)) == NULL) { - PrintErr("Non ho trovato il file"); + print_headers(sock, codes[1]); + print_error(sock, codes[1], line); return; } if ((version = strtok_r(NULL, " ", &ptr)) == NULL) { - PrintErr("Non ho trovato la versione"); + print_headers(sock, codes[1]); + print_error(sock, codes[1], 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 +286,44 @@ void ServPage(int sockfd) i++; } if (i>=2) { - printf("No method %s found\n", method); + print_headers(sock, codes[4]); + print_error(sock, codes[4], method); 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]); - print_headers(sock); + 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]); - //PrintHeader(sock); - print_headers(sock); - - j = 0; + print_headers(sock, codes[0]); while (!feof(file)) { - printf("Loop %d\n", j++); if ( (nleft = full_fread(file, outbuf, 1024)) != 0) { if (ferror(file)) { - printf("Errore in lettura"); + strncpy(buffer, strerror(errno), MAXLINE); + print_headers(sock, codes[3]); + print_error(sock, codes[3], 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"); + strncpy(buffer, strerror(errno), MAXLINE); + print_headers(sock, codes[3]); + print_error(sock, codes[3], buffer); return; } } } - printf("Ok fin qui!"); -// line = fgets(buffer, MAXLINE, sock); fclose(file); fclose(sock); return; @@ -307,20 +341,27 @@ 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"); 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_error(FILE *file, struct code_page page, char * string) +{ + 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; +} +