FreeBSD Bugzilla – Attachment 36190 Details for
Bug 58119
New Port: www/pserv (pico webserver)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
pserv.sh
pserv.sh (text/plain), 37.60 KB, created by
Alex Dupre
on 2003-10-16 14:00:34 UTC
(
hide
)
Description:
pserv.sh
Filename:
MIME Type:
Creator:
Alex Dupre
Created:
2003-10-16 14:00:34 UTC
Size:
37.60 KB
patch
obsolete
># This is a shell archive. Save it in a file, remove anything before ># this line, and then unpack it by entering "sh file". Note, it may ># create directories; files and directories will be owned by you and ># have default permissions. ># ># This archive contains: ># ># pserv ># pserv/files ># pserv/files/patch-main.c ># pserv/files/patch-Makefile ># pserv/files/patch-main.h ># pserv/files/patch-mime_types.dat ># pserv/files/patch-pserv.conf ># pserv/files/patch-handlers.c ># pserv/files/patch-handlers.h ># pserv/files/patch-mime.c ># pserv/files/pserv.sh ># pserv/Makefile ># pserv/distinfo ># pserv/pkg-descr ># pserv/pkg-plist ># >echo c - pserv >mkdir -p pserv > /dev/null 2>&1 >echo c - pserv/files >mkdir -p pserv/files > /dev/null 2>&1 >echo x - pserv/files/patch-main.c >sed 's/^X//' >pserv/files/patch-main.c << 'END-of-pserv/files/patch-main.c' >X--- main.c.orig Mon Sep 22 10:39:24 2003 >X+++ main.c Thu Oct 16 14:00:02 2003 >X@@ -23,6 +23,7 @@ >X char defaultFileName[MAX_PATH_LEN+1]; >X char logFileName[MAX_PATH_LEN+1]; >X char mimeTypesFileName[MAX_PATH_LEN+1]; >X+char phpFileName[MAX_PATH_LEN+1]; >X char cgiRoot[MAX_PATH_LEN+1]; /* root for CGI scripts exec */ >X struct timeval sockTimeVal; >X mimeData *mimeArray; /* here we will hold all MIME data, inited once, never to be changed */ >X@@ -206,10 +207,10 @@ >X int reqSize; >X int readLines; >X int tokenEnd; >X- >X- /* we copy the header lines to an array for easier parsing */ >X+ >X+ /* we copy the header lines to an array for easier parsing */ >X /* but first we make sure that our string has a newline and an end */ >X- req[BUFFER_SIZE] = '\0'; >X+ req[BUFFER_SIZE] = '\0'; >X reqSize = strlen(req); >X req[reqSize] = '\n'; >X reqSize++; >X@@ -230,7 +231,7 @@ >X for (k = 0; k < readLines; k++) >X printf("%d - |%s|\n", k, reqArray[k]); >X #endif >X- >X+ >X /* first line: method, path and protocol version */ >X /* we copy to a temporary buffer to be more secure against overflows */ >X i = j = 0; >X@@ -246,7 +247,7 @@ >X else >X tokenEnd = NO; >X i++; >X- >X+ >X /* we look for the document address */ >X j = 0; >X reqStruct->documentAddress[0] = '\0'; >X@@ -259,14 +260,14 @@ >X else >X token[j] = '\0'; /* to make sure we have a string */ >X /* now we need to convert some escapings from the path like %20 */ >X- convertPercents(token, j); >X+ convertPercents(token, j); >X strcpy(reqStruct->documentAddress, token); /* copy back */ >X if (reqArray[0][i] == '\0') >X tokenEnd = YES; >X else >X tokenEnd = NO; >X i++; >X- >X+ >X /* we need now to separate path from query string ("?" separated) */ >X if (reqArray[0][i-1] == '?') >X { >X@@ -282,7 +283,7 @@ >X i++; >X } >X } >X- >X+ >X /* we analyze the HTTP protocol version */ >X /* default is 0.9 since that version didn't report itself */ >X strcpy(reqStruct->protocolVersion, "HTTP/0.9"); >X@@ -306,10 +307,13 @@ >X else if (!strncmp(reqArray[1], "Connection: Keep-Alive", strlen("Connection: keep-alive"))) >X reqStruct->keepAlive = YES; >X >X- /* user-agent, content-length and else */ >X+ /* user-agent, content-length, content-type, cookie and else */ >X i = 1; >X j = NO; >X reqStruct->userAgent[0] = '\0'; >X+ reqStruct->contentLength = -1; >X+ reqStruct->contentType[0] = '\0'; >X+ reqStruct->cookie[0] = '\0'; >X while (i < readLines) >X { >X if (!strncmp(reqArray[i], "User-Agent:", strlen("User-Agent:"))) >X@@ -317,14 +321,28 @@ >X strncpy(reqStruct->userAgent, &reqArray[i][strlen("User-Agent: ")], USER_AGENT_LEN - 1); >X reqStruct->userAgent[USER_AGENT_LEN] = '\0'; >X } >X- else if (!strncmp(reqArray[i], "Content-Length:", strlen("Content-length:")) || !strncmp(reqArray[i], "Content-length:", strlen("Content-length:"))) >X- { >X- strcpy(token, &reqArray[i][strlen("Content-length: ")]); >X- sscanf(token, "%ld", &(reqStruct->contentLength)); >X+ else if (!strncmp(reqArray[i], "Content-Length:", strlen("Content-length:")) || !strncmp(reqArray[i], "Content-length:", strlen("Content-length:"))) >X+ { >X+ strcpy(token, &reqArray[i][strlen("Content-length: ")]); >X+ sscanf(token, "%ld", &(reqStruct->contentLength)); >X #ifdef PRINTF_DEBUG >X- printf("content length %ld\n", reqStruct->contentLength); >X+ printf("content length %ld\n", reqStruct->contentLength); >X #endif >X- } >X+ } >X+ else if (!strncmp(reqArray[i], "Content-Type:", strlen("Content-type:")) || !strncmp(reqArray[i], "Content-type:", strlen("Content-type:"))) >X+ { >X+ strncpy(reqStruct->contentType, &reqArray[i][strlen("Content-type: ")], CONTENT_TYPE_LEN - 1); >X+#ifdef PRINTF_DEBUG >X+ printf("content type %s\n", reqStruct->contentType); >X+#endif >X+ } >X+ else if (!strncmp(reqArray[i], "Cookie:", strlen("Cookie:"))) >X+ { >X+ strncpy(reqStruct->cookie, &reqArray[i][strlen("Cookie: ")], MAX_COOKIE_LEN - 1); >X+#ifdef PRINTF_DEBUG >X+ printf("cookie %s\n", reqStruct->cookie); >X+#endif >X+ } >X i++; >X } >X /* if we didn't find a User-Aget we fill in a (N)ot(R)ecognized */ >X@@ -414,18 +432,39 @@ >X /* we append the default file name */ >X strcat(completeFilePath, defaultFileName); >X analyzeExtension(mimeType, completeFilePath); >X- dumpFile(sock, completeFilePath, mimeType, req); >X+#ifdef PHP >X+ if (strncmp(mimeType, "application/x-httpd-php", 23)) >X+#endif >X+ dumpFile(sock, completeFilePath, mimeType, req); >X+#ifdef PHP >X+ else >X+ phpHandler(port, sock, phpFileName, completeFilePath, req, NULL); >X+#endif >X } >X #else >X /* we append the default file name */ >X strcat(completeFilePath, defaultFileName); >X analyzeExtension(mimeType, completeFilePath); >X- dumpFile(sock, completeFilePath, mimeType, req); >X+#ifdef PHP >X+ if (strncmp(mimeType, "application/x-httpd-php", 23)) >X+#endif >X+ dumpFile(sock, completeFilePath, mimeType, req); >X+#ifdef PHP >X+ else >X+ phpHandler(port, sock, phpFileName, completeFilePath, req, NULL); >X+#endif >X #endif >X } else >X { /* it is a plain file */ >X analyzeExtension(mimeType, completeFilePath); >X- dumpFile(sock, completeFilePath, mimeType, req); >X+#ifdef PHP >X+ if (strncmp(mimeType, "application/x-httpd-php", 23)) >X+#endif >X+ dumpFile(sock, completeFilePath, mimeType, req); >X+#ifdef PHP >X+ else >X+ phpHandler(port, sock, phpFileName, completeFilePath, req, NULL); >X+#endif >X } >X } >X } else if (!strcmp(req.method, "HEAD")) >X@@ -494,7 +533,14 @@ >X strcat(completeFilePath, defaultFileName); >X } >X analyzeExtension(mimeType, completeFilePath); >X- dumpHeader(sock, completeFilePath, mimeType, req); >X+#ifdef PHP >X+ if (strncmp(mimeType, "application/x-httpd-php", 23)) >X+#endif >X+ dumpFile(sock, completeFilePath, mimeType, req); >X+#ifdef PHP >X+ else >X+ phpHandler(port, sock, phpFileName, completeFilePath, req, NULL); >X+#endif >X } >X } else if (!strcmp(req.method, "POST")) >X { >X@@ -507,13 +553,6 @@ >X int readFinished; >X >X printf("Handling of POST method\n"); >X- /* first we check if the path contains the directory selected for cgi's and in case handle it */ >X- if (strncmp(req.documentAddress, CGI_MATCH_STRING, strlen(CGI_MATCH_STRING))) >X- { >X- /* non cgi POST is not supported */ >X- sayError(sock, UNHANDLED_METHOD, "", req); >X- return -1; >X- } >X #ifdef PRINTF_DEBUG >X printf ("begin of post handling\n"); >X >X@@ -523,9 +562,15 @@ >X totalRead = 0; >X stuckCounter = 0; >X timeOutCounter = 0; >X- while (!readFinished) >X- { >X- howMany = recv(newSocket, tempBuff, BUFFER_SIZE, 0); >X+ >X+ /* SECURITY: Avoid malicious Content-Length -- check \r\n\r\n\0 also */ >X+ if (req.contentLength < 0 || req.contentLength >= BUFFER_SIZE-5) { >X+ sayError(sock, 500, "", req); >X+ return -1; >X+ } >X+ >X+ /* SECURITY: Remove loop to prevent buffer overflow */ >X+ howMany = recv(newSocket, tempBuff, req.contentLength+5, 0); >X tempBuff[howMany] = '\0'; /* seems that some Unices need this */ >X #ifdef PRINTF_DEBUG >X printf ("read: %d\n%s\n", howMany, tempBuff); >X@@ -579,16 +624,15 @@ >X if (howMany == req.contentLength) >X readFinished = YES; >X } >X- } >X #ifdef PRINTF_DEBUG >X- printf("total read %d\n", totalRead); >X+ printf("total read %d\n", totalRead); >X #endif >X- if (totalRead == 0) >X- { >X- printf("Request read error\n"); >X- } else >X- { >X- if (buff[totalRead - 1] != '\n') /* we need a trailing \n or the script will wait forever */ >X+ if (totalRead == 0) >X+ { >X+ printf("Request read error\n"); >X+ } else >X+ { >X+ if (buff[totalRead - 1] != '\n') /* we need a trailing \n or the script will wait forever */ >X { >X buff[totalRead++] = '\n'; >X buff[totalRead] = '\0'; >X@@ -596,7 +640,77 @@ >X #ifdef PRINTF_DEBUG >X printf("buff: |%s|\n", buff); >X #endif >X- cgiHandler(port, sock, req, buff); >X+ if (!strncmp(req.documentAddress, CGI_MATCH_STRING, strlen(CGI_MATCH_STRING))) >X+ { >X+ cgiHandler(port, sock, req, buff); >X+ } else >X+ { >X+#ifdef PHP >X+ strcpy(completeFilePath, homePath); >X+ strcat(completeFilePath, req.documentAddress); >X+ /* now we check if the given path tries to get out of the root */ >X+ { >X+ int i,j; >X+ int sL; >X+ char dirName[MAX_PATH_LEN+1]; >X+ int depthCount = 0; >X+ >X+ sL = strlen(req.documentAddress); >X+ dirName[0] = '\0'; >X+ if (sL > 3) { >X+ dirName[0] = req.documentAddress[1]; >X+ dirName[1] = req.documentAddress[2]; >X+ dirName[2] = req.documentAddress[3]; >X+ dirName[3] ='\0'; >X+ if (!strcmp(dirName, "../")) >X+ { >X+ sayError(sock, FORBIDDEN, req.documentAddress, req); >X+ return -1; >X+ } >X+ } >X+ j = 0; >X+ for (i = 1; i < sL; i++) { >X+ if (req.documentAddress[i] == '/') >X+ { >X+ dirName[j] = '\0'; >X+ if (strcmp(dirName, "..")) >X+ depthCount ++; >X+ else >X+ depthCount--; >X+ j = 0; >X+ } else >X+ dirName[j++] = req.documentAddress[i]; >X+ } >X+ if (depthCount < 0) >X+ { >X+ sayError(sock, FORBIDDEN, req.documentAddress, req); >X+ return -1; >X+ } >X+ } >X+ /* now we check if the given file is a directory or a plain file */ >X+ stat(completeFilePath, &fileStats); >X+ if ((fileStats.st_mode & S_IFDIR) == S_IFDIR) >X+ { >X+ /* if does not end with a slash, we get an error */ >X+ if(completeFilePath[strlen(completeFilePath)-1] != '/') >X+ { >X+ sayError(sock, NOT_FOUND, req.documentAddress, req); >X+ return -1; >X+ } >X+ /* we append the default file name */ >X+ strcat(completeFilePath, defaultFileName); >X+ } >X+ analyzeExtension(mimeType, completeFilePath); >X+ if (strncmp(mimeType, "application/x-httpd-php", 23)) >X+ { >X+#endif >X+ /* non cgi POST is not supported */ >X+ sayError(sock, UNHANDLED_METHOD, "", req); >X+ return -1; >X+#ifdef PHP >X+ } else phpHandler(port, sock, phpFileName, completeFilePath, req, buff); >X+#endif >X+ } >X } >X } else >X { >X@@ -625,7 +739,7 @@ >X f = fopen(configFile, "r"); >X if (f == NULL) >X { >X- printf("Error opening config file. Setting defaults.\n"); >X+ printf("Config file not found. Setting defaults.\n"); >X *serverPort = DEFAULT_PORT; >X *maxChildren = DEFAULT_MAX_CHILDREN; >X strcpy(homePath, DEFAULT_DOCS_LOCATION); >X@@ -634,7 +748,9 @@ >X sockTimeVal.tv_usec = DEFAULT_USEC_TO; >X strcpy(logFileName, DEFAULT_LOG_FILE); >X strcpy(mimeTypesFileName, DEFAULT_MIME_FILE); >X+ strcpy(phpFileName, DEFAULT_PHP_FILE); >X strcpy(cgiRoot, DEFAULT_CGI_ROOT); >X+ initMimeTypes(); >X return -1; >X } >X if (!feof(f)) fscanf(f, "%s %s", str1, str2); >X@@ -735,11 +851,25 @@ >X if (mimeTypesFileName == NULL) >X { >X strcpy(mimeTypesFileName, DEFAULT_MIME_FILE); >X- printf("Error reading mimeTypesFileName from file, setting default, %s\n", mimeTypesFileName); >X+ printf("Error reading mimeTypesFile from file, setting default, %s\n", mimeTypesFileName); >X } >X } else { >X strcpy(mimeTypesFileName, DEFAULT_MIME_FILE); >X- printf("Error reading mimeTypesFileName from file, setting default, %s\n", mimeTypesFileName); >X+ printf("Error reading mimeTypesFile from file, setting default, %s\n", mimeTypesFileName); >X+ } >X+ if (!feof(f)) fscanf(f, "%s %s", str1, str2); >X+ if (str1 != NULL && str2 != NULL && !strcmp(str1, "phpFile")) >X+ { >X+ sscanf(str2, "%s", phpFileName); >X+ if (logFileName == NULL) >X+ { >X+ strcpy(phpFileName, DEFAULT_LOG_FILE); >X+ printf("Error reading phpFile from file, setting default, %s\n", phpFileName); >X+ } >X+ } else >X+ { >X+ strcpy(phpFileName, DEFAULT_PHP_FILE); >X+ printf("Error reading phpFile from file, setting default, %s\n", phpFileName); >X } >X if (!feof(f)) fscanf(f, "%s %s", str1, str2); >X if (str1 != NULL && str2 != NULL && !strcmp(str1, "cgiRoot")) >X@@ -775,6 +905,7 @@ >X int readFinished; >X struct request gottenReq; >X int isKeepAlive; >X+ int bool; >X struct sockaddr_in listenName; /* data struct for the listen port */ >X struct sockaddr_in acceptedSockStruct; /* sockaddr for the internetworking */ >X int acceptedSocketLen; /* size of the structure */ >X@@ -808,9 +939,16 @@ >X printf("socket creation error occoured\n"); >X return -1; >X } >X+ bool = 1; >X+ error = setsockopt (theSocket, SOL_SOCKET, SO_REUSEADDR, &bool, sizeof(bool)); >X+ if (error == -1) >X+ { if (errno == EADDRINUSE) >X+ printf("set socket option error occoured\n"); >X+ return -1; >X+ } >X error = bind (theSocket, (struct sockaddr*) &listenName, sizeof(listenName)); >X if (error == -1) >X- { >X+ { if (errno == EADDRINUSE) >X printf("socket binding error occoured\n"); >X return -2; >X } >END-of-pserv/files/patch-main.c >echo x - pserv/files/patch-Makefile >sed 's/^X//' >pserv/files/patch-Makefile << 'END-of-pserv/files/patch-Makefile' >X--- Makefile.orig Mon Sep 8 20:05:54 2003 >X+++ Makefile Thu Oct 16 14:24:50 2003 >X@@ -1,11 +1,11 @@ >X #Change the following to your needs >X-CC = gcc >X+CC ?= gcc >X #insert here flags, eg. optimizations >X-CFLAGS = -Wall -O3 >X-LIBS = -lnsl -lsocket >X SRCS = main.c handlers.c mime.c log.c >X OBJS = main.o handlers.o mime.o log.o >X PROGRAM = pserv >X+ >X+all : $(PROGRAM) >X >X $(PROGRAM) : $(OBJS) >X $(CC) -o $(PROGRAM) $(OBJS) $(LIBS) >END-of-pserv/files/patch-Makefile >echo x - pserv/files/patch-main.h >sed 's/^X//' >pserv/files/patch-main.h << 'END-of-pserv/files/patch-main.h' >X--- main.h.orig Fri Sep 19 00:36:03 2003 >X+++ main.h Thu Oct 16 13:52:18 2003 >X@@ -24,11 +24,12 @@ >X >X >X /* --- CPP parsing options --- */ >X-#define PRINTF_DEBUG /* enable this to print some debugging messages */ >X+#undef PRINTF_DEBUG /* enable this to print some debugging messages */ >X #undef ON_THE_FLY_CONVERSION /* enable this for line ending conversion */ >X #undef BRAIN_DEAD_CAST /* if your compiler is brainwashed and does not cast standard types.h structures */ >X #define FORKING_SERVER /* enables to fork for every request */ >X #define AUTO_INDEX /* enables auto-index of directories */ >X+#define PHP /* enables transparent PHP support */ >X >X /* --- Configure options --- */ >X #define CONFIG_FILE_NAME "pserv.conf" >X@@ -39,19 +40,19 @@ >X #define MIME_TYPE_DEFAULT "application/octet-stream" >X >X /* configuration file location */ >X-#define DEFAULT_CONFIG_LOCATION "/export/home/multix/pserv/" >X-//#define DEFAULT_CONFIG_LOCATION "/Users/multix/Documents/code/pserv/" >X+#define DEFAULT_CONFIG_LOCATION "/usr/local/etc/" >X >X /* hard-wired defaults, if loading of config file fails */ >X-#define DEFAULT_PORT 2000 >X+#define DEFAULT_PORT 80 >X #define DEFAULT_MAX_CHILDREN 5 >X-#define DEFAULT_DOCS_LOCATION "/export/home/multix/public_html" >X+#define DEFAULT_DOCS_LOCATION "/usr/local/www/data" >X #define DEFAULT_FILE_NAME "index.html" >X #define DEFAULT_SEC_TO 1 >X #define DEFAULT_USEC_TO 100 >X-#define DEFAULT_LOG_FILE "/export/home/multix/pserv/pserv.log" >X-#define DEFAULT_MIME_FILE "/export/home/multix/pserv/mime_types.dat" >X-#define DEFAULT_CGI_ROOT "/export/home/multix/public_html/cgi-bin" >X+#define DEFAULT_LOG_FILE "/var/log/pserv.log" >X+#define DEFAULT_MIME_FILE "/usr/local/etc/mime.types" >X+#define DEFAULT_PHP_FILE "/usr/local/bin/php" >X+#define DEFAULT_CGI_ROOT "/usr/local/www/cgi-bin" >X #define DEFAULT_SERVER_NAME "localhost" >X >X /* amount of connections queued in listening */ >X@@ -120,9 +121,11 @@ >X #define ADDRESS_LEN 16 >X #define METHOD_LEN 16 >X #define PROTOCOL_LEN 16 >X+#define CONTENT_TYPE_LEN 256 >X #define USER_AGENT_LEN 256 >X #define MAX_QUERY_STRING_LEN 1024 >X #define MAX_PATH_LEN 1024 >X+#define MAX_COOKIE_LEN 4096 >X >X struct request >X { >X@@ -133,7 +136,9 @@ >X char protocolVersion[PROTOCOL_LEN+1]; >X int keepAlive; >X char userAgent[USER_AGENT_LEN+1]; >X+ char cookie[MAX_COOKIE_LEN+1]; >X long int contentLength; >X+ char contentType[CONTENT_TYPE_LEN+1]; >X char rest[BUFFER_SIZE+1]; >X }; >X >END-of-pserv/files/patch-main.h >echo x - pserv/files/patch-mime_types.dat >sed 's/^X//' >pserv/files/patch-mime_types.dat << 'END-of-pserv/files/patch-mime_types.dat' >X--- mime_types.dat.orig Wed Oct 15 15:57:08 2003 >X+++ mime_types.dat Wed Oct 15 15:57:22 2003 >X@@ -14,3 +14,4 @@ >X tar application/x-tar >X lha application/octet-stream >X lzh application/octet-stream >X+php application/x-httpd-php >END-of-pserv/files/patch-mime_types.dat >echo x - pserv/files/patch-pserv.conf >sed 's/^X//' >pserv/files/patch-pserv.conf << 'END-of-pserv/files/patch-pserv.conf' >X--- pserv.conf.orig Wed Oct 15 16:18:05 2003 >X+++ pserv.conf Wed Oct 15 16:20:01 2003 >X@@ -1,9 +1,10 @@ >X-port 80 >X+port 80 >X maxChildren 4 >X-documentsPath /export/home/multix/public_html >X+documentsPath %%PREFIX%%/www/data >X defaultFile index.html >X secTimeout 1 >X uSecTimeout 100000 >X-logFile /export/home/multix/pserv/pserv.log >X-mimeTypesFile /export/home/multix/pserv/mime_types.dat >X-cgiRoot /export/home/multix/public_html/cgi-bin >X+logFile /var/log/pserv.log >X+mimeTypesFile %%PREFIX%%/etc/mime.types >X+phpFile %%LOCALBASE%%/bin/php >X+cgiRoot %%PREFIX%%/www/cgi-bin >END-of-pserv/files/patch-pserv.conf >echo x - pserv/files/patch-handlers.c >sed 's/^X//' >pserv/files/patch-handlers.c << 'END-of-pserv/files/patch-handlers.c' >X--- handlers.c.orig Thu Sep 18 15:26:48 2003 >X+++ handlers.c Thu Oct 16 14:16:05 2003 >X@@ -24,6 +24,7 @@ >X #endif >X >X extern char cgiRoot[MAX_PATH_LEN+1]; /* root for CGI scripts exec */ >X+extern char homePath[MAX_PATH_LEN+1]; /* root for PHP scripts exec */ >X extern int port; /* server port */ >X extern char defaultFileName[MAX_PATH_LEN+1]; /* default name for index, default or similar file */ >X >X@@ -262,12 +263,33 @@ >X newArgv[i] = NULL; /* we correctly terminate argv */ >X >X i = 0; >X+ if (req.contentLength != -1) >X+ { >X+ sprintf(newEnvp[i++], "CONTENT_LENGTH=%ld", req.contentLength); >X+ strcpy(newEnvp[i], "CONTENT_TYPE="); >X+ strcat(newEnvp[i++], req.contentType); >X+ } >X+ strcpy(newEnvp[i], "SERVER_NAME="); >X+ strcat(newEnvp[i++], DEFAULT_SERVER_NAME); >X strcpy(newEnvp[i], "SERVER_SOFTWARE="); >X strcat(newEnvp[i], SERVER_SOFTWARE_STR); >X strcat(newEnvp[i], "/"); >X strcat(newEnvp[i++], SERVER_VERSION_STR); >X+ strcpy(newEnvp[i], "SERVER_PROTOCOL="); >X+ strcat(newEnvp[i++], req.protocolVersion); >X strcpy(newEnvp[i], "REQUEST_METHOD="); >X strcat(newEnvp[i++], req.method); >X+ strcpy(newEnvp[i], "REMOTE_ADDR="); >X+ strcat(newEnvp[i++], req.address); >X+ strcpy(newEnvp[i], "HTTP_USER_AGENT="); >X+ strcat(newEnvp[i++], req.userAgent); >X+ if (req.cookie[0] != '\0') >X+ { >X+ strcpy(newEnvp[i], "HTTP_COOKIE="); >X+ strcat(newEnvp[i++], req.cookie); >X+ } >X+ strcpy(newEnvp[i], "SCRIPT_FILENAME="); >X+ strcat(newEnvp[i++], completedPath); >X strcpy(newEnvp[i], "SCRIPT_NAME="); >X strcat(newEnvp[i++], req.documentAddress); >X strcpy(newEnvp[i], "GATEWAY_INTERFACE="); >X@@ -302,13 +324,256 @@ >X execve(completedPath, newArgv, newEnvp); >X /* we reach this line only if an execution error occoured */ >X /* logging will happen in the father */ >X- printf("\n<HTML><HEAD><TITLE>CGI Error</TITLE></HEAD><BODY><H1>Cgi Exec error</H1></BODY></HTML>\n"); >X+ printf("\n<HTML><HEAD><TITLE>CGI Error</TITLE></HEAD><BODY><H1>CGI Exec error</H1></BODY></HTML>\n"); >X exit(-1); >X } >X return 0; >X } >X >X-int dumpHeader(sock, filePath, mimeType, req) >X+ >X+#ifdef PHP >X+int phpHandler(port, sock, phpFileName, completedPath, req, postStr) >X+int port; >X+int sock; >X+char *phpFileName; >X+char *completedPath; >X+struct request req; >X+char *postStr; >X+{ >X+ char envPath[MAX_PATH_LEN+1]; /* where to hold the envrion PATH parameter */ >X+ char *relativePath; >X+ char scriptWorkingDir[MAX_PATH_LEN+1]; >X+ char **newArgv; >X+ char **newEnvp; >X+ int i; >X+ int outStdPipe[2]; /* we will redirect the script output to a pipe so we can read it */ >X+ int inStdPipe[2]; /* we will redirect the script input to a pipe so we can read it */ >X+ int pid; /* we fork and execute inside the child the script */ >X+ char pipeReadBuf[PIPE_READ_BUF+1]; >X+ int howMany; >X+ int totalSentFromPipe; /* ampunt of bytes sucked from the pipe and pushed in to the socket */ >X+ int fatal; >X+ >X+ relativePath = strrchr(completedPath, '/'); >X+ strncpy(scriptWorkingDir, completedPath, strlen(completedPath) - strlen(relativePath)); >X+ scriptWorkingDir[strlen(completedPath) - strlen(relativePath)] = '\0'; >X+ >X+ /* first we create the pipes needed for stdout redirection */ >X+ if (pipe(outStdPipe)) >X+ { >X+#ifdef PRINTF_DEBUG >X+ printf("Pipe creation error\n"); >X+ return -1; >X+#endif >X+ } >X+ if (pipe(inStdPipe)) >X+ { >X+#ifdef PRINTF_DEBUG >X+ printf("Pipe creation error\n"); >X+ return -1; >X+#endif >X+ } >X+ >X+ >X+ /* now we fork to subsequently execve */ >X+ pid = fork(); >X+ if (pid) >X+ { /* this is the parent process */ >X+ if (pid < 0) >X+ { /* we check for creation error */ >X+ printf ("Forking error during cgi exec: %d\n", errno); >X+ return -1; >X+ } >X+ /* we close the unused end of the pipe */ >X+ close(outStdPipe[WRITE]); >X+ close(inStdPipe[READ]); >X+ >X+ if (!strcmp(req.method, "POST")) /* we have to feed the stdin of the script */ >X+ { >X+ if(!strlen(postStr)) >X+ { >X+#ifdef PRINTF_DEBUG >X+ printf("cannot post empty data\n"); >X+#endif >X+ return -1; >X+ } >X+ howMany = write(inStdPipe[WRITE], postStr, strlen(postStr)); >X+ if (howMany < 0) >X+ printf("Error during script pipe read.\n"); >X+ } >X+ totalSentFromPipe = 0; >X+ fatal = NO; >X+ howMany = 1; >X+ while (howMany > 0 && !fatal) >X+ { >X+ howMany = read(outStdPipe[READ], &pipeReadBuf, PIPE_READ_BUF); >X+ if (howMany < 0) >X+ printf("Error during script pipe read.\n"); >X+ else if (!howMany) >X+ printf("Nothing read from script pipe.\n"); >X+ else { >X+ pipeReadBuf[howMany] = '\0'; >X+ if (send(sock, pipeReadBuf, howMany, 0) < 0) >X+ { >X+ printf("error during CGI sock writing! %d\n", errno); >X+ if (errno == EAGAIN) >X+ printf("output resource temporarily not available\n"); >X+ else if (errno == EPIPE) >X+ { >X+ printf("broken pipe during CGI out.\n"); >X+ fatal = YES; >X+ } else if (errno == EBADF) >X+ { >X+#ifdef PRINTF_DEBUG >X+ printf("invalid out descriptor.\n"); >X+#endif >X+ fatal = YES; >X+ } >X+ } else >X+ totalSentFromPipe += howMany; >X+ } >X+ } >X+ /* now we finished and we clean up */ >X+ wait(&i); >X+ if (i) /* check if execution exited cleanly or with code */ >X+ logWriter(LOG_CGI_FAILURE, NULL, 0, req, i); >X+ else >X+ logWriter(LOG_CGI_SUCCESS, NULL, totalSentFromPipe, req, 0); >X+ close(outStdPipe[READ]); >X+ close(inStdPipe[WRITE]); >X+ } else >X+ { /* this is the child process */ >X+ /* now we do some environment setup work */ >X+ newArgv = calloc(MAX_ARGV_LEN + 1, sizeof(char*)); >X+ for (i = 0; i < MAX_ARGV_LEN + 1; i++) >X+ { >X+ newArgv[i] = calloc(MAX_PATH_LEN, sizeof(char)); >X+ } >X+ >X+ newEnvp = calloc(MAX_ENVP_LEN + 1, sizeof(char*)); >X+ for (i = 0; i < MAX_ENVP_LEN + 1; i++) >X+ { >X+ newEnvp[i] = calloc(MAX_PATH_LEN, sizeof(char)); >X+ } >X+ >X+ >X+ >X+ /* extracting PATH env variable */ >X+ i = 0; >X+ while (environ && strncmp(environ[i], PATH_MATCH_STRING, strlen(PATH_MATCH_STRING))) >X+ i++; >X+ if(environ[i]) >X+ strcpy(envPath, environ[i]); >X+ else >X+ envPath[0] = '\0'; /* maybe we should set some default? */ >X+ >X+ i = 0; >X+ strcpy(newArgv[i++], phpFileName); /* here we should pass the phppath */ >X+ strcpy(newArgv[i++], completedPath); /* here we should pass the scriptpath */ >X+ if (strlen(req.queryString)) >X+ { >X+ int toParse; >X+ int j, k; >X+ >X+ toParse = YES; >X+ j = strlen(req.queryString); >X+ while (toParse && j > 0) >X+ { >X+ if (req.queryString[j] == '=') >X+ toParse = NO; >X+ j--; >X+ } >X+ if (toParse) >X+ { >X+ j = 0; >X+ k = 0; >X+ howMany = strlen(req.queryString); >X+ while (j < howMany) >X+ { >X+ if (req.queryString[j] == '+') >X+ { >X+ newArgv[i++][k] = '\0'; >X+ k = 0; >X+ } else >X+ newArgv[i][k++] = req.queryString[j]; >X+ j++; >X+ } >X+ i++; /* after all we will have at least one argument! */ >X+ } >X+ } >X+ newArgv[i] = NULL; /* we correctly terminate argv */ >X+ >X+ i = 0; >X+ if (req.contentLength != -1) >X+ { >X+ sprintf(newEnvp[i++], "CONTENT_LENGTH=%ld", req.contentLength); >X+ strcpy(newEnvp[i], "CONTENT_TYPE="); >X+ strcat(newEnvp[i++], req.contentType); >X+ } >X+ strcpy(newEnvp[i], "SERVER_NAME="); >X+ strcat(newEnvp[i++], DEFAULT_SERVER_NAME); >X+ strcpy(newEnvp[i], "SERVER_SOFTWARE="); >X+ strcat(newEnvp[i], SERVER_SOFTWARE_STR); >X+ strcat(newEnvp[i], "/"); >X+ strcat(newEnvp[i++], SERVER_VERSION_STR); >X+ strcpy(newEnvp[i], "SERVER_PROTOCOL="); >X+ strcat(newEnvp[i++], req.protocolVersion); >X+ strcpy(newEnvp[i], "REQUEST_METHOD="); >X+ strcat(newEnvp[i++], req.method); >X+ strcpy(newEnvp[i], "REMOTE_ADDR="); >X+ strcat(newEnvp[i++], req.address); >X+ strcpy(newEnvp[i], "HTTP_USER_AGENT="); >X+ strcat(newEnvp[i++], req.userAgent); >X+ if (req.cookie[0] != '\0') >X+ { >X+ strcpy(newEnvp[i], "HTTP_COOKIE="); >X+ strcat(newEnvp[i++], req.cookie); >X+ } >X+ strcpy(newEnvp[i], "SCRIPT_FILENAME="); >X+ strcat(newEnvp[i++], completedPath); >X+ strcpy(newEnvp[i], "SCRIPT_NAME="); >X+ strcat(newEnvp[i++], req.documentAddress); >X+ strcpy(newEnvp[i], "GATEWAY_INTERFACE="); >X+ strcat(newEnvp[i++], CGI_VERSION); >X+ sprintf(newEnvp[i++], "SERVER_PORT=%d", port); >X+ strcpy(newEnvp[i++], envPath); >X+ strcpy(newEnvp[i], "QUERY_STRING="); >X+ strcat(newEnvp[i++], req.queryString); >X+ newEnvp[i] = NULL; >X+ >X+ /* we change the current working directory to the scripts one */ >X+ if(chdir(scriptWorkingDir)) >X+ { >X+#ifdef PRINTF_DEBUG >X+ printf("error while changing PWD in script execution: %d\n", errno); >X+#endif >X+ } >X+ >X+ close(outStdPipe[READ]); /* we close the unused end*/ >X+ dup2(outStdPipe[WRITE], 1); /* we duplicate the pipe to the stdout */ >X+ close(outStdPipe[WRITE]); /* we close the pipe, since we use the duplicate */ >X+ >X+ close(inStdPipe[WRITE]); /* we close the unused end*/ >X+ dup2(inStdPipe[READ], 0); /* we duplicate the pipe to the stdin */ >X+ close(inStdPipe[READ]); /* we close the pipe, since we use the duplicate */ >X+ >X+ >X+ /* generate a reduced mimeHeader, no type, no size, etc */ >X+ generateMimeHeader(sock, 200, "", NULL, req.protocolVersion, CGI_ONLY_HEADER); >X+ >X+ /* now we execute the script replacing the current child */ >X+ execve(phpFileName, newArgv, newEnvp); >X+ /* we reach this line only if an execution error occoured */ >X+ /* logging will happen in the father */ >X+ printf("\n<HTML><HEAD><TITLE>PHP Error</TITLE></HEAD><BODY><H1>PHP Exec error</H1></BODY></HTML>\n"); >X+ exit(-1); >X+ } >X+ return 0; >X+} >X+#endif >X+ >X+int dumpHeader(port, sock, filePath, mimeType, req) >X+int port; >X int sock; >X char filePath[]; >X char mimeType[]; >X@@ -351,11 +616,11 @@ >X return -1; >X } >X stat(filePath, &fileStats); >X- generateMimeHeader(sock, 200, mimeType, &fileStats, req.protocolVersion, FULL_HEADER); >X- logWriter(LOG_GET_SUCCESS, req.documentAddress, (long int)fileStats.st_size, req, 0); >X howMany = 0; >X if (strncmp(mimeType, "text", 4)) /* check if it is a text type */ >X { /* raw binary output routine */ >X+ generateMimeHeader(sock, 200, mimeType, &fileStats, req.protocolVersion, FULL_HEADER); >X+ logWriter(LOG_GET_SUCCESS, req.documentAddress, (long int)fileStats.st_size, req, 0); >X fatal = NO; >X retry = NO; >X while(!feof(inFile) && !fatal) >X@@ -399,11 +664,11 @@ >X if (howMany > 0) >X { >X #ifdef ON_THE_FLY_CONVERSION >X- { >X- int i; >X- for (i = 0; i < howMany; i++) >X- if(outBuff[i] == '\r') outBuff[i] = '\n'; >X- } >X+ { >X+ int i; >X+ for (i = 0; i < howMany; i++) >X+ if(outBuff[i] == '\r') outBuff[i] = '\n'; >X+ } >X #endif >X if (send(sock, outBuff, howMany, 0) < 0) >X { >X@@ -449,7 +714,7 @@ >X FILE *tempFile; >X size_t generatedBytes; >X char tempStr[MAX_PATH_LEN+1]; >X- char linkStr[MAX_PATH_LEN+1]; >X+ char linkStr[MAX_PATH_LEN+2]; >X time_t currTime; >X char timeStr[256]; >X >X@@ -497,10 +762,16 @@ >X if (strcmp(dp->d_name, ".")) /* not self */ >X { >X if (strcmp(dp->d_name, "..")) >X+ { >X strcpy(linkStr, dp->d_name); >X- else >X+ if (dp->d_type == DT_DIR) >X+ strcat(linkStr, "/"); >X+ sprintf(tempStr, "<A HREF=\"%s\">%s</A><BR>\n", linkStr, linkStr); >X+ } else >X+ { >X strcpy(linkStr, "Parent Directory"); >X- sprintf(tempStr, "<A HREF=\"%s\">%s</A><BR>\n", dp->d_name, linkStr); >X+ sprintf(tempStr, "<A HREF=\"%s/\">%s</A><BR>\n", dp->d_name, linkStr); >X+ } >X generatedBytes += strlen(tempStr); >X fprintf(tempFile, "%s\n", tempStr); >X } >END-of-pserv/files/patch-handlers.c >echo x - pserv/files/patch-handlers.h >sed 's/^X//' >pserv/files/patch-handlers.h << 'END-of-pserv/files/patch-handlers.h' >X--- handlers.h.orig Wed Oct 15 17:06:59 2003 >X+++ handlers.h Wed Oct 15 17:07:08 2003 >X@@ -19,6 +19,7 @@ >X >X /* handlers.c */ >X int cgiHandler(); >X+int phpHandler(); >X int dumpHeader(); >X int dumpFile(); >X int generateIndex(); >END-of-pserv/files/patch-handlers.h >echo x - pserv/files/patch-mime.c >sed 's/^X//' >pserv/files/patch-mime.c << 'END-of-pserv/files/patch-mime.c' >X--- mime.c.orig Thu Sep 18 15:26:55 2003 >X+++ mime.c Wed Oct 15 18:38:42 2003 >X@@ -43,8 +43,8 @@ >X f = fopen(mimeTypesFileName, "r"); >X if (f == NULL) >X { >X- printf("Error opening mime types file. Setting defaults.\n"); >X- entries = 3; >X+ printf("Mime types file not found. Setting defaults.\n"); >X+ entries = 6; >X mimeArray = (mimeData *) calloc(entries, sizeof(mimeData)); >X if (mimeArray == NULL) { >X printf("Errory while allocating mime types Array. Exiting.\n"); >X@@ -52,10 +52,16 @@ >X } >X strcpy(mimeArray[0].ext, "html"); >X strcpy(mimeArray[0].type, "text/html"); >X- strcpy(mimeArray[1].ext, "gif"); >X- strcpy(mimeArray[1].type, "image/gif"); >X- strcpy(mimeArray[2].ext, "jpg"); >X- strcpy(mimeArray[2].type, "image/jpg"); >X+ strcpy(mimeArray[1].ext, "htm"); >X+ strcpy(mimeArray[1].type, "text/html"); >X+ strcpy(mimeArray[2].ext, "gif"); >X+ strcpy(mimeArray[2].type, "image/gif"); >X+ strcpy(mimeArray[3].ext, "jpg"); >X+ strcpy(mimeArray[3].type, "image/jpg"); >X+ strcpy(mimeArray[4].ext, "png"); >X+ strcpy(mimeArray[4].type, "image/png"); >X+ strcpy(mimeArray[5].ext, "php"); >X+ strcpy(mimeArray[5].type, "application/x-httpd-php"); >X mimeEntries = entries; >X return -1; >X } >END-of-pserv/files/patch-mime.c >echo x - pserv/files/pserv.sh >sed 's/^X//' >pserv/files/pserv.sh << 'END-of-pserv/files/pserv.sh' >X#!/bin/sh >X >Xif ! PREFIX=$(expr $0 : "\(/.*\)/etc/rc\.d/$(basename $0)\$"); then >X echo "$0: Cannot determine the PREFIX" >&2 >X exit 1 >Xfi >X >Xcase "$1" in >Xstart) >X if [ -x ${PREFIX}/sbin/pserv ]; then >X ${PREFIX}/sbin/pserv > /dev/null & >X echo -n ' pserv' >X fi >X ;; >Xstop) >X killall pserv > /dev/null 2>&1 >X echo -n ' pserv' >X ;; >X*) >X echo "Usage: `basename $0` {start|stop}" >&2 >X ;; >Xesac >X >Xexit 0 >END-of-pserv/files/pserv.sh >echo x - pserv/Makefile >sed 's/^X//' >pserv/Makefile << 'END-of-pserv/Makefile' >X# New ports collection makefile for: pserv >X# Date created: Wed Oct 15 14:16:14 CEST 2003 >X# Whom: Alex Dupre <sysadmin@alexdupre.com> >X# >X# $FreeBSD$ >X# >X >XPORTNAME= pserv >XPORTVERSION= 3.0.b1 >XCATEGORIES= www >XMASTER_SITES= ${MASTER_SITE_SOURCEFORGE} >XMASTER_SITE_SUBDIR= ${PORTNAME} >XDISTNAME= ${PORTNAME}-22-Sep-03 >XEXTRACT_SUFX= .tar.Z >X >XMAINTAINER= sysadmin@alexdupre.com >XCOMMENT= A portable and small webserver written in C >X >XWRKSRC= ${WRKDIR}/${PORTNAME} >XUSE_REINPLACE= yes >X >Xpost-patch: >X @${REINPLACE_CMD} "s|%%PREFIX%%|${PREFIX}|g;s|%%LOCALBASE%%|${LOCALBASE}|g" \ >X ${WRKSRC}/pserv.conf >X >Xdo-install: >X ${INSTALL_PROGRAM} ${WRKSRC}/pserv ${PREFIX}/sbin/ >X ${INSTALL_DATA} ${WRKSRC}/mime_types.dat ${PREFIX}/etc/mime.types >X ${INSTALL_DATA} ${WRKSRC}/pserv.conf ${PREFIX}/etc/ >X ${INSTALL_SCRIPT} ${FILESDIR}/pserv.sh ${PREFIX}/etc/rc.d/ >X >X.include <bsd.port.mk> >END-of-pserv/Makefile >echo x - pserv/distinfo >sed 's/^X//' >pserv/distinfo << 'END-of-pserv/distinfo' >XMD5 (pserv-22-Sep-03.tar.Z) = 4895631b730836c9202d5ac28b05f0fa >END-of-pserv/distinfo >echo x - pserv/pkg-descr >sed 's/^X//' >pserv/pkg-descr << 'END-of-pserv/pkg-descr' >XpServ is a small, portable HTTP server. It is written in pure C for speed and >Xportability. It runs as a standalone program and does not require inetd. >XIt should be small enough to be used in a mobile computer or to be run on your >Xobsolete workstation you have somewhere. >X >XThis port contains a patched version to support the execution of php scripts. >X >XWWW: http://sourceforge.net/projects/pserv/ >X >X- Alex Dupre >Xsysadmin@alexdupre.com >END-of-pserv/pkg-descr >echo x - pserv/pkg-plist >sed 's/^X//' >pserv/pkg-plist << 'END-of-pserv/pkg-plist' >Xsbin/pserv >Xetc/mime.types >Xetc/pserv.conf >Xetc/rc.d/pserv.sh >END-of-pserv/pkg-plist >exit
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 58119
: 36190