mirror of
https://github.com/NishiOwO/ncsa-httpd.git
synced 2025-04-21 08:44:40 +00:00
NCSA HTTPd 1.5.2 (export)
This commit is contained in:
parent
bb0575c774
commit
3145f7d291
51
BUGS
51
BUGS
@ -1,5 +1,56 @@
|
|||||||
|
NOTE: Bugs are mentioned in the version they are found in. This doesn't
|
||||||
|
mean that they didn't exist prior to that version.
|
||||||
|
|
||||||
|
Known Bugs in 1.5.1
|
||||||
|
---------------------
|
||||||
|
*) Can only use a single group on a require group
|
||||||
|
*) core dumps at random due to a free in env.c
|
||||||
|
*) Relative urls in imagemaps are broken
|
||||||
|
*) doesn't kill cgi scripts if the user aborts
|
||||||
|
*) content_length gets reset after scanning cgi headers, instead of before
|
||||||
|
*) can core dump on special case in getline (rfc822 line wrapping)
|
||||||
|
|
||||||
|
Known Bugs in 1.5.1b3
|
||||||
|
---------------------
|
||||||
|
*) 299: File descriptors aren't set correctly on child_alone()
|
||||||
|
*) 301: Sending headers on HTTP/0.9 response
|
||||||
|
|
||||||
|
Known Bugs in 1.5.1b2
|
||||||
|
---------------------
|
||||||
|
*) 900: ErrorDocument 401s as html files doesn't work on Mosaic/X, does on
|
||||||
|
netscape
|
||||||
|
*) 293: Socket isn't closed before CGI execution, causing client to hang
|
||||||
|
waiting for close
|
||||||
|
|
||||||
|
Known Bugs in 1.5.1b1
|
||||||
|
---------------------
|
||||||
|
*) 264: imagemap fails because of invalid fgets() argument
|
||||||
|
*) 265: in_ip() broken causing all access control by ip to fail
|
||||||
|
*) 266: 301 and 204 status codes broken in set_stat_line()
|
||||||
|
*) 267: no bounds checking in access_control array
|
||||||
|
|
||||||
|
|
||||||
Known Bugs in 1.5a
|
Known Bugs in 1.5a
|
||||||
---------------------
|
---------------------
|
||||||
|
*) server doesn't clean up directory indexing information added by .htaccess
|
||||||
|
*) fgets in src/imagemap.c only uses MAX_STRING_LEN, which may be too short
|
||||||
|
for complex polygons
|
||||||
|
*) If you don't have an allow or require line in .htaccess LIMIT, it won't
|
||||||
|
work (ie, just a deny)
|
||||||
|
*) Doesn't log HEAD request to automatically indexed directory
|
||||||
|
*) Can't use group and user name which are the same in flat group file
|
||||||
|
*) Off by one errors in DBM support
|
||||||
|
*) typo in LOCALHACK
|
||||||
|
*) Server core dumped if user aborted before reqInfo->remote_name set
|
||||||
|
*) Server core dumped if setuid/setgid failed
|
||||||
|
*) Bug in http_access.c which makes matchexp directories in access control
|
||||||
|
not work correctly
|
||||||
|
*) NIS group files only work if using NIS password files as well
|
||||||
|
*) Order mutual-failure is broken, does exact opposite
|
||||||
|
*) Don't strip Content-Length header from CGI scripts
|
||||||
|
*) require group will match user as postfix of another, and fails if a
|
||||||
|
prefix occurs first
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Known Bugs in 1.5
|
Known Bugs in 1.5
|
||||||
|
62
CHANGES
62
CHANGES
@ -1,3 +1,56 @@
|
|||||||
|
|
||||||
|
Changes for 1.5.2
|
||||||
|
------------------
|
||||||
|
*) Changed getline rfc822 line wrap to check for validity of the next bits
|
||||||
|
before attempting to see them
|
||||||
|
*) Changed imagemap.c so relative URLs actually work
|
||||||
|
*) Don't core dump on a method only request
|
||||||
|
*) reset errno to 0 in send_fp so we break out of loop
|
||||||
|
*) somewhere we stopped killing cgi scripts on SIGALRM and SIGPIPE
|
||||||
|
*) changed group handling support to support multiple groups again
|
||||||
|
*) reset content_length before scanning cgi headers, not after
|
||||||
|
*) don't free env var in replace (it uses allocate now)
|
||||||
|
*) Only look for path_info if its part of the requested URL (as opposed
|
||||||
|
to keep looking until you hit a real directory)
|
||||||
|
*) Make make_dirstr() in util.c return / instead of null if n = 1
|
||||||
|
*) Added FCGI support from Openmarket
|
||||||
|
*) Added support for Linux 2.0
|
||||||
|
*) Added support for SCO OpenServer 5
|
||||||
|
|
||||||
|
Changes for 1.5.1
|
||||||
|
------------------
|
||||||
|
*) Imagemaps (both internal and external) now add the path of the map file
|
||||||
|
for non full path urls in the map file
|
||||||
|
*) A couple logging functions didn't check reqInfo->remote_name for a NULL
|
||||||
|
*) change getuid to geteuid in httpd.c so that effectively root people can
|
||||||
|
start the server and have it change uids
|
||||||
|
*) Slight code rearrangement to make Redirects from .htaccess more
|
||||||
|
useful because the file doesn't have to exist.
|
||||||
|
*) Added support for restricted access by Referer field
|
||||||
|
*) Added OnDeny command for Limit directive which allows a redirect on
|
||||||
|
failure (esp. useful for denying by referer)
|
||||||
|
*) Added string allocating mechanism for speed
|
||||||
|
*) Added CONTENT_MD5 header support from patches by Martin Hamilton
|
||||||
|
(martin@net.lut.ac.uk)
|
||||||
|
*) Server doesn't keep creating more structures in the event of KeepAlive
|
||||||
|
*) Added bounds checking for security structures
|
||||||
|
*) Fixed Order mutual-failure
|
||||||
|
*) Support both CERN and NCSA style imagemaps (on a line by line basis)
|
||||||
|
*) Attempting to make the server thread safe
|
||||||
|
*) First attempt at allowing ErrorDocument 401s as html files (still broken)
|
||||||
|
*) Fixed string searching for user in group
|
||||||
|
*) Close csd (socket) on exec of CGI scripts so that client doesn't hang
|
||||||
|
waiting for the scripts (and their children) to finish
|
||||||
|
*) made a single interface for most output functions to make it easier
|
||||||
|
to go to different output functions (SSL is a good example)
|
||||||
|
*) remove path_args/path_alias crap, and put it in reqInfo structure
|
||||||
|
*) Why do we require full URLs in Redirect? A local (root) url should work fine
|
||||||
|
*) Redirect from .htaccess should work now (completely)
|
||||||
|
*) Added hack to allow SSI of CGI, at a great expense of speed (CGI_SSI_HACK)
|
||||||
|
*) Made getline() code re-entrant (now has its own sock_buf struct)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Fixes for 1.5c
|
Fixes for 1.5c
|
||||||
------------------
|
------------------
|
||||||
*) add newline character to list of characters to strip from shell cmds
|
*) add newline character to list of characters to strip from shell cmds
|
||||||
@ -12,15 +65,6 @@ Fixes for 1.5c
|
|||||||
start the server and have it change uids
|
start the server and have it change uids
|
||||||
*) Fix group checking
|
*) Fix group checking
|
||||||
|
|
||||||
Fixes for 1.5b (internal)
|
|
||||||
------------------
|
|
||||||
*) Couple of off by one errors in the DBM support (server and support files)
|
|
||||||
*) HP/Apollo Domain/OS support updated
|
|
||||||
*) SCO ODT and SCO SVR3 support updated
|
|
||||||
*) Typo in LOCALHACK
|
|
||||||
*) No error message for NO_CONTENT default imagemap
|
|
||||||
*) clean up after directory indexing (memory leak)
|
|
||||||
|
|
||||||
Fixes for 1.5a
|
Fixes for 1.5a
|
||||||
-------------------
|
-------------------
|
||||||
*) Typo/Thinko for http_access.c which makes order deny/allow not work as
|
*) Typo/Thinko for http_access.c which makes order deny/allow not work as
|
||||||
|
5
CREDITS
5
CREDITS
@ -28,9 +28,11 @@ Vince Tkac (tkac@oclc.org)
|
|||||||
Elf Sternberg (elf@aaden.spry.com)
|
Elf Sternberg (elf@aaden.spry.com)
|
||||||
Nathan Neulinger (nneul@umr.edu)
|
Nathan Neulinger (nneul@umr.edu)
|
||||||
Stuart Lynne (sl@wimsey.com)
|
Stuart Lynne (sl@wimsey.com)
|
||||||
|
Martin Hamilton (martin@net.lut.ac.uk)
|
||||||
|
Tim Hudson (tjh@mincom.oz.au) SSL
|
||||||
|
|
||||||
And for Porting information/help:
|
And for Porting information/help:
|
||||||
Alex Podlecki (a.podlecki@att.com) SVR4
|
Alex Podlecki (apodlecki@lucent.com) SVR4
|
||||||
Sanj Kharbanda (sanj@wordsworth.com) QNX
|
Sanj Kharbanda (sanj@wordsworth.com) QNX
|
||||||
Jeffrey Ray Thieleke (thieleke@icaen.uiowa.edu) NetBSD for m68k
|
Jeffrey Ray Thieleke (thieleke@icaen.uiowa.edu) NetBSD for m68k
|
||||||
David Cornejo (dave@dogwood.com) NetBSD
|
David Cornejo (dave@dogwood.com) NetBSD
|
||||||
@ -46,6 +48,7 @@ Eugene Mah (eugene@raddi.uah.ualberta.ca) NeXT 3.2 m68k
|
|||||||
Kevin Steves (stevesk@mayfield.hp.com) HPUX
|
Kevin Steves (stevesk@mayfield.hp.com) HPUX
|
||||||
Vincent D. Skahan (vds7789@aw101.iasl.ca.boeing.com) HP/Apollo DomainOS
|
Vincent D. Skahan (vds7789@aw101.iasl.ca.boeing.com) HP/Apollo DomainOS
|
||||||
Achille Hui (eillihca@drizzle.stanford.edu) OSF/1 2.0
|
Achille Hui (eillihca@drizzle.stanford.edu) OSF/1 2.0
|
||||||
|
Huw Rogers (count0@iac.co.jp) Linux
|
||||||
Miquel van Smoorenburg (miquels@cistron.nl) Linux
|
Miquel van Smoorenburg (miquels@cistron.nl) Linux
|
||||||
A. P. Harris (apharris@onshore.com) Linux
|
A. P. Harris (apharris@onshore.com) Linux
|
||||||
Stan Johnson (johnson@mission.jsc.nasa.gov) ConvexOS 10.1
|
Stan Johnson (johnson@mission.jsc.nasa.gov) ConvexOS 10.1
|
||||||
|
43
LICENSE.TERMS.fcgi
Normal file
43
LICENSE.TERMS.fcgi
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
This FastCGI application library source and object code (the
|
||||||
|
"Software") and its documentation (the "Documentation") are
|
||||||
|
copyrighted by Open Market, Inc ("Open Market"). The following terms
|
||||||
|
apply to all files associated with the Software and Documentation
|
||||||
|
unless explicitly disclaimed in individual files.
|
||||||
|
|
||||||
|
Open Market permits you to use, copy, modify, distribute, and license
|
||||||
|
this Software and the Documentation solely for the purpose of
|
||||||
|
implementing the FastCGI specification defined by Open Market or
|
||||||
|
derivative specifications publicly endorsed by Open Market and
|
||||||
|
promulgated by an open standards organization and for no other
|
||||||
|
purpose, provided that existing copyright notices are retained in all
|
||||||
|
copies and that this notice is included verbatim in any distributions.
|
||||||
|
|
||||||
|
No written agreement, license, or royalty fee is required for any of
|
||||||
|
the authorized uses. Modifications to this Software and Documentation
|
||||||
|
may be copyrighted by their authors and need not follow the licensing
|
||||||
|
terms described here, but the modified Software and Documentation must
|
||||||
|
be used for the sole purpose of implementing the FastCGI specification
|
||||||
|
defined by Open Market or derivative specifications publicly endorsed
|
||||||
|
by Open Market and promulgated by an open standards organization and
|
||||||
|
for no other purpose. If modifications to this Software and
|
||||||
|
Documentation have new licensing terms, the new terms must protect Open
|
||||||
|
Market's proprietary rights in the Software and Documentation to the
|
||||||
|
same extent as these licensing terms and must be clearly indicated on
|
||||||
|
the first page of each file where they apply.
|
||||||
|
|
||||||
|
Open Market shall retain all right, title and interest in and to the
|
||||||
|
Software and Documentation, including without limitation all patent,
|
||||||
|
copyright, trade secret and other proprietary rights.
|
||||||
|
|
||||||
|
OPEN MARKET MAKES NO EXPRESS OR IMPLIED WARRANTY WITH RESPECT TO THE
|
||||||
|
SOFTWARE OR THE DOCUMENTATION, INCLUDING WITHOUT LIMITATION ANY
|
||||||
|
WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN
|
||||||
|
NO EVENT SHALL OPEN MARKET BE LIABLE TO YOU OR ANY THIRD PARTY FOR ANY
|
||||||
|
DAMAGES ARISING FROM OR RELATING TO THIS SOFTWARE OR THE
|
||||||
|
DOCUMENTATION, INCLUDING, WITHOUT LIMITATION, ANY INDIRECT, SPECIAL OR
|
||||||
|
CONSEQUENTIAL DAMAGES OR SIMILAR DAMAGES, INCLUDING LOST PROFITS OR
|
||||||
|
LOST DATA, EVEN IF OPEN MARKET HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES. THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS".
|
||||||
|
OPEN MARKET HAS NO LIABILITY IN CONTRACT, TORT, NEGLIGENCE OR
|
||||||
|
OTHERWISE ARISING OUT OF THIS SOFTWARE OR THE DOCUMENTATION.
|
||||||
|
|
4
Makefile
4
Makefile
@ -5,7 +5,7 @@ all:
|
|||||||
@echo Please choose a system type.
|
@echo Please choose a system type.
|
||||||
@echo Valid types are aix3, aix4, sunos, sgi4, sgi5,
|
@echo Valid types are aix3, aix4, sunos, sgi4, sgi5,
|
||||||
@echo hp-cc, hp-gcc, solaris, netbsd, svr4, linux,
|
@echo hp-cc, hp-gcc, solaris, netbsd, svr4, linux,
|
||||||
@echo next, ultrix, osf1, aux, bsdi
|
@echo next, ultrix, osf1, aux, bsdi, sco5
|
||||||
@echo If you do not have one of these systems, you must edit
|
@echo If you do not have one of these systems, you must edit
|
||||||
@echo src/Makefile, src/portability.h, src/config.h,
|
@echo src/Makefile, src/portability.h, src/config.h,
|
||||||
@echo cgi-src/Makefile, and support/Makefile
|
@echo cgi-src/Makefile, and support/Makefile
|
||||||
@ -45,6 +45,8 @@ next:
|
|||||||
|
|
||||||
osf1:
|
osf1:
|
||||||
cd src ; make osf1; cd ../cgi-src ; make osf1; cd ../support ; make osf1
|
cd src ; make osf1; cd ../cgi-src ; make osf1; cd ../support ; make osf1
|
||||||
|
sco5:
|
||||||
|
cd src ; make sco5; cd ../cgi-src ; make CC=icc ; cd ../support ; make sco5
|
||||||
|
|
||||||
sgi4:
|
sgi4:
|
||||||
cd src ; make sgi; cd ../cgi-src ; make sgi ; cd ../support ; make sgi4
|
cd src ; make sgi; cd ../cgi-src ; make sgi ; cd ../support ; make sgi4
|
||||||
|
5
README
5
README
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
NCSA HTTPd Server 1.5c
|
NCSA HTTPd Server 1.5.2
|
||||||
|
|
||||||
Copyright (c) 1995 Board of Trustees, University of Illinois
|
Copyright (c) 1995 Board of Trustees, University of Illinois
|
||||||
|
|
||||||
@ -70,6 +70,8 @@ support/dbmpasswd Program to make password files that use dbm
|
|||||||
support/htdigest Program to make MD5 password files (std/text)
|
support/htdigest Program to make MD5 password files (std/text)
|
||||||
support/htpasswd Program to make password files (std/text)
|
support/htpasswd Program to make password files (std/text)
|
||||||
support/std2dbm Program to convert std files to dbm
|
support/std2dbm Program to convert std files to dbm
|
||||||
|
support/webgrab Brian J. Swetland's Command Line Browser
|
||||||
|
(its almost as good as telnet)
|
||||||
|
|
||||||
Version Number Defined
|
Version Number Defined
|
||||||
---------------------------
|
---------------------------
|
||||||
@ -82,3 +84,4 @@ Version Number Defined
|
|||||||
| ---- Major revisions. Probably not going to be another until 2.0
|
| ---- Major revisions. Probably not going to be another until 2.0
|
||||||
------ Really major revisions, code overhauls, goal changes, language
|
------ Really major revisions, code overhauls, goal changes, language
|
||||||
changes
|
changes
|
||||||
|
|
||||||
|
24
README.fcgi
Normal file
24
README.fcgi
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
NOTE: The information in this was the information in the README for
|
||||||
|
the FCGI patch from Openmarket, and may not necessarily apply to this
|
||||||
|
version of the server.
|
||||||
|
|
||||||
|
For more information on FastCGI, see http://www.fastcgi.com/
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
FastCGI Module for the NCSA HTTPd
|
||||||
|
This module has been tested on NCSA version 1.5.1
|
||||||
|
which is available at
|
||||||
|
http://httpd.ncsa.uiuc.edu/beta-1.5/ncsa-httpd-1.5.1.tar.Z
|
||||||
|
Contained in ncsa-fastcgi.tar.Z is the source
|
||||||
|
code for the FastCGI module, documentation, and the licensing terms.
|
||||||
|
|
||||||
|
Directions for installing and using this module are in the file
|
||||||
|
mod_fastcgi.html which is in the top level directory of the
|
||||||
|
FastCGI module kit.
|
||||||
|
|
||||||
|
|
||||||
|
You can obtain the FastCGI developers kit, along with pre-compiled FastCGI
|
||||||
|
capable perl-5 and tcl distributions at
|
||||||
|
http://www.fastcgi.com/.
|
0
cgi-src/Makefile
Executable file → Normal file
0
cgi-src/Makefile
Executable file → Normal file
@ -47,6 +47,9 @@
|
|||||||
**
|
**
|
||||||
** 1.9 : Fixed bug: If you requested a new style conf file in DOCUMENT_ROOT,
|
** 1.9 : Fixed bug: If you requested a new style conf file in DOCUMENT_ROOT,
|
||||||
** and didn't have an old style conf file, it would fail
|
** and didn't have an old style conf file, it would fail
|
||||||
|
** 1.9a: Most other imagemap programs seem to allow a non-full path as the url,
|
||||||
|
** so we'll switch to that. Any url not starting with / goes to the
|
||||||
|
** same path as the map file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -80,11 +83,11 @@ static int pointincircle(double point[2], double coords[MAXVERTS][2]);
|
|||||||
static int pointinrect(double point[2], double coords[MAXVERTS][2]);
|
static int pointinrect(double point[2], double coords[MAXVERTS][2]);
|
||||||
|
|
||||||
int isname(char);
|
int isname(char);
|
||||||
|
char input[MAXLINE], *mapname, def[MAXLINE], conf[MAXLINE], errstr[MAXLINE];
|
||||||
|
double testpoint[2], pointarray[MAXVERTS][2];
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char input[MAXLINE], *mapname, def[MAXLINE], conf[MAXLINE], errstr[MAXLINE];
|
|
||||||
double testpoint[2], pointarray[MAXVERTS][2];
|
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *t;
|
char *t;
|
||||||
@ -111,7 +114,7 @@ int main(int argc, char **argv)
|
|||||||
* we get the translated path, and skip reading the configuration file.
|
* we get the translated path, and skip reading the configuration file.
|
||||||
*/
|
*/
|
||||||
if (strchr(mapname,'/')) {
|
if (strchr(mapname,'/')) {
|
||||||
strcpy(conf,getenv("PATH_TRANSLATED"));
|
strncpy(conf,getenv("PATH_TRANSLATED"),MAXLINE);
|
||||||
goto openconf;
|
goto openconf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +142,7 @@ int main(int argc, char **argv)
|
|||||||
*/
|
*/
|
||||||
if(feof(fp)) {
|
if(feof(fp)) {
|
||||||
struct stat sbuf;
|
struct stat sbuf;
|
||||||
strcpy(conf,getenv("PATH_TRANSLATED"));
|
strncpy(conf,getenv("PATH_TRANSLATED"),MAXLINE);
|
||||||
if (!stat(conf,&sbuf) && ((sbuf.st_mode & S_IFMT) == S_IFREG))
|
if (!stat(conf,&sbuf) && ((sbuf.st_mode & S_IFMT) == S_IFREG))
|
||||||
goto openconf;
|
goto openconf;
|
||||||
else
|
else
|
||||||
@ -240,19 +243,39 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
static void sendmesg(char *url)
|
static void sendmesg(char *url)
|
||||||
{
|
{
|
||||||
|
char *port;
|
||||||
|
char *path_info;
|
||||||
|
char path[MAXLINE];
|
||||||
|
|
||||||
if (strchr(url, ':')) /*** It is a full URL ***/
|
if (strchr(url, ':')) /*** It is a full URL ***/
|
||||||
printf("Location: ");
|
printf("Location: %s%c%c",url,LF,LF);
|
||||||
else { /*** It is a virtual URL ***/
|
else { /*** It is a virtual URL ***/
|
||||||
char *port;
|
|
||||||
printf("Location: http://%s", getenv("SERVER_NAME"));
|
printf("Location: http://%s", getenv("SERVER_NAME"));
|
||||||
|
|
||||||
/* only add port if it's not the default */
|
/* only add port if it's not the default */
|
||||||
if ((port = getenv("SERVER_PORT")) && strcmp(port,"80"))
|
if ((port = getenv("SERVER_PORT")) && strcmp(port,"80"))
|
||||||
printf(":%s",port);
|
printf(":%s",port);
|
||||||
|
|
||||||
|
/* if its a full path, just use it, else add path from PATH_INFO */
|
||||||
|
if (url[0] == '/') {
|
||||||
|
printf("%s%c%c",url,LF,LF);
|
||||||
|
} else {
|
||||||
|
if ((path_info = getenv("PATH_INFO"))) {
|
||||||
|
char *last = strrchr(path_info,'/');
|
||||||
|
int x = 0;
|
||||||
|
while (((path_info+x) <= last) && (x < MAXLINE)) {
|
||||||
|
path[x] = *(path_info+x);
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
path[x] = '\0';
|
||||||
|
} else {
|
||||||
|
strcpy(path,"/");
|
||||||
|
}
|
||||||
|
printf("%s%s%c%c",path,url,LF,LF);
|
||||||
}
|
}
|
||||||
printf("%s%c%c",url,10,10);
|
}
|
||||||
printf("This document has moved <A HREF=\"%s\">here</A>%c",url,10);
|
printf("This document has moved <A HREF=\"%s\">here</A>%c",url,LF);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pointinrect(double point[2], double coords[MAXVERTS][2])
|
static int pointinrect(double point[2], double coords[MAXVERTS][2])
|
||||||
@ -341,7 +364,7 @@ static int pointinpoly(double point[2], double pgon[MAXVERTS][2])
|
|||||||
|
|
||||||
static void servererr(char *msg)
|
static void servererr(char *msg)
|
||||||
{
|
{
|
||||||
printf("Content-type: text/html%c%c",10,10);
|
printf("Content-type: text/html%c%c",LF,LF);
|
||||||
printf("<title>Mapping Server Error</title>");
|
printf("<title>Mapping Server Error</title>");
|
||||||
printf("<h1>Mapping Server Error</h1>");
|
printf("<h1>Mapping Server Error</h1>");
|
||||||
printf("This server encountered an error:<p>");
|
printf("This server encountered an error:<p>");
|
||||||
|
0
cgi-src/phf.c
Executable file → Normal file
0
cgi-src/phf.c
Executable file → Normal file
0
cgi-src/query.c
Executable file → Normal file
0
cgi-src/query.c
Executable file → Normal file
@ -139,7 +139,7 @@ void escape_shell_cmd(char *cmd) {
|
|||||||
|
|
||||||
l=strlen(cmd);
|
l=strlen(cmd);
|
||||||
for(x=0;cmd[x];x++) {
|
for(x=0;cmd[x];x++) {
|
||||||
if(ind("&;`'\"|*?~<>^()[]{}$\\",cmd[x]) != -1){
|
if(ind("&;`'\"|*?~<>^()[]{}$\\\x0A",cmd[x]) != -1){
|
||||||
for(y=l+1;y>x;y--)
|
for(y=l+1;y>x;y--)
|
||||||
cmd[y] = cmd[y-1];
|
cmd[y] = cmd[y-1];
|
||||||
l++; /* length has been increased */
|
l++; /* length has been increased */
|
||||||
|
@ -160,13 +160,13 @@ AccessConfig conf/access.conf
|
|||||||
|
|
||||||
LogOptions Separate
|
LogOptions Separate
|
||||||
|
|
||||||
# LogDirGroupWriteOk, LogDirPublicWriteOk: Define either of these if you
|
# LogDirGroupWriteOk, LogDirOtherWriteOk: Define either of these if you
|
||||||
# want the server to start even if you have write permissions on the log
|
# want the server to start even if you have write permissions on the log
|
||||||
# directory. Having write permissions set is a potential security hole.
|
# directory. Having write permissions set is a potential security hole.
|
||||||
# Only makes a difference if the server process is started by root.
|
# Only makes a difference if the server process is started by root.
|
||||||
|
|
||||||
#LogDirGroupWriteOk
|
#LogDirGroupWriteOk
|
||||||
#LogDirPublicWriteOk
|
#LogDirOtherWriteOk
|
||||||
|
|
||||||
# RefererIgnore: If you don't want to keep track of links from certain
|
# RefererIgnore: If you don't want to keep track of links from certain
|
||||||
# servers (like your own), place it here. If you want to log them all,
|
# servers (like your own), place it here. If you want to log them all,
|
||||||
|
@ -43,6 +43,19 @@ Alias /icons/ /usr/local/etc/httpd/icons/
|
|||||||
|
|
||||||
ScriptAlias /cgi-bin/ /usr/local/etc/httpd/cgi-bin/
|
ScriptAlias /cgi-bin/ /usr/local/etc/httpd/cgi-bin/
|
||||||
|
|
||||||
|
#===========================================================================
|
||||||
|
# OpenMarket's FCGI Support Options (http://www.fastcgi.com/
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# FCGIScritpAlias: Same as ScriptAlias, except for FCGI scripts
|
||||||
|
# Format: FCGIScriptAlias fakename realname
|
||||||
|
|
||||||
|
FCGIScriptAlias /fcgi-bin/ /usr/local/etc/httpd/fcgi-devel-kit/examples/
|
||||||
|
|
||||||
|
# Define the AppClasses. These get hit when requests come in for
|
||||||
|
# /fcgi-bin/tiny-fcgi.fcgi or /fcgi-bin/tiny-fcgi2.fcgi
|
||||||
|
AppClass /usr/local/etc/httpd/fcgi-devel-kit/examples/tiny-fcgi.fcgi -listen-queue-depth 10 -processes 2
|
||||||
|
AppClass /usr/local/etc/httpd/fcgi-devel-kit/examples/tiny-fcgi2.fcgi -listen-queue-depth 10 -processes 2
|
||||||
|
|
||||||
#===========================================================================
|
#===========================================================================
|
||||||
# Directory Indexing
|
# Directory Indexing
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@ -122,8 +135,8 @@ DefaultType text/plain
|
|||||||
# AddEncoding allows you to have certain browsers (Mosaic/X 2.1+) uncompress
|
# AddEncoding allows you to have certain browsers (Mosaic/X 2.1+) uncompress
|
||||||
# information on the fly. Note: Not all browsers support this.
|
# information on the fly. Note: Not all browsers support this.
|
||||||
|
|
||||||
#AddEncoding x-compress Z
|
#AddEncoding compress Z
|
||||||
#AddEncoding x-gzip gz
|
#AddEncoding gzip gz
|
||||||
|
|
||||||
# The following are known to the server as "Magic Mime Types" They allow
|
# The following are known to the server as "Magic Mime Types" They allow
|
||||||
# you to change how the server perceives a document by the extension
|
# you to change how the server perceives a document by the extension
|
||||||
@ -137,6 +150,7 @@ DefaultType text/plain
|
|||||||
#AddType text/x-server-parsed-html .shtml
|
#AddType text/x-server-parsed-html .shtml
|
||||||
#AddType text/x-imagemap .map
|
#AddType text/x-imagemap .map
|
||||||
#AddType application/x-httpd-cgi .cgi
|
#AddType application/x-httpd-cgi .cgi
|
||||||
|
#AddType application/x-httpd-fcgi .fcgi
|
||||||
|
|
||||||
#===========================================================================
|
#===========================================================================
|
||||||
# Misc Server Resources
|
# Misc Server Resources
|
||||||
|
16
src/CHANGES
Normal file
16
src/CHANGES
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
Fixes for 1.5.2
|
||||||
|
------------------
|
||||||
|
*) Changed getline rfc822 line wrap to check for validity of the next bits
|
||||||
|
before attempting to see them
|
||||||
|
*) Changed imagemap.c so relative URLs actually work
|
||||||
|
*) Don't core dump on a method only request
|
||||||
|
*) reset errno to 0 in send_fp so we break out of loop
|
||||||
|
*) somewhere we stopped killing cgi scripts on SIGALRM and SIGPIPE
|
||||||
|
*) changed group handling support to support multiple groups again
|
||||||
|
*) reset content_length before scanning cgi headers, not after
|
||||||
|
*) don't free env var in replace (it uses allocate now)
|
||||||
|
*) Only look for path_info if its part of the requested URL (as opposed
|
||||||
|
to keep looking until you hit a real directory)
|
||||||
|
*) Make make_dirstr() in util.c return / instead of null if n = 1
|
||||||
|
|
37
src/FEATURE_REQUESTS
Normal file
37
src/FEATURE_REQUESTS
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
Port configurable per VirtualHost
|
||||||
|
kadow@msg.net (Kevin Kadow)
|
||||||
|
Server Parse CGI output
|
||||||
|
not feasible because SSI parser using buffered I/O, CGI uses getline()
|
||||||
|
(server buffered I/O)
|
||||||
|
But, we did it anyways. See CGI_SSI_HACK in config.h
|
||||||
|
Allow extra CGI environment variables to be specified via configuration
|
||||||
|
Kevin Kadow (kadow@msg.net) and Brian Millett (bpm@techapp.com)
|
||||||
|
Shouldn't be too hard, probably in 1.5.1b4
|
||||||
|
Ok, maybe in 1.5.2
|
||||||
|
AuthUserScript - Heiner Schorn (Heiner.Schorn@informatik.umu.se)
|
||||||
|
Pass a user name to a script, it returns the password to check against
|
||||||
|
the one the client sent to the server. This is safe from someone
|
||||||
|
writing a script to gather passwords, because the given password is
|
||||||
|
never sent to the script. This is unsafe on the server system because
|
||||||
|
it will return the password of a user. That could be made safer by
|
||||||
|
making the mechanism employ crypt on the password before hand..
|
||||||
|
Shouldn't be too hard, but needs some design work. Perhaps 1.5.1b4
|
||||||
|
Ok, maybe 1.5.2
|
||||||
|
Have separate UID/GID per CGI script - Marc Evans (marc@destek.net)
|
||||||
|
With Patch (NF-1.5b7-marc_cgi_uid_hack)
|
||||||
|
Basically, changes calls from setuid to seteuid, so it changes the
|
||||||
|
effective user id of the server. This makes any security hole
|
||||||
|
potentially dangerous, such as the one in 1.3, since the program
|
||||||
|
that you can force to run can set the euid back to root.
|
||||||
|
Look at it for 1.5.1b4, probably always have to be a #define for the
|
||||||
|
more security conscious users of NCSA HTTPd
|
||||||
|
Push off to 1.5.2
|
||||||
|
SHTTP
|
||||||
|
Alpha is done, but we need to test it more
|
||||||
|
SSL
|
||||||
|
Again, alpha code is in place, but it needs to be tested more
|
||||||
|
RADIUS
|
||||||
|
Ok, I was expecting something slightly different. Doesn't quite fit
|
||||||
|
the current way of doing things, but shouldn't be too hard to figure
|
||||||
|
out either. Probably 1.5.2
|
81
src/HTTP_HEADERS
Normal file
81
src/HTTP_HEADERS
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
|
||||||
|
The following is NCSA HTTPd treatment of HTTP headers. By Supported,
|
||||||
|
we mean that the server explicitly manipulates the headers. This
|
||||||
|
doesn't include forwarding of headers to CGI scripts or including
|
||||||
|
headers from CGI scripts.
|
||||||
|
|
||||||
|
In
|
||||||
|
HTTP HEADER HTTP Section Sup to/why length Used for?
|
||||||
|
Date 1.0 General N Do I care what the clients date is?
|
||||||
|
MIME-Version 1.0 General N The server isn't MIME Compliant
|
||||||
|
Pragma 1.0 General N Only no-cache is defined, and this isn't a proxy server
|
||||||
|
Authorization 1.0 Request Y reqInfo->inh_auth_line HUGE_STRING_LEN Authentication (Basic/MD5/Keberos)
|
||||||
|
From 1.0 Request N no one uses it
|
||||||
|
If-Modified-Since 1.0 Request Y reqInfo->inh_if_mod MAX_STRING_LEN 304 Use Local Copy response
|
||||||
|
Referer 1.0 Request Y reqInfo->inh_referer HUGE_STRING_LEN Logs
|
||||||
|
User-agent 1.0 Request Y reqInfo->inh_agent HUGE_STRING_LEN Logs
|
||||||
|
Allow 1.0 Entity N not clear how useful in request
|
||||||
|
Content-Encoding 1.0 Entity N
|
||||||
|
Content-Length 1.0 Entity Y reqInfo->inh_content_length int POST content length
|
||||||
|
Content-Type 1.0 Entity Y reqInfo->inh_content_type MAX_STRING_LEN POST content should be application/x-www-form-urlencoded
|
||||||
|
Expires 1.0 Entity N time request expires?
|
||||||
|
Last-Modified 1.0 Entity N last time request was modified?
|
||||||
|
Cache-Control 1.1 General N
|
||||||
|
Connection 1.1 General Y Keep-Alive
|
||||||
|
Forwarded 1.1 General N
|
||||||
|
Keep-Alive 1.1 General N max= timeout= same
|
||||||
|
Upgrade 1.1 General N
|
||||||
|
Accept 1.1 Request N
|
||||||
|
Accept-Charset 1.1 Request N
|
||||||
|
Accept-Encoding 1.1 Request N
|
||||||
|
Accept-Language 1.1 Request N
|
||||||
|
Host 1.1 Request Y reqInfo->inh_called_hostname MAX_STRING_LEN to provide virtual host support with CNAMES
|
||||||
|
Proxy-Authorization 1.1 Request N
|
||||||
|
Range 1.1 Request N
|
||||||
|
Unless 1.1 Request N
|
||||||
|
Content-Language 1.1 Entity N
|
||||||
|
Content-MD5 1.1 Entity N
|
||||||
|
Content-Range 1.1 Entity N
|
||||||
|
Content-Version 1.1 Entity N
|
||||||
|
Derived-From 1.1 Entity N
|
||||||
|
Link 1.1 Entity N
|
||||||
|
Title 1.1 Entity N
|
||||||
|
Transfer-Encoding 1.1 Entity N
|
||||||
|
URI-header 1.1 Entity N
|
||||||
|
Extension
|
||||||
|
|
||||||
|
|
||||||
|
Out
|
||||||
|
HTTP HEADER HTTP Section Sup from/why
|
||||||
|
Date 1.0 General Y GMT Date in rfc 822 format
|
||||||
|
MIME-Version 1.0 General N The server isn't MIME Compliant
|
||||||
|
Pragma 1.0 General N Only no-cache is defined, and this isn't a proxy server
|
||||||
|
Location 1.0 Response Y reqInfo->outh_location HUGE_STRING_LEN redirects
|
||||||
|
Server 1.0 Response Y #define SERVER_VERSION
|
||||||
|
WWW-Authenticate 1.0 Response Y reqInfo->outh_www_auth HUGE_STRING_LEN
|
||||||
|
Allow 1.0 Entity N We could make a list in evaluate_access(), but wouldn't that be a security hole?
|
||||||
|
Content-Encoding 1.0 Entity Y reqInfo->outh_content_encoding MAX_STRING_LEN AddEncoding
|
||||||
|
Content-Length 1.0 Entity Y reqInfo->outh_content_length int
|
||||||
|
Content-Type 1.0 Entity Y reqInfo->outh_content_type MAX_STRING_LEN
|
||||||
|
Expires 1.0 Entity N could add an AddExpires config option
|
||||||
|
Last-Modified 1.0 Entity Y reqInfo->outh_last_mod MAX_STRING_LEN client caching
|
||||||
|
Cache-Control 1.1 General N
|
||||||
|
Connection 1.1 General Y keep_alive. stuff Keep-Alive
|
||||||
|
Forwarded 1.1 General N
|
||||||
|
Keep-Alive 1.1 General Y max= timeout= same
|
||||||
|
Upgrade 1.1 General N
|
||||||
|
Proxy-Authenticate 1.1 Response N
|
||||||
|
Public 1.1 Response N
|
||||||
|
Retry-After 1.1 Response N
|
||||||
|
Content-Language 1.1 Entity N
|
||||||
|
Content-MD5 1.1 Entity Y reqInfo->outh_content_md5 allocated do you get what you asked for
|
||||||
|
Content-Range 1.1 Entity N
|
||||||
|
Content-Version 1.1 Entity N
|
||||||
|
Derived-From 1.1 Entity N
|
||||||
|
Link 1.1 Entity N
|
||||||
|
Title 1.1 Entity N
|
||||||
|
Transfer-Encoding 1.1 Entity N
|
||||||
|
URI-header 1.1 Entity N
|
||||||
|
Annotations-cgi reqInfo->hostInfo->annotation_server
|
||||||
|
Extension: Domain-Restricted reqInfo->bNotifyDomainRestricted &&
|
||||||
|
reqInfo->bSatisfiedDomain
|
212
src/HTTPd_REQ_PATH
Normal file
212
src/HTTPd_REQ_PATH
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
child_main httpd.c
|
||||||
|
GetDescriptor httpd.c
|
||||||
|
setproctitle
|
||||||
|
recv_fd
|
||||||
|
GetRemoteLogName httpd.c
|
||||||
|
getpeername
|
||||||
|
rfc931
|
||||||
|
initialize_request http_request.c
|
||||||
|
malloc
|
||||||
|
reset_security http_access.c
|
||||||
|
free
|
||||||
|
init_header_vars http_mime.c
|
||||||
|
free
|
||||||
|
RequestMain http_request.c
|
||||||
|
signal
|
||||||
|
getline
|
||||||
|
setproctitle
|
||||||
|
decode_request http_request.c
|
||||||
|
strtok
|
||||||
|
MapMethod http_request.c
|
||||||
|
get_mime_headers
|
||||||
|
getline
|
||||||
|
strchr
|
||||||
|
isspace
|
||||||
|
strcasecmp
|
||||||
|
http2cgi util.c
|
||||||
|
merge_header env.c
|
||||||
|
realloc
|
||||||
|
make_env_str env.c
|
||||||
|
malloc
|
||||||
|
realloc
|
||||||
|
unescape_url util.c
|
||||||
|
which_host_conf
|
||||||
|
get_local_addr
|
||||||
|
getsockname
|
||||||
|
get_remote_host util.c
|
||||||
|
getpeername
|
||||||
|
strdup
|
||||||
|
gethostbyaddr
|
||||||
|
gethostbyname
|
||||||
|
inet_ntoa
|
||||||
|
process_request http_request.c
|
||||||
|
translate_name http_alias.c
|
||||||
|
getparents util.c
|
||||||
|
make_full_path util.c
|
||||||
|
log_reason
|
||||||
|
malloc
|
||||||
|
log_error util.c
|
||||||
|
free
|
||||||
|
send_node http_send.c
|
||||||
|
stat
|
||||||
|
extract_path_info http_send.c
|
||||||
|
count_dirs util.c
|
||||||
|
make_dirstr util.c
|
||||||
|
stat
|
||||||
|
evaluate_access http_access.c
|
||||||
|
no2slash util.c
|
||||||
|
reset_mime_vars http_mime.c
|
||||||
|
is_matchexp util.c
|
||||||
|
strcmp_match util.c
|
||||||
|
check_dir_access http_access.c
|
||||||
|
find_allow http_access.c
|
||||||
|
in_ip http_access.c
|
||||||
|
get_remote_host_min util.c
|
||||||
|
getpeername
|
||||||
|
gethostbyaddr
|
||||||
|
in_domain http_access.c
|
||||||
|
find_deny http_access.c
|
||||||
|
in_ip http_access.c
|
||||||
|
get_remote_host_min util.c
|
||||||
|
in_domain http_access.c
|
||||||
|
parse_htaccess http_config.c
|
||||||
|
stat
|
||||||
|
FOpen fdwrap.c
|
||||||
|
parse_access_dir http_config.c
|
||||||
|
cfg_getline util.c
|
||||||
|
access_syntax_error http_config.c
|
||||||
|
cfg_getword util.c
|
||||||
|
add_type http_mime.c
|
||||||
|
malloc
|
||||||
|
strdup
|
||||||
|
add_encoding http_mime.c
|
||||||
|
malloc
|
||||||
|
strdup
|
||||||
|
add_desc http_dir.c
|
||||||
|
new_item http_dir.c
|
||||||
|
malloc
|
||||||
|
strdup
|
||||||
|
add_ignore http_dir.c
|
||||||
|
new_item http_dir.c
|
||||||
|
add_icon http_dir.c
|
||||||
|
add_alt http_dir.c
|
||||||
|
new_item http_dir.c
|
||||||
|
new_item http_dir.c
|
||||||
|
add_readme http_dir.c
|
||||||
|
new_item http_dir.c
|
||||||
|
add_header http_dir.c
|
||||||
|
new_item http_dir.c
|
||||||
|
add_opts http_dir.c
|
||||||
|
cfg_getword util.c
|
||||||
|
add_opts_int http_dir.c
|
||||||
|
new_item http_dir.c
|
||||||
|
strdup
|
||||||
|
FClose fdwrap.c
|
||||||
|
readlink
|
||||||
|
check_auth http_auth.c
|
||||||
|
auth_bong
|
||||||
|
uudecode
|
||||||
|
getword
|
||||||
|
get_pw
|
||||||
|
crypt
|
||||||
|
Digest_Check
|
||||||
|
k4_server_auth
|
||||||
|
k5_server_auth
|
||||||
|
check_krb_restrict
|
||||||
|
init_group http_auth.c
|
||||||
|
FOpen fdwrap.c
|
||||||
|
malloc
|
||||||
|
fread
|
||||||
|
FClose fdwrap.c
|
||||||
|
DBM_Open fdwrap.c
|
||||||
|
in_group http_auth.c
|
||||||
|
DBM_Close fdwrap.c
|
||||||
|
send_dir http_send.c
|
||||||
|
construct_url
|
||||||
|
escape_url
|
||||||
|
index_directory http_dir.c
|
||||||
|
Opendir
|
||||||
|
send_http_header
|
||||||
|
CloseDir
|
||||||
|
find_opts
|
||||||
|
find_header
|
||||||
|
insert_readme
|
||||||
|
make_dir_entry
|
||||||
|
malloc
|
||||||
|
qsort
|
||||||
|
output_directories
|
||||||
|
free
|
||||||
|
find_readme
|
||||||
|
insert_readme
|
||||||
|
log_transaction
|
||||||
|
probe_content_type http_mime.c
|
||||||
|
find_ct http_mime.c
|
||||||
|
send_cgi cgi.c
|
||||||
|
add_common_vars cgi.c
|
||||||
|
make_env_str env.c
|
||||||
|
cgi_stub cgi.c
|
||||||
|
can_exec util.c
|
||||||
|
Pipe fdwrap.c
|
||||||
|
fork
|
||||||
|
add_cgi_vars
|
||||||
|
error_log2stderr
|
||||||
|
execle/execve
|
||||||
|
getline util.c
|
||||||
|
write
|
||||||
|
read
|
||||||
|
scan_script_header cgi.c
|
||||||
|
getline util.c
|
||||||
|
strdup
|
||||||
|
realloc
|
||||||
|
waitpid
|
||||||
|
send_http_header http_mime.c
|
||||||
|
set_stat_line http_mime.c
|
||||||
|
free
|
||||||
|
strdup
|
||||||
|
begin_http_header http_log.c
|
||||||
|
dump_default_header http_mime.c
|
||||||
|
send_script cgi.c
|
||||||
|
alarm
|
||||||
|
getline
|
||||||
|
write
|
||||||
|
read
|
||||||
|
kill_children cgi.c
|
||||||
|
sleep
|
||||||
|
kill
|
||||||
|
waitpid
|
||||||
|
log_transaction
|
||||||
|
send_file http_send.c
|
||||||
|
set_content_type http_mime.c
|
||||||
|
find_ct http_mime.c
|
||||||
|
send_parsed_file http_include.c
|
||||||
|
FOpen fdwrap.c
|
||||||
|
set_content_length http_mime.c
|
||||||
|
set_last_modified http_mime.c
|
||||||
|
gmtime
|
||||||
|
strftime
|
||||||
|
later_than util.c
|
||||||
|
send_http_header http_mime.c
|
||||||
|
send_fd http_send.c
|
||||||
|
signal
|
||||||
|
fread
|
||||||
|
write
|
||||||
|
log_transaction http_log.c
|
||||||
|
FClose fdwrap.c
|
||||||
|
probe_content_type http_mime.c
|
||||||
|
send_cgi cgi.c
|
||||||
|
send_imagemap imagemap.c
|
||||||
|
FOpen fdwrap.c
|
||||||
|
pointinpoly imagemap.c
|
||||||
|
sendmsg imagemap.c
|
||||||
|
pointincircle imagemap.c
|
||||||
|
pointinrect imagemap.c
|
||||||
|
FClose fdwrap.c
|
||||||
|
send_file http_send.c
|
||||||
|
exec_cgi_script cgi.c
|
||||||
|
get_path_info
|
||||||
|
evaluate_access
|
||||||
|
add_common_vars
|
||||||
|
cgi_stub
|
||||||
|
CompleteRequest httpd.c
|
||||||
|
CloseAll fd_wrap.c
|
||||||
|
free_request http_request.c
|
83
src/Makefile
83
src/Makefile
@ -1,12 +1,13 @@
|
|||||||
# NCSA HTTPd 1.5
|
# NCSA HTTPd 1.5
|
||||||
#
|
#
|
||||||
# For normal machines with ANSI compilers
|
# For normal machines with ANSI compilers
|
||||||
# CC= cc
|
#CC= cc
|
||||||
# For Suns or other non-ANSI platforms.
|
# For Suns or other non-ANSI platforms.
|
||||||
CC= gcc
|
CC= gcc
|
||||||
QUANTIFY=/hdf2/pure/quantify-2.0-sunos4/quantify
|
#CC = xlc
|
||||||
PURIFY=purify
|
QUANTIFY=/hdf2/pure/quantify-2.0.1-sunos4/quantify
|
||||||
|
PURIFY=/hdf2/pure/purify-3.2-sunos4/purify
|
||||||
|
#PURIFY=/X11/sgi5/purify3.1/purify
|
||||||
|
|
||||||
# CFLAGS, compile flags.
|
# CFLAGS, compile flags.
|
||||||
#
|
#
|
||||||
@ -14,12 +15,17 @@ PURIFY=purify
|
|||||||
# All other defines are in config.h
|
# All other defines are in config.h
|
||||||
# If you want to ensure that CGI scripts can't mess with the log files,
|
# If you want to ensure that CGI scripts can't mess with the log files,
|
||||||
# use -DSECURE_LOGS
|
# use -DSECURE_LOGS
|
||||||
#
|
|
||||||
|
|
||||||
CFLAGS= -g
|
CFLAGS= -g
|
||||||
#CFLAGS= -pg -DPROFILE
|
#CFLAGS= -pg -DPROFILE
|
||||||
#CFLAGS= -g -Wall -ansi -pedantic
|
#CFLAGS= -g -ansi -pedantic -Wall -DAIX_BROKEN_HEADERS
|
||||||
|
|
||||||
|
# FCGI Support
|
||||||
|
#
|
||||||
|
# To enable Openmarkets FCGI, uncomment the following
|
||||||
|
# Currently uses the TCL library for strings, which requires the math library
|
||||||
|
|
||||||
|
#FCGI_CFLAGS = -DFCGI_SUPPORT -I/local/include
|
||||||
|
|
||||||
# DIGEST AUTHENTICATION
|
# DIGEST AUTHENTICATION
|
||||||
#
|
#
|
||||||
@ -46,8 +52,8 @@ KRB5_CFLAGS = -DKRB5 -I$(KRB5_DIR)/include -I$(KRB5_DIR)/include/krb5
|
|||||||
|
|
||||||
# Comment out the following two lines to exclude Kerberos support
|
# Comment out the following two lines to exclude Kerberos support
|
||||||
|
|
||||||
# KRB_CFLAGS = $(KRB4_CFLAGS) $(KRB5_CFLAGS) # -DKRB-ENCRYPT
|
#KRB_CFLAGS = $(KRB4_CFLAGS) $(KRB5_CFLAGS) # -DKRB-ENCRYPT
|
||||||
# KRB_LIBS = $(KRB4_LIBS) $(KRB5_LIBS)
|
#KRB_LIBS = $(KRB4_LIBS) $(KRB5_LIBS)
|
||||||
|
|
||||||
|
|
||||||
# DBM
|
# DBM
|
||||||
@ -81,7 +87,7 @@ LFLAGS= # -pg -DPROFILE
|
|||||||
# EXTRA_LIBS= -lresolv
|
# EXTRA_LIBS= -lresolv
|
||||||
# For Solaris 2.x
|
# For Solaris 2.x
|
||||||
# AUX_CFLAGS= -DSOLARIS2
|
# AUX_CFLAGS= -DSOLARIS2
|
||||||
# EXTRA_LIBS= -lsocket -lnsl
|
# EXTRA_LIBS= -lsocket -lnsl
|
||||||
# For SGI IRIX. Use the EXTRA_LIBS line if you're using NIS and want
|
# For SGI IRIX. Use the EXTRA_LIBS line if you're using NIS and want
|
||||||
# user-supported directories
|
# user-supported directories
|
||||||
# AUX_CFLAGS= -DIRIX
|
# AUX_CFLAGS= -DIRIX
|
||||||
@ -89,7 +95,7 @@ LFLAGS= # -pg -DPROFILE
|
|||||||
# For HP-UX
|
# For HP-UX
|
||||||
# AUX_CFLAGS= -DHPUX
|
# AUX_CFLAGS= -DHPUX
|
||||||
# For AIX3
|
# For AIX3
|
||||||
AUX_CFLAGS= -DAIX3
|
# AUX_CFLAGS= -DAIX3 -D_ALL_SOURCE # For xlc compiler
|
||||||
# For AIX4
|
# For AIX4
|
||||||
# AUX_CFLAGS= -DAIX4
|
# AUX_CFLAGS= -DAIX4
|
||||||
# For Ultrix
|
# For Ultrix
|
||||||
@ -101,7 +107,8 @@ LFLAGS= # -pg -DPROFILE
|
|||||||
# For Sequent
|
# For Sequent
|
||||||
# AUX_CFLAGS= -DSEQUENT
|
# AUX_CFLAGS= -DSEQUENT
|
||||||
# For Linux -m486 ONLY IF YOU HAVE 486 BINARY SUPPORT IN KERNEL
|
# For Linux -m486 ONLY IF YOU HAVE 486 BINARY SUPPORT IN KERNEL
|
||||||
# AUX_CFLAGS= -DLINUX
|
# AUX_CFLAGS= -DLINUX # -DFD_LINUX for Linux 1.2.13
|
||||||
|
# DBM_LIBS = -lgdbm
|
||||||
# For NetBSD 1.0
|
# For NetBSD 1.0
|
||||||
# May not need -lcrypt if its included in your libc
|
# May not need -lcrypt if its included in your libc
|
||||||
# AUX_CFLAGS= -DNetBSD
|
# AUX_CFLAGS= -DNetBSD
|
||||||
@ -120,6 +127,9 @@ LFLAGS= # -pg -DPROFILE
|
|||||||
# For SCO SVR3.2
|
# For SCO SVR3.2
|
||||||
# AUX_CFLAGS= -DSCO3
|
# AUX_CFLAGS= -DSCO3
|
||||||
# EXTRA_LIBS= -lPW -lsocket -lmalloc -lintl -lcrypt
|
# EXTRA_LIBS= -lPW -lsocket -lmalloc -lintl -lcrypt
|
||||||
|
# For SCO OpenServer 5
|
||||||
|
# AUX_CFLAGS= -DSCO5
|
||||||
|
# EXTRA_LIBS= -lPW -lsocket -lmalloc -lintl -lcrypt
|
||||||
# For SVR4
|
# For SVR4
|
||||||
# AUX_CFLAGS= -DSVR4
|
# AUX_CFLAGS= -DSVR4
|
||||||
# EXTRA_LIBS= -lsocket -lnsl -lc
|
# EXTRA_LIBS= -lsocket -lnsl -lc
|
||||||
@ -142,18 +152,21 @@ LFLAGS= # -pg -DPROFILE
|
|||||||
# -------------- You shouldn't have to edit anything else -----------------
|
# -------------- You shouldn't have to edit anything else -----------------
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
SEC_CFLAGS = $(MD5_CFLAGS) $(PGP_CFLAGS) $(KRB_CFLAGS)
|
SEC_CFLAGS = $(MD5_CFLAGS) $(KRB_CFLAGS)
|
||||||
SEC_LIBS = $(KRB_LIBS)
|
SEC_LIBS = $(KRB_LIBS)
|
||||||
|
|
||||||
|
ALL_CFLAGS = $(CFLAGS) $(AUX_CFLAGS) $(SEC_CFLAGS) $(DBM_CFLAGS) $(FCGI_CFLAGS)
|
||||||
|
ALL_LIBS = $(EXTRA_LIBS) $(SEC_LIBS) $(DBM_LIBS)
|
||||||
|
|
||||||
|
|
||||||
OBJS=httpd.o http_config.o http_request.o util.o http_dir.o \
|
OBJS=httpd.o http_config.o http_request.o util.o http_dir.o \
|
||||||
http_alias.o http_log.o http_mime.o http_access.o http_auth.o \
|
http_alias.o http_log.o http_mime.o http_access.o http_auth.o \
|
||||||
http_send.o cgi.o http_include.o rfc931.o imagemap.o \
|
http_send.o cgi.o http_include.o rfc931.o imagemap.o \
|
||||||
http_ipc.o digest.o md5.o md5c.o env.o host_config.o fdwrap.o \
|
http_ipc.o digest.o md5.o md5c.o env.o host_config.o fdwrap.o \
|
||||||
open_logfile.o
|
open_logfile.o allocate.o debug.o blackout.o fcgi.o
|
||||||
|
|
||||||
.c.o: Makefile config.h portability.h constants.h
|
.c.o: Makefile config.h portability.h constants.h
|
||||||
$(CC) -c $(CFLAGS) $(AUX_CFLAGS) $(SEC_CFLAGS) $(DBM_CFLAGS) $<
|
$(CC) -c $(ALL_CFLAGS) $<
|
||||||
|
|
||||||
all: httpd
|
all: httpd
|
||||||
|
|
||||||
@ -176,6 +189,10 @@ hp-cc:
|
|||||||
linux:
|
linux:
|
||||||
make tar AUX_CFLAGS=-DLINUX CC=gcc CFLAGS=-O2 DBM_LIBS=-lgdbm
|
make tar AUX_CFLAGS=-DLINUX CC=gcc CFLAGS=-O2 DBM_LIBS=-lgdbm
|
||||||
|
|
||||||
|
linux2: linux
|
||||||
|
linux1:
|
||||||
|
make tar AUX_CFLAGS="-DLINUX -DFD_LINUX" CC=gcc CFLAGS=-O2 DBM_LIBS=-lgdbm
|
||||||
|
|
||||||
netbsd:
|
netbsd:
|
||||||
make tar AUX_CFLAGS=-DNETBSD EXTRA_LIBS=-lcrypt CC=cc CFLAGS=-O2
|
make tar AUX_CFLAGS=-DNETBSD EXTRA_LIBS=-lcrypt CC=cc CFLAGS=-O2
|
||||||
|
|
||||||
@ -185,6 +202,9 @@ next:
|
|||||||
osf1:
|
osf1:
|
||||||
make tar AUX_CFLAGS=-DOSF1 CC=cc CFLAGS="-O2 -Olimit 750"
|
make tar AUX_CFLAGS=-DOSF1 CC=cc CFLAGS="-O2 -Olimit 750"
|
||||||
|
|
||||||
|
sco5:
|
||||||
|
make tar AUX_CFLAGS=-DSCO5 CC=icc CFLAGS="" EXTRA_LIBS="-lPW -lsocket -lmalloc -lintl -lcrypt" DBM_LIBS=-ldbm
|
||||||
|
|
||||||
sgi:
|
sgi:
|
||||||
make tar AUX_CFLAGS=-DIRIX EXTRA_LIBS=-lsun CC=cc CFLAGS=-O2
|
make tar AUX_CFLAGS=-DIRIX EXTRA_LIBS=-lsun CC=cc CFLAGS=-O2
|
||||||
|
|
||||||
@ -203,21 +223,22 @@ ultrix:
|
|||||||
make tar AUX_CFLAGS=-DULTRIX CC=gcc CFLAGS=-O2
|
make tar AUX_CFLAGS=-DULTRIX CC=gcc CFLAGS=-O2
|
||||||
|
|
||||||
httpd: $(OBJS)
|
httpd: $(OBJS)
|
||||||
$(CC) $(LFLAGS) -o httpd $(OBJS) $(EXTRA_LIBS) $(SEC_LIBS) $(DBM_LIBS)
|
$(CC) $(LFLAGS) -o httpd $(OBJS) $(ALL_LIBS)
|
||||||
|
|
||||||
|
# -logfile=/X11/blong/httpd/logs/pure_log
|
||||||
purify: $(OBJS)
|
purify: $(OBJS)
|
||||||
$(PURIFY) -logfile=/X11/blong/httpd/logs/pure_log \
|
$(PURIFY) -program-name=/X11/blong/httpd/src/httpd \
|
||||||
-program-name=/X11/blong/httpd/src/httpd \
|
|
||||||
-follow-child-processes=yes \
|
-follow-child-processes=yes \
|
||||||
$(CC) $(LFLAGS) -o httpd $(OBJS) $(EXTRA_LIBS) $(SEC_LIBS) $(DBM_LIBS)
|
$(CC) $(LFLAGS) -o httpd $(OBJS) $(ALL_LIBS)
|
||||||
|
|
||||||
quantify: $(OBJS)
|
quantify: $(OBJS)
|
||||||
$(QUANTIFY) -record-child-process-data=yes \
|
$(QUANTIFY) -record-child-process-data=yes \
|
||||||
-avoid-recording-system-calls=93,113,114 \
|
-record-data=no \
|
||||||
$(CC) $(LFLAGS) -o httpd $(OBJS) $(EXTRA_LIBS) $(SEC_LIBS) $(DBM_LIBS)
|
-avoid-recording-system-calls=1,6,93,113,114 \
|
||||||
|
$(CC) $(LFLAGS) -o httpd $(OBJS) $(ALL_LIBS)
|
||||||
|
|
||||||
tar: $(OBJS)
|
tar: $(OBJS)
|
||||||
$(CC) $(LFLAGS) -o ../httpd $(OBJS) $(EXTRA_LIBS) $(SEC_LIBS) $(DBM_LIBS)
|
$(CC) $(LFLAGS) -o ../httpd $(OBJS) $(ALL_LIBS)
|
||||||
|
|
||||||
|
|
||||||
http_access.o: Makefile config.h portability.h constants.h http_access.h \
|
http_access.o: Makefile config.h portability.h constants.h http_access.h \
|
||||||
@ -248,13 +269,15 @@ http_log.o: config.h portability.h constants.h http_log.h \
|
|||||||
http_mime.o: Makefile config.h portability.h constants.h http_mime.h \
|
http_mime.o: Makefile config.h portability.h constants.h http_mime.h \
|
||||||
http_log.h util.h http_config.h http_access.h env.h
|
http_log.h util.h http_config.h http_access.h env.h
|
||||||
http_request.o: Makefile config.h portability.h constants.h http_request.h \
|
http_request.o: Makefile config.h portability.h constants.h http_request.h \
|
||||||
util.h http_mime.h http_config.h http_log.h http_auth.h \
|
allocate.h cgi.h env.h http_access.h http_alias.h \
|
||||||
httpd.h http_send.h cgi.h http_access.h host_config.h \
|
host_config.h http_config.h http_log.h http_send.h util.h
|
||||||
http_alias.h env.h
|
imagemap.o: Makefile constants.h imagemap.h allocate.h
|
||||||
imagemap.o: Makefile constants.h imagemap.h
|
|
||||||
cgi.o: Makefile config.h portability.h constants.h cgi.h \
|
cgi.o: Makefile config.h portability.h constants.h cgi.h \
|
||||||
http_log.h http_request.h util.h http_mime.h http_access.h \
|
http_log.h http_request.h util.h http_mime.h http_access.h \
|
||||||
http_auth.h http_alias.h http_config.h
|
http_auth.h http_alias.h http_config.h
|
||||||
|
fcgi.o: Makefile config.h portability.h constants.h fcgi.h \
|
||||||
|
fdwrap.h cgi.h env.h http_request.h http_log.h http_access.h \
|
||||||
|
http_mime.h http_config.h http_auth.h http_alias.h util.h
|
||||||
httpd.o: Makefile config.h portability.h constants.h httpd.h \
|
httpd.o: Makefile config.h portability.h constants.h httpd.h \
|
||||||
http_request.h http_config.h http_log.h http_auth.h \
|
http_request.h http_config.h http_log.h http_auth.h \
|
||||||
http_dir.h http_access.h util.h http_ipc.h host_config.h \
|
http_dir.h http_access.h util.h http_ipc.h host_config.h \
|
||||||
@ -265,6 +288,8 @@ env.o: config.h portability.h constants.h http_log.h env.h
|
|||||||
rfc931.o: config.h portability.h
|
rfc931.o: config.h portability.h
|
||||||
open_logfile.o: config.h portability.h constants.h open_logfile.h \
|
open_logfile.o: config.h portability.h constants.h open_logfile.h \
|
||||||
http_config.h util.h
|
http_config.h util.h
|
||||||
|
allocate.o: config.h portability.h constants.h host_config.h http_log.h \
|
||||||
|
allocate.h
|
||||||
|
|
||||||
# file descriptor scoreboarding
|
# file descriptor scoreboarding
|
||||||
fdwrap.o: config.h portability.h constants.h fdwrap.h
|
fdwrap.o: config.h portability.h constants.h fdwrap.h
|
||||||
@ -282,5 +307,5 @@ SRC = $(OBJS:%.o=%.c)
|
|||||||
codecenter:
|
codecenter:
|
||||||
#setopt ansi
|
#setopt ansi
|
||||||
#setopt print_string 128
|
#setopt print_string 128
|
||||||
#setopt load_flags $(CFLAGS) $(AUX_CFLAGS) $(SEC_CFLAGS) $(DBM_CFLAGS)
|
#setopt load_flags $(ALL_FLAGS)
|
||||||
#load $(LFLAGS) $(SRC) $(EXTRA_LIBS) $(SEC_LIBS) $(DBM_LIBS)
|
#load $(LFLAGS) $(SRC) $(ALL_LIBS)
|
||||||
|
267
src/allocate.c
Normal file
267
src/allocate.c
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* NCSA HTTPd Server
|
||||||
|
* Software Development Group
|
||||||
|
* National Center for Supercomputing Applications
|
||||||
|
* University of Illinois at Urbana-Champaign
|
||||||
|
* 605 E. Springfield, Champaign, IL 61820
|
||||||
|
* httpd@ncsa.uiuc.edu
|
||||||
|
*
|
||||||
|
* Copyright (C) 1995, Board of Trustees of the University of Illinois
|
||||||
|
*
|
||||||
|
************************************************************************
|
||||||
|
*
|
||||||
|
* allocate.c,v 1.5 1996/04/05 18:54:28 blong Exp
|
||||||
|
*
|
||||||
|
************************************************************************
|
||||||
|
*
|
||||||
|
* allocate.c: Functions to allocate data types as needed
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "portability.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#ifndef NO_STDLIB_H
|
||||||
|
# include <stdlib.h>
|
||||||
|
#endif /* NO_STDLIB_H */
|
||||||
|
#ifndef NO_MALLOC_H
|
||||||
|
# ifdef NEED_SYS_MALLOC_H
|
||||||
|
# include <sys/malloc.h>
|
||||||
|
# else
|
||||||
|
# include <malloc.h>
|
||||||
|
# endif /* NEED_SYS_MALLOC_H */
|
||||||
|
#endif /* NO_MALLOC_H */
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "constants.h"
|
||||||
|
#include "host_config.h"
|
||||||
|
#include "http_log.h"
|
||||||
|
#include "allocate.h"
|
||||||
|
#include "http_request.h"
|
||||||
|
|
||||||
|
|
||||||
|
string_list free_list;
|
||||||
|
string_list used_list;
|
||||||
|
|
||||||
|
int initialize_allocate()
|
||||||
|
{
|
||||||
|
initialize_string_allocate();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int initialize_string_allocate()
|
||||||
|
{
|
||||||
|
free_list.num = 0;
|
||||||
|
free_list.first = NULL;
|
||||||
|
|
||||||
|
used_list.num = 0;
|
||||||
|
used_list.first = NULL;
|
||||||
|
|
||||||
|
allocate_strings(&free_list,HUGE_STRING_LEN,5);
|
||||||
|
allocate_strings(&free_list,MAX_STRING_LEN,5);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int allocate_strings(string_list *slist, int length, int num)
|
||||||
|
{
|
||||||
|
string_item *stmp;
|
||||||
|
char *S;
|
||||||
|
|
||||||
|
|
||||||
|
while (num) {
|
||||||
|
if (!(S = (char *) malloc(length * sizeof(char))))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
S[0] = '\0';
|
||||||
|
|
||||||
|
if (!(stmp = (string_item *) malloc(sizeof(string_item))))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
stmp->string = S;
|
||||||
|
stmp->length = length;
|
||||||
|
|
||||||
|
if (slist->num == 0) {
|
||||||
|
slist->first = stmp;
|
||||||
|
stmp->next = NULL;
|
||||||
|
slist->num = 1;
|
||||||
|
} else {
|
||||||
|
stmp->next = slist->first;
|
||||||
|
slist->first = stmp;
|
||||||
|
slist->num++;
|
||||||
|
}
|
||||||
|
num--;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int remove_string_item(string_list *slist, string_item *sitem)
|
||||||
|
{
|
||||||
|
string_item *stmp,*last;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
stmp = slist->first;
|
||||||
|
last = NULL;
|
||||||
|
|
||||||
|
for(x = 0; x < slist->num ; x++) {
|
||||||
|
if (stmp == sitem) {
|
||||||
|
if (stmp == slist->first) {
|
||||||
|
slist->first = slist->first->next;
|
||||||
|
} else {
|
||||||
|
last->next = stmp->next;
|
||||||
|
}
|
||||||
|
slist->num--;
|
||||||
|
stmp->next = NULL;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
last = stmp;
|
||||||
|
stmp = stmp->next;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int add_string_item(string_list *slist, string_item *sitem)
|
||||||
|
{
|
||||||
|
if (slist->num == 0) {
|
||||||
|
slist->first = sitem;
|
||||||
|
slist->num = 1;
|
||||||
|
} else {
|
||||||
|
sitem->next = slist->first;
|
||||||
|
slist->first = sitem;
|
||||||
|
slist->num++;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* newString(int length, int type)
|
||||||
|
{
|
||||||
|
int num, x;
|
||||||
|
string_item *sitem;
|
||||||
|
|
||||||
|
if (free_list.num == 0) {
|
||||||
|
if ((length == HUGE_STRING_LEN) || (length == MAX_STRING_LEN))
|
||||||
|
num = 5;
|
||||||
|
else
|
||||||
|
num = 1;
|
||||||
|
allocate_strings(&free_list, length, num);
|
||||||
|
}
|
||||||
|
|
||||||
|
sitem = free_list.first;
|
||||||
|
for(x = 0; x < free_list.num ; x++) {
|
||||||
|
if (sitem->length == length) {
|
||||||
|
remove_string_item(&free_list,sitem);
|
||||||
|
add_string_item(&used_list,sitem);
|
||||||
|
sitem->type = type;
|
||||||
|
return sitem->string;
|
||||||
|
}
|
||||||
|
sitem = sitem->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't have a string of the correct size, make one.
|
||||||
|
* Since allocate_strings adds strings to beginning of list, just return
|
||||||
|
* first string in used_list.
|
||||||
|
* In the future, might want to just return one which is larger.
|
||||||
|
*/
|
||||||
|
|
||||||
|
allocate_strings(&used_list, length, 1);
|
||||||
|
used_list.first->type = type;
|
||||||
|
return used_list.first->string;
|
||||||
|
}
|
||||||
|
|
||||||
|
int freeString(char *string)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
string_item *sitem;
|
||||||
|
|
||||||
|
if (string == NULL) return FALSE;
|
||||||
|
|
||||||
|
sitem = used_list.first;
|
||||||
|
for(x = 0; x < used_list.num ; x++) {
|
||||||
|
if (sitem->string == string) {
|
||||||
|
string[0] = '\0';
|
||||||
|
remove_string_item(&used_list,sitem);
|
||||||
|
add_string_item(&free_list,sitem);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
sitem = sitem->next;
|
||||||
|
}
|
||||||
|
log_error("Attempt to Free String not in Use",gConfiguration->error_log);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Look up allocated size of string
|
||||||
|
* Success returns lenth of string
|
||||||
|
* Failure returns -1
|
||||||
|
*/
|
||||||
|
int sizeofString(char *string)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
string_item *sitem;
|
||||||
|
|
||||||
|
if (string == NULL) return -1;
|
||||||
|
|
||||||
|
sitem = used_list.first;
|
||||||
|
for(x = 0; x < used_list.num ; x++) {
|
||||||
|
if (sitem->string == string) {
|
||||||
|
return sitem->length;
|
||||||
|
}
|
||||||
|
sitem = sitem->next;
|
||||||
|
}
|
||||||
|
/* log_error("String not allocated.",gConfiguration->error_log); */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int freeAllStrings(int type)
|
||||||
|
{
|
||||||
|
|
||||||
|
string_item *sitem,*slast;
|
||||||
|
|
||||||
|
slast = NULL;
|
||||||
|
sitem = used_list.first;
|
||||||
|
while (used_list.num && (sitem != NULL)) {
|
||||||
|
if (sitem->type <= type) {
|
||||||
|
sitem->string[0] = '\0';
|
||||||
|
if (sitem == used_list.first) {
|
||||||
|
used_list.first = sitem->next;
|
||||||
|
used_list.num--;
|
||||||
|
sitem->next = NULL;
|
||||||
|
add_string_item(&free_list,sitem);
|
||||||
|
sitem = used_list.first;
|
||||||
|
} else {
|
||||||
|
used_list.num--;
|
||||||
|
slast->next = sitem->next;
|
||||||
|
add_string_item(&free_list,sitem);
|
||||||
|
sitem = slast->next;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
slast = sitem;
|
||||||
|
sitem = sitem->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dupStringP() : Promotes and copies strings to MAX/HUGE in order to
|
||||||
|
* attempt to use already existing strings (no malloc). This will
|
||||||
|
* truncate strings to HUGE length.
|
||||||
|
*/
|
||||||
|
char *dupStringP(char *str_in, int type)
|
||||||
|
{
|
||||||
|
int req_len;
|
||||||
|
char *str_out;
|
||||||
|
|
||||||
|
req_len = strlen(str_in);
|
||||||
|
if (req_len <= MAX_STRING_LEN)
|
||||||
|
req_len = MAX_STRING_LEN;
|
||||||
|
else
|
||||||
|
req_len = HUGE_STRING_LEN;
|
||||||
|
|
||||||
|
|
||||||
|
str_out = newString(req_len,type);
|
||||||
|
strncpy(str_out,str_in,req_len);
|
||||||
|
str_out[req_len-1] = '\0';
|
||||||
|
|
||||||
|
return str_out;
|
||||||
|
}
|
61
src/allocate.h
Normal file
61
src/allocate.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* NCSA HTTPd Server
|
||||||
|
* Software Development Group
|
||||||
|
* National Center for Supercomputing Applications
|
||||||
|
* University of Illinois at Urbana-Champaign
|
||||||
|
* 605 E. Springfield, Champaign, IL 61820
|
||||||
|
* httpd@ncsa.uiuc.edu
|
||||||
|
*
|
||||||
|
* Copyright (C) 1995, Board of Trustees of the University of Illinois
|
||||||
|
*
|
||||||
|
************************************************************************
|
||||||
|
*
|
||||||
|
* allocate.h,v 1.2 1996/04/05 18:54:29 blong Exp
|
||||||
|
*
|
||||||
|
************************************************************************
|
||||||
|
*
|
||||||
|
* allocate.h: Functions to allocate data types as needed
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ALLOCATE_H
|
||||||
|
#define _ALLOCATE_H 1
|
||||||
|
|
||||||
|
/* There are different levels of strings, depending on when they can
|
||||||
|
* be "free'd".
|
||||||
|
* STR_TMP can be free'd outside the function.
|
||||||
|
* STR_REQ can be free'd at the end of the request.
|
||||||
|
* STR_HUP can be free'd at Restart.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define STR_TMP 0
|
||||||
|
#define STR_REQ 2
|
||||||
|
#define STR_HUP 5
|
||||||
|
|
||||||
|
typedef struct _string_item {
|
||||||
|
char *string;
|
||||||
|
int length;
|
||||||
|
int type;
|
||||||
|
struct _string_item* next;
|
||||||
|
} string_item;
|
||||||
|
|
||||||
|
typedef struct _string_list {
|
||||||
|
string_item* first;
|
||||||
|
int num;
|
||||||
|
} string_list;
|
||||||
|
|
||||||
|
/* Public Interface */
|
||||||
|
int initialize_allocate(void);
|
||||||
|
char* newString(int length, int type);
|
||||||
|
char *dupStringP(char *str_in, int type);
|
||||||
|
int freeString(char *string);
|
||||||
|
int freeAllStrings(int type);
|
||||||
|
int sizeofString(char *string);
|
||||||
|
|
||||||
|
/* Private Interface */
|
||||||
|
int initialize_string_allocate();
|
||||||
|
int allocate_strings(string_list *slist, int length, int num);
|
||||||
|
int remove_string_item(string_list *slist, string_item *sitem);
|
||||||
|
int add_string_item(string_list *slist, string_item *sitem);
|
||||||
|
|
||||||
|
#endif /* _ALLOCATE_H */
|
187
src/blackout.c
Normal file
187
src/blackout.c
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* NCSA HTTPd Server
|
||||||
|
* Software Development Group
|
||||||
|
* National Center for Supercomputing Applications
|
||||||
|
* University of Illinois at Urbana-Champaign
|
||||||
|
* 605 E. Springfield, Champaign, IL 61820
|
||||||
|
* httpd@ncsa.uiuc.edu
|
||||||
|
*
|
||||||
|
* Copyright (C) 1995, Board of Trustees of the University of Illinois
|
||||||
|
*
|
||||||
|
************************************************************************
|
||||||
|
*
|
||||||
|
* blackout.c,v 1.3 1996/03/07 21:27:21 blong Exp
|
||||||
|
*
|
||||||
|
************************************************************************
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "portability.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#ifndef NO_STDLIB_H
|
||||||
|
# include <stdlib.h>
|
||||||
|
#endif /* NO_STDLIB_H */
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "constants.h"
|
||||||
|
#include "fdwrap.h"
|
||||||
|
#include "allocate.h"
|
||||||
|
#include "http_send.h"
|
||||||
|
#include "cgi.h"
|
||||||
|
#include "imagemap.h"
|
||||||
|
#include "http_mime.h"
|
||||||
|
#include "http_log.h"
|
||||||
|
#include "http_request.h"
|
||||||
|
#include "http_config.h"
|
||||||
|
#include "http_include.h"
|
||||||
|
#include "http_alias.h"
|
||||||
|
#include "http_access.h"
|
||||||
|
#include "http_dir.h"
|
||||||
|
#include "httpd.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#ifdef BLACKOUT_CODE
|
||||||
|
|
||||||
|
char *bodyTag = "<BODY BGCOLOR=\"#000000\" TEXT=\"#FFFFFF\" LINK=\"#0099FF\" VLINK=\"#00FF99\"\n>";
|
||||||
|
|
||||||
|
/* void (*exit_callback)(void); */
|
||||||
|
|
||||||
|
|
||||||
|
int realWrite(int fd, char *buf, int length)
|
||||||
|
{
|
||||||
|
int left = length;
|
||||||
|
int sent = 0;
|
||||||
|
int off = 0;
|
||||||
|
int wrote = 0;
|
||||||
|
|
||||||
|
while(left) {
|
||||||
|
if ((wrote = write(fd,&buf[off],left)) < 0) {
|
||||||
|
if (errno != EINTR) break;
|
||||||
|
}
|
||||||
|
left -= wrote;
|
||||||
|
off += wrote;
|
||||||
|
sent += wrote;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sendBody(per_request *reqInfo, char *buf, int length)
|
||||||
|
{
|
||||||
|
int x = 0;
|
||||||
|
int found = 0;
|
||||||
|
int state = 0;
|
||||||
|
int begin = 0;
|
||||||
|
|
||||||
|
while(x < length) {
|
||||||
|
switch (state) {
|
||||||
|
case 0 :
|
||||||
|
if (buf[x] == '<') {
|
||||||
|
begin = x;
|
||||||
|
state++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1 :
|
||||||
|
if ((buf[x] == 'B') || (buf[x] == 'b')) state++;
|
||||||
|
else state = 0;
|
||||||
|
break;
|
||||||
|
case 2 :
|
||||||
|
if ((buf[x] == 'O') || (buf[x] == 'o')) state++;
|
||||||
|
else state = 0;
|
||||||
|
break;
|
||||||
|
case 3 :
|
||||||
|
if ((buf[x] == 'D') || (buf[x] == 'd')) state++;
|
||||||
|
else state = 0;
|
||||||
|
break;
|
||||||
|
case 4 :
|
||||||
|
if ((buf[x] == 'Y') || (buf[x] == 'y')) state++;
|
||||||
|
else state = 0;
|
||||||
|
break;
|
||||||
|
/* case 5 :
|
||||||
|
if (buf[x] == ' ') state++;
|
||||||
|
else state = 0;
|
||||||
|
break; */
|
||||||
|
case 5 :
|
||||||
|
if (buf[x] == '>') state++;
|
||||||
|
break;
|
||||||
|
case 6 :
|
||||||
|
realWrite(fileno(reqInfo->out), buf,begin);
|
||||||
|
realWrite(fileno(reqInfo->out), bodyTag, strlen(bodyTag));
|
||||||
|
realWrite(fileno(reqInfo->out), buf+x,length-x);
|
||||||
|
x = length;
|
||||||
|
}
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state != 6) realWrite(fileno(reqInfo->out),buf,length);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
We'll make it return the number of bytes sent
|
||||||
|
so that we know if we need to send a body by default
|
||||||
|
*/
|
||||||
|
long send_fp_black(per_request *reqInfo, FILE *f, void (*onexit)(void))
|
||||||
|
{
|
||||||
|
char *buf;
|
||||||
|
long total_bytes_sent;
|
||||||
|
register int n,o,w;
|
||||||
|
int isHTML = FALSE;
|
||||||
|
|
||||||
|
buf = newString(IOBUFSIZE,STR_TMP);
|
||||||
|
exit_callback = onexit;
|
||||||
|
signal(SIGALRM,send_fd_timed_out);
|
||||||
|
signal(SIGPIPE,send_fd_timed_out);
|
||||||
|
|
||||||
|
total_bytes_sent = 0;
|
||||||
|
if (!strcmp(reqInfo->outh_content_type,"text/html")) {
|
||||||
|
isHTML = TRUE;
|
||||||
|
total_bytes_sent = rprintf(reqInfo,bodyTag);
|
||||||
|
}
|
||||||
|
rflush(reqInfo);
|
||||||
|
while (1) {
|
||||||
|
alarm(timeout);
|
||||||
|
if((n=fread(buf,sizeof(char),IOBUFSIZE,f)) < 1) {
|
||||||
|
if (errno != EINTR) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
o=0;
|
||||||
|
if(reqInfo->bytes_sent != -1)
|
||||||
|
reqInfo->bytes_sent += n;
|
||||||
|
if (isHTML) {
|
||||||
|
sendBody(reqInfo,buf,n);
|
||||||
|
total_bytes_sent += n;
|
||||||
|
n = 0;
|
||||||
|
}
|
||||||
|
while(n) {
|
||||||
|
/* Seems some systems have broken fwrite's (like AIX 3.2.5 on PowerPC)
|
||||||
|
* this should be a drop in replacement, maybe even be faster.
|
||||||
|
* For now, we'll just replace, but may have to #define one or the other
|
||||||
|
* depending on the system.
|
||||||
|
*/
|
||||||
|
if ((w=write(fileno(reqInfo->out),&buf[o],n)) < 0) {
|
||||||
|
if (errno != EINTR) break;
|
||||||
|
}
|
||||||
|
n-=w;
|
||||||
|
o+=w;
|
||||||
|
total_bytes_sent += w;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (isHTML)
|
||||||
|
rprintf(reqInfo,"<HR><a href=\"http://www.vtw.org/speech/\">My World Wide Web Pages are black for 48 hours to protest second-class treatment from the US Government for free speech. Read about it at this WWW page.</a>");
|
||||||
|
alarm(0);
|
||||||
|
signal(SIGALRM,SIG_IGN);
|
||||||
|
signal(SIGPIPE,SIG_IGN);
|
||||||
|
freeString(buf);
|
||||||
|
return total_bytes_sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* BLACKOUT_CODE */
|
26
src/blackout.h
Normal file
26
src/blackout.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* NCSA HTTPd Server
|
||||||
|
* Software Development Group
|
||||||
|
* National Center for Supercomputing Applications
|
||||||
|
* University of Illinois at Urbana-Champaign
|
||||||
|
* 605 E. Springfield, Champaign, IL 61820
|
||||||
|
* httpd@ncsa.uiuc.edu
|
||||||
|
*
|
||||||
|
* Copyright (C) 1995, Board of Trustees of the University of Illinois
|
||||||
|
*
|
||||||
|
************************************************************************
|
||||||
|
*
|
||||||
|
* blackout.h,v 1.1 1996/02/08 18:01:02 blong Exp
|
||||||
|
*
|
||||||
|
************************************************************************
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _BLACKOUT_H
|
||||||
|
#define _BLACKOUT_H
|
||||||
|
|
||||||
|
/* function prototypes */
|
||||||
|
long send_fp_black(per_request *reqInfo, FILE *f, void (*onexit)(void));
|
||||||
|
|
||||||
|
#endif /* _BLACKOUT_H */
|
||||||
|
|
688
src/cgi.c
688
src/cgi.c
@ -10,33 +10,14 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* cgi.c,v 1.34 1995/11/28 09:01:37 blong Exp
|
* cgi.c,v 1.44 1996/04/05 18:54:31 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* cgi: keeps all script-related ramblings together.
|
* cgi: keeps all script-related ramblings together.
|
||||||
*
|
|
||||||
* Based on NCSA HTTPd 1.3 by Rob McCool
|
|
||||||
*
|
*
|
||||||
* 03-07-95 blong
|
|
||||||
* Added support for variable REMOTE_GROUP from access files
|
|
||||||
*
|
|
||||||
* 03-20-95 sguillory
|
|
||||||
* Moved to more dynamic memory management of environment arrays
|
|
||||||
*
|
|
||||||
* 04-03-95 blong
|
|
||||||
* Added support for variables DOCUMENT_ROOT, ERROR_REQINFO->STATUS
|
|
||||||
* ERROR_URL, ERROR_REQUEST
|
|
||||||
*
|
|
||||||
* 04-20-95 blong
|
|
||||||
* Added Apache patch "B18" from Rob Hartill to allow nondelayed redirects
|
|
||||||
*
|
|
||||||
* 05-02-95 blong
|
|
||||||
* Since Apache is using REDIRECT_ as the env variables, I've decided to
|
|
||||||
* go with this in the interest of general Internet Harmony and Peace.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "portability.h"
|
#include "portability.h"
|
||||||
|
|
||||||
@ -56,21 +37,34 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "fdwrap.h"
|
#include "fdwrap.h"
|
||||||
|
#include "allocate.h"
|
||||||
#include "cgi.h"
|
#include "cgi.h"
|
||||||
#include "env.h"
|
#include "env.h"
|
||||||
#include "http_request.h"
|
|
||||||
#include "http_log.h"
|
|
||||||
#include "http_access.h"
|
#include "http_access.h"
|
||||||
#include "http_mime.h"
|
|
||||||
#include "http_config.h"
|
|
||||||
#include "http_auth.h"
|
|
||||||
#include "http_alias.h"
|
#include "http_alias.h"
|
||||||
|
#include "http_auth.h"
|
||||||
|
#include "http_config.h"
|
||||||
|
#include "http_include.h"
|
||||||
|
#include "http_log.h"
|
||||||
|
#include "http_mime.h"
|
||||||
|
#include "http_request.h"
|
||||||
|
#include "http_send.h"
|
||||||
|
#include "http_include.h"
|
||||||
|
#include "httpd.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
int pid;
|
int pid;
|
||||||
|
|
||||||
|
#ifdef KRB4
|
||||||
|
# include <krb.h>
|
||||||
|
extern AUTH_DAT kerb_kdata;
|
||||||
|
# include <string.h>
|
||||||
|
#endif /* KRB4 */
|
||||||
|
|
||||||
void kill_children(per_request *reqInfo) {
|
void kill_children(per_request *reqInfo) {
|
||||||
char errstr[MAX_STRING_LEN];
|
char errstr[MAX_STRING_LEN];
|
||||||
sprintf(errstr,"killing CGI process %d",pid);
|
sprintf(errstr,"killing CGI process %d",pid);
|
||||||
@ -82,75 +76,87 @@ void kill_children(per_request *reqInfo) {
|
|||||||
waitpid(pid,NULL,0);
|
waitpid(pid,NULL,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef KRB4
|
void kill_children_timed_out() {
|
||||||
# include <krb.h>
|
kill_children(gCurrentRequest);
|
||||||
extern AUTH_DAT kerb_kdata;
|
}
|
||||||
# include <string.h>
|
|
||||||
#endif /* KRB4 */
|
|
||||||
|
|
||||||
char **create_argv(per_request *reqInfo,char *av0) {
|
char **create_argv(per_request *reqInfo,char *av0) {
|
||||||
register int x,n;
|
register int x,n;
|
||||||
char **av;
|
char **av;
|
||||||
char w[HUGE_STRING_LEN];
|
char *str1,*str2;
|
||||||
char l[HUGE_STRING_LEN];
|
|
||||||
|
str1 = newString(HUGE_STRING_LEN,STR_TMP);
|
||||||
|
str2 = newString(HUGE_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
for(x=0,n=2;reqInfo->args[x];x++)
|
for(x=0,n=2;reqInfo->args[x];x++)
|
||||||
if(reqInfo->args[x] == '+') ++n;
|
if(reqInfo->args[x] == '+') ++n;
|
||||||
|
|
||||||
if(!(av = (char **)malloc((n+1)*sizeof(char *))))
|
if(!(av = (char **)malloc((n+1)*sizeof(char *)))) {
|
||||||
|
freeString(str1);
|
||||||
|
freeString(str2);
|
||||||
die(reqInfo,SC_NO_MEMORY,"create_argv");
|
die(reqInfo,SC_NO_MEMORY,"create_argv");
|
||||||
|
}
|
||||||
av[0] = av0;
|
av[0] = av0;
|
||||||
strcpy(l,reqInfo->args);
|
strcpy(str2,reqInfo->args);
|
||||||
for(x=1;x<n;x++) {
|
for(x=1;x<n;x++) {
|
||||||
getword(w,l,'+');
|
getword(str1,str2,'+');
|
||||||
unescape_url(w);
|
unescape_url(str1);
|
||||||
escape_shell_cmd(w);
|
escape_shell_cmd(str1);
|
||||||
if(!(av[x] = strdup(w)))
|
if(!(av[x] = strdup(str1))) {
|
||||||
|
freeString(str1);
|
||||||
|
freeString(str2);
|
||||||
die(reqInfo,SC_NO_MEMORY,"create_argv");
|
die(reqInfo,SC_NO_MEMORY,"create_argv");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
av[n] = NULL;
|
av[n] = NULL;
|
||||||
|
freeString(str1);
|
||||||
|
freeString(str2);
|
||||||
return av;
|
return av;
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_path_info(per_request *reqInfo, char *path_args,
|
void get_path_info(per_request *reqInfo, struct stat *finfo)
|
||||||
struct stat *finfo)
|
|
||||||
{
|
{
|
||||||
register int x,max;
|
register int x,max;
|
||||||
char t[HUGE_STRING_LEN];
|
char *str;
|
||||||
|
|
||||||
|
str = newString(HUGE_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
path_args[0] = '\0';
|
|
||||||
max=count_dirs(reqInfo->filename);
|
max=count_dirs(reqInfo->filename);
|
||||||
for(x=dirs_in_alias;x<=max;x++) {
|
for(x=dirs_in_alias;x<=max;x++) {
|
||||||
make_dirstr(reqInfo->filename,x+1,t);
|
make_dirstr(reqInfo->filename,x+1,str);
|
||||||
if(!(stat(t,finfo))) {
|
if(!(stat(str,finfo))) {
|
||||||
if(S_ISREG(finfo->st_mode)) {
|
if(S_ISREG(finfo->st_mode)) {
|
||||||
int l=strlen(t);
|
int l=strlen(str);
|
||||||
strcpy(path_args,&(reqInfo->filename[l]));
|
strcpy(reqInfo->path_info,&(reqInfo->filename[l]));
|
||||||
reqInfo->filename[l] = '\0';
|
reqInfo->filename[l] = '\0';
|
||||||
reqInfo->url[strlen(reqInfo->url) - strlen(path_args)] = '\0';
|
reqInfo->url[strlen(reqInfo->url) - strlen(reqInfo->path_info)] = '\0';
|
||||||
|
freeString(str);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(x=dirs_in_alias - 1; (x > 0) ;--x) {
|
for(x=dirs_in_alias - 1; (x > 0) ;--x) {
|
||||||
make_dirstr(reqInfo->filename,x+1,t);
|
make_dirstr(reqInfo->filename,x+1,str);
|
||||||
if(!(stat(t,finfo))) {
|
if(!(stat(str,finfo))) {
|
||||||
if(S_ISREG(finfo->st_mode)) {
|
if(S_ISREG(finfo->st_mode)) {
|
||||||
strcpy(path_args,&(reqInfo->filename[strlen(t)]));
|
strcpy(reqInfo->path_info,&(reqInfo->filename[strlen(str)]));
|
||||||
strcpy(reqInfo->filename,t);
|
strcpy(reqInfo->filename,str);
|
||||||
reqInfo->url[strlen(reqInfo->url) - strlen(path_args)] = '\0';
|
reqInfo->url[strlen(reqInfo->url) - strlen(reqInfo->path_info)] = '\0';
|
||||||
|
freeString(str);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* unmunge_name(reqInfo,reqInfo->filename); */
|
|
||||||
log_reason(reqInfo,"script does not exist",reqInfo->filename);
|
log_reason(reqInfo,"script does not exist",reqInfo->filename);
|
||||||
|
freeString(str);
|
||||||
die(reqInfo,SC_NOT_FOUND,reqInfo->url);
|
die(reqInfo,SC_NOT_FOUND,reqInfo->url);
|
||||||
}
|
}
|
||||||
|
|
||||||
int add_cgi_vars(per_request *reqInfo, char *path_args, int *content)
|
int add_cgi_vars(per_request *reqInfo, int *content)
|
||||||
{
|
{
|
||||||
char t[HUGE_STRING_LEN];
|
char *str;
|
||||||
|
|
||||||
|
str = newString(HUGE_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
make_env_str(reqInfo,"GATEWAY_INTERFACE","CGI/1.1");
|
make_env_str(reqInfo,"GATEWAY_INTERFACE","CGI/1.1");
|
||||||
|
|
||||||
@ -160,10 +166,10 @@ int add_cgi_vars(per_request *reqInfo, char *path_args, int *content)
|
|||||||
methods[reqInfo->method]);
|
methods[reqInfo->method]);
|
||||||
|
|
||||||
make_env_str(reqInfo,"SCRIPT_NAME",reqInfo->url);
|
make_env_str(reqInfo,"SCRIPT_NAME",reqInfo->url);
|
||||||
if(path_args[0]) {
|
if(reqInfo->path_info[0]) {
|
||||||
make_env_str(reqInfo,"PATH_INFO",path_args);
|
make_env_str(reqInfo,"PATH_INFO",reqInfo->path_info);
|
||||||
translate_name(reqInfo,path_args,t);
|
translate_name(reqInfo,reqInfo->path_info,str);
|
||||||
make_env_str(reqInfo,"PATH_TRANSLATED",t);
|
make_env_str(reqInfo,"PATH_TRANSLATED",str);
|
||||||
}
|
}
|
||||||
make_env_str(reqInfo,"QUERY_STRING",reqInfo->args);
|
make_env_str(reqInfo,"QUERY_STRING",reqInfo->args);
|
||||||
|
|
||||||
@ -171,18 +177,21 @@ int add_cgi_vars(per_request *reqInfo, char *path_args, int *content)
|
|||||||
*content=0;
|
*content=0;
|
||||||
if ((reqInfo->method == M_POST) || (reqInfo->method == M_PUT)) {
|
if ((reqInfo->method == M_POST) || (reqInfo->method == M_PUT)) {
|
||||||
*content=1;
|
*content=1;
|
||||||
sprintf(t,"%d",content_length);
|
sprintf(str,"%d",reqInfo->inh_content_length);
|
||||||
make_env_str(reqInfo,"CONTENT_TYPE",content_type_in);
|
make_env_str(reqInfo,"CONTENT_TYPE",reqInfo->inh_content_type);
|
||||||
make_env_str(reqInfo,"CONTENT_LENGTH",t);
|
make_env_str(reqInfo,"CONTENT_LENGTH",str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
freeString(str);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int add_common_vars(per_request *reqInfo) {
|
int add_common_vars(per_request *reqInfo) {
|
||||||
char t[MAX_STRING_LEN],*env_path,*env_tz;
|
char *env_path,*env_tz;
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
str = newString(HUGE_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
if(!(env_path = getenv("PATH")))
|
if(!(env_path = getenv("PATH")))
|
||||||
env_path=DEFAULT_PATH;
|
env_path=DEFAULT_PATH;
|
||||||
@ -193,32 +202,32 @@ int add_common_vars(per_request *reqInfo) {
|
|||||||
make_env_str(reqInfo,"SERVER_NAME",reqInfo->hostInfo->server_hostname);
|
make_env_str(reqInfo,"SERVER_NAME",reqInfo->hostInfo->server_hostname);
|
||||||
make_env_str(reqInfo,"SERVER_ADMIN",reqInfo->hostInfo->server_admin);
|
make_env_str(reqInfo,"SERVER_ADMIN",reqInfo->hostInfo->server_admin);
|
||||||
|
|
||||||
sprintf(t,"%d",port);
|
sprintf(str,"%d",port);
|
||||||
make_env_str(reqInfo,"SERVER_PORT",t);
|
make_env_str(reqInfo,"SERVER_PORT",str);
|
||||||
|
|
||||||
make_env_str(reqInfo,"REMOTE_HOST",reqInfo->remote_name);
|
make_env_str(reqInfo,"REMOTE_HOST",reqInfo->remote_name);
|
||||||
make_env_str(reqInfo,"REMOTE_ADDR",reqInfo->remote_ip);
|
make_env_str(reqInfo,"REMOTE_ADDR",reqInfo->remote_ip);
|
||||||
make_env_str(reqInfo,"DOCUMENT_ROOT",reqInfo->hostInfo->document_root);
|
make_env_str(reqInfo,"DOCUMENT_ROOT",reqInfo->hostInfo->document_root);
|
||||||
|
|
||||||
if(user[0])
|
if(reqInfo->auth_user[0])
|
||||||
make_env_str(reqInfo,"REMOTE_USER",user);
|
make_env_str(reqInfo,"REMOTE_USER",reqInfo->auth_user);
|
||||||
|
if(reqInfo->auth_group[0])
|
||||||
|
make_env_str(reqInfo,"REMOTE_GROUP",reqInfo->auth_group);
|
||||||
|
|
||||||
if(reqInfo->hostInfo->annotation_server[0])
|
if(reqInfo->hostInfo->annotation_server[0])
|
||||||
make_env_str(reqInfo,"ANNOTATION_SERVER",
|
make_env_str(reqInfo,"ANNOTATION_SERVER",
|
||||||
reqInfo->hostInfo->annotation_server);
|
reqInfo->hostInfo->annotation_server);
|
||||||
if(groupname[0])
|
|
||||||
make_env_str(reqInfo,"REMOTE_GROUP",groupname);
|
|
||||||
|
|
||||||
if (reqInfo->auth_type[0]) {
|
if (reqInfo->auth_type[0]) {
|
||||||
#ifdef KRB4
|
#ifdef KRB4
|
||||||
if(strncmp(reqInfo->auth_type, "kerberos", 8) == 0) {
|
if(strncmp(reqInfo->auth_type, "kerberos", 8) == 0) {
|
||||||
char buffer[1024];
|
|
||||||
make_env_str(reqInfo,"AUTH_TYPE","KERB4_MUTUAL");
|
make_env_str(reqInfo,"AUTH_TYPE","KERB4_MUTUAL");
|
||||||
make_env_str(reqInfo,"KERB4_USER",kerb_kdata.pname);
|
make_env_str(reqInfo,"KERB4_USER",kerb_kdata.pname);
|
||||||
make_env_str(reqInfo,"KERB4_INSTANCE",kerb_kdata.pinst);
|
make_env_str(reqInfo,"KERB4_INSTANCE",kerb_kdata.pinst);
|
||||||
make_env_str(reqInfo,"KERB4_REALM",kerb_kdata.prealm);
|
make_env_str(reqInfo,"KERB4_REALM",kerb_kdata.prealm);
|
||||||
sprintf (buffer, "%s.%s@%s", kerb_kdata.pname,
|
sprintf (str, "%s.%s@%s", kerb_kdata.pname,
|
||||||
kerb_kdata.pinst, kerb_kdata.prealm);
|
kerb_kdata.pinst, kerb_kdata.prealm);
|
||||||
make_env_str(reqInfo,"KERB4_PRINCIPAL",buffer);
|
make_env_str(reqInfo,"KERB4_PRINCIPAL",str);
|
||||||
} else
|
} else
|
||||||
#endif /* KRB4 */
|
#endif /* KRB4 */
|
||||||
make_env_str(reqInfo,"AUTH_TYPE",reqInfo->auth_type);
|
make_env_str(reqInfo,"AUTH_TYPE",reqInfo->auth_type);
|
||||||
@ -234,268 +243,356 @@ int add_common_vars(per_request *reqInfo) {
|
|||||||
make_env_str(reqInfo,"REDIRECT_STATUS",set_stat_line(reqInfo));
|
make_env_str(reqInfo,"REDIRECT_STATUS",set_stat_line(reqInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
freeString(str);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int scan_script_header(per_request *reqInfo, int pd)
|
int scan_cgi_header(per_request *reqInfo, int pd)
|
||||||
{
|
{
|
||||||
char w[HUGE_STRING_LEN];
|
|
||||||
char *l;
|
char *l;
|
||||||
int p;
|
int p;
|
||||||
int nFirst = 1;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
int options = 0;
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
str = newString(HUGE_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
/* Don't do keepalive unless the script returns a content-length
|
/* Don't do keepalive unless the script returns a content-length
|
||||||
header */
|
header */
|
||||||
keep_alive.bKeepAlive = 0;
|
keep_alive.bKeepAlive = 0;
|
||||||
while(1) {
|
|
||||||
if((ret = getline(pd,w,HUGE_STRING_LEN-1,nFirst,timeout)) <= 0) {
|
|
||||||
char error_msg[MAX_STRING_LEN];
|
|
||||||
Close(pd);
|
|
||||||
sprintf(error_msg,"HTTPd: malformed header from script %s",
|
|
||||||
reqInfo->filename);
|
|
||||||
die(reqInfo,SC_SERVER_ERROR,error_msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* turn off forced read off socket */
|
reqInfo->cgi_buf = new_sock_buf(reqInfo,pd);
|
||||||
if (nFirst) nFirst = 0;
|
cgibuf_count++;
|
||||||
|
|
||||||
|
/* ADC put in the G_SINGLE_CHAR option, so that CGI SSI's would work.
|
||||||
|
* it was:
|
||||||
|
* if((ret = getline(reqInfo->cgi_buf,str,HUGE_STRING_LEN-1,0,timeout)) <= 0)
|
||||||
|
*
|
||||||
|
* This should be cleaned up perhaps so that it only does this if SSI's are
|
||||||
|
* allowed for this script directory. ZZZZ
|
||||||
|
*/
|
||||||
|
#ifdef CGI_SSI_HACK
|
||||||
|
if (reqInfo->RequestFlags & DOING_SHTTP)
|
||||||
|
options = G_SINGLE_CHAR;
|
||||||
|
#endif /* CGI_SSI_HACK */
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
if((ret = getline(reqInfo->cgi_buf,str,HUGE_STRING_LEN-1,options,timeout)) <= 0)
|
||||||
|
{
|
||||||
|
char error_msg[MAX_STRING_LEN];
|
||||||
|
Close(pd);
|
||||||
|
freeString(str);
|
||||||
|
sprintf(error_msg,"HTTPd: malformed header from script %s",
|
||||||
|
reqInfo->filename);
|
||||||
|
die(reqInfo,SC_SERVER_ERROR,error_msg);
|
||||||
|
}
|
||||||
|
|
||||||
/* Always return zero, so as not to cause redirect+sleep3+kill */
|
/* Always return zero, so as not to cause redirect+sleep3+kill */
|
||||||
if(w[0] == '\0') {
|
if(str[0] == '\0') {
|
||||||
if (content_type[0] == '\0') {
|
if (reqInfo->outh_content_type[0] == '\0') {
|
||||||
if (location[0] != '\0') {
|
if (reqInfo->outh_location[0] != '\0') {
|
||||||
strcpy(content_type,"text/html");
|
strcpy(reqInfo->outh_content_type,"text/html");
|
||||||
} else {
|
} else {
|
||||||
if (local_default_type[0] != '\0')
|
if (local_default_type[0] != '\0')
|
||||||
strcpy(content_type,local_default_type);
|
strcpy(reqInfo->outh_content_type,local_default_type);
|
||||||
else strcpy(content_type,reqInfo->hostInfo->default_type);
|
else strcpy(reqInfo->outh_content_type,
|
||||||
|
reqInfo->hostInfo->default_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
freeString(str);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(!(l = strchr(w,':')))
|
if(!(l = strchr(str,':')))
|
||||||
l = w;
|
l = str;
|
||||||
*l++ = '\0';
|
*l++ = '\0';
|
||||||
if(!strcasecmp(w,"Content-type")) {
|
if(!strcasecmp(str,"Content-type")) {
|
||||||
/* Thanks Netscape for showing this bug to everyone */
|
/* Thanks Netscape for showing this bug to everyone */
|
||||||
/* delete trailing whitespace, esp. for "server push" */
|
/* delete trailing whitespace, esp. for "server push" */
|
||||||
char *endp = l + strlen(l) - 1;
|
char *endp = l + strlen(l) - 1;
|
||||||
while ((endp > l) && isspace(*endp)) *endp-- = '\0';
|
while ((endp > l) && isspace(*endp)) *endp-- = '\0';
|
||||||
sscanf(l,"%s",content_type);
|
sscanf(l,"%s",reqInfo->outh_content_type);
|
||||||
}
|
}
|
||||||
else if(!strcasecmp(w,"Location")) {
|
else if(!strcasecmp(str,"Location")) {
|
||||||
/* If we don't already have a status line, make one */
|
/* If we don't already have a status line, make one */
|
||||||
if (!&status_line[0]) {
|
if (!reqInfo->status_line) {
|
||||||
reqInfo->status = 302;
|
reqInfo->status = SC_REDIRECT_TEMP;
|
||||||
set_stat_line(reqInfo);
|
set_stat_line(reqInfo);
|
||||||
}
|
}
|
||||||
sscanf(l,"%s",location);
|
strncpy(reqInfo->outh_location,l,HUGE_STRING_LEN);
|
||||||
|
reqInfo->outh_location[HUGE_STRING_LEN-1] = '\0';
|
||||||
}
|
}
|
||||||
else if(!strcasecmp(w,"Status")) {
|
else if(!strcasecmp(str,"Status")) {
|
||||||
for(p=0;isspace(l[p]);p++);
|
for(p=0;isspace(l[p]);p++);
|
||||||
sscanf(&l[p],"%d",&reqInfo->status);
|
sscanf(&l[p],"%d",&(reqInfo->status));
|
||||||
if(!(status_line = strdup(&l[p]))) {
|
if(!(reqInfo->status_line = dupStringP(&l[p],STR_REQ))) {
|
||||||
Close(pd);
|
Close(pd);
|
||||||
die(reqInfo,SC_NO_MEMORY,"CGI: scan_script_header");
|
freeString(str);
|
||||||
|
die(reqInfo,SC_NO_MEMORY,"CGI: scan_cgi_header");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(!strcasecmp(w,"Content-length")) {
|
else if(!strcasecmp(str,"Content-length")) {
|
||||||
keep_alive.bKeepAlive = 1;
|
keep_alive.bKeepAlive = 1;
|
||||||
|
sscanf(l,"%d",&(reqInfo->outh_content_length));
|
||||||
}
|
}
|
||||||
|
else if(!strcasecmp(str,"WWW-Authenticate")) {
|
||||||
|
if (!reqInfo->status_line) {
|
||||||
|
reqInfo->status = SC_AUTH_REQUIRED;
|
||||||
|
set_stat_line(reqInfo);
|
||||||
|
}
|
||||||
|
strncpy(reqInfo->outh_www_auth,l,HUGE_STRING_LEN);
|
||||||
|
reqInfo->outh_www_auth[HUGE_STRING_LEN-1] = '\0';
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
*(--l) = ':';
|
*(--l) = ':';
|
||||||
for(p=0;w[p];p++);
|
for(p=0;str[p];p++);
|
||||||
w[p] = LF;
|
str[p] = LF;
|
||||||
w[++p] = '\0';
|
str[++p] = '\0';
|
||||||
if(!out_headers) {
|
if(!(reqInfo->outh_cgi)) {
|
||||||
if(!(out_headers = strdup(w))) {
|
if(!(reqInfo->outh_cgi = strdup(str))) {
|
||||||
Close(pd);
|
Close(pd);
|
||||||
die(reqInfo,SC_NO_MEMORY,"CGI: scan_script_header");
|
freeString(str);
|
||||||
|
die(reqInfo,SC_NO_MEMORY,"CGI: scan_cgi_header");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int loh = strlen(out_headers);
|
int loh = strlen(reqInfo->outh_cgi);
|
||||||
out_headers = (char *) realloc(out_headers,
|
reqInfo->outh_cgi = (char *) realloc(reqInfo->outh_cgi,
|
||||||
(loh+strlen(w)+1)*sizeof(char));
|
(loh+strlen(str)+1)*sizeof(char));
|
||||||
if(!out_headers) {
|
if(!(reqInfo->outh_cgi)) {
|
||||||
Close(pd);
|
Close(pd);
|
||||||
die(reqInfo,SC_NO_MEMORY,"CGI: scan_script_header");
|
freeString(str);
|
||||||
|
die(reqInfo,SC_NO_MEMORY,"CGI: scan_cgi_header");
|
||||||
}
|
}
|
||||||
strcpy(&out_headers[loh],w);
|
strcpy(&(reqInfo->outh_cgi[loh]),str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int cgi_stub(per_request *reqInfo, char *path_args, struct stat *finfo)
|
void internal_redirect(per_request *reqInfo)
|
||||||
{
|
{
|
||||||
int p[2], p2[2]; /* p = script-> server, p2 = server -> script */
|
char url[HUGE_STRING_LEN],args[HUGE_STRING_LEN],*argp;
|
||||||
int content, nph;
|
per_request *newInfo;
|
||||||
char *argv0;
|
|
||||||
char errlog[100];
|
url[0] = '\0';
|
||||||
|
args[0] = '\0';
|
||||||
|
|
||||||
if(!can_exec(finfo)) {
|
/* Split the location header into URL and args */
|
||||||
log_reason(reqInfo,
|
strncpy(url,reqInfo->outh_location,HUGE_STRING_LEN);
|
||||||
"client denied by server configuration (CGI non-executable)",
|
if((argp = strchr(url,'?'))) {
|
||||||
reqInfo->filename);
|
*argp++ = '\0';
|
||||||
die(reqInfo,SC_FORBIDDEN,reqInfo->url);
|
strcpy(args,argp);
|
||||||
}
|
}
|
||||||
|
log_transaction(reqInfo);
|
||||||
|
|
||||||
if((argv0 = strrchr(reqInfo->filename,'/')) != NULL)
|
/* The global string the_request currently holds the request as
|
||||||
argv0++;
|
* read off the socket, and is used to log the information. We force
|
||||||
else argv0 = reqInfo->filename;
|
* it to this internal request here. Only redirects to GET requests
|
||||||
|
*/
|
||||||
|
sprintf(the_request,"GET ");
|
||||||
|
strncat(the_request,url,HUGE_STRING_LEN - strlen(the_request));
|
||||||
|
if (args[0] != '\0') {
|
||||||
|
strncat(the_request,"?",HUGE_STRING_LEN - strlen(the_request));
|
||||||
|
strncat(the_request,args, HUGE_STRING_LEN - strlen(the_request));
|
||||||
|
}
|
||||||
|
|
||||||
|
strncat(the_request," ",HUGE_STRING_LEN - strlen(the_request));
|
||||||
|
/* Replace the protocal with Internal to let people know it was an
|
||||||
|
* internal redirect.
|
||||||
|
*/
|
||||||
|
/* strncat(the_request, protocals[reqInfo->http_version],
|
||||||
|
HUGE_STRING_LEN - strlen(the_request)); */
|
||||||
|
strncat(the_request, "Internal",HUGE_STRING_LEN - strlen(the_request));
|
||||||
|
newInfo = continue_request(reqInfo, KEEP_AUTH | FORCE_GET);
|
||||||
|
newInfo->status = SC_DOCUMENT_FOLLOWS;
|
||||||
|
set_stat_line(newInfo);
|
||||||
|
strcpy(newInfo->url, url);
|
||||||
|
strcpy(newInfo->args, args);
|
||||||
|
construct_url(newInfo->outh_location,reqInfo->hostInfo,
|
||||||
|
reqInfo->outh_location);
|
||||||
|
process_request(newInfo);
|
||||||
|
}
|
||||||
|
|
||||||
chdir_file(reqInfo->filename);
|
int cgi_stub(per_request *reqInfo, struct stat *finfo, int allow_options)
|
||||||
|
{
|
||||||
if(Pipe(p) < 0)
|
int p[2], p2[2]; /* p = script-> server, p2 = server -> script */
|
||||||
die(reqInfo,SC_SERVER_ERROR,"HTTPd/CGI: could not create IPC pipe");
|
int content, nph;
|
||||||
if(Pipe(p2) < 0) {
|
char *argv0;
|
||||||
Close(p[0]);
|
char errlog[100];
|
||||||
Close(p[1]);
|
FILE *fp = NULL;
|
||||||
die(reqInfo,SC_SERVER_ERROR,"HTTPd/CGI: could not create IPC pipe");
|
|
||||||
}
|
if(!can_exec(finfo)) {
|
||||||
|
log_reason(reqInfo,
|
||||||
if((pid = fork()) < 0) {
|
"client denied by server configuration (CGI non-executable)",
|
||||||
Close(p[0]);
|
reqInfo->filename);
|
||||||
Close(p[1]);
|
die(reqInfo,SC_FORBIDDEN,reqInfo->url);
|
||||||
Close(p2[0]);
|
}
|
||||||
Close(p2[1]);
|
|
||||||
sprintf(errlog,"HTTPd/CGI: could not fork new process, errno is %d",
|
if((argv0 = strrchr(reqInfo->filename,'/')) != NULL)
|
||||||
errno);
|
argv0++;
|
||||||
die(reqInfo,SC_SERVER_ERROR,errlog);
|
else argv0 = reqInfo->filename;
|
||||||
}
|
|
||||||
|
chdir_file(reqInfo->filename);
|
||||||
nph = (strncmp(argv0,"nph-",4) ? 0 : 1);
|
|
||||||
if(!pid) {
|
if(Pipe(p) < 0)
|
||||||
Close(p[0]);
|
die(reqInfo,SC_SERVER_ERROR,"HTTPd/CGI: could not create IPC pipe");
|
||||||
Close(p2[1]);
|
if(Pipe(p2) < 0) {
|
||||||
standalone = 0;
|
|
||||||
add_cgi_vars(reqInfo,path_args,&content);
|
|
||||||
|
|
||||||
/* TAKE OUT "if (nph)" THROUGH "else {" IF SHIT HAPPENS */
|
|
||||||
if (nph) {
|
|
||||||
if (reqInfo->connection_socket != STDOUT_FILENO) {
|
|
||||||
dup2(reqInfo->connection_socket, STDOUT_FILENO);
|
|
||||||
close(reqInfo->connection_socket);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
dup2(p[1],STDOUT_FILENO);
|
|
||||||
Close(p[1]);
|
|
||||||
dup2(p2[0],STDIN_FILENO);
|
|
||||||
Close(p2[0]);
|
|
||||||
|
|
||||||
/* Need to close the connection for processes which spawn processes.
|
|
||||||
* is there a CLOSE_ON_EXEC_ON_EXEC ? */
|
|
||||||
/* close(reqInfo->connection_socket); */
|
|
||||||
/* fclose(reqInfo->out); */
|
|
||||||
|
|
||||||
error_log2stderr(reqInfo->hostInfo->error_log);
|
|
||||||
/* To make the signal handling work on HPUX, according to
|
|
||||||
David-Michael Lincke (dlincke@bandon.unisg.ch) */
|
|
||||||
#ifdef HPUX
|
|
||||||
signal(SIGCHLD, SIG_DFL);
|
|
||||||
#endif /* HPUX */
|
|
||||||
/* Only ISINDEX scripts get decoded arguments. */
|
|
||||||
if((!reqInfo->args[0]) || (ind(reqInfo->args,'=') >= 0)) {
|
|
||||||
execle(reqInfo->filename,argv0,NULL,reqInfo->env);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
execve(reqInfo->filename,create_argv(reqInfo,argv0),
|
|
||||||
reqInfo->env);
|
|
||||||
|
|
||||||
}
|
|
||||||
fprintf(stderr,"HTTPd/CGI: exec of %s failed, errno is %d\n",
|
|
||||||
reqInfo->filename,errno);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Close(p[1]);
|
|
||||||
Close(p2[0]);
|
|
||||||
if (content_length > 0) {
|
|
||||||
/* read content off socket and write to script */
|
|
||||||
char szBuf[IOBUFSIZE];
|
|
||||||
int nBytes, nTotalBytes = 0;
|
|
||||||
int nDone = 0;
|
|
||||||
|
|
||||||
signal(SIGPIPE,SIG_IGN);
|
|
||||||
nBytes=getline(reqInfo->connection_socket, szBuf,IOBUFSIZE,2,
|
|
||||||
timeout);
|
|
||||||
nTotalBytes = nBytes;
|
|
||||||
write (p2[1], szBuf, nBytes);
|
|
||||||
while (!nDone && (nTotalBytes < content_length)) {
|
|
||||||
if((nBytes=read(reqInfo->connection_socket,
|
|
||||||
szBuf,IOBUFSIZE)) < 1) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
write (p2[1], szBuf, nBytes);
|
|
||||||
nTotalBytes += nBytes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Close(p2[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!nph) {
|
|
||||||
content_type[0] = '\0';
|
|
||||||
|
|
||||||
scan_script_header(reqInfo,p[0]);
|
|
||||||
if(location[0] == '/') {
|
|
||||||
char t[HUGE_STRING_LEN],a[HUGE_STRING_LEN],*argp;
|
|
||||||
|
|
||||||
a[0] = '\0';
|
|
||||||
Close(p[0]);
|
|
||||||
waitpid(pid,NULL,0);
|
|
||||||
strcpy(t,location);
|
|
||||||
if((argp = strchr(t,'?'))) {
|
|
||||||
*argp++ = '\0';
|
|
||||||
strcpy(a,argp);
|
|
||||||
}
|
|
||||||
reqInfo->status = SC_REDIRECT_TEMP;
|
|
||||||
log_transaction(reqInfo);
|
|
||||||
reqInfo->status = SC_DOCUMENT_FOLLOWS;
|
|
||||||
init_header_vars(reqInfo); /* clear location */
|
|
||||||
sprintf(the_request,"GET ");
|
|
||||||
strncat(the_request,t,HUGE_STRING_LEN - strlen(the_request));
|
|
||||||
if (a[0] != '\0') {
|
|
||||||
strncat(the_request,"?",HUGE_STRING_LEN - strlen(the_request));
|
|
||||||
strncat(the_request,a, HUGE_STRING_LEN - strlen(the_request));
|
|
||||||
}
|
|
||||||
|
|
||||||
strncat(the_request," ",HUGE_STRING_LEN - strlen(the_request));
|
|
||||||
strncat(the_request, protocals[reqInfo->http_version],
|
|
||||||
HUGE_STRING_LEN - strlen(the_request));
|
|
||||||
reqInfo = continue_request(reqInfo, KEEP_AUTH | FORCE_GET);
|
|
||||||
strcpy(reqInfo->url, t);
|
|
||||||
strcpy(reqInfo->args, a);
|
|
||||||
process_request(reqInfo);
|
|
||||||
return SC_REDIRECT_LOCAL;
|
|
||||||
}
|
|
||||||
content_length = -1;
|
|
||||||
if(!no_headers)
|
|
||||||
send_http_header(reqInfo);
|
|
||||||
if(!header_only) {
|
|
||||||
/* Send a default body of text if the script
|
|
||||||
failed to produce any, but ONLY for redirects */
|
|
||||||
if (!send_fd(reqInfo,p[0],NULL) && location[0]) {
|
|
||||||
title_html(reqInfo,"Document moved");
|
|
||||||
fprintf(reqInfo->out,
|
|
||||||
"This document has temporarily moved <A HREF=\"%s\">here</A>.</P>%c",
|
|
||||||
location,LF);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
kill_children(reqInfo);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
reqInfo->bytes_sent = -1;
|
|
||||||
/* If there is KeepAlive going on, its handled internally to the
|
|
||||||
script. This means that we want to close the connection after
|
|
||||||
the nph- script has finished. */
|
|
||||||
keep_alive.bKeepAlive = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
waitpid(pid,NULL,0);
|
|
||||||
Close(p[0]);
|
Close(p[0]);
|
||||||
return SC_DOCUMENT_FOLLOWS;
|
Close(p[1]);
|
||||||
|
die(reqInfo,SC_SERVER_ERROR,"HTTPd/CGI: could not create IPC pipe");
|
||||||
|
}
|
||||||
|
|
||||||
|
if((pid = fork()) < 0) {
|
||||||
|
Close(p[0]);
|
||||||
|
Close(p[1]);
|
||||||
|
Close(p2[0]);
|
||||||
|
Close(p2[1]);
|
||||||
|
sprintf(errlog,"HTTPd/CGI: could not fork new process, errno is %d",
|
||||||
|
errno);
|
||||||
|
die(reqInfo,SC_SERVER_ERROR,errlog);
|
||||||
|
}
|
||||||
|
|
||||||
|
nph = (strncmp(argv0,"nph-",4) ? 0 : 1);
|
||||||
|
if(!pid) {
|
||||||
|
Close(p[0]);
|
||||||
|
Close(p2[1]);
|
||||||
|
standalone = 0;
|
||||||
|
add_cgi_vars(reqInfo,&content);
|
||||||
|
|
||||||
|
/* TAKE OUT "if (nph)" THROUGH "else {" IF SHIT HAPPENS */
|
||||||
|
if (nph) {
|
||||||
|
if (fileno(reqInfo->out) != STDOUT_FILENO) {
|
||||||
|
dup2(fileno(reqInfo->out), STDOUT_FILENO);
|
||||||
|
close(fileno(reqInfo->out));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dup2(p[1],STDOUT_FILENO);
|
||||||
|
Close(p[1]);
|
||||||
|
dup2(p2[0],STDIN_FILENO);
|
||||||
|
Close(p2[0]);
|
||||||
|
|
||||||
|
/* Close the socket so the CGI program doesn't hold it open */
|
||||||
|
close(csd);
|
||||||
|
|
||||||
|
error_log2stderr(reqInfo->hostInfo->error_log);
|
||||||
|
/* To make the signal handling work on HPUX, according to
|
||||||
|
* David-Michael Lincke (dlincke@bandon.unisg.ch)
|
||||||
|
*/
|
||||||
|
#ifdef HPUX
|
||||||
|
signal(SIGCHLD, SIG_DFL);
|
||||||
|
#endif /* HPUX */
|
||||||
|
/* Only ISINDEX scripts get decoded arguments. */
|
||||||
|
if((!reqInfo->args[0]) || (ind(reqInfo->args,'=') >= 0)) {
|
||||||
|
execle(reqInfo->filename,argv0,NULL,reqInfo->env);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
execve(reqInfo->filename,create_argv(reqInfo,argv0),
|
||||||
|
reqInfo->env);
|
||||||
|
|
||||||
|
}
|
||||||
|
fprintf(stderr,"HTTPd/CGI: exec of %s failed, errno is %d\n",
|
||||||
|
reqInfo->filename,errno);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Close(p[1]);
|
||||||
|
Close(p2[0]);
|
||||||
|
if (reqInfo->inh_content_length > 0) {
|
||||||
|
/* read content off socket and write to script */
|
||||||
|
char szBuf[HUGE_STRING_LEN];
|
||||||
|
int nBytes, nTotalBytes = 0;
|
||||||
|
int nDone = 0;
|
||||||
|
|
||||||
|
signal(SIGPIPE,SIG_IGN);
|
||||||
|
nBytes=getline(reqInfo->sb, szBuf,HUGE_STRING_LEN,G_FLUSH, timeout);
|
||||||
|
nTotalBytes = nBytes;
|
||||||
|
if (nBytes >= 0) {
|
||||||
|
if (nBytes > 0) write(p2[1], szBuf, nBytes);
|
||||||
|
while (!nDone && (nTotalBytes < reqInfo->inh_content_length)) {
|
||||||
|
nBytes=read(reqInfo->in, szBuf,HUGE_STRING_LEN);
|
||||||
|
if(nBytes < 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
write(p2[1], szBuf, nBytes);
|
||||||
|
nTotalBytes += nBytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Close(p2[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!nph) {
|
||||||
|
reqInfo->outh_content_type[0] = '\0';
|
||||||
|
reqInfo->outh_content_length = -1;
|
||||||
|
|
||||||
|
scan_cgi_header(reqInfo,p[0]);
|
||||||
|
if(reqInfo->outh_location[0] == '/') {
|
||||||
|
Close(p[0]);
|
||||||
|
waitpid(pid,NULL,0);
|
||||||
|
internal_redirect(reqInfo);
|
||||||
|
return SC_REDIRECT_LOCAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Previously, this was broken because we read the results of the CGI using
|
||||||
|
* getline, but the SSI parser used buffered stdio.
|
||||||
|
*
|
||||||
|
* ADC changed scan_cgi_header so that it uses G_SINGLE_CHAR when it
|
||||||
|
* calls getline. Yes, this means pitiful performance for CGI scripts.
|
||||||
|
*/
|
||||||
|
/* Fine, parse the output of CGI scripts. Talk about useless
|
||||||
|
* overhead. . .
|
||||||
|
*/
|
||||||
|
#ifdef CGI_SSI_HACK
|
||||||
|
if (!strcasecmp(reqInfo->outh_content_type, INCLUDES_MAGIC_TYPE) &&
|
||||||
|
(allow_options & OPT_INCLUDES)) {
|
||||||
|
strcpy(reqInfo->outh_content_type, "text/html");
|
||||||
|
if(reqInfo->http_version != P_HTTP_0_9)
|
||||||
|
send_http_header(reqInfo);
|
||||||
|
if(reqInfo->method != M_HEAD) {
|
||||||
|
rflush(reqInfo);
|
||||||
|
alarm(timeout);
|
||||||
|
add_include_vars(reqInfo,DEFAULT_TIME_FORMAT);
|
||||||
|
if (!(fp = FdOpen(p[0],"r"))) {
|
||||||
|
char errstr[MAX_STRING_LEN];
|
||||||
|
sprintf(errstr,"HTTPd/CGI/SSI: Could not fdopen() fildes, errno is %d.",errno);
|
||||||
|
die(reqInfo,SC_SERVER_ERROR,errstr);
|
||||||
|
}
|
||||||
|
send_parsed_content(reqInfo,fp,allow_options & OPT_EXECCGI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif /* CGI_SSI_HACK */
|
||||||
|
{ /* Not Parsed, send normally */
|
||||||
|
if(reqInfo->http_version != P_HTTP_0_9)
|
||||||
|
send_http_header(reqInfo);
|
||||||
|
if(reqInfo->method != M_HEAD) {
|
||||||
|
/* Send a default body of text if the script
|
||||||
|
* failed to produce any, but ONLY for redirects
|
||||||
|
*/
|
||||||
|
if (!send_fd(reqInfo,p[0],kill_children_timed_out) &&
|
||||||
|
reqInfo->outh_location[0])
|
||||||
|
{
|
||||||
|
title_html(reqInfo,"Document moved");
|
||||||
|
rprintf(reqInfo,
|
||||||
|
"This document has temporarily moved <A HREF=\"%s\">here</A>.</P>%c",
|
||||||
|
reqInfo->outh_location,LF);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
kill_children(reqInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { /* Is nph- script */
|
||||||
|
reqInfo->bytes_sent = -1;
|
||||||
|
/* If there is KeepAlive going on, its handled internally to the
|
||||||
|
script. This means that we want to close the connection after
|
||||||
|
the nph- script has finished. */
|
||||||
|
keep_alive.bKeepAlive = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
waitpid(pid,NULL,0);
|
||||||
|
if (fp != NULL) FClose(fp); else Close(p[0]);
|
||||||
|
return SC_DOCUMENT_FOLLOWS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -504,23 +601,31 @@ int cgi_stub(per_request *reqInfo, char *path_args, struct stat *finfo)
|
|||||||
*/
|
*/
|
||||||
long send_fd(per_request *reqInfo, int pd, void (*onexit)(void))
|
long send_fd(per_request *reqInfo, int pd, void (*onexit)(void))
|
||||||
{
|
{
|
||||||
char buf[IOBUFSIZE];
|
char *buf;
|
||||||
register int n,w,o;
|
register int n,w,o;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
|
buf = newString(IOBUFSIZE,STR_TMP);
|
||||||
|
|
||||||
|
exit_callback = onexit;
|
||||||
signal(SIGALRM,send_fd_timed_out);
|
signal(SIGALRM,send_fd_timed_out);
|
||||||
signal(SIGPIPE,send_fd_timed_out);
|
signal(SIGPIPE,send_fd_timed_out);
|
||||||
|
|
||||||
/* Flush stdio pipe, since scripts now use non buffered i/o */
|
/* Flush stdio pipe, since scripts now use non buffered i/o */
|
||||||
fflush(reqInfo->out);
|
rflush(reqInfo);
|
||||||
fd = fileno(reqInfo->out);
|
fd = fileno(reqInfo->out);
|
||||||
|
|
||||||
alarm(timeout);
|
alarm(timeout);
|
||||||
n=getline(pd, buf,IOBUFSIZE,2,timeout);
|
if (reqInfo->cgi_buf != NULL)
|
||||||
|
n=getline(reqInfo->cgi_buf, buf,IOBUFSIZE,G_FLUSH,timeout);
|
||||||
|
else
|
||||||
|
n = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
o=0;
|
o=0;
|
||||||
while(n) {
|
while(n) {
|
||||||
if ((w=write(fd, buf + o,n)) < 1) {
|
w = write(fd, buf + o,n);
|
||||||
|
|
||||||
|
if (w < 1) {
|
||||||
if (errno != EINTR) break;
|
if (errno != EINTR) break;
|
||||||
}
|
}
|
||||||
n-=w;
|
n-=w;
|
||||||
@ -538,18 +643,18 @@ long send_fd(per_request *reqInfo, int pd, void (*onexit)(void))
|
|||||||
alarm(0);
|
alarm(0);
|
||||||
signal(SIGALRM,SIG_IGN);
|
signal(SIGALRM,SIG_IGN);
|
||||||
signal(SIGPIPE,SIG_IGN);
|
signal(SIGPIPE,SIG_IGN);
|
||||||
|
freeString(buf);
|
||||||
return reqInfo->bytes_sent;
|
return reqInfo->bytes_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called for ScriptAliased directories */
|
/* Called for ScriptAliased directories */
|
||||||
void exec_cgi_script(per_request *reqInfo) {
|
void exec_cgi_script(per_request *reqInfo) {
|
||||||
struct stat finfo;
|
struct stat finfo;
|
||||||
char path_args[HUGE_STRING_LEN];
|
|
||||||
int stub_returns;
|
int stub_returns;
|
||||||
int allow;
|
int allow;
|
||||||
char allow_options;
|
char allow_options;
|
||||||
|
|
||||||
get_path_info(reqInfo,path_args,&finfo);
|
get_path_info(reqInfo,&finfo);
|
||||||
|
|
||||||
evaluate_access(reqInfo,&finfo,&allow,&allow_options);
|
evaluate_access(reqInfo,&finfo,&allow,&allow_options);
|
||||||
if(!allow) {
|
if(!allow) {
|
||||||
@ -561,11 +666,11 @@ void exec_cgi_script(per_request *reqInfo) {
|
|||||||
add_common_vars(reqInfo);
|
add_common_vars(reqInfo);
|
||||||
|
|
||||||
reqInfo->bytes_sent = 0;
|
reqInfo->bytes_sent = 0;
|
||||||
stub_returns = cgi_stub(reqInfo,path_args,&finfo);
|
stub_returns = cgi_stub(reqInfo,&finfo,allow_options);
|
||||||
|
|
||||||
switch (stub_returns) {
|
switch (stub_returns) {
|
||||||
case SC_REDIRECT_TEMP:
|
case SC_REDIRECT_TEMP:
|
||||||
die(reqInfo,SC_REDIRECT_TEMP,location);
|
die(reqInfo,SC_REDIRECT_TEMP,reqInfo->outh_location);
|
||||||
break;
|
break;
|
||||||
case SC_REDIRECT_LOCAL:
|
case SC_REDIRECT_LOCAL:
|
||||||
break;
|
break;
|
||||||
@ -581,8 +686,7 @@ void exec_cgi_script(per_request *reqInfo) {
|
|||||||
evaluate_access
|
evaluate_access
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void send_cgi(per_request *reqInfo,struct stat *finfo, char *path_args,
|
void send_cgi(per_request *reqInfo,struct stat *finfo, char allow_options)
|
||||||
char allow_options)
|
|
||||||
{
|
{
|
||||||
int stub_returns;
|
int stub_returns;
|
||||||
|
|
||||||
@ -594,11 +698,11 @@ void send_cgi(per_request *reqInfo,struct stat *finfo, char *path_args,
|
|||||||
add_common_vars(reqInfo);
|
add_common_vars(reqInfo);
|
||||||
|
|
||||||
reqInfo->bytes_sent = 0;
|
reqInfo->bytes_sent = 0;
|
||||||
stub_returns = cgi_stub(reqInfo,path_args,finfo);
|
stub_returns = cgi_stub(reqInfo,finfo,allow_options);
|
||||||
|
|
||||||
switch (stub_returns) {
|
switch (stub_returns) {
|
||||||
case SC_REDIRECT_TEMP:
|
case SC_REDIRECT_TEMP:
|
||||||
die(reqInfo,SC_REDIRECT_TEMP,location);
|
die(reqInfo,SC_REDIRECT_TEMP,reqInfo->outh_location);
|
||||||
break;
|
break;
|
||||||
case SC_REDIRECT_LOCAL:
|
case SC_REDIRECT_LOCAL:
|
||||||
break;
|
break;
|
||||||
|
25
src/cgi.h
25
src/cgi.h
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* cgi.h,v 1.6 1995/11/28 09:01:39 blong Exp
|
* cgi.h,v 1.9 1996/04/05 18:54:40 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
@ -21,25 +21,18 @@
|
|||||||
#ifndef _HTTP_SCRIPT_H_
|
#ifndef _HTTP_SCRIPT_H_
|
||||||
#define _HTTP_SCRIPT_H_
|
#define _HTTP_SCRIPT_H_
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
/* function prototypes */
|
/* function prototypes */
|
||||||
void exec_cgi_script(per_request *reqInfo);
|
void exec_cgi_script(per_request *reqInfo);
|
||||||
int cgi_stub(per_request *reqInfo, char *path_args, struct stat *finfo);
|
int cgi_stub(per_request *reqInfo, struct stat *finfo, int allow_options);
|
||||||
int add_common_vars(per_request *reqInfo);
|
int add_common_vars(per_request *reqInfo);
|
||||||
void get_path_info(per_request *reqInfo, char *path_args, struct stat *finfo);
|
int add_cgi_vars(per_request *reqInfo, int *content);
|
||||||
int scan_script_header(per_request *reqInfo, int pd);
|
void get_path_info(per_request *reqInfo, struct stat *finfo);
|
||||||
|
int scan_cgi_header(per_request *reqInfo, int pd);
|
||||||
long send_fd(per_request *reqInfo, int pd, void (*onexit)(void));
|
long send_fd(per_request *reqInfo, int pd, void (*onexit)(void));
|
||||||
long send_nph_script(per_request *reqInfo, int pd, void (*onexit)(void));
|
long send_nph_script(per_request *reqInfo, int pd, void (*onexit)(void));
|
||||||
void send_cgi(per_request *reqInfo,struct stat *finfo, char *path_args,
|
void send_cgi(per_request *reqInfo,struct stat *finfo, char allow_options);
|
||||||
char allow_options);
|
void internal_redirect(per_request *reqInfo);
|
||||||
|
|
||||||
|
|
||||||
void send_fd_timed_out(int);
|
|
||||||
|
|
||||||
#endif /* _HTTP_SCRIPT_H_ */
|
#endif /* _HTTP_SCRIPT_H_ */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
49
src/config.h
49
src/config.h
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* config.h,v 1.16 1995/11/10 02:01:46 blong Exp
|
* config.h,v 1.21 1996/03/27 20:43:51 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
@ -32,14 +32,14 @@
|
|||||||
on all systems, either. It is known to work under AIX3, SunOS, OSF1,
|
on all systems, either. It is known to work under AIX3, SunOS, OSF1,
|
||||||
FreeBSD, and NetBSD. */
|
FreeBSD, and NetBSD. */
|
||||||
|
|
||||||
/* #define SETPROCTITLE /* */
|
/* #define SETPROCTITLE */
|
||||||
|
|
||||||
/* If you have SETPROCTITLE enabled, and you are a stats fanatic, and your
|
/* If you have SETPROCTITLE enabled, and you are a stats fanatic, and your
|
||||||
server has a few extra clock cycles to spare, defining the following
|
server has a few extra clock cycles to spare, defining the following
|
||||||
will enable an RPM (requests per minute) indicator in the proc title. */
|
will enable an RPM (requests per minute) indicator in the proc title. */
|
||||||
|
|
||||||
#ifdef SETPROCTITLE
|
#ifdef SETPROCTITLE
|
||||||
#define TACHOMETER /* */
|
#define TACHOMETER */
|
||||||
# ifdef TACHOMETER
|
# ifdef TACHOMETER
|
||||||
# define MAX_TACHOMETER 30
|
# define MAX_TACHOMETER 30
|
||||||
# endif
|
# endif
|
||||||
@ -51,23 +51,45 @@
|
|||||||
|
|
||||||
#define IMAGEMAP_SUPPORT /* */
|
#define IMAGEMAP_SUPPORT /* */
|
||||||
|
|
||||||
|
/* To add an additional field -- request duration -- to the access_log.
|
||||||
|
This adds the duration, in seconds that the processing of this
|
||||||
|
request took. */
|
||||||
|
|
||||||
|
/* #define LOG_DURATION */
|
||||||
|
|
||||||
/* If you want the server to check the execute bit of an HTML file to
|
/* If you want the server to check the execute bit of an HTML file to
|
||||||
determine if the file should be parsed, uncomment the following.
|
determine if the file should be parsed, uncomment the following.
|
||||||
Using this feature will give better performance for files which
|
Using this feature will give better performance for files which
|
||||||
are not parsed without the necessity of using the magic mime type */
|
are not parsed without the necessity of using the magic mime type */
|
||||||
|
|
||||||
/* #define XBITHACK /* */
|
/* #define XBITHACK */
|
||||||
|
|
||||||
|
/* If you want the server to be able to parse the output of CGI scripts,
|
||||||
|
then define the following. This will automatically be defined for
|
||||||
|
SHTTP. This does cause a performance degradation for CGI scripts,
|
||||||
|
as it requires reading the returned CGI headers off the socket one
|
||||||
|
byte at a time. */
|
||||||
|
|
||||||
|
/* #define CGI_SSI_HACK */
|
||||||
|
|
||||||
/* If you would like to ensure that CGI scripts don't mess with the
|
/* If you would like to ensure that CGI scripts don't mess with the
|
||||||
log files (except the error_log file), uncomment the following. */
|
log files (except the error_log file), uncomment the following. */
|
||||||
|
|
||||||
/* #define SECURE_LOGS /* */
|
/* #define SECURE_LOGS */
|
||||||
|
|
||||||
|
/* If you would like each "static" file to be sent with a Content-MD5
|
||||||
|
header to give clients a way of telling whether the object they
|
||||||
|
requested is the one they got - and hasn't been mangled along the way.
|
||||||
|
Of course, no clients support this yet (to my knowledge) and this will
|
||||||
|
_really_ hinder performance on really big files, but that's life. */
|
||||||
|
|
||||||
|
/* #define CONTENT_MD5 */
|
||||||
|
|
||||||
/* If you would like to specify the keyword LOCAL in your access
|
/* If you would like to specify the keyword LOCAL in your access
|
||||||
configuration file to match local address (ie, those without embedded
|
configuration file to match local address (ie, those without embedded
|
||||||
dots), uncomment the following. */
|
dots), uncomment the following. */
|
||||||
|
|
||||||
/* #define LOCALHACK /* */
|
/* #define LOCALHACK */
|
||||||
|
|
||||||
/* If you would like to use NIS services for passwords and group information,
|
/* If you would like to use NIS services for passwords and group information,
|
||||||
uncomment the following. NOTE: DO NOT USE THIS ON OPEN NETWORKS. The
|
uncomment the following. NOTE: DO NOT USE THIS ON OPEN NETWORKS. The
|
||||||
@ -75,20 +97,20 @@
|
|||||||
password in clear text across the network on every request which requires
|
password in clear text across the network on every request which requires
|
||||||
it. */
|
it. */
|
||||||
|
|
||||||
/* #define NIS_SUPPORT /* */
|
/* #define NIS_SUPPORT */
|
||||||
|
|
||||||
/* If you have a REALLY heavily loaded system, and you can't afford to
|
/* If you have a REALLY heavily loaded system, and you can't afford to
|
||||||
have a server per request(low memory?), you can compile with this i
|
have a server per request(low memory?), you can compile with this i
|
||||||
option to make max_servers a hard limit. */
|
option to make max_servers a hard limit. */
|
||||||
|
|
||||||
/* #define RESOURCE_LIMIT /* */
|
/* #define RESOURCE_LIMIT */
|
||||||
|
|
||||||
/* If your system doesn't support file descriptor passing, or if you
|
/* If your system doesn't support file descriptor passing, or if you
|
||||||
don't want to use it, defining the following will enable HTTPd to
|
don't want to use it, defining the following will enable HTTPd to
|
||||||
mimic the 1.3 Forking server. This should be defined in the system
|
mimic the 1.3 Forking server. This should be defined in the system
|
||||||
specific information in portability.h, and not here. */
|
specific information in portability.h, and not here. */
|
||||||
|
|
||||||
/* #define NO_PASS /* */
|
/* #define NO_PASS */
|
||||||
|
|
||||||
|
|
||||||
/* defines for new muli-child approach
|
/* defines for new muli-child approach
|
||||||
@ -103,12 +125,13 @@
|
|||||||
PROFILE to set the server up to profile the code
|
PROFILE to set the server up to profile the code
|
||||||
QUANTIFY is a profiler from Pure software
|
QUANTIFY is a profiler from Pure software
|
||||||
PURIFY is a memory checker from Pure software
|
PURIFY is a memory checker from Pure software
|
||||||
|
DEBUG compiles in extra debugging code (debug.c, mostly)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* #define PROFILE /* */
|
/* #define DEBUG */
|
||||||
|
/* #define PROFILE */
|
||||||
/* #define QUANTIFY /* */
|
/* #define QUANTIFY */
|
||||||
/* #define PURIFY /* */
|
/* #define PURIFY */
|
||||||
|
|
||||||
/* SHELL_PATH defines where the shell path is */
|
/* SHELL_PATH defines where the shell path is */
|
||||||
|
|
||||||
|
172
src/constants.h
172
src/constants.h
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* constants.h,v 1.42 1995/11/28 09:01:40 blong Exp
|
* constants.h,v 1.54 1996/04/05 18:54:42 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
@ -46,26 +46,34 @@
|
|||||||
#define IOBUFSIZE 8192
|
#define IOBUFSIZE 8192
|
||||||
|
|
||||||
|
|
||||||
#define HTTP_TIME_FORMAT "%a, %d %b %Y %T GMT"
|
#ifdef NEXT
|
||||||
|
# define HTTP_TIME_FORMAT "%a, %d %b %Y %X"
|
||||||
|
#else
|
||||||
|
# define HTTP_TIME_FORMAT "%a, %d %b %Y %T GMT"
|
||||||
|
#endif /* NEXT */
|
||||||
|
|
||||||
|
#define SERVER_VERSION "NCSA/1.5.2"
|
||||||
#define SERVER_VERSION "NCSA/1.5"
|
#define SERVER_SOURCE "NCSA/1.5.2"
|
||||||
#define SERVER_SOURCE "NCSA/1.5.0c"
|
|
||||||
#define SERVER_PROTOCOL "HTTP/1.0"
|
#define SERVER_PROTOCOL "HTTP/1.0"
|
||||||
|
|
||||||
/* Response Codes from HTTP/1.0 Spec
|
/* Response Codes from HTTP/1.0 Spec
|
||||||
all 4 digit codes are internal only */
|
all 4 digit codes are internal only */
|
||||||
|
#define SC_CONTINUE 100
|
||||||
|
#define SC_SWITCHING_PROTOCOLS 101
|
||||||
#define SC_DOCUMENT_FOLLOWS 200
|
#define SC_DOCUMENT_FOLLOWS 200
|
||||||
#define SC_CREATED 201
|
#define SC_CREATED 201
|
||||||
#define SC_ACCEPTED 202
|
#define SC_ACCEPTED 202
|
||||||
#define SC_PROV_INFO 203
|
#define SC_NON_AUTH_INFO 203
|
||||||
#define SC_NO_CONTENT 204
|
#define SC_NO_CONTENT 204
|
||||||
|
#define SC_RESET_CONTENT 205
|
||||||
|
#define SC_PARTIAL_CONTENT 206
|
||||||
#define SC_MULTIPLE_CHOICES 300
|
#define SC_MULTIPLE_CHOICES 300
|
||||||
#define SC_REDIRECT_PERM 301
|
#define SC_REDIRECT_PERM 301
|
||||||
#define SC_REDIRECT_TEMP 302
|
#define SC_REDIRECT_TEMP 302
|
||||||
#define SC_REDIRECT_LOCAL 3020
|
#define SC_REDIRECT_LOCAL 3020
|
||||||
#define SC_METHOD 303
|
#define SC_SEE_OTHER 303
|
||||||
#define SC_USE_LOCAL_COPY 304
|
#define SC_USE_LOCAL_COPY 304
|
||||||
|
#define SC_USE_PROXY 305
|
||||||
#define SC_BAD_REQUEST 400
|
#define SC_BAD_REQUEST 400
|
||||||
#define SC_AUTH_REQUIRED 401
|
#define SC_AUTH_REQUIRED 401
|
||||||
#define SC_PAY_REQUIRED 402
|
#define SC_PAY_REQUIRED 402
|
||||||
@ -77,6 +85,8 @@
|
|||||||
#define SC_REQUEST_TIMEOUT 408
|
#define SC_REQUEST_TIMEOUT 408
|
||||||
#define SC_CONFLICT 409
|
#define SC_CONFLICT 409
|
||||||
#define SC_GONE 410
|
#define SC_GONE 410
|
||||||
|
#define SC_LENGTH_REQUIRED 411
|
||||||
|
#define SC_UNLESS_TRUE 412
|
||||||
#define SC_SERVER_ERROR 500
|
#define SC_SERVER_ERROR 500
|
||||||
#define SC_NOT_IMPLEMENTED 501
|
#define SC_NOT_IMPLEMENTED 501
|
||||||
#define SC_BAD_GATEWAY 502
|
#define SC_BAD_GATEWAY 502
|
||||||
@ -85,28 +95,48 @@
|
|||||||
#define SC_NO_MEMORY 6992
|
#define SC_NO_MEMORY 6992
|
||||||
#define SC_CONF_ERROR 6993
|
#define SC_CONF_ERROR 6993
|
||||||
#define SC_BAD_IMAGEMAP 6994
|
#define SC_BAD_IMAGEMAP 6994
|
||||||
|
#define SC_AUTH_NO_WWW_AUTH 7001
|
||||||
|
|
||||||
/* Supported Methods - sorta*/
|
/* Supported Methods - sorta */
|
||||||
#define METHODS 7
|
#define METHODS 8
|
||||||
#define M_GET 0
|
#define M_GET 0
|
||||||
#define M_HEAD 1
|
#define M_HEAD 1
|
||||||
#define M_POST 2
|
#define M_POST 2
|
||||||
#define M_PUT 3
|
#define M_PUT 3
|
||||||
#define M_DELETE 4
|
#define M_DELETE 4
|
||||||
|
#define M_SECURE 5
|
||||||
#define M_INVALID -1
|
#define M_INVALID -1
|
||||||
|
|
||||||
/* Unsupported Methods */
|
/* Unsupported Methods */
|
||||||
#define M_LINK 5
|
#define M_LINK 6
|
||||||
#define M_UNLINK 6
|
#define M_UNLINK 7
|
||||||
|
#define M_OPTIONS 8
|
||||||
|
#define M_PATCH 9
|
||||||
|
#define M_COPY 10
|
||||||
|
#define M_MOVE 11
|
||||||
|
#define M_TRACE 12
|
||||||
|
#define M_WRAPPED 13
|
||||||
|
|
||||||
/* Array containing Method names */
|
/* Array containing Method names */
|
||||||
extern char *methods[];
|
extern char *methods[];
|
||||||
|
|
||||||
|
/* Supported Protocals - sorta */
|
||||||
|
#define PROTOCALS 6
|
||||||
|
#define P_OTHER 0
|
||||||
|
#define P_HTTP_0_9 1
|
||||||
|
#define P_HTTP_1_0 2
|
||||||
|
#define P_HTTP_1_1 3
|
||||||
|
#define P_SHTTP_1_1 4
|
||||||
|
#define P_SHTTP_1_2 5
|
||||||
|
|
||||||
|
extern char *protocals[];
|
||||||
|
|
||||||
/* Object types */
|
/* Object types */
|
||||||
#define A_STD_DOCUMENT 0
|
#define A_STD_DOCUMENT 0
|
||||||
#define A_REDIRECT_TEMP 1
|
#define A_REDIRECT_TEMP 1
|
||||||
#define A_REDIRECT_PERM 2
|
#define A_REDIRECT_PERM 2
|
||||||
#define A_SCRIPT_CGI 3
|
#define A_SCRIPT_CGI 3
|
||||||
|
#define A_SCRIPT_FCGI 4
|
||||||
|
|
||||||
/* Security Options */
|
/* Security Options */
|
||||||
#define OPT_NONE 0
|
#define OPT_NONE 0
|
||||||
@ -126,14 +156,15 @@ extern char *methods[];
|
|||||||
#define OR_AUTHCFG 8
|
#define OR_AUTHCFG 8
|
||||||
#define OR_INDEXES 16
|
#define OR_INDEXES 16
|
||||||
#define OR_REDIRECT 32
|
#define OR_REDIRECT 32
|
||||||
#define OR_ALL (OR_LIMIT | OR_OPTIONS | OR_FILEINFO | OR_AUTHCFG | OR_INDEXES | OR_REDIRECT)
|
#define OR_PRIVACY_ENHANCE 64
|
||||||
|
#define OR_ALL (OR_LIMIT | OR_OPTIONS | OR_FILEINFO | OR_AUTHCFG | OR_INDEXES | OR_REDIRECT | OR_PRIVACY_ENHANCE)
|
||||||
/* PEM/PGP Encodings */
|
|
||||||
|
|
||||||
/* Magic MIME Types */
|
/* Magic MIME Types */
|
||||||
#define CGI_MAGIC_TYPE "application/x-httpd-cgi"
|
#define CGI_MAGIC_TYPE "application/x-httpd-cgi"
|
||||||
|
#define FCGI_MAGIC_TYPE "application/x-httpd-fcgi"
|
||||||
#define INCLUDES_MAGIC_TYPE "text/x-server-parsed-html"
|
#define INCLUDES_MAGIC_TYPE "text/x-server-parsed-html"
|
||||||
#define IMAGEMAP_MAGIC_TYPE "text/x-imagemap"
|
#define IMAGEMAP_MAGIC_TYPE "text/x-imagemap"
|
||||||
|
#define BLACKOUT_MAGIC_TYPE "text/x-httpd-black"
|
||||||
|
|
||||||
/* For directory indexing */
|
/* For directory indexing */
|
||||||
#define BY_PATH 0
|
#define BY_PATH 0
|
||||||
@ -171,6 +202,7 @@ typedef struct {
|
|||||||
#define AUTHFILETYPE_STANDARD 0
|
#define AUTHFILETYPE_STANDARD 0
|
||||||
#define AUTHFILETYPE_DBM 1
|
#define AUTHFILETYPE_DBM 1
|
||||||
#define AUTHFILETYPE_NIS 2
|
#define AUTHFILETYPE_NIS 2
|
||||||
|
#define AUTHFILETYPE_RADIUS 3
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char d[MAX_STRING_LEN];
|
char d[MAX_STRING_LEN];
|
||||||
@ -178,13 +210,25 @@ typedef struct {
|
|||||||
char override;
|
char override;
|
||||||
|
|
||||||
int order[METHODS];
|
int order[METHODS];
|
||||||
|
int bSatisfy; /* 0 = All, 1 = Any */
|
||||||
|
|
||||||
int num_allow[METHODS];
|
int num_allow[METHODS];
|
||||||
char *allow[METHODS][MAX_SECURITY];
|
char *allow[METHODS][MAX_SECURITY];
|
||||||
int bSatisfy; /* 0 = All, 1 = Any */
|
|
||||||
int num_auth[METHODS];
|
int num_auth[METHODS];
|
||||||
char *auth[METHODS][MAX_SECURITY];
|
char *auth[METHODS][MAX_SECURITY];
|
||||||
|
|
||||||
|
int num_referer_allow[METHODS];
|
||||||
|
char *referer_allow[METHODS][MAX_SECURITY];
|
||||||
|
|
||||||
|
int num_referer_deny[METHODS];
|
||||||
|
char *referer_deny[METHODS][MAX_SECURITY];
|
||||||
|
|
||||||
|
int num_deny[METHODS];
|
||||||
|
char *deny[METHODS][MAX_SECURITY];
|
||||||
|
|
||||||
|
char *on_deny[METHODS];
|
||||||
|
|
||||||
char auth_type[MAX_STRING_LEN];
|
char auth_type[MAX_STRING_LEN];
|
||||||
char auth_name[MAX_STRING_LEN];
|
char auth_name[MAX_STRING_LEN];
|
||||||
char auth_pwfile[MAX_STRING_LEN];
|
char auth_pwfile[MAX_STRING_LEN];
|
||||||
@ -196,17 +240,8 @@ typedef struct {
|
|||||||
int auth_digestfile_type;
|
int auth_digestfile_type;
|
||||||
#endif /* DIGEST_AUTH */
|
#endif /* DIGEST_AUTH */
|
||||||
|
|
||||||
int num_deny[METHODS];
|
|
||||||
char *deny[METHODS][MAX_SECURITY];
|
|
||||||
} security_data;
|
} security_data;
|
||||||
|
|
||||||
#define PROTOCALS 4
|
|
||||||
#define P_OTHER 0
|
|
||||||
#define P_HTTP_0_9 1
|
|
||||||
#define P_HTTP_1_0 2
|
|
||||||
#define P_HTTP_1_1 3
|
|
||||||
|
|
||||||
extern char *protocals[];
|
|
||||||
|
|
||||||
typedef struct _ErrorDoc {
|
typedef struct _ErrorDoc {
|
||||||
/* int Type; */
|
/* int Type; */
|
||||||
@ -221,6 +256,20 @@ typedef struct _ErrorDoc {
|
|||||||
#define DNS_STD 2
|
#define DNS_STD 2
|
||||||
#define DNS_MAX 3
|
#define DNS_MAX 3
|
||||||
|
|
||||||
|
/* ----------- Our socket buffering routine defines ----------------- */
|
||||||
|
#define SB_NEW 1
|
||||||
|
#define SB_READ 2
|
||||||
|
#define SB_FLUSHED 3
|
||||||
|
#define SB_ERROR 4
|
||||||
|
|
||||||
|
typedef struct _sock_buf {
|
||||||
|
char buffer[HUGE_STRING_LEN];
|
||||||
|
int buf_posn;
|
||||||
|
int buf_good;
|
||||||
|
int status;
|
||||||
|
int sd;
|
||||||
|
} sock_buf;
|
||||||
|
|
||||||
/* ------------------- per hostname configuration -------------------- */
|
/* ------------------- per hostname configuration -------------------- */
|
||||||
|
|
||||||
/* These #defines are for keeping track of which options are links to
|
/* These #defines are for keeping track of which options are links to
|
||||||
@ -273,37 +322,66 @@ typedef struct _per_host {
|
|||||||
int num_doc_errors;
|
int num_doc_errors;
|
||||||
ErrorDoc **doc_errors;
|
ErrorDoc **doc_errors;
|
||||||
|
|
||||||
|
|
||||||
struct _lookup *translations;
|
struct _lookup *translations;
|
||||||
struct _per_host *next;
|
struct _per_host *next;
|
||||||
} per_host;
|
} per_host;
|
||||||
|
|
||||||
/* --------- Per request Data Structure ------------- */
|
/* --------- Per request Data Structure ------------- */
|
||||||
|
|
||||||
|
/* Request Flags */
|
||||||
|
#define DOING_PGP 1
|
||||||
|
#define DOING_SHTTP 2
|
||||||
|
#define DOING_SSL 3
|
||||||
|
|
||||||
typedef struct _per_request {
|
typedef struct _per_request {
|
||||||
/* Information about Contents; */
|
/* Information about Contents; */
|
||||||
int ownURL;
|
|
||||||
int ownDNS;
|
|
||||||
int ownENV;
|
int ownENV;
|
||||||
|
int ownDNS;
|
||||||
|
int ownSB;
|
||||||
|
int RequestFlags;
|
||||||
|
|
||||||
/* Request Information */
|
/* Request Information */
|
||||||
int status;
|
int status;
|
||||||
/* char *status_line; */
|
char *status_line;
|
||||||
long bytes_sent;
|
long bytes_sent;
|
||||||
|
|
||||||
/* request stuff to be logged */
|
/* request stuff to be logged */
|
||||||
char agent[HUGE_STRING_LEN];
|
|
||||||
char referer[HUGE_STRING_LEN];
|
|
||||||
|
|
||||||
int http_version;
|
|
||||||
int method;
|
int method;
|
||||||
char url[HUGE_STRING_LEN];
|
char url[HUGE_STRING_LEN];
|
||||||
char filename[HUGE_STRING_LEN];
|
|
||||||
char args[HUGE_STRING_LEN];
|
char args[HUGE_STRING_LEN];
|
||||||
/* char *content_type; */
|
char path_info[HUGE_STRING_LEN];
|
||||||
|
int http_version;
|
||||||
|
char inh_agent[HUGE_STRING_LEN];
|
||||||
|
char inh_referer[HUGE_STRING_LEN];
|
||||||
|
char inh_called_hostname[MAX_STRING_LEN];
|
||||||
|
char inh_if_mod_since[MAX_STRING_LEN];
|
||||||
|
char inh_auth_line[HUGE_STRING_LEN];
|
||||||
|
char inh_content_type[MAX_STRING_LEN];
|
||||||
|
int inh_content_length;
|
||||||
|
|
||||||
|
/* Internal Info */
|
||||||
|
char filename[HUGE_STRING_LEN];
|
||||||
|
|
||||||
|
/* Outgoing information */
|
||||||
|
char outh_location[HUGE_STRING_LEN];
|
||||||
|
char outh_last_mod[MAX_STRING_LEN];
|
||||||
|
char outh_www_auth[HUGE_STRING_LEN];
|
||||||
|
char outh_content_type[MAX_STRING_LEN];
|
||||||
|
char outh_content_encoding[MAX_STRING_LEN];
|
||||||
|
int outh_content_length;
|
||||||
|
char *outh_cgi;
|
||||||
|
|
||||||
|
#ifdef CONTENT_MD5
|
||||||
|
char *outh_content_md5;
|
||||||
|
#endif /* CONTENT_MD5 */
|
||||||
|
|
||||||
char auth_type[MAX_STRING_LEN];
|
char auth_type[MAX_STRING_LEN];
|
||||||
int dirs_in_alias;
|
int dirs_in_alias;
|
||||||
|
|
||||||
|
/* Authentication Information */
|
||||||
|
char auth_user[MAX_STRING_LEN];
|
||||||
|
char auth_group[MAX_STRING_LEN];
|
||||||
|
|
||||||
/* authentication files */
|
/* authentication files */
|
||||||
char* auth_name;
|
char* auth_name;
|
||||||
char* auth_pwfile;
|
char* auth_pwfile;
|
||||||
@ -314,32 +392,36 @@ typedef struct _per_request {
|
|||||||
char* auth_digestfile;
|
char* auth_digestfile;
|
||||||
int auth_digestfile_type;
|
int auth_digestfile_type;
|
||||||
#endif /* DIGEST_AUTH */
|
#endif /* DIGEST_AUTH */
|
||||||
|
|
||||||
/* Domain Restriction Info */
|
/* Domain Restriction Info */
|
||||||
int bNotifyDomainRestricted;
|
int bNotifyDomainRestricted;
|
||||||
int bSatisfiedDomain;
|
int bSatisfiedDomain;
|
||||||
|
int bSatisfiedReferer;
|
||||||
int dns_host_lookup;
|
int dns_host_lookup;
|
||||||
|
|
||||||
int num_env;
|
int num_env;
|
||||||
int max_env;
|
int max_env;
|
||||||
char **env;
|
char **env;
|
||||||
int *env_len;
|
int *env_len;
|
||||||
|
|
||||||
/* Client Information */
|
/* Client Information */
|
||||||
char *remote_host;
|
char *remote_host;
|
||||||
char *remote_name;
|
char *remote_name;
|
||||||
char *remote_ip;
|
char *remote_ip;
|
||||||
/* char *remote_logname; */
|
/* char *remote_logname; */
|
||||||
|
|
||||||
/* Server Information */
|
/* Server Information */
|
||||||
int connection_socket;
|
int connection_socket;
|
||||||
|
int in;
|
||||||
FILE *out;
|
FILE *out;
|
||||||
|
sock_buf *sb;
|
||||||
|
sock_buf *cgi_buf;
|
||||||
per_host *hostInfo;
|
per_host *hostInfo;
|
||||||
struct in_addr address_info;
|
struct in_addr address_info;
|
||||||
|
|
||||||
/* Linked List of requests */
|
/* Linked List of requests */
|
||||||
struct _per_request *next;
|
struct _per_request *next;
|
||||||
|
|
||||||
} per_request;
|
} per_request;
|
||||||
|
|
||||||
#endif /* _CONSTANTS_H_ */
|
#endif /* _CONSTANTS_H_ */
|
||||||
|
83
src/debug.c
Normal file
83
src/debug.c
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/* Various debugging routines */
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "portability.h"
|
||||||
|
|
||||||
|
#include "constants.h"
|
||||||
|
#include "host_config.h"
|
||||||
|
#include "http_request.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef SOLARIS2
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/procfs.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
prpsinfo_t p;
|
||||||
|
long current_process_size()
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
char filename[MAX_STRING_LEN];
|
||||||
|
int fd;
|
||||||
|
int pid;
|
||||||
|
|
||||||
|
pid = getpid();
|
||||||
|
|
||||||
|
fprintf(stderr,"%d\n",pid);
|
||||||
|
|
||||||
|
if (pid < 10) {
|
||||||
|
sprintf(filename,"/proc/0000%d",pid);
|
||||||
|
} else if (pid < 100) {
|
||||||
|
sprintf(filename,"/proc/000%d",pid);
|
||||||
|
} else if (pid < 1000) {
|
||||||
|
sprintf(filename,"/proc/00%d",pid);
|
||||||
|
} else if (pid < 10000) {
|
||||||
|
sprintf(filename,"/proc/0%d",pid);
|
||||||
|
} else {
|
||||||
|
sprintf(filename,"/proc/%d",pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* fprintf(stderr,filename); */
|
||||||
|
if (!(fd = open(filename,O_RDONLY))) {
|
||||||
|
fprintf(stderr,"Error openning file %s, errno=%d\n",filename,errno);
|
||||||
|
}
|
||||||
|
retval = ioctl(fd,PIOCPSINFO,&p);
|
||||||
|
if (retval == -1) {
|
||||||
|
fprintf(stderr,"Error in ioctl, errno = %d\n", errno);
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
fprintf(stderr,"%X %X\n",&p,filename);
|
||||||
|
sprintf(filename,"%d bytes memory", p.pr_bysize);
|
||||||
|
log_error(filename,gConfiguration->error_log);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* SOLARIS2 */
|
||||||
|
|
||||||
|
#ifdef AIX3
|
||||||
|
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
long current_process_size(char *msg) {
|
||||||
|
char S[MAX_STRING_LEN];
|
||||||
|
struct mallinfo mi;
|
||||||
|
int memory;
|
||||||
|
|
||||||
|
mi = mallinfo();
|
||||||
|
|
||||||
|
|
||||||
|
memory = mi.usmblks+mi.uordblks;
|
||||||
|
sprintf(S,"%25s: Space in Use: %d", msg,memory);
|
||||||
|
log_error(S,gConfiguration->error_log);
|
||||||
|
|
||||||
|
return memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* AIX3 */
|
||||||
|
|
||||||
|
#endif /* DEBUG */
|
@ -53,6 +53,11 @@ int get_digest(per_request *reqInfo, char *user, char *realm, char *digest,
|
|||||||
char r[MAX_STRING_LEN];
|
char r[MAX_STRING_LEN];
|
||||||
|
|
||||||
if (reqInfo->auth_digestfile_type == AUTHFILETYPE_STANDARD) {
|
if (reqInfo->auth_digestfile_type == AUTHFILETYPE_STANDARD) {
|
||||||
|
if (reqInfo->auth_digestfile == NULL) {
|
||||||
|
sprintf (errstr, "No digest file specified for URL: %s\n",
|
||||||
|
reqInfo->url);
|
||||||
|
die(reqInfo,SC_SERVER_ERROR,errstr);
|
||||||
|
}
|
||||||
if(!(f=FOpen(reqInfo->auth_digestfile,"r"))) {
|
if(!(f=FOpen(reqInfo->auth_digestfile,"r"))) {
|
||||||
sprintf(errstr,"Could not open digest file %s",
|
sprintf(errstr,"Could not open digest file %s",
|
||||||
reqInfo->auth_digestfile);
|
reqInfo->auth_digestfile);
|
||||||
@ -202,7 +207,7 @@ void Digest_Check(per_request *reqInfo, char *user, security_data* sec)
|
|||||||
opaque[0] = 0;
|
opaque[0] = 0;
|
||||||
p = q = NULL;
|
p = q = NULL;
|
||||||
|
|
||||||
p = auth_line;
|
p = reqInfo->inh_auth_line;
|
||||||
while (isspace(*p)) {
|
while (isspace(*p)) {
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
59
src/env.c
59
src/env.c
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
*env.c,v 1.17 1995/11/28 09:01:42 blong Exp
|
*env.c,v 1.20 1996/04/05 18:54:44 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
@ -28,10 +28,15 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "env.h"
|
#include "env.h"
|
||||||
|
#include "http_request.h"
|
||||||
#include "http_log.h"
|
#include "http_log.h"
|
||||||
|
#include "allocate.h"
|
||||||
|
|
||||||
/* Older version, required external help. Newer version should be self
|
/* Older version, required external help. Newer version should be self
|
||||||
contained for easier extensibility */
|
* contained for easier extensibility
|
||||||
|
* updated to use string allocation structures for speed and so it doesn't
|
||||||
|
* leak
|
||||||
|
*/
|
||||||
|
|
||||||
/* This will change the value of an environment variable to *value
|
/* This will change the value of an environment variable to *value
|
||||||
if found. Returns TRUE if the replace took place, FALSE otherwise */
|
if found. Returns TRUE if the replace took place, FALSE otherwise */
|
||||||
@ -42,7 +47,7 @@ int replace_env_str(per_request *reqInfo, char *name, char *value)
|
|||||||
|
|
||||||
for (i = 0, len = strlen(name); reqInfo->env[i]; i++) {
|
for (i = 0, len = strlen(name); reqInfo->env[i]; i++) {
|
||||||
if (strncmp(reqInfo->env[i], name, len) == 0) {
|
if (strncmp(reqInfo->env[i], name, len) == 0) {
|
||||||
free(reqInfo->env[i]);
|
freeString(reqInfo->env[i]);
|
||||||
if (i < reqInfo->num_env) {
|
if (i < reqInfo->num_env) {
|
||||||
reqInfo->env[i] = reqInfo->env[--(reqInfo->num_env)];
|
reqInfo->env[i] = reqInfo->env[--(reqInfo->num_env)];
|
||||||
reqInfo->env_len[i] = reqInfo->env_len[reqInfo->num_env];
|
reqInfo->env_len[i] = reqInfo->env_len[reqInfo->num_env];
|
||||||
@ -63,9 +68,9 @@ int replace_env_str(per_request *reqInfo, char *name, char *value)
|
|||||||
|
|
||||||
void free_env(per_request *reqInfo) {
|
void free_env(per_request *reqInfo) {
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
for(x=0;reqInfo->env[x];x++)
|
for(x=0;reqInfo->env[x];x++)
|
||||||
free(reqInfo->env[x]);
|
freeString(reqInfo->env[x]);
|
||||||
free(reqInfo->env);
|
free(reqInfo->env);
|
||||||
free(reqInfo->env_len);
|
free(reqInfo->env_len);
|
||||||
reqInfo->env = NULL;
|
reqInfo->env = NULL;
|
||||||
@ -82,7 +87,7 @@ int merge_header(per_request *reqInfo, char *header, char *value)
|
|||||||
{
|
{
|
||||||
register int l,lt;
|
register int l,lt;
|
||||||
int len, ndx;
|
int len, ndx;
|
||||||
char **t;
|
char **t,*tmp;
|
||||||
|
|
||||||
len = strlen(value);
|
len = strlen(value);
|
||||||
|
|
||||||
@ -94,14 +99,20 @@ int merge_header(per_request *reqInfo, char *header, char *value)
|
|||||||
if(!strncmp(*t,header,l)) {
|
if(!strncmp(*t,header,l)) {
|
||||||
lt = strlen(*t);
|
lt = strlen(*t);
|
||||||
if ((lt + len + 2) > reqInfo->env_len[ndx]) {
|
if ((lt + len + 2) > reqInfo->env_len[ndx]) {
|
||||||
int n = reqInfo->env_len[ndx] / BIG_ENV_VAR_LEN + 1;
|
tmp = reqInfo->env[ndx];
|
||||||
if(!(*t = (char *) realloc(*t,n * BIG_ENV_VAR_LEN*sizeof(char))))
|
if ((lt+len+2) > HUGE_STRING_LEN) {
|
||||||
die(reqInfo, SC_NO_MEMORY,"merge_header");
|
reqInfo->env[ndx] = newString(lt+len+2,STR_REQ);
|
||||||
reqInfo->env_len[ndx] = n * BIG_ENV_VAR_LEN;
|
} else {
|
||||||
}
|
reqInfo->env[ndx] = newString(HUGE_STRING_LEN,STR_REQ);
|
||||||
(*t)[lt++] = ',';
|
}
|
||||||
(*t)[lt++] = ' ';
|
sprintf(reqInfo->env[ndx],"%s, %s",tmp,value);
|
||||||
strcpy(&((*t)[lt]),value);
|
freeString(tmp);
|
||||||
|
} else {
|
||||||
|
(*t)[lt++] = ',';
|
||||||
|
(*t)[lt++] = ' ';
|
||||||
|
strcpy(&((*t)[lt]),value);
|
||||||
|
}
|
||||||
|
header[l-1] = '\0';
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,7 +127,14 @@ int merge_header(per_request *reqInfo, char *header, char *value)
|
|||||||
int make_env_str(per_request *reqInfo, char *name, char *value)
|
int make_env_str(per_request *reqInfo, char *name, char *value)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
char tmp[HUGE_STRING_LEN];
|
||||||
|
|
||||||
|
if (value == NULL) {
|
||||||
|
/*
|
||||||
|
* I've generally protected against this, but sanity isn't a bad thing
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (reqInfo->env == NULL) {
|
if (reqInfo->env == NULL) {
|
||||||
if (!(reqInfo->env = (char **) malloc(ENV_BEG_SIZE * sizeof(char *)))
|
if (!(reqInfo->env = (char **) malloc(ENV_BEG_SIZE * sizeof(char *)))
|
||||||
|| !(reqInfo->env_len = (int*) malloc(ENV_BEG_SIZE * sizeof(int))))
|
|| !(reqInfo->env_len = (int*) malloc(ENV_BEG_SIZE * sizeof(int))))
|
||||||
@ -131,13 +149,12 @@ int make_env_str(per_request *reqInfo, char *name, char *value)
|
|||||||
die(reqInfo,SC_NO_MEMORY,"make_env_str:realloc");
|
die(reqInfo,SC_NO_MEMORY,"make_env_str:realloc");
|
||||||
reqInfo->max_env += ENV_INC_SIZE;
|
reqInfo->max_env += ENV_INC_SIZE;
|
||||||
}
|
}
|
||||||
if (!(reqInfo->env[reqInfo->num_env] =
|
strncpy(tmp, name, HUGE_STRING_LEN);
|
||||||
(char *) malloc(n = (strlen(name) + strlen(value) + 2))))
|
strncat(tmp,"=",HUGE_STRING_LEN - strlen(tmp));
|
||||||
die(reqInfo,SC_NO_MEMORY,"make_env_str:add");
|
strncat(tmp,value,HUGE_STRING_LEN - strlen(tmp));
|
||||||
strcpy(reqInfo->env[reqInfo->num_env], name);
|
reqInfo->env[reqInfo->num_env] = dupStringP(tmp,STR_REQ);
|
||||||
strcat(reqInfo->env[reqInfo->num_env],"=");
|
reqInfo->env_len[reqInfo->num_env] =
|
||||||
strcat(reqInfo->env[reqInfo->num_env],value);
|
sizeofString(reqInfo->env[reqInfo->num_env]);
|
||||||
reqInfo->env_len[reqInfo->num_env] = n;
|
|
||||||
|
|
||||||
reqInfo->num_env++;
|
reqInfo->num_env++;
|
||||||
reqInfo->env[reqInfo->num_env] = NULL;
|
reqInfo->env[reqInfo->num_env] = NULL;
|
||||||
|
3529
src/fcgi.c
Normal file
3529
src/fcgi.c
Normal file
File diff suppressed because it is too large
Load Diff
28
src/fcgi.h
Normal file
28
src/fcgi.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* FCGI Interface for the NCSA HTTPd Server
|
||||||
|
*
|
||||||
|
* Copyright (C) 1995 Open Market, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This file contains proprietary and confidential information and
|
||||||
|
* remains the unpublished property of Open Market, Inc. Use,
|
||||||
|
* disclosure, or reproduction is prohibited except as permitted by
|
||||||
|
* express written license agreement with Open Market, Inc.
|
||||||
|
************************************************************************
|
||||||
|
* $Id: fcgi.h,v 1.2 1996/03/25 22:21:30 blong Exp $
|
||||||
|
************************************************************************
|
||||||
|
*
|
||||||
|
* fcgi.c -- interface to FCGI
|
||||||
|
*
|
||||||
|
* Trung Dung
|
||||||
|
* tdung@openmarket.com
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _FCGI_H
|
||||||
|
#define _FCGI_H 1
|
||||||
|
|
||||||
|
/* External Functions */
|
||||||
|
int FastCgiHandler(per_request *reqPtr);
|
||||||
|
char * AppClassCmd(per_host *host, char *arg);
|
||||||
|
#endif /* _FCGI_H */
|
15
src/fdwrap.c
15
src/fdwrap.c
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* fdwrap.c,v 1.11 1995/11/28 09:01:44 blong Exp
|
* fdwrap.c,v 1.15 1996/04/05 18:54:46 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
@ -18,14 +18,6 @@
|
|||||||
* of open ones and close them when errors happen. Should
|
* of open ones and close them when errors happen. Should
|
||||||
* make leaks next to impossible.
|
* make leaks next to impossible.
|
||||||
*
|
*
|
||||||
* 08-15-95 guillory
|
|
||||||
* initial code
|
|
||||||
*
|
|
||||||
* 08-16-95 blong
|
|
||||||
* added headers, etc.
|
|
||||||
*
|
|
||||||
* 09-07-97 mshapiro
|
|
||||||
* added includes for <malloc.h> / <sys/malloc.h>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -60,7 +52,7 @@ static int nSize;
|
|||||||
void fd_error(char *err_msg)
|
void fd_error(char *err_msg)
|
||||||
{
|
{
|
||||||
char S[MAX_STRING_LEN];
|
char S[MAX_STRING_LEN];
|
||||||
sprintf(S,"fdwrap error: %s\n",err_msg);
|
sprintf(S,"fdwrap error: %s",err_msg);
|
||||||
log_error(S,gConfiguration->error_log);
|
log_error(S,gConfiguration->error_log);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -68,7 +60,7 @@ void fd_error(char *err_msg)
|
|||||||
void fd_warn(char *err_msg)
|
void fd_warn(char *err_msg)
|
||||||
{
|
{
|
||||||
char S[MAX_STRING_LEN];
|
char S[MAX_STRING_LEN];
|
||||||
sprintf(S,"fdwrap warn: %s\n",err_msg);
|
sprintf(S,"fdwrap warn: %s",err_msg);
|
||||||
log_error(S,gConfiguration->error_log);
|
log_error(S,gConfiguration->error_log);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,6 +102,7 @@ int GrowTable (int fd)
|
|||||||
FdTab[ndx].fp = NULL;
|
FdTab[ndx].fp = NULL;
|
||||||
}
|
}
|
||||||
nSize = fd + 10;
|
nSize = fd + 10;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
*host_config.c,v 1.15 1995/11/06 20:57:59 blong Exp
|
*host_config.c,v 1.20 1996/04/05 18:54:47 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
@ -28,6 +28,7 @@
|
|||||||
#include "http_log.h"
|
#include "http_log.h"
|
||||||
#include "http_alias.h"
|
#include "http_alias.h"
|
||||||
#include "http_mime.h"
|
#include "http_mime.h"
|
||||||
|
#include "http_request.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
per_host* gConfiguration;
|
per_host* gConfiguration;
|
||||||
@ -81,7 +82,6 @@ per_host* create_host_conf(per_host *hostInfo, int virtual) {
|
|||||||
newInfo->doc_errors = hostInfo->doc_errors;
|
newInfo->doc_errors = hostInfo->doc_errors;
|
||||||
newInfo->translations = hostInfo->translations;
|
newInfo->translations = hostInfo->translations;
|
||||||
|
|
||||||
|
|
||||||
/* thanks to Kevin Ruddy (smiles@powerdog.com) for re-teaching me
|
/* thanks to Kevin Ruddy (smiles@powerdog.com) for re-teaching me
|
||||||
how to make a linked list */
|
how to make a linked list */
|
||||||
|
|
||||||
@ -278,7 +278,10 @@ void which_host_conf(per_request *reqInfo) {
|
|||||||
while (host && !Found) {
|
while (host && !Found) {
|
||||||
if (host->address_info.s_addr == reqInfo->address_info.s_addr) {
|
if (host->address_info.s_addr == reqInfo->address_info.s_addr) {
|
||||||
if (!host->virtualhost && host->called_hostname) {
|
if (!host->virtualhost && host->called_hostname) {
|
||||||
if (!strcasecmp(called_hostname,host->called_hostname)) Found = TRUE;
|
if (!strncasecmp(host->called_hostname,reqInfo->inh_called_hostname,
|
||||||
|
strlen(host->called_hostname))) {
|
||||||
|
Found = TRUE;
|
||||||
|
}
|
||||||
} else Found = TRUE;
|
} else Found = TRUE;
|
||||||
}
|
}
|
||||||
if (!Found) host = host->next;
|
if (!Found) host = host->next;
|
||||||
|
@ -10,21 +10,12 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* http_access.c,v 1.69 1995/11/28 09:01:48 blong Exp
|
* http_access.c,v 1.78 1996/04/05 18:54:49 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* http_access: Security options etc.
|
* http_access: Security options etc.
|
||||||
*
|
*
|
||||||
* Based on NCSA HTTPd 1.3 by Rob McCool
|
|
||||||
*
|
|
||||||
* 03-12-95 blong
|
|
||||||
* Added patch to fix ALLOW_THEN_DENY
|
|
||||||
*
|
|
||||||
* 10-02-95 blong
|
|
||||||
* Added patch by Maurizio Codogno (mau@beatles.cselt.stet.it) to
|
|
||||||
* allow or deny hosts using a LOCAL keyword which matches all hosts
|
|
||||||
* without a dot in their name
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -47,12 +38,7 @@
|
|||||||
#include "http_mime.h"
|
#include "http_mime.h"
|
||||||
#include "http_log.h"
|
#include "http_log.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "allocate.h"
|
||||||
#ifdef DIGEST_AUTH
|
|
||||||
int client_accepts_digest;
|
|
||||||
int assume_digest_support;
|
|
||||||
#endif /* DIGEST_AUTH */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Modified this bad boy so he wouldn't
|
* Modified this bad boy so he wouldn't
|
||||||
@ -81,25 +67,28 @@ int in_domain(char *domain, char *what)
|
|||||||
* Address matching should really be done with subnet masks, though.
|
* Address matching should really be done with subnet masks, though.
|
||||||
* mullen@itd.nrl.navy.mil 11/16/95
|
* mullen@itd.nrl.navy.mil 11/16/95
|
||||||
*
|
*
|
||||||
* Forget it, the code didn't work, and we'll just change the docs to
|
* Returned to normal, as the patch didn't work. For now, I think
|
||||||
* let everyone know how it really works.
|
* that updating the documenation to say that you have to end in
|
||||||
|
* a . in order to prohibit other networks is better, as some people
|
||||||
|
* might like the ability to allow anything that matches 128.174.1
|
||||||
|
* blong - 1/26/96
|
||||||
*/
|
*/
|
||||||
int in_ip(char *domain, char *what)
|
int in_ip(char *domain, char *what)
|
||||||
{
|
{
|
||||||
/* int dl=strlen(domain);
|
/* int dl=strlen(domain);
|
||||||
|
|
||||||
return (!strncmp(domain,what,dl)) &&
|
return (!strncmp(domain,what,dl)) &&
|
||||||
(domain[dl-1]=='.' && strlen(what)<=dl && what[dl]=='.');
|
(domain[dl-1]=='.' && strlen(what)<=dl && what[dl]=='.'); */
|
||||||
*/
|
|
||||||
return(!strncmp(domain,what,strlen(domain)));
|
return(!strncmp(domain,what,strlen(domain)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find_allow()
|
/* find_host_allow()
|
||||||
* Hunts down list of allowed hosts and returns 1 if allowed, 0 if not
|
* Hunts down list of allowed hosts and returns 1 if allowed, 0 if not
|
||||||
* As soon as it finds an allow that matches, it returns 1
|
* As soon as it finds an allow that matches, it returns 1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int find_allow(per_request *reqInfo, int x)
|
int find_host_allow(per_request *reqInfo, int x)
|
||||||
{
|
{
|
||||||
register int y;
|
register int y;
|
||||||
|
|
||||||
@ -142,11 +131,11 @@ int find_allow(per_request *reqInfo, int x)
|
|||||||
return FA_DENY;
|
return FA_DENY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find_deny()
|
/* find_host_deny()
|
||||||
* Hunts down list of denied hosts and returns 0 if denied, 1 if not
|
* Hunts down list of denied hosts and returns 0 if denied, 1 if not
|
||||||
* As soon as it finds a deny that matches, it returns 0
|
* As soon as it finds a deny that matches, it returns 0
|
||||||
*/
|
*/
|
||||||
int find_deny(per_request *reqInfo, int x)
|
int find_host_deny(per_request *reqInfo, int x)
|
||||||
{
|
{
|
||||||
register int y;
|
register int y;
|
||||||
|
|
||||||
@ -191,8 +180,85 @@ int find_deny(per_request *reqInfo, int x)
|
|||||||
return FA_ALLOW;
|
return FA_ALLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* match_referer()
|
||||||
|
* currently matches restriction with sent for only as long as restricted
|
||||||
|
*/
|
||||||
|
int match_referer(char *restrict, char *sent) {
|
||||||
|
return !(strcmp_match(sent,restrict));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find_referer_allow()
|
||||||
|
* Hunts down list of allowed hosts and returns 1 if allowed, 0 if not
|
||||||
|
* As soon as it finds an allow that matches, it returns 1
|
||||||
|
*/
|
||||||
|
|
||||||
|
int find_referer_allow(per_request *reqInfo, int x)
|
||||||
|
{
|
||||||
|
register int y;
|
||||||
|
|
||||||
|
/* If no allows are specified, then allow */
|
||||||
|
if(sec[x].num_referer_allow[reqInfo->method] == 0)
|
||||||
|
return FA_ALLOW;
|
||||||
|
|
||||||
|
for(y=0;y<sec[x].num_referer_allow[reqInfo->method];y++) {
|
||||||
|
if(!strcmp("all",sec[x].referer_allow[reqInfo->method][y]))
|
||||||
|
return FA_ALLOW;
|
||||||
|
#ifdef LOCALHACK
|
||||||
|
/* I haven't quite come up with either a reason or a method for
|
||||||
|
* using the LOCALHACK with referer, so nothing for now.
|
||||||
|
*/
|
||||||
|
#endif /* LOCALHACK */
|
||||||
|
if(match_referer(sec[x].referer_allow[reqInfo->method][y],
|
||||||
|
reqInfo->inh_referer))
|
||||||
|
{
|
||||||
|
reqInfo->bSatisfiedReferer = TRUE;
|
||||||
|
return FA_ALLOW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Default is to deny */
|
||||||
|
return FA_DENY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find_referer_deny()
|
||||||
|
* Hunts down list of denied hosts and returns 0 if denied, 1 if not
|
||||||
|
* As soon as it finds a deny that matches, it returns 0
|
||||||
|
*/
|
||||||
|
int find_referer_deny(per_request *reqInfo, int x)
|
||||||
|
{
|
||||||
|
register int y;
|
||||||
|
|
||||||
|
/* If there aren't any denies, then it is allowed
|
||||||
|
*/
|
||||||
|
if(sec[x].num_referer_deny[reqInfo->method] == 0)
|
||||||
|
return FA_ALLOW;
|
||||||
|
|
||||||
|
for(y=0;y<sec[x].num_referer_deny[reqInfo->method];y++) {
|
||||||
|
if(!strcmp("all",sec[x].referer_deny[reqInfo->method][y]))
|
||||||
|
{
|
||||||
|
reqInfo->bSatisfiedReferer = FALSE;
|
||||||
|
return FA_DENY;
|
||||||
|
}
|
||||||
|
#ifdef LOCALHACK
|
||||||
|
/* I haven't quite come up with either a reason or a method for
|
||||||
|
* using the LOCALHACK with referer, so nothing for now.
|
||||||
|
*/
|
||||||
|
#endif /* LOCALHACK */
|
||||||
|
if(match_referer(sec[x].referer_deny[reqInfo->method][y],
|
||||||
|
reqInfo->inh_referer))
|
||||||
|
{
|
||||||
|
reqInfo->bSatisfiedReferer = FALSE;
|
||||||
|
return FA_DENY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Default is to allow */
|
||||||
|
reqInfo->bSatisfiedReferer = TRUE;
|
||||||
|
return FA_ALLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void check_dir_access(per_request *reqInfo,int x,
|
void check_dir_access(per_request *reqInfo,int x,
|
||||||
int *allow, int *allow_options)
|
int *allow, int *allow_options, int *other)
|
||||||
{
|
{
|
||||||
if(sec[x].auth_name[0])
|
if(sec[x].auth_name[0])
|
||||||
reqInfo->auth_name = sec[x].auth_name;
|
reqInfo->auth_name = sec[x].auth_name;
|
||||||
@ -215,32 +281,40 @@ void check_dir_access(per_request *reqInfo,int x,
|
|||||||
|
|
||||||
if(sec[x].order[reqInfo->method] == ALLOW_THEN_DENY) {
|
if(sec[x].order[reqInfo->method] == ALLOW_THEN_DENY) {
|
||||||
*allow=FA_DENY;
|
*allow=FA_DENY;
|
||||||
if (find_allow(reqInfo,x) == FA_ALLOW)
|
if ((find_host_allow(reqInfo,x) == FA_ALLOW) &&
|
||||||
|
(find_referer_allow(reqInfo,x) == FA_ALLOW))
|
||||||
*allow = FA_ALLOW;
|
*allow = FA_ALLOW;
|
||||||
if (find_deny(reqInfo,x) == FA_DENY)
|
if ((find_host_deny(reqInfo,x) == FA_DENY) ||
|
||||||
|
(find_referer_deny(reqInfo,x) == FA_DENY))
|
||||||
*allow = FA_DENY;
|
*allow = FA_DENY;
|
||||||
}
|
}
|
||||||
else if(sec[x].order[reqInfo->method] == DENY_THEN_ALLOW) {
|
else if(sec[x].order[reqInfo->method] == DENY_THEN_ALLOW) {
|
||||||
if (find_deny(reqInfo,x) == FA_DENY)
|
if ((find_host_deny(reqInfo,x) == FA_DENY) ||
|
||||||
|
(find_referer_deny(reqInfo,x) == FA_DENY))
|
||||||
*allow = FA_DENY;
|
*allow = FA_DENY;
|
||||||
if (find_allow(reqInfo,x) == FA_ALLOW)
|
if ((find_host_allow(reqInfo,x) == FA_ALLOW) &&
|
||||||
|
(find_referer_allow(reqInfo,x) == FA_ALLOW))
|
||||||
*allow = FA_ALLOW;
|
*allow = FA_ALLOW;
|
||||||
}
|
}
|
||||||
else { /* order == MUTUAL_FAILURE: allowed and not denied */
|
else { /* order == MUTUAL_FAILURE: allowed and not denied */
|
||||||
*allow = FA_DENY;
|
*allow = FA_DENY;
|
||||||
if ((find_allow(reqInfo,x) == FA_ALLOW) &&
|
if ((find_host_allow(reqInfo,x) == FA_ALLOW) &&
|
||||||
!(find_deny(reqInfo,x) == FA_DENY))
|
(find_referer_allow(reqInfo,x) == FA_ALLOW) &&
|
||||||
|
!(find_host_deny(reqInfo,x) == FA_DENY) &&
|
||||||
|
!(find_referer_deny(reqInfo,x) == FA_DENY))
|
||||||
*allow = FA_ALLOW;
|
*allow = FA_ALLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sec[x].num_auth[reqInfo->method])
|
if(sec[x].num_auth[reqInfo->method])
|
||||||
*allow_options=x;
|
*allow_options=x;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void evaluate_access(per_request *reqInfo,struct stat *finfo,int *allow,
|
void evaluate_access(per_request *reqInfo,struct stat *finfo,int *allow,
|
||||||
char *allow_options)
|
char *allow_options)
|
||||||
{
|
{
|
||||||
int will_allow, need_auth, num_dirs;
|
int will_allow, need_auth, num_dirs;
|
||||||
|
int need_enhance;
|
||||||
char opts[MAX_STRING_LEN], override[MAX_STRING_LEN];
|
char opts[MAX_STRING_LEN], override[MAX_STRING_LEN];
|
||||||
char path[MAX_STRING_LEN], d[MAX_STRING_LEN];
|
char path[MAX_STRING_LEN], d[MAX_STRING_LEN];
|
||||||
char errstr[MAX_STRING_LEN];
|
char errstr[MAX_STRING_LEN];
|
||||||
@ -255,9 +329,10 @@ void evaluate_access(per_request *reqInfo,struct stat *finfo,int *allow,
|
|||||||
num_dirs = count_dirs(path);
|
num_dirs = count_dirs(path);
|
||||||
will_allow = FA_ALLOW;
|
will_allow = FA_ALLOW;
|
||||||
need_auth = -1;
|
need_auth = -1;
|
||||||
|
need_enhance = -1;
|
||||||
|
|
||||||
user[0] = '\0';
|
reqInfo->auth_user[0] = '\0';
|
||||||
groupname[0] = '\0';
|
reqInfo->auth_group[0] = '\0';
|
||||||
reset_mime_vars();
|
reset_mime_vars();
|
||||||
|
|
||||||
for(x=0;x<num_dirs;x++) {
|
for(x=0;x<num_dirs;x++) {
|
||||||
@ -277,7 +352,7 @@ void evaluate_access(per_request *reqInfo,struct stat *finfo,int *allow,
|
|||||||
opts[y] = sec[x].opts;
|
opts[y] = sec[x].opts;
|
||||||
override[y] = sec[x].override;
|
override[y] = sec[x].override;
|
||||||
}
|
}
|
||||||
check_dir_access(reqInfo,x,&will_allow,&need_auth);
|
check_dir_access(reqInfo,x,&will_allow,&need_auth,&need_enhance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(!strncmp(path,sec[x].d,strlen(sec[x].d))) {
|
else if(!strncmp(path,sec[x].d,strlen(sec[x].d))) {
|
||||||
@ -286,7 +361,10 @@ void evaluate_access(per_request *reqInfo,struct stat *finfo,int *allow,
|
|||||||
opts[y] = sec[x].opts;
|
opts[y] = sec[x].opts;
|
||||||
override[y] = sec[x].override;
|
override[y] = sec[x].override;
|
||||||
}
|
}
|
||||||
check_dir_access(reqInfo,x,&will_allow,&need_auth);
|
check_dir_access(reqInfo,x,&will_allow,&need_auth,&need_enhance);
|
||||||
|
}
|
||||||
|
if (!will_allow && sec[x].on_deny[reqInfo->method]) {
|
||||||
|
strcpy(reqInfo->outh_location,sec[x].on_deny[reqInfo->method]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if((override[n]) || (!(opts[n] & OPT_SYM_LINKS)) ||
|
if((override[n]) || (!(opts[n] & OPT_SYM_LINKS)) ||
|
||||||
@ -299,7 +377,7 @@ void evaluate_access(per_request *reqInfo,struct stat *finfo,int *allow,
|
|||||||
|
|
||||||
if(lstat(d,&lfi) != 0)
|
if(lstat(d,&lfi) != 0)
|
||||||
{
|
{
|
||||||
sprintf(errstr,"httpd: can't lstat %s, errno = %d",d, errno);
|
sprintf(errstr,"HTTPd: can't lstat %s, errno = %d",d, errno);
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
*allow=FA_DENY;
|
*allow=FA_DENY;
|
||||||
*allow_options = OPT_NONE;
|
*allow_options = OPT_NONE;
|
||||||
@ -309,7 +387,7 @@ void evaluate_access(per_request *reqInfo,struct stat *finfo,int *allow,
|
|||||||
if(opts[x] & OPT_SYM_OWNER) {
|
if(opts[x] & OPT_SYM_OWNER) {
|
||||||
if(stat(d,&fi) != 0)
|
if(stat(d,&fi) != 0)
|
||||||
{
|
{
|
||||||
sprintf(errstr,"httpd: can't stat %s, errno = %d",d, errno);
|
sprintf(errstr,"HTTPd: can't stat %s, errno = %d",d, errno);
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
*allow=FA_DENY;
|
*allow=FA_DENY;
|
||||||
*allow_options = OPT_NONE;
|
*allow_options = OPT_NONE;
|
||||||
@ -320,7 +398,7 @@ void evaluate_access(per_request *reqInfo,struct stat *finfo,int *allow,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bong:
|
bong:
|
||||||
sprintf(errstr,"httpd: will not follow link %s",d);
|
sprintf(errstr,"HTTPd: will not follow link %s",d);
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
*allow=FA_DENY;
|
*allow=FA_DENY;
|
||||||
*allow_options = OPT_NONE;
|
*allow_options = OPT_NONE;
|
||||||
@ -338,8 +416,14 @@ void evaluate_access(per_request *reqInfo,struct stat *finfo,int *allow,
|
|||||||
}
|
}
|
||||||
if ((sec[y].num_auth[reqInfo->method] > 0) ||
|
if ((sec[y].num_auth[reqInfo->method] > 0) ||
|
||||||
(sec[y].num_allow[reqInfo->method] > 0) ||
|
(sec[y].num_allow[reqInfo->method] > 0) ||
|
||||||
(sec[y].num_deny[reqInfo->method] > 0))
|
(sec[y].num_deny[reqInfo->method] > 0) ||
|
||||||
check_dir_access(reqInfo,y,&will_allow,&need_auth);
|
(sec[y].num_referer_allow[reqInfo->method] > 0) ||
|
||||||
|
(sec[y].num_referer_deny[reqInfo->method] > 0))
|
||||||
|
check_dir_access(reqInfo,y,&will_allow,&need_auth,&need_enhance);
|
||||||
|
if (!will_allow && sec[y].on_deny[reqInfo->method]) {
|
||||||
|
strcpy(reqInfo->outh_location,
|
||||||
|
sec[y].on_deny[reqInfo->method]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -349,7 +433,7 @@ void evaluate_access(per_request *reqInfo,struct stat *finfo,int *allow,
|
|||||||
struct stat fi,lfi;
|
struct stat fi,lfi;
|
||||||
if(lstat(path,&fi)!=0)
|
if(lstat(path,&fi)!=0)
|
||||||
{
|
{
|
||||||
sprintf(errstr,"httpd: can't lstat %s, errno = %d",path, errno);
|
sprintf(errstr,"HTTPd: can't lstat %s, errno = %d",path, errno);
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
*allow=FA_DENY;
|
*allow=FA_DENY;
|
||||||
*allow_options = OPT_NONE;
|
*allow_options = OPT_NONE;
|
||||||
@ -359,7 +443,7 @@ void evaluate_access(per_request *reqInfo,struct stat *finfo,int *allow,
|
|||||||
if(opts[n] & OPT_SYM_OWNER) {
|
if(opts[n] & OPT_SYM_OWNER) {
|
||||||
if(stat(path,&lfi)!=0)
|
if(stat(path,&lfi)!=0)
|
||||||
{
|
{
|
||||||
sprintf(errstr,"httpd: can't stat %s, errno = %d",path, errno);
|
sprintf(errstr,"HTTPd: can't stat %s, errno = %d",path, errno);
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
*allow=FA_DENY;
|
*allow=FA_DENY;
|
||||||
*allow_options = OPT_NONE;
|
*allow_options = OPT_NONE;
|
||||||
@ -370,7 +454,7 @@ void evaluate_access(per_request *reqInfo,struct stat *finfo,int *allow,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gong:
|
gong:
|
||||||
sprintf(errstr,"httpd: will not follow link %s",path);
|
sprintf(errstr,"HTTPd: will not follow link %s",path);
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
*allow=FA_DENY;
|
*allow=FA_DENY;
|
||||||
*allow_options = OPT_NONE;
|
*allow_options = OPT_NONE;
|
||||||
@ -381,12 +465,12 @@ void evaluate_access(per_request *reqInfo,struct stat *finfo,int *allow,
|
|||||||
*allow = will_allow;
|
*allow = will_allow;
|
||||||
if(will_allow) {
|
if(will_allow) {
|
||||||
*allow_options = opts[num_dirs-1];
|
*allow_options = opts[num_dirs-1];
|
||||||
if ((need_auth >= 0) && !sec[need_auth].bSatisfy) {
|
if ((need_auth >= 0) && (sec[need_auth].bSatisfy == SATISFY_ALL)) {
|
||||||
reqInfo->bSatisfiedDomain = 0;
|
reqInfo->bSatisfiedDomain = 0;
|
||||||
check_auth(reqInfo,&sec[need_auth], auth_line);
|
check_auth(reqInfo,&sec[need_auth], reqInfo->inh_auth_line);
|
||||||
}
|
}
|
||||||
} else if (need_auth >= 0 && sec[need_auth].bSatisfy) {
|
} else if ((need_auth >= 0) && (sec[need_auth].bSatisfy == SATISFY_ANY)) {
|
||||||
check_auth(reqInfo,&sec[need_auth], auth_line);
|
check_auth(reqInfo,&sec[need_auth], reqInfo->inh_auth_line);
|
||||||
*allow_options = opts[num_dirs-1];
|
*allow_options = opts[num_dirs-1];
|
||||||
*allow = FA_ALLOW;
|
*allow = FA_ALLOW;
|
||||||
}
|
}
|
||||||
@ -406,6 +490,11 @@ void kill_security(void)
|
|||||||
free(sec[x].deny[m][y]);
|
free(sec[x].deny[m][y]);
|
||||||
for(y=0;y<sec[x].num_auth[m];y++)
|
for(y=0;y<sec[x].num_auth[m];y++)
|
||||||
free(sec[x].auth[m][y]);
|
free(sec[x].auth[m][y]);
|
||||||
|
for(y=0;y<sec[x].num_referer_allow[m];y++)
|
||||||
|
free(sec[x].referer_allow[m][y]);
|
||||||
|
for(y=0;y<sec[x].num_referer_deny[m];y++)
|
||||||
|
free(sec[x].referer_deny[m][y]);
|
||||||
|
free(sec[x].on_deny[m]);
|
||||||
}
|
}
|
||||||
/* if(sec[x].auth_type)
|
/* if(sec[x].auth_type)
|
||||||
free(sec[x].auth_type);
|
free(sec[x].auth_type);
|
||||||
@ -440,6 +529,11 @@ void reset_security(void)
|
|||||||
free(sec[x].deny[m][y]);
|
free(sec[x].deny[m][y]);
|
||||||
for(y=0;y<sec[x].num_auth[m];y++)
|
for(y=0;y<sec[x].num_auth[m];y++)
|
||||||
free(sec[x].auth[m][y]);
|
free(sec[x].auth[m][y]);
|
||||||
|
for(y=0;y<sec[x].num_referer_allow[m];y++)
|
||||||
|
free(sec[x].referer_allow[m][y]);
|
||||||
|
for(y=0;y<sec[x].num_referer_deny[m];y++)
|
||||||
|
free(sec[x].referer_deny[m][y]);
|
||||||
|
if (sec[x].on_deny[m]) free(sec[x].on_deny[m]);
|
||||||
}
|
}
|
||||||
/* if(sec[x].auth_type)
|
/* if(sec[x].auth_type)
|
||||||
free(sec[x].auth_type);
|
free(sec[x].auth_type);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* http_access.h,v 1.11 1995/11/28 09:01:50 blong Exp
|
* http_access.h,v 1.12 1996/02/22 23:46:41 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
@ -25,11 +25,6 @@
|
|||||||
#define FA_DENY 0
|
#define FA_DENY 0
|
||||||
#define FA_ALLOW 1
|
#define FA_ALLOW 1
|
||||||
|
|
||||||
#ifdef DIGEST_AUTH
|
|
||||||
extern int client_accepts_digest;
|
|
||||||
extern int assume_digest_support;
|
|
||||||
#endif /* DIGEST_AUTH */
|
|
||||||
|
|
||||||
/* http_access function prototypes */
|
/* http_access function prototypes */
|
||||||
void evaluate_access(per_request *reqInfo, struct stat *finfo,int *allow,
|
void evaluate_access(per_request *reqInfo, struct stat *finfo,int *allow,
|
||||||
char *op);
|
char *op);
|
||||||
|
@ -12,21 +12,6 @@
|
|||||||
*
|
*
|
||||||
* http_alias.c: Stuff for dealing with directory aliases
|
* http_alias.c: Stuff for dealing with directory aliases
|
||||||
*
|
*
|
||||||
* Based on NCSA HTTPd 1.3 by Rob McCool
|
|
||||||
*
|
|
||||||
* 04-06-95 blong
|
|
||||||
* Added Saved_ variables to allow reset of aliases to configured
|
|
||||||
* only. save_aliases is called from http_config, and
|
|
||||||
* reset_to_saved_alias is called in the initialization of
|
|
||||||
* transactions.
|
|
||||||
*
|
|
||||||
* 06-30-95 blong
|
|
||||||
* removed saved stuff, since we now don't have to add user directories
|
|
||||||
* to the aliases, and so they never change after startup
|
|
||||||
*
|
|
||||||
* 07-27-95 blong
|
|
||||||
* log access to unknown users directory as suggested by
|
|
||||||
* Gioacchino La Vecchia (gio@di.unipi.it)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -43,17 +28,9 @@
|
|||||||
#include "http_alias.h"
|
#include "http_alias.h"
|
||||||
#include "http_config.h"
|
#include "http_config.h"
|
||||||
#include "http_log.h"
|
#include "http_log.h"
|
||||||
|
#include "http_request.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
/*
|
|
||||||
static int Saved_num_alias = 0;
|
|
||||||
static int num_aliases = 0;
|
|
||||||
static alias aliases[MAX_ALIASES];
|
|
||||||
static int Saved_num_redirect = 0;
|
|
||||||
static int num_redirect = 0;
|
|
||||||
static alias redirect[MAX_ALIASES];
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* To send stat() information to cgi.c */
|
/* To send stat() information to cgi.c */
|
||||||
int dirs_in_alias;
|
int dirs_in_alias;
|
||||||
|
|
||||||
|
352
src/http_auth.c
352
src/http_auth.c
@ -12,8 +12,6 @@
|
|||||||
*
|
*
|
||||||
* http_auth: authentication
|
* http_auth: authentication
|
||||||
*
|
*
|
||||||
* Based on NCSA HTTPd 1.3 by Rob McCool
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -35,17 +33,17 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <termios.h>
|
||||||
#ifdef DBM_SUPPORT
|
#ifdef DBM_SUPPORT
|
||||||
# ifndef _DBMSUPPORT_H /* moronic OSs which don't protect their own include */
|
# ifndef _DBMSUPPORT_H /* moronic OSs which don't protect their own include */
|
||||||
# define _DBMSUPPORT_H /* files from being multiply included */
|
# define _DBMSUPPORT_H /* files from being multiply included */
|
||||||
# include <ndbm.h>
|
# include <ndbm.h>
|
||||||
# endif /* _DBMSUPPORT_H */
|
# endif /* _DBMSUPPORT_H */
|
||||||
#endif /* DBM_SUPPORT */
|
#endif /* DBM_SUPPORT */
|
||||||
|
|
||||||
#ifdef NIS_SUPPORT
|
#ifdef NIS_SUPPORT
|
||||||
#include <rpcsvc/ypclnt.h>
|
# include <rpcsvc/ypclnt.h>
|
||||||
#endif /* NIS_SUPPORT */
|
#endif /* NIS_SUPPORT */
|
||||||
|
|
||||||
#if defined(KRB4) || defined(KRB5)
|
#if defined(KRB4) || defined(KRB5)
|
||||||
# define HAVE_KERBEROS
|
# define HAVE_KERBEROS
|
||||||
#endif /* defined(KRB4) || defined(KRB5) */
|
#endif /* defined(KRB4) || defined(KRB5) */
|
||||||
@ -55,29 +53,25 @@
|
|||||||
#ifdef KRB5
|
#ifdef KRB5
|
||||||
# include <krb5.h>
|
# include <krb5.h>
|
||||||
#endif /* KRB5 */
|
#endif /* KRB5 */
|
||||||
|
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "fdwrap.h"
|
#include "fdwrap.h"
|
||||||
|
#include "allocate.h"
|
||||||
#include "http_auth.h"
|
#include "http_auth.h"
|
||||||
#include "http_access.h"
|
#include "http_access.h"
|
||||||
#include "http_mime.h"
|
#include "http_mime.h"
|
||||||
#include "http_config.h"
|
#include "http_config.h"
|
||||||
#include "http_log.h"
|
#include "http_log.h"
|
||||||
|
#include "http_request.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "digest.h"
|
#include "digest.h"
|
||||||
|
|
||||||
|
|
||||||
char user[MAX_STRING_LEN];
|
|
||||||
char groupname[MAX_STRING_LEN];
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_KERBEROS
|
#ifdef HAVE_KERBEROS
|
||||||
#define T 1
|
#define T 1
|
||||||
#define NIL 0
|
#define NIL 0
|
||||||
char* index();
|
char* index();
|
||||||
char krb_authreply[2048];
|
char krb_authreply[2048];
|
||||||
extern char *remote_logname;
|
extern char *remote_logname;
|
||||||
extern char out_auth_header[];
|
/* extern char out_auth_header[]; */
|
||||||
|
|
||||||
/* Table for converting binary values to and from hexadecimal */
|
/* Table for converting binary values to and from hexadecimal */
|
||||||
static char hex[] = "0123456789abcdef";
|
static char hex[] = "0123456789abcdef";
|
||||||
@ -108,6 +102,12 @@ AUTH_DAT kerb_kdata;
|
|||||||
char k5_srvtab[MAX_STRING_LEN] = "";
|
char k5_srvtab[MAX_STRING_LEN] = "";
|
||||||
#endif /* KRB5 */
|
#endif /* KRB5 */
|
||||||
|
|
||||||
|
#ifdef RADIUS_AUTH
|
||||||
|
/* Experimental RADIUS authentication
|
||||||
|
*/
|
||||||
|
int testpass (char * user, char * clear_pw, char * servername);
|
||||||
|
#endif /* RADIUS_AUTH */
|
||||||
|
|
||||||
#ifdef NIS_SUPPORT
|
#ifdef NIS_SUPPORT
|
||||||
int
|
int
|
||||||
init_nis(char **dom)
|
init_nis(char **dom)
|
||||||
@ -220,117 +220,220 @@ int get_pw(per_request *reqInfo, char *user, char *pw, security_data* sec)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int in_group(per_request *reqInfo, char *user,
|
/* in_list()
|
||||||
char *group, char* pchGrps
|
* Search a comma or space delimited list for a user
|
||||||
#ifdef DBM_SUPPORT
|
* return 0 if not found, 1 if found
|
||||||
, DBM* db
|
|
||||||
#endif /* DBM_SUPPORT */
|
|
||||||
) {
|
|
||||||
char *mems = NULL, *endp = NULL;
|
|
||||||
char *pch;
|
|
||||||
char chSaved = '\0';
|
|
||||||
int nlen, bFound = 0;
|
|
||||||
char l[MAX_STRING_LEN];
|
|
||||||
int x,start;
|
|
||||||
|
|
||||||
if (reqInfo->auth_grpfile_type == AUTHFILETYPE_STANDARD) {
|
|
||||||
nlen = strlen (group);
|
|
||||||
if ((mems = strstr (pchGrps, group)) && *(mems + nlen) == ':') {
|
|
||||||
if ((endp = strchr (mems + nlen + 1, ':'))) {
|
|
||||||
while (!isspace(*endp)) endp--;
|
|
||||||
chSaved = *endp;
|
|
||||||
*endp = '\0';
|
|
||||||
}
|
|
||||||
/* BUG FIX: Couldn't have the same name as the group as a user because
|
|
||||||
* failed to move the string beyond the group:
|
|
||||||
*/
|
*/
|
||||||
mems = mems + nlen;
|
int in_list(char *user, char *list)
|
||||||
}
|
{
|
||||||
else
|
int x = 0;
|
||||||
return 0;
|
int start = 0;
|
||||||
|
int Found = 0;
|
||||||
|
|
||||||
|
while(isspace(list[x]) || (list[x] == ','))
|
||||||
|
x++;
|
||||||
|
start = x;
|
||||||
|
while (!Found && (list[x] != '\0')) {
|
||||||
|
if ((isspace(list[x]) || (list[x] == ','))) {
|
||||||
|
Found = !strncmp(user,(list+start),x-start);
|
||||||
|
start = x+1;
|
||||||
|
}
|
||||||
|
x++;
|
||||||
}
|
}
|
||||||
#ifdef DBM_SUPPORT
|
if (!Found && list[x] == '\0' && (x-start > 0)) {
|
||||||
else if (reqInfo->auth_grpfile_type == AUTHFILETYPE_DBM) {
|
Found = !strncmp(user,(list+start),x-start);
|
||||||
datum dtKey, dtRec;
|
}
|
||||||
|
|
||||||
|
return Found;
|
||||||
|
}
|
||||||
|
|
||||||
dtKey.dptr = group;
|
/* in_listn()
|
||||||
dtKey.dsize = strlen(group);
|
* Search a comma or space delimited list for a user
|
||||||
dtRec = dbm_fetch(db, dtKey);
|
* Group list doesn't need to be NULL terminated (for DBM format)
|
||||||
if (dtRec.dptr) {
|
* return 0 if not found, 1 if found
|
||||||
strncpy(l, dtRec.dptr, dtRec.dsize);
|
*/
|
||||||
l[dtRec.dsize] = '\0';
|
int in_listn(char *user, char *list, int len)
|
||||||
mems = l;
|
{
|
||||||
}
|
int x = 0;
|
||||||
else
|
int start = 0;
|
||||||
return 0;
|
int Found = 0;
|
||||||
|
|
||||||
|
while(isspace(list[x]) || (list[x] == ','))
|
||||||
|
x++;
|
||||||
|
start = x;
|
||||||
|
while (!Found && (list[x] != '\0') && (x < len)) {
|
||||||
|
if ((isspace(list[x]) || (list[x] == ','))) {
|
||||||
|
Found = !strncmp(user,(list+start),x-start);
|
||||||
|
start = x+1;
|
||||||
|
}
|
||||||
|
x++;
|
||||||
}
|
}
|
||||||
#endif /* DBM_SUPPORT */
|
if (!Found && ((list[x] == '\0') || (x == len)) && (x-start > 0)) {
|
||||||
|
Found = !strncmp(user,(list+start),x-start);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Found;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* nis_group_lookup()
|
||||||
|
* Validate a user in an NIS group. Retrieves the group from an NIS database.
|
||||||
|
* (Default group file is webgroup)
|
||||||
|
* return 0 on failure, 1 on success
|
||||||
|
*/
|
||||||
#ifdef NIS_SUPPORT
|
#ifdef NIS_SUPPORT
|
||||||
else if (reqInfo->auth_pwfile_type == AUTHFILETYPE_NIS) {
|
int nis_group_lookup(per_request *reqInfo, char *user, char *group)
|
||||||
|
{
|
||||||
char *domain,
|
char *domain,
|
||||||
*grfile,
|
*grfile,
|
||||||
*resptr,
|
*resptr,
|
||||||
w[MAX_STRING_LEN];
|
w[MAX_STRING_LEN];
|
||||||
int yperr,
|
int yperr,
|
||||||
resize;
|
resize;
|
||||||
|
|
||||||
if (init_nis(&domain) != 0)
|
if (init_nis(&domain) != 0) {
|
||||||
return 0;
|
log_error("HTTPd/NIS: init_nis() failed",reqInfo->hostInfo->error_log);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (strcmp(reqInfo->auth_grpfile, "+"))
|
if (strcmp(reqInfo->auth_grpfile, "+"))
|
||||||
grfile = reqInfo->auth_grpfile;
|
grfile = reqInfo->auth_grpfile;
|
||||||
else
|
else
|
||||||
grfile = "webgroup";
|
grfile = "webgroup";
|
||||||
|
|
||||||
yperr = yp_match(domain, grfile, group, strlen(group), &resptr, &resize);
|
yperr = yp_match(domain, grfile, group, strlen(group), &resptr, &resize);
|
||||||
if (yperr != 0)
|
if (yperr != 0) {
|
||||||
return 0;
|
sprintf(w,"HTTPd/NIS: yp_match() failed, yperr = %d\n",yperr);
|
||||||
|
log_error(w,reqInfo->hostInfo->error_log);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
getword(w, resptr, ':');
|
getword(w, resptr, ':');
|
||||||
if (strcmp(w, group) != 0)
|
if (strcmp(w, group) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
while (*resptr && isspace(*resptr))
|
|
||||||
resptr++;
|
|
||||||
(void) strcpy(l, resptr);
|
|
||||||
mems = l;
|
|
||||||
}
|
|
||||||
#endif /* NIS_SUPPORT */
|
|
||||||
else {
|
|
||||||
die(reqInfo,SC_SERVER_ERROR,"Invalid group file type");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Actually search the group line for the user. Can be comma or space
|
|
||||||
* delimited
|
|
||||||
*/
|
|
||||||
x = 0;
|
|
||||||
start = 0;
|
|
||||||
pch = mems;
|
|
||||||
while (!bFound && (pch[x] != '\0')) {
|
|
||||||
if ((isspace(pch[x])) || (pch[x] == ',')) {
|
|
||||||
bFound = !strncmp(user,(pch+start),x-start);
|
|
||||||
start = x+1;
|
|
||||||
}
|
|
||||||
x++;
|
|
||||||
}
|
|
||||||
if (!bFound && pch[x] == '\0' && (x-start > 0)) {
|
|
||||||
bFound = !strncmp(user,(pch+start),x-start);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return in_list(user,resptr);
|
||||||
|
}
|
||||||
|
#endif /* NIS_SUPPORT */
|
||||||
|
|
||||||
/* Buggy, and obfuscated. */
|
/* dbm_group_lookup()
|
||||||
/* nlen = strlen (user);
|
* Implicitly requires group line not to exceed HUGE_STRING_LEN because
|
||||||
nlen = strlen (user);
|
* groups aren't stored with trailing 0.
|
||||||
pch = mems;
|
* Searches open DBM database (db) for keypair with the group name as key
|
||||||
while (!bFound && (pch = strstr(pch, user)) &&
|
* and returns 0 if user or group not found, 1 if user is in group
|
||||||
(!*(pch + nlen) || isspace (*(pch + nlen)) || *(pch + nlen) == ','))
|
*/
|
||||||
bFound = 1;
|
#ifdef DBM_SUPPORT
|
||||||
*/
|
int dbm_group_lookup(per_request *reqInfo, char *user, char *group, DBM *db)
|
||||||
if (endp && *endp == '\0') *endp = chSaved;
|
{
|
||||||
return bFound;
|
datum dtKey, dtRec;
|
||||||
|
int Found = 0;
|
||||||
|
|
||||||
|
dtKey.dptr = group;
|
||||||
|
dtKey.dsize = strlen(group);
|
||||||
|
dtRec = dbm_fetch(db, dtKey);
|
||||||
|
if (dtRec.dptr) {
|
||||||
|
Found = in_listn(user,dtRec.dptr,dtRec.dsize);
|
||||||
|
}
|
||||||
|
return Found;
|
||||||
|
}
|
||||||
|
#endif /* DBM_SUPPORT */
|
||||||
|
|
||||||
|
int mind(char *S, char *possible)
|
||||||
|
{
|
||||||
|
int x,y;
|
||||||
|
for (x = 0; S[x]; x++)
|
||||||
|
for (y = 0; possible[y]; y++)
|
||||||
|
if (S[x] == possible[y]) return x;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int eoln(char *S)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
for (x = 0; S[x]; x++)
|
||||||
|
if (S[x] == '\n') return x;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
int in_group(per_request *reqInfo, char *user,
|
||||||
|
char *group, char* gfile_mem
|
||||||
|
#ifdef DBM_SUPPORT
|
||||||
|
, DBM* db
|
||||||
|
#endif /* DBM_SUPPORT */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int bFound = FALSE;
|
||||||
|
int Done = FALSE;
|
||||||
|
|
||||||
|
if (reqInfo->auth_grpfile_type == AUTHFILETYPE_STANDARD) {
|
||||||
|
/*
|
||||||
|
char *cur_group = NULL;
|
||||||
|
char *cur_list = NULL;
|
||||||
|
cur_group = strtok(gfile_mem,":");
|
||||||
|
while (!Done && !bFound) {
|
||||||
|
cur_list = strtok(NULL,"\n");
|
||||||
|
if (!strcmp(group,cur_group)) {
|
||||||
|
bFound = in_list(user,cur_list);
|
||||||
|
}
|
||||||
|
cur_group = strtok(NULL,":");
|
||||||
|
if (cur_group == NULL) Done = TRUE;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
int beg_line = 0;
|
||||||
|
int end_line = 0;
|
||||||
|
int end_grp = 0;
|
||||||
|
int len = strlen(group);
|
||||||
|
while (!Done && !bFound) {
|
||||||
|
end_grp = ind(&gfile_mem[beg_line],':');
|
||||||
|
if (end_grp != -1) {
|
||||||
|
end_line = ind(&gfile_mem[beg_line],'\n');
|
||||||
|
if (end_line < 0) {
|
||||||
|
end_line = strlen(&gfile_mem[beg_line]);
|
||||||
|
Done = TRUE;
|
||||||
|
}
|
||||||
|
if (end_line > end_grp) {
|
||||||
|
if ((end_grp == len) &&
|
||||||
|
(!strncmp(&gfile_mem[beg_line],group,len)))
|
||||||
|
{
|
||||||
|
bFound = in_listn(user,&gfile_mem[beg_line+end_grp+1],end_line - end_grp);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* hmm, how to handle the backward compat with the bug in 1.5 which
|
||||||
|
* allowed a group to span multiple lines
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
beg_line += end_line+1;
|
||||||
|
} else Done = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef DBM_SUPPORT
|
||||||
|
else if (reqInfo->auth_grpfile_type == AUTHFILETYPE_DBM) {
|
||||||
|
bFound = dbm_group_lookup(reqInfo,user,group,db);
|
||||||
|
}
|
||||||
|
#endif /* DBM_SUPPORT */
|
||||||
|
#ifdef NIS_SUPPORT
|
||||||
|
else if (reqInfo->auth_grpfile_type == AUTHFILETYPE_NIS) {
|
||||||
|
bFound = nis_group_lookup(reqInfo,user,group);
|
||||||
|
}
|
||||||
|
#endif /* NIS_SUPPORT */
|
||||||
|
else {
|
||||||
|
die(reqInfo,SC_SERVER_ERROR,"Invalid group file type");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
int fputsn(FILE *fp,char *S,int num) {
|
||||||
|
int x;
|
||||||
|
for(x = 0 ; x < num ; x++)
|
||||||
|
fprintf(fp,"%c",S[x]);
|
||||||
|
}
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
/* init_group(): loads an entire group file into memory for parsing.
|
||||||
|
* and returns a pointer to it.
|
||||||
|
*/
|
||||||
char* init_group(per_request *reqInfo,char* grpfile)
|
char* init_group(per_request *reqInfo,char* grpfile)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
@ -422,54 +525,64 @@ void check_auth(per_request *reqInfo, security_data *sec, char* auth_line)
|
|||||||
KerberosInfo kdat;
|
KerberosInfo kdat;
|
||||||
#endif /* HAVE_KERBEROS */
|
#endif /* HAVE_KERBEROS */
|
||||||
|
|
||||||
|
/* Default to Auth Type Basic */
|
||||||
|
|
||||||
if(!sec->auth_type[0])
|
if(!sec->auth_type[0])
|
||||||
strcpy(sec->auth_type, "Basic");
|
strcpy(sec->auth_type, "Basic");
|
||||||
|
|
||||||
|
|
||||||
|
/* No authorization info, so return the 401 to retrieve it */
|
||||||
if(!auth_line[0])
|
if(!auth_line[0])
|
||||||
auth_bong(reqInfo,NULL, reqInfo->auth_name, sec->auth_type);
|
auth_bong(reqInfo,NULL, reqInfo->auth_name, sec->auth_type);
|
||||||
|
|
||||||
for (x=0 ; auth_line[x] && (auth_line[x] != ' ') && x < MAX_STRING_LEN; x++)
|
for (x=0 ; auth_line[x] && (auth_line[x] != ' ') && x < MAX_STRING_LEN; x++)
|
||||||
auth_type[x] = auth_line[x];
|
auth_type[x] = auth_line[x];
|
||||||
auth_type[x++] = '\0';
|
auth_type[x++] = '\0';
|
||||||
|
|
||||||
|
|
||||||
|
/* The authorization in the auth line is not the same which protects this
|
||||||
|
* directory.
|
||||||
|
*/
|
||||||
if (strcmp(auth_type, sec->auth_type))
|
if (strcmp(auth_type, sec->auth_type))
|
||||||
auth_bong(reqInfo,"type mismatch",reqInfo->auth_name,sec->auth_type);
|
auth_bong(reqInfo,"type mismatch",reqInfo->auth_name,sec->auth_type);
|
||||||
|
|
||||||
|
/* Basic Authentication */
|
||||||
if(!strcasecmp(sec->auth_type,"Basic")) {
|
if(!strcasecmp(sec->auth_type,"Basic")) {
|
||||||
if(!reqInfo->auth_name) {
|
if(!reqInfo->auth_name) {
|
||||||
sprintf(errstr,"httpd: need AuthName for %s",sec->d);
|
sprintf(errstr,"HTTPd: need AuthName for %s",sec->d);
|
||||||
die(reqInfo,SC_SERVER_ERROR,errstr);
|
die(reqInfo,SC_SERVER_ERROR,errstr);
|
||||||
}
|
}
|
||||||
if(!reqInfo->auth_pwfile) {
|
if(!reqInfo->auth_pwfile) {
|
||||||
sprintf(errstr,"httpd: need AuthUserFile for %s",sec->d);
|
sprintf(errstr,"HTTPd: need AuthUserFile for %s",sec->d);
|
||||||
die(reqInfo,SC_SERVER_ERROR,errstr);
|
die(reqInfo,SC_SERVER_ERROR,errstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
uudecode(auth_line + strlen(auth_type),(unsigned char *)ad,MAX_STRING_LEN);
|
uudecode(auth_line + strlen(auth_type),(unsigned char *)ad,MAX_STRING_LEN);
|
||||||
getword(user,ad,':');
|
getword(reqInfo->auth_user,ad,':');
|
||||||
strcpy(sent_pw,ad);
|
strcpy(sent_pw,ad);
|
||||||
if(!get_pw(reqInfo,user,real_pw,sec)) {
|
if(!get_pw(reqInfo,reqInfo->auth_user,real_pw,sec)) {
|
||||||
sprintf(errstr,"user %s not found",user);
|
sprintf(errstr,"user %s not found",reqInfo->auth_user);
|
||||||
auth_bong(reqInfo,errstr,reqInfo->auth_name,sec->auth_type);
|
auth_bong(reqInfo,errstr,reqInfo->auth_name,sec->auth_type);
|
||||||
}
|
}
|
||||||
/* anyone know where the prototype for crypt is? */
|
/* anyone know where the prototype for crypt is? */
|
||||||
/* Yeah, in unistd.h on most systems, it seems */
|
/* Yeah, in unistd.h on most systems, it seems */
|
||||||
if(strcmp(real_pw,(char *)crypt(sent_pw,real_pw))) {
|
if(strcmp(real_pw,(char *)crypt(sent_pw,real_pw))) {
|
||||||
sprintf(errstr,"user %s: password mismatch",user);
|
sprintf(errstr,"user %s: password mismatch",reqInfo->auth_user);
|
||||||
auth_bong(reqInfo,errstr,reqInfo->auth_name,sec->auth_type);
|
auth_bong(reqInfo,errstr,reqInfo->auth_name,sec->auth_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* End Basic Authentication */
|
||||||
#ifdef DIGEST_AUTH
|
#ifdef DIGEST_AUTH
|
||||||
else if(!strcasecmp(sec->auth_type,"Digest")) {
|
else if(!strcasecmp(sec->auth_type,"Digest")) {
|
||||||
if(!reqInfo->auth_name) {
|
if(!reqInfo->auth_name) {
|
||||||
sprintf(errstr,"httpd: need AuthName for %s",sec->d);
|
sprintf(errstr,"HTTPd: need AuthName for %s",sec->d);
|
||||||
die(reqInfo,SC_SERVER_ERROR,errstr);
|
die(reqInfo,SC_SERVER_ERROR,errstr);
|
||||||
}
|
}
|
||||||
if(!sec->auth_digestfile) {
|
if(!sec->auth_digestfile) {
|
||||||
sprintf(errstr,"httpd: need AuthDigestFile for %s",sec->d);
|
sprintf(errstr,"HTTPd: need AuthDigestFile for %s",sec->d);
|
||||||
die(reqInfo,SC_SERVER_ERROR,errstr);
|
die(reqInfo,SC_SERVER_ERROR,errstr);
|
||||||
}
|
}
|
||||||
Digest_Check(reqInfo,user, sec);
|
Digest_Check(reqInfo,reqInfo->auth_user, sec);
|
||||||
}
|
}
|
||||||
#endif /* DIGEST_AUTH */
|
#endif /* DIGEST_AUTH */
|
||||||
#ifdef HAVE_KERBEROS
|
#ifdef HAVE_KERBEROS
|
||||||
@ -501,9 +614,8 @@ void check_auth(per_request *reqInfo, security_data *sec, char* auth_line)
|
|||||||
|
|
||||||
if (krbresult) {
|
if (krbresult) {
|
||||||
if (check_krb_restrict(reqInfo, sec, &kdat)) {
|
if (check_krb_restrict(reqInfo, sec, &kdat)) {
|
||||||
remote_logname = user;
|
remote_logname = reqInfo->auth_user;
|
||||||
out_auth_header[0] = '\0';
|
sprintf(reqInfo->outh_www_auth,"%s %s",
|
||||||
sprintf(out_auth_header, "WWW-Authenticate: %s %s\r\n",
|
|
||||||
sec->auth_type, krb_authreply);
|
sec->auth_type, krb_authreply);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -557,7 +669,7 @@ void check_auth(per_request *reqInfo, security_data *sec, char* auth_line)
|
|||||||
t[y] = t[y+1];
|
t[y] = t[y+1];
|
||||||
}
|
}
|
||||||
getword(w,t,' ');
|
getword(w,t,' ');
|
||||||
if(!strcmp(user,w)) {
|
if(!strcmp(reqInfo->auth_user,w)) {
|
||||||
bValid = 1;
|
bValid = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -572,11 +684,11 @@ void check_auth(per_request *reqInfo, security_data *sec, char* auth_line)
|
|||||||
while (t[0]) {
|
while (t[0]) {
|
||||||
getword(w,t,' ');
|
getword(w,t,' ');
|
||||||
#ifdef DBM_SUPPORT
|
#ifdef DBM_SUPPORT
|
||||||
if (in_group(reqInfo,user,w, pchGrpData, db)) {
|
if (in_group(reqInfo,reqInfo->auth_user,w, pchGrpData, db)) {
|
||||||
#else
|
#else
|
||||||
if (in_group(reqInfo,user,w, pchGrpData)) {
|
if (in_group(reqInfo,reqInfo->auth_user,w, pchGrpData)) {
|
||||||
#endif /* DBM_SUPPORT */
|
#endif /* DBM_SUPPORT */
|
||||||
strcpy(groupname,w);
|
strcpy(reqInfo->auth_group,w);
|
||||||
bValid = 1;
|
bValid = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -597,12 +709,11 @@ void check_auth(per_request *reqInfo, security_data *sec, char* auth_line)
|
|||||||
}
|
}
|
||||||
/* if we didn't validate the user */
|
/* if we didn't validate the user */
|
||||||
if (!bValid) {
|
if (!bValid) {
|
||||||
sprintf(errstr,"user %s denied",user);
|
sprintf(errstr,"user %s denied",reqInfo->auth_user);
|
||||||
auth_bong(reqInfo,errstr,reqInfo->auth_name,sec->auth_type);
|
auth_bong(reqInfo,errstr,reqInfo->auth_name,sec->auth_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_KERBEROS
|
#ifdef HAVE_KERBEROS
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@ -983,6 +1094,3 @@ int krb_in_group(KerberosInfo* kdat, char *group, char* pchGrps)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_KERBEROS */
|
#endif /* HAVE_KERBEROS */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* http_auth.h,v 1.20 1995/07/25 14:48:05 blong Exp
|
* http_auth.h,v 1.22 1996/03/27 20:43:57 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
@ -25,11 +25,10 @@
|
|||||||
# include <ndbm.h>
|
# include <ndbm.h>
|
||||||
# endif /* _DBMSUPPORT_H */
|
# endif /* _DBMSUPPORT_H */
|
||||||
#endif /* DBM_SUPPORT */
|
#endif /* DBM_SUPPORT */
|
||||||
|
#include "global.h"
|
||||||
|
|
||||||
/* globals defined in this module */
|
/* globals defined in this module */
|
||||||
|
|
||||||
extern char user[];
|
|
||||||
extern char groupname[];
|
|
||||||
|
|
||||||
|
|
||||||
/* http_auth */
|
/* http_auth */
|
||||||
@ -44,8 +43,6 @@ int in_group(per_request *reqInfo, char *user, char *group, char* pchGrps);
|
|||||||
char* init_group(per_request *reqInfo,char* grpfile);
|
char* init_group(per_request *reqInfo,char* grpfile);
|
||||||
void auth_bong(per_request *reqInfo,char *s,char* auth_name, char* auth_type);
|
void auth_bong(per_request *reqInfo,char *s,char* auth_name, char* auth_type);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(KRB4) || defined(KRB5)
|
#if defined(KRB4) || defined(KRB5)
|
||||||
typedef struct _krbdata {
|
typedef struct _krbdata {
|
||||||
char client_name[MAX_STRING_LEN];
|
char client_name[MAX_STRING_LEN];
|
||||||
@ -72,5 +69,4 @@ extern char k5_srvtab[];
|
|||||||
int k5_server_auth(char* authline, char* reply, KerberosInfo *kdat);
|
int k5_server_auth(char* authline, char* reply, KerberosInfo *kdat);
|
||||||
#endif /* KRB5 */
|
#endif /* KRB5 */
|
||||||
|
|
||||||
|
|
||||||
#endif /* _HTTP_AUTH_H_ */
|
#endif /* _HTTP_AUTH_H_ */
|
||||||
|
@ -13,39 +13,6 @@
|
|||||||
* http_config.c: auxillary functions for reading httpd's config file
|
* http_config.c: auxillary functions for reading httpd's config file
|
||||||
* and converting filenames into a namespace
|
* and converting filenames into a namespace
|
||||||
*
|
*
|
||||||
* Based on NCSA HTTPd 1.3 by Rob McCool
|
|
||||||
*
|
|
||||||
* 10/28/94 cvarela
|
|
||||||
* Added config options AgentLog and RefererLog for extra log info
|
|
||||||
*
|
|
||||||
* 02/19/95 blong
|
|
||||||
* Added config options MaxServers and StartServers for configuration
|
|
||||||
* defined children
|
|
||||||
*
|
|
||||||
* 03/21/95 cvarela
|
|
||||||
* Added RefererIgnore to ignore certain URIs when logging referers
|
|
||||||
*
|
|
||||||
* 06/01/95 blong
|
|
||||||
* Added patch by Conrad Damon (damon@netserver.stanford.edu) that
|
|
||||||
* avoids a cfg_getline loop if a user sets a directory as a password
|
|
||||||
* file.
|
|
||||||
*
|
|
||||||
* 09/02/95 blong
|
|
||||||
* Added patch by Kevin Ruddy (kevin.ruddy@powerdog.com) that should
|
|
||||||
* allow systems which don't recognize a numeric address to gethostbyname
|
|
||||||
* to use a numeric IP in the BindAddress and VirtualHost fields
|
|
||||||
*
|
|
||||||
* 09/10/95 mshapiro
|
|
||||||
* Added includes for <netinet/in.h> and <arpa/inet.h>
|
|
||||||
* 09/18/95 mshapiro
|
|
||||||
* Added LogDirGroupWriteOk, LogDirPublicWriteOk
|
|
||||||
* directives
|
|
||||||
* 10/06/95 blong
|
|
||||||
* Added patch by Elf Sternberg (elf@aaden.spry.com) to configure
|
|
||||||
* the process name which SETPROCTITLE uses
|
|
||||||
* 10/06/95 blong
|
|
||||||
* Added patch by Nathan Neulinger (nneul@umr.edu) to have separate
|
|
||||||
* security permissions for Redirect in .htaccess files
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -67,6 +34,8 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "fdwrap.h"
|
#include "fdwrap.h"
|
||||||
@ -78,8 +47,10 @@
|
|||||||
#include "http_log.h"
|
#include "http_log.h"
|
||||||
#include "http_dir.h"
|
#include "http_dir.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include <netinet/in.h>
|
#ifdef FCGI_SUPPORT
|
||||||
#include <arpa/inet.h>
|
# include "fcgi.h" /* for AppClassCmd() */
|
||||||
|
#endif /* FCGI_SUPPORT */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Server config globals */
|
/* Server config globals */
|
||||||
@ -191,8 +162,6 @@ void set_defaults(per_host *host, FILE *errors)
|
|||||||
timeout = DEFAULT_TIMEOUT;
|
timeout = DEFAULT_TIMEOUT;
|
||||||
do_rfc931 = DEFAULT_RFC931;
|
do_rfc931 = DEFAULT_RFC931;
|
||||||
|
|
||||||
/* Necessary with new configuration stuff? */
|
|
||||||
|
|
||||||
/* default resource config stuff */
|
/* default resource config stuff */
|
||||||
set_host_conf(host,PH_SRM_CONF,SRM_USER_DIR,DEFAULT_USER_DIR);
|
set_host_conf(host,PH_SRM_CONF,SRM_USER_DIR,DEFAULT_USER_DIR);
|
||||||
set_host_conf(host,PH_SRM_CONF,SRM_INDEX_NAMES,DEFAULT_INDEX_NAMES);
|
set_host_conf(host,PH_SRM_CONF,SRM_INDEX_NAMES,DEFAULT_INDEX_NAMES);
|
||||||
@ -486,11 +455,9 @@ void process_server_config(per_host *host, FILE *cfg, FILE *errors,
|
|||||||
}
|
}
|
||||||
#ifdef DIGEST_AUTH
|
#ifdef DIGEST_AUTH
|
||||||
else if(!strcasecmp(w,"AssumeDigestSupport")) {
|
else if(!strcasecmp(w,"AssumeDigestSupport")) {
|
||||||
cfg_getword(w,l);
|
/* Doesn't do anything anymore, but if we take it out, anyone with
|
||||||
if(!strcmp(w,"on"))
|
* it in their configuration files would complain. *sigh*
|
||||||
assume_digest_support = TRUE;
|
*/
|
||||||
else
|
|
||||||
assume_digest_support = FALSE;
|
|
||||||
}
|
}
|
||||||
#endif /* DIGEST_AUTH */
|
#endif /* DIGEST_AUTH */
|
||||||
else if(((!strcasecmp(w,"<VirtualHost")) || (!strcasecmp(w,"<Host")))
|
else if(((!strcasecmp(w,"<VirtualHost")) || (!strcasecmp(w,"<Host")))
|
||||||
@ -590,6 +557,30 @@ host->srm_confname,n,errors);
|
|||||||
config_warn("OldScriptAlias directive obsolete, ignored",
|
config_warn("OldScriptAlias directive obsolete, ignored",
|
||||||
host->srm_confname,n,errors);
|
host->srm_confname,n,errors);
|
||||||
}
|
}
|
||||||
|
#ifdef FCGI_SUPPORT
|
||||||
|
else if(!strcasecmp(w,"FCGIScriptAlias")) {
|
||||||
|
cfg_getword(w,l);
|
||||||
|
cfg_getword(w2,l);
|
||||||
|
if((w[0] == '\0') || (w2[0] == '\0')) {
|
||||||
|
config_error(
|
||||||
|
"FCGIScriptAlias must be followed by a fakename, one space, then a realname",
|
||||||
|
host->srm_confname,n,errors);
|
||||||
|
}
|
||||||
|
if (!set_host_conf_value(host,PH_SRM_CONF,SRM_TRANSLATIONS)) {
|
||||||
|
host->translations = NULL;
|
||||||
|
}
|
||||||
|
add_alias(host,w,w2,A_SCRIPT_FCGI);
|
||||||
|
}
|
||||||
|
else if(!strcasecmp(w,"AppClass")) {
|
||||||
|
char *result;
|
||||||
|
if (!set_host_conf_value(host,PH_SRM_CONF,SRM_TRANSLATIONS)) {
|
||||||
|
host->translations = NULL;
|
||||||
|
}
|
||||||
|
result = AppClassCmd(host, l);
|
||||||
|
if (result)
|
||||||
|
config_error(result, host->srm_confname, n, errors);
|
||||||
|
}
|
||||||
|
#endif /* FCGI_SUPPORT */
|
||||||
else if(!strcasecmp(w,"UserDir")) {
|
else if(!strcasecmp(w,"UserDir")) {
|
||||||
cfg_getword(w,l);
|
cfg_getword(w,l);
|
||||||
if(!strcmp(w,"DISABLED"))
|
if(!strcmp(w,"DISABLED"))
|
||||||
@ -655,11 +646,18 @@ host->srm_confname,n,errors);
|
|||||||
else if(!strcasecmp(w,"Redirect") || !strcasecmp(w,"RedirectTemp")) {
|
else if(!strcasecmp(w,"Redirect") || !strcasecmp(w,"RedirectTemp")) {
|
||||||
cfg_getword(w,l);
|
cfg_getword(w,l);
|
||||||
cfg_getword(w2,l);
|
cfg_getword(w2,l);
|
||||||
if((w[0] == '\0') || (w2[0] == '\0') || (!is_url(w2))) {
|
if((w[0] == '\0') || (w2[0] == '\0') ||
|
||||||
|
!(is_url(w2) || (w2[0] == '/')))
|
||||||
|
{
|
||||||
config_error(
|
config_error(
|
||||||
"Redirect must be followed by a document, one space, then a URL",
|
"Redirect must be followed by a document, one space, then a URL",
|
||||||
host->srm_confname,n,errors);
|
host->srm_confname,n,errors);
|
||||||
}
|
}
|
||||||
|
if (w2[0] == '/') {
|
||||||
|
char w3[MAX_STRING_LEN];
|
||||||
|
construct_url(w3,host,w2);
|
||||||
|
strcpy(w2,w3);
|
||||||
|
}
|
||||||
if (!set_host_conf_value(host,PH_SRM_CONF,SRM_TRANSLATIONS)) {
|
if (!set_host_conf_value(host,PH_SRM_CONF,SRM_TRANSLATIONS)) {
|
||||||
host->translations = NULL;
|
host->translations = NULL;
|
||||||
}
|
}
|
||||||
@ -668,7 +666,9 @@ host->srm_confname,n,errors);
|
|||||||
else if(!strcasecmp(w,"RedirectPermanent")) {
|
else if(!strcasecmp(w,"RedirectPermanent")) {
|
||||||
cfg_getword(w,l);
|
cfg_getword(w,l);
|
||||||
cfg_getword(w2,l);
|
cfg_getword(w2,l);
|
||||||
if((w[0] == '\0') || (w2[0] == '\0') || (!is_url(w2))) {
|
if((w[0] == '\0') || (w2[0] == '\0') ||
|
||||||
|
!(is_url(w2) || (w2[0] == '/')))
|
||||||
|
{
|
||||||
config_error(
|
config_error(
|
||||||
"RedirectPermanent must be followed by a document, one space, then a URL",
|
"RedirectPermanent must be followed by a document, one space, then a URL",
|
||||||
host->srm_confname,n,errors);
|
host->srm_confname,n,errors);
|
||||||
@ -676,6 +676,11 @@ host->srm_confname,n,errors);
|
|||||||
if (!set_host_conf_value(host,PH_SRM_CONF,SRM_TRANSLATIONS)) {
|
if (!set_host_conf_value(host,PH_SRM_CONF,SRM_TRANSLATIONS)) {
|
||||||
host->translations = NULL;
|
host->translations = NULL;
|
||||||
}
|
}
|
||||||
|
if (w2[0] == '/') {
|
||||||
|
char w3[MAX_STRING_LEN];
|
||||||
|
construct_url(w3,host,w2);
|
||||||
|
strcpy(w2,w3);
|
||||||
|
}
|
||||||
add_redirect(host,w,w2,A_REDIRECT_PERM);
|
add_redirect(host,w,w2,A_REDIRECT_PERM);
|
||||||
}
|
}
|
||||||
else if(!strcasecmp(w,"FancyIndexing")) {
|
else if(!strcasecmp(w,"FancyIndexing")) {
|
||||||
@ -806,7 +811,7 @@ void access_syntax_error(per_request *reqInfo, int n, char *err, FILE *fp,
|
|||||||
else {
|
else {
|
||||||
char e[MAX_STRING_LEN];
|
char e[MAX_STRING_LEN];
|
||||||
FClose(fp);
|
FClose(fp);
|
||||||
sprintf(e,"httpd: syntax error or override violation in access control file %s, reason: %s",file,err);
|
sprintf(e,"HTTPd: syntax error or override violation in access control file %s, reason: %s",file,err);
|
||||||
die(reqInfo,SC_SERVER_ERROR,e);
|
die(reqInfo,SC_SERVER_ERROR,e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -821,6 +826,10 @@ int parse_access_dir(per_request *reqInfo, FILE *f, int line, char or,
|
|||||||
register int x,i;
|
register int x,i;
|
||||||
|
|
||||||
x = num_sec;
|
x = num_sec;
|
||||||
|
if (num_sec > MAX_SECURITY)
|
||||||
|
access_syntax_error(reqInfo,n,
|
||||||
|
"Too many security entries, increase MAX_SECURITY and recompile",
|
||||||
|
f,file);
|
||||||
|
|
||||||
sec[x].opts=OPT_UNSET;
|
sec[x].opts=OPT_UNSET;
|
||||||
sec[x].override = or;
|
sec[x].override = or;
|
||||||
@ -842,7 +851,10 @@ int parse_access_dir(per_request *reqInfo, FILE *f, int line, char or,
|
|||||||
sec[x].order[i] = DENY_THEN_ALLOW;
|
sec[x].order[i] = DENY_THEN_ALLOW;
|
||||||
sec[x].num_allow[i]=0;
|
sec[x].num_allow[i]=0;
|
||||||
sec[x].num_deny[i]=0;
|
sec[x].num_deny[i]=0;
|
||||||
|
sec[x].num_referer_allow[i]=0;
|
||||||
|
sec[x].num_referer_deny[i]=0;
|
||||||
sec[x].num_auth[i] = 0;
|
sec[x].num_auth[i] = 0;
|
||||||
|
sec[x].on_deny[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(!(cfg_getline(l,MAX_STRING_LEN,f))) {
|
while(!(cfg_getline(l,MAX_STRING_LEN,f))) {
|
||||||
@ -1087,18 +1099,38 @@ int parse_access_dir(per_request *reqInfo, FILE *f, int line, char or,
|
|||||||
access_syntax_error(reqInfo,n,"override violation",f,file);
|
access_syntax_error(reqInfo,n,"override violation",f,file);
|
||||||
cfg_getword(w,l);
|
cfg_getword(w,l);
|
||||||
cfg_getword(w2,l);
|
cfg_getword(w2,l);
|
||||||
if((w[0] == '\0') || (w2[0] == '\0') || (!is_url(w2))) {
|
if((w[0] == '\0') || (w2[0] == '\0') ||
|
||||||
|
!(is_url(w2) || (w2[0] == '/')))
|
||||||
|
{
|
||||||
access_syntax_error(reqInfo,n,
|
access_syntax_error(reqInfo,n,
|
||||||
"Redirect must be followed by a document, one space, then a URL.",f,file);
|
"Redirect must be followed by a document, one space, then a URL.",f,file);
|
||||||
}
|
}
|
||||||
if(!file) {
|
if(!file) {
|
||||||
|
if (w2[0] == '/') {
|
||||||
|
char w3[MAX_STRING_LEN];
|
||||||
|
construct_url(w3,gConfiguration,w2);
|
||||||
|
strcpy(w2,w3);
|
||||||
|
}
|
||||||
if (!set_host_conf_value(gConfiguration,PH_SRM_CONF,SRM_TRANSLATIONS)) {
|
if (!set_host_conf_value(gConfiguration,PH_SRM_CONF,SRM_TRANSLATIONS)) {
|
||||||
gConfiguration->translations = NULL;
|
gConfiguration->translations = NULL;
|
||||||
}
|
}
|
||||||
add_redirect(gConfiguration,w,w2,A_REDIRECT_TEMP);
|
add_redirect(gConfiguration,w,w2,A_REDIRECT_TEMP);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!strcmp(reqInfo->url,w)) {
|
char tmp[HUGE_STRING_LEN];
|
||||||
|
int len;
|
||||||
|
if (w2[0] == '/') {
|
||||||
|
construct_url(tmp,reqInfo->hostInfo,w2);
|
||||||
|
strcpy(w2,tmp);
|
||||||
|
}
|
||||||
|
strcpy(tmp,reqInfo->url);
|
||||||
|
if (reqInfo->path_info[0]) {
|
||||||
|
len = strlen(reqInfo->url);
|
||||||
|
if (reqInfo->url[len-1] == '/')
|
||||||
|
reqInfo->url[len-1] = '\0';
|
||||||
|
strcat(tmp,reqInfo->path_info);
|
||||||
|
}
|
||||||
|
if (!strcmp(tmp,w) || !strcmp_match(tmp,w)) {
|
||||||
FClose(f);
|
FClose(f);
|
||||||
die(reqInfo,SC_REDIRECT_TEMP,w2);
|
die(reqInfo,SC_REDIRECT_TEMP,w2);
|
||||||
}
|
}
|
||||||
@ -1109,20 +1141,40 @@ int parse_access_dir(per_request *reqInfo, FILE *f, int line, char or,
|
|||||||
access_syntax_error(reqInfo,n,"override violation",f,file);
|
access_syntax_error(reqInfo,n,"override violation",f,file);
|
||||||
cfg_getword(w,l);
|
cfg_getword(w,l);
|
||||||
cfg_getword(w2,l);
|
cfg_getword(w2,l);
|
||||||
if((w[0] == '\0') || (w2[0] == '\0') || (!is_url(w2))) {
|
if((w[0] == '\0') || (w2[0] == '\0') ||
|
||||||
|
!(is_url(w2) || (w2[0] == '/')))
|
||||||
|
{
|
||||||
access_syntax_error(reqInfo,n,
|
access_syntax_error(reqInfo,n,
|
||||||
"Redirect must be followed by a document, one space, then a URL.",f,file);
|
"Redirect must be followed by a document, one space, then a URL.",f,file);
|
||||||
}
|
}
|
||||||
if(!file) {
|
if(!file) {
|
||||||
|
if (w2[0] == '/') {
|
||||||
|
char w3[MAX_STRING_LEN];
|
||||||
|
construct_url(w3,gConfiguration,w2);
|
||||||
|
strcpy(w2,w3);
|
||||||
|
}
|
||||||
if (!set_host_conf_value(gConfiguration,PH_SRM_CONF,SRM_TRANSLATIONS)) {
|
if (!set_host_conf_value(gConfiguration,PH_SRM_CONF,SRM_TRANSLATIONS)) {
|
||||||
gConfiguration->translations = NULL;
|
gConfiguration->translations = NULL;
|
||||||
}
|
}
|
||||||
add_redirect(gConfiguration,w,w2,A_REDIRECT_PERM);
|
add_redirect(gConfiguration,w,w2,A_REDIRECT_PERM);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!strcmp(reqInfo->url,w)) {
|
char tmp[HUGE_STRING_LEN];
|
||||||
|
int len;
|
||||||
|
if (w2[0] == '/') {
|
||||||
|
construct_url(tmp,reqInfo->hostInfo,w2);
|
||||||
|
strcpy(w2,tmp);
|
||||||
|
}
|
||||||
|
strcpy(tmp,reqInfo->url);
|
||||||
|
if (reqInfo->path_info[0]) {
|
||||||
|
len = strlen(reqInfo->url);
|
||||||
|
if (reqInfo->url[len-1] == '/')
|
||||||
|
reqInfo->url[len-1] = '\0';
|
||||||
|
strcat(tmp,reqInfo->path_info);
|
||||||
|
}
|
||||||
|
if (!strcmp(tmp,w) || !strcmp_match(tmp,w)) {
|
||||||
FClose(f);
|
FClose(f);
|
||||||
die(reqInfo,SC_REDIRECT_PERM,w2);
|
die(reqInfo,SC_REDIRECT_TEMP,w2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1180,15 +1232,65 @@ int parse_access_dir(per_request *reqInfo, FILE *f, int line, char or,
|
|||||||
for(i=0;i<METHODS;i++)
|
for(i=0;i<METHODS;i++)
|
||||||
if(m[i]) {
|
if(m[i]) {
|
||||||
int q=sec[x].num_allow[i]++;
|
int q=sec[x].num_allow[i]++;
|
||||||
|
if (q >= MAX_SECURITY)
|
||||||
|
access_syntax_error(reqInfo,n,
|
||||||
|
"Too many allow entries, increase MAX_SECURITY and recompile",
|
||||||
|
f,file);
|
||||||
if(!(sec[x].allow[i][q] = strdup(w)))
|
if(!(sec[x].allow[i][q] = strdup(w)))
|
||||||
die(reqInfo,SC_NO_MEMORY,"parse_access_dir");
|
die(reqInfo,SC_NO_MEMORY,"parse_access_dir");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(!strcasecmp(w,"referer")) {
|
||||||
|
int ref_type;
|
||||||
|
|
||||||
|
cfg_getword(w,l);
|
||||||
|
if(!strcmp(w,"allow")) {
|
||||||
|
ref_type = FA_ALLOW;
|
||||||
|
} else if (!strcmp(w,"deny")) {
|
||||||
|
ref_type = FA_DENY;
|
||||||
|
} else access_syntax_error(reqInfo,n,
|
||||||
|
"unknown referer type.",
|
||||||
|
f,file);
|
||||||
|
cfg_getword(w,l);
|
||||||
|
if(strcmp(w,"from"))
|
||||||
|
access_syntax_error(reqInfo,n,
|
||||||
|
"allow/deny must be followed by from.",
|
||||||
|
f,file);
|
||||||
|
while(1) {
|
||||||
|
cfg_getword(w,l);
|
||||||
|
if (!w[0]) break;
|
||||||
|
for(i=0;i<METHODS;i++)
|
||||||
|
if(m[i]) {
|
||||||
|
int q;
|
||||||
|
if (ref_type == FA_ALLOW) {
|
||||||
|
q=sec[x].num_referer_allow[i]++;
|
||||||
|
if (q >= MAX_SECURITY)
|
||||||
|
access_syntax_error(reqInfo,n,
|
||||||
|
"Too many referer allow entries, increase MAX_SECURITY and recompile",
|
||||||
|
f,file);
|
||||||
|
if(!(sec[x].referer_allow[i][q] = strdup(w)))
|
||||||
|
die(reqInfo,SC_NO_MEMORY,"parse_access_dir");
|
||||||
|
} else if (ref_type == FA_DENY) {
|
||||||
|
q=sec[x].num_referer_deny[i]++;
|
||||||
|
if (q >= MAX_SECURITY)
|
||||||
|
access_syntax_error(reqInfo,n,
|
||||||
|
"Too many referer deny entries, increase MAX_SECURITY and recompile",
|
||||||
|
f,file);
|
||||||
|
if(!(sec[x].referer_deny[i][q] = strdup(w)))
|
||||||
|
die(reqInfo,SC_NO_MEMORY,"parse_access_dir");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else if(!strcasecmp(w,"require")) {
|
else if(!strcasecmp(w,"require")) {
|
||||||
for(i=0;i<METHODS;i++)
|
for(i=0;i<METHODS;i++)
|
||||||
if(m[i]) {
|
if(m[i]) {
|
||||||
int q=sec[x].num_auth[i]++;
|
int q=sec[x].num_auth[i]++;
|
||||||
|
if (q >= MAX_SECURITY)
|
||||||
|
access_syntax_error(reqInfo,n,
|
||||||
|
"Too many require entries, increase MAX_SECURITY and recompile",
|
||||||
|
f,file);
|
||||||
if(!(sec[x].auth[i][q] = strdup(l)))
|
if(!(sec[x].auth[i][q] = strdup(l)))
|
||||||
die(reqInfo,SC_NO_MEMORY,"parse_access_dir");
|
die(reqInfo,SC_NO_MEMORY,"parse_access_dir");
|
||||||
}
|
}
|
||||||
@ -1205,6 +1307,10 @@ int parse_access_dir(per_request *reqInfo, FILE *f, int line, char or,
|
|||||||
for(i=0;i<METHODS;i++)
|
for(i=0;i<METHODS;i++)
|
||||||
if(m[i]) {
|
if(m[i]) {
|
||||||
int q=sec[x].num_deny[i]++;
|
int q=sec[x].num_deny[i]++;
|
||||||
|
if (q >= MAX_SECURITY)
|
||||||
|
access_syntax_error(reqInfo,n,
|
||||||
|
"Too many deny entries, increase MAX_SECURITY and recompile",
|
||||||
|
f,file);
|
||||||
if(!(sec[x].deny[i][q] = strdup(w)))
|
if(!(sec[x].deny[i][q] = strdup(w)))
|
||||||
die(reqInfo,SC_NO_MEMORY,"parse_access_dir");
|
die(reqInfo,SC_NO_MEMORY,"parse_access_dir");
|
||||||
}
|
}
|
||||||
@ -1221,6 +1327,13 @@ int parse_access_dir(per_request *reqInfo, FILE *f, int line, char or,
|
|||||||
"Satisfy either any or all.",
|
"Satisfy either any or all.",
|
||||||
f,file);
|
f,file);
|
||||||
}
|
}
|
||||||
|
else if(!strcasecmp(w,"OnDeny")) {
|
||||||
|
for(i=0;i<METHODS;i++)
|
||||||
|
if(m[i]) {
|
||||||
|
if(!(sec[x].on_deny[i] = strdup(l)))
|
||||||
|
die(reqInfo,SC_NO_MEMORY,"parse_access_dir");
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
access_syntax_error(reqInfo,n,
|
access_syntax_error(reqInfo,n,
|
||||||
"Unknown keyword in Limit region.",
|
"Unknown keyword in Limit region.",
|
||||||
@ -1270,7 +1383,7 @@ void process_access_config(FILE *errors)
|
|||||||
num_sec = 0;
|
num_sec = 0;
|
||||||
n=0;
|
n=0;
|
||||||
if(!(f=fopen(access_confname,"r"))) {
|
if(!(f=fopen(access_confname,"r"))) {
|
||||||
fprintf(errors,"httpd: could not open access configuration file %s.\n",
|
fprintf(errors,"HTTPd: could not open access configuration file %s.\n",
|
||||||
access_confname);
|
access_confname);
|
||||||
perror("fopen");
|
perror("fopen");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -1302,7 +1415,7 @@ void read_config(FILE *errors)
|
|||||||
|
|
||||||
if(!(cfg = fopen(server_confname,"r"))) {
|
if(!(cfg = fopen(server_confname,"r"))) {
|
||||||
fprintf(errors,
|
fprintf(errors,
|
||||||
"httpd: could not open server config. file %s\n",
|
"HTTPd: could not open server config. file %s\n",
|
||||||
server_confname);
|
server_confname);
|
||||||
perror("fopen");
|
perror("fopen");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* http_config.h,v 1.13 1995/11/28 09:01:58 blong Exp
|
* http_config.h,v 1.15 1996/03/27 20:44:01 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
|
209
src/http_dir.c
209
src/http_dir.c
@ -12,12 +12,6 @@
|
|||||||
*
|
*
|
||||||
* http_dir.c: Handles the on-the-fly html index generation
|
* http_dir.c: Handles the on-the-fly html index generation
|
||||||
*
|
*
|
||||||
* 03-23-93 Rob McCool
|
|
||||||
* Wrote base code up to release 1.3
|
|
||||||
*
|
|
||||||
* 03-12-95 blong
|
|
||||||
* Added patch by Roy T. Fielding <fielding@avron.ICS.UCI.EDU>
|
|
||||||
* to fix missing trailing slash for parent directory
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -41,15 +35,16 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
|
#include "http_request.h"
|
||||||
#include "http_dir.h"
|
#include "http_dir.h"
|
||||||
#include "http_mime.h"
|
#include "http_mime.h"
|
||||||
#include "http_log.h"
|
#include "http_log.h"
|
||||||
#include "http_config.h"
|
#include "http_config.h"
|
||||||
#include "http_request.h"
|
|
||||||
#include "http_send.h"
|
#include "http_send.h"
|
||||||
#include "http_alias.h"
|
#include "http_alias.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "fdwrap.h"
|
#include "fdwrap.h"
|
||||||
|
#include "allocate.h"
|
||||||
|
|
||||||
/* Split each item list into two lists, the 0-th entry holds items which
|
/* Split each item list into two lists, the 0-th entry holds items which
|
||||||
* are valid over this request while the 1-st entry for those valids for
|
* are valid over this request while the 1-st entry for those valids for
|
||||||
@ -62,21 +57,21 @@ static struct item *hdr_list[2], *rdme_list[2], *opts_list[2];
|
|||||||
static int dir_opts;
|
static int dir_opts;
|
||||||
|
|
||||||
void init_indexing(int local) {
|
void init_indexing(int local) {
|
||||||
icon_list[0] = NULL;
|
icon_list[FI_LOCAL] = NULL;
|
||||||
alt_list[0] = NULL;
|
alt_list[FI_LOCAL] = NULL;
|
||||||
desc_list[0] = NULL;
|
desc_list[FI_LOCAL] = NULL;
|
||||||
ign_list[0] = NULL;
|
ign_list[FI_LOCAL] = NULL;
|
||||||
hdr_list[0] = NULL;
|
hdr_list[FI_LOCAL] = NULL;
|
||||||
rdme_list[0] = NULL;
|
rdme_list[FI_LOCAL] = NULL;
|
||||||
opts_list[0] = NULL;
|
opts_list[FI_LOCAL] = NULL;
|
||||||
if (local == FI_GLOBAL) {
|
if (local == FI_GLOBAL) {
|
||||||
icon_list[1] = NULL;
|
icon_list[FI_GLOBAL] = NULL;
|
||||||
alt_list[1] = NULL;
|
alt_list[FI_GLOBAL] = NULL;
|
||||||
desc_list[1] = NULL;
|
desc_list[FI_GLOBAL] = NULL;
|
||||||
ign_list[1] = NULL;
|
ign_list[FI_GLOBAL] = NULL;
|
||||||
hdr_list[1] = NULL;
|
hdr_list[FI_GLOBAL] = NULL;
|
||||||
rdme_list[1] = NULL;
|
rdme_list[FI_GLOBAL] = NULL;
|
||||||
opts_list[1] = NULL;
|
opts_list[FI_GLOBAL] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,38 +257,48 @@ char *find_item(per_request *reqInfo, struct item *list[2], char *path,
|
|||||||
{
|
{
|
||||||
struct item *p = NULL;
|
struct item *p = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
char *file_type,*file_encoding;
|
||||||
|
|
||||||
|
file_type = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
file_encoding = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
for (i=0; i < 2; i++) {
|
for (i=0; i < 2; i++) {
|
||||||
for (p = list[i]; p; p = p->next) {
|
for (p = list[i]; p; p = p->next) {
|
||||||
/* Special cased for ^^DIRECTORY^^ and ^^BLANKICON^^ */
|
/* Special cased for ^^DIRECTORY^^ and ^^BLANKICON^^ */
|
||||||
if((path[0] == '^') || (!strcmp_match(path,p->apply_path))) {
|
if((path[0] == '^') || (!strcmp_match(path,p->apply_path))) {
|
||||||
if(!(p->apply_to))
|
if(!(p->apply_to))
|
||||||
return p->data;
|
goto found_item;
|
||||||
else if(p->type == BY_PATH) {
|
else if(p->type == BY_PATH) {
|
||||||
if(!strcmp_match(path,p->apply_to))
|
if(!strcmp_match(path,p->apply_to))
|
||||||
return p->data;
|
goto found_item;
|
||||||
} else if(!path_only) {
|
} else if(!path_only) {
|
||||||
char pathbak[MAX_STRING_LEN];
|
char pathbak[MAX_STRING_LEN];
|
||||||
|
|
||||||
strcpy(pathbak,path);
|
strcpy(pathbak,path);
|
||||||
content_encoding[0] = '\0';
|
get_content_type(reqInfo,pathbak,file_type,file_encoding);
|
||||||
set_content_type(reqInfo,pathbak);
|
if(!file_encoding[0]) {
|
||||||
if(!content_encoding[0]) {
|
|
||||||
if(p->type == BY_TYPE) {
|
if(p->type == BY_TYPE) {
|
||||||
if(!strcmp_match(content_type,p->apply_to))
|
if(!strcmp_match(file_type,p->apply_to))
|
||||||
return p->data;
|
goto found_item;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(p->type == BY_ENCODING) {
|
if(p->type == BY_ENCODING) {
|
||||||
if(!strcmp_match(content_encoding,p->apply_to))
|
if(!strcmp_match(file_encoding,p->apply_to))
|
||||||
return p->data;
|
goto found_item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
freeString(file_type);
|
||||||
|
freeString(file_encoding);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
found_item:
|
||||||
|
freeString(file_type);
|
||||||
|
freeString(file_encoding);
|
||||||
|
return p->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define find_icon(r,p,t) find_item(r,icon_list,p,t)
|
#define find_icon(r,p,t) find_item(r,icon_list,p,t)
|
||||||
@ -342,16 +347,15 @@ int insert_readme(per_request *reqInfo, char *name,
|
|||||||
if(stat(fn,&finfo) == -1)
|
if(stat(fn,&finfo) == -1)
|
||||||
return 0;
|
return 0;
|
||||||
plaintext=1;
|
plaintext=1;
|
||||||
if(rule) reqInfo->bytes_sent += fprintf(reqInfo->out,"<HR>%c",LF);
|
if(rule) rprintf(reqInfo,"<HR>%c",LF);
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"<PRE>%c",LF);
|
rprintf(reqInfo,"<PRE>%c",LF);
|
||||||
}
|
}
|
||||||
else if(rule) reqInfo->bytes_sent += fprintf(reqInfo->out,"<HR>%c",LF);
|
else if(rule) rprintf(reqInfo,"<HR>%c",LF);
|
||||||
if(!(r = FOpen(fn,"r")))
|
if(!(r = FOpen(fn,"r")))
|
||||||
return 0;
|
return 0;
|
||||||
send_fp(reqInfo,r,NULL);
|
send_fp(reqInfo,r,NULL);
|
||||||
FClose(r);
|
FClose(r);
|
||||||
if(plaintext)
|
if(plaintext) rprintf(reqInfo,"</PRE>%c",LF);
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"</PRE>%c",LF);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -361,15 +365,18 @@ char *find_title(per_request *reqInfo, char *filename) {
|
|||||||
char filebak[MAX_STRING_LEN];
|
char filebak[MAX_STRING_LEN];
|
||||||
FILE *thefile;
|
FILE *thefile;
|
||||||
int x,y,n,p;
|
int x,y,n,p;
|
||||||
|
char *file_type, *file_encoding;
|
||||||
|
|
||||||
|
file_type = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
file_encoding = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
content_encoding[0] = '\0';
|
|
||||||
strcpy(filebak,filename);
|
strcpy(filebak,filename);
|
||||||
set_content_type(reqInfo,filebak);
|
get_content_type(reqInfo,filebak,file_type,file_encoding);
|
||||||
if(((!strcmp(content_type,"text/html")) ||
|
if(((!strcmp(file_type,"text/html")) ||
|
||||||
(strcmp(content_type, INCLUDES_MAGIC_TYPE) == 0))
|
(strcmp(file_type, INCLUDES_MAGIC_TYPE) == 0))
|
||||||
&& (!content_encoding[0])) {
|
&& (!file_encoding[0])) {
|
||||||
if(!(thefile = FOpen(filename,"r")))
|
if(!(thefile = FOpen(filename,"r")))
|
||||||
return NULL;
|
goto not_found;
|
||||||
n = fread(titlebuf,sizeof(char),MAX_STRING_LEN - 1,thefile);
|
n = fread(titlebuf,sizeof(char),MAX_STRING_LEN - 1,thefile);
|
||||||
titlebuf[n] = '\0';
|
titlebuf[n] = '\0';
|
||||||
for(x=0,p=0;titlebuf[x];x++) {
|
for(x=0,p=0;titlebuf[x];x++) {
|
||||||
@ -382,14 +389,17 @@ char *find_title(per_request *reqInfo, char *filename) {
|
|||||||
if((titlebuf[y] == CR) || (titlebuf[y] == LF))
|
if((titlebuf[y] == CR) || (titlebuf[y] == LF))
|
||||||
titlebuf[y] = ' ';
|
titlebuf[y] = ' ';
|
||||||
FClose(thefile);
|
FClose(thefile);
|
||||||
|
freeString(file_type);
|
||||||
|
freeString(file_encoding);
|
||||||
return strdup(&titlebuf[x]);
|
return strdup(&titlebuf[x]);
|
||||||
}
|
}
|
||||||
} else p=0;
|
} else p=0;
|
||||||
}
|
}
|
||||||
FClose(thefile);
|
FClose(thefile);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
content_encoding[0] = '\0';
|
not_found:
|
||||||
|
freeString(file_type);
|
||||||
|
freeString(file_encoding);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,9 +464,10 @@ struct ent *make_dir_entry(per_request *reqInfo, char *path,
|
|||||||
p->alt = NULL;
|
p->alt = NULL;
|
||||||
p->desc = NULL;
|
p->desc = NULL;
|
||||||
if(S_ISDIR(finfo.st_mode)) {
|
if(S_ISDIR(finfo.st_mode)) {
|
||||||
if(!(p->icon = find_icon(reqInfo,t,1)))
|
if(!(p->icon = find_icon(reqInfo,t,1))) {
|
||||||
if (p->icon != NULL) free(p->icon);
|
if (p->icon != NULL) free(p->icon);
|
||||||
p->icon = find_icon(reqInfo,"^^DIRECTORY^^",1);
|
p->icon = find_icon(reqInfo,"^^DIRECTORY^^",1);
|
||||||
|
}
|
||||||
if(!(tmp = find_alt(reqInfo,t,1))){
|
if(!(tmp = find_alt(reqInfo,t,1))){
|
||||||
p->alt = (char *) malloc(sizeof(char)*4);
|
p->alt = (char *) malloc(sizeof(char)*4);
|
||||||
strcpy(p->alt,"DIR");
|
strcpy(p->alt,"DIR");
|
||||||
@ -495,22 +506,19 @@ struct ent *make_dir_entry(per_request *reqInfo, char *path,
|
|||||||
void send_size(per_request *reqInfo, size_t size) {
|
void send_size(per_request *reqInfo, size_t size) {
|
||||||
|
|
||||||
if(size == -1) {
|
if(size == -1) {
|
||||||
fputs(" -",reqInfo->out);
|
rputs(" -",reqInfo);
|
||||||
reqInfo->bytes_sent += 5;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(!size) {
|
if(!size) {
|
||||||
fputs(" 0K",reqInfo->out);
|
rputs(" 0K",reqInfo);
|
||||||
reqInfo->bytes_sent += 5;
|
|
||||||
}
|
}
|
||||||
else if(size < 1024) {
|
else if(size < 1024) {
|
||||||
fputs(" 1K",reqInfo->out);
|
rputs(" 1K",reqInfo);
|
||||||
reqInfo->bytes_sent += 5;
|
|
||||||
}
|
}
|
||||||
else if(size < 1048576)
|
else if(size < 1048576)
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%4dK",size / 1024);
|
rprintf(reqInfo,"%4dK",size / 1024);
|
||||||
else
|
else
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%4dM",size / 1048576);
|
rprintf(reqInfo,"%4dM",size / 1048576);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -550,30 +558,28 @@ void output_directories(per_request *reqInfo, struct ent **ar,int n,char *name)
|
|||||||
name[0] = '/'; name[1] = '\0';
|
name[0] = '/'; name[1] = '\0';
|
||||||
}
|
}
|
||||||
/* aaaaargh Solaris sucks. */
|
/* aaaaargh Solaris sucks. */
|
||||||
fflush(reqInfo->out);
|
rflush(reqInfo);
|
||||||
|
|
||||||
if(dir_opts & FANCY_INDEXING) {
|
if(dir_opts & FANCY_INDEXING) {
|
||||||
fputs("<PRE>",reqInfo->out);
|
rputs("<PRE>",reqInfo);
|
||||||
(reqInfo->bytes_sent) += 5;
|
|
||||||
if((tp = find_icon(reqInfo,"^^BLANKICON^^",1)))
|
if((tp = find_icon(reqInfo,"^^BLANKICON^^",1)))
|
||||||
reqInfo->bytes_sent += (fprintf(reqInfo->out,
|
rprintf(reqInfo,"<IMG SRC=\"%s\" ALT=\" \"> ",tp);
|
||||||
"<IMG SRC=\"%s\" ALT=\" \"> ",tp));
|
rprintf(reqInfo,"Name ");
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"Name ");
|
|
||||||
if(!(dir_opts & SUPPRESS_LAST_MOD))
|
if(!(dir_opts & SUPPRESS_LAST_MOD))
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"Last modified ");
|
rprintf(reqInfo,"Last modified ");
|
||||||
if(!(dir_opts & SUPPRESS_SIZE))
|
if(!(dir_opts & SUPPRESS_SIZE))
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"Size ");
|
rprintf(reqInfo,"Size ");
|
||||||
if(!(dir_opts & SUPPRESS_DESC))
|
if(!(dir_opts & SUPPRESS_DESC))
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"Description");
|
rprintf(reqInfo,"Description");
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%c<HR>%c",LF,LF);
|
rprintf(reqInfo,"%c<HR>%c",LF,LF);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fputs("<UL>",reqInfo->out);
|
rputs("<UL>",reqInfo);
|
||||||
reqInfo->bytes_sent += 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(x=0;x<n;x++) {
|
for(x=0;x<n;x++) {
|
||||||
if((!strcmp(ar[x]->name,"../")) || (!strcmp(ar[x]->name,".."))) {
|
if((!strcmp(ar[x]->name,"../")) || (!strcmp(ar[x]->name,".."))) {
|
||||||
|
int i;
|
||||||
|
|
||||||
/* Fixes trailing slash for fancy indexing. Thanks Roy ? */
|
/* Fixes trailing slash for fancy indexing. Thanks Roy ? */
|
||||||
make_full_path(name,"../",t);
|
make_full_path(name,"../",t);
|
||||||
@ -581,6 +587,10 @@ void output_directories(per_request *reqInfo, struct ent **ar,int n,char *name)
|
|||||||
if(t[0] == '\0') {
|
if(t[0] == '\0') {
|
||||||
t[0] = '/'; t[1] = '\0';
|
t[0] = '/'; t[1] = '\0';
|
||||||
}
|
}
|
||||||
|
i = strlen(t);
|
||||||
|
if(t[i-1] != '/') {
|
||||||
|
t[i-1] = '/'; t[i] = '\0';
|
||||||
|
}
|
||||||
escape_uri(t);
|
escape_uri(t);
|
||||||
sprintf(anchor,"<A HREF=\"%s\">",t);
|
sprintf(anchor,"<A HREF=\"%s\">",t);
|
||||||
strcpy(t2,"Parent Directory</A>");
|
strcpy(t2,"Parent Directory</A>");
|
||||||
@ -602,59 +612,51 @@ void output_directories(per_request *reqInfo, struct ent **ar,int n,char *name)
|
|||||||
|
|
||||||
if(dir_opts & FANCY_INDEXING) {
|
if(dir_opts & FANCY_INDEXING) {
|
||||||
if(dir_opts & ICONS_ARE_LINKS)
|
if(dir_opts & ICONS_ARE_LINKS)
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%s",anchor);
|
rprintf(reqInfo,"%s",anchor);
|
||||||
if((ar[x]->icon) || reqInfo->hostInfo->default_icon[0]
|
if((ar[x]->icon) || reqInfo->hostInfo->default_icon[0]
|
||||||
|| local_default_icon[0]) {
|
|| local_default_icon[0]) {
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,
|
rprintf(reqInfo,"<IMG SRC=\"%s\" ALT=\"[%s]\">",
|
||||||
"<IMG SRC=\"%s\" ALT=\"[%s]\">",
|
ar[x]->icon ? ar[x]->icon :
|
||||||
ar[x]->icon ? ar[x]->icon :
|
local_default_icon[0] ?
|
||||||
local_default_icon[0] ?
|
local_default_icon :
|
||||||
local_default_icon :
|
reqInfo->hostInfo->default_icon,
|
||||||
reqInfo->hostInfo->default_icon,
|
ar[x]->alt ? ar[x]->alt : " ");
|
||||||
ar[x]->alt ? ar[x]->alt : " ");
|
|
||||||
}
|
}
|
||||||
if(dir_opts & ICONS_ARE_LINKS) {
|
if(dir_opts & ICONS_ARE_LINKS) {
|
||||||
fputs("</A>",reqInfo->out);
|
rputs("</A>",reqInfo);
|
||||||
reqInfo->bytes_sent += 4;
|
|
||||||
}
|
}
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out," %s",anchor);
|
rprintf(reqInfo," %s",anchor);
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%-27.27s",t2);
|
rprintf(reqInfo,"%-27.27s",t2);
|
||||||
if(!(dir_opts & SUPPRESS_LAST_MOD)) {
|
if(!(dir_opts & SUPPRESS_LAST_MOD)) {
|
||||||
if(ar[x]->lm != -1) {
|
if(ar[x]->lm != -1) {
|
||||||
struct tm *ts = localtime(&ar[x]->lm);
|
struct tm *ts = localtime(&ar[x]->lm);
|
||||||
strftime(t,MAX_STRING_LEN,"%d-%b-%y %H:%M ",ts);
|
strftime(t,MAX_STRING_LEN,"%d-%b-%y %H:%M ",ts);
|
||||||
fputs(t,reqInfo->out);
|
rputs(t,reqInfo);
|
||||||
reqInfo->bytes_sent += strlen(t);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fputs(" ",reqInfo->out);
|
rputs(" ",reqInfo);
|
||||||
reqInfo->bytes_sent += 17;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!(dir_opts & SUPPRESS_SIZE)) {
|
if(!(dir_opts & SUPPRESS_SIZE)) {
|
||||||
send_size(reqInfo,ar[x]->size);
|
send_size(reqInfo,ar[x]->size);
|
||||||
fputs(" ",reqInfo->out);
|
rputs(" ",reqInfo);
|
||||||
reqInfo->bytes_sent += 2;
|
|
||||||
}
|
}
|
||||||
if(!(dir_opts & SUPPRESS_DESC)) {
|
if(!(dir_opts & SUPPRESS_DESC)) {
|
||||||
if(ar[x]->desc) {
|
if(ar[x]->desc) {
|
||||||
terminate_description(ar[x]->desc);
|
terminate_description(ar[x]->desc);
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%s",ar[x]->desc);
|
rprintf(reqInfo,"%s",ar[x]->desc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"<LI> %s %s",anchor,t2);
|
rprintf(reqInfo,"<LI> %s %s",anchor,t2);
|
||||||
fputc(LF,reqInfo->out);
|
rputc(LF,reqInfo);
|
||||||
++(reqInfo->bytes_sent);
|
|
||||||
}
|
}
|
||||||
if(dir_opts & FANCY_INDEXING) {
|
if(dir_opts & FANCY_INDEXING) {
|
||||||
fputs("</PRE>",reqInfo->out);
|
rputs("</PRE>",reqInfo);
|
||||||
reqInfo->bytes_sent += 6;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fputs("</UL>",reqInfo->out);
|
rputs("</UL>",reqInfo);
|
||||||
reqInfo->bytes_sent += 5;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -678,12 +680,13 @@ void index_directory(per_request *reqInfo)
|
|||||||
if(!(d=Opendir(reqInfo->filename)))
|
if(!(d=Opendir(reqInfo->filename)))
|
||||||
die(reqInfo,SC_FORBIDDEN,reqInfo->url);
|
die(reqInfo,SC_FORBIDDEN,reqInfo->url);
|
||||||
|
|
||||||
strcpy(content_type,"text/html");
|
strcpy(reqInfo->outh_content_type,"text/html");
|
||||||
if(!no_headers)
|
if(reqInfo->http_version != P_HTTP_0_9)
|
||||||
send_http_header(reqInfo);
|
send_http_header(reqInfo);
|
||||||
|
|
||||||
if(header_only) {
|
if(reqInfo->method == M_HEAD) {
|
||||||
Closedir(d);
|
Closedir(d);
|
||||||
|
log_transaction(reqInfo);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -692,16 +695,13 @@ void index_directory(per_request *reqInfo)
|
|||||||
dir_opts = find_opts(reqInfo->filename);
|
dir_opts = find_opts(reqInfo->filename);
|
||||||
|
|
||||||
/* Spew HTML preamble */
|
/* Spew HTML preamble */
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,
|
rprintf(reqInfo,"<HEAD><TITLE>Index of %s</TITLE></HEAD><BODY>",
|
||||||
"<HEAD><TITLE>Index of %s</TITLE></HEAD><BODY>",
|
|
||||||
reqInfo->url);
|
reqInfo->url);
|
||||||
fputc(LF,reqInfo->out);
|
rputc(LF,reqInfo);
|
||||||
++(reqInfo->bytes_sent);
|
|
||||||
|
|
||||||
if((!(tmp = find_header(reqInfo, reqInfo->filename))) ||
|
if((!(tmp = find_header(reqInfo, reqInfo->filename))) ||
|
||||||
(!(insert_readme(reqInfo,reqInfo->filename,tmp,0))))
|
(!(insert_readme(reqInfo,reqInfo->filename,tmp,0))))
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,
|
rprintf(reqInfo, "<H1>Index of %s</H1>%c",reqInfo->url,LF);
|
||||||
"<H1>Index of %s</H1>%c",reqInfo->url,LF);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since we don't know how many dir. entries there are, put them into a
|
* Since we don't know how many dir. entries there are, put them into a
|
||||||
@ -750,13 +750,10 @@ void index_directory(per_request *reqInfo)
|
|||||||
if((tmp = find_readme(reqInfo,reqInfo->filename)))
|
if((tmp = find_readme(reqInfo,reqInfo->filename)))
|
||||||
insert_readme(reqInfo,reqInfo->filename,tmp,1);
|
insert_readme(reqInfo,reqInfo->filename,tmp,1);
|
||||||
else {
|
else {
|
||||||
fputs("</UL>",reqInfo->out);
|
rputs("</UL>",reqInfo);
|
||||||
reqInfo->bytes_sent += 5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fputs("</BODY>", reqInfo->out);
|
rputs("</BODY>", reqInfo);
|
||||||
fflush(reqInfo->out);
|
rflush(reqInfo);
|
||||||
reqInfo->bytes_sent += 7;
|
|
||||||
fflush(reqInfo->out);
|
|
||||||
log_transaction(reqInfo);
|
log_transaction(reqInfo);
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* http_include.c,v 1.41 1995/11/28 09:02:02 blong Exp
|
* http_include.c,v 1.50 1996/03/27 20:44:02 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
@ -18,9 +18,6 @@
|
|||||||
*
|
*
|
||||||
* Based on NCSA HTTPd 1.3 by Rob McCool
|
* Based on NCSA HTTPd 1.3 by Rob McCool
|
||||||
*
|
*
|
||||||
* 04-07-95 blong
|
|
||||||
* Fixes bug where substrings of the environment variable might be
|
|
||||||
* included first as suggested by David Robinson (drtr@ast.cam.ac.uk)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -41,6 +38,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "fdwrap.h"
|
#include "fdwrap.h"
|
||||||
|
#include "allocate.h"
|
||||||
#include "http_include.h"
|
#include "http_include.h"
|
||||||
#include "http_mime.h"
|
#include "http_mime.h"
|
||||||
#include "http_log.h"
|
#include "http_log.h"
|
||||||
@ -62,8 +60,10 @@ static time_t date,lm;
|
|||||||
int add_include_vars(per_request *reqInfo, char *timefmt)
|
int add_include_vars(per_request *reqInfo, char *timefmt)
|
||||||
{
|
{
|
||||||
struct stat finfo;
|
struct stat finfo;
|
||||||
char uri[HUGE_STRING_LEN];
|
char *uri;
|
||||||
char *t;
|
char *str;
|
||||||
|
|
||||||
|
uri = newString(HUGE_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
date = time(NULL);
|
date = time(NULL);
|
||||||
make_env_str(reqInfo,"DATE_LOCAL",ht_time(date,timefmt,0));
|
make_env_str(reqInfo,"DATE_LOCAL",ht_time(date,timefmt,0));
|
||||||
@ -73,23 +73,24 @@ int add_include_vars(per_request *reqInfo, char *timefmt)
|
|||||||
lm = finfo.st_mtime;
|
lm = finfo.st_mtime;
|
||||||
make_env_str(reqInfo,"LAST_MODIFIED",ht_time(lm,timefmt,0));
|
make_env_str(reqInfo,"LAST_MODIFIED",ht_time(lm,timefmt,0));
|
||||||
}
|
}
|
||||||
if((t = strrchr(reqInfo->filename,'/')))
|
if((str = strrchr(reqInfo->filename,'/')))
|
||||||
++t;
|
++str;
|
||||||
else
|
else
|
||||||
t = reqInfo->url;
|
str = reqInfo->url;
|
||||||
make_env_str(reqInfo,"DOCUMENT_NAME",t);
|
make_env_str(reqInfo,"DOCUMENT_NAME",str);
|
||||||
|
|
||||||
/* Jump through hoops because <=1.4 set DOCUMENT_URI to
|
/* Jump through hoops because <=1.4 set DOCUMENT_URI to
|
||||||
include index file name */
|
include index file name */
|
||||||
if (reqInfo->url[strlen(reqInfo->url)-1] == '/' ){
|
if (reqInfo->url[strlen(reqInfo->url)-1] == '/' ){
|
||||||
strncpy(uri,reqInfo->url,HUGE_STRING_LEN);
|
strncpy(uri,reqInfo->url,HUGE_STRING_LEN);
|
||||||
strncat(uri,t,HUGE_STRING_LEN-strlen(uri));
|
strncat(uri,str,HUGE_STRING_LEN-strlen(uri));
|
||||||
make_env_str(reqInfo,"DOCUMENT_URI",uri);
|
make_env_str(reqInfo,"DOCUMENT_URI",uri);
|
||||||
} else {
|
} else {
|
||||||
make_env_str(reqInfo,"DOCUMENT_URI",reqInfo->url);
|
make_env_str(reqInfo,"DOCUMENT_URI",reqInfo->url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
freeString(uri);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,12 +120,10 @@ int find_string(per_request *reqInfo, FILE *fp, char *str) {
|
|||||||
if(reqInfo->out) {
|
if(reqInfo->out) {
|
||||||
if(p) {
|
if(p) {
|
||||||
for(x=0;x<p;x++) {
|
for(x=0;x<p;x++) {
|
||||||
putc(str[x],reqInfo->out);
|
rputc(str[x],reqInfo);
|
||||||
++(reqInfo->bytes_sent);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
putc(c,reqInfo->out);
|
rputc(c,reqInfo);
|
||||||
++(reqInfo->bytes_sent);
|
|
||||||
}
|
}
|
||||||
p=0;
|
p=0;
|
||||||
}
|
}
|
||||||
@ -211,9 +210,6 @@ int get_directive(FILE *fp, char *d) {
|
|||||||
/* --------------------------- Action handlers ---------------------------- */
|
/* --------------------------- Action handlers ---------------------------- */
|
||||||
|
|
||||||
|
|
||||||
void send_parsed_content(per_request *reqInfo, FILE *f, char *path_args,
|
|
||||||
int noexec);
|
|
||||||
|
|
||||||
int send_included_file(per_request *reqInfo, char *fn)
|
int send_included_file(per_request *reqInfo, char *fn)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
@ -227,13 +223,14 @@ int send_included_file(per_request *reqInfo, char *fn)
|
|||||||
if(!allow)
|
if(!allow)
|
||||||
return -1;
|
return -1;
|
||||||
set_content_type(reqInfo,reqInfo->filename);
|
set_content_type(reqInfo,reqInfo->filename);
|
||||||
if((op & OPT_INCLUDES) && (!strcmp(content_type,INCLUDES_MAGIC_TYPE))) {
|
if((op & OPT_INCLUDES) &&
|
||||||
|
(!strcmp(reqInfo->outh_content_type,INCLUDES_MAGIC_TYPE))) {
|
||||||
if(!(fp = FOpen(reqInfo->filename,"r")))
|
if(!(fp = FOpen(reqInfo->filename,"r")))
|
||||||
return -1;
|
return -1;
|
||||||
send_parsed_content(reqInfo,fp,"",op & OPT_INCNOEXEC);
|
send_parsed_content(reqInfo,fp,op & OPT_INCNOEXEC);
|
||||||
chdir_file(fn); /* grumble */
|
chdir_file(fn); /* grumble */
|
||||||
}
|
}
|
||||||
else if(!strcmp(content_type,CGI_MAGIC_TYPE))
|
else if(!strcmp(reqInfo->outh_content_type,CGI_MAGIC_TYPE))
|
||||||
return -1;
|
return -1;
|
||||||
else {
|
else {
|
||||||
if(!(fp=FOpen(reqInfo->filename,"r")))
|
if(!(fp=FOpen(reqInfo->filename,"r")))
|
||||||
@ -245,20 +242,30 @@ int send_included_file(per_request *reqInfo, char *fn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int handle_include(per_request *reqInfo, FILE *fp, char *error) {
|
int handle_include(per_request *reqInfo, FILE *fp, char *error) {
|
||||||
char tag[MAX_STRING_LEN],errstr[MAX_STRING_LEN];
|
char *tag,*errstr;
|
||||||
char *tag_val;
|
char *tag_val;
|
||||||
|
|
||||||
|
tag = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
errstr = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if(!(tag_val = get_tag(fp,tag)))
|
if(!(tag_val = get_tag(fp,tag))) {
|
||||||
|
freeString(tag);
|
||||||
|
freeString(errstr);
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
if(!strcmp(tag,"file")) {
|
if(!strcmp(tag,"file")) {
|
||||||
char dir[MAX_STRING_LEN],to_send[MAX_STRING_LEN];
|
char *dir,*to_send;
|
||||||
per_request *newInfo;
|
per_request *newInfo;
|
||||||
|
|
||||||
|
dir = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
to_send = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
getparents(tag_val); /* get rid of any nasties */
|
getparents(tag_val); /* get rid of any nasties */
|
||||||
getwd(dir);
|
getcwd(dir,MAX_STRING_LEN);
|
||||||
make_full_path(dir,tag_val,to_send);
|
make_full_path(dir,tag_val,to_send);
|
||||||
newInfo = continue_request(reqInfo,NEW_URL | KEEP_ENV);
|
newInfo = continue_request(reqInfo, KEEP_ENV | KEEP_AUTH);
|
||||||
|
newInfo->http_version = P_HTTP_0_9;
|
||||||
strcpy(newInfo->url,tag_val);
|
strcpy(newInfo->url,tag_val);
|
||||||
strcpy(newInfo->args,reqInfo->args);
|
strcpy(newInfo->args,reqInfo->args);
|
||||||
strcpy(newInfo->filename,to_send);
|
strcpy(newInfo->filename,to_send);
|
||||||
@ -266,18 +273,21 @@ int handle_include(per_request *reqInfo, FILE *fp, char *error) {
|
|||||||
sprintf(errstr,"unable to include %s in parsed file %s",
|
sprintf(errstr,"unable to include %s in parsed file %s",
|
||||||
newInfo->filename,reqInfo->filename );
|
newInfo->filename,reqInfo->filename );
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%s",error);
|
rprintf(reqInfo,"%s",error);
|
||||||
}
|
}
|
||||||
reqInfo->bytes_sent += newInfo->bytes_sent;
|
reqInfo->bytes_sent += newInfo->bytes_sent;
|
||||||
free_request(newInfo,ONLY_LAST);
|
free_request(newInfo,ONLY_LAST);
|
||||||
|
freeString(dir);
|
||||||
|
freeString(to_send);
|
||||||
}
|
}
|
||||||
else if(!strcmp(tag,"virtual")) {
|
else if(!strcmp(tag,"virtual")) {
|
||||||
per_request *newInfo;
|
per_request *newInfo;
|
||||||
newInfo = continue_request(reqInfo, NEW_URL | KEEP_ENV);
|
newInfo = continue_request(reqInfo, KEEP_ENV | KEEP_AUTH);
|
||||||
|
newInfo->http_version = P_HTTP_0_9;
|
||||||
strcpy(newInfo->url,tag_val);
|
strcpy(newInfo->url,tag_val);
|
||||||
if(translate_name(newInfo,newInfo->url,newInfo->filename)
|
if(translate_name(newInfo,newInfo->url,newInfo->filename)
|
||||||
!= A_STD_DOCUMENT) {
|
!= A_STD_DOCUMENT) {
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%s",error);
|
rprintf(reqInfo,"%s",error);
|
||||||
sprintf(errstr,"unable to include %s in parsed file %s, non standard document",newInfo->filename, reqInfo->filename);
|
sprintf(errstr,"unable to include %s in parsed file %s, non standard document",newInfo->filename, reqInfo->filename);
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
} else {
|
} else {
|
||||||
@ -285,19 +295,22 @@ int handle_include(per_request *reqInfo, FILE *fp, char *error) {
|
|||||||
sprintf(errstr,"unable to include %s in parsed file %s",
|
sprintf(errstr,"unable to include %s in parsed file %s",
|
||||||
newInfo->filename, reqInfo->filename);
|
newInfo->filename, reqInfo->filename);
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%s",error);
|
rprintf(reqInfo,"%s",error);
|
||||||
}
|
}
|
||||||
reqInfo->bytes_sent += newInfo->bytes_sent;
|
reqInfo->bytes_sent += newInfo->bytes_sent;
|
||||||
}
|
}
|
||||||
free_request(newInfo,ONLY_LAST);
|
free_request(newInfo,ONLY_LAST);
|
||||||
}
|
}
|
||||||
else if(!strcmp(tag,"done"))
|
else if(!strcmp(tag,"done")) {
|
||||||
|
freeString(tag);
|
||||||
|
freeString(errstr);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
sprintf(errstr,"unknown parameter %s to tag echo in %s",tag,
|
sprintf(errstr,"unknown parameter %s to tag echo in %s",tag,
|
||||||
reqInfo->filename);
|
reqInfo->filename);
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%s",error);
|
rprintf(reqInfo,"%s",error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -305,23 +318,22 @@ int handle_include(per_request *reqInfo, FILE *fp, char *error) {
|
|||||||
#ifndef NO_YOW
|
#ifndef NO_YOW
|
||||||
#include "httpy.h"
|
#include "httpy.h"
|
||||||
|
|
||||||
int print_yow(per_request *reqInfo, int yow_num) {
|
void print_yow(per_request *reqInfo, int yow_num) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int href_on = FALSE;
|
int href_on = FALSE;
|
||||||
int tmp;
|
int tmp;
|
||||||
|
|
||||||
if (yow_num >= MAX_YOW) yow_num = MAX_YOW-1;
|
if (yow_num >= MAX_YOW) yow_num = MAX_YOW-1;
|
||||||
while (yow_lines[yow_num][i]) {
|
while (yow_lines[yow_num][i]) {
|
||||||
putc(yow_lines[yow_num][i],reqInfo->out);
|
rputc(yow_lines[yow_num][i],reqInfo);
|
||||||
if (yow_lines[yow_num][i] == ' ') {
|
if (yow_lines[yow_num][i] == ' ') {
|
||||||
tmp = href_on;
|
tmp = href_on;
|
||||||
href_on = (rand() % 100 < 50) ? 1 : 0;
|
href_on = (rand() % 100 < 50) ? 1 : 0;
|
||||||
if (tmp != href_on) {
|
if (tmp != href_on) {
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"<A HREF=\"%s\">",
|
rprintf(reqInfo,"<A HREF=\"%s\">", reqInfo->url);
|
||||||
reqInfo->url);
|
|
||||||
else
|
else
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"</A>");
|
rprintf(reqInfo,"</A>");
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
while ((yow_lines[yow_num][i] == ' ') && yow_lines[yow_num][i++]);
|
while ((yow_lines[yow_num][i] == ' ') && yow_lines[yow_num][i++]);
|
||||||
@ -332,19 +344,23 @@ int print_yow(per_request *reqInfo, int yow_num) {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (href_on) {
|
if (href_on) {
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"</A>");
|
rprintf(reqInfo,"</A>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* NO_YOW */
|
#endif /* NO_YOW */
|
||||||
|
|
||||||
int handle_echo(per_request *reqInfo, FILE *fp, char *error) {
|
int handle_echo(per_request *reqInfo, FILE *fp, char *error) {
|
||||||
char tag[MAX_STRING_LEN];
|
char *tag;
|
||||||
char *tag_val;
|
char *tag_val;
|
||||||
|
|
||||||
|
tag = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if(!(tag_val = get_tag(fp,tag)))
|
if(!(tag_val = get_tag(fp,tag))) {
|
||||||
|
freeString(tag);
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
if(!strcmp(tag,"var")) {
|
if(!strcmp(tag,"var")) {
|
||||||
int x,i,len;
|
int x,i,len;
|
||||||
|
|
||||||
@ -352,13 +368,12 @@ int handle_echo(per_request *reqInfo, FILE *fp, char *error) {
|
|||||||
for(x=0;reqInfo->env[x] != NULL; x++) {
|
for(x=0;reqInfo->env[x] != NULL; x++) {
|
||||||
i = ind(reqInfo->env[x],'=');
|
i = ind(reqInfo->env[x],'=');
|
||||||
if((i == len) && !(strncmp(reqInfo->env[x],tag_val,i))) {
|
if((i == len) && !(strncmp(reqInfo->env[x],tag_val,i))) {
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%s",
|
rprintf(reqInfo,"%s",&(reqInfo->env[x][i+1]));
|
||||||
&(reqInfo->env[x][i+1]));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!(reqInfo->env[x]))
|
if(!(reqInfo->env[x]))
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"(none)");
|
rprintf(reqInfo,"(none)");
|
||||||
}
|
}
|
||||||
#ifndef NO_YOW
|
#ifndef NO_YOW
|
||||||
else if(!strcmp(tag,"yow")) {
|
else if(!strcmp(tag,"yow")) {
|
||||||
@ -366,19 +381,26 @@ int handle_echo(per_request *reqInfo, FILE *fp, char *error) {
|
|||||||
print_yow(reqInfo,num);
|
print_yow(reqInfo,num);
|
||||||
}
|
}
|
||||||
#endif /* NO_YOW */
|
#endif /* NO_YOW */
|
||||||
else if(!strcmp(tag,"done"))
|
else if(!strcmp(tag,"done")) {
|
||||||
|
freeString(tag);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
char errstr[MAX_STRING_LEN];
|
char *errstr;
|
||||||
|
|
||||||
|
errstr = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
sprintf(errstr,"unknown parameter %s to tag echo in %s",tag,
|
sprintf(errstr,"unknown parameter %s to tag echo in %s",tag,
|
||||||
reqInfo->filename);
|
reqInfo->filename);
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%s",error);
|
rprintf(reqInfo,"%s",error);
|
||||||
|
|
||||||
|
freeString(errstr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int include_cgi(per_request *reqInfo, char *pargs) {
|
int include_cgi(per_request *reqInfo) {
|
||||||
char op;
|
char op;
|
||||||
int allow,check_cgiopt;
|
int allow,check_cgiopt;
|
||||||
struct stat finfo;
|
struct stat finfo;
|
||||||
@ -390,10 +412,12 @@ int include_cgi(per_request *reqInfo, char *pargs) {
|
|||||||
return -1;
|
return -1;
|
||||||
check_cgiopt=0;
|
check_cgiopt=0;
|
||||||
} else {
|
} else {
|
||||||
char dir[MAX_STRING_LEN];
|
char *dir;
|
||||||
getwd(dir);
|
dir = newString(MAX_STRING_LEN, STR_TMP);
|
||||||
|
getcwd(dir,MAX_STRING_LEN);
|
||||||
make_full_path(dir,reqInfo->url,reqInfo->filename);
|
make_full_path(dir,reqInfo->url,reqInfo->filename);
|
||||||
check_cgiopt=1;
|
check_cgiopt=1;
|
||||||
|
freeString(dir);
|
||||||
}
|
}
|
||||||
/* No hardwired path info or query allowed */
|
/* No hardwired path info or query allowed */
|
||||||
if(stat(reqInfo->filename,&finfo) == -1)
|
if(stat(reqInfo->filename,&finfo) == -1)
|
||||||
@ -404,43 +428,51 @@ int include_cgi(per_request *reqInfo, char *pargs) {
|
|||||||
if((!allow) || (check_cgiopt && (!(op & OPT_EXECCGI))))
|
if((!allow) || (check_cgiopt && (!(op & OPT_EXECCGI))))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if(cgi_stub(reqInfo,pargs,&finfo) == SC_REDIRECT_TEMP)
|
if(cgi_stub(reqInfo,&finfo,op) == SC_REDIRECT_TEMP)
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,
|
rprintf(reqInfo, "<A HREF=\"%s\">%s</A>",reqInfo->outh_location,
|
||||||
"<A HREF=\"%s\">%s</A>",location,location);
|
reqInfo->outh_location);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ipid;
|
static int ipid;
|
||||||
void kill_include_child(void) {
|
void kill_include_child(void) {
|
||||||
char errstr[MAX_STRING_LEN];
|
char *errstr;
|
||||||
|
|
||||||
|
errstr = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
sprintf(errstr,"killing command process %d",ipid);
|
sprintf(errstr,"killing command process %d",ipid);
|
||||||
log_error(errstr,gCurrentRequest->hostInfo->error_log);
|
log_error(errstr,gCurrentRequest->hostInfo->error_log);
|
||||||
kill(ipid,SIGKILL);
|
kill(ipid,SIGKILL);
|
||||||
waitpid(ipid,NULL,0);
|
waitpid(ipid,NULL,0);
|
||||||
|
|
||||||
|
freeString(errstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int include_cmd(per_request *reqInfo, char *s, char *pargs) {
|
int include_cmd(per_request *reqInfo, char *s) {
|
||||||
int p[2];
|
int p[2];
|
||||||
FILE *fp;
|
|
||||||
|
|
||||||
if(Pipe(p) == -1)
|
if(Pipe(p) == -1)
|
||||||
die(reqInfo,SC_SERVER_ERROR,"httpd: could not create IPC pipe");
|
die(reqInfo,SC_SERVER_ERROR,"HTTPd: could not create IPC pipe");
|
||||||
if((ipid = fork()) == -1) {
|
if((ipid = fork()) == -1) {
|
||||||
Close(p[0]);
|
Close(p[0]);
|
||||||
Close(p[1]);
|
Close(p[1]);
|
||||||
die(reqInfo,SC_SERVER_ERROR,"httpd: could not fork new process");
|
die(reqInfo,SC_SERVER_ERROR,"HTTPd: could not fork new process");
|
||||||
}
|
}
|
||||||
if(!ipid) {
|
if(!ipid) {
|
||||||
char *argv0;
|
char *argv0;
|
||||||
|
|
||||||
if(pargs[0] || reqInfo->args[0]) {
|
if(reqInfo->path_info[0] || reqInfo->args[0]) {
|
||||||
if(pargs[0]) {
|
if(reqInfo->path_info[0]) {
|
||||||
char p2[HUGE_STRING_LEN];
|
char *p2;
|
||||||
|
|
||||||
escape_shell_cmd(pargs);
|
p2 = newString(HUGE_STRING_LEN,STR_TMP);
|
||||||
make_env_str(reqInfo,"PATH_INFO",pargs);
|
|
||||||
translate_name(reqInfo,pargs,p2);
|
escape_shell_cmd(reqInfo->path_info);
|
||||||
|
make_env_str(reqInfo,"PATH_INFO",reqInfo->path_info);
|
||||||
|
translate_name(reqInfo,reqInfo->path_info,p2);
|
||||||
make_env_str(reqInfo,"PATH_TRANSLATED",p2);
|
make_env_str(reqInfo,"PATH_TRANSLATED",p2);
|
||||||
|
|
||||||
|
freeString(p2);
|
||||||
}
|
}
|
||||||
if(reqInfo->args[0]) {
|
if(reqInfo->args[0]) {
|
||||||
make_env_str(reqInfo,"QUERY_STRING",reqInfo->args);
|
make_env_str(reqInfo,"QUERY_STRING",reqInfo->args);
|
||||||
@ -455,72 +487,76 @@ int include_cmd(per_request *reqInfo, char *s, char *pargs) {
|
|||||||
dup2(p[1],STDOUT_FILENO);
|
dup2(p[1],STDOUT_FILENO);
|
||||||
Close(p[1]);
|
Close(p[1]);
|
||||||
}
|
}
|
||||||
|
close(reqInfo->in);
|
||||||
close(reqInfo->connection_socket);
|
close(reqInfo->connection_socket);
|
||||||
error_log2stderr(reqInfo->hostInfo->error_log);
|
error_log2stderr(reqInfo->hostInfo->error_log);
|
||||||
if(!(argv0 = strrchr(SHELL_PATH,'/')))
|
if(!(argv0 = strrchr(SHELL_PATH,'/')))
|
||||||
argv0=SHELL_PATH;
|
argv0=SHELL_PATH;
|
||||||
if(execle(SHELL_PATH,argv0,"-c",s,(char *)0,reqInfo->env) == -1) {
|
if(execle(SHELL_PATH,argv0,"-c",s,(char *)0,reqInfo->env) == -1) {
|
||||||
fprintf(stderr,"httpd: exec of %s failed, errno is %d\n",
|
fprintf(stderr,"HTTPd: exec of %s failed, errno is %d\n",
|
||||||
SHELL_PATH,errno);
|
SHELL_PATH,errno);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Close(p[1]);
|
Close(p[1]);
|
||||||
/* if(!(fp=FdOpen(p[0],"r"))) {
|
|
||||||
waitpid(ipid,NULL,0);
|
|
||||||
return -1;
|
|
||||||
} */
|
|
||||||
send_fd(reqInfo,p[0],kill_include_child);
|
send_fd(reqInfo,p[0],kill_include_child);
|
||||||
/* FClose(fp); */
|
|
||||||
Close(p[0]);
|
Close(p[0]);
|
||||||
waitpid(ipid,NULL,0);
|
waitpid(ipid,NULL,0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int handle_exec(per_request *reqInfo, FILE *fp, char *path_args,
|
int handle_exec(per_request *reqInfo, FILE *fp, char *error)
|
||||||
char *error)
|
|
||||||
{
|
{
|
||||||
char tag[MAX_STRING_LEN],errstr[MAX_STRING_LEN];
|
char *tag,*errstr;
|
||||||
char *tag_val;
|
char *tag_val;
|
||||||
|
|
||||||
|
tag = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
errstr = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if(!(tag_val = get_tag(fp,tag)))
|
if(!(tag_val = get_tag(fp,tag))) {
|
||||||
|
freeString(tag);
|
||||||
|
freeString(errstr);
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
if(!strcmp(tag,"cmd")) {
|
if(!strcmp(tag,"cmd")) {
|
||||||
if(include_cmd(reqInfo,tag_val,path_args) == -1) {
|
if(include_cmd(reqInfo,tag_val) == -1) {
|
||||||
sprintf(errstr,"invalid command exec %s in %s",tag_val,
|
sprintf(errstr,"invalid command exec %s in %s",tag_val,
|
||||||
reqInfo->filename);
|
reqInfo->filename);
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%s",error);
|
rprintf(reqInfo,"%s",error);
|
||||||
}
|
}
|
||||||
/* just in case some stooge changed directories */
|
/* just in case some stooge changed directories */
|
||||||
chdir_file(reqInfo->filename);
|
chdir_file(reqInfo->filename);
|
||||||
}
|
}
|
||||||
else if(!strcmp(tag,"cgi")) {
|
else if(!strcmp(tag,"cgi")) {
|
||||||
per_request *newInfo;
|
per_request *newInfo;
|
||||||
newInfo = continue_request(reqInfo,NEW_URL | KEEP_ENV);
|
newInfo = continue_request(reqInfo, KEEP_ENV | KEEP_AUTH);
|
||||||
|
newInfo->http_version = P_HTTP_0_9;
|
||||||
strcpy(newInfo->url,tag_val);
|
strcpy(newInfo->url,tag_val);
|
||||||
|
|
||||||
if(include_cgi(newInfo,path_args) == -1) {
|
if(include_cgi(newInfo) == -1) {
|
||||||
sprintf(errstr,"invalid CGI ref %s in %s",newInfo->filename,
|
sprintf(errstr,"invalid CGI ref %s in %s",newInfo->filename,
|
||||||
reqInfo->filename);
|
reqInfo->filename);
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%s",error);
|
rprintf(reqInfo,"%s",error);
|
||||||
}
|
}
|
||||||
reqInfo->bytes_sent += newInfo->bytes_sent;
|
reqInfo->bytes_sent += newInfo->bytes_sent;
|
||||||
free_request(newInfo,ONLY_LAST);
|
free_request(newInfo,ONLY_LAST);
|
||||||
/* grumble groan */
|
/* grumble groan */
|
||||||
chdir_file(reqInfo->filename);
|
chdir_file(reqInfo->filename);
|
||||||
}
|
}
|
||||||
else if(!strcmp(tag,"done"))
|
else if(!strcmp(tag,"done")) {
|
||||||
|
freeString(errstr);
|
||||||
|
freeString(tag);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
char errstr[MAX_STRING_LEN];
|
|
||||||
sprintf(errstr,"unknown parameter %s to tag echo in %s",tag,
|
sprintf(errstr,"unknown parameter %s to tag echo in %s",tag,
|
||||||
reqInfo->filename);
|
reqInfo->filename);
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%s",error);
|
rprintf(reqInfo,"%s",error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,12 +564,16 @@ int handle_exec(per_request *reqInfo, FILE *fp, char *path_args,
|
|||||||
|
|
||||||
int handle_config(per_request *reqInfo, FILE *fp, char *error,
|
int handle_config(per_request *reqInfo, FILE *fp, char *error,
|
||||||
char *tf, int *sizefmt) {
|
char *tf, int *sizefmt) {
|
||||||
char tag[MAX_STRING_LEN];
|
char *tag;
|
||||||
char *tag_val;
|
char *tag_val;
|
||||||
|
|
||||||
|
tag = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if(!(tag_val = get_tag(fp,tag)))
|
if(!(tag_val = get_tag(fp,tag))) {
|
||||||
|
freeString(tag);
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
if(!strcmp(tag,"errmsg"))
|
if(!strcmp(tag,"errmsg"))
|
||||||
strcpy(error,tag_val);
|
strcpy(error,tag_val);
|
||||||
else if(!strcmp(tag,"timefmt")) {
|
else if(!strcmp(tag,"timefmt")) {
|
||||||
@ -548,24 +588,33 @@ int handle_config(per_request *reqInfo, FILE *fp, char *error,
|
|||||||
*sizefmt = SIZEFMT_BYTES;
|
*sizefmt = SIZEFMT_BYTES;
|
||||||
else if(!strcmp(tag_val,"abbrev"))
|
else if(!strcmp(tag_val,"abbrev"))
|
||||||
*sizefmt = SIZEFMT_KMG;
|
*sizefmt = SIZEFMT_KMG;
|
||||||
}
|
}
|
||||||
else if(!strcmp(tag,"done"))
|
else if(!strcmp(tag,"done")) {
|
||||||
|
freeString(tag);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
char errstr[MAX_STRING_LEN];
|
char *errstr;
|
||||||
|
|
||||||
|
errstr = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
sprintf(errstr,"unknown parameter %s to tag config in %s",
|
sprintf(errstr,"unknown parameter %s to tag config in %s",
|
||||||
tag, reqInfo->filename);
|
tag, reqInfo->filename);
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%s",error);
|
rprintf(reqInfo,"%s",error);
|
||||||
|
|
||||||
|
freeString(errstr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_YOW
|
#ifndef NO_YOW
|
||||||
int handle_yow(per_request *reqInfo, FILE *fp, char *error) {
|
int handle_yow(per_request *reqInfo, FILE *fp, char *error) {
|
||||||
char tag[MAX_STRING_LEN];
|
char *tag;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
|
tag = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
srand((int) (getpid() + time((long *) 0)));
|
srand((int) (getpid() + time((long *) 0)));
|
||||||
GET_CHAR(fp,c,1);
|
GET_CHAR(fp,c,1);
|
||||||
if (c == ENDING_SEQUENCE[0]) {
|
if (c == ENDING_SEQUENCE[0]) {
|
||||||
@ -574,10 +623,20 @@ int handle_yow(per_request *reqInfo, FILE *fp, char *error) {
|
|||||||
GET_CHAR(fp,c,1);
|
GET_CHAR(fp,c,1);
|
||||||
if (c == ENDING_SEQUENCE[2]) {
|
if (c == ENDING_SEQUENCE[2]) {
|
||||||
print_yow(reqInfo,rand() % MAX_YOW);
|
print_yow(reqInfo,rand() % MAX_YOW);
|
||||||
|
freeString(tag);
|
||||||
return 0;
|
return 0;
|
||||||
} else return 1;
|
} else {
|
||||||
} else return 1;
|
freeString(tag);
|
||||||
} else return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
freeString(tag);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
freeString(tag);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif /* NO_YOW */
|
#endif /* NO_YOW */
|
||||||
|
|
||||||
@ -586,30 +645,41 @@ int handle_yow(per_request *reqInfo, FILE *fp, char *error) {
|
|||||||
int find_file(per_request *reqInfo, char *directive, char *tag,
|
int find_file(per_request *reqInfo, char *directive, char *tag,
|
||||||
char *tag_val, struct stat *finfo, char *error)
|
char *tag_val, struct stat *finfo, char *error)
|
||||||
{
|
{
|
||||||
char errstr[MAX_STRING_LEN], dir[MAX_STRING_LEN], to_send[MAX_STRING_LEN];
|
char *errstr, *dir, *to_send;
|
||||||
|
|
||||||
|
errstr = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
dir = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
to_send = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
if(!strcmp(tag,"file")) {
|
if(!strcmp(tag,"file")) {
|
||||||
getparents(tag_val); /* get rid of any nasties */
|
getparents(tag_val); /* get rid of any nasties */
|
||||||
getwd(dir);
|
getcwd(dir,MAX_STRING_LEN);
|
||||||
make_full_path(dir,tag_val,to_send);
|
make_full_path(dir,tag_val,to_send);
|
||||||
if(stat(to_send,finfo) == -1) {
|
if(stat(to_send,finfo) == -1) {
|
||||||
sprintf(errstr,
|
sprintf(errstr,
|
||||||
"unable to get information about %s in parsed file %s",
|
"unable to get information about %s in parsed file %s",
|
||||||
to_send,reqInfo->filename);
|
to_send,reqInfo->filename);
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%s",error);
|
rprintf(reqInfo,"%s",error);
|
||||||
|
freeString(errstr);
|
||||||
|
freeString(dir);
|
||||||
|
freeString(to_send);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
freeString(errstr);
|
||||||
|
freeString(dir);
|
||||||
|
freeString(to_send);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if(!strcmp(tag,"virtual")) {
|
else if(!strcmp(tag,"virtual")) {
|
||||||
per_request *newInfo;
|
per_request *newInfo;
|
||||||
newInfo = continue_request(reqInfo,NEW_URL | KEEP_ENV);
|
newInfo = continue_request(reqInfo, KEEP_ENV | KEEP_AUTH);
|
||||||
|
newInfo->http_version = P_HTTP_0_9;
|
||||||
strcpy(newInfo->url,tag_val);
|
strcpy(newInfo->url,tag_val);
|
||||||
if(translate_name(newInfo,newInfo->url,newInfo->filename)
|
if(translate_name(newInfo,newInfo->url,newInfo->filename)
|
||||||
!= A_STD_DOCUMENT) {
|
!= A_STD_DOCUMENT) {
|
||||||
sprintf(errstr,"unable to get information about non standard file %s in parsed file %s",newInfo->filename,reqInfo->filename);
|
sprintf(errstr,"unable to get information about non standard file %s in parsed file %s",newInfo->filename,reqInfo->filename);
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%s",error);
|
rprintf(reqInfo,"%s",error);
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
}
|
}
|
||||||
else if(stat(newInfo->filename,finfo) == -1) {
|
else if(stat(newInfo->filename,finfo) == -1) {
|
||||||
@ -617,18 +687,27 @@ int find_file(per_request *reqInfo, char *directive, char *tag,
|
|||||||
"unable to get information about %s in parsed file %s",
|
"unable to get information about %s in parsed file %s",
|
||||||
newInfo->filename,reqInfo->filename);
|
newInfo->filename,reqInfo->filename);
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%s",error);
|
rprintf(reqInfo,"%s",error);
|
||||||
free_request(newInfo,ONLY_LAST);
|
free_request(newInfo,ONLY_LAST);
|
||||||
|
freeString(errstr);
|
||||||
|
freeString(dir);
|
||||||
|
freeString(to_send);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
free_request(newInfo,ONLY_LAST);
|
free_request(newInfo,ONLY_LAST);
|
||||||
|
freeString(errstr);
|
||||||
|
freeString(dir);
|
||||||
|
freeString(to_send);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sprintf(errstr,"unknown parameter %s to tag %s in %s",
|
sprintf(errstr,"unknown parameter %s to tag %s in %s",
|
||||||
tag,directive,reqInfo->filename);
|
tag,directive,reqInfo->filename);
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%s",error);
|
rprintf(reqInfo,"%s",error);
|
||||||
|
freeString(errstr);
|
||||||
|
freeString(dir);
|
||||||
|
freeString(to_send);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -636,15 +715,21 @@ int find_file(per_request *reqInfo, char *directive, char *tag,
|
|||||||
|
|
||||||
int handle_fsize(per_request *reqInfo, FILE *fp, char *error, int sizefmt)
|
int handle_fsize(per_request *reqInfo, FILE *fp, char *error, int sizefmt)
|
||||||
{
|
{
|
||||||
char tag[MAX_STRING_LEN];
|
char *tag;
|
||||||
char *tag_val;
|
char *tag_val;
|
||||||
struct stat finfo;
|
struct stat finfo;
|
||||||
|
|
||||||
|
tag = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if(!(tag_val = get_tag(fp,tag)))
|
if(!(tag_val = get_tag(fp,tag))) {
|
||||||
|
freeString(tag);
|
||||||
return 1;
|
return 1;
|
||||||
else if(!strcmp(tag,"done"))
|
}
|
||||||
|
else if(!strcmp(tag,"done")) {
|
||||||
|
freeString(tag);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
else if(!find_file(reqInfo,"fsize",tag,tag_val,&finfo,error)) {
|
else if(!find_file(reqInfo,"fsize",tag,tag_val,&finfo,error)) {
|
||||||
if(sizefmt == SIZEFMT_KMG) {
|
if(sizefmt == SIZEFMT_KMG) {
|
||||||
send_size(reqInfo,finfo.st_size);
|
send_size(reqInfo,finfo.st_size);
|
||||||
@ -656,11 +741,9 @@ int handle_fsize(per_request *reqInfo, FILE *fp, char *error, int sizefmt)
|
|||||||
l = strlen(tag); /* grrr */
|
l = strlen(tag); /* grrr */
|
||||||
for(x=0;x<l;x++) {
|
for(x=0;x<l;x++) {
|
||||||
if(x && (!((l-x) % 3))) {
|
if(x && (!((l-x) % 3))) {
|
||||||
fputc(',',reqInfo->out);
|
rputc(',',reqInfo);
|
||||||
++reqInfo->bytes_sent;
|
|
||||||
}
|
}
|
||||||
fputc(tag[x],reqInfo->out);
|
rputc(tag[x],reqInfo);
|
||||||
++reqInfo->bytes_sent;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -669,34 +752,41 @@ int handle_fsize(per_request *reqInfo, FILE *fp, char *error, int sizefmt)
|
|||||||
|
|
||||||
int handle_flastmod(per_request *reqInfo, FILE *fp, char *error, char *tf)
|
int handle_flastmod(per_request *reqInfo, FILE *fp, char *error, char *tf)
|
||||||
{
|
{
|
||||||
char tag[MAX_STRING_LEN];
|
char *tag;
|
||||||
char *tag_val;
|
char *tag_val;
|
||||||
struct stat finfo;
|
struct stat finfo;
|
||||||
|
|
||||||
|
tag = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if(!(tag_val = get_tag(fp,tag)))
|
if(!(tag_val = get_tag(fp,tag))) {
|
||||||
|
freeString(tag);
|
||||||
return 1;
|
return 1;
|
||||||
else if(!strcmp(tag,"done"))
|
}
|
||||||
|
else if(!strcmp(tag,"done")) {
|
||||||
|
freeString(tag);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
else if(!find_file(reqInfo,"flastmod",tag,tag_val,&finfo,error))
|
else if(!find_file(reqInfo,"flastmod",tag,tag_val,&finfo,error))
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%s",
|
rprintf(reqInfo,"%s", ht_time(finfo.st_mtime,tf,0));
|
||||||
ht_time(finfo.st_mtime,tf,0));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------- The main function --------------------------- */
|
/* -------------------------- The main function --------------------------- */
|
||||||
|
|
||||||
/* This is a stub which parses a file descriptor. */
|
/* This is a stub which parses a file descriptor. */
|
||||||
|
|
||||||
void send_parsed_content(per_request *reqInfo, FILE *fp, char *path_args,
|
void send_parsed_content(per_request *reqInfo, FILE *fp, int noexec)
|
||||||
int noexec)
|
|
||||||
{
|
{
|
||||||
char directive[MAX_STRING_LEN], error[MAX_STRING_LEN];
|
char *directive, *error, *timefmt, *errstr;
|
||||||
char timefmt[MAX_STRING_LEN], errstr[MAX_STRING_LEN];
|
|
||||||
int ret, sizefmt;
|
int ret, sizefmt;
|
||||||
|
|
||||||
|
directive = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
error = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
timefmt = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
errstr = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
strcpy(error,DEFAULT_ERROR_MSG);
|
strcpy(error,DEFAULT_ERROR_MSG);
|
||||||
strcpy(timefmt,DEFAULT_TIME_FORMAT);
|
strcpy(timefmt,DEFAULT_TIME_FORMAT);
|
||||||
sizefmt = SIZEFMT_KMG;
|
sizefmt = SIZEFMT_KMG;
|
||||||
@ -705,17 +795,22 @@ void send_parsed_content(per_request *reqInfo, FILE *fp, char *path_args,
|
|||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if(!find_string(reqInfo,fp,STARTING_SEQUENCE)) {
|
if(!find_string(reqInfo,fp,STARTING_SEQUENCE)) {
|
||||||
if(get_directive(fp,directive))
|
if(get_directive(fp,directive)) {
|
||||||
|
freeString(directive);
|
||||||
|
freeString(error);
|
||||||
|
freeString(timefmt);
|
||||||
|
freeString(errstr);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if(!strcmp(directive,"exec")) {
|
if(!strcmp(directive,"exec")) {
|
||||||
if(noexec) {
|
if(noexec) {
|
||||||
sprintf(errstr,"httpd: exec used but not allowed in %s",
|
sprintf(errstr,"HTTPd: exec used but not allowed in %s",
|
||||||
reqInfo->filename);
|
reqInfo->filename);
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%s",error);
|
rprintf(reqInfo,"%s",error);
|
||||||
ret = find_string(reqInfo,fp,ENDING_SEQUENCE);
|
ret = find_string(reqInfo,fp,ENDING_SEQUENCE);
|
||||||
} else
|
} else
|
||||||
ret=handle_exec(reqInfo,fp,path_args,error);
|
ret=handle_exec(reqInfo,fp,error);
|
||||||
}
|
}
|
||||||
else if(!strcmp(directive,"config"))
|
else if(!strcmp(directive,"config"))
|
||||||
ret=handle_config(reqInfo,fp,error,timefmt,&sizefmt);
|
ret=handle_config(reqInfo,fp,error,timefmt,&sizefmt);
|
||||||
@ -732,26 +827,35 @@ void send_parsed_content(per_request *reqInfo, FILE *fp, char *path_args,
|
|||||||
ret=handle_yow(reqInfo,fp,error);
|
ret=handle_yow(reqInfo,fp,error);
|
||||||
#endif /* NO_YOW */
|
#endif /* NO_YOW */
|
||||||
else {
|
else {
|
||||||
sprintf(errstr,"httpd: unknown directive %s in parsed doc %s",
|
sprintf(errstr,"HTTPd: unknown directive %s in parsed doc %s",
|
||||||
directive,reqInfo->filename);
|
directive,reqInfo->filename);
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
reqInfo->bytes_sent += fprintf(reqInfo->out,"%s",error);
|
rprintf(reqInfo,"%s",error);
|
||||||
ret=find_string(reqInfo,fp,ENDING_SEQUENCE);
|
ret=find_string(reqInfo,fp,ENDING_SEQUENCE);
|
||||||
}
|
}
|
||||||
if(ret) {
|
if(ret) {
|
||||||
sprintf(errstr,"httpd: premature EOF in parsed file %s",
|
sprintf(errstr,"HTTPd: premature EOF in parsed file %s",
|
||||||
reqInfo->filename);
|
reqInfo->filename);
|
||||||
log_error(errstr,reqInfo->hostInfo->error_log);
|
log_error(errstr,reqInfo->hostInfo->error_log);
|
||||||
|
freeString(directive);
|
||||||
|
freeString(error);
|
||||||
|
freeString(timefmt);
|
||||||
|
freeString(errstr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
|
freeString(directive);
|
||||||
|
freeString(error);
|
||||||
|
freeString(timefmt);
|
||||||
|
freeString(errstr);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called by send_file */
|
/* Called by send_file */
|
||||||
|
|
||||||
void send_parsed_file(per_request *reqInfo, char *path_args, int noexec)
|
void send_parsed_file(per_request *reqInfo, int noexec)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
@ -761,8 +865,8 @@ void send_parsed_file(per_request *reqInfo, char *path_args, int noexec)
|
|||||||
/* unmunge_name(reqInfo,reqInfo->filename); */
|
/* unmunge_name(reqInfo,reqInfo->filename); */
|
||||||
die(reqInfo,SC_FORBIDDEN,reqInfo->url);
|
die(reqInfo,SC_FORBIDDEN,reqInfo->url);
|
||||||
}
|
}
|
||||||
strcpy(content_type,"text/html");
|
strcpy(reqInfo->outh_content_type,"text/html");
|
||||||
if(!no_headers)
|
if(reqInfo->http_version != P_HTTP_0_9)
|
||||||
send_http_header(reqInfo);
|
send_http_header(reqInfo);
|
||||||
if(reqInfo->method == M_HEAD) {
|
if(reqInfo->method == M_HEAD) {
|
||||||
FClose(fp);
|
FClose(fp);
|
||||||
@ -770,14 +874,13 @@ void send_parsed_file(per_request *reqInfo, char *path_args, int noexec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure no children inherit our buffers */
|
/* Make sure no children inherit our buffers */
|
||||||
fflush(reqInfo->out);
|
rflush(reqInfo);
|
||||||
no_headers = TRUE; /* make sure no headers get inserted anymore */
|
|
||||||
alarm(timeout);
|
alarm(timeout);
|
||||||
|
|
||||||
add_include_vars(reqInfo,DEFAULT_TIME_FORMAT);
|
add_include_vars(reqInfo,DEFAULT_TIME_FORMAT);
|
||||||
|
|
||||||
add_common_vars(reqInfo);
|
add_common_vars(reqInfo);
|
||||||
|
|
||||||
send_parsed_content(reqInfo,fp,path_args,noexec);
|
send_parsed_content(reqInfo,fp,noexec);
|
||||||
FClose(fp);
|
FClose(fp);
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* http_include.h,v 1.5 1995/07/25 06:43:33 blong Exp
|
* http_include.h,v 1.7 1996/03/27 20:44:04 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
@ -32,7 +32,9 @@
|
|||||||
#define NUM_INCLUDE_VARS 5
|
#define NUM_INCLUDE_VARS 5
|
||||||
|
|
||||||
/* http_include */
|
/* http_include */
|
||||||
void send_parsed_file(per_request *reqInfo, char *path_args, int noexec);
|
void send_parsed_file(per_request *reqInfo, int noexec);
|
||||||
char *ht_time(time_t t, char *fmt, int gmt);
|
char *ht_time(time_t t, char *fmt, int gmt);
|
||||||
|
int add_include_vars(per_request *reqInfo, char *timefmt);
|
||||||
|
void send_parsed_content(per_request *reqInfo, FILE *f, int noexec);
|
||||||
|
|
||||||
#endif /* _HTTP_INCLUDE_H_ */
|
#endif /* _HTTP_INCLUDE_H_ */
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* http_ipc.c,v 1.20 1995/09/21 22:50:55 blong Exp
|
* http_ipc.c,v 1.22 1996/02/22 23:46:59 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
@ -21,13 +21,6 @@
|
|||||||
* Based (with modifications) on code by W. Richard Stevens,
|
* Based (with modifications) on code by W. Richard Stevens,
|
||||||
* in _Advanced Programming in the UNIX Environment_
|
* in _Advanced Programming in the UNIX Environment_
|
||||||
*
|
*
|
||||||
* 03-06-95 blong
|
|
||||||
* Added #ifdefs to handle not using this at all for machines like
|
|
||||||
* Linux.
|
|
||||||
*
|
|
||||||
* 04-17-95 blong
|
|
||||||
* Added NEED_SPIPE with s_pipe from Stevens _Unix Network Programming_
|
|
||||||
* for SVR3.2 systems without socketpair.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -49,6 +42,9 @@
|
|||||||
|
|
||||||
#ifdef FD_BSD
|
#ifdef FD_BSD
|
||||||
# include <sys/uio.h>
|
# include <sys/uio.h>
|
||||||
|
# ifdef NEED_SYS_UN_H
|
||||||
|
# include <sys/un.h>
|
||||||
|
# endif /* NEED_SYS_UN_H */
|
||||||
# include <errno.h>
|
# include <errno.h>
|
||||||
# include <stddef.h>
|
# include <stddef.h>
|
||||||
#elif defined(FD_SYSV)
|
#elif defined(FD_SYSV)
|
||||||
@ -103,20 +99,20 @@ int recv_fd(int servfd)
|
|||||||
dat.maxlen = IOBUFSIZE;
|
dat.maxlen = IOBUFSIZE;
|
||||||
flag = 0;
|
flag = 0;
|
||||||
if (getmsg(servfd, NULL, &dat, &flag) < 0) {
|
if (getmsg(servfd, NULL, &dat, &flag) < 0) {
|
||||||
fprintf(stderr,"httpd:getmsg error recv_fd\n");
|
fprintf(stderr,"HTTPd: getmsg error recv_fd\n");
|
||||||
perror("getmsg");
|
perror("getmsg");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
nread = dat.len;
|
nread = dat.len;
|
||||||
if (nread == 0) {
|
if (nread == 0) {
|
||||||
fprintf(stderr,"httpd: connection closed by server\n");
|
fprintf(stderr,"HTTPd: connection closed by server\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ptr = buf; ptr < &buf[nread]; ) {
|
for (ptr = buf; ptr < &buf[nread]; ) {
|
||||||
if (*ptr++ == 0) {
|
if (*ptr++ == 0) {
|
||||||
if (ptr != &buf[nread-1]) {
|
if (ptr != &buf[nread-1]) {
|
||||||
fprintf(stderr,"httpd: message format error recv_fd\n");
|
fprintf(stderr,"HTTPd: message format error recv_fd\n");
|
||||||
perror("recv_fd");
|
perror("recv_fd");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -266,18 +262,18 @@ int recv_fd(int servfd) {
|
|||||||
#endif /* FD_BSDRENO */
|
#endif /* FD_BSDRENO */
|
||||||
|
|
||||||
if ((nread = recvmsg(servfd, &msg, 0)) < 0) {
|
if ((nread = recvmsg(servfd, &msg, 0)) < 0) {
|
||||||
fprintf(stderr,"httpd: recvmsg error");
|
fprintf(stderr,"HTTPd: recvmsg error");
|
||||||
perror("recvmsg");
|
perror("recvmsg");
|
||||||
exit(1);
|
exit(1);
|
||||||
} else if (nread == 0) {
|
} else if (nread == 0) {
|
||||||
fprintf(stderr, "httpd: connection closed by server");
|
fprintf(stderr, "HTTPd: connection closed by server");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ptr = buf; ptr < &buf[nread]; ) {
|
for (ptr = buf; ptr < &buf[nread]; ) {
|
||||||
if (*ptr++ == 0) {
|
if (*ptr++ == 0) {
|
||||||
if (ptr != &buf[nread-1]) {
|
if (ptr != &buf[nread-1]) {
|
||||||
fprintf(stderr, "httpd:message format error");
|
fprintf(stderr, "HTTPd: message format error");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
status = *ptr & 255;
|
status = *ptr & 255;
|
||||||
@ -288,7 +284,7 @@ int recv_fd(int servfd) {
|
|||||||
if (msg.msg_accrightslen != sizeof(int))
|
if (msg.msg_accrightslen != sizeof(int))
|
||||||
#endif /* FD_BSDRENO */
|
#endif /* FD_BSDRENO */
|
||||||
{
|
{
|
||||||
fprintf(stderr, "httpd: status = 0 but no fd");
|
fprintf(stderr, "HTTPd: status = 0 but no fd");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
#ifdef FD_BSDRENO
|
#ifdef FD_BSDRENO
|
||||||
|
335
src/http_log.c
335
src/http_log.c
@ -10,45 +10,12 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* http_log.c,v 1.76 1995/11/28 09:02:04 blong Exp
|
* http_log.c,v 1.84 1996/04/05 18:54:59 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* http_log.c: Dealing with the logs and errors
|
* http_log.c: Dealing with the logs and errors
|
||||||
*
|
*
|
||||||
* Based on NCSA HTTPd 1.3 by Rob McCool
|
|
||||||
*
|
|
||||||
* 10/28/94 cvarela
|
|
||||||
* Added agent_log and referer_log files.
|
|
||||||
*
|
|
||||||
* 02/15/95 blong
|
|
||||||
* Added support for configuration defined error messages
|
|
||||||
*
|
|
||||||
* 03/19/95 blong
|
|
||||||
* Some modification to status lines for uniformity, and for user
|
|
||||||
* defined error messages to give the correct status.
|
|
||||||
*
|
|
||||||
* 04/11/95 blong
|
|
||||||
* Changed custom error responses to only send the error string as
|
|
||||||
* arguments to the script
|
|
||||||
*
|
|
||||||
* 05/08/95 blong
|
|
||||||
* Bowing to pressure, added patch by Paul Phillips (paulp@cerf.net)
|
|
||||||
* to set CLOSE_ON_EXEC flag for log files under #define SECURE_LOGS
|
|
||||||
*
|
|
||||||
* 06/01/95 blong
|
|
||||||
* Changed die() so that it only logs the transaction on non-ErrorDocument
|
|
||||||
* errors (errors that are handled internally to the server)
|
|
||||||
*
|
|
||||||
* 09/13/95 mshapiro
|
|
||||||
* Added log directory checking - group/public write permissions
|
|
||||||
*
|
|
||||||
* 09-28-95 blong
|
|
||||||
* Added fix by Vince Tkac (tkac@oclc.org) to check if there are any
|
|
||||||
* errordocuments defined for the virtual host in the new schema.
|
|
||||||
*
|
|
||||||
* 09-29-95 blong
|
|
||||||
* Changed error_document fix to one suggested by Tim Adam (tma@osa.com.au)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -70,8 +37,10 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
|
#include "allocate.h"
|
||||||
#include "http_log.h"
|
#include "http_log.h"
|
||||||
#include "http_request.h"
|
#include "http_request.h"
|
||||||
|
#include "http_send.h"
|
||||||
#include "http_config.h"
|
#include "http_config.h"
|
||||||
#include "host_config.h"
|
#include "host_config.h"
|
||||||
#include "http_auth.h"
|
#include "http_auth.h"
|
||||||
@ -83,6 +52,7 @@
|
|||||||
|
|
||||||
const char StatLine200[] = "200 Document follows";
|
const char StatLine200[] = "200 Document follows";
|
||||||
const char StatLine204[] = "204 No Content";
|
const char StatLine204[] = "204 No Content";
|
||||||
|
const char StatLine206[] = "206 Partial Content";
|
||||||
const char StatLine301[] = "301 Moved Permanently";
|
const char StatLine301[] = "301 Moved Permanently";
|
||||||
const char StatLine302[] = "302 Moved Temporarily";
|
const char StatLine302[] = "302 Moved Temporarily";
|
||||||
const char StatLine304[] = "304 Not modified";
|
const char StatLine304[] = "304 Not modified";
|
||||||
@ -93,6 +63,7 @@ const char StatLine404[] = "404 Not Found";
|
|||||||
const char StatLine408[] = "408 Request Timeout";
|
const char StatLine408[] = "408 Request Timeout";
|
||||||
const char StatLine500[] = "500 Server Error";
|
const char StatLine500[] = "500 Server Error";
|
||||||
const char StatLine501[] = "501 Not Implemented";
|
const char StatLine501[] = "501 Not Implemented";
|
||||||
|
const char StatLine503[] = "503 Service Unavailable";
|
||||||
char error_msg[MAX_STRING_LEN];
|
char error_msg[MAX_STRING_LEN];
|
||||||
|
|
||||||
/* Moved to http_request.c */
|
/* Moved to http_request.c */
|
||||||
@ -108,7 +79,7 @@ void open_logs(per_host *host) {
|
|||||||
|
|
||||||
if (host->httpd_conf & HC_ERROR_FNAME) {
|
if (host->httpd_conf & HC_ERROR_FNAME) {
|
||||||
if(!(host->error_log = fopen_logfile(host->error_fname,"a"))) {
|
if(!(host->error_log = fopen_logfile(host->error_fname,"a"))) {
|
||||||
fprintf(stderr,"httpd: could not open error log file %s.\n",
|
fprintf(stderr,"HTTPd: could not open error log file %s.\n",
|
||||||
host->error_fname);
|
host->error_fname);
|
||||||
perror("fopen");
|
perror("fopen");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -116,7 +87,7 @@ void open_logs(per_host *host) {
|
|||||||
}
|
}
|
||||||
if (host->httpd_conf & HC_XFER_FNAME) {
|
if (host->httpd_conf & HC_XFER_FNAME) {
|
||||||
if((host->xfer_log = open_logfile(host->xfer_fname,xfer_flags, xfer_mode)) < 0) {
|
if((host->xfer_log = open_logfile(host->xfer_fname,xfer_flags, xfer_mode)) < 0) {
|
||||||
fprintf(stderr,"httpd: could not open transfer log file %s.\n",
|
fprintf(stderr,"HTTPd: could not open transfer log file %s.\n",
|
||||||
host->xfer_fname);
|
host->xfer_fname);
|
||||||
perror("open");
|
perror("open");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -130,7 +101,7 @@ void open_logs(per_host *host) {
|
|||||||
if (!(host->log_opts & LOG_COMBINED)) {
|
if (!(host->log_opts & LOG_COMBINED)) {
|
||||||
if (host->httpd_conf & HC_AGENT_FNAME) {
|
if (host->httpd_conf & HC_AGENT_FNAME) {
|
||||||
if(!(host->agent_log = fopen_logfile(host->agent_fname,"a"))) {
|
if(!(host->agent_log = fopen_logfile(host->agent_fname,"a"))) {
|
||||||
fprintf(stderr,"httpd: could not open agent log file %s.\n",
|
fprintf(stderr,"HTTPd: could not open agent log file %s.\n",
|
||||||
host->agent_fname);
|
host->agent_fname);
|
||||||
perror("fopen");
|
perror("fopen");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -143,7 +114,7 @@ void open_logs(per_host *host) {
|
|||||||
}
|
}
|
||||||
if (host->httpd_conf & HC_REFERER_FNAME) {
|
if (host->httpd_conf & HC_REFERER_FNAME) {
|
||||||
if(!(host->referer_log = fopen_logfile(host->referer_fname,"a"))) {
|
if(!(host->referer_log = fopen_logfile(host->referer_fname,"a"))) {
|
||||||
fprintf(stderr,"httpd: could not open referer log file %s.\n",
|
fprintf(stderr,"HTTPd: could not open referer log file %s.\n",
|
||||||
host->referer_fname);
|
host->referer_fname);
|
||||||
perror("fopen");
|
perror("fopen");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -187,19 +158,29 @@ void log_pid(void)
|
|||||||
FILE *pid_file;
|
FILE *pid_file;
|
||||||
|
|
||||||
if(!(pid_file = fopen(pid_fname,"w"))) {
|
if(!(pid_file = fopen(pid_fname,"w"))) {
|
||||||
fprintf(stderr,"httpd: could not log pid to file %s\n",pid_fname);
|
fprintf(stderr,"HTTPd: could not log pid to file %s\n",pid_fname);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
fprintf(pid_file,"%d\n",getpid());
|
fprintf(pid_file,"%d\n",getpid());
|
||||||
fclose(pid_file);
|
fclose(pid_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern int num_children;
|
||||||
|
|
||||||
void log_transaction(per_request *reqInfo)
|
void log_transaction(per_request *reqInfo)
|
||||||
{
|
{
|
||||||
char str[HUGE_STRING_LEN];
|
char *str;
|
||||||
long timz;
|
long timz;
|
||||||
struct tm *t;
|
struct tm *t;
|
||||||
char tstr[MAX_STRING_LEN],sign;
|
char *tstr,sign;
|
||||||
|
#ifdef LOG_DURATION
|
||||||
|
extern time_t request_time;
|
||||||
|
time_t duration = request_time ? (time(NULL) - request_time) : 0;
|
||||||
|
#endif /* LOG_DURATION */
|
||||||
|
|
||||||
|
str = newString(HUGE_STRING_LEN,STR_TMP);
|
||||||
|
tstr = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
|
|
||||||
t = get_gmtoff(&timz);
|
t = get_gmtoff(&timz);
|
||||||
sign = (timz < 0 ? '-' : '+');
|
sign = (timz < 0 ? '-' : '+');
|
||||||
@ -208,9 +189,9 @@ void log_transaction(per_request *reqInfo)
|
|||||||
|
|
||||||
strftime(tstr,MAX_STRING_LEN,"%d/%b/%Y:%H:%M:%S",t);
|
strftime(tstr,MAX_STRING_LEN,"%d/%b/%Y:%H:%M:%S",t);
|
||||||
sprintf(str,"%s %s %s [%s %c%02ld%02d] \"%s\" ",
|
sprintf(str,"%s %s %s [%s %c%02ld%02d] \"%s\" ",
|
||||||
reqInfo->remote_name,
|
(reqInfo->remote_name ? reqInfo->remote_name : "-"),
|
||||||
(do_rfc931 ? remote_logname : "-"),
|
(do_rfc931 ? remote_logname : "-"),
|
||||||
(user[0] ? user : "-"),
|
(reqInfo->auth_user[0] ? reqInfo->auth_user : "-"),
|
||||||
tstr,
|
tstr,
|
||||||
sign,
|
sign,
|
||||||
timz/3600,
|
timz/3600,
|
||||||
@ -231,16 +212,17 @@ void log_transaction(per_request *reqInfo)
|
|||||||
else
|
else
|
||||||
strcat(str," -");
|
strcat(str," -");
|
||||||
}
|
}
|
||||||
if (reqInfo->hostInfo->referer_ignore && reqInfo->referer[0]) {
|
if (reqInfo->hostInfo->referer_ignore && reqInfo->inh_referer[0]) {
|
||||||
char str[MAX_STRING_LEN];
|
char *str1;
|
||||||
int bIgnore = 0;
|
int bIgnore = 0;
|
||||||
|
|
||||||
lim_strcpy(str, reqInfo->hostInfo->referer_ignore, 255);
|
str1 = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
lim_strcpy(str1, reqInfo->hostInfo->referer_ignore, 255);
|
||||||
if (reqInfo->hostInfo->referer_ignore[0]) {
|
if (reqInfo->hostInfo->referer_ignore[0]) {
|
||||||
char* tok = strtok (str, " ");
|
char* tok = strtok (str1, " ");
|
||||||
|
|
||||||
while (tok) {
|
while (tok) {
|
||||||
if (strstr(reqInfo->referer, tok)) {
|
if (strstr(reqInfo->inh_referer, tok)) {
|
||||||
bIgnore = 1;
|
bIgnore = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -248,43 +230,50 @@ void log_transaction(per_request *reqInfo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bIgnore) {
|
if (bIgnore) {
|
||||||
reqInfo->referer[0] = '\0';
|
reqInfo->inh_referer[0] = '\0';
|
||||||
}
|
}
|
||||||
|
freeString(str1);
|
||||||
}
|
}
|
||||||
|
#ifdef LOG_DURATION
|
||||||
|
sprintf(str+strlen(str), " %ld", duration);
|
||||||
|
#endif /* LOG_DURATION */
|
||||||
|
|
||||||
if (!(reqInfo->hostInfo->log_opts & LOG_COMBINED)) {
|
if (!(reqInfo->hostInfo->log_opts & LOG_COMBINED)) {
|
||||||
strcat(str,"\n");
|
strcat(str,"\n");
|
||||||
write(reqInfo->hostInfo->xfer_log,str,strlen(str));
|
write(reqInfo->hostInfo->xfer_log,str,strlen(str));
|
||||||
|
|
||||||
/* log the user agent */
|
/* log the user agent */
|
||||||
if (reqInfo->agent[0]) {
|
if (reqInfo->inh_agent[0]) {
|
||||||
if (reqInfo->hostInfo->log_opts & LOG_DATE)
|
if (reqInfo->hostInfo->log_opts & LOG_DATE)
|
||||||
fprintf(reqInfo->hostInfo->agent_log, "[%s] %s\n",tstr,
|
fprintf(reqInfo->hostInfo->agent_log, "[%s] %s\n",tstr,
|
||||||
reqInfo->agent);
|
reqInfo->inh_agent);
|
||||||
else
|
else
|
||||||
fprintf(reqInfo->hostInfo->agent_log, "%s\n", reqInfo->agent);
|
fprintf(reqInfo->hostInfo->agent_log, "%s\n", reqInfo->inh_agent);
|
||||||
fflush(reqInfo->hostInfo->agent_log);
|
fflush(reqInfo->hostInfo->agent_log);
|
||||||
}
|
}
|
||||||
/* log the referer */
|
/* log the referer */
|
||||||
if (reqInfo->referer[0]) {
|
if (reqInfo->inh_referer[0]) {
|
||||||
if (reqInfo->hostInfo->log_opts & LOG_DATE)
|
if (reqInfo->hostInfo->log_opts & LOG_DATE)
|
||||||
fprintf(reqInfo->hostInfo->referer_log, "[%s] %s -> %s\n",tstr,
|
fprintf(reqInfo->hostInfo->referer_log, "[%s] %s -> %s\n",tstr,
|
||||||
reqInfo->referer, reqInfo->url);
|
reqInfo->inh_referer, reqInfo->url);
|
||||||
else
|
else
|
||||||
fprintf(reqInfo->hostInfo->referer_log, "%s -> %s\n",
|
fprintf(reqInfo->hostInfo->referer_log, "%s -> %s\n",
|
||||||
reqInfo->referer, reqInfo->url);
|
reqInfo->inh_referer, reqInfo->url);
|
||||||
fflush(reqInfo->hostInfo->referer_log);
|
fflush(reqInfo->hostInfo->referer_log);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (reqInfo->referer[0])
|
if (reqInfo->inh_referer[0])
|
||||||
sprintf(str,"%s \"%s\"",str,reqInfo->referer);
|
sprintf(str,"%s \"%s\"",str,reqInfo->inh_referer);
|
||||||
else
|
else
|
||||||
strcat(str," \"\"");
|
strcat(str," \"\"");
|
||||||
if (reqInfo->agent[0])
|
if (reqInfo->inh_agent[0])
|
||||||
sprintf(str,"%s \"%s\"\n",str,reqInfo->agent);
|
sprintf(str,"%s \"%s\"\n",str,reqInfo->inh_agent);
|
||||||
else
|
else
|
||||||
strcat(str," \"\"\n");
|
strcat(str," \"\"\n");
|
||||||
write(reqInfo->hostInfo->xfer_log,str,strlen(str));
|
write(reqInfo->hostInfo->xfer_log,str,strlen(str));
|
||||||
}
|
}
|
||||||
|
freeString(str);
|
||||||
|
freeString(tstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void log_error(char *err, FILE *fp) {
|
void log_error(char *err, FILE *fp) {
|
||||||
@ -296,46 +285,46 @@ void log_reason(per_request *reqInfo, char *reason, char *file)
|
|||||||
{
|
{
|
||||||
char *buffer;
|
char *buffer;
|
||||||
|
|
||||||
buffer = (char *)malloc(strlen(reason)+strlen(reqInfo->referer)+
|
/* This might not be big enough, but since its in the heap, the
|
||||||
strlen(reqInfo->remote_name)+strlen(file)+50);
|
* worst that will happen is a core dump, and its faster than a
|
||||||
sprintf(buffer,"httpd: access to %s failed for %s, reason: %s from %s",
|
* malloc, and won't fragment the memory as badly.
|
||||||
|
*/
|
||||||
|
buffer = newString(HUGE_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
|
sprintf(buffer,"HTTPd: access to %s failed for %s, reason: %s from %s",
|
||||||
file,reqInfo->remote_name,reason,
|
file,reqInfo->remote_name,reason,
|
||||||
( (reqInfo->referer[0] != '\0') ? reqInfo->referer : "-"));
|
( (reqInfo->inh_referer[0] != '\0') ? reqInfo->inh_referer : "-"));
|
||||||
log_error(buffer,reqInfo->hostInfo->error_log);
|
log_error(buffer,reqInfo->hostInfo->error_log);
|
||||||
free(buffer);
|
freeString(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void begin_http_header(per_request *reqInfo, const char *msg)
|
|
||||||
{
|
|
||||||
fprintf(reqInfo->out,"%s %s%c",SERVER_PROTOCOL,msg,LF);
|
|
||||||
dump_default_header(reqInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void error_head(per_request *reqInfo, const char *err)
|
void error_head(per_request *reqInfo, const char *err)
|
||||||
{
|
{
|
||||||
if(!no_headers) {
|
if(reqInfo->http_version != P_HTTP_0_9) {
|
||||||
begin_http_header(reqInfo,err);
|
strcpy(reqInfo->outh_content_type,"text/html");
|
||||||
fprintf(reqInfo->out,"Content-type: text/html%c%c",LF,LF);
|
send_http_header(reqInfo);
|
||||||
}
|
}
|
||||||
if(reqInfo->method != M_HEAD) {
|
if(reqInfo->method != M_HEAD) {
|
||||||
fprintf(reqInfo->out,"<HEAD><TITLE>%s</TITLE></HEAD>%c",err,LF);
|
rprintf(reqInfo,"<HEAD><TITLE>%s</TITLE></HEAD>%c",err,LF);
|
||||||
fprintf(reqInfo->out,"<BODY><H1>%s</H1>%c",err,LF);
|
rprintf(reqInfo,"<BODY><H1>%s</H1>%c",err,LF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void title_html(per_request *reqInfo, char *msg)
|
void title_html(per_request *reqInfo, char *msg)
|
||||||
{
|
{
|
||||||
fprintf(reqInfo->out,"<HEAD><TITLE>%s</TITLE></HEAD>%c",msg,LF);
|
rprintf(reqInfo,"<HEAD><TITLE>%s</TITLE></HEAD>%c",msg,LF);
|
||||||
fprintf(reqInfo->out,"<BODY><H1>%s</H1>%c",msg,LF);
|
rprintf(reqInfo,"<BODY><H1>%s</H1>%c",msg,LF);
|
||||||
}
|
}
|
||||||
|
|
||||||
int die(per_request *reqInfo, int type, char *err_string)
|
int die(per_request *reqInfo, int type, char *err_string)
|
||||||
{
|
{
|
||||||
char arguments[MAX_STRING_LEN];
|
char *arguments;
|
||||||
int RetVal=0;
|
int RetVal=0;
|
||||||
int x;
|
int x;
|
||||||
int die_type;
|
int die_type;
|
||||||
|
|
||||||
|
arguments = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
/* kill keepalive on errors until we figure out what to do
|
/* kill keepalive on errors until we figure out what to do
|
||||||
such as compute content_length of error messages */
|
such as compute content_length of error messages */
|
||||||
die_type = DIE_NORMAL;
|
die_type = DIE_NORMAL;
|
||||||
@ -346,62 +335,57 @@ int die(per_request *reqInfo, int type, char *err_string)
|
|||||||
strcpy(failed_request,the_request);
|
strcpy(failed_request,the_request);
|
||||||
strcpy(failed_url,reqInfo->url);
|
strcpy(failed_url,reqInfo->url);
|
||||||
|
|
||||||
/* For 1.4b4, changed to have a common message for ErrorDocument calls
|
|
||||||
We now send only error=err_string (as passed) and the CGI environment
|
|
||||||
variable ERROR_STATUS,ERROR_REQUEST,ERROR_URL contain the rest of the
|
|
||||||
relevent information */
|
|
||||||
/* For 1.4 release, changed ERROR_ to REDIRECT_ */
|
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case SC_NO_CONTENT:
|
case SC_NO_CONTENT:
|
||||||
reqInfo->status = SC_NO_CONTENT;
|
reqInfo->status = SC_NO_CONTENT;
|
||||||
begin_http_header(reqInfo,StatLine204);
|
set_stat_line(reqInfo);
|
||||||
fputc(LF,reqInfo->out);
|
if (reqInfo->http_version != P_HTTP_0_9) {
|
||||||
|
send_http_header(reqInfo);
|
||||||
|
}
|
||||||
keep_alive.bKeepAlive = 0;
|
keep_alive.bKeepAlive = 0;
|
||||||
header_only = 1;
|
|
||||||
RetVal = SC_NO_CONTENT;
|
RetVal = SC_NO_CONTENT;
|
||||||
log_transaction(reqInfo);
|
log_transaction(reqInfo);
|
||||||
break;
|
break;
|
||||||
case SC_REDIRECT_TEMP:
|
case SC_REDIRECT_TEMP:
|
||||||
reqInfo->status = SC_REDIRECT_TEMP;
|
reqInfo->status = SC_REDIRECT_TEMP;
|
||||||
|
set_stat_line(reqInfo);
|
||||||
if (((x=have_doc_error(reqInfo,type)) >= 0) && (!ErrorStat)) {
|
if (((x=have_doc_error(reqInfo,type)) >= 0) && (!ErrorStat)) {
|
||||||
ErrorStat = reqInfo->status;
|
ErrorStat = reqInfo->status;
|
||||||
GoErrorDoc(reqInfo,x,err_string);
|
GoErrorDoc(reqInfo,x,err_string);
|
||||||
} else {
|
} else {
|
||||||
keep_alive.bKeepAlive = 0;
|
keep_alive.bKeepAlive = 0;
|
||||||
if(!no_headers) {
|
if(reqInfo->http_version != P_HTTP_0_9) {
|
||||||
begin_http_header(reqInfo,StatLine302);
|
strcpy(reqInfo->outh_location,err_string);
|
||||||
fprintf(reqInfo->out,"Location: %s%c",err_string,LF);
|
strcpy(reqInfo->outh_content_type,"text/html");
|
||||||
fprintf(reqInfo->out,"Content-type: text/html%c",LF);
|
send_http_header(reqInfo);
|
||||||
fputc(LF,reqInfo->out);
|
|
||||||
}
|
}
|
||||||
if (reqInfo->method != M_HEAD) {
|
if (reqInfo->method != M_HEAD) {
|
||||||
title_html(reqInfo,"Document moved");
|
title_html(reqInfo,"Document moved");
|
||||||
fprintf(reqInfo->out,
|
rprintf(reqInfo,
|
||||||
"This document has moved <A HREF=\"%s\">here</A>.<P>%c",
|
"This document has moved <A HREF=\"%s\">here</A>.<P>%c",
|
||||||
err_string,LF);
|
err_string,LF);
|
||||||
fprintf(reqInfo->out,"</BODY>%c",LF);
|
rprintf(reqInfo,"</BODY>%c",LF);
|
||||||
}
|
}
|
||||||
log_transaction(reqInfo);
|
log_transaction(reqInfo);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SC_REDIRECT_PERM:
|
case SC_REDIRECT_PERM:
|
||||||
reqInfo->status = SC_REDIRECT_PERM;
|
reqInfo->status = SC_REDIRECT_PERM;
|
||||||
|
set_stat_line(reqInfo);
|
||||||
if (((x=have_doc_error(reqInfo,type)) >= 0) && (!ErrorStat)) {
|
if (((x=have_doc_error(reqInfo,type)) >= 0) && (!ErrorStat)) {
|
||||||
ErrorStat = reqInfo->status;
|
ErrorStat = reqInfo->status;
|
||||||
GoErrorDoc(reqInfo,x,err_string);
|
GoErrorDoc(reqInfo,x,err_string);
|
||||||
} else {
|
} else {
|
||||||
keep_alive.bKeepAlive = 0;
|
keep_alive.bKeepAlive = 0;
|
||||||
if(!no_headers) {
|
if(reqInfo->http_version != P_HTTP_0_9) {
|
||||||
begin_http_header(reqInfo,StatLine301);
|
strcpy(reqInfo->outh_location,err_string);
|
||||||
fprintf(reqInfo->out,"Location: %s%c",err_string,LF);
|
strcpy(reqInfo->outh_content_type,"text/html");
|
||||||
fprintf(reqInfo->out,"Content-type: text/html%c",LF);
|
send_http_header(reqInfo);
|
||||||
fputc(LF,reqInfo->out);
|
}
|
||||||
}
|
|
||||||
if (reqInfo->method != M_HEAD) {
|
if (reqInfo->method != M_HEAD) {
|
||||||
title_html(reqInfo,"Document moved");
|
title_html(reqInfo,"Document moved");
|
||||||
fprintf(reqInfo->out,"This document has permanently moved ");
|
rprintf(reqInfo,"This document has permanently moved ");
|
||||||
fprintf(reqInfo->out,"<A HREF=\"%s\">here</A>.<P>%c</BODY>%c",
|
rprintf(reqInfo,"<A HREF=\"%s\">here</A>.<P>%c</BODY>%c",
|
||||||
err_string,LF,LF);
|
err_string,LF,LF);
|
||||||
}
|
}
|
||||||
log_transaction(reqInfo);
|
log_transaction(reqInfo);
|
||||||
@ -409,73 +393,95 @@ int die(per_request *reqInfo, int type, char *err_string)
|
|||||||
break;
|
break;
|
||||||
case SC_USE_LOCAL_COPY:
|
case SC_USE_LOCAL_COPY:
|
||||||
reqInfo->status = SC_USE_LOCAL_COPY;
|
reqInfo->status = SC_USE_LOCAL_COPY;
|
||||||
begin_http_header(reqInfo,StatLine304);
|
set_stat_line(reqInfo);
|
||||||
fputc(LF,reqInfo->out);
|
if (reqInfo->http_version != P_HTTP_0_9) {
|
||||||
|
send_http_header(reqInfo);
|
||||||
|
}
|
||||||
keep_alive.bKeepAlive = 0;
|
keep_alive.bKeepAlive = 0;
|
||||||
header_only = 1;
|
|
||||||
RetVal = SC_USE_LOCAL_COPY;
|
RetVal = SC_USE_LOCAL_COPY;
|
||||||
log_transaction(reqInfo);
|
log_transaction(reqInfo);
|
||||||
break;
|
break;
|
||||||
case SC_AUTH_REQUIRED:
|
case SC_AUTH_REQUIRED:
|
||||||
reqInfo->status = SC_AUTH_REQUIRED;
|
reqInfo->status = SC_AUTH_REQUIRED;
|
||||||
|
set_stat_line(reqInfo);
|
||||||
|
strcpy(reqInfo->outh_www_auth, err_string);
|
||||||
if (((x=have_doc_error(reqInfo,type)) >= 0) && (!ErrorStat)) {
|
if (((x=have_doc_error(reqInfo,type)) >= 0) && (!ErrorStat)) {
|
||||||
ErrorStat = reqInfo->status;
|
ErrorStat = reqInfo->status;
|
||||||
GoErrorDoc(reqInfo,x,err_string);
|
GoErrorDoc(reqInfo,x,err_string);
|
||||||
} else {
|
} else {
|
||||||
keep_alive.bKeepAlive = 0;
|
keep_alive.bKeepAlive = 0;
|
||||||
if(!no_headers) {
|
if(reqInfo->http_version != P_HTTP_0_9) {
|
||||||
begin_http_header(reqInfo,StatLine401);
|
strcpy(reqInfo->outh_content_type,"text/html");
|
||||||
fprintf(reqInfo->out,"Content-type: text/html%c",LF);
|
send_http_header(reqInfo);
|
||||||
fprintf(reqInfo->out,"WWW-Authenticate: %s%c%c",
|
|
||||||
err_string,LF,LF);
|
|
||||||
}
|
}
|
||||||
if (reqInfo->method != M_HEAD) {
|
if (reqInfo->method != M_HEAD) {
|
||||||
title_html(reqInfo,"Authorization Required");
|
title_html(reqInfo,"Authorization Required");
|
||||||
fprintf(reqInfo->out,
|
rprintf(reqInfo,"Browser not authentication-capable or %c",LF);
|
||||||
"Browser not authentication-capable or %c",LF);
|
rprintf(reqInfo,"authentication failed.%c",LF);
|
||||||
fprintf(reqInfo->out,"authentication failed.%c",LF);
|
rprintf(reqInfo,"</BODY>%c",LF);
|
||||||
fprintf(reqInfo->out,"</BODY>%c",LF);
|
|
||||||
}
|
}
|
||||||
log_transaction(reqInfo);
|
log_transaction(reqInfo);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SC_AUTH_NO_WWW_AUTH:
|
||||||
|
reqInfo->status = SC_AUTH_REQUIRED;
|
||||||
|
set_stat_line(reqInfo);
|
||||||
|
keep_alive.bKeepAlive = 0;
|
||||||
|
if(reqInfo->http_version != P_HTTP_0_9) {
|
||||||
|
strcpy(reqInfo->outh_content_type,"text/html");
|
||||||
|
send_http_header(reqInfo);
|
||||||
|
}
|
||||||
|
if (reqInfo->method != M_HEAD) {
|
||||||
|
title_html(reqInfo,"Authorization Required");
|
||||||
|
rprintf(reqInfo,"You are not permitted to get this URL: %c",LF);
|
||||||
|
rprintf(reqInfo,"%s%c",err_string,LF);
|
||||||
|
rprintf(reqInfo,"</BODY>%c",LF);
|
||||||
|
}
|
||||||
|
log_transaction(reqInfo);
|
||||||
|
break;
|
||||||
case SC_BAD_REQUEST:
|
case SC_BAD_REQUEST:
|
||||||
reqInfo->status = SC_BAD_REQUEST;
|
reqInfo->status = SC_BAD_REQUEST;
|
||||||
|
set_stat_line(reqInfo);
|
||||||
if (((x=have_doc_error(reqInfo,type)) >= 0) && (!ErrorStat)) {
|
if (((x=have_doc_error(reqInfo,type)) >= 0) && (!ErrorStat)) {
|
||||||
ErrorStat = reqInfo->status;
|
ErrorStat = reqInfo->status;
|
||||||
GoErrorDoc(reqInfo,x,err_string);
|
GoErrorDoc(reqInfo,x,err_string);
|
||||||
} else {
|
} else {
|
||||||
error_head(reqInfo,StatLine400);
|
error_head(reqInfo,StatLine400);
|
||||||
keep_alive.bKeepAlive = 0;
|
keep_alive.bKeepAlive = 0;
|
||||||
if (!header_only) {
|
if (reqInfo->method != M_HEAD) {
|
||||||
fprintf(reqInfo->out,
|
rprintf(reqInfo,
|
||||||
"Your client sent a query that this server could%c",LF);
|
"Your client sent a query that this server could%c",LF);
|
||||||
fprintf(reqInfo->out,"not understand.<P>%c",LF);
|
rprintf(reqInfo,"not understand.<P>%c",LF);
|
||||||
fprintf(reqInfo->out,"Reason: %s<P>%c",err_string,LF);
|
rprintf(reqInfo,"Reason: %s<P>%c",err_string,LF);
|
||||||
fprintf(reqInfo->out,"</BODY>%c",LF);
|
rprintf(reqInfo,"</BODY>%c",LF);
|
||||||
}
|
}
|
||||||
log_transaction(reqInfo);
|
log_transaction(reqInfo);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SC_BAD_IMAGEMAP:
|
case SC_BAD_IMAGEMAP:
|
||||||
reqInfo->status = SC_BAD_REQUEST;
|
reqInfo->status = SC_BAD_REQUEST;
|
||||||
|
set_stat_line(reqInfo);
|
||||||
if (((x=have_doc_error(reqInfo,type)) >= 0) && (!ErrorStat)) {
|
if (((x=have_doc_error(reqInfo,type)) >= 0) && (!ErrorStat)) {
|
||||||
ErrorStat = reqInfo->status;
|
ErrorStat = reqInfo->status;
|
||||||
GoErrorDoc(reqInfo,x,err_string);
|
GoErrorDoc(reqInfo,x,err_string);
|
||||||
} else {
|
} else {
|
||||||
error_head(reqInfo,StatLine400);
|
error_head(reqInfo,StatLine400);
|
||||||
keep_alive.bKeepAlive = 0;
|
keep_alive.bKeepAlive = 0;
|
||||||
if (!header_only) {
|
if (reqInfo->method != M_HEAD) {
|
||||||
fprintf(reqInfo->out,
|
rprintf(reqInfo,
|
||||||
"Server encountered error processing imagemap%c",LF);
|
"Server encountered error processing imagemap%c",LF);
|
||||||
fprintf(reqInfo->out,"Reason: %s<P>%c",err_string,LF);
|
rprintf(reqInfo,"<P>Reason: %s<P>%c",err_string,LF);
|
||||||
fprintf(reqInfo->out,"</BODY>%c",LF);
|
rprintf(reqInfo,"</BODY>%c",LF);
|
||||||
}
|
}
|
||||||
log_transaction(reqInfo);
|
log_transaction(reqInfo);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SC_FORBIDDEN:
|
case SC_FORBIDDEN:
|
||||||
reqInfo->status = SC_FORBIDDEN;
|
if (reqInfo->outh_location[0])
|
||||||
|
reqInfo->status = SC_REDIRECT_TEMP;
|
||||||
|
else
|
||||||
|
reqInfo->status = SC_FORBIDDEN;
|
||||||
|
set_stat_line(reqInfo);
|
||||||
if (((x=have_doc_error(reqInfo,type)) >= 0) && (!ErrorStat)) {
|
if (((x=have_doc_error(reqInfo,type)) >= 0) && (!ErrorStat)) {
|
||||||
ErrorStat = reqInfo->status;
|
ErrorStat = reqInfo->status;
|
||||||
GoErrorDoc(reqInfo,x,err_string);
|
GoErrorDoc(reqInfo,x,err_string);
|
||||||
@ -483,17 +489,18 @@ int die(per_request *reqInfo, int type, char *err_string)
|
|||||||
error_head(reqInfo,StatLine403);
|
error_head(reqInfo,StatLine403);
|
||||||
keep_alive.bKeepAlive = 0;
|
keep_alive.bKeepAlive = 0;
|
||||||
if (reqInfo->method != M_HEAD) {
|
if (reqInfo->method != M_HEAD) {
|
||||||
fprintf(reqInfo->out,
|
rprintf(reqInfo,
|
||||||
"Your client does not have permission to get URL %s ",
|
"Your client does not have permission to get URL %s ",
|
||||||
err_string);
|
err_string);
|
||||||
fprintf(reqInfo->out,"from this server.<P>%c",LF);
|
rprintf(reqInfo,"from this server.<P>%c",LF);
|
||||||
fprintf(reqInfo->out,"</BODY>%c",LF);
|
rprintf(reqInfo,"</BODY>%c",LF);
|
||||||
}
|
}
|
||||||
log_transaction(reqInfo);
|
log_transaction(reqInfo);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SC_NOT_FOUND:
|
case SC_NOT_FOUND:
|
||||||
reqInfo->status = SC_NOT_FOUND;
|
reqInfo->status = SC_NOT_FOUND;
|
||||||
|
set_stat_line(reqInfo);
|
||||||
if (((x=have_doc_error(reqInfo,type)) >= 0) && (!ErrorStat)) {
|
if (((x=have_doc_error(reqInfo,type)) >= 0) && (!ErrorStat)) {
|
||||||
ErrorStat = reqInfo->status;
|
ErrorStat = reqInfo->status;
|
||||||
GoErrorDoc(reqInfo,x,err_string);
|
GoErrorDoc(reqInfo,x,err_string);
|
||||||
@ -501,16 +508,36 @@ int die(per_request *reqInfo, int type, char *err_string)
|
|||||||
error_head(reqInfo,StatLine404);
|
error_head(reqInfo,StatLine404);
|
||||||
keep_alive.bKeepAlive = 0;
|
keep_alive.bKeepAlive = 0;
|
||||||
if (reqInfo->method != M_HEAD) {
|
if (reqInfo->method != M_HEAD) {
|
||||||
fprintf(reqInfo->out,
|
rprintf(reqInfo,
|
||||||
"The requested URL %s was not found on this server.%c",
|
"The requested URL %s was not found on this server.%c",
|
||||||
err_string,LF);
|
err_string,LF);
|
||||||
fprintf(reqInfo->out,"</BODY>%c",LF);
|
rprintf(reqInfo,"</BODY>%c",LF);
|
||||||
}
|
}
|
||||||
log_transaction(reqInfo);
|
log_transaction(reqInfo);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SC_SERVICE_UNAVAIL:
|
||||||
|
reqInfo->status = SC_SERVICE_UNAVAIL;
|
||||||
|
set_stat_line(reqInfo);
|
||||||
|
if (((x=have_doc_error(reqInfo,type)) >= 0) && (!ErrorStat)) {
|
||||||
|
ErrorStat = reqInfo->status;
|
||||||
|
GoErrorDoc(reqInfo,x,err_string);
|
||||||
|
} else {
|
||||||
|
error_head(reqInfo,StatLine503);
|
||||||
|
keep_alive.bKeepAlive = 0;
|
||||||
|
if (reqInfo->method != M_HEAD) {
|
||||||
|
rprintf(reqInfo,
|
||||||
|
"The requested URL %s is temporarily unavailable",
|
||||||
|
err_string);
|
||||||
|
rprintf(reqInfo,"from this server.%c",LF);
|
||||||
|
rprintf(reqInfo,"</BODY>%c",LF);
|
||||||
|
}
|
||||||
|
log_transaction(reqInfo);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SC_SERVER_ERROR:
|
case SC_SERVER_ERROR:
|
||||||
reqInfo->status = SC_SERVER_ERROR;
|
reqInfo->status = SC_SERVER_ERROR;
|
||||||
|
set_stat_line(reqInfo);
|
||||||
die_type = DIE_NORMAL;
|
die_type = DIE_NORMAL;
|
||||||
if (((x=have_doc_error(reqInfo,type)) >= 0) && (!ErrorStat)) {
|
if (((x=have_doc_error(reqInfo,type)) >= 0) && (!ErrorStat)) {
|
||||||
ErrorStat = reqInfo->status;
|
ErrorStat = reqInfo->status;
|
||||||
@ -521,22 +548,23 @@ int die(per_request *reqInfo, int type, char *err_string)
|
|||||||
keep_alive.bKeepAlive = 0;
|
keep_alive.bKeepAlive = 0;
|
||||||
log_error(err_string,reqInfo->hostInfo->error_log);
|
log_error(err_string,reqInfo->hostInfo->error_log);
|
||||||
if (reqInfo->method != M_HEAD) {
|
if (reqInfo->method != M_HEAD) {
|
||||||
fprintf(reqInfo->out,"The server encountered an internal error or%c",LF);
|
rprintf(reqInfo,"The server encountered an internal error or%c",LF);
|
||||||
fprintf(reqInfo->out,"misconfiguration and was unable to complete %c",LF);
|
rprintf(reqInfo,"misconfiguration and was unable to complete %c",LF);
|
||||||
fprintf(reqInfo->out,"your request.<P>%c",LF);
|
rprintf(reqInfo,"your request.<P>%c",LF);
|
||||||
fprintf(reqInfo->out,"Please contact the server administrator,%c",LF);
|
rprintf(reqInfo,"Please contact the server administrator,%c",LF);
|
||||||
fprintf(reqInfo->out," %s ",reqInfo->hostInfo->server_admin);
|
rprintf(reqInfo," %s ",reqInfo->hostInfo->server_admin);
|
||||||
fprintf(reqInfo->out,"and inform them of the time the error occurred%c",LF);
|
rprintf(reqInfo,"and inform them of the time the error occurred%c",LF);
|
||||||
fprintf(reqInfo->out,", and anything you might have done that may%c",LF);
|
rprintf(reqInfo,", and anything you might have done that may%c",LF);
|
||||||
fprintf(reqInfo->out,"have caused the error.<P>%c",LF);
|
rprintf(reqInfo,"have caused the error.<P>%c",LF);
|
||||||
fprintf(reqInfo->out,"<b>Error:</b> %s%c",err_string,LF);
|
rprintf(reqInfo,"<b>Error:</b> %s%c",err_string,LF);
|
||||||
fprintf(reqInfo->out,"</BODY>%c",LF);
|
rprintf(reqInfo,"</BODY>%c",LF);
|
||||||
}
|
}
|
||||||
log_transaction(reqInfo);
|
log_transaction(reqInfo);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SC_NOT_IMPLEMENTED:
|
case SC_NOT_IMPLEMENTED:
|
||||||
reqInfo->status = SC_NOT_IMPLEMENTED;
|
reqInfo->status = SC_NOT_IMPLEMENTED;
|
||||||
|
set_stat_line(reqInfo);
|
||||||
if (((x=have_doc_error(reqInfo,type)) >= 0) && (!ErrorStat)) {
|
if (((x=have_doc_error(reqInfo,type)) >= 0) && (!ErrorStat)) {
|
||||||
ErrorStat = reqInfo->status;
|
ErrorStat = reqInfo->status;
|
||||||
GoErrorDoc(reqInfo,x,err_string);
|
GoErrorDoc(reqInfo,x,err_string);
|
||||||
@ -544,10 +572,10 @@ int die(per_request *reqInfo, int type, char *err_string)
|
|||||||
error_head(reqInfo,StatLine501);
|
error_head(reqInfo,StatLine501);
|
||||||
keep_alive.bKeepAlive = 0;
|
keep_alive.bKeepAlive = 0;
|
||||||
if (reqInfo->method != M_HEAD) {
|
if (reqInfo->method != M_HEAD) {
|
||||||
fprintf(reqInfo->out,"We are sorry to be unable to perform the method %s",
|
rprintf(reqInfo,"We are sorry to be unable to perform the method %s",
|
||||||
err_string);
|
err_string);
|
||||||
fprintf(reqInfo->out," at this time or to this document.<P>%c",LF);
|
rprintf(reqInfo," at this time or to this document.<P>%c",LF);
|
||||||
fprintf(reqInfo->out,"</BODY>%c",LF);
|
rprintf(reqInfo,"</BODY>%c",LF);
|
||||||
}
|
}
|
||||||
log_transaction(reqInfo);
|
log_transaction(reqInfo);
|
||||||
}
|
}
|
||||||
@ -555,30 +583,33 @@ int die(per_request *reqInfo, int type, char *err_string)
|
|||||||
case SC_NO_MEMORY:
|
case SC_NO_MEMORY:
|
||||||
log_error("HTTPd: memory exhausted",reqInfo->hostInfo->error_log);
|
log_error("HTTPd: memory exhausted",reqInfo->hostInfo->error_log);
|
||||||
reqInfo->status = SC_SERVER_ERROR;
|
reqInfo->status = SC_SERVER_ERROR;
|
||||||
|
set_stat_line(reqInfo);
|
||||||
die_type = DIE_NORMAL;
|
die_type = DIE_NORMAL;
|
||||||
error_head(reqInfo,StatLine500);
|
error_head(reqInfo,StatLine500);
|
||||||
keep_alive.bKeepAlive = 0;
|
keep_alive.bKeepAlive = 0;
|
||||||
if (reqInfo->method != M_HEAD) {
|
if (reqInfo->method != M_HEAD) {
|
||||||
fprintf(reqInfo->out,"The server has temporarily run out of resources%c",LF);
|
rprintf(reqInfo,"The server has temporarily run out of resources%c",LF);
|
||||||
fprintf(reqInfo->out,"for your request. Please try again at a later time.<P>%c",LF);
|
rprintf(reqInfo,"for your request. Please try again at a later time.<P>%c",LF);
|
||||||
fprintf(reqInfo->out,"</BODY>%c",LF);
|
rprintf(reqInfo,"</BODY>%c",LF);
|
||||||
}
|
}
|
||||||
log_transaction(reqInfo);
|
log_transaction(reqInfo);
|
||||||
break;
|
break;
|
||||||
case SC_CONF_ERROR:
|
case SC_CONF_ERROR:
|
||||||
reqInfo->status = SC_SERVER_ERROR;
|
reqInfo->status = SC_SERVER_ERROR;
|
||||||
sprintf(arguments,"httpd: configuration error = %s",err_string);
|
set_stat_line(reqInfo);
|
||||||
|
sprintf(arguments,"HTTPd: configuration error = %s",err_string);
|
||||||
log_error(arguments,reqInfo->hostInfo->error_log);
|
log_error(arguments,reqInfo->hostInfo->error_log);
|
||||||
error_head(reqInfo,StatLine500);
|
error_head(reqInfo,StatLine500);
|
||||||
keep_alive.bKeepAlive = 0;
|
keep_alive.bKeepAlive = 0;
|
||||||
if (reqInfo->method != M_HEAD) {
|
if (reqInfo->method != M_HEAD) {
|
||||||
fprintf(reqInfo->out,"The server has encountered a misconfiguration.%c",LF);
|
rprintf(reqInfo,"The server has encountered a misconfiguration.%c",LF);
|
||||||
fprintf(reqInfo->out,"The error was %s.%c",err_string,LF);
|
rprintf(reqInfo,"The error was %s.%c",err_string,LF);
|
||||||
fprintf(reqInfo->out,"</BODY>%c",LF);
|
rprintf(reqInfo,"</BODY>%c",LF);
|
||||||
}
|
}
|
||||||
log_transaction(reqInfo);
|
log_transaction(reqInfo);
|
||||||
}
|
}
|
||||||
fflush(reqInfo->out);
|
rflush(reqInfo);
|
||||||
|
freeString(arguments);
|
||||||
if (!RetVal)
|
if (!RetVal)
|
||||||
htexit(reqInfo,1,die_type);
|
htexit(reqInfo,1,die_type);
|
||||||
return RetVal;
|
return RetVal;
|
||||||
@ -587,7 +618,7 @@ int die(per_request *reqInfo, int type, char *err_string)
|
|||||||
int GoErrorDoc(per_request *reqInfo, int x, char *ErrString) {
|
int GoErrorDoc(per_request *reqInfo, int x, char *ErrString) {
|
||||||
per_request *newInfo;
|
per_request *newInfo;
|
||||||
|
|
||||||
newInfo = continue_request(reqInfo,NEW_URL | FORCE_GET | KEEP_ENV | KEEP_AUTH);
|
newInfo = continue_request(reqInfo, FORCE_GET | KEEP_ENV | KEEP_AUTH);
|
||||||
strcpy(newInfo->url,reqInfo->hostInfo->doc_errors[x]->DocErrorFile);
|
strcpy(newInfo->url,reqInfo->hostInfo->doc_errors[x]->DocErrorFile);
|
||||||
if (ErrString)
|
if (ErrString)
|
||||||
sprintf(newInfo->args,"error=%s",ErrString);
|
sprintf(newInfo->args,"error=%s",ErrString);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* http_log.h,v 1.15 1995/11/28 09:02:05 blong Exp
|
* http_log.h,v 1.18 1996/03/06 23:21:06 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
/* globals defined in this module */
|
/* globals defined in this module */
|
||||||
extern const char StatLine200[];
|
extern const char StatLine200[];
|
||||||
|
extern const char StatLine204[];
|
||||||
extern const char StatLine301[];
|
extern const char StatLine301[];
|
||||||
extern const char StatLine302[];
|
extern const char StatLine302[];
|
||||||
extern const char StatLine304[];
|
extern const char StatLine304[];
|
||||||
@ -51,6 +52,7 @@ extern const char StatLine404[];
|
|||||||
extern const char StatLine408[];
|
extern const char StatLine408[];
|
||||||
extern const char StatLine500[];
|
extern const char StatLine500[];
|
||||||
extern const char StatLine501[];
|
extern const char StatLine501[];
|
||||||
|
extern const char StatLine503[];
|
||||||
extern char error_msg[];
|
extern char error_msg[];
|
||||||
|
|
||||||
extern int ErrorStat;
|
extern int ErrorStat;
|
||||||
@ -66,7 +68,6 @@ void close_logs(per_host *host);
|
|||||||
void error_log2stderr(FILE *error_log);
|
void error_log2stderr(FILE *error_log);
|
||||||
|
|
||||||
void title_html(per_request *reqInfo, char *msg);
|
void title_html(per_request *reqInfo, char *msg);
|
||||||
void begin_http_header(per_request *reqInfo, const char *msg);
|
|
||||||
|
|
||||||
int die(per_request *reqInfo, int type, char *err_string);
|
int die(per_request *reqInfo, int type, char *err_string);
|
||||||
|
|
||||||
|
275
src/http_mime.c
275
src/http_mime.c
@ -10,28 +10,14 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* http_mime.c,v 1.98 1995/11/28 09:02:07 blong Exp
|
* http_mime.c,v 1.106 1996/03/13 18:28:39 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* http_mime.c: Sends/gets MIME headers for requests
|
* http_mime.c: maintains the list of mime types, encodings. Currently
|
||||||
|
* still contains functions for setting some HTTP headers, probably be
|
||||||
|
* moved eventually.
|
||||||
*
|
*
|
||||||
* Based on NCSA HTTPd 1.3 by Rob McCool
|
|
||||||
*
|
|
||||||
* 03/19/95 blong
|
|
||||||
* Added set_stat_line as part of making user config error messages work
|
|
||||||
* The correct status line should now be sent back
|
|
||||||
*
|
|
||||||
* 04/20/95 blong
|
|
||||||
* Added a modified "B18" from apache patches by Rob Hartill
|
|
||||||
*
|
|
||||||
* 08/07/95 blong
|
|
||||||
* Moved scan_script_header() function to cgi.c in an attempt at
|
|
||||||
* increased modularity of the code (at least representatively)
|
|
||||||
*
|
|
||||||
* 10/30/95 blong
|
|
||||||
* Fixed get_mime_header string length problems as suggested by
|
|
||||||
* Marc Evans (Marc@Destek.NET)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -57,11 +43,13 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "fdwrap.h"
|
#include "fdwrap.h"
|
||||||
|
#include "allocate.h"
|
||||||
#include "http_mime.h"
|
#include "http_mime.h"
|
||||||
#include "http_log.h"
|
#include "http_log.h"
|
||||||
#include "http_config.h"
|
#include "http_config.h"
|
||||||
#include "http_access.h"
|
#include "http_access.h"
|
||||||
#include "env.h"
|
#include "env.h"
|
||||||
|
#include "http_request.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#if defined(KRB4) || defined(KRB5)
|
#if defined(KRB4) || defined(KRB5)
|
||||||
@ -81,27 +69,6 @@ struct mime_ext *encoding_types;
|
|||||||
struct mime_ext *Saved_Forced;
|
struct mime_ext *Saved_Forced;
|
||||||
struct mime_ext *Saved_Encoding;
|
struct mime_ext *Saved_Encoding;
|
||||||
|
|
||||||
int content_length;
|
|
||||||
char content_type[MAX_STRING_LEN];
|
|
||||||
char content_type_in[MAX_STRING_LEN];
|
|
||||||
char content_encoding[MAX_STRING_LEN];
|
|
||||||
|
|
||||||
char location[MAX_STRING_LEN];
|
|
||||||
static char last_modified[MAX_STRING_LEN];
|
|
||||||
|
|
||||||
char auth_line[HUGE_STRING_LEN];
|
|
||||||
|
|
||||||
char called_hostname[MAX_STRING_LEN];
|
|
||||||
|
|
||||||
char *out_headers = NULL;
|
|
||||||
char *status_line = NULL;
|
|
||||||
char ims[MAX_STRING_LEN]; /* If-modified-since */
|
|
||||||
|
|
||||||
#ifdef HAVE_KERBEROS
|
|
||||||
char out_auth_header[1024];
|
|
||||||
#endif /* HAVE_KERBEROS */
|
|
||||||
|
|
||||||
|
|
||||||
void hash_insert(struct mime_ext *me) {
|
void hash_insert(struct mime_ext *me) {
|
||||||
register int i = hash(me->ext[0]);
|
register int i = hash(me->ext[0]);
|
||||||
register struct mime_ext *p, *q;
|
register struct mime_ext *p, *q;
|
||||||
@ -168,7 +135,7 @@ void init_mime(void)
|
|||||||
reqInfo.out = stderr;
|
reqInfo.out = stderr;
|
||||||
|
|
||||||
if(!(f = FOpen(types_confname,"r"))) {
|
if(!(f = FOpen(types_confname,"r"))) {
|
||||||
fprintf(stderr,"httpd: could not open mime types file %s\n",
|
fprintf(stderr,"HTTPd: could not open mime types file %s\n",
|
||||||
types_confname);
|
types_confname);
|
||||||
perror("fopen");
|
perror("fopen");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -225,11 +192,10 @@ void dump_types(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
int is_content_type(char *type) {
|
|
||||||
return(!strcmp(content_type,type));
|
|
||||||
}
|
|
||||||
|
|
||||||
void find_ct(per_request *reqInfo, char *file, int store_encoding) {
|
void find_ct(per_request *reqInfo, char *file,
|
||||||
|
char *content_type, char *content_encoding)
|
||||||
|
{
|
||||||
int i,l,l2;
|
int i,l,l2;
|
||||||
struct mime_ext *p;
|
struct mime_ext *p;
|
||||||
char fn[MAX_STRING_LEN];
|
char fn[MAX_STRING_LEN];
|
||||||
@ -246,7 +212,7 @@ void find_ct(per_request *reqInfo, char *file, int store_encoding) {
|
|||||||
while(p) {
|
while(p) {
|
||||||
if(!strcmp(p->ext,&fn[i])) {
|
if(!strcmp(p->ext,&fn[i])) {
|
||||||
fn[i-1] = '\0';
|
fn[i-1] = '\0';
|
||||||
if(store_encoding) {
|
if(content_encoding != NULL) {
|
||||||
if(content_encoding[0])
|
if(content_encoding[0])
|
||||||
sprintf(content_encoding,"%s, %s",content_encoding,
|
sprintf(content_encoding,"%s, %s",content_encoding,
|
||||||
p->ct);
|
p->ct);
|
||||||
@ -299,14 +265,20 @@ void find_ct(per_request *reqInfo, char *file, int store_encoding) {
|
|||||||
|
|
||||||
void probe_content_type(per_request *reqInfo, char *file)
|
void probe_content_type(per_request *reqInfo, char *file)
|
||||||
{
|
{
|
||||||
find_ct(reqInfo,file,0);
|
find_ct(reqInfo,file,reqInfo->outh_content_type,NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_content_type(per_request *reqInfo, char *file)
|
void set_content_type(per_request *reqInfo, char *file)
|
||||||
{
|
{
|
||||||
find_ct(reqInfo,file,1);
|
find_ct(reqInfo,file,reqInfo->outh_content_type,
|
||||||
|
reqInfo->outh_content_encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void get_content_type(per_request *reqInfo, char *file,
|
||||||
|
char *content_type, char *content_encoding)
|
||||||
|
{
|
||||||
|
find_ct(reqInfo,file,content_type,content_encoding);
|
||||||
|
}
|
||||||
|
|
||||||
/* Should remove all the added types from .htaccess files when the
|
/* Should remove all the added types from .htaccess files when the
|
||||||
child sticks around */
|
child sticks around */
|
||||||
@ -370,217 +342,76 @@ void add_encoding(per_request *reqInfo, char *fn, char *t) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void set_content_length(per_request *reqInfo, int l) {
|
void set_content_length(per_request *reqInfo, int l) {
|
||||||
content_length = l;
|
reqInfo->outh_content_length = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
int set_last_modified(per_request *reqInfo, time_t t) {
|
int set_last_modified(per_request *reqInfo, time_t t) {
|
||||||
struct tm *tms;
|
struct tm *tms;
|
||||||
char ts[MAX_STRING_LEN];
|
/* char ts[MAX_STRING_LEN]; */
|
||||||
|
|
||||||
tms = gmtime(&t);
|
tms = gmtime(&t);
|
||||||
strftime(ts,MAX_STRING_LEN,HTTP_TIME_FORMAT,tms);
|
strftime(reqInfo->outh_last_mod,MAX_STRING_LEN,HTTP_TIME_FORMAT,tms);
|
||||||
strcpy(last_modified,ts);
|
/* strcpy(reqInfo->outh_last_mod,ts); */
|
||||||
|
|
||||||
if(!ims[0])
|
if(!reqInfo->inh_if_mod_since[0])
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(later_than(tms, ims))
|
if(later_than(tms, reqInfo->inh_if_mod_since))
|
||||||
return die(reqInfo,SC_USE_LOCAL_COPY,NULL);
|
return die(reqInfo,SC_USE_LOCAL_COPY,NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_header_vars(per_request *reqInfo)
|
|
||||||
{
|
|
||||||
content_type[0] = '\0';
|
|
||||||
content_type_in[0] = '\0';
|
|
||||||
last_modified[0] = '\0';
|
|
||||||
content_length = -1;
|
|
||||||
auth_line[0] = '\0';
|
|
||||||
content_encoding[0] = '\0';
|
|
||||||
location[0] = '\0';
|
|
||||||
ims[0] = '\0';
|
|
||||||
if (status_line != NULL) free(status_line);
|
|
||||||
status_line = NULL;
|
|
||||||
if (out_headers != NULL) free(out_headers);
|
|
||||||
out_headers = NULL;
|
|
||||||
|
|
||||||
#ifdef HAVE_KERBEROS
|
|
||||||
out_auth_header[0] = '\0';
|
|
||||||
#endif /* HAVE_KERBEROS */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Globals for speed because of size, these are for get_mime_headers */
|
|
||||||
static char field_type[HUGE_STRING_LEN];
|
|
||||||
static char unrec_hdr[HUGE_STRING_LEN];
|
|
||||||
static char unrec_hdr_val[HUGE_STRING_LEN];
|
|
||||||
|
|
||||||
void get_mime_headers(per_request *reqInfo)
|
|
||||||
{
|
|
||||||
char *field_val;
|
|
||||||
|
|
||||||
#ifdef DIGEST_AUTH
|
|
||||||
client_accepts_digest = assume_digest_support;
|
|
||||||
#endif /* DIGEST_AUTH */
|
|
||||||
while(getline(reqInfo->connection_socket,field_type,HUGE_STRING_LEN-1,0,
|
|
||||||
timeout) != -1) {
|
|
||||||
if(!field_type[0])
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(!(field_val = strchr(field_type,':')))
|
|
||||||
continue;
|
|
||||||
*field_val++ = '\0';
|
|
||||||
while(isspace(*field_val)) ++field_val;
|
|
||||||
|
|
||||||
if(!strcasecmp(field_type,"Content-type")) {
|
|
||||||
strncpy(content_type_in,field_val,MAX_STRING_LEN);
|
|
||||||
content_type_in[MAX_STRING_LEN-1] = '\0';
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(!strcasecmp(field_type,"Authorization")) {
|
|
||||||
strncpy(auth_line,field_val,HUGE_STRING_LEN);
|
|
||||||
auth_line[HUGE_STRING_LEN-1]='\0';
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(!strcasecmp(field_type,"Host")) {
|
|
||||||
strncpy(called_hostname, field_val, MAX_STRING_LEN);
|
|
||||||
called_hostname[MAX_STRING_LEN-1] = '\0';
|
|
||||||
}
|
|
||||||
if(!strcasecmp(field_type,"Extension")) {
|
|
||||||
if (!strcasecmp(field_val, "Notify-Domain-Restriction"))
|
|
||||||
reqInfo->bNotifyDomainRestricted = 1;
|
|
||||||
#ifdef DIGEST_AUTH
|
|
||||||
else if (!strcasecmp(field_val, "Security/Digest"))
|
|
||||||
client_accepts_digest = 1;
|
|
||||||
#endif /* DIGEST_AUTH */
|
|
||||||
}
|
|
||||||
if(!strcasecmp(field_type,"Content-length")) {
|
|
||||||
sscanf(field_val,"%d",&content_length);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(!strcasecmp(field_type,"Connection")) {
|
|
||||||
if (!strcasecmp(field_val, "Keep-Alive") &&
|
|
||||||
keep_alive.bAllowKeepAlive)
|
|
||||||
keep_alive.bKeepAlive = 1;
|
|
||||||
}
|
|
||||||
if(!strcasecmp(field_type,"User-agent")) {
|
|
||||||
strncpy(reqInfo->agent, field_val, HUGE_STRING_LEN);
|
|
||||||
reqInfo->agent[HUGE_STRING_LEN-1] = '\0';
|
|
||||||
}
|
|
||||||
if(!strcasecmp(field_type,"Referer")) {
|
|
||||||
strncpy(reqInfo->referer, field_val, HUGE_STRING_LEN);
|
|
||||||
reqInfo->referer[HUGE_STRING_LEN-1] = '\0';
|
|
||||||
}
|
|
||||||
if(!strcasecmp(field_type,"If-modified-since")) {
|
|
||||||
strcpy(ims,field_val);
|
|
||||||
ims[MAX_STRING_LEN-1] = '\0';
|
|
||||||
}
|
|
||||||
http2cgi(unrec_hdr, field_type);
|
|
||||||
strcpy (unrec_hdr_val, field_val);
|
|
||||||
if(reqInfo->env) {
|
|
||||||
if(!merge_header(reqInfo,unrec_hdr,field_val))
|
|
||||||
make_env_str(reqInfo,unrec_hdr,field_val);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
make_env_str(reqInfo,unrec_hdr,field_val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void dump_default_header(per_request *reqInfo)
|
|
||||||
{
|
|
||||||
fprintf(reqInfo->out,"Date: %s%c",gm_timestr_822(time(NULL)),LF);
|
|
||||||
fprintf(reqInfo->out,"Server: %s%c",SERVER_VERSION,LF);
|
|
||||||
if (reqInfo->hostInfo->annotation_server[0])
|
|
||||||
fprintf(reqInfo->out,"Annotations-cgi: %s%c",
|
|
||||||
reqInfo->hostInfo->annotation_server,LF);
|
|
||||||
|
|
||||||
/* Not part of HTTP spec, removed. */
|
|
||||||
/* fprintf(fd,"MIME-version: 1.0%c",LF); */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* This needs to malloc in case a CGI script passes back its own
|
/* This needs to malloc in case a CGI script passes back its own
|
||||||
* status_line, so we can free without problem.
|
* status_line, so we can free without problem.
|
||||||
*/
|
*/
|
||||||
char* set_stat_line(per_request *reqInfo)
|
char* set_stat_line(per_request *reqInfo)
|
||||||
{
|
{
|
||||||
if (status_line) free(status_line);
|
if (reqInfo->status_line) {
|
||||||
|
freeString(reqInfo->status_line);
|
||||||
|
}
|
||||||
|
|
||||||
switch (reqInfo->status) {
|
switch (reqInfo->status) {
|
||||||
case 302:
|
case 200:
|
||||||
status_line = strdup((char *)StatLine302);
|
reqInfo->status_line = dupStringP((char *)StatLine200,STR_REQ);
|
||||||
break;
|
break;
|
||||||
case 304:
|
case 204:
|
||||||
status_line = strdup((char *)StatLine304);
|
reqInfo->status_line = dupStringP((char *)StatLine204,STR_REQ);
|
||||||
|
break;
|
||||||
|
case 301:
|
||||||
|
reqInfo->status_line = dupStringP((char *)StatLine301,STR_REQ);
|
||||||
|
break;
|
||||||
|
case 302:
|
||||||
|
reqInfo->status_line = dupStringP((char *)StatLine302,STR_REQ);
|
||||||
|
break;
|
||||||
|
case 304:
|
||||||
|
reqInfo->status_line = dupStringP((char *)StatLine304,STR_REQ);
|
||||||
break;
|
break;
|
||||||
case 400:
|
case 400:
|
||||||
status_line = strdup((char *)StatLine400);
|
reqInfo->status_line = dupStringP((char *)StatLine400,STR_REQ);
|
||||||
break;
|
break;
|
||||||
case 401:
|
case 401:
|
||||||
status_line = strdup((char *)StatLine401);
|
reqInfo->status_line = dupStringP((char *)StatLine401,STR_REQ);
|
||||||
break;
|
break;
|
||||||
case 403:
|
case 403:
|
||||||
status_line = strdup((char *)StatLine403);
|
reqInfo->status_line = dupStringP((char *)StatLine403,STR_REQ);
|
||||||
break;
|
break;
|
||||||
case 404:
|
case 404:
|
||||||
status_line = strdup((char *)StatLine404);
|
reqInfo->status_line = dupStringP((char *)StatLine404,STR_REQ);
|
||||||
break;
|
break;
|
||||||
case 500:
|
case 500:
|
||||||
status_line = strdup((char *)StatLine500);
|
reqInfo->status_line = dupStringP((char *)StatLine500,STR_REQ);
|
||||||
break;
|
break;
|
||||||
case 501:
|
case 501:
|
||||||
status_line = strdup((char *)StatLine501);
|
reqInfo->status_line = dupStringP((char *)StatLine501,STR_REQ);
|
||||||
|
break;
|
||||||
|
case 503:
|
||||||
|
reqInfo->status_line = dupStringP((char *)StatLine503,STR_REQ);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
status_line = strdup((char *)StatLine200);
|
reqInfo->status_line = dupStringP((char *)StatLine200,STR_REQ);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return status_line;
|
return reqInfo->status_line;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void send_http_header(per_request *reqInfo)
|
|
||||||
{
|
|
||||||
if(!status_line) {
|
|
||||||
if(location[0]) {
|
|
||||||
reqInfo->status = 302;
|
|
||||||
status_line = strdup((char *)StatLine302);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
set_stat_line(reqInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
begin_http_header(reqInfo,status_line);
|
|
||||||
if(content_type[0])
|
|
||||||
fprintf(reqInfo->out,"Content-type: %s%c",content_type,LF);
|
|
||||||
if(last_modified[0])
|
|
||||||
fprintf(reqInfo->out,"Last-modified: %s%c",last_modified,LF);
|
|
||||||
if(content_length >= 0)
|
|
||||||
fprintf(reqInfo->out,"Content-length: %d%c",content_length,LF);
|
|
||||||
if(location[0])
|
|
||||||
fprintf(reqInfo->out,"Location: %s%c",location,LF);
|
|
||||||
if(content_encoding[0])
|
|
||||||
fprintf(reqInfo->out,"Content-encoding: %s%c",content_encoding,LF);
|
|
||||||
|
|
||||||
if (reqInfo->bNotifyDomainRestricted && reqInfo->bSatisfiedDomain)
|
|
||||||
fprintf(reqInfo->out,"Extension: Domain-Restricted%c", LF);
|
|
||||||
|
|
||||||
keep_alive.bKeepAlive = keep_alive.bKeepAlive && (content_length >= 0);
|
|
||||||
if (keep_alive.bKeepAlive && (!keep_alive.nMaxRequests ||
|
|
||||||
keep_alive.nCurrRequests + 1 <
|
|
||||||
keep_alive.nMaxRequests)) {
|
|
||||||
keep_alive.bKeepAlive = 1;
|
|
||||||
fprintf(reqInfo->out,
|
|
||||||
"Connection: Keep-Alive%cKeep-Alive: max=%d, timeout=%d%c",
|
|
||||||
LF, keep_alive.nMaxRequests, keep_alive.nTimeOut, LF);
|
|
||||||
}
|
|
||||||
if(out_headers)
|
|
||||||
fprintf(reqInfo->out,"%s",out_headers);
|
|
||||||
#ifdef HAVE_KERBEROS
|
|
||||||
if (out_auth_header[0])
|
|
||||||
fprintf (reqInfo->out, "%s", out_auth_header);
|
|
||||||
#endif /* HAVE_KERBEROS */
|
|
||||||
fprintf(reqInfo->out,"%c",LF);
|
|
||||||
fflush(reqInfo->out);
|
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* http_mime.h,v 1.16 1995/11/28 09:02:08 blong Exp
|
* http_mime.h,v 1.19 1996/02/22 23:47:04 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
@ -32,39 +32,29 @@ struct mime_ext {
|
|||||||
|
|
||||||
/* globals defined in this module */
|
/* globals defined in this module */
|
||||||
|
|
||||||
extern char content_type[];
|
|
||||||
extern char content_type_in[];
|
|
||||||
extern char content_encoding[];
|
|
||||||
extern int content_length;
|
|
||||||
extern char location[];
|
|
||||||
extern char auth_line[];
|
|
||||||
extern char called_hostname[];
|
|
||||||
extern struct mime_ext *Saved_Forced;
|
extern struct mime_ext *Saved_Forced;
|
||||||
extern struct mime_ext *Saved_Encoding;
|
extern struct mime_ext *Saved_Encoding;
|
||||||
extern struct mime_ext *forced_types;
|
extern struct mime_ext *forced_types;
|
||||||
extern struct mime_ext *encoding_types;
|
extern struct mime_ext *encoding_types;
|
||||||
extern char *out_headers;
|
|
||||||
|
|
||||||
/* http_mime function prototypes */
|
/* http_mime function prototypes */
|
||||||
void get_mime_headers(per_request *reqInfo);
|
|
||||||
|
|
||||||
void send_http_header(per_request *reqInfo);
|
|
||||||
void set_content_type(per_request *reqInfo, char *fn);
|
void set_content_type(per_request *reqInfo, char *fn);
|
||||||
int set_last_modified(per_request *reqInfo, time_t t);
|
|
||||||
void probe_content_type(per_request *reqInfo, char *fn);
|
void probe_content_type(per_request *reqInfo, char *fn);
|
||||||
int scan_script_header(per_request *reqInfo, int pd);
|
void set_content_length(per_request *reqInfo, int l);
|
||||||
|
void get_content_type(per_request *reqInfo, char *file,
|
||||||
|
char *content_type, char *content_encoding);
|
||||||
|
|
||||||
|
int set_last_modified(per_request *reqInfo, time_t t);
|
||||||
|
|
||||||
void add_type(per_request *reqInfo, char *fn, char *t);
|
void add_type(per_request *reqInfo, char *fn, char *t);
|
||||||
void add_encoding(per_request *reqInfo, char *fn, char *t);
|
void add_encoding(per_request *reqInfo, char *fn, char *t);
|
||||||
void set_content_length(per_request *reqInfo, int l);
|
|
||||||
void dump_types(void);
|
void dump_types(void);
|
||||||
void init_mime(void);
|
void init_mime(void);
|
||||||
void kill_mime(void);
|
void kill_mime(void);
|
||||||
void reset_mime_vars(void);
|
void reset_mime_vars(void);
|
||||||
int is_content_type(char *type);
|
|
||||||
void dump_default_header(per_request *reqInfo);
|
|
||||||
void init_header_vars(per_request *reqInfo);
|
|
||||||
|
|
||||||
extern char *status_line;
|
|
||||||
char* set_stat_line(per_request *reqInfo);
|
char* set_stat_line(per_request *reqInfo);
|
||||||
|
|
||||||
#endif /* _HTTP_MIME_H_ */
|
#endif /* _HTTP_MIME_H_ */
|
||||||
|
@ -10,23 +10,19 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* http_request.c,v 1.99 1995/11/06 20:58:09 blong Exp
|
* http_request.c,v 1.113 1996/04/05 18:55:02 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* http_request.c: functions to get and process requests
|
* http_request.c: functions to handle the request structure and initial
|
||||||
|
* request handling including decoding
|
||||||
*
|
*
|
||||||
* 03-21-95 Based on NCSA HTTPd 1.3 by Rob McCool
|
* 03-21-95 Based on NCSA HTTPd 1.3 by Rob McCool
|
||||||
|
* 05-17-95 NCSA HTTPd 1.4.1
|
||||||
|
* 05-01-95 NCSA HTTPd 1.4.2
|
||||||
|
* 11-10-95 NCSA HTTPd 1.5.0
|
||||||
|
* 11-14-95 NCSA HTTPd 1.5.0a
|
||||||
*
|
*
|
||||||
* 04-19-95 blong
|
|
||||||
* Forgot to remove free(remote_ip) from here, like elsewhere
|
|
||||||
*
|
|
||||||
* 04-20-95 blong
|
|
||||||
* Added patch "B18" for redirects w/o delay by Robert Hartill
|
|
||||||
*
|
|
||||||
* 05-01-95 blong
|
|
||||||
* Added patch by Steve Abatangle (sabat@enterprise.DTS.Harris.COM)
|
|
||||||
* to log SIGPIPE and timed out differently in send_fd_timed_out
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -38,44 +34,61 @@
|
|||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
#endif /* NO_STDLIB_H */
|
#endif /* NO_STDLIB_H */
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <setjmp.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <setjmp.h>
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "httpd.h"
|
#include "allocate.h" /* for freeString() */
|
||||||
|
#include "cgi.h" /* for exec_cgi_script() */
|
||||||
|
#ifdef FCGI_SUPPORT
|
||||||
|
# include "fcgi.h" /* for FastCgiHandler() */
|
||||||
|
#endif /* FCGI */
|
||||||
|
#include "env.h" /* for free_env() */
|
||||||
|
#include "http_access.h" /* for reset_security() */
|
||||||
|
#include "http_alias.h" /* For translate_name() */
|
||||||
|
#include "host_config.h" /* For which_host_conf(), gConfiguration */
|
||||||
|
#include "http_config.h" /* For timeout */
|
||||||
|
#include "http_log.h" /* For die(),ErrorStat */
|
||||||
|
#include "http_send.h" /* for send_node() */
|
||||||
|
#include "util.h" /* for strcasecmp(), etc */
|
||||||
#include "http_request.h"
|
#include "http_request.h"
|
||||||
#include "http_send.h"
|
|
||||||
#include "cgi.h"
|
|
||||||
#include "http_access.h"
|
|
||||||
#include "http_mime.h"
|
|
||||||
#include "http_config.h"
|
|
||||||
#include "host_config.h"
|
|
||||||
#include "http_log.h"
|
|
||||||
#include "http_auth.h"
|
|
||||||
#include "http_alias.h"
|
|
||||||
#include "env.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
int no_headers;
|
int req_count = 0;
|
||||||
int header_only;
|
int cgibuf_count = 0;
|
||||||
|
int sockbuf_count = 0;
|
||||||
|
|
||||||
per_request *gCurrentRequest;
|
per_request *gCurrentRequest;
|
||||||
|
|
||||||
|
/* *sigh* Yeah, we still have some globals left. We could probably
|
||||||
|
* move these into the request structure as well . . . its hitting
|
||||||
|
* 100k in size, though.
|
||||||
|
*/
|
||||||
/* If RFC931 identity check is on, the remote user name */
|
/* If RFC931 identity check is on, the remote user name */
|
||||||
char *remote_logname;
|
char *remote_logname;
|
||||||
|
|
||||||
/* Per request information */
|
/* Per request information */
|
||||||
|
|
||||||
char the_request[HUGE_STRING_LEN];
|
char the_request[HUGE_STRING_LEN];
|
||||||
char as_requested[HUGE_STRING_LEN];
|
char as_requested[HUGE_STRING_LEN];
|
||||||
char failed_request[HUGE_STRING_LEN];
|
char failed_request[HUGE_STRING_LEN];
|
||||||
char failed_url[HUGE_STRING_LEN];
|
char failed_url[HUGE_STRING_LEN];
|
||||||
|
#ifdef LOG_DURATION
|
||||||
|
time_t request_time = 0;
|
||||||
|
#endif /* LOG_DURATION */
|
||||||
|
|
||||||
char *methods[METHODS] = {"GET","HEAD","POST","PUT","DELETE","LINK","UNLINK"};
|
/* String constants for the request. Numbers are in constants.h */
|
||||||
char *protocals[PROTOCALS] = {"HTTP","HTTP/0.9","HTTP/1.0","HTTP/1.1"};
|
char *methods[METHODS] = {"GET","HEAD","POST","PUT","DELETE","SECURE",
|
||||||
|
"LINK","UNLINK"};
|
||||||
|
char *protocals[PROTOCALS] = {"HTTP","HTTP/0.9","HTTP/1.0","HTTP/1.1",
|
||||||
|
"Secure-HTTP/1.1", "Secure-HTTP/1.2"};
|
||||||
|
|
||||||
|
/* initialize_request()
|
||||||
|
* either creates, or inits a request structure passed to it.
|
||||||
|
* This assumes that a request structure passed to it was passed
|
||||||
|
* through free_request, so it doesn't have any extra pointers that
|
||||||
|
* need to be dealt with (though it still checks env, that shouldn't
|
||||||
|
* be necessary)
|
||||||
|
*/
|
||||||
per_request *initialize_request(per_request *reqInfo)
|
per_request *initialize_request(per_request *reqInfo)
|
||||||
{
|
{
|
||||||
int RealInit = 0;
|
int RealInit = 0;
|
||||||
@ -83,42 +96,46 @@ per_request *initialize_request(per_request *reqInfo)
|
|||||||
|
|
||||||
RealInit = (reqInfo == NULL) ? 1 : 0;
|
RealInit = (reqInfo == NULL) ? 1 : 0;
|
||||||
|
|
||||||
newInfo = (per_request *) malloc(sizeof(per_request));
|
|
||||||
newInfo->hostInfo = gConfiguration;
|
|
||||||
|
|
||||||
if (RealInit) {
|
if (RealInit) {
|
||||||
|
newInfo = (per_request *) malloc(sizeof(per_request));
|
||||||
|
req_count++;
|
||||||
reqInfo = newInfo;
|
reqInfo = newInfo;
|
||||||
reqInfo->ownURL = TRUE;
|
|
||||||
reqInfo->ownDNS = TRUE;
|
reqInfo->ownDNS = TRUE;
|
||||||
reqInfo->dns_host_lookup = FALSE;
|
reqInfo->dns_host_lookup = FALSE;
|
||||||
reqInfo->remote_name = NULL;
|
reqInfo->remote_name = NULL;
|
||||||
reqInfo->remote_ip = NULL;
|
reqInfo->remote_ip = NULL;
|
||||||
reqInfo->remote_host = NULL;
|
reqInfo->remote_host = NULL;
|
||||||
reqInfo->next = NULL;
|
reqInfo->next = NULL;
|
||||||
} else {
|
reqInfo->ownENV = TRUE;
|
||||||
newInfo->next = reqInfo;
|
reqInfo->env = NULL;
|
||||||
reqInfo = newInfo;
|
reqInfo->outh_cgi = NULL;
|
||||||
reqInfo->ownURL = FALSE;
|
reqInfo->RequestFlags = 0;
|
||||||
reqInfo->ownDNS = FALSE;
|
reqInfo->sb = NULL;
|
||||||
reqInfo->dns_host_lookup = reqInfo->next->dns_host_lookup;
|
reqInfo->ownSB = TRUE;
|
||||||
reqInfo->remote_name = reqInfo->next->remote_name;
|
reqInfo->cgi_buf = NULL;
|
||||||
reqInfo->remote_host = reqInfo->next->remote_host;
|
}
|
||||||
reqInfo->remote_ip = reqInfo->next->remote_ip;
|
|
||||||
reqInfo->hostInfo = reqInfo->next->hostInfo;
|
reqInfo->hostInfo = gConfiguration;
|
||||||
}
|
|
||||||
|
|
||||||
/* Can't think (now) of any case where environment should transfer
|
/* Can't think (now) of any case where environment should transfer
|
||||||
from last request during KeepAlive, but in other cases, perhaps */
|
from last request during KeepAlive, but in other cases, perhaps */
|
||||||
|
|
||||||
|
if (reqInfo->ownENV && reqInfo->env) {
|
||||||
|
free_env(reqInfo);
|
||||||
|
}
|
||||||
|
|
||||||
reqInfo->ownENV = TRUE;
|
reqInfo->ownENV = TRUE;
|
||||||
reqInfo->env = NULL;
|
reqInfo->env = NULL;
|
||||||
reqInfo->env_len = NULL;
|
reqInfo->env_len = NULL;
|
||||||
reqInfo->num_env = 0;
|
reqInfo->num_env = 0;
|
||||||
reqInfo->max_env = 0;
|
reqInfo->max_env = 0;
|
||||||
|
|
||||||
|
|
||||||
/* initialize auth stuff */
|
/* initialize auth stuff */
|
||||||
reqInfo->bNotifyDomainRestricted = 0;
|
reqInfo->bNotifyDomainRestricted = 0;
|
||||||
reqInfo->bSatisfiedDomain = 0;
|
reqInfo->bSatisfiedDomain = 0;
|
||||||
|
reqInfo->bSatisfiedReferer = 0;
|
||||||
|
|
||||||
reqInfo->auth_name = "ByPassword";
|
reqInfo->auth_name = "ByPassword";
|
||||||
reqInfo->auth_pwfile = NULL;
|
reqInfo->auth_pwfile = NULL;
|
||||||
@ -140,46 +157,70 @@ per_request *initialize_request(per_request *reqInfo)
|
|||||||
|
|
||||||
/* Initialize Error codes */
|
/* Initialize Error codes */
|
||||||
ErrorStat = 0;
|
ErrorStat = 0;
|
||||||
/* status = 200; */
|
|
||||||
reqInfo->status = SC_DOCUMENT_FOLLOWS;
|
reqInfo->status = SC_DOCUMENT_FOLLOWS;
|
||||||
/* reqInfo->status_line = NULL; */
|
reqInfo->status_line = NULL;
|
||||||
reqInfo->bytes_sent = -1;
|
reqInfo->bytes_sent = -1;
|
||||||
|
|
||||||
reqInfo->auth_type[0] = '\0';
|
reqInfo->auth_type[0] = '\0';
|
||||||
|
|
||||||
if (!reqInfo->ownURL) {
|
|
||||||
strcpy(reqInfo->url, reqInfo->next->url);
|
|
||||||
strcpy(reqInfo->args, reqInfo->next->args);
|
|
||||||
strcpy(reqInfo->filename, reqInfo->next->filename);
|
|
||||||
}
|
|
||||||
reqInfo->url[0] = '\0';
|
reqInfo->url[0] = '\0';
|
||||||
reqInfo->args[0] = '\0';
|
reqInfo->args[0] = '\0';
|
||||||
|
reqInfo->path_info[0] = '\0';
|
||||||
reqInfo->filename[0] = '\0';
|
reqInfo->filename[0] = '\0';
|
||||||
|
|
||||||
reqInfo->agent[0] = '\0';
|
reqInfo->inh_agent[0] = '\0';
|
||||||
reqInfo->referer[0] = '\0';
|
reqInfo->inh_referer[0] = '\0';
|
||||||
|
reqInfo->inh_called_hostname[0] = '\0';
|
||||||
|
reqInfo->inh_if_mod_since[0] = '\0';
|
||||||
|
reqInfo->inh_auth_line[0] = '\0';
|
||||||
|
reqInfo->inh_content_type[0] = '\0';
|
||||||
|
reqInfo->inh_content_length = -1;
|
||||||
|
|
||||||
|
reqInfo->outh_location[0] = '\0';
|
||||||
|
reqInfo->outh_last_mod[0] = '\0';
|
||||||
|
reqInfo->outh_www_auth[0] = '\0';
|
||||||
|
reqInfo->outh_content_type[0] = '\0';
|
||||||
|
reqInfo->outh_content_encoding[0] = '\0';
|
||||||
|
reqInfo->outh_content_length = -1;
|
||||||
|
#ifdef CONTENT_MD5
|
||||||
|
reqInfo->outh_content_md5 = NULL;
|
||||||
|
#endif /* CONTENT_MD5 */
|
||||||
|
reqInfo->outh_cgi = NULL;
|
||||||
|
|
||||||
init_header_vars(reqInfo);
|
|
||||||
as_requested[0] = '\0';
|
as_requested[0] = '\0';
|
||||||
failed_url[0] = '\0';
|
failed_url[0] = '\0';
|
||||||
failed_request[0] = '\0';
|
failed_request[0] = '\0';
|
||||||
local_default_type[0] = '\0';
|
local_default_type[0] = '\0';
|
||||||
local_default_icon[0] = '\0';
|
local_default_icon[0] = '\0';
|
||||||
|
|
||||||
/* All but HEAD send more than a header */
|
|
||||||
header_only = 0;
|
|
||||||
|
|
||||||
/* reset keep-alive, client will indicate desire on next request */
|
/* reset keep-alive, client will indicate desire on next request */
|
||||||
keep_alive.bKeepAlive = 0;
|
keep_alive.bKeepAlive = 0;
|
||||||
|
|
||||||
return reqInfo;
|
return reqInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* continue_request()
|
||||||
|
* Used (especially in SSI and ErrorDocs) to handle "multiple"
|
||||||
|
* internal requests. Will probably be used for SHTTP requests
|
||||||
|
* since they can be wrapped multiple times.
|
||||||
|
* Will copy over all inbound http headers, clear all outbound
|
||||||
|
* http headers except outh_www_auth which depends on KEEP_AUTH
|
||||||
|
* Option values in constants.h
|
||||||
|
* Takes as options:
|
||||||
|
* KEEP_ENV : Copy ENV from passed request
|
||||||
|
* KEEP_AUTH : Copy auth info from passed request
|
||||||
|
* FORCE_GET : Unless a HEAD request, change to GET request
|
||||||
|
* (don't POST to ErrorDoc)
|
||||||
|
* COPY_URL : Copy URL from passed request
|
||||||
|
* NEW_SOCK_BUF: Set sb to NULL to cause a new sock buf to be created
|
||||||
|
*/
|
||||||
per_request *continue_request(per_request *reqInfo, int options) {
|
per_request *continue_request(per_request *reqInfo, int options) {
|
||||||
per_request *newInfo;
|
per_request *newInfo;
|
||||||
|
|
||||||
newInfo = (per_request *)malloc(sizeof(per_request));
|
newInfo = (per_request *)malloc(sizeof(per_request));
|
||||||
|
req_count++;
|
||||||
newInfo->status = reqInfo->status;
|
newInfo->status = reqInfo->status;
|
||||||
|
newInfo->status_line = NULL;
|
||||||
|
|
||||||
if (options & KEEP_ENV) {
|
if (options & KEEP_ENV) {
|
||||||
newInfo->ownENV = FALSE;
|
newInfo->ownENV = FALSE;
|
||||||
@ -197,6 +238,10 @@ per_request *continue_request(per_request *reqInfo, int options) {
|
|||||||
|
|
||||||
if (options & KEEP_AUTH) {
|
if (options & KEEP_AUTH) {
|
||||||
strcpy(newInfo->auth_type,reqInfo->auth_type);
|
strcpy(newInfo->auth_type,reqInfo->auth_type);
|
||||||
|
strcpy(newInfo->auth_user,reqInfo->auth_user);
|
||||||
|
strcpy(newInfo->auth_group,reqInfo->auth_group);
|
||||||
|
strcpy(newInfo->inh_auth_line,reqInfo->inh_auth_line);
|
||||||
|
strcpy(newInfo->outh_www_auth,reqInfo->outh_www_auth);
|
||||||
newInfo->auth_name = reqInfo->auth_name;
|
newInfo->auth_name = reqInfo->auth_name;
|
||||||
newInfo->auth_pwfile = reqInfo->auth_pwfile;
|
newInfo->auth_pwfile = reqInfo->auth_pwfile;
|
||||||
newInfo->auth_grpfile = reqInfo->auth_grpfile;
|
newInfo->auth_grpfile = reqInfo->auth_grpfile;
|
||||||
@ -207,8 +252,13 @@ per_request *continue_request(per_request *reqInfo, int options) {
|
|||||||
newInfo->auth_digestfile_type = newInfo->auth_digestfile_type;
|
newInfo->auth_digestfile_type = newInfo->auth_digestfile_type;
|
||||||
#endif /* DIGEST_AUTH */
|
#endif /* DIGEST_AUTH */
|
||||||
newInfo->bSatisfiedDomain = reqInfo->bSatisfiedDomain;
|
newInfo->bSatisfiedDomain = reqInfo->bSatisfiedDomain;
|
||||||
|
newInfo->bSatisfiedReferer = reqInfo->bSatisfiedReferer;
|
||||||
} else {
|
} else {
|
||||||
newInfo->auth_type[0] = '\0';
|
newInfo->auth_type[0] = '\0';
|
||||||
|
newInfo->auth_user[0] = '\0';
|
||||||
|
newInfo->auth_group[0] = '\0';
|
||||||
|
newInfo->inh_auth_line[0] = '\0';
|
||||||
|
newInfo->outh_www_auth[0] = '\0';
|
||||||
newInfo->auth_name = NULL;
|
newInfo->auth_name = NULL;
|
||||||
newInfo->auth_pwfile = NULL;
|
newInfo->auth_pwfile = NULL;
|
||||||
newInfo->auth_grpfile = NULL;
|
newInfo->auth_grpfile = NULL;
|
||||||
@ -219,6 +269,7 @@ per_request *continue_request(per_request *reqInfo, int options) {
|
|||||||
newInfo->auth_digestfile_type = 0;
|
newInfo->auth_digestfile_type = 0;
|
||||||
#endif /* DIGEST_AUTH */
|
#endif /* DIGEST_AUTH */
|
||||||
newInfo->bSatisfiedDomain = FALSE;
|
newInfo->bSatisfiedDomain = FALSE;
|
||||||
|
newInfo->bSatisfiedReferer = FALSE;
|
||||||
}
|
}
|
||||||
newInfo->bNotifyDomainRestricted = reqInfo->bNotifyDomainRestricted;
|
newInfo->bNotifyDomainRestricted = reqInfo->bNotifyDomainRestricted;
|
||||||
newInfo->bytes_sent = 0;
|
newInfo->bytes_sent = 0;
|
||||||
@ -232,39 +283,53 @@ per_request *continue_request(per_request *reqInfo, int options) {
|
|||||||
|
|
||||||
newInfo->http_version = reqInfo->http_version;
|
newInfo->http_version = reqInfo->http_version;
|
||||||
|
|
||||||
if (options & NEW_DNS) {
|
newInfo->ownDNS = FALSE;
|
||||||
newInfo->ownDNS = TRUE;
|
newInfo->dns_host_lookup = reqInfo->dns_host_lookup;
|
||||||
newInfo->dns_host_lookup = FALSE;
|
newInfo->remote_host = reqInfo->remote_host;
|
||||||
newInfo->remote_host = NULL;
|
newInfo->remote_name = reqInfo->remote_name;
|
||||||
newInfo->remote_name = NULL;
|
newInfo->remote_ip = reqInfo->remote_ip;
|
||||||
newInfo->remote_ip = NULL;
|
newInfo->hostInfo = reqInfo->hostInfo;
|
||||||
newInfo->hostInfo = NULL;
|
|
||||||
} else {
|
|
||||||
newInfo->ownDNS = FALSE;
|
|
||||||
newInfo->dns_host_lookup = reqInfo->dns_host_lookup;
|
|
||||||
newInfo->remote_host = reqInfo->remote_host;
|
|
||||||
newInfo->remote_name = reqInfo->remote_name;
|
|
||||||
newInfo->remote_ip = reqInfo->remote_ip;
|
|
||||||
newInfo->hostInfo = reqInfo->hostInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options & NEW_URL) {
|
|
||||||
newInfo->ownURL = TRUE;
|
if (options & COPY_URL) {
|
||||||
newInfo->url[0] = '\0';
|
|
||||||
newInfo->args[0] = '\0';
|
|
||||||
newInfo->filename[0] = '\0';
|
|
||||||
} else {
|
|
||||||
newInfo->ownURL = FALSE;
|
|
||||||
strcpy(newInfo->url, reqInfo->url);
|
strcpy(newInfo->url, reqInfo->url);
|
||||||
strcpy(newInfo->args, reqInfo->args);
|
strcpy(newInfo->args, reqInfo->args);
|
||||||
|
strcpy(newInfo->path_info, reqInfo->path_info);
|
||||||
strcpy(newInfo->filename, reqInfo->filename);
|
strcpy(newInfo->filename, reqInfo->filename);
|
||||||
|
} else {
|
||||||
|
newInfo->url[0] = '\0';
|
||||||
|
newInfo->args[0] = '\0';
|
||||||
|
newInfo->path_info[0] = '\0';
|
||||||
|
newInfo->filename[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(newInfo->referer,reqInfo->referer);
|
/* Copy all in headers */
|
||||||
strcpy(newInfo->agent,reqInfo->agent);
|
strcpy(newInfo->inh_agent,reqInfo->inh_agent);
|
||||||
|
strcpy(newInfo->inh_referer,reqInfo->inh_referer);
|
||||||
|
strcpy(newInfo->inh_called_hostname,reqInfo->inh_called_hostname);
|
||||||
|
strcpy(newInfo->inh_if_mod_since,reqInfo->inh_if_mod_since);
|
||||||
|
strcpy(newInfo->inh_content_type,reqInfo->inh_content_type);
|
||||||
|
newInfo->inh_content_length = reqInfo->inh_content_length;
|
||||||
|
|
||||||
|
/* Zero all out headers : outh_www_auth is handled in auth above */
|
||||||
|
newInfo->outh_location[0] = '\0';
|
||||||
|
newInfo->outh_last_mod[0] = '\0';
|
||||||
|
newInfo->outh_content_type[0] = '\0';
|
||||||
|
newInfo->outh_content_encoding[0] = '\0';
|
||||||
|
newInfo->outh_content_length = -1;
|
||||||
|
newInfo->outh_cgi = NULL;
|
||||||
|
|
||||||
newInfo->connection_socket = reqInfo->connection_socket;
|
newInfo->connection_socket = reqInfo->connection_socket;
|
||||||
|
newInfo->in = reqInfo->in;
|
||||||
newInfo->out = reqInfo->out;
|
newInfo->out = reqInfo->out;
|
||||||
|
if (options & NEW_SOCK_BUF) {
|
||||||
|
newInfo->ownSB = TRUE;
|
||||||
|
newInfo->sb = NULL;
|
||||||
|
} else {
|
||||||
|
newInfo->ownSB = FALSE;
|
||||||
|
newInfo->sb = reqInfo->sb;
|
||||||
|
}
|
||||||
|
newInfo->cgi_buf = NULL;
|
||||||
|
|
||||||
newInfo->next = reqInfo;
|
newInfo->next = reqInfo;
|
||||||
|
|
||||||
@ -272,27 +337,61 @@ per_request *continue_request(per_request *reqInfo, int options) {
|
|||||||
return newInfo;
|
return newInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* free_request()
|
||||||
|
* Clears the request structure linked list.
|
||||||
|
* Options: (from constants.h)
|
||||||
|
* ONLY_LAST : deletes only the top most (most recent)
|
||||||
|
* NOT_LAST : Don't delete the last one (so we don't have to malloc again)
|
||||||
|
*/
|
||||||
void free_request(per_request *reqInfo,int options) {
|
void free_request(per_request *reqInfo,int options) {
|
||||||
per_request *tmp = reqInfo;
|
per_request *tmp = reqInfo;
|
||||||
|
|
||||||
while (reqInfo != NULL) {
|
while (reqInfo != NULL) {
|
||||||
if (reqInfo->ownDNS) {
|
/* We'll just let the freeAllStrings clean up these instead. */
|
||||||
if (reqInfo->remote_name != NULL) free(reqInfo->remote_name);
|
reqInfo->remote_name = NULL;
|
||||||
if (reqInfo->remote_host != NULL) free(reqInfo->remote_host);
|
reqInfo->remote_host = NULL;
|
||||||
if (reqInfo->remote_ip != NULL) free(reqInfo->remote_ip);
|
reqInfo->remote_ip = NULL;
|
||||||
}
|
#ifdef CONTENT_MD5
|
||||||
|
if (reqInfo->outh_content_md5 != NULL) free(reqInfo->outh_content_md5);
|
||||||
|
#endif /* CONTENT_MD5 */
|
||||||
|
if (reqInfo->outh_cgi != NULL) free(reqInfo->outh_cgi);
|
||||||
|
|
||||||
|
|
||||||
if (reqInfo->ownENV && reqInfo->env) {
|
if (reqInfo->ownENV && reqInfo->env) {
|
||||||
free_env(reqInfo);
|
free_env(reqInfo);
|
||||||
}
|
}
|
||||||
|
if (reqInfo->ownSB && reqInfo->sb) {
|
||||||
|
free(reqInfo->sb);
|
||||||
|
reqInfo->sb = NULL;
|
||||||
|
sockbuf_count--;
|
||||||
|
}
|
||||||
|
if (reqInfo->cgi_buf) {
|
||||||
|
free(reqInfo->cgi_buf);
|
||||||
|
reqInfo->cgi_buf = NULL;
|
||||||
|
cgibuf_count--;
|
||||||
|
}
|
||||||
|
/* I have no idea how this is possible, but it is happening */
|
||||||
|
if (reqInfo == reqInfo->next) reqInfo->next = NULL;
|
||||||
|
/* Don't clear the last one */
|
||||||
|
if ((reqInfo->next == NULL) && (options & NOT_LAST)) {
|
||||||
|
reqInfo->ownDNS = TRUE;
|
||||||
|
reqInfo->dns_host_lookup = FALSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
tmp = reqInfo->next;
|
tmp = reqInfo->next;
|
||||||
free(reqInfo);
|
free(reqInfo);
|
||||||
|
req_count--;
|
||||||
reqInfo = tmp;
|
reqInfo = tmp;
|
||||||
gCurrentRequest = reqInfo;
|
gCurrentRequest = reqInfo;
|
||||||
if (options & ONLY_LAST) return;
|
if (options & ONLY_LAST) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* decode_request()
|
||||||
|
* given an HTTP request line as a string, decodes it into
|
||||||
|
* METHOD URL?ARGS PROTOCAL
|
||||||
|
* Then calls get_http_headers() to get the rfc822 style headers
|
||||||
|
*/
|
||||||
void decode_request(per_request *reqInfo, char *request)
|
void decode_request(per_request *reqInfo, char *request)
|
||||||
{
|
{
|
||||||
char *protocal;
|
char *protocal;
|
||||||
@ -310,6 +409,7 @@ void decode_request(per_request *reqInfo, char *request)
|
|||||||
|
|
||||||
/* extract the URL, and args if present */
|
/* extract the URL, and args if present */
|
||||||
url = strtok (NULL, "\t\r ");
|
url = strtok (NULL, "\t\r ");
|
||||||
|
if (!url) die(reqInfo,SC_BAD_REQUEST,"Incomplete request.");
|
||||||
if (url && (chp = strchr (url, '?'))) {
|
if (url && (chp = strchr (url, '?'))) {
|
||||||
*chp++ = '\0';
|
*chp++ = '\0';
|
||||||
strcpy (reqInfo->args, chp);
|
strcpy (reqInfo->args, chp);
|
||||||
@ -319,20 +419,22 @@ void decode_request(per_request *reqInfo, char *request)
|
|||||||
protocal = strtok (NULL, "\r");
|
protocal = strtok (NULL, "\r");
|
||||||
|
|
||||||
if(!protocal) {
|
if(!protocal) {
|
||||||
no_headers = 1;
|
|
||||||
reqInfo->http_version = P_HTTP_0_9;
|
reqInfo->http_version = P_HTTP_0_9;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
no_headers = 0;
|
if (!strcmp(protocal,protocals[P_HTTP_1_0]))
|
||||||
if (!strcmp(protocal,"HTTP/1.0"))
|
|
||||||
reqInfo->http_version = P_HTTP_1_0;
|
reqInfo->http_version = P_HTTP_1_0;
|
||||||
else if (!strcmp(protocal,"HTTP/1.1"))
|
else if (!strcmp(protocal,protocals[P_HTTP_1_0]))
|
||||||
reqInfo->http_version = P_HTTP_1_1;
|
reqInfo->http_version = P_HTTP_1_1;
|
||||||
|
else if (!strcasecmp(protocal,protocals[P_SHTTP_1_1]))
|
||||||
|
reqInfo->http_version = P_SHTTP_1_1;
|
||||||
|
else if (!strcasecmp(protocal,protocals[P_SHTTP_1_2]))
|
||||||
|
reqInfo->http_version = P_SHTTP_1_2;
|
||||||
else reqInfo->http_version = P_OTHER;
|
else reqInfo->http_version = P_OTHER;
|
||||||
|
|
||||||
/* dummy call to eat LF at end of protocal */
|
/* dummy call to eat LF at end of protocal */
|
||||||
strtok (NULL, "\n");
|
strtok (NULL, "\n");
|
||||||
get_mime_headers(reqInfo);
|
get_http_headers(reqInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fprintf(stderr,"method:%s url:%s args:%s prot:%s\n",method,
|
/* fprintf(stderr,"method:%s url:%s args:%s prot:%s\n",method,
|
||||||
@ -340,61 +442,115 @@ void decode_request(per_request *reqInfo, char *request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void get_request(per_request *reqInfo)
|
/* Returns a method number for a given method string. SHTTP requires
|
||||||
{
|
* case independent (as per standard network protocal). HTTP is broken,
|
||||||
|
* and is case dependent.
|
||||||
signal(SIGPIPE,send_fd_timed_out);
|
*/
|
||||||
|
|
||||||
|
|
||||||
if (getline(reqInfo->connection_socket, as_requested, HUGE_STRING_LEN,
|
|
||||||
1, timeout) == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(!as_requested[0])
|
|
||||||
return;
|
|
||||||
|
|
||||||
strcpy(the_request, as_requested);
|
|
||||||
|
|
||||||
#ifdef SETPROCTITLE
|
|
||||||
setproctitle(the_request);
|
|
||||||
#endif /* SETPROCTITLE */
|
|
||||||
decode_request(reqInfo, as_requested);
|
|
||||||
unescape_url(reqInfo->url);
|
|
||||||
|
|
||||||
/* Moved this to later so we can read the headers first for HTTP/1.1
|
|
||||||
Host: support */
|
|
||||||
which_host_conf(reqInfo);
|
|
||||||
if (reqInfo->ownDNS) {
|
|
||||||
/* Only when ownDNS set do we find out the remote host name info
|
|
||||||
and by which name the server was called */
|
|
||||||
get_remote_host(reqInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(reqInfo->method == M_HEAD)
|
|
||||||
header_only=1;
|
|
||||||
else if(reqInfo->method == M_GET) {
|
|
||||||
}
|
|
||||||
|
|
||||||
process_request(reqInfo);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int MapMethod (char* method)
|
int MapMethod (char* method)
|
||||||
{
|
{
|
||||||
if(!strcmp(method,"HEAD"))
|
if(!strcmp(method,methods[M_HEAD]))
|
||||||
return M_HEAD;
|
return M_HEAD;
|
||||||
else if(!strcmp(method,"GET"))
|
else if(!strcmp(method,methods[M_GET]))
|
||||||
return M_GET;
|
return M_GET;
|
||||||
else if(!strcmp(method,"POST"))
|
else if(!strcmp(method,methods[M_POST]))
|
||||||
return M_POST;
|
return M_POST;
|
||||||
else if(!strcmp(method,"PUT"))
|
else if(!strcmp(method,methods[M_PUT]))
|
||||||
return M_PUT;
|
return M_PUT;
|
||||||
else if(!strcmp(method,"DELETE"))
|
else if(!strcmp(method,methods[M_DELETE]))
|
||||||
return M_DELETE;
|
return M_DELETE;
|
||||||
|
else if(!strcasecmp(method,methods[M_SECURE]))
|
||||||
|
return M_SECURE;
|
||||||
else
|
else
|
||||||
return M_INVALID;
|
return M_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Globals for speed because of size, these are for get_http_headers */
|
||||||
|
static char field_type[HUGE_STRING_LEN];
|
||||||
|
static char unrec_hdr[HUGE_STRING_LEN];
|
||||||
|
static char unrec_hdr_val[HUGE_STRING_LEN];
|
||||||
|
|
||||||
|
/* get_http_headers() (formerly get_mime_headers)
|
||||||
|
* Read line by line off from the client, and if we recognize a header,
|
||||||
|
* add it to reqInfo, otherwise let it go through to become an
|
||||||
|
* environment variable for CGI scripts. Also, SHTTP headers all start
|
||||||
|
* with SHTTP, so we pass them through to the SHTTP library.
|
||||||
|
* The Content-Type, Content-Length and Authorization headers don't get
|
||||||
|
* made into CGI variables (Content-Type, Content-Length are already
|
||||||
|
* defined in the CGI spec, and Authorization would be a security risk.)
|
||||||
|
*/
|
||||||
|
void get_http_headers(per_request *reqInfo)
|
||||||
|
{
|
||||||
|
char *field_val;
|
||||||
|
int options = 0;
|
||||||
|
|
||||||
|
while(getline(reqInfo->sb,field_type,HUGE_STRING_LEN-1,options,
|
||||||
|
timeout) != -1) {
|
||||||
|
|
||||||
|
if(!field_type[0])
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!(field_val = strchr(field_type,':')))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
*field_val++ = '\0';
|
||||||
|
while(isspace(*field_val)) ++field_val;
|
||||||
|
|
||||||
|
if(!strcasecmp(field_type,"Content-type")) {
|
||||||
|
strncpy(reqInfo->inh_content_type,field_val,MAX_STRING_LEN);
|
||||||
|
reqInfo->inh_content_type[MAX_STRING_LEN-1] = '\0';
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
|
if(!strcasecmp(field_type,"Authorization")) {
|
||||||
|
strncpy(reqInfo->inh_auth_line,field_val,HUGE_STRING_LEN);
|
||||||
|
reqInfo->inh_auth_line[HUGE_STRING_LEN-1]='\0';
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
|
if(!strcasecmp(field_type,"Host")) {
|
||||||
|
strncpy(reqInfo->inh_called_hostname, field_val, MAX_STRING_LEN);
|
||||||
|
reqInfo->inh_called_hostname[MAX_STRING_LEN-1] = '\0';
|
||||||
|
} else
|
||||||
|
if(!strcasecmp(field_type,"Extension")) {
|
||||||
|
if (!strcasecmp(field_val, "Notify-Domain-Restriction"))
|
||||||
|
reqInfo->bNotifyDomainRestricted = 1;
|
||||||
|
#ifdef DIGEST_AUTH
|
||||||
|
/* Should we do something if we get this header? Maybe set a flag
|
||||||
|
* to know that a client doesn't accept this type of authentication?
|
||||||
|
*/
|
||||||
|
/* else if (!strcasecmp(field_val, "Security/Digest")); */
|
||||||
|
#endif /* DIGEST_AUTH */
|
||||||
|
} else
|
||||||
|
if(!strcasecmp(field_type,"Content-length")) {
|
||||||
|
sscanf(field_val,"%d",&(reqInfo->inh_content_length));
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
|
if(!strcasecmp(field_type,"Connection")) {
|
||||||
|
if (!strcasecmp(field_val, "Keep-Alive") &&
|
||||||
|
keep_alive.bAllowKeepAlive)
|
||||||
|
keep_alive.bKeepAlive = 1;
|
||||||
|
} else
|
||||||
|
if(!strcasecmp(field_type,"User-agent")) {
|
||||||
|
strncpy(reqInfo->inh_agent, field_val, HUGE_STRING_LEN);
|
||||||
|
reqInfo->inh_agent[HUGE_STRING_LEN-1] = '\0';
|
||||||
|
} else
|
||||||
|
if(!strcasecmp(field_type,"Referer")) {
|
||||||
|
strncpy(reqInfo->inh_referer, field_val, HUGE_STRING_LEN);
|
||||||
|
reqInfo->inh_referer[HUGE_STRING_LEN-1] = '\0';
|
||||||
|
} else
|
||||||
|
if(!strcasecmp(field_type,"If-modified-since")) {
|
||||||
|
strncpy(reqInfo->inh_if_mod_since,field_val, MAX_STRING_LEN);
|
||||||
|
reqInfo->inh_if_mod_since[MAX_STRING_LEN-1] = '\0';
|
||||||
|
}
|
||||||
|
http2cgi(unrec_hdr, field_type);
|
||||||
|
strcpy (unrec_hdr_val, field_val);
|
||||||
|
if(reqInfo->env) {
|
||||||
|
if(!merge_header(reqInfo,unrec_hdr,field_val))
|
||||||
|
make_env_str(reqInfo,unrec_hdr,field_val);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
make_env_str(reqInfo,unrec_hdr,field_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Split from get_request (the former process_request) so that we can call
|
/* Split from get_request (the former process_request) so that we can call
|
||||||
this from other places (on LOCAL_REDIRECTs and ErrorDocument handling) */
|
this from other places (on LOCAL_REDIRECTs and ErrorDocument handling) */
|
||||||
|
|
||||||
@ -408,7 +564,6 @@ void process_request(per_request *reqInfo)
|
|||||||
case A_STD_DOCUMENT:
|
case A_STD_DOCUMENT:
|
||||||
if ((reqInfo->method == M_HEAD) &&
|
if ((reqInfo->method == M_HEAD) &&
|
||||||
(reqInfo->http_version == P_HTTP_0_9)) {
|
(reqInfo->http_version == P_HTTP_0_9)) {
|
||||||
header_only = 0;
|
|
||||||
reqInfo->method = M_GET;
|
reqInfo->method = M_GET;
|
||||||
die(reqInfo,SC_BAD_REQUEST,"Invalid HTTP/0.9 method.");
|
die(reqInfo,SC_BAD_REQUEST,"Invalid HTTP/0.9 method.");
|
||||||
}
|
}
|
||||||
@ -423,5 +578,71 @@ void process_request(per_request *reqInfo)
|
|||||||
case A_SCRIPT_CGI:
|
case A_SCRIPT_CGI:
|
||||||
exec_cgi_script(reqInfo);
|
exec_cgi_script(reqInfo);
|
||||||
break;
|
break;
|
||||||
|
#ifdef FCGI_SUPPORT
|
||||||
|
case A_SCRIPT_FCGI:
|
||||||
|
FastCgiHandler(reqInfo);
|
||||||
|
break;
|
||||||
|
#endif /* FCGI_SUPPORT */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* RequestMain()
|
||||||
|
* The start of the request cycle. This routine starts reading off
|
||||||
|
* the socket, and also calls the messages for decoding (decode_request()),
|
||||||
|
* figuring out which virtual host (which_host_conf()), and getting the
|
||||||
|
* DNS info (get_remote_host()). It then calls process_request() to
|
||||||
|
* handle things once it has all of the information from the client
|
||||||
|
* (with the exception of an entity body). These are split so that
|
||||||
|
* process_request() can be called internally in the server to handle
|
||||||
|
* new request types (internal redirect handling and ErrorDoc)
|
||||||
|
*/
|
||||||
|
void RequestMain(per_request *reqInfo)
|
||||||
|
{
|
||||||
|
int options = 0;
|
||||||
|
|
||||||
|
signal(SIGPIPE,send_fd_timed_out);
|
||||||
|
|
||||||
|
#ifdef LOG_DURATION
|
||||||
|
request_time = 0;
|
||||||
|
#endif /* LOG_DURATION */
|
||||||
|
|
||||||
|
if (reqInfo->sb == NULL) {
|
||||||
|
reqInfo->sb = new_sock_buf(reqInfo,reqInfo->in);
|
||||||
|
sockbuf_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getline(reqInfo->sb, as_requested, HUGE_STRING_LEN,
|
||||||
|
options, timeout) == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!as_requested[0])
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef LOG_DURATION
|
||||||
|
request_time = time(NULL);
|
||||||
|
#endif /* LOG_DURATION */
|
||||||
|
|
||||||
|
strcpy(the_request, as_requested);
|
||||||
|
|
||||||
|
#ifdef SETPROCTITLE
|
||||||
|
setproctitle(the_request);
|
||||||
|
#endif /* SETPROCTITLE */
|
||||||
|
decode_request(reqInfo, as_requested);
|
||||||
|
unescape_url(reqInfo->url);
|
||||||
|
|
||||||
|
/* Moved this to later so we can read the headers first for HTTP/1.1
|
||||||
|
* Host: support
|
||||||
|
*/
|
||||||
|
which_host_conf(reqInfo);
|
||||||
|
|
||||||
|
if (reqInfo->dns_host_lookup == FALSE) {
|
||||||
|
/* Only when we haven't done DNS do we call get_remote_host().
|
||||||
|
* If we aren't supposed to, get_remote_host() will not do it.
|
||||||
|
*/
|
||||||
|
get_remote_host(reqInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
process_request(reqInfo);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* http_request.h,v 1.14 1995/11/09 01:48:21 blong Exp
|
* http_request.h,v 1.20 1996/04/05 18:55:04 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
@ -20,31 +20,37 @@
|
|||||||
|
|
||||||
#ifndef _HTTP_REQUEST_H_
|
#ifndef _HTTP_REQUEST_H_
|
||||||
#define _HTTP_REQUEST_H_
|
#define _HTTP_REQUEST_H_
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* globals defined in this module */
|
/* globals defined in this module */
|
||||||
|
|
||||||
extern per_request *gCurrentRequest;
|
extern per_request *gCurrentRequest;
|
||||||
extern int no_headers;
|
|
||||||
extern char *remote_logname;
|
extern char *remote_logname;
|
||||||
extern char failed_request[];
|
extern char failed_request[];
|
||||||
extern char failed_url[];
|
extern char failed_url[];
|
||||||
extern int header_only;
|
|
||||||
extern char the_request[];
|
extern char the_request[];
|
||||||
|
|
||||||
/* Continue Request Options */
|
/* Continue Request Options */
|
||||||
#define NEW_URL 1
|
#define COPY_URL 1
|
||||||
#define NEW_DNS 2
|
#define FORCE_GET 2
|
||||||
#define FORCE_GET 4
|
#define NOT_LAST 4
|
||||||
#define ONLY_LAST 8
|
#define ONLY_LAST 8
|
||||||
#define KEEP_ENV 16
|
#define KEEP_ENV 16
|
||||||
#define KEEP_AUTH 32
|
#define KEEP_AUTH 32
|
||||||
|
#define NEW_SOCK_BUF 64
|
||||||
|
extern int req_count;
|
||||||
|
extern int cgibuf_count;
|
||||||
|
extern int sockbuf_count;
|
||||||
|
|
||||||
|
|
||||||
/* function prototypes */
|
/* function prototypes */
|
||||||
per_request *initialize_request(per_request *reqInfo);
|
per_request *initialize_request(per_request *reqInfo);
|
||||||
per_request *continue_request(per_request *reqInfo, int options);
|
per_request *continue_request(per_request *reqInfo, int options);
|
||||||
void free_request(per_request *reqInfo, int options);
|
void free_request(per_request *reqInfo, int options);
|
||||||
|
void get_http_headers(per_request *reqInfo);
|
||||||
void process_request(per_request *reqInfo);
|
void process_request(per_request *reqInfo);
|
||||||
void get_request(per_request *reqInfo);
|
void RequestMain(per_request *reqInfo);
|
||||||
int MapMethod (char* method);
|
int MapMethod (char* method);
|
||||||
#endif /* _HTTP_REQUEST_H_ */
|
#endif /* _HTTP_REQUEST_H_ */
|
||||||
|
435
src/http_send.c
435
src/http_send.c
@ -10,25 +10,14 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* http_send.c,v 1.22 1995/11/28 09:02:09 blong Exp
|
* http_send.c,v 1.34 1996/04/05 18:55:06 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* http_send.c: handles sending of regular files and determining which
|
* http_send.c: handles sending of regular files and determining which
|
||||||
* type of request it is if its not for a regular file
|
* type of request it is if its not for a regular file
|
||||||
*
|
*
|
||||||
* Based on NCSA HTTPd 1.3 by Rob McCool
|
|
||||||
*
|
*
|
||||||
* 04-08-95 blong
|
|
||||||
* Fixed security hole which allowed a trailing slash on CGI_MAGIC_TYPE
|
|
||||||
* cgi anywhere scripts to send back the script contents. Now the
|
|
||||||
* trailing slash is added to the PATH_INFO, and the script is run.
|
|
||||||
* Oh yeah, and don't forget about directories.
|
|
||||||
*
|
|
||||||
* 09-01-95 blong
|
|
||||||
* Fixed bug under AIX 3.2.5 where last part of file is garbled using
|
|
||||||
* fwrite, but works fine with write. I didn't say I understood it,
|
|
||||||
* but the fix seems to work.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -39,6 +28,13 @@
|
|||||||
#ifndef NO_STDLIB_H
|
#ifndef NO_STDLIB_H
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
#endif /* NO_STDLIB_H */
|
#endif /* NO_STDLIB_H */
|
||||||
|
#ifdef HAVE_STDARG
|
||||||
|
# include <stdarg.h>
|
||||||
|
#else
|
||||||
|
# ifdef HAVE_VARARGS
|
||||||
|
# include <varargs.h>
|
||||||
|
# endif /* HAVE_VARARGS */
|
||||||
|
#endif /* HAVE_STDARG */
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -47,6 +43,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "fdwrap.h"
|
#include "fdwrap.h"
|
||||||
|
#include "allocate.h"
|
||||||
#include "http_send.h"
|
#include "http_send.h"
|
||||||
#include "cgi.h"
|
#include "cgi.h"
|
||||||
#include "imagemap.h"
|
#include "imagemap.h"
|
||||||
@ -60,17 +57,16 @@
|
|||||||
#include "http_dir.h"
|
#include "http_dir.h"
|
||||||
#include "httpd.h"
|
#include "httpd.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "blackout.h"
|
||||||
|
#ifdef FCGI_SUPPORT
|
||||||
|
# include "fcgi.h"
|
||||||
|
#endif /* FCGI_SUPPORT */
|
||||||
|
|
||||||
|
void (*exit_callback)(void);
|
||||||
int num_includes;
|
|
||||||
|
|
||||||
static void (*exit_callback)(void);
|
|
||||||
|
|
||||||
void send_node(per_request *reqInfo)
|
void send_node(per_request *reqInfo)
|
||||||
{
|
{
|
||||||
struct stat finfo;
|
struct stat finfo;
|
||||||
char pa[MAX_STRING_LEN];
|
|
||||||
int length = 0;
|
|
||||||
register x = 0;
|
register x = 0;
|
||||||
int allow;
|
int allow;
|
||||||
char allow_options;
|
char allow_options;
|
||||||
@ -78,32 +74,32 @@ void send_node(per_request *reqInfo)
|
|||||||
|
|
||||||
exit_callback = NULL;
|
exit_callback = NULL;
|
||||||
|
|
||||||
/* Remove all but 1 of the trailing slashes from the filename in order
|
/* It is no longer necessary to move all but one of the trailing slashes
|
||||||
to fix security hole. Place them in the path alias (pa) array */
|
* to the path_info string, since all multiple slashes are now compressed
|
||||||
|
* to one as a security precaution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
length = strlen(reqInfo->filename);
|
|
||||||
while ((length>1) && (reqInfo->filename[length-1] == '/') &&
|
|
||||||
(reqInfo->filename[length-2] == '/') && (x < MAX_STRING_LEN)) {
|
|
||||||
pa[x] = '/';
|
|
||||||
x++;
|
|
||||||
reqInfo->filename[length-1] = '\0';
|
|
||||||
length--;
|
|
||||||
}
|
|
||||||
pa[x] = '\0';
|
|
||||||
if(stat(reqInfo->filename,&finfo) == -1) {
|
if(stat(reqInfo->filename,&finfo) == -1) {
|
||||||
if ((ErrReturn = extract_path_info(reqInfo,pa,&finfo))) {
|
ErrReturn = extract_path_info(reqInfo,&finfo);
|
||||||
if(ErrReturn == ENOENT) {
|
|
||||||
log_reason(reqInfo,"file does not exist",reqInfo->filename);
|
|
||||||
die(reqInfo,SC_NOT_FOUND,reqInfo->url);
|
|
||||||
} else {
|
|
||||||
log_reason(reqInfo,"(3) file permissions deny server access",
|
|
||||||
reqInfo->filename);
|
|
||||||
die(reqInfo,SC_FORBIDDEN,reqInfo->url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
evaluate_access(reqInfo,&finfo,&allow,&allow_options);
|
evaluate_access(reqInfo,&finfo,&allow,&allow_options);
|
||||||
|
if (ErrReturn) {
|
||||||
|
if(ErrReturn == ENOENT) {
|
||||||
|
log_reason(reqInfo,"file does not exist",reqInfo->filename);
|
||||||
|
die(reqInfo,SC_NOT_FOUND,reqInfo->url);
|
||||||
|
/* Check for AFS/NFS problems, and send back an unavailable message instead
|
||||||
|
* Larry Schwimmer (schwim@cyclone.stanford.edu)
|
||||||
|
*/
|
||||||
|
} else if ((ErrReturn == ETIMEDOUT) || (ErrReturn == ENODEV)) {
|
||||||
|
log_reason(reqInfo, "file temporarily unavailable",
|
||||||
|
reqInfo->filename);
|
||||||
|
die(reqInfo,SC_SERVICE_UNAVAIL,reqInfo->url);
|
||||||
|
} else {
|
||||||
|
log_reason(reqInfo,"(3) file permissions deny server access",
|
||||||
|
reqInfo->filename);
|
||||||
|
die(reqInfo,SC_FORBIDDEN,reqInfo->url);
|
||||||
|
}
|
||||||
|
}
|
||||||
if(!allow) {
|
if(!allow) {
|
||||||
log_reason(reqInfo,"client denied by server configuration",
|
log_reason(reqInfo,"client denied by server configuration",
|
||||||
reqInfo->filename);
|
reqInfo->filename);
|
||||||
@ -111,17 +107,30 @@ void send_node(per_request *reqInfo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (S_ISDIR(finfo.st_mode)) {
|
if (S_ISDIR(finfo.st_mode)) {
|
||||||
send_dir(reqInfo,&finfo,pa,allow_options);
|
send_dir(reqInfo,&finfo,allow_options);
|
||||||
} else if (S_ISREG(finfo.st_mode)) {
|
} else if (S_ISREG(finfo.st_mode)) {
|
||||||
|
x = strlen(reqInfo->filename);
|
||||||
|
/* Remove the trailing slash if its not a directory */
|
||||||
|
if (reqInfo->filename[x-1] == '/') {
|
||||||
|
if (reqInfo->path_info[0] == '\0') {
|
||||||
|
reqInfo->path_info[0] = '/';
|
||||||
|
reqInfo->path_info[1] = '\0';
|
||||||
|
}
|
||||||
|
reqInfo->filename[x-1] = '\0';
|
||||||
|
}
|
||||||
probe_content_type(reqInfo,reqInfo->filename);
|
probe_content_type(reqInfo,reqInfo->filename);
|
||||||
if (!strcmp(content_type, CGI_MAGIC_TYPE))
|
if (!strcmp(reqInfo->outh_content_type, CGI_MAGIC_TYPE))
|
||||||
send_cgi(reqInfo,&finfo,pa,allow_options);
|
send_cgi(reqInfo,&finfo,allow_options);
|
||||||
#ifdef IMAGEMAP_SUPPORT
|
#ifdef IMAGEMAP_SUPPORT
|
||||||
else if (!strcmp(content_type, IMAGEMAP_MAGIC_TYPE))
|
else if (!strcmp(reqInfo->outh_content_type, IMAGEMAP_MAGIC_TYPE))
|
||||||
send_imagemap(reqInfo,&finfo,pa,allow_options);
|
send_imagemap(reqInfo,&finfo,allow_options);
|
||||||
#endif /* IMAGEMAP_SUPPORT */
|
#endif /* IMAGEMAP_SUPPORT */
|
||||||
|
#ifdef FCGI_SUPPORT
|
||||||
|
else if (!strcmp(reqInfo->outh_content_type, FCGI_MAGIC_TYPE))
|
||||||
|
FastCgiHandler(reqInfo);
|
||||||
|
#endif /* FCGI_SUPPORT */
|
||||||
else
|
else
|
||||||
send_file(reqInfo,&finfo,pa,allow_options);
|
send_file(reqInfo,&finfo,allow_options);
|
||||||
} else {
|
} else {
|
||||||
log_reason(reqInfo,"improper file type",reqInfo->filename);
|
log_reason(reqInfo,"improper file type",reqInfo->filename);
|
||||||
/* device driver or pipe, no permission */
|
/* device driver or pipe, no permission */
|
||||||
@ -129,10 +138,12 @@ void send_node(per_request *reqInfo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_file(per_request *reqInfo, struct stat *fi,
|
void send_file(per_request *reqInfo, struct stat *fi, char allow_options)
|
||||||
char *path_args, char allow_options)
|
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
#ifdef BLACKOUT_CODE
|
||||||
|
int isblack = FALSE;
|
||||||
|
#endif /* BLACKOUT_CODE */
|
||||||
|
|
||||||
if ((reqInfo->method != M_GET) && (reqInfo->method != M_HEAD)) {
|
if ((reqInfo->method != M_GET) && (reqInfo->method != M_HEAD)) {
|
||||||
sprintf(error_msg,"%s to non-script",methods[reqInfo->method]);
|
sprintf(error_msg,"%s to non-script",methods[reqInfo->method]);
|
||||||
@ -140,23 +151,22 @@ void send_file(per_request *reqInfo, struct stat *fi,
|
|||||||
}
|
}
|
||||||
set_content_type(reqInfo,reqInfo->filename);
|
set_content_type(reqInfo,reqInfo->filename);
|
||||||
|
|
||||||
if((allow_options & OPT_INCLUDES) && (!content_encoding[0])) {
|
if((allow_options & OPT_INCLUDES) && (!reqInfo->outh_content_encoding[0])) {
|
||||||
#ifdef XBITHACK
|
#ifdef XBITHACK
|
||||||
if((fi->st_mode & S_IXUSR) ||
|
if((fi->st_mode & S_IXUSR) ||
|
||||||
(!strcmp(content_type,INCLUDES_MAGIC_TYPE))) {
|
(!strcmp(reqInfo->outh_content_type,INCLUDES_MAGIC_TYPE))) {
|
||||||
#else
|
#else
|
||||||
if(!strcmp(content_type,INCLUDES_MAGIC_TYPE)) {
|
if(!strcmp(reqInfo->outh_content_type,INCLUDES_MAGIC_TYPE)) {
|
||||||
#endif /* XBITHACK */
|
#endif /* XBITHACK */
|
||||||
reqInfo->bytes_sent = 0;
|
reqInfo->bytes_sent = 0;
|
||||||
send_parsed_file(reqInfo,path_args,
|
send_parsed_file(reqInfo, allow_options & OPT_INCNOEXEC);
|
||||||
allow_options & OPT_INCNOEXEC);
|
|
||||||
log_transaction(reqInfo);
|
log_transaction(reqInfo);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (path_args[0]) {
|
if (reqInfo->path_info[0]) {
|
||||||
strcat(reqInfo->filename,path_args);
|
strcat(reqInfo->filename,reqInfo->path_info);
|
||||||
strcat(reqInfo->url,path_args);
|
strcat(reqInfo->url,reqInfo->path_info);
|
||||||
sprintf(error_msg,"No file matching URL: %s",reqInfo->url);
|
sprintf(error_msg,"No file matching URL: %s",reqInfo->url);
|
||||||
log_reason(reqInfo, error_msg, reqInfo->filename);
|
log_reason(reqInfo, error_msg, reqInfo->filename);
|
||||||
die(reqInfo,SC_NOT_FOUND,reqInfo->url);
|
die(reqInfo,SC_NOT_FOUND,reqInfo->url);
|
||||||
@ -181,49 +191,75 @@ void send_file(per_request *reqInfo, struct stat *fi,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
reqInfo->bytes_sent = 0;
|
reqInfo->bytes_sent = 0;
|
||||||
if(!no_headers) {
|
|
||||||
|
#ifdef BLACKOUT_CODE
|
||||||
|
if (!strcmp(reqInfo->outh_content_type,BLACKOUT_MAGIC_TYPE)) {
|
||||||
|
isblack = TRUE;
|
||||||
|
strcpy(reqInfo->outh_content_type,"text/html");
|
||||||
|
}
|
||||||
|
#endif /* BLACKOUT_CODE */
|
||||||
|
|
||||||
|
if(reqInfo->http_version != P_HTTP_0_9) {
|
||||||
|
/* No length dependent headers since black is parsed */
|
||||||
|
#ifdef BLACKOUT_CODE
|
||||||
|
if (isblack == FALSE) {
|
||||||
|
#endif /* BLACKOUT_CODE */
|
||||||
|
#ifdef CONTENT_MD5
|
||||||
|
reqInfo->outh_content_md5 = (unsigned char *)md5digest(f);
|
||||||
|
#endif /* CONTENT_MD5 */
|
||||||
set_content_length(reqInfo,fi->st_size);
|
set_content_length(reqInfo,fi->st_size);
|
||||||
if (set_last_modified(reqInfo,fi->st_mtime)) {
|
if (set_last_modified(reqInfo,fi->st_mtime)) {
|
||||||
FClose(f);
|
FClose(f);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
send_http_header(reqInfo);
|
}
|
||||||
|
if (reqInfo->http_version != P_HTTP_0_9) {
|
||||||
|
send_http_header(reqInfo);
|
||||||
|
}
|
||||||
|
#ifdef BLACKOUT_CODE
|
||||||
}
|
}
|
||||||
|
#endif /* BLACKOUT_CODE */
|
||||||
|
|
||||||
num_includes = 0;
|
if(reqInfo->method != M_HEAD) {
|
||||||
if(!header_only)
|
#ifdef BLACKOUT_CODE
|
||||||
|
if (isblack == TRUE)
|
||||||
|
send_fp_black(reqInfo,f,NULL);
|
||||||
|
else
|
||||||
|
#endif /* BLACKOUT_CODE */
|
||||||
send_fp(reqInfo,f,NULL);
|
send_fp(reqInfo,f,NULL);
|
||||||
|
}
|
||||||
log_transaction(reqInfo);
|
log_transaction(reqInfo);
|
||||||
FClose(f);
|
FClose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Globals for speed */
|
|
||||||
static char ifile[HUGE_STRING_LEN];
|
|
||||||
static char temp_name[HUGE_STRING_LEN];
|
|
||||||
|
|
||||||
void send_dir(per_request *reqInfo,struct stat *finfo, char *pa,
|
void send_dir(per_request *reqInfo,struct stat *finfo, char allow_options) {
|
||||||
char allow_options) {
|
|
||||||
char *name_ptr, *end_ptr;
|
char *name_ptr, *end_ptr;
|
||||||
|
char *ifile, *temp_name;
|
||||||
|
|
||||||
|
ifile = newString(HUGE_STRING_LEN,STR_TMP);
|
||||||
|
temp_name = newString(HUGE_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
/* Path Alias (pa) array should now have the trailing slash */
|
/* Path Alias (pa) array should now have the trailing slash */
|
||||||
/* if (pa[0] != '/') { */
|
/* if (pa[0] != '/') { */
|
||||||
if ((reqInfo->filename[strlen(reqInfo->filename) - 1] != '/') &&
|
if ((reqInfo->filename[strlen(reqInfo->filename) - 1] != '/') &&
|
||||||
(pa[0] != '/')) {
|
(reqInfo->path_info[0] != '/')) {
|
||||||
char url[HUGE_STRING_LEN];
|
|
||||||
strcpy_dir(ifile,reqInfo->url);
|
strcpy_dir(ifile,reqInfo->url);
|
||||||
construct_url(url,reqInfo->hostInfo,ifile);
|
construct_url(temp_name,reqInfo->hostInfo,ifile);
|
||||||
escape_url(url);
|
escape_url(temp_name);
|
||||||
die(reqInfo,SC_REDIRECT_PERM,url);
|
die(reqInfo,SC_REDIRECT_PERM,temp_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't allow PATH_INFO to directory indexes as a compromise for
|
/* Don't allow PATH_INFO to directory indexes as a compromise for
|
||||||
error messages for files which don't exist */
|
error messages for files which don't exist */
|
||||||
|
|
||||||
if ((pa[0] != '\0') || (strlen(pa) > 1)) {
|
if ((reqInfo->path_info[0] != '\0') || (strlen(reqInfo->path_info) > 1)) {
|
||||||
strcat(reqInfo->filename,pa);
|
strcat(reqInfo->filename,reqInfo->path_info);
|
||||||
strcat(reqInfo->url,pa);
|
strcat(reqInfo->url,reqInfo->path_info);
|
||||||
sprintf(error_msg,"No file matching URL: %s",reqInfo->url);
|
sprintf(error_msg,"No file matching URL: %s",reqInfo->url);
|
||||||
log_reason(reqInfo, error_msg, reqInfo->filename);
|
log_reason(reqInfo, error_msg, reqInfo->filename);
|
||||||
|
freeString(temp_name);
|
||||||
|
freeString(ifile);
|
||||||
die(reqInfo,SC_NOT_FOUND,reqInfo->url);
|
die(reqInfo,SC_NOT_FOUND,reqInfo->url);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,30 +279,40 @@ void send_dir(per_request *reqInfo,struct stat *finfo, char *pa,
|
|||||||
make_full_path(reqInfo->filename,name_ptr,ifile);
|
make_full_path(reqInfo->filename,name_ptr,ifile);
|
||||||
if(stat(ifile,finfo) == -1) {
|
if(stat(ifile,finfo) == -1) {
|
||||||
if(! *end_ptr && (allow_options & OPT_INDEXES)) {
|
if(! *end_ptr && (allow_options & OPT_INDEXES)) {
|
||||||
if (pa[0]) {
|
if (reqInfo->path_info[0]) {
|
||||||
strcat(reqInfo->filename,pa);
|
strcat(reqInfo->filename,reqInfo->path_info);
|
||||||
strcat(reqInfo->url,pa);
|
strcat(reqInfo->url,reqInfo->path_info);
|
||||||
log_reason(reqInfo,"file does not exist",reqInfo->filename);
|
log_reason(reqInfo,"file does not exist",reqInfo->filename);
|
||||||
|
freeString(ifile);
|
||||||
|
freeString(temp_name);
|
||||||
die(reqInfo,SC_NOT_FOUND,reqInfo->url);
|
die(reqInfo,SC_NOT_FOUND,reqInfo->url);
|
||||||
}
|
}
|
||||||
if ((reqInfo->method != M_GET) && (reqInfo->method != M_HEAD)) {
|
if ((reqInfo->method != M_GET) && (reqInfo->method != M_HEAD)) {
|
||||||
sprintf(error_msg,"%s to non-script",methods[reqInfo->method]);
|
sprintf(error_msg,"%s to non-script",methods[reqInfo->method]);
|
||||||
|
freeString(ifile);
|
||||||
|
freeString(temp_name);
|
||||||
die(reqInfo,SC_NOT_IMPLEMENTED,error_msg);
|
die(reqInfo,SC_NOT_IMPLEMENTED,error_msg);
|
||||||
}
|
}
|
||||||
index_directory(reqInfo);
|
index_directory(reqInfo);
|
||||||
|
freeString(ifile);
|
||||||
|
freeString(temp_name);
|
||||||
return;
|
return;
|
||||||
} else if (! *end_ptr) {
|
} else if (! *end_ptr) {
|
||||||
log_reason(reqInfo,"(2) file permissions deny server access",
|
log_reason(reqInfo,"(2) file permissions deny server access",
|
||||||
reqInfo->filename);
|
reqInfo->filename);
|
||||||
|
freeString(ifile);
|
||||||
|
freeString(temp_name);
|
||||||
die(reqInfo,SC_FORBIDDEN,reqInfo->url);
|
die(reqInfo,SC_FORBIDDEN,reqInfo->url);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
strcpy(reqInfo->filename,ifile);
|
strcpy(reqInfo->filename,ifile);
|
||||||
probe_content_type(reqInfo,reqInfo->filename);
|
probe_content_type(reqInfo,reqInfo->filename);
|
||||||
if(!strcmp(content_type,CGI_MAGIC_TYPE))
|
if(!strcmp(reqInfo->outh_content_type,CGI_MAGIC_TYPE))
|
||||||
send_cgi(reqInfo,finfo,pa,allow_options);
|
send_cgi(reqInfo,finfo,allow_options);
|
||||||
else
|
else
|
||||||
send_file(reqInfo,finfo,pa, allow_options);
|
send_file(reqInfo,finfo,allow_options);
|
||||||
|
freeString(ifile);
|
||||||
|
freeString(temp_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
name_ptr = end_ptr;
|
name_ptr = end_ptr;
|
||||||
@ -274,45 +320,162 @@ void send_dir(per_request *reqInfo,struct stat *finfo, char *pa,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Search down given translated URL searching for actual file name and filling
|
/* Search down given translated URL searching for actual file name and filling
|
||||||
in path_args string. Doesn't make any claims about file type, must be
|
* in path_info string. Doesn't make any claims about file type, must be
|
||||||
handled elsewhere.
|
* handled elsewhere.
|
||||||
Returns 0 on success, errno on failure
|
* Returns 0 on success, errno on failure
|
||||||
*/
|
*/
|
||||||
int extract_path_info(per_request *reqInfo, char *path_args,
|
int extract_path_info(per_request *reqInfo, struct stat *finfo)
|
||||||
struct stat *finfo)
|
|
||||||
{
|
{
|
||||||
register int x,max;
|
register int x,max;
|
||||||
char t[HUGE_STRING_LEN];
|
char *str;
|
||||||
|
int l,u;
|
||||||
|
|
||||||
|
str = newString(HUGE_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
max=count_dirs(reqInfo->filename);
|
max=count_dirs(reqInfo->filename);
|
||||||
for(x=max ; x > 0 ; x--) {
|
for(x=max ; x > 0 ; x--) {
|
||||||
make_dirstr(reqInfo->filename,x+1,t);
|
make_dirstr(reqInfo->filename,x+1,str);
|
||||||
if(!(stat(t,finfo))) {
|
l=strlen(str);
|
||||||
int l=strlen(t);
|
u=strlen(reqInfo->url);
|
||||||
strcat(path_args,&(reqInfo->filename[l]));
|
if(!(stat(str,finfo)) &&
|
||||||
|
!strcmp(reqInfo->filename+l, reqInfo->url+u-strlen(reqInfo->filename+ l)))
|
||||||
|
{
|
||||||
|
strcat(reqInfo->path_info,&(reqInfo->filename[l]));
|
||||||
reqInfo->filename[l] = '\0';
|
reqInfo->filename[l] = '\0';
|
||||||
reqInfo->url[strlen(reqInfo->url) - strlen(path_args)] = '\0';
|
reqInfo->url[strlen(reqInfo->url) - strlen(reqInfo->path_info)]='\0';
|
||||||
|
freeString(str);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
freeString(str);
|
||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Dump the headers of the per_request structure to the client.
|
||||||
|
* Will also set the status line if it hasn't already been set,
|
||||||
|
* will set to 302 if location, 401 if auth required, 200 otherwise.
|
||||||
|
* Will dump the following headers:
|
||||||
|
* Date GMT Date in rfc 822 format
|
||||||
|
* Server SERVER_VERSION
|
||||||
|
* Annotations-cgi reqInfo->hostInfo->annotation_server
|
||||||
|
* Location reqInfo->outh_location
|
||||||
|
* Last-modified reqInfo->outh_last_mod
|
||||||
|
* Content-type reqInfo->outh_content_type
|
||||||
|
* Content-length reqInfo->outh_content_length
|
||||||
|
* Content-encoding reqInfo->outh_content_encoding
|
||||||
|
* Content-MD5 reqInfo->outh_content_md5
|
||||||
|
* WWW-Authenticate reqInfo->outh_www_auth
|
||||||
|
* Extension: Domain-Restricted reqInfo->bNotifyDomainRestricted &&
|
||||||
|
* reqInfo->bSatisfiedDomain
|
||||||
|
* Connection: Keep-Alive keep_alive. stuff
|
||||||
|
* Keep-Alive: max= timeout= same
|
||||||
|
* other headers from CGI reqInfo->outh_cgi
|
||||||
|
* We don't dump the MIME-Version header that NCSA HTTP/1.3 did, because
|
||||||
|
* the server is not mime-compliant.
|
||||||
|
*
|
||||||
|
* Should we only give back HTTP/1.0 headers to 1.0 clients? The docs are
|
||||||
|
* unclear on this, and almost all clients (even ones supporting 1.1 features)
|
||||||
|
* are sending HTTP/1.0 anyways, so we will for now.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void send_http_header(per_request *reqInfo)
|
||||||
|
{
|
||||||
|
if(!reqInfo->status_line) {
|
||||||
|
/* Special Cases */
|
||||||
|
if(reqInfo->outh_location[0])
|
||||||
|
reqInfo->status = SC_REDIRECT_TEMP;
|
||||||
|
if(reqInfo->outh_www_auth[0])
|
||||||
|
reqInfo->status = SC_AUTH_REQUIRED;
|
||||||
|
set_stat_line(reqInfo);
|
||||||
|
}
|
||||||
|
rprintf(reqInfo,"%s %s%c%c",protocals[reqInfo->http_version],
|
||||||
|
reqInfo->status_line,CR,LF);
|
||||||
|
rprintf(reqInfo,"Date: %s%c%c",gm_timestr_822(time(NULL)),CR,LF);
|
||||||
|
rprintf(reqInfo,"Server: %s%c%c",SERVER_VERSION,CR,LF);
|
||||||
|
if (reqInfo->hostInfo->annotation_server[0])
|
||||||
|
rprintf(reqInfo,"Annotations-cgi: %s%c%c",
|
||||||
|
reqInfo->hostInfo->annotation_server,CR,LF);
|
||||||
|
|
||||||
|
if(reqInfo->outh_location[0])
|
||||||
|
rprintf(reqInfo,"Location: %s%c%c",
|
||||||
|
reqInfo->outh_location,CR,LF);
|
||||||
|
if(reqInfo->outh_last_mod[0])
|
||||||
|
rprintf(reqInfo,"Last-modified: %s%c%c",
|
||||||
|
reqInfo->outh_last_mod,CR,LF);
|
||||||
|
|
||||||
|
if(reqInfo->outh_content_type[0])
|
||||||
|
rprintf(reqInfo,"Content-type: %s%c%c",
|
||||||
|
reqInfo->outh_content_type,CR,LF);
|
||||||
|
|
||||||
|
/* If we know the content_length, we can fulfill byte range requests */
|
||||||
|
if(reqInfo->outh_content_length >= 0) {
|
||||||
|
/* Not yet, working on it */
|
||||||
|
/* rprintf(reqInfo,"Accept-Ranges: bytes%c%c",CR,LF); */
|
||||||
|
rprintf(reqInfo,"Content-length: %d%c%c",
|
||||||
|
reqInfo->outh_content_length,CR,LF);
|
||||||
|
}
|
||||||
|
if(reqInfo->outh_content_encoding[0])
|
||||||
|
rprintf(reqInfo,"Content-encoding: %s%c%c",
|
||||||
|
reqInfo->outh_content_encoding,CR,LF);
|
||||||
|
#ifdef CONTENT_MD5
|
||||||
|
if(reqInfo->outh_content_md5)
|
||||||
|
rprintf(reqInfo,"Content-MD5: %s%c%c",
|
||||||
|
reqInfo->outh_content_md5,CR,LF);
|
||||||
|
#endif /* CONTENT_MD5 */
|
||||||
|
|
||||||
|
if(reqInfo->outh_www_auth[0])
|
||||||
|
rprintf(reqInfo,"WWW-Authenticate: %s%c%c",
|
||||||
|
reqInfo->outh_www_auth,CR,LF);
|
||||||
|
|
||||||
|
if (reqInfo->bNotifyDomainRestricted && reqInfo->bSatisfiedDomain)
|
||||||
|
rprintf(reqInfo,"Extension: Domain-Restricted%c%c",CR,LF);
|
||||||
|
|
||||||
|
keep_alive.bKeepAlive = keep_alive.bKeepAlive &&
|
||||||
|
(reqInfo->outh_content_length >= 0);
|
||||||
|
if (keep_alive.bKeepAlive && (!keep_alive.nMaxRequests ||
|
||||||
|
keep_alive.nCurrRequests + 1 <
|
||||||
|
keep_alive.nMaxRequests)) {
|
||||||
|
keep_alive.bKeepAlive = 1;
|
||||||
|
rprintf(reqInfo,
|
||||||
|
"Connection: Keep-Alive%c%cKeep-Alive: max=%d, timeout=%d%c%c",
|
||||||
|
CR,LF, keep_alive.nMaxRequests, keep_alive.nTimeOut,CR,LF);
|
||||||
|
}
|
||||||
|
if(reqInfo->outh_cgi)
|
||||||
|
rprintf(reqInfo,"%s",reqInfo->outh_cgi);
|
||||||
|
|
||||||
|
rprintf(reqInfo,"%c%c",CR,LF);
|
||||||
|
|
||||||
|
/* CLF doesn't include the headers, I don't think, so clear the information
|
||||||
|
* on what has been sent so far (byte count wise)
|
||||||
|
*/
|
||||||
|
reqInfo->bytes_sent = 0;
|
||||||
|
/* rflush(reqInfo); */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Time out function for send_fd and send_fp
|
||||||
|
* Logs whether an Abort or Time out occurs, logs how much has been sent,
|
||||||
|
* Does some cleanup (CloseAll) and either exits of jumps back
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
void send_fd_timed_out(int sigcode)
|
void send_fd_timed_out(int sigcode)
|
||||||
{
|
{
|
||||||
char errstr[MAX_STRING_LEN];
|
char *errstr;
|
||||||
|
|
||||||
|
errstr = newString(HUGE_STRING_LEN,STR_TMP);
|
||||||
if(exit_callback) (*exit_callback)();
|
if(exit_callback) (*exit_callback)();
|
||||||
if (sigcode != SIGPIPE) {
|
if (sigcode != SIGPIPE) {
|
||||||
sprintf(errstr,"httpd: send timed out for %s, URL: %s",
|
sprintf(errstr,"HTTPd: send timed out for %s, URL: %s",
|
||||||
(gCurrentRequest->remote_name ?
|
(gCurrentRequest->remote_name ?
|
||||||
gCurrentRequest->remote_name : "remote host"),
|
gCurrentRequest->remote_name : "remote host"),
|
||||||
(gCurrentRequest->url ? gCurrentRequest->url : "-"));
|
(gCurrentRequest->url ? gCurrentRequest->url : "-"));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sprintf(errstr,"httpd: send aborted for %s, URL: %s",
|
sprintf(errstr,"HTTPd: send aborted for %s, URL: %s",
|
||||||
(gCurrentRequest->remote_name ?
|
(gCurrentRequest->remote_name ?
|
||||||
gCurrentRequest->remote_name : "remote host"),
|
gCurrentRequest->remote_name : "remote host"),
|
||||||
(gCurrentRequest->url ? gCurrentRequest->url : "-"));
|
(gCurrentRequest->url ? gCurrentRequest->url : "-"));
|
||||||
}
|
}
|
||||||
log_error(errstr,gCurrentRequest->hostInfo->error_log);
|
log_error(errstr,gCurrentRequest->hostInfo->error_log);
|
||||||
@ -335,26 +498,33 @@ void send_fd_timed_out(int sigcode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* send_fp(): sends a file pointer to the socket. Uses fread to read,
|
||||||
We'll make it return the number of bytes sent
|
* but uses non-buffered I/O for writes (write())
|
||||||
so that we know if we need to send a body by default
|
*
|
||||||
*/
|
* We'll make it return the number of bytes sent
|
||||||
|
* so that we know if we need to send a body by default
|
||||||
|
*/
|
||||||
long send_fp(per_request *reqInfo, FILE *f, void (*onexit)(void))
|
long send_fp(per_request *reqInfo, FILE *f, void (*onexit)(void))
|
||||||
{
|
{
|
||||||
char buf[IOBUFSIZE];
|
char *buf;
|
||||||
long total_bytes_sent;
|
long total_bytes_sent;
|
||||||
register int n,o,w;
|
register int n,o,w;
|
||||||
|
/* ADC hack ZZZZ */
|
||||||
|
/* blong Unused? */
|
||||||
|
/* int i; */
|
||||||
|
|
||||||
|
buf = newString(IOBUFSIZE,STR_TMP);
|
||||||
exit_callback = onexit;
|
exit_callback = onexit;
|
||||||
signal(SIGALRM,send_fd_timed_out);
|
signal(SIGALRM,send_fd_timed_out);
|
||||||
signal(SIGPIPE,send_fd_timed_out);
|
signal(SIGPIPE,send_fd_timed_out);
|
||||||
|
|
||||||
total_bytes_sent = 0;
|
total_bytes_sent = 0;
|
||||||
fflush(reqInfo->out);
|
rflush(reqInfo);
|
||||||
while (1) {
|
while (1) {
|
||||||
alarm(timeout);
|
alarm(timeout);
|
||||||
if((n=fread(buf,sizeof(char),IOBUFSIZE,f)) < 1) {
|
if((n=fread(buf,sizeof(char),IOBUFSIZE,f)) < 1) {
|
||||||
if (errno != EINTR) break;
|
if (errno != EINTR) break;
|
||||||
|
else errno = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
o=0;
|
o=0;
|
||||||
@ -366,18 +536,67 @@ long send_fp(per_request *reqInfo, FILE *f, void (*onexit)(void))
|
|||||||
* For now, we'll just replace, but may have to #define one or the other
|
* For now, we'll just replace, but may have to #define one or the other
|
||||||
* depending on the system.
|
* depending on the system.
|
||||||
*/
|
*/
|
||||||
/* w=fwrite(&buf[o],sizeof(char),n,reqInfo->out); */
|
w = write(fileno(reqInfo->out),&buf[o],n);
|
||||||
if ((w=write(fileno(reqInfo->out),&buf[o],n)) < 0) {
|
if (w < 0) {
|
||||||
if (errno != EINTR) break;
|
if (errno != EINTR) break;
|
||||||
|
else errno = 0;
|
||||||
}
|
}
|
||||||
|
/* there goes ADC again... ZZZZ */
|
||||||
|
/*
|
||||||
|
for (i = 0; i<w; i++)
|
||||||
|
fputc(buf[o+i],stderr);
|
||||||
|
fflush(stderr);
|
||||||
|
*/
|
||||||
|
|
||||||
n-=w;
|
n-=w;
|
||||||
o+=w;
|
o+=w;
|
||||||
total_bytes_sent += w;
|
total_bytes_sent += w;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* fflush(reqInfo->out); */
|
|
||||||
alarm(0);
|
alarm(0);
|
||||||
signal(SIGALRM,SIG_IGN);
|
signal(SIGALRM,SIG_IGN);
|
||||||
signal(SIGPIPE,SIG_IGN);
|
signal(SIGPIPE,SIG_IGN);
|
||||||
|
freeString(buf);
|
||||||
return total_bytes_sent;
|
return total_bytes_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* rprintf() will print out to the socket, using buffered I/O
|
||||||
|
*/
|
||||||
|
int rprintf(per_request *reqInfo, char *format, ...)
|
||||||
|
{
|
||||||
|
va_list argList;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
#ifndef HAVE_VARARGS
|
||||||
|
va_start(argList,format);
|
||||||
|
#else
|
||||||
|
va_start(argList);
|
||||||
|
#endif /* HAVE_VARARGS */
|
||||||
|
x = vfprintf(reqInfo->out, format, argList);
|
||||||
|
|
||||||
|
|
||||||
|
va_end(argList);
|
||||||
|
|
||||||
|
reqInfo->bytes_sent += x;
|
||||||
|
return x;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* rputs() for drop into fputs(), for now.
|
||||||
|
*/
|
||||||
|
int rputs(char *string, per_request *reqInfo)
|
||||||
|
{
|
||||||
|
reqInfo->bytes_sent += strlen(string);
|
||||||
|
return fputs(string,reqInfo->out);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rputc(int ch, per_request *reqInfo)
|
||||||
|
{
|
||||||
|
(reqInfo->bytes_sent)++;
|
||||||
|
return putc(ch, reqInfo->out);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rflush(per_request *reqInfo)
|
||||||
|
{
|
||||||
|
return fflush(reqInfo->out);
|
||||||
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* http_send.h,v 1.6 1995/11/28 09:02:11 blong Exp
|
* http_send.h,v 1.10 1996/03/27 20:44:12 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
@ -20,16 +20,21 @@
|
|||||||
#ifndef _HTTP_SEND_H_
|
#ifndef _HTTP_SEND_H_
|
||||||
#define _HTTP_SEND_H_
|
#define _HTTP_SEND_H_
|
||||||
|
|
||||||
|
extern void (*exit_callback)(void);
|
||||||
|
|
||||||
/* function prototypes */
|
/* function prototypes */
|
||||||
void send_node(per_request *reqInfo);
|
void send_node(per_request *reqInfo);
|
||||||
void send_file(per_request *reqInfo, struct stat *fi,
|
void send_file(per_request *reqInfo, struct stat *fi, char allow_options);
|
||||||
char *path_args, char allow_options);
|
void send_dir(per_request *reqInfo,struct stat *finfo, char allow_options);
|
||||||
void send_dir(per_request *reqInfo,struct stat *finfo, char *pa,
|
int extract_path_info(per_request *reqInfo, struct stat *finfo);
|
||||||
char allow_options);
|
|
||||||
int extract_path_info(per_request *reqInfo, char *path_args,
|
|
||||||
struct stat *finfo);
|
|
||||||
long send_fp(per_request *reqInfo, FILE *f, void (*onexit)(void));
|
long send_fp(per_request *reqInfo, FILE *f, void (*onexit)(void));
|
||||||
void send_fd_timed_out(int);
|
void send_fd_timed_out(int);
|
||||||
|
void send_http_header(per_request *reqInfo);
|
||||||
|
|
||||||
|
int rprintf(per_request *reqInfo, char *format, ...);
|
||||||
|
int rputs(char *string, per_request *reqInfo);
|
||||||
|
int rputc(int ch, per_request *reqInfo);
|
||||||
|
int rflush(per_request *reqInfo);
|
||||||
|
|
||||||
#endif /* _HTTP_SEND_H_ */
|
#endif /* _HTTP_SEND_H_ */
|
||||||
|
|
||||||
|
301
src/httpd.c
301
src/httpd.c
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* httpd.c,v 1.115 1995/11/28 09:02:12 blong Exp
|
* httpd.c,v 1.131 1996/04/05 18:55:09 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
@ -18,36 +18,12 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 03-21-93 Rob McCool wrote original code (up to NCSA HTTPd 1.3)
|
* 03-21-93 Rob McCool wrote original code (up to NCSA HTTPd 1.3)
|
||||||
|
* 05-17-95 NCSA HTTPd 1.4.1
|
||||||
|
* 05-01-95 NCSA HTTPd 1.4.2
|
||||||
|
* 11-10-95 NCSA HTTPd 1.5.0
|
||||||
|
* 11-14-95 NCSA HTTPd 1.5.0a
|
||||||
|
* 03-21-96 NCSA HTTPd 1.5.0c
|
||||||
*
|
*
|
||||||
* 03-06-95 blong
|
|
||||||
* changed server number for child-alone processes to 0 and changed name
|
|
||||||
* of processes
|
|
||||||
*
|
|
||||||
* 03-10-95 blong
|
|
||||||
* Added numerous speed hacks proposed by Robert S. Thau (rst@ai.mit.edu)
|
|
||||||
* including set group before fork, and call gettime before to fork
|
|
||||||
* to set up libraries.
|
|
||||||
*
|
|
||||||
* 04-28-95 guillory
|
|
||||||
* Changed search pattern on child processes to better distribute load
|
|
||||||
*
|
|
||||||
* 04-30-95 blong
|
|
||||||
* added patch by Kevin Steves (stevesk@mayfield.hp.com) to fix
|
|
||||||
* rfc931 logging. We were passing sa_client, but this information
|
|
||||||
* wasn't known yet at the time of the pass to the child. Now uses
|
|
||||||
* getpeername in child_main to find this information.
|
|
||||||
*
|
|
||||||
* 08-16-95 blong
|
|
||||||
* added patch by Vince Tkac (tkac@oclc.org) to allow restart when
|
|
||||||
* a relative path is used on the command line with -f
|
|
||||||
*
|
|
||||||
* 10-26-95 blong
|
|
||||||
* added a RESOURCE_LIMIT compiletime option which limits the number
|
|
||||||
* of possible servers running to MaxServers
|
|
||||||
*
|
|
||||||
* 10-26-95 blong
|
|
||||||
* added patch by Stuart Lynne (sl@wimsey.com) to turn the proc title
|
|
||||||
* into a tachometer
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -87,10 +63,11 @@
|
|||||||
# include <sys/select.h>
|
# include <sys/select.h>
|
||||||
#endif /* NEED_SELECT_H */
|
#endif /* NEED_SELECT_H */
|
||||||
#ifndef NO_SYS_RESOURCE_H
|
#ifndef NO_SYS_RESOURCE_H
|
||||||
#include <sys/resource.h>
|
# include <sys/resource.h>
|
||||||
#endif /* NO_SYS_RESOURCE_H */
|
#endif /* NO_SYS_RESOURCE_H */
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "fdwrap.h"
|
#include "fdwrap.h"
|
||||||
|
#include "allocate.h"
|
||||||
#include "httpd.h"
|
#include "httpd.h"
|
||||||
#include "http_request.h"
|
#include "http_request.h"
|
||||||
#include "http_config.h"
|
#include "http_config.h"
|
||||||
@ -101,25 +78,31 @@
|
|||||||
#include "http_dir.h"
|
#include "http_dir.h"
|
||||||
#include "http_ipc.h"
|
#include "http_ipc.h"
|
||||||
#include "http_mime.h"
|
#include "http_mime.h"
|
||||||
|
#include "http_send.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
JMP_BUF jmpbuffer;
|
|
||||||
JMP_BUF restart_buffer;
|
JMP_BUF restart_buffer;
|
||||||
int servernum=0;
|
|
||||||
int mainSocket;
|
int mainSocket;
|
||||||
pid_t pgrp;
|
pid_t pgrp;
|
||||||
|
int debug_mode = FALSE;
|
||||||
|
|
||||||
|
/* Current global information per child, will need to be made
|
||||||
|
* non-global for threading
|
||||||
|
*/
|
||||||
|
#ifndef NOT_READY
|
||||||
int Child=0;
|
int Child=0;
|
||||||
int Alone=0;
|
int Alone=0;
|
||||||
int csd = -1;
|
|
||||||
/* To keep from being clobbered with setjmp */
|
/* To keep from being clobbered with setjmp */
|
||||||
static per_request *reqInfo = NULL;
|
JMP_BUF jmpbuffer;
|
||||||
|
int csd = -1;
|
||||||
KeepAliveData keep_alive; /* global keep alive info */
|
KeepAliveData keep_alive; /* global keep alive info */
|
||||||
|
#endif /* NOT_READY */
|
||||||
|
|
||||||
|
ChildInfo *Children;
|
||||||
|
int num_children = 0;
|
||||||
|
|
||||||
#ifndef NO_PASS
|
#ifndef NO_PASS
|
||||||
char donemsg[]="DONE";
|
char donemsg[]="DONE";
|
||||||
ChildInfo *Children;
|
|
||||||
int num_children = 0;
|
|
||||||
#endif /* NO_PASS */
|
#endif /* NO_PASS */
|
||||||
|
|
||||||
#if defined(KRB4) || defined(KRB5)
|
#if defined(KRB4) || defined(KRB5)
|
||||||
@ -135,7 +118,7 @@ void htexit(per_request *reqInfo, int status, int die_type)
|
|||||||
if(standalone || keep_alive.bKeepAlive) siglongjmp(jmpbuffer,die_type);
|
if(standalone || keep_alive.bKeepAlive) siglongjmp(jmpbuffer,die_type);
|
||||||
#endif /* NO_SIGLONGJMP */
|
#endif /* NO_SIGLONGJMP */
|
||||||
else {
|
else {
|
||||||
fflush(reqInfo->out);
|
rflush(reqInfo);
|
||||||
exit(status);
|
exit(status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,20 +142,20 @@ void detach(void)
|
|||||||
if((x = fork()) > 0)
|
if((x = fork()) > 0)
|
||||||
exit(0);
|
exit(0);
|
||||||
else if(x == -1) {
|
else if(x == -1) {
|
||||||
fprintf(stderr,"httpd: unable to fork new process\n");
|
fprintf(stderr,"HTTPd: unable to fork new process\n");
|
||||||
perror("fork");
|
perror("fork");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_SETSID
|
#ifndef NO_SETSID
|
||||||
if((pgrp=setsid()) == -1) {
|
if((pgrp=setsid()) == -1) {
|
||||||
fprintf(stderr,"httpd: setsid failed\n");
|
fprintf(stderr,"HTTPd: setsid failed\n");
|
||||||
perror("setsid");
|
perror("setsid");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if((pgrp=setpgrp(getpid(),0)) == -1) {
|
if((pgrp=setpgrp(getpid(),0)) == -1) {
|
||||||
fprintf(stderr,"httpd: setpgrp failed\n");
|
fprintf(stderr,"HTTPd: setpgrp failed\n");
|
||||||
perror("setpgrp");
|
perror("setpgrp");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -225,7 +208,7 @@ void seg_fault(void)
|
|||||||
close_all_logs();
|
close_all_logs();
|
||||||
chdir(core_dir);
|
chdir(core_dir);
|
||||||
abort();
|
abort();
|
||||||
exit(1);
|
/* exit(1); */
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_debug(void) {
|
void dump_debug(void) {
|
||||||
@ -234,6 +217,8 @@ void dump_debug(void) {
|
|||||||
log_error("HTTPd: caught USR1, dumping debugging information",
|
log_error("HTTPd: caught USR1, dumping debugging information",
|
||||||
gConfiguration->error_log);
|
gConfiguration->error_log);
|
||||||
|
|
||||||
|
fprintf(gConfiguration->error_log," ReqInfo: %d\tSockbuf: %d\tCGbuf: %d\n",
|
||||||
|
req_count,sockbuf_count,cgibuf_count);
|
||||||
tmp = gCurrentRequest;
|
tmp = gCurrentRequest;
|
||||||
while (tmp != NULL) {
|
while (tmp != NULL) {
|
||||||
fprintf(gConfiguration->error_log," Status: %d \t\t Bytes: %ld\n",tmp->status,
|
fprintf(gConfiguration->error_log," Status: %d \t\t Bytes: %ld\n",tmp->status,
|
||||||
@ -247,11 +232,11 @@ void dump_debug(void) {
|
|||||||
fprintf(gConfiguration->error_log," Host: %s \t IP: %s\n",
|
fprintf(gConfiguration->error_log," Host: %s \t IP: %s\n",
|
||||||
tmp->remote_host, tmp->remote_ip);
|
tmp->remote_host, tmp->remote_ip);
|
||||||
fprintf(gConfiguration->error_log," Content-type: %s \t Content-Length: %d\n",
|
fprintf(gConfiguration->error_log," Content-type: %s \t Content-Length: %d\n",
|
||||||
content_type, content_length);
|
tmp->outh_content_type, tmp->outh_content_length);
|
||||||
fprintf(gConfiguration->error_log," Refererer: %s\n",
|
fprintf(gConfiguration->error_log," Refererer: %s\n",
|
||||||
tmp->referer);
|
tmp->inh_referer);
|
||||||
fprintf(gConfiguration->error_log," User Agent: %s\n",
|
fprintf(gConfiguration->error_log," User Agent: %s\n",
|
||||||
tmp->agent);
|
tmp->inh_agent);
|
||||||
if (tmp->hostInfo->server_hostname)
|
if (tmp->hostInfo->server_hostname)
|
||||||
fprintf(gConfiguration->error_log," ServerName: %s\n",
|
fprintf(gConfiguration->error_log," ServerName: %s\n",
|
||||||
tmp->hostInfo->server_hostname);
|
tmp->hostInfo->server_hostname);
|
||||||
@ -266,7 +251,7 @@ void dump2(void)
|
|||||||
{
|
{
|
||||||
log_error("HTTPd: caught USR2, dumping debugging information",
|
log_error("HTTPd: caught USR2, dumping debugging information",
|
||||||
gConfiguration->error_log);
|
gConfiguration->error_log);
|
||||||
purify_new_leaks();
|
purify_new_leaks();
|
||||||
}
|
}
|
||||||
#endif /* PURIFY */
|
#endif /* PURIFY */
|
||||||
|
|
||||||
@ -333,6 +318,9 @@ void set_group_privs(void)
|
|||||||
fakeit.out = stdout;
|
fakeit.out = stdout;
|
||||||
fakeit.hostInfo = gConfiguration;
|
fakeit.hostInfo = gConfiguration;
|
||||||
|
|
||||||
|
/* Only change if root. Changed to geteuid() so that setuid scripts, etc
|
||||||
|
* can start the server and change from root
|
||||||
|
*/
|
||||||
if (!geteuid()) {
|
if (!geteuid()) {
|
||||||
/* Change standalone so that on error, we die, instead of siglongjmp */
|
/* Change standalone so that on error, we die, instead of siglongjmp */
|
||||||
tmp_stand = standalone;
|
tmp_stand = standalone;
|
||||||
@ -370,6 +358,7 @@ void speed_hack_libs(void)
|
|||||||
char buf[MAX_STRING_LEN];
|
char buf[MAX_STRING_LEN];
|
||||||
|
|
||||||
strftime (buf, MAX_STRING_LEN, "%d/%b/%Y:%H:%M:%S", dummy_time);
|
strftime (buf, MAX_STRING_LEN, "%d/%b/%Y:%H:%M:%S", dummy_time);
|
||||||
|
strftime (buf, MAX_STRING_LEN, "%d/%b/%Y:%H:%M:%S", other_dummy_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -378,7 +367,7 @@ void speed_hack_libs(void)
|
|||||||
* another request is ready, or the timeout period is up.
|
* another request is ready, or the timeout period is up.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int WaitForRequest (int csd, KeepAliveData *kad)
|
int wait_keepalive(int csd, KeepAliveData *kad)
|
||||||
{
|
{
|
||||||
fd_set listen_set;
|
fd_set listen_set;
|
||||||
struct timeval ka_timeout;
|
struct timeval ka_timeout;
|
||||||
@ -401,20 +390,31 @@ int WaitForRequest (int csd, KeepAliveData *kad)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompleteRequest (per_request *reqInfo, int pipe)
|
void CompleteRequest(per_request *reqInfo, int pipe)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Changed from shutdown(csd,2) to allow kernel to finish sending data
|
/* Changed from shutdown(csd,2) to allow kernel to finish sending data
|
||||||
required on OSF/1 2.0 (Achille Hui (eillihca@drizzle.stanford.edu)) */
|
* required on OSF/1 2.0 (Achille Hui (eillihca@drizzle.stanford.edu)) */
|
||||||
shutdown(csd,0);
|
/* shutdown(csd,0); */
|
||||||
|
shutdown(csd,2);
|
||||||
close(csd);
|
close(csd);
|
||||||
#ifndef NO_PASS
|
#ifndef NO_PASS
|
||||||
if (pipe >= 0) {
|
if (pipe >= 0) {
|
||||||
write(pipe,donemsg,sizeof(donemsg));
|
write(pipe,donemsg,sizeof(donemsg));
|
||||||
|
if (reqInfo != NULL) reqInfo->RequestFlags = 0;
|
||||||
|
free_request(reqInfo,NOT_LAST);
|
||||||
CloseAll();
|
CloseAll();
|
||||||
|
freeAllStrings(STR_REQ);
|
||||||
kill_indexing(FI_LOCAL);
|
kill_indexing(FI_LOCAL);
|
||||||
free_request(reqInfo,0);
|
/* current_process_size("CompleteRequest/2"); */
|
||||||
|
#ifdef QUANTIFY
|
||||||
|
/* quantify_save_data(); */
|
||||||
|
#endif /* QUANTIFY */
|
||||||
} else
|
} else
|
||||||
#endif /* NO_PASS */
|
#endif /* NO_PASS */
|
||||||
|
#ifdef QUANTIFY
|
||||||
|
/* quantify_save_data(); */
|
||||||
|
#endif /* QUANTIFY */
|
||||||
#ifdef PROFILE
|
#ifdef PROFILE
|
||||||
exit (2);
|
exit (2);
|
||||||
#else
|
#else
|
||||||
@ -425,12 +425,20 @@ void CompleteRequest (per_request *reqInfo, int pipe)
|
|||||||
void child_alone(int csd, struct sockaddr_in *sa_server,
|
void child_alone(int csd, struct sockaddr_in *sa_server,
|
||||||
CLIENT_SOCK_ADDR *sa_client)
|
CLIENT_SOCK_ADDR *sa_client)
|
||||||
{
|
{
|
||||||
|
static per_request *reqInfo = NULL;
|
||||||
|
|
||||||
|
#ifndef THREADED
|
||||||
close(mainSocket);
|
close(mainSocket);
|
||||||
|
#endif /* THREADED */
|
||||||
|
|
||||||
#ifdef PROFILE
|
#ifdef PROFILE
|
||||||
moncontrol(1);
|
moncontrol(1);
|
||||||
#endif /* PROFILE */
|
#endif /* PROFILE */
|
||||||
|
#ifdef QUANTIFY
|
||||||
|
/* quantify_clear_data(); */
|
||||||
|
quantify_start_recording_data();
|
||||||
|
#endif /* QUANTIFY */
|
||||||
|
|
||||||
Child = Alone = 1;
|
Child = Alone = 1;
|
||||||
standalone = 0;
|
standalone = 0;
|
||||||
keep_alive.nCurrRequests = 0;
|
keep_alive.nCurrRequests = 0;
|
||||||
@ -444,12 +452,12 @@ void child_alone(int csd, struct sockaddr_in *sa_server,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef THREADED
|
||||||
/* this should check error status, but it's not crucial */
|
|
||||||
close(0);
|
close(0);
|
||||||
close(1);
|
close(1);
|
||||||
dup2(csd,0);
|
dup2(csd,0);
|
||||||
dup2(csd,1);
|
dup2(csd,1);
|
||||||
|
#endif /* THREADED */
|
||||||
|
|
||||||
remote_logname = (!do_rfc931 ? NULL :
|
remote_logname = (!do_rfc931 ? NULL :
|
||||||
rfc931((struct sockaddr_in *)sa_client,
|
rfc931((struct sockaddr_in *)sa_client,
|
||||||
@ -460,49 +468,46 @@ void child_alone(int csd, struct sockaddr_in *sa_server,
|
|||||||
#else
|
#else
|
||||||
if (sigsetjmp(jmpbuffer,1) != 0) {
|
if (sigsetjmp(jmpbuffer,1) != 0) {
|
||||||
#endif /* NO_SIGLONGJMP */
|
#endif /* NO_SIGLONGJMP */
|
||||||
/* WaitForRequests returns 0 if timeout */
|
/* wait_keepalive returns 0 if timeout */
|
||||||
/* CompleteRequest doesn't return */
|
/* CompleteRequest doesn't return */
|
||||||
fflush(gCurrentRequest->out);
|
rflush(gCurrentRequest);
|
||||||
kill_indexing(FI_LOCAL);
|
kill_indexing(FI_LOCAL);
|
||||||
if ((keep_alive.nMaxRequests
|
if ((keep_alive.nMaxRequests
|
||||||
&& (++keep_alive.nCurrRequests >= keep_alive.nMaxRequests)) ||
|
&& (++keep_alive.nCurrRequests >= keep_alive.nMaxRequests)) ||
|
||||||
!WaitForRequest(csd, &keep_alive)) {
|
!wait_keepalive(csd, &keep_alive)) {
|
||||||
CompleteRequest(gCurrentRequest,-1);
|
CompleteRequest(gCurrentRequest,-1);
|
||||||
reqInfo = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
reqInfo = initialize_request(reqInfo);
|
reqInfo = initialize_request(reqInfo);
|
||||||
reqInfo->connection_socket = 0;
|
reqInfo->connection_socket = 0;
|
||||||
|
reqInfo->in = 0;
|
||||||
reqInfo->out = stdout;
|
reqInfo->out = stdout;
|
||||||
get_request(reqInfo);
|
RequestMain(reqInfo);
|
||||||
fflush(reqInfo->out);
|
rflush(reqInfo);
|
||||||
kill_indexing(FI_LOCAL);
|
kill_indexing(FI_LOCAL);
|
||||||
|
|
||||||
if (!keep_alive.bKeepAlive) {
|
if (!keep_alive.bKeepAlive) {
|
||||||
CompleteRequest(reqInfo,-1);
|
CompleteRequest(reqInfo,-1);
|
||||||
reqInfo = NULL;
|
|
||||||
} else if ((keep_alive.nMaxRequests
|
} else if ((keep_alive.nMaxRequests
|
||||||
&& (++keep_alive.nCurrRequests >= keep_alive.nMaxRequests))
|
&& (++keep_alive.nCurrRequests >= keep_alive.nMaxRequests))
|
||||||
|| !WaitForRequest(csd, &keep_alive)) {
|
|| !wait_keepalive(csd, &keep_alive)) {
|
||||||
CompleteRequest(reqInfo,-1);
|
CompleteRequest(reqInfo,-1);
|
||||||
reqInfo = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_PASS
|
|
||||||
/* to keep from being clobbered by setjmp */
|
/* to keep from being clobbered by setjmp */
|
||||||
static int x;
|
static int x;
|
||||||
static int val; /* indicates if keep_alive should remain active */
|
static int val; /* indicates if keep_alive should remain active */
|
||||||
static int nFirst = 0;
|
|
||||||
#ifdef FD_LINUX
|
#ifdef FD_LINUX
|
||||||
static int switch_uid = 0;
|
static int switch_uid = 0;
|
||||||
#endif /* FD_LINUX */
|
#endif /* FD_LINUX */
|
||||||
|
|
||||||
void child_main(int parent_pipe, SERVER_SOCK_ADDR *sa_server)
|
void child_main(int parent_pipe, SERVER_SOCK_ADDR *sa_server)
|
||||||
{
|
{
|
||||||
|
static per_request *reqInfo = NULL;
|
||||||
close(mainSocket);
|
close(mainSocket);
|
||||||
|
|
||||||
#ifdef PROFILE
|
#ifdef PROFILE
|
||||||
@ -510,7 +515,8 @@ void child_main(int parent_pipe, SERVER_SOCK_ADDR *sa_server)
|
|||||||
#endif /* PROFILE */
|
#endif /* PROFILE */
|
||||||
|
|
||||||
#ifdef QUANTIFY
|
#ifdef QUANTIFY
|
||||||
quantify_clear_data();
|
/* quantify_clear_data(); */
|
||||||
|
quantify_start_recording_data();
|
||||||
#endif /* QUANTIFY */
|
#endif /* QUANTIFY */
|
||||||
|
|
||||||
/* Only try to switch if we're running as root */
|
/* Only try to switch if we're running as root */
|
||||||
@ -547,12 +553,14 @@ void child_main(int parent_pipe, SERVER_SOCK_ADDR *sa_server)
|
|||||||
standalone = 1;
|
standalone = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef THREADED
|
||||||
for(x=0;x<num_children;x++) {
|
for(x=0;x<num_children;x++) {
|
||||||
if (parent_pipe != Children[x].parentfd) close(Children[x].parentfd);
|
if (parent_pipe != Children[x].parentfd) close(Children[x].parentfd);
|
||||||
if (parent_pipe != Children[x].childfd) close(Children[x].childfd);
|
if (parent_pipe != Children[x].childfd) close(Children[x].childfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(Children);
|
free(Children);
|
||||||
|
#endif /* THREADED */
|
||||||
|
|
||||||
#ifdef NO_SIGLONGJMP
|
#ifdef NO_SIGLONGJMP
|
||||||
if ((val = setjmp(jmpbuffer)) != 0) {
|
if ((val = setjmp(jmpbuffer)) != 0) {
|
||||||
@ -560,60 +568,58 @@ void child_main(int parent_pipe, SERVER_SOCK_ADDR *sa_server)
|
|||||||
if ((val = sigsetjmp(jmpbuffer,1)) != 0) {
|
if ((val = sigsetjmp(jmpbuffer,1)) != 0) {
|
||||||
#endif /* NO_SIGLONGJMP */
|
#endif /* NO_SIGLONGJMP */
|
||||||
reqInfo = gCurrentRequest;
|
reqInfo = gCurrentRequest;
|
||||||
fflush(reqInfo->out);
|
rflush(reqInfo);
|
||||||
kill_indexing(FI_LOCAL);
|
kill_indexing(FI_LOCAL);
|
||||||
if (val == DIE_KEEPALIVE) {
|
if (val == DIE_KEEPALIVE) {
|
||||||
/* returns 0 if timeout during multiple request session */
|
/* returns 0 if timeout during multiple request session */
|
||||||
if ((keep_alive.nMaxRequests
|
if ((keep_alive.nMaxRequests
|
||||||
&& (++keep_alive.nCurrRequests >= keep_alive.nMaxRequests))
|
&& (++keep_alive.nCurrRequests >= keep_alive.nMaxRequests))
|
||||||
|| !WaitForRequest(csd, &keep_alive)) {
|
|| !wait_keepalive(csd, &keep_alive)) {
|
||||||
keep_alive.bKeepAlive = 0;
|
keep_alive.bKeepAlive = 0;
|
||||||
CompleteRequest(reqInfo,parent_pipe);
|
CompleteRequest(reqInfo,parent_pipe);
|
||||||
reqInfo = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { /* in case it was in effect. probably a better place to reset */
|
else { /* in case it was in effect. probably a better place to reset */
|
||||||
keep_alive.bKeepAlive = 0;
|
keep_alive.bKeepAlive = 0;
|
||||||
CompleteRequest(reqInfo,parent_pipe);
|
CompleteRequest(reqInfo,parent_pipe);
|
||||||
reqInfo = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
alarm (0);
|
alarm (0);
|
||||||
if (!nFirst || !keep_alive.bKeepAlive) {
|
if (!keep_alive.bKeepAlive) {
|
||||||
GetDescriptor (parent_pipe);
|
GetDescriptor (parent_pipe);
|
||||||
remote_logname = GetRemoteLogName(sa_server);
|
remote_logname = GetRemoteLogName(sa_server);
|
||||||
nFirst = 1;
|
|
||||||
keep_alive.nCurrRequests = 0;
|
keep_alive.nCurrRequests = 0;
|
||||||
|
if (reqInfo != NULL) reqInfo->RequestFlags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
reqInfo = initialize_request(reqInfo);
|
reqInfo = initialize_request(reqInfo);
|
||||||
reqInfo->connection_socket = 0;
|
reqInfo->connection_socket = 0;
|
||||||
|
reqInfo->in = 0;
|
||||||
reqInfo->out = stdout;
|
reqInfo->out = stdout;
|
||||||
get_request(reqInfo);
|
RequestMain(reqInfo);
|
||||||
fflush(reqInfo->out);
|
rflush(reqInfo);
|
||||||
kill_indexing(FI_LOCAL);
|
kill_indexing(FI_LOCAL);
|
||||||
|
|
||||||
if (!keep_alive.bKeepAlive) {
|
if (!keep_alive.bKeepAlive) {
|
||||||
CompleteRequest(reqInfo,parent_pipe);
|
CompleteRequest(reqInfo,parent_pipe);
|
||||||
reqInfo = NULL;
|
|
||||||
nFirst = 0;
|
|
||||||
} else if ((keep_alive.nMaxRequests
|
} else if ((keep_alive.nMaxRequests
|
||||||
&& (++keep_alive.nCurrRequests >= keep_alive.nMaxRequests))
|
&& (++keep_alive.nCurrRequests >= keep_alive.nMaxRequests))
|
||||||
|| !WaitForRequest(csd, &keep_alive)) {
|
|| !wait_keepalive(csd, &keep_alive)) {
|
||||||
keep_alive.bKeepAlive = 0;
|
keep_alive.bKeepAlive = 0;
|
||||||
nFirst = 0;
|
|
||||||
CompleteRequest(reqInfo,parent_pipe);
|
CompleteRequest(reqInfo,parent_pipe);
|
||||||
reqInfo = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetDescriptor (int parent_pipe)
|
#ifndef NO_PASS
|
||||||
|
void GetDescriptor(int parent_pipe)
|
||||||
{
|
{
|
||||||
|
#ifndef THREADED
|
||||||
dup2(parent_pipe,0);
|
dup2(parent_pipe,0);
|
||||||
dup2(parent_pipe,1);
|
dup2(parent_pipe,1);
|
||||||
|
#endif /* THREADED */
|
||||||
#ifdef SETPROCTITLE
|
#ifdef SETPROCTITLE
|
||||||
setproctitle("idle");
|
setproctitle("idle");
|
||||||
#endif /* SETPROCTITLE */
|
#endif /* SETPROCTITLE */
|
||||||
@ -647,11 +653,15 @@ void GetDescriptor (int parent_pipe)
|
|||||||
close(parent_pipe);
|
close(parent_pipe);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
#ifndef THREADED
|
||||||
close(0);
|
close(0);
|
||||||
close(1);
|
close(1);
|
||||||
dup2(csd,0);
|
dup2(csd,0);
|
||||||
dup2(csd,1);
|
dup2(csd,1);
|
||||||
|
#endif /* THREADED */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif /* NO_PASS */
|
||||||
|
|
||||||
char* GetRemoteLogName (SERVER_SOCK_ADDR *sa_server)
|
char* GetRemoteLogName (SERVER_SOCK_ADDR *sa_server)
|
||||||
{
|
{
|
||||||
@ -668,15 +678,17 @@ char* GetRemoteLogName (SERVER_SOCK_ADDR *sa_server)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NO_PASS
|
||||||
int make_child(int argc, char **argv, int childnum,
|
int make_child(int argc, char **argv, int childnum,
|
||||||
SERVER_SOCK_ADDR *sa_server)
|
SERVER_SOCK_ADDR *sa_server)
|
||||||
{
|
{
|
||||||
int fd[2];
|
int fd[2];
|
||||||
int pid;
|
int pid;
|
||||||
|
#ifdef SETPROCTITLE
|
||||||
char namestr[30];
|
char namestr[30];
|
||||||
|
#endif /* SETPROCTITLE */
|
||||||
|
|
||||||
pid = 1;
|
pid = 1;
|
||||||
servernum = childnum;
|
|
||||||
#ifndef NEED_SPIPE
|
#ifndef NEED_SPIPE
|
||||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1) {
|
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1) {
|
||||||
#else
|
#else
|
||||||
@ -698,20 +710,22 @@ int make_child(int argc, char **argv, int childnum,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!pid) {
|
if (!pid) {
|
||||||
close(Children[childnum].childfd);
|
/* Child */
|
||||||
|
|
||||||
|
close(Children[childnum].childfd);
|
||||||
#ifdef BSD
|
#ifdef BSD
|
||||||
signal(SIGCHLD,(void (*)())ign);
|
signal(SIGCHLD,(void (*)())ign);
|
||||||
#else
|
#else
|
||||||
signal(SIGCHLD,SIG_IGN);
|
signal(SIGCHLD,SIG_IGN);
|
||||||
#endif /* BSD */
|
#endif /* BSD */
|
||||||
sprintf(namestr,"child %d",childnum);
|
|
||||||
#ifdef SETPROCTITLE
|
#ifdef SETPROCTITLE
|
||||||
/* inststr(argv,argc,namestr); */
|
sprintf(namestr,"child %d",childnum);
|
||||||
setproctitle(namestr);
|
setproctitle(namestr);
|
||||||
#endif /* SETPROCTITLE */
|
#endif /* SETPROCTITLE */
|
||||||
Child = 1;
|
Child = 1;
|
||||||
child_main(Children[childnum].parentfd, sa_server);
|
child_main(Children[childnum].parentfd, sa_server);
|
||||||
} else {
|
} else {
|
||||||
|
/* Parent */
|
||||||
close(Children[childnum].parentfd);
|
close(Children[childnum].parentfd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -727,14 +741,14 @@ void initialize_socket(SERVER_SOCK_ADDR *sa_server,
|
|||||||
int keepalive_value = 1;
|
int keepalive_value = 1;
|
||||||
|
|
||||||
if ((mainSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1) {
|
if ((mainSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1) {
|
||||||
fprintf(stderr,"httpd: could not get socket\n");
|
fprintf(stderr,"HTTPd: could not get socket\n");
|
||||||
perror("socket");
|
perror("socket");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((setsockopt(mainSocket,SOL_SOCKET,SO_REUSEADDR,(char *)&one,
|
if((setsockopt(mainSocket,SOL_SOCKET,SO_REUSEADDR,(char *)&one,
|
||||||
sizeof(one))) == -1) {
|
sizeof(one))) == -1) {
|
||||||
fprintf(stderr,"httpd: could not set socket option SO_REUSEADDR\n");
|
fprintf(stderr,"HTTPd: could not set socket option SO_REUSEADDR\n");
|
||||||
perror("setsockopt");
|
perror("setsockopt");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -746,12 +760,12 @@ void initialize_socket(SERVER_SOCK_ADDR *sa_server,
|
|||||||
|
|
||||||
if((setsockopt(mainSocket,SOL_SOCKET,SO_KEEPALIVE,(void *)&keepalive_value,
|
if((setsockopt(mainSocket,SOL_SOCKET,SO_KEEPALIVE,(void *)&keepalive_value,
|
||||||
sizeof(keepalive_value))) == -1) {
|
sizeof(keepalive_value))) == -1) {
|
||||||
fprintf(stderr,"httpd: could not set socket option SO_KEEPALIVE\n");
|
fprintf(stderr,"HTTPd: could not set socket option SO_KEEPALIVE\n");
|
||||||
perror("setsockopt");
|
perror("setsockopt");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bzero((char *) sa_server, sizeof(*sa_server));
|
memset((char *)sa_server, 0, sizeof(*sa_server));
|
||||||
sa_server->sin_family=AF_INET;
|
sa_server->sin_family=AF_INET;
|
||||||
sa_server->sin_addr= gConfiguration->address_info;
|
sa_server->sin_addr= gConfiguration->address_info;
|
||||||
/* sa_server.sin_addr.s_addr=htonl(INADDR_ANY); */
|
/* sa_server.sin_addr.s_addr=htonl(INADDR_ANY); */
|
||||||
@ -761,7 +775,7 @@ void initialize_socket(SERVER_SOCK_ADDR *sa_server,
|
|||||||
fprintf(stderr,"HTTPd: cound not bind to address %s port %d\n",
|
fprintf(stderr,"HTTPd: cound not bind to address %s port %d\n",
|
||||||
inet_ntoa(gConfiguration->address_info),port);
|
inet_ntoa(gConfiguration->address_info),port);
|
||||||
else
|
else
|
||||||
fprintf(stderr,"httpd: could not bind to port %d\n",port);
|
fprintf(stderr,"HTTPd: could not bind to port %d\n",port);
|
||||||
perror("bind");
|
perror("bind");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -781,12 +795,13 @@ void standalone_main(int argc, char **argv)
|
|||||||
static SERVER_SOCK_ADDR sa_server;
|
static SERVER_SOCK_ADDR sa_server;
|
||||||
static CLIENT_SOCK_ADDR sa_client;
|
static CLIENT_SOCK_ADDR sa_client;
|
||||||
static int one = 1;
|
static int one = 1;
|
||||||
|
static int pid = 0;
|
||||||
#ifdef TACHOMETER
|
#ifdef TACHOMETER
|
||||||
static int Requests[MAX_TACHOMETER];
|
static int Requests[MAX_TACHOMETER];
|
||||||
static time_t Request_time = 0L;
|
static time_t Request_time = 0L;
|
||||||
static int i;
|
static int i;
|
||||||
static char Request_title[64];
|
static char Request_title[64];
|
||||||
#endif
|
#endif /* TACHOMETER */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -794,9 +809,8 @@ void standalone_main(int argc, char **argv)
|
|||||||
process to ensure proper time zone settings */
|
process to ensure proper time zone settings */
|
||||||
tzset();
|
tzset();
|
||||||
|
|
||||||
#if !defined(PROFILE) && !defined(QUANTIFY)
|
if (debug_mode == FALSE)
|
||||||
detach();
|
detach();
|
||||||
#endif /* PROFILE */
|
|
||||||
|
|
||||||
sprintf(error_msg,"HTTPd: Starting as %s",argv[0]);
|
sprintf(error_msg,"HTTPd: Starting as %s",argv[0]);
|
||||||
x = 1;
|
x = 1;
|
||||||
@ -816,6 +830,7 @@ void standalone_main(int argc, char **argv)
|
|||||||
#endif /* SETPROCTITLE */
|
#endif /* SETPROCTITLE */
|
||||||
|
|
||||||
while(!Exit) {
|
while(!Exit) {
|
||||||
|
/* current_process_size("Starting"); */
|
||||||
initialize_socket(&sa_server,&sa_client);
|
initialize_socket(&sa_server,&sa_client);
|
||||||
set_signals();
|
set_signals();
|
||||||
speed_hack_libs();
|
speed_hack_libs();
|
||||||
@ -823,9 +838,11 @@ void standalone_main(int argc, char **argv)
|
|||||||
|
|
||||||
#ifndef NO_PASS
|
#ifndef NO_PASS
|
||||||
num_children = 0;
|
num_children = 0;
|
||||||
Children = (ChildInfo *) malloc(sizeof(ChildInfo)*(max_servers+1));
|
if (debug_mode == FALSE) {
|
||||||
while (num_children < start_servers) {
|
Children = (ChildInfo *) malloc(sizeof(ChildInfo)*(max_servers+1));
|
||||||
make_child(argc, argv, num_children++, &sa_server);
|
while (num_children < start_servers) {
|
||||||
|
make_child(argc, argv, num_children++, &sa_server);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif /* NO_PASS */
|
#endif /* NO_PASS */
|
||||||
|
|
||||||
@ -935,10 +952,13 @@ void standalone_main(int argc, char **argv)
|
|||||||
} /* if (make_child) else ... */
|
} /* if (make_child) else ... */
|
||||||
} else {
|
} else {
|
||||||
/* Already have as many children as compiled for.*/
|
/* Already have as many children as compiled for.*/
|
||||||
if (!fork()) {
|
if (debug_mode == FALSE)
|
||||||
/* inststr(argv, argc, "httpd-alone"); */
|
pid = fork();
|
||||||
|
else
|
||||||
|
Exit = TRUE;
|
||||||
|
if (!pid) {
|
||||||
child_alone(csd,&sa_server,&sa_client);
|
child_alone(csd,&sa_server,&sa_client);
|
||||||
} /* fork */
|
}
|
||||||
} /* if (num_children < max_servers) ... else ... */
|
} /* if (num_children < max_servers) ... else ... */
|
||||||
} else {
|
} else {
|
||||||
Children[free_child].busy = 1;
|
Children[free_child].busy = 1;
|
||||||
@ -952,8 +972,11 @@ void standalone_main(int argc, char **argv)
|
|||||||
} else
|
} else
|
||||||
#endif /* NO_PASS */
|
#endif /* NO_PASS */
|
||||||
{
|
{
|
||||||
if (!fork()) {
|
if (debug_mode == FALSE)
|
||||||
/* inststr(argv, argc, "httpd-alone"); */
|
pid = fork();
|
||||||
|
else
|
||||||
|
Exit = TRUE;
|
||||||
|
if (!pid) {
|
||||||
child_alone(csd,&sa_server,&sa_client);
|
child_alone(csd,&sa_server,&sa_client);
|
||||||
} /* fork */
|
} /* fork */
|
||||||
close(csd);
|
close(csd);
|
||||||
@ -979,7 +1002,7 @@ void standalone_main(int argc, char **argv)
|
|||||||
avg1, avg5/5, avg30/30);
|
avg1, avg5/5, avg30/30);
|
||||||
setproctitle(Request_title);
|
setproctitle(Request_title);
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* TACHOMETER */
|
||||||
} /* If good accept */
|
} /* If good accept */
|
||||||
} /* if mainSocket ready for read */
|
} /* if mainSocket ready for read */
|
||||||
} /* if select */
|
} /* if select */
|
||||||
@ -1005,6 +1028,7 @@ void standalone_main(int argc, char **argv)
|
|||||||
free(Children);
|
free(Children);
|
||||||
#endif /* NO_PASS */
|
#endif /* NO_PASS */
|
||||||
free_host_conf();
|
free_host_conf();
|
||||||
|
freeAllStrings(STR_HUP);
|
||||||
read_config(error_log);
|
read_config(error_log);
|
||||||
set_group_privs();
|
set_group_privs();
|
||||||
log_error("HTTPd: successful restart",error_log);
|
log_error("HTTPd: successful restart",error_log);
|
||||||
@ -1015,10 +1039,30 @@ void standalone_main(int argc, char **argv)
|
|||||||
} /* while (!Exit) */
|
} /* while (!Exit) */
|
||||||
} /* standalone_main */
|
} /* standalone_main */
|
||||||
|
|
||||||
|
void default_banner(FILE* fout)
|
||||||
|
{
|
||||||
|
fprintf(fout,"NCSA HTTPd %s\n",SERVER_SOURCE);
|
||||||
|
fprintf(fout,"Licensed material. Portions of this work are\n");
|
||||||
|
fprintf(fout,"Copyright (C) 1995-1996 Board of Trustees of the University of Illinois\n");
|
||||||
|
fprintf(fout,"Copyright (C) 1995-1996 The Apache Group\n");
|
||||||
|
#if defined(DIGEST_AUTH)
|
||||||
|
fprintf(fout,"Copyright (C) 1989-1993 RSA Data Security, Inc.\n");
|
||||||
|
#endif /* DIGEST_AUTH */
|
||||||
|
#ifdef DIGEST_AUTH
|
||||||
|
fprintf(fout,"Copyright (C) 1993-1994 Carnegie Mellon University\n");
|
||||||
|
fprintf(fout,"Copyright (C) 1991 Bell Communications Research, Inc. (Bellcore)\n");
|
||||||
|
fprintf(fout,"Copyright (C) 1994 Spyglass, Inc.\n");
|
||||||
|
#endif /* DIGEST_AUTH */
|
||||||
|
#ifdef FCGI_SUPPORT
|
||||||
|
fprintf(fout,"Copyright (C) 1995 Open Market, Inc.\n");
|
||||||
|
#endif /* FCGI_SUPPORT */
|
||||||
|
fflush(fout);
|
||||||
|
}
|
||||||
|
|
||||||
void usage(char *bin)
|
void usage(char *bin)
|
||||||
{
|
{
|
||||||
fprintf(stderr,"NCSA HTTPd %s\n",SERVER_SOURCE);
|
default_banner(stderr);
|
||||||
fprintf(stderr,"Documentation online at http://hoohoo.ncsa.uiuc.edu/\n\n");
|
fprintf(stderr,"\nDocumentation online at http://hoohoo.ncsa.uiuc.edu/\n\n");
|
||||||
|
|
||||||
fprintf(stderr,"Compiled in Options:\n");
|
fprintf(stderr,"Compiled in Options:\n");
|
||||||
#ifdef SETPROCTITLE
|
#ifdef SETPROCTITLE
|
||||||
@ -1036,29 +1080,42 @@ void usage(char *bin)
|
|||||||
#ifdef NO_PASS
|
#ifdef NO_PASS
|
||||||
fprintf(stderr,"\tNO_PASS\n");
|
fprintf(stderr,"\tNO_PASS\n");
|
||||||
#endif /* NO_PASS */
|
#endif /* NO_PASS */
|
||||||
|
#ifdef FCGI_SUPPORT
|
||||||
|
fprintf(stderr,"\tFCGI_SUPPORT\n");
|
||||||
|
#endif /* FCGI_SUPPORT */
|
||||||
#ifdef DBM_SUPPORT
|
#ifdef DBM_SUPPORT
|
||||||
fprintf(stderr,"\tDBM_SUPPORT\n");
|
fprintf(stderr,"\tDBM_SUPPORT\n");
|
||||||
#endif /* DBM_SUPPORT */
|
#endif /* DBM_SUPPORT */
|
||||||
|
#ifdef NIS_SUPPORT
|
||||||
|
fprintf(stderr,"\tNIS_SUPPORT\n");
|
||||||
|
#endif /* NIS_SUPPORT */
|
||||||
#ifdef DIGEST_AUTH
|
#ifdef DIGEST_AUTH
|
||||||
fprintf(stderr,"\tDIGEST_AUTH\n");
|
fprintf(stderr,"\tDIGEST_AUTH\n");
|
||||||
#endif /* DIGEST_AUTH */
|
#endif /* DIGEST_AUTH */
|
||||||
|
#ifdef CONTENT_MD5
|
||||||
|
fprintf(stderr,"\tCONTENT_MD5\n");
|
||||||
|
#endif /* CONTENT_MD5 */
|
||||||
#ifdef KRB4
|
#ifdef KRB4
|
||||||
fprintf(stderr,"\tKRB4\n");
|
fprintf(stderr,"\tKRB4\n");
|
||||||
#endif /* KRB4 */
|
#endif /* KRB4 */
|
||||||
#ifdef KRB5
|
#ifdef KRB5
|
||||||
fprintf(stderr,"\tKRB5\n");
|
fprintf(stderr,"\tKRB5\n");
|
||||||
#endif /* KRB5 */
|
#endif /* KRB5 */
|
||||||
|
#ifdef PEM_AUTH
|
||||||
|
fprintf(stderr,"\tPEM_AUTH\n");
|
||||||
|
#endif /* PEM_AUTH */
|
||||||
fprintf(stderr,"\tHTTPD_ROOT = %s\n",HTTPD_ROOT);
|
fprintf(stderr,"\tHTTPD_ROOT = %s\n",HTTPD_ROOT);
|
||||||
fprintf(stderr,"\tDOCUMENT_ROOT = %s\n", DOCUMENT_LOCATION);
|
fprintf(stderr,"\tDOCUMENT_ROOT = %s\n", DOCUMENT_LOCATION);
|
||||||
|
|
||||||
fprintf(stderr,"\n");
|
fprintf(stderr,"\n");
|
||||||
#ifdef HAVE_KERBEROS
|
#ifdef HAVE_KERBEROS
|
||||||
fprintf(stderr,"Usage: %s [-d directory] [-f file] [-k file] [-K file] [-v]\n",bin);
|
fprintf(stderr,"Usage: %s [-d directory] [-f file] [-k file] [-K file] [-vX]\n",bin);
|
||||||
#else
|
#else
|
||||||
fprintf(stderr,"Usage: %s [-d directory] [-f file] [-v]\n",bin);
|
fprintf(stderr,"Usage: %s [-d directory] [-f file] [-vX]\n",bin);
|
||||||
#endif /* HAVE_KERBEROS */
|
#endif /* HAVE_KERBEROS */
|
||||||
fprintf(stderr,"-d directory\t : specify an alternate initial ServerRoot\n");
|
fprintf(stderr,"-d directory\t : specify an alternate initial ServerRoot\n");
|
||||||
fprintf(stderr,"-f file\t\t : specify an alternate ServerConfigFile\n");
|
fprintf(stderr,"-f file\t\t : specify an alternate ServerConfigFile\n");
|
||||||
|
fprintf(stderr,"-X\t\t : Answer one request for debugging, don't fork\n");
|
||||||
fprintf(stderr,"-v\t\t : version information (this screen)\n");
|
fprintf(stderr,"-v\t\t : version information (this screen)\n");
|
||||||
#ifdef KRB4
|
#ifdef KRB4
|
||||||
fprintf(stderr,"-k file\t\t : specify an alternate Kerberos V4 svrtab file\n");
|
fprintf(stderr,"-k file\t\t : specify an alternate Kerberos V4 svrtab file\n");
|
||||||
@ -1076,6 +1133,7 @@ int main (int argc, char **argv, char **envp)
|
|||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
|
/* FIRST */
|
||||||
#ifdef RLIMIT_NOFILE
|
#ifdef RLIMIT_NOFILE
|
||||||
/* If defined (not user defined, but in sys/resource.h), this will attempt
|
/* If defined (not user defined, but in sys/resource.h), this will attempt
|
||||||
* to set the max file descriptors per process as high as allowed under
|
* to set the max file descriptors per process as high as allowed under
|
||||||
@ -1102,16 +1160,20 @@ int main (int argc, char **argv, char **envp)
|
|||||||
moncontrol(0);
|
moncontrol(0);
|
||||||
#endif /* PROFILE */
|
#endif /* PROFILE */
|
||||||
|
|
||||||
|
/* First things first */
|
||||||
strcpy(server_root,HTTPD_ROOT);
|
strcpy(server_root,HTTPD_ROOT);
|
||||||
make_full_path(server_root,SERVER_CONFIG_FILE,server_confname);
|
make_full_path(server_root,SERVER_CONFIG_FILE,server_confname);
|
||||||
|
|
||||||
#ifdef HAVE_KERBEROS
|
#ifdef HAVE_KERBEROS
|
||||||
while((c = getopt(argc,argv,"d:f:vk:K:")) != -1) {
|
while((c = getopt(argc,argv,"d:f:vk:K:Xs")) != -1) {
|
||||||
#else
|
#else
|
||||||
while((c = getopt(argc,argv,"d:f:v")) != -1) {
|
while((c = getopt(argc,argv,"d:f:vXs")) != -1) {
|
||||||
#endif /* HAVE_KERBEROS */
|
#endif /* HAVE_KERBEROS */
|
||||||
switch(c) {
|
switch(c) {
|
||||||
|
case 'X':
|
||||||
|
debug_mode = TRUE;
|
||||||
|
printf("Debug On\n");
|
||||||
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
strcpy(server_root,optarg);
|
strcpy(server_root,optarg);
|
||||||
make_full_path(server_root,SERVER_CONFIG_FILE,server_confname);
|
make_full_path(server_root,SERVER_CONFIG_FILE,server_confname);
|
||||||
@ -1146,20 +1208,30 @@ int main (int argc, char **argv, char **envp)
|
|||||||
break;
|
break;
|
||||||
#endif /* KRB5 */
|
#endif /* KRB5 */
|
||||||
#endif /* HAVE_KERBEROS */
|
#endif /* HAVE_KERBEROS */
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Global Initialization:
|
||||||
|
* Currently for File Descriptor Table and allocater
|
||||||
|
*/
|
||||||
InitFdTable();
|
InitFdTable();
|
||||||
|
initialize_allocate();
|
||||||
|
|
||||||
read_config(stderr);
|
read_config(stderr);
|
||||||
|
/* Passed arguments stage, dump baloney */
|
||||||
|
#ifndef SUPPRESS_BANNER
|
||||||
|
if (standalone) default_banner(stdout);
|
||||||
|
#endif /* SUPPRESS_BANNER */
|
||||||
#ifdef SETPROCTITLE
|
#ifdef SETPROCTITLE
|
||||||
initproctitle(process_name, argc, argv, envp);
|
initproctitle(process_name, argc, argv, envp);
|
||||||
#endif /* SETPROCTITLE */
|
#endif /* SETPROCTITLE */
|
||||||
|
|
||||||
set_group_privs();
|
set_group_privs();
|
||||||
get_local_host();
|
get_local_host();
|
||||||
|
|
||||||
#ifdef __QNX__
|
#ifdef __QNX__
|
||||||
dup2(0,1);
|
dup2(0,1);
|
||||||
dup2(0,2);
|
dup2(0,2);
|
||||||
@ -1174,14 +1246,15 @@ int main (int argc, char **argv, char **envp)
|
|||||||
group_id = getgid();
|
group_id = getgid();
|
||||||
|
|
||||||
reqInfo->connection_socket = 0;
|
reqInfo->connection_socket = 0;
|
||||||
|
reqInfo->in = 0;
|
||||||
reqInfo->out = stdout;
|
reqInfo->out = stdout;
|
||||||
port = get_portnum(reqInfo,fileno(reqInfo->out));
|
port = get_portnum(reqInfo,fileno(reqInfo->out));
|
||||||
|
|
||||||
if(do_rfc931)
|
if(do_rfc931)
|
||||||
remote_logname = get_remote_logname(reqInfo->out);
|
remote_logname = get_remote_logname(reqInfo->out);
|
||||||
|
|
||||||
get_request(reqInfo);
|
RequestMain(reqInfo);
|
||||||
fflush(reqInfo->out);
|
rflush(reqInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
close_all_logs();
|
close_all_logs();
|
||||||
|
16
src/httpd.h
16
src/httpd.h
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* httpd.h,v 1.91 1995/11/28 09:02:14 blong Exp
|
* httpd.h,v 1.97 1996/03/27 20:44:19 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
@ -25,16 +25,28 @@
|
|||||||
#define _HTTPD_H_
|
#define _HTTPD_H_
|
||||||
|
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
#include "http_request.h"
|
||||||
|
|
||||||
typedef struct _ChildInfo {
|
typedef struct _ChildInfo {
|
||||||
int parentfd;
|
int parentfd;
|
||||||
int childfd;
|
int childfd;
|
||||||
int pid;
|
int pid;
|
||||||
int busy;
|
int busy;
|
||||||
|
#ifdef NOT_READY
|
||||||
|
int status;
|
||||||
|
KeepAliveData keep_alive; /* Child's keep alive info */
|
||||||
|
int csd; /* Current Socket Descriptor */
|
||||||
|
JMP_BUF restart_child; /* Return buffer for siglongjmp */
|
||||||
|
per_request *gCurrentRequest; /* Current Request of Child */
|
||||||
|
#endif /* NOT_READY */
|
||||||
} ChildInfo;
|
} ChildInfo;
|
||||||
|
|
||||||
|
#ifndef NOT_READY
|
||||||
extern KeepAliveData keep_alive; /* global keep alive info */
|
extern KeepAliveData keep_alive; /* global keep alive info */
|
||||||
extern JMP_BUF jmpbuffer; /* Return buffer for siglongjmp */
|
extern JMP_BUF jmpbuffer; /* Return buffer for siglongjmp */
|
||||||
|
extern int csd; /* Current Socket Descriptor */
|
||||||
|
#endif /* NOT_READY */
|
||||||
|
|
||||||
|
|
||||||
/* function prototypes */
|
/* function prototypes */
|
||||||
|
|
||||||
|
@ -6,6 +6,8 @@ httpd \- NCSA HTTPd (hypertext transfer protocol daemon)
|
|||||||
[
|
[
|
||||||
.B \-v
|
.B \-v
|
||||||
] [
|
] [
|
||||||
|
.B \-X
|
||||||
|
] [
|
||||||
.BI \-d " serverroot"
|
.BI \-d " serverroot"
|
||||||
] [
|
] [
|
||||||
.BI \-f " config"
|
.BI \-f " config"
|
||||||
@ -32,6 +34,10 @@ the ServerRoot. The default is \fBconf/httpd.conf\fP.
|
|||||||
.B \-v
|
.B \-v
|
||||||
Print the version of httpd, including compiled defaults and
|
Print the version of httpd, including compiled defaults and
|
||||||
command line options.
|
command line options.
|
||||||
|
.TP
|
||||||
|
.B \-X
|
||||||
|
Execute in single request debugging mode, with no fork, no detach.
|
||||||
|
Useful for profiling and debugging.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
.PD 0
|
.PD 0
|
||||||
.B /usr/local/etc/httpd/conf/httpd.conf
|
.B /usr/local/etc/httpd/conf/httpd.conf
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
/* zippy.c
|
/* zippy.c
|
||||||
*
|
*
|
||||||
* Print a quotation from Zippy the Pinhead.
|
* Print a quotation from Zippy the Pinhead.
|
||||||
|
232
src/imagemap.c
232
src/imagemap.c
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* imagemap.c,v 1.7 1995/11/28 09:02:16 blong Exp
|
* imagemap.c,v 1.15 1996/04/05 19:14:19 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
@ -30,34 +30,60 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "http_log.h"
|
|
||||||
#include "fdwrap.h"
|
#include "fdwrap.h"
|
||||||
|
#include "allocate.h"
|
||||||
|
#include "http_log.h"
|
||||||
|
#include "http_config.h"
|
||||||
|
#include "http_request.h"
|
||||||
#include "imagemap.h"
|
#include "imagemap.h"
|
||||||
|
#include "cgi.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#ifdef IMAGEMAP_SUPPORT
|
#ifdef IMAGEMAP_SUPPORT
|
||||||
|
|
||||||
extern int port;
|
/* Error messages for imagemaps */
|
||||||
|
|
||||||
int send_imagemap(per_request* reqInfo, struct stat* fi, char* path_args,
|
#define IMAP_ERR_INCORRECT_ARGS 1
|
||||||
char allow_options)
|
#define IMAP_ERR_INCORRECT_COORDS 2
|
||||||
|
#define IMAP_ERR_CERN_MISSING_RIGHT_PAREN 3
|
||||||
|
|
||||||
|
char *imagemap_errors[] = {
|
||||||
|
"IMAP: Imagemap request requires two coordinates as arguments",
|
||||||
|
"IMAP: Imagemap args missing y value",
|
||||||
|
"IMAP: Imagemap args missing right paren"};
|
||||||
|
|
||||||
|
|
||||||
|
/* NCSA Imagemap files use: method URL coord1 coord2
|
||||||
|
* CERN Imagemap files use: method (coord1) (coord2) URL
|
||||||
|
* This version of imagemap will probably work with either in the same file,
|
||||||
|
* as long as a full line is in one format or the other.
|
||||||
|
*/
|
||||||
|
int send_imagemap(per_request* reqInfo, struct stat* fi, char allow_options)
|
||||||
{
|
{
|
||||||
char input[MAX_STRING_LEN], def[MAX_STRING_LEN];
|
char *input, *def, *szPoint, *url, *type;
|
||||||
char szPoint[MAX_STRING_LEN];
|
|
||||||
double testpoint[2], pointarray[MAXVERTS][2];
|
double testpoint[2], pointarray[MAXVERTS][2];
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
|
int error_num = 0;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *t;
|
char *t;
|
||||||
double dist, mindist = -1;
|
double dist, mindist = -1;
|
||||||
int sawpoint = 0;
|
int sawpoint = 0;
|
||||||
|
int sawparen = 0;
|
||||||
|
int Found = 0;
|
||||||
|
|
||||||
|
|
||||||
|
input = newString(HUGE_STRING_LEN,STR_TMP);
|
||||||
|
def = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
szPoint = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
type = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
url = newString(MAX_STRING_LEN,STR_TMP);
|
||||||
|
|
||||||
def[0] = '\0';
|
def[0] = '\0';
|
||||||
strcpy(szPoint, reqInfo->args);
|
strcpy(szPoint, reqInfo->args);
|
||||||
|
|
||||||
if(!(t = strchr(szPoint,','))) {
|
if(!(t = strchr(szPoint,','))) {
|
||||||
log_reason(reqInfo,
|
error_num = IMAP_ERR_INCORRECT_ARGS;
|
||||||
"Your client doesn't support image mapping properly.",
|
goto imagemap_error;
|
||||||
reqInfo->filename);
|
|
||||||
die(reqInfo, SC_BAD_IMAGEMAP, reqInfo->url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*t++ = '\0';
|
*t++ = '\0';
|
||||||
@ -67,70 +93,114 @@ int send_imagemap(per_request* reqInfo, struct stat* fi, char* path_args,
|
|||||||
if(!(fp=FOpen(reqInfo->filename,"r"))){
|
if(!(fp=FOpen(reqInfo->filename,"r"))){
|
||||||
log_reason(reqInfo, "File permissions deny server access",
|
log_reason(reqInfo, "File permissions deny server access",
|
||||||
reqInfo->filename);
|
reqInfo->filename);
|
||||||
|
freeString(input);
|
||||||
|
freeString(def);
|
||||||
|
freeString(szPoint);
|
||||||
|
freeString(url);
|
||||||
|
freeString(type);
|
||||||
die(reqInfo, SC_FORBIDDEN, reqInfo->url);
|
die(reqInfo, SC_FORBIDDEN, reqInfo->url);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (fgets(input,MAX_STRING_LEN,fp)) {
|
while (!Found && fgets(input,HUGE_STRING_LEN,fp)) {
|
||||||
char type[MAX_STRING_LEN];
|
|
||||||
char url[MAX_STRING_LEN];
|
|
||||||
char num[10];
|
char num[10];
|
||||||
|
|
||||||
|
/* Skip lines with # as comments and blank lines */
|
||||||
if((input[0] == '#') || (!input[0]))
|
if((input[0] == '#') || (!input[0]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
type[0] = '\0';url[0] = '\0';
|
type[0] = '\0';url[0] = '\0';
|
||||||
|
|
||||||
for(i=0;isname(input[i]) && (input[i]);i++)
|
/* Copy the shape keyword into type */
|
||||||
|
for(i=0;!isspace(input[i]) && (input[i]);i++)
|
||||||
type[i] = input[i];
|
type[i] = input[i];
|
||||||
type[i] = '\0';
|
type[i] = '\0';
|
||||||
|
|
||||||
|
/* Forward to next word */
|
||||||
while(isspace(input[i])) ++i;
|
while(isspace(input[i])) ++i;
|
||||||
for(j=0;input[i] && isname(input[i]);++i,++j)
|
|
||||||
url[j] = input[i];
|
|
||||||
url[j] = '\0';
|
|
||||||
|
|
||||||
|
/* If no coordinates, must be url for default, or NCSA format */
|
||||||
|
if (input[i] != '(') {
|
||||||
|
for(j=0;input[i] && !isspace(input[i]);++i,++j)
|
||||||
|
url[j] = input[i];
|
||||||
|
url[j] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle default keyword */
|
||||||
if(!strcmp(type,"default") && !sawpoint) {
|
if(!strcmp(type,"default") && !sawpoint) {
|
||||||
strcpy(def,url);
|
strcpy(def,url);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Looking for Coordinates */
|
||||||
k=0;
|
k=0;
|
||||||
while (input[i]) {
|
while (input[i]) {
|
||||||
|
/* Move over spaces and commas */
|
||||||
while (isspace(input[i]) || input[i] == ',')
|
while (isspace(input[i]) || input[i] == ',')
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
|
/* Under CERN, coordinates are in parenthesis */
|
||||||
|
if (input[i] == '(') {
|
||||||
|
sawparen = 1;
|
||||||
|
while (isspace(input[++i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy digits into num array */
|
||||||
|
j = 0;
|
||||||
|
while (isdigit(input[i]))
|
||||||
|
num[j++] = input[i++];
|
||||||
|
|
||||||
|
num[j] = '\0';
|
||||||
|
if (!j) break;
|
||||||
|
pointarray[k][X] = (double) atoi(num);
|
||||||
|
|
||||||
|
/* Skip to next digit */
|
||||||
|
while (isspace(input[i]) || input[i] == ',')
|
||||||
|
i++;
|
||||||
|
/* Copy other number into num */
|
||||||
j = 0;
|
j = 0;
|
||||||
while (isdigit(input[i]))
|
while (isdigit(input[i]))
|
||||||
num[j++] = input[i++];
|
num[j++] = input[i++];
|
||||||
num[j] = '\0';
|
num[j] = '\0';
|
||||||
if (num[0] != '\0')
|
|
||||||
pointarray[k][X] = (double) atoi(num);
|
if (!j && !sawparen && k > 0) {
|
||||||
else
|
pointarray[k++][Y] = -127;
|
||||||
break;
|
break;
|
||||||
while (isspace(input[i]) || input[i] == ',')
|
}
|
||||||
i++;
|
|
||||||
j = 0;
|
if (j)
|
||||||
while (isdigit(input[i]))
|
|
||||||
num[j++] = input[i++];
|
|
||||||
num[j] = '\0';
|
|
||||||
if (num[0] != '\0')
|
|
||||||
pointarray[k++][Y] = (double) atoi(num);
|
pointarray[k++][Y] = (double) atoi(num);
|
||||||
else {
|
else {
|
||||||
FClose(fp);
|
error_num = IMAP_ERR_INCORRECT_COORDS;
|
||||||
log_reason(reqInfo, "Imagemap args missing y value.",
|
FClose(fp);
|
||||||
reqInfo->filename);
|
goto imagemap_error;
|
||||||
die(reqInfo, SC_BAD_IMAGEMAP, reqInfo->url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* End of parenthesis for coordinates under CERN */
|
||||||
|
if (input[i] == ')') {
|
||||||
|
i++;
|
||||||
|
sawparen = 0;
|
||||||
|
} else if (sawparen) {
|
||||||
|
error_num = IMAP_ERR_CERN_MISSING_RIGHT_PAREN;
|
||||||
|
FClose(fp);
|
||||||
|
goto imagemap_error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (url[0] == '\0' && input[i]) {
|
||||||
|
while (isspace(input[i])) i++;
|
||||||
|
for (j = 0; input[i] && !isspace(input[i]); ++i, ++j)
|
||||||
|
url[j] = input[i];
|
||||||
|
url[j] = '\0';
|
||||||
}
|
}
|
||||||
pointarray[k][X] = -1;
|
pointarray[k][X] = -1;
|
||||||
if(!strcmp(type,"poly"))
|
if(!strncmp(type, "poly", 4))
|
||||||
if(pointinpoly(testpoint,pointarray))
|
if(pointinpoly(testpoint,pointarray))
|
||||||
sendmesg(reqInfo, url, fp);
|
Found = 1;
|
||||||
if(!strcmp(type,"circle"))
|
if(!strncmp(type, "circ", 4))
|
||||||
if(pointincircle(testpoint,pointarray))
|
if(pointincircle(testpoint,pointarray))
|
||||||
sendmesg(reqInfo, url, fp);
|
Found = 1;
|
||||||
if(!strcmp(type,"rect"))
|
if(!strncmp(type, "rect", 4))
|
||||||
if(pointinrect(testpoint,pointarray))
|
if(pointinrect(testpoint,pointarray))
|
||||||
sendmesg(reqInfo, url, fp);
|
Found = 1;
|
||||||
if(!strcmp(type,"point")) {
|
if(!strcmp(type,"point")) {
|
||||||
/* Don't need to take square root. */
|
/* Don't need to take square root. */
|
||||||
dist = ((testpoint[X] - pointarray[0][X])
|
dist = ((testpoint[X] - pointarray[0][X])
|
||||||
@ -145,30 +215,70 @@ int send_imagemap(per_request* reqInfo, struct stat* fi, char* path_args,
|
|||||||
sawpoint++;
|
sawpoint++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(def[0])
|
if(Found) {
|
||||||
|
sendmesg(reqInfo, url, fp);
|
||||||
|
goto imagemap_ok;
|
||||||
|
} else {
|
||||||
|
if(def[0]) {
|
||||||
sendmesg(reqInfo, def, fp);
|
sendmesg(reqInfo, def, fp);
|
||||||
|
goto imagemap_ok;
|
||||||
FClose(fp);
|
}
|
||||||
|
}
|
||||||
/* No reason to log each of these as an "error" */
|
/* No reason to log each of these as an "error" */
|
||||||
/* log_reason(reqInfo, "No default defined in imagemap.",
|
/* log_reason(reqInfo, "No default defined in imagemap.",
|
||||||
reqInfo->filename); */
|
reqInfo->filename); */
|
||||||
|
FClose(fp);
|
||||||
|
freeString(input);
|
||||||
|
freeString(def);
|
||||||
|
freeString(szPoint);
|
||||||
|
freeString(url);
|
||||||
|
freeString(type);
|
||||||
die(reqInfo, SC_NO_CONTENT, reqInfo->url);
|
die(reqInfo, SC_NO_CONTENT, reqInfo->url);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
imagemap_ok:
|
||||||
|
FClose(fp);
|
||||||
|
freeString(input);
|
||||||
|
freeString(def);
|
||||||
|
freeString(szPoint);
|
||||||
|
freeString(url);
|
||||||
|
freeString(type);
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
imagemap_error:
|
||||||
|
freeString(input);
|
||||||
|
freeString(def);
|
||||||
|
freeString(szPoint);
|
||||||
|
freeString(url);
|
||||||
|
freeString(type);
|
||||||
|
log_reason(reqInfo,imagemap_errors[error_num-1],reqInfo->filename);
|
||||||
|
die(reqInfo,SC_BAD_IMAGEMAP,imagemap_errors[error_num-1]);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendmesg(per_request* reqInfo, char *url, FILE* fp)
|
void sendmesg(per_request* reqInfo, char *url, FILE *fp)
|
||||||
{
|
{
|
||||||
char loc[HUGE_STRING_LEN];
|
char *loc, *furl;
|
||||||
|
|
||||||
|
loc = newString(HUGE_STRING_LEN,STR_REQ);
|
||||||
|
furl = newString(HUGE_STRING_LEN,STR_REQ);
|
||||||
|
|
||||||
FClose(fp);
|
FClose(fp);
|
||||||
if (!strchr(url, ':')) { /*** If not a full URL ***/
|
if (!strstr(url, "://")) { /*** If not a full URL ***/
|
||||||
if (port == 80) /*** It is a virtual URL ***/
|
if (url[0] != '/') { /*** Relative URL ***/
|
||||||
sprintf(loc, "http://%s", reqInfo->hostInfo->server_hostname);
|
char *last = strrchr(reqInfo->url,'/');
|
||||||
else /* only add port if it's not the default */
|
int x = 0, y = 0;
|
||||||
sprintf(loc, "http://%s:%d",reqInfo->hostInfo->server_hostname,
|
while (((reqInfo->url+x) <= last) && (y < HUGE_STRING_LEN)) {
|
||||||
port);
|
loc[y] = *(reqInfo->url+x);
|
||||||
strcat(loc,url);
|
x++; y++;
|
||||||
die(reqInfo,SC_REDIRECT_TEMP,loc);
|
}
|
||||||
|
loc[y] = '\0';
|
||||||
|
strncat(loc,url,HUGE_STRING_LEN - y);
|
||||||
|
} else {
|
||||||
|
strncpy(loc,url,HUGE_STRING_LEN);
|
||||||
|
}
|
||||||
|
construct_url(furl, reqInfo->hostInfo, loc);
|
||||||
|
die(reqInfo,SC_REDIRECT_TEMP,furl);
|
||||||
} else {
|
} else {
|
||||||
die(reqInfo,SC_REDIRECT_TEMP,url);
|
die(reqInfo,SC_REDIRECT_TEMP,url);
|
||||||
}
|
}
|
||||||
@ -184,11 +294,16 @@ int pointincircle(double point[2], double coords[MAXVERTS][2])
|
|||||||
{
|
{
|
||||||
int radius1, radius2;
|
int radius1, radius2;
|
||||||
|
|
||||||
radius1 = ((coords[0][Y] - coords[1][Y]) * (coords[0][Y] -
|
/* If given a radius instead of a coordinate */
|
||||||
coords[1][Y])) + ((coords[0][X] - coords[1][X]) * (coords[0][X] -
|
if (coords[1][Y] == -127)
|
||||||
coords[1][X]));
|
radius1 = coords[1][X];
|
||||||
|
else
|
||||||
|
radius1 = ((coords[0][Y] - coords[1][Y]) *
|
||||||
|
(coords[0][Y] - coords[1][Y])) +
|
||||||
|
((coords[0][X] - coords[1][X]) *
|
||||||
|
(coords[0][X] - coords[1][X]));
|
||||||
radius2 = ((coords[0][Y] - point[Y]) * (coords[0][Y] - point[Y])) +
|
radius2 = ((coords[0][Y] - point[Y]) * (coords[0][Y] - point[Y])) +
|
||||||
((coords[0][X] - point[X]) * (coords[0][X] - point[X]));
|
((coords[0][X] - point[X]) * (coords[0][X] - point[X]));
|
||||||
return (radius2 <= radius1);
|
return (radius2 <= radius1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,9 +373,4 @@ int pointinpoly(double point[2], double pgon[MAXVERTS][2])
|
|||||||
return (inside_flag);
|
return (inside_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
int isname(char c)
|
|
||||||
{
|
|
||||||
return (!isspace(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* IMAGEMAP_SUPPORT */
|
#endif /* IMAGEMAP_SUPPORT */
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* imagemap.h,v 1.3 1995/10/06 19:15:56 blong Exp
|
* imagemap.h,v 1.6 1996/04/05 18:55:18 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
@ -22,11 +22,13 @@
|
|||||||
#ifndef _IMAGEMAP_H
|
#ifndef _IMAGEMAP_H
|
||||||
#define _IMAGEMAP_H 1
|
#define _IMAGEMAP_H 1
|
||||||
|
|
||||||
#define MAXLINE 500
|
|
||||||
#define MAXVERTS 100
|
#define MAXVERTS 100
|
||||||
#define X 0
|
#define X 0
|
||||||
#define Y 1
|
#define Y 1
|
||||||
|
|
||||||
|
#define IMAP_NCSA 1
|
||||||
|
#define IMAP_CERN 2
|
||||||
|
|
||||||
void sendmesg(per_request* reqInfo, char *url, FILE* fp);
|
void sendmesg(per_request* reqInfo, char *url, FILE* fp);
|
||||||
int pointinpoly(double point[2], double pgon[MAXVERTS][2]);
|
int pointinpoly(double point[2], double pgon[MAXVERTS][2]);
|
||||||
int pointincircle(double point[2], double coords[MAXVERTS][2]);
|
int pointincircle(double point[2], double coords[MAXVERTS][2]);
|
||||||
@ -34,7 +36,6 @@ int pointinrect(double point[2], double coords[MAXVERTS][2]);
|
|||||||
|
|
||||||
int isname(char);
|
int isname(char);
|
||||||
|
|
||||||
int send_imagemap(per_request* reqInfo, struct stat* fi, char* path_args,
|
int send_imagemap(per_request* reqInfo, struct stat* fi, char allow_options);
|
||||||
char allow_options);
|
|
||||||
|
|
||||||
#endif /* _IMAGE_MAP_H */
|
#endif /* _IMAGE_MAP_H */
|
||||||
|
129
src/md5.c
129
src/md5.c
@ -1,13 +1,46 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* NCSA HTTPd Server
|
||||||
|
* Software Development Group
|
||||||
|
* National Center for Supercomputing Applications
|
||||||
|
* University of Illinois at Urbana-Champaign
|
||||||
|
* 605 E. Springfield, Champaign, IL 61820
|
||||||
|
* httpd@ncsa.uiuc.edu
|
||||||
|
*
|
||||||
|
* Copyright (C) 1995, Board of Trustees of the University of Illinois
|
||||||
|
*
|
||||||
|
************************************************************************
|
||||||
|
*
|
||||||
|
* md5.c,v 1.6 1996/03/06 23:21:21 blong Exp
|
||||||
|
*
|
||||||
|
************************************************************************
|
||||||
|
*
|
||||||
|
* md5.c: NCSA HTTPd code which uses the md5c.c RSA Code
|
||||||
|
*
|
||||||
|
* Original Code Copyright (C) 1994, Jeff Hostetler, Spyglass, Inc.
|
||||||
|
* Portions of Content-MD5 code Copyright (C) 1993, 1994 by Carnegie Mellon
|
||||||
|
* University (see Copyright below).
|
||||||
|
* Portions of Content-MD5 code Copyright (C) 1991 Bell Communications
|
||||||
|
* Research, Inc. (Bellcore) (see Copyright below).
|
||||||
|
* Portions extracted from mpack, John G. Myers - jgm+@cmu.edu
|
||||||
|
* Content-MD5 Code contributed by Martin Hamilton (martin@net.lut.ac.uk)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* md5.c --Module Interface to MD5. */
|
/* md5.c --Module Interface to MD5. */
|
||||||
/* Jeff Hostetler, Spyglass, Inc., 1994. */
|
/* Jeff Hostetler, Spyglass, Inc., 1994. */
|
||||||
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "portability.h"
|
#include "portability.h"
|
||||||
|
#include "constants.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "global.h"
|
#ifndef SHTTP
|
||||||
|
#include "global.h"
|
||||||
|
#endif /* SHTTP */
|
||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
|
|
||||||
void md5 (unsigned char *string, char result[33])
|
void md5 (unsigned char *string, char result[33])
|
||||||
@ -31,3 +64,97 @@ void md5 (unsigned char *string, char result[33])
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONTENT_MD5
|
||||||
|
/* these portions extracted from mpack, John G. Myers - jgm+@cmu.edu */
|
||||||
|
|
||||||
|
/* (C) Copyright 1993,1994 by Carnegie Mellon University
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software
|
||||||
|
* and its documentation for any purpose is hereby granted without
|
||||||
|
* fee, provided that the above copyright notice appear in all copies
|
||||||
|
* and that both that copyright notice and this permission notice
|
||||||
|
* appear in supporting documentation, and that the name of Carnegie
|
||||||
|
* Mellon University not be used in advertising or publicity
|
||||||
|
* pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. Carnegie Mellon University makes no
|
||||||
|
* representations about the suitability of this software for any
|
||||||
|
* purpose. It is provided "as is" without express or implied
|
||||||
|
* warranty.
|
||||||
|
*
|
||||||
|
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||||
|
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||||
|
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore)
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this material
|
||||||
|
* for any purpose and without fee is hereby granted, provided
|
||||||
|
* that the above copyright notice and this permission notice
|
||||||
|
* appear in all copies, and that the name of Bellcore not be
|
||||||
|
* used in advertising or publicity pertaining to this
|
||||||
|
* material without the specific, prior written permission
|
||||||
|
* of an authorized representative of Bellcore. BELLCORE
|
||||||
|
* MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY
|
||||||
|
* OF THIS MATERIAL FOR ANY PURPOSE. IT IS PROVIDED "AS IS",
|
||||||
|
* WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static char basis_64[] =
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
|
char *md5contextTo64(context)
|
||||||
|
MD5_CTX *context;
|
||||||
|
{
|
||||||
|
unsigned char digest[18];
|
||||||
|
char *encodedDigest;
|
||||||
|
int i;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
encodedDigest = (char *)malloc(25 * sizeof(char));
|
||||||
|
|
||||||
|
MD5Final(digest, context);
|
||||||
|
digest[sizeof(digest)-1] = digest[sizeof(digest)-2] = 0;
|
||||||
|
|
||||||
|
p = encodedDigest;
|
||||||
|
for (i=0; i < sizeof(digest); i+=3) {
|
||||||
|
*p++ = basis_64[digest[i]>>2];
|
||||||
|
*p++ = basis_64[((digest[i] & 0x3)<<4) | ((digest[i+1] & 0xF0)>>4)];
|
||||||
|
*p++ = basis_64[((digest[i+1] & 0xF)<<2) | ((digest[i+2] & 0xC0)>>6)];+ *p++ = basis_64[digest[i+2] & 0x3F];
|
||||||
|
}
|
||||||
|
*p-- = '\0';
|
||||||
|
*p-- = '=';
|
||||||
|
*p-- = '=';
|
||||||
|
return encodedDigest;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *md5digest(infile)
|
||||||
|
FILE *infile;
|
||||||
|
{
|
||||||
|
MD5_CTX context;
|
||||||
|
char buf[1000];
|
||||||
|
long length = 0;
|
||||||
|
int nbytes;
|
||||||
|
|
||||||
|
MD5Init(&context);
|
||||||
|
while (nbytes = fread(buf, 1, sizeof(buf), infile)) {
|
||||||
|
length += nbytes;
|
||||||
|
MD5Update(&context, buf, nbytes);
|
||||||
|
}
|
||||||
|
rewind(infile);
|
||||||
|
return md5contextTo64(&context);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONTENT_MD5 */
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* portability.h,v 1.29 1995/11/28 09:02:18 blong Exp
|
* portability.h,v 1.32 1996/03/27 20:44:29 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
@ -37,7 +37,6 @@ char *crypt(char *pw, char *salt);
|
|||||||
#define FD_BSD
|
#define FD_BSD
|
||||||
#define MIX_SOCKADDR
|
#define MIX_SOCKADDR
|
||||||
#define bzero(a,b) memset(a,0,b)
|
#define bzero(a,b) memset(a,0,b)
|
||||||
#define getwd(d) getcwd(d,MAX_STRING_LEN)
|
|
||||||
#define JMP_BUF sigjmp_buf
|
#define JMP_BUF sigjmp_buf
|
||||||
#define DIR_FILENO(p) ((p)->dd_fd)
|
#define DIR_FILENO(p) ((p)->dd_fd)
|
||||||
#define NEED_CRYPT_H
|
#define NEED_CRYPT_H
|
||||||
@ -58,7 +57,6 @@ char *crypt(char *pw, char *salt);
|
|||||||
#ifndef _HPUX_SOURCE
|
#ifndef _HPUX_SOURCE
|
||||||
# define _HPUX_SOURCE
|
# define _HPUX_SOURCE
|
||||||
#endif /* _HPUX_SOURCE */
|
#endif /* _HPUX_SOURCE */
|
||||||
#define getwd(d) getcwd(d,MAX_STRING_LEN)
|
|
||||||
#define JMP_BUF sigjmp_buf
|
#define JMP_BUF sigjmp_buf
|
||||||
#define DIR_FILENO(p) ((p)->dd_fd)
|
#define DIR_FILENO(p) ((p)->dd_fd)
|
||||||
|
|
||||||
@ -71,6 +69,7 @@ char *crypt(char *pw, char *salt);
|
|||||||
#define JMP_BUF sigjmp_buf
|
#define JMP_BUF sigjmp_buf
|
||||||
#define DIR_FILENO(p) ((p)->dd_fd)
|
#define DIR_FILENO(p) ((p)->dd_fd)
|
||||||
#define HEAD_CRYPT
|
#define HEAD_CRYPT
|
||||||
|
#define MISSING_HEADERS
|
||||||
|
|
||||||
#elif defined(AIX4)
|
#elif defined(AIX4)
|
||||||
#undef BSD
|
#undef BSD
|
||||||
@ -198,28 +197,33 @@ typedef int pid_t;
|
|||||||
typedef int mode_t;
|
typedef int mode_t;
|
||||||
#define JMP_BUF jmp_buf
|
#define JMP_BUF jmp_buf
|
||||||
#define DIR_FILENO(p) ((p)->dd_fd)
|
#define DIR_FILENO(p) ((p)->dd_fd)
|
||||||
|
/* The following might be required for some versions of NeXTStep on
|
||||||
|
* some platforms.
|
||||||
|
*/
|
||||||
|
/* #include <netinet/in_systm.h> */
|
||||||
|
|
||||||
|
|
||||||
#elif defined(LINUX)
|
#elif defined(LINUX)
|
||||||
/* This release contains a Linux file descriptor hack using the /proc filesystem.
|
#if !defined(FD_LINUX) && !defined(NO_PASS)
|
||||||
This is a largely unsupported feature, and will hopefully be replaced by one
|
#define FD_BSD
|
||||||
of the other file descriptor passing mechanisms when they are supported by
|
#define FD_BSDRENO
|
||||||
the Linux kernel */
|
#endif
|
||||||
/* #define NO_PASS */
|
|
||||||
#define FD_LINUX
|
|
||||||
/* Needed for newer versions of libc (5.2.x) to use FD_LINUX hack */
|
/* Needed for newer versions of libc (5.2.x) to use FD_LINUX hack */
|
||||||
#define DIRENT_ILLEGAL_ACCESS
|
#define DIRENT_ILLEGAL_ACCESS
|
||||||
|
#define DIR_FILENO(p) ((p)->dd_fd)
|
||||||
|
#define CMSG_DATA(cmptr) ((cmptr)->cmsg_data)
|
||||||
|
#define NEED_SYS_UN_H
|
||||||
#undef BSD
|
#undef BSD
|
||||||
#undef NO_KILLPG
|
#undef NO_KILLPG
|
||||||
#undef NO_SETSID
|
#undef NO_SETSID
|
||||||
#undef NEED_STRDUP
|
#undef NEED_STRDUP
|
||||||
#define MIX_SOCKADDR
|
#define MIX_SOCKADDR
|
||||||
/* This are defined, in linux/time.h included from sys/time.h, as of 1.2.8 */
|
/* This are defined, in linux/time.h included from sys/time.h, as of 1.2.8 */
|
||||||
#ifdef 0
|
#ifdef NEVER_DEFINED
|
||||||
# define FD_SET __FD_SET
|
# define FD_SET __FD_SET
|
||||||
# define FD_ZERO __FD_ZERO
|
# define FD_ZERO __FD_ZERO
|
||||||
# define FD_ISSET __FD_ISSET
|
# define FD_ISSET __FD_ISSET
|
||||||
#endif /* 0 */
|
#endif /* NEVER_DEFINED */
|
||||||
#define JMP_BUF sigjmp_buf
|
#define JMP_BUF sigjmp_buf
|
||||||
|
|
||||||
#elif defined(NETBSD) || defined(__NetBSD__)
|
#elif defined(NETBSD) || defined(__NetBSD__)
|
||||||
@ -252,7 +256,15 @@ typedef int mode_t;
|
|||||||
#undef NO_SETSID
|
#undef NO_SETSID
|
||||||
#define NEED_INITGROUPS
|
#define NEED_INITGROUPS
|
||||||
#define CALL_TZSET
|
#define CALL_TZSET
|
||||||
#define getwd(d) getcwd(d,MAX_STRING_LEN)
|
#define JMP_BUF sigjmp_buf
|
||||||
|
#define MIX_SOCKADDR
|
||||||
|
|
||||||
|
#elif defined(SCO5)
|
||||||
|
#undef BSD
|
||||||
|
#define FD_SYSV
|
||||||
|
#undef NO_KILLPG
|
||||||
|
#undef NO_SETSID
|
||||||
|
#define CALL_TZSET
|
||||||
#define JMP_BUF sigjmp_buf
|
#define JMP_BUF sigjmp_buf
|
||||||
#define MIX_SOCKADDR
|
#define MIX_SOCKADDR
|
||||||
|
|
||||||
@ -260,7 +272,6 @@ typedef int mode_t;
|
|||||||
#define BSD
|
#define BSD
|
||||||
#define FD_BSD
|
#define FD_BSD
|
||||||
#define NEED_STRDUP
|
#define NEED_STRDUP
|
||||||
#define getwd(d) getcwd(d,MAX_STRING_LEN)
|
|
||||||
#define NEED_SYS_MALLOC_H
|
#define NEED_SYS_MALLOC_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#define JMP_BUF sigjmp_buf
|
#define JMP_BUF sigjmp_buf
|
||||||
@ -294,7 +305,6 @@ typedef int mode_t;
|
|||||||
#define NEED_STRNCASECMP
|
#define NEED_STRNCASECMP
|
||||||
#define bzero(a,b) memset(a,0,b)
|
#define bzero(a,b) memset(a,0,b)
|
||||||
#define JMP_BUF sigjmp_buf
|
#define JMP_BUF sigjmp_buf
|
||||||
#define getwd(d) getcwd(d,MAX_STRING_LEN)
|
|
||||||
#define S_ISLNK(m) (((m)&(S_IFMT)) == (S_IFLNK))
|
#define S_ISLNK(m) (((m)&(S_IFMT)) == (S_IFLNK))
|
||||||
|
|
||||||
#elif defined(__bsdi__)
|
#elif defined(__bsdi__)
|
||||||
@ -350,7 +360,6 @@ typedef int mode_t;
|
|||||||
#endif
|
#endif
|
||||||
#define lstat stat
|
#define lstat stat
|
||||||
#define strftime(buf,bufsize,fmt,tm) ascftime(buf,fmt,tm)
|
#define strftime(buf,bufsize,fmt,tm) ascftime(buf,fmt,tm)
|
||||||
#define getwd(d) getcwd(d,MAX_STRING_LEN)
|
|
||||||
#define readlink(a,b,c) -1
|
#define readlink(a,b,c) -1
|
||||||
typedef int uid_t;
|
typedef int uid_t;
|
||||||
typedef int gid_t;
|
typedef int gid_t;
|
||||||
@ -412,6 +421,9 @@ extern char *getenv();
|
|||||||
# define DIR_TYPE direct
|
# define DIR_TYPE direct
|
||||||
#endif /* !defined(NeXT) && !defined(CONVEXOS) && !defined(APOLLO) */
|
#endif /* !defined(NeXT) && !defined(CONVEXOS) && !defined(APOLLO) */
|
||||||
|
|
||||||
|
#if !defined(HAVE_STDARG) && !defined(HAVE_VARARGS)
|
||||||
|
# define HAVE_STDARG
|
||||||
|
#endif /* !defined(HAVE_STDARG) && !defined(HAVE_VARARGS) */
|
||||||
|
|
||||||
#ifndef JMP_BUF
|
#ifndef JMP_BUF
|
||||||
# define JMP_BUF sigjmp_buf
|
# define JMP_BUF sigjmp_buf
|
||||||
@ -435,4 +447,34 @@ typedef struct sockaddr CLIENT_SOCK_ADDR;
|
|||||||
typedef struct sockaddr_in CLIENT_SOCK_ADDR;
|
typedef struct sockaddr_in CLIENT_SOCK_ADDR;
|
||||||
#endif /* MIX_SOCKADDR */
|
#endif /* MIX_SOCKADDR */
|
||||||
|
|
||||||
|
#ifdef AIX_BROKEN_HEADERS
|
||||||
|
/* string.h */
|
||||||
|
int strcasecmp(const char *, const char *);
|
||||||
|
int strncasecmp(const char *, const char *, size_t);
|
||||||
|
#include <sys/socket.h>
|
||||||
|
int accept(int, struct sockaddr *, int *);
|
||||||
|
int bind(int, struct sockaddr *, int);
|
||||||
|
int connect(int, struct sockaddr *, int);
|
||||||
|
int getpeername(int, struct sockaddr *, int *);
|
||||||
|
int getsockname(int, struct sockaddr *, int *);
|
||||||
|
int getsockopt(int, int, int, char *, int *);
|
||||||
|
int listen(int, int);
|
||||||
|
int recv(int, char *, int, int);
|
||||||
|
int recvfrom(int, char *, int, int, struct sockaddr *, int *);
|
||||||
|
int send(int, const char *, int, int);
|
||||||
|
int sendto(int, const char *, int, int, struct sockaddr *, int);
|
||||||
|
int setsockopt(int, int, int, const char *, int);
|
||||||
|
int socket(int, int, int);
|
||||||
|
int recvmsg(int, struct msghdr *, int);
|
||||||
|
int sendmsg(int, struct msghdr *, int);
|
||||||
|
int shutdown(int, int);
|
||||||
|
int socketpair(int, int, int, int *);
|
||||||
|
int killpg(int ProcessGroup, int Signal);
|
||||||
|
int initgroups(char* User, int BaseGID);
|
||||||
|
void bzero(char* String, int Length);
|
||||||
|
int gethostname(char* Name, int NameLength);
|
||||||
|
char *crypt(char* PW, char *Salt);
|
||||||
|
#endif /* AIX_BROKEN_HEADERS */
|
||||||
|
|
||||||
|
|
||||||
#endif /* _PORTABILITY_H_ */
|
#endif /* _PORTABILITY_H_ */
|
||||||
|
60
src/rfc822.c
Normal file
60
src/rfc822.c
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*rfc822.c -- utilities to make httpd do rfc822
|
||||||
|
Copyright (C) 1994 Enterprise Integration Technologies Corp
|
||||||
|
30-Aug-94 ekr
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*A wrapper around getline to do rfc822 line unfolding*/
|
||||||
|
int ht_rfc822_getline(char *s,int n,int f,unsigned int timeout)
|
||||||
|
{
|
||||||
|
static char pb=0;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if(pb){
|
||||||
|
if(n--){
|
||||||
|
if(pb=='\n'){
|
||||||
|
*s=pb='\0';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*s++=pb;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(!getline(s,n,f,timeout)){
|
||||||
|
len=strlen(s);
|
||||||
|
s+=len;
|
||||||
|
n-=len;
|
||||||
|
if(n==1) /*If we get here, we've failed to read a full line*/
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
/*Here's where things get heinous. We're gonna read 1 character
|
||||||
|
ahead with read(2)...McCool doesn't leave us any choice*/
|
||||||
|
if(read(f,&pb,1)<=0){
|
||||||
|
pb=0;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pb=='\r'){
|
||||||
|
if(read(f,&pb,1)<=0){
|
||||||
|
pb=0;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pb==' '){ /*This is a folded line*/
|
||||||
|
/*Trim off trailing whitespace*/
|
||||||
|
while(isspace(*--s)){
|
||||||
|
*s='\0';
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
n--;
|
||||||
|
*s++=pb;
|
||||||
|
pb=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
}
|
258
src/util.c
258
src/util.c
@ -10,68 +10,12 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* util.c,v 1.106 1995/11/28 09:02:21 blong Exp
|
* util.c,v 1.115 1996/03/27 20:44:30 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* util.c: string utility things, and other utilities
|
* util.c: string utility things, and other utilities
|
||||||
*
|
*
|
||||||
* 03-23-93 Rob McCool
|
|
||||||
* Original code up to version 1.3 from Rob McCool
|
|
||||||
*
|
|
||||||
* 02-16-95 cvarela
|
|
||||||
* Fixed stack hole in strsubfirst
|
|
||||||
*
|
|
||||||
* 03-06-95 blong
|
|
||||||
* Added inststr from bdflush-1.5 for Linux to set the name of
|
|
||||||
* the running processes
|
|
||||||
*
|
|
||||||
* 03-10-95 blong
|
|
||||||
* Added buffered getline for all but POST requests as suggested by
|
|
||||||
* Robert S. Thau (rst@ai.mit.edu)
|
|
||||||
*
|
|
||||||
* 03-20-95 blong & cvarela
|
|
||||||
* Fixed make_env_str so that it doesn't modify the pointers
|
|
||||||
*
|
|
||||||
* 04-03-95 blong
|
|
||||||
* May have fixed problems (esp. under Solaris 2.3) with playing
|
|
||||||
* with library memory in get_remote_name
|
|
||||||
*
|
|
||||||
* 04-13-95 guillory
|
|
||||||
* added strncpy_dir that limits the length of a directory copy
|
|
||||||
* also added strncpy for same reason
|
|
||||||
*
|
|
||||||
* 04-29-95 blong
|
|
||||||
* added patch by Kevin Steves (stevesk@mayfield.hp.com) for inststr
|
|
||||||
* under HPUX which uses the pstat command
|
|
||||||
*
|
|
||||||
* 06-01-95 blong
|
|
||||||
* added patch by Vince Skahan (vds7789@aw101.iasl.ca.boeing.com)
|
|
||||||
* to fix Apollo DomainOS timezone handling
|
|
||||||
*
|
|
||||||
* 09-02-95 blong
|
|
||||||
* added patch by Gioacchino La Vecchia (gio@di.unipi.it) to make
|
|
||||||
* full host name in get_local_host() to keep from needing to use
|
|
||||||
* the ServerName configuration directive
|
|
||||||
*
|
|
||||||
* 09-11-95 mshapiro
|
|
||||||
* replaced atoi() in uname2id() and gname2id with scan_long() to
|
|
||||||
* convert user_id and group_id from #n to uid_t, gid_t.
|
|
||||||
* If the config file had contained #non-digit then atoi() would
|
|
||||||
* have returned 0 and the server would have been run as root.
|
|
||||||
*
|
|
||||||
* 09-12-95 blong
|
|
||||||
* removed get_local_host() patch, because its the wrong thing to
|
|
||||||
* do. Use the ServerName directive, thats what its there for.
|
|
||||||
*
|
|
||||||
* 11-02-95 mshapiro
|
|
||||||
* recoded no2slash() to perform the following replacecments
|
|
||||||
* sequences of / (//, ///, etc) with a single /
|
|
||||||
* all occurenences of /./ with a single /
|
|
||||||
* remove ./ at the beginning of the name
|
|
||||||
* replace /. at the end of the name with a single /
|
|
||||||
*
|
|
||||||
* added a call to no2slash() at the beginning of getparents()
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -111,6 +55,7 @@
|
|||||||
# include <sys/time.h>
|
# include <sys/time.h>
|
||||||
#endif
|
#endif
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
|
#include "allocate.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "http_request.h"
|
#include "http_request.h"
|
||||||
#include "http_config.h"
|
#include "http_config.h"
|
||||||
@ -486,7 +431,7 @@ void no2slash(char *name)
|
|||||||
while (s[0] == '/' && s[1] == '/')
|
while (s[0] == '/' && s[1] == '/')
|
||||||
{
|
{
|
||||||
p = s;
|
p = s;
|
||||||
while (p[0] = p[1])
|
while ((p[0] = p[1]))
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,7 +441,7 @@ void no2slash(char *name)
|
|||||||
while (s[0] =='/' && s[1] == '.' && s[2] == '/')
|
while (s[0] =='/' && s[1] == '.' && s[2] == '/')
|
||||||
{
|
{
|
||||||
p = s;
|
p = s;
|
||||||
while (p[0] = p[2])
|
while ((p[0] = p[2]))
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -504,7 +449,7 @@ void no2slash(char *name)
|
|||||||
if (name[0] == '.' && name[1] == '/')
|
if (name[0] == '.' && name[1] == '/')
|
||||||
{
|
{
|
||||||
p = name;
|
p = name;
|
||||||
while (p[0] = p[2])
|
while ((p[0] = p[2]))
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -523,8 +468,10 @@ void make_dirstr(char *s, int n, char *d) {
|
|||||||
for(x=0,f=0;s[x];x++) {
|
for(x=0,f=0;s[x];x++) {
|
||||||
if((d[x] = s[x]) == '/')
|
if((d[x] = s[x]) == '/')
|
||||||
if((++f) == n) {
|
if((++f) == n) {
|
||||||
d[x] = '\0';
|
if(x == 0)
|
||||||
return;
|
x++;
|
||||||
|
d[x] = '\0';
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d[x] = '\0';
|
d[x] = '\0';
|
||||||
@ -602,7 +549,8 @@ void getline_timed_out(int sig)
|
|||||||
{
|
{
|
||||||
char errstr[MAX_STRING_LEN];
|
char errstr[MAX_STRING_LEN];
|
||||||
|
|
||||||
sprintf(errstr,"timed out waiting for %s", gCurrentRequest->remote_name);
|
sprintf(errstr,"timed out waiting for %s",
|
||||||
|
gCurrentRequest->remote_name ? gCurrentRequest->remote_name : "-");
|
||||||
log_error(errstr,gCurrentRequest->hostInfo->error_log);
|
log_error(errstr,gCurrentRequest->hostInfo->error_log);
|
||||||
if (!standalone) {
|
if (!standalone) {
|
||||||
fclose(stdin);
|
fclose(stdin);
|
||||||
@ -617,60 +565,115 @@ void getline_timed_out(int sig)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int getline(int sd, char *s, int n, int reset, unsigned int timeout)
|
sock_buf *new_sock_buf(per_request *reqInfo, int sd)
|
||||||
|
{
|
||||||
|
sock_buf *tmp;
|
||||||
|
if (!(tmp = (sock_buf *)malloc(sizeof(sock_buf)))) {
|
||||||
|
die(reqInfo,SC_NO_MEMORY,"new_sock_buf");
|
||||||
|
}
|
||||||
|
tmp->status = SB_NEW;
|
||||||
|
tmp->sd = sd;
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Modified by Trung Dung (tdung@OpenMarket.com) to handle RFC822
|
||||||
|
* line wraps
|
||||||
|
* This routine is currently not thread safe.
|
||||||
|
* This routine may be thread safe. (blong 3/13/96)
|
||||||
|
*/
|
||||||
|
int getline(sock_buf *sb, char *s, int n, int options, unsigned int timeout)
|
||||||
{
|
{
|
||||||
char *endp = s + n - 1;
|
char *endp = s + n - 1;
|
||||||
int have_alarmed = 0;
|
int have_alarmed = 0;
|
||||||
static int buf_posn, buf_good;
|
/* static int buf_posn, buf_good; */
|
||||||
int buf_start;
|
int buf_start;
|
||||||
static char buffer[HUGE_STRING_LEN];
|
/* static char buffer[HUGE_STRING_LEN]; */
|
||||||
int c;
|
int c;
|
||||||
int ret;
|
int ret;
|
||||||
|
int size;
|
||||||
|
|
||||||
buf_start = buf_posn;
|
buf_start = sb->buf_posn;
|
||||||
if (reset == 1) {
|
if ((options & G_RESET_BUF) || (sb->status == SB_NEW)) {
|
||||||
buf_start = buf_posn = buf_good = 0;
|
buf_start = sb->buf_posn = sb->buf_good = 0;
|
||||||
buffer[0] = '\0';
|
sb->buffer[0] = '\0';
|
||||||
}
|
}
|
||||||
else if (reset == 2) {
|
else if (options & G_FLUSH) {
|
||||||
while (buf_posn < buf_good)
|
while (sb->buf_posn < sb->buf_good)
|
||||||
*s++ = buffer[buf_posn++];
|
*s++ = sb->buffer[(sb->buf_posn)++];
|
||||||
*s = '\0';
|
*s = '\0';
|
||||||
return buf_posn - buf_start;
|
sb->status = SB_FLUSHED;
|
||||||
|
return sb->buf_posn - buf_start;
|
||||||
|
}
|
||||||
|
if (options & G_SINGLE_CHAR) {
|
||||||
|
size = 1;
|
||||||
|
} else {
|
||||||
|
size = HUGE_STRING_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (buf_posn == buf_good) {
|
if (sb->buf_posn == sb->buf_good) {
|
||||||
have_alarmed = 1;
|
have_alarmed = 1;
|
||||||
signal(SIGALRM,getline_timed_out);
|
signal(SIGALRM,getline_timed_out);
|
||||||
alarm(timeout);
|
alarm(timeout);
|
||||||
|
|
||||||
if ((ret=read(sd, buffer, HUGE_STRING_LEN)) <= 0) {
|
ret=read(sb->sd, sb->buffer, size);
|
||||||
|
|
||||||
|
if (ret <= 0) {
|
||||||
if (ret == -1 && errno == EINTR)
|
if (ret == -1 && errno == EINTR)
|
||||||
continue; /* Solaris... */
|
continue; /* Solaris... */
|
||||||
else {
|
else {
|
||||||
|
sb->status = SB_ERROR;
|
||||||
if (have_alarmed) { alarm(0); signal(SIGALRM,SIG_IGN); }
|
if (have_alarmed) { alarm(0); signal(SIGALRM,SIG_IGN); }
|
||||||
/* just always return -1, instead of 0 */
|
/* just always return -1, instead of 0 */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sb->status = SB_READ;
|
||||||
|
|
||||||
|
sb->buf_good = ret;
|
||||||
|
buf_start -= sb->buf_posn;
|
||||||
|
sb->buf_posn = 0;
|
||||||
|
|
||||||
|
/* ADC hack below ZZZ */
|
||||||
|
/*
|
||||||
|
if (ret >0) {
|
||||||
|
for (c = 0; c < ret; c++)
|
||||||
|
fputc(sb->buffer[c],stderr);
|
||||||
|
c = 0;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
buf_good = ret;
|
|
||||||
buf_start -= buf_posn;
|
|
||||||
buf_posn = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c = buffer[buf_posn++];
|
c = sb->buffer[(sb->buf_posn)++];
|
||||||
|
if ((c == '\r') && (sb->buf_posn + 1 < sb->buf_good) &&
|
||||||
if (c == LF) break;
|
(sb->buffer[sb->buf_posn] == '\n') &&
|
||||||
if (c != CR) *s++ = c;
|
((sb->buffer[sb->buf_posn + 1] == ' ') ||
|
||||||
|
(sb->buffer[sb->buf_posn + 1] == '\t')))
|
||||||
|
{
|
||||||
|
*s++ = c;
|
||||||
|
*s++ = '\n';
|
||||||
|
*s++ = sb->buffer[sb->buf_posn + 1];
|
||||||
|
sb->buf_posn += 2;
|
||||||
|
}
|
||||||
|
else if ((c == '\n') && (sb->buf_posn < sb->buf_good) &&
|
||||||
|
((sb->buffer[sb->buf_posn] == ' ') ||
|
||||||
|
(sb->buffer[sb->buf_posn] == '\t')))
|
||||||
|
{
|
||||||
|
*s++ = '\n';
|
||||||
|
*s++ = sb->buffer[sb->buf_posn];
|
||||||
|
sb->buf_posn += 1;
|
||||||
|
}
|
||||||
|
else if (c == LF) break;
|
||||||
|
else if (c != CR) *s++ = c;
|
||||||
} while (s < endp);
|
} while (s < endp);
|
||||||
|
|
||||||
if (have_alarmed) { alarm(0); signal(SIGALRM,SIG_IGN); }
|
if (have_alarmed) { alarm(0); signal(SIGALRM,SIG_IGN); }
|
||||||
|
|
||||||
*s = '\0';
|
*s = '\0';
|
||||||
|
|
||||||
return buf_posn - buf_start;
|
return sb->buf_posn - buf_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
void splitURL(char *line, char *url, char *args) {
|
void splitURL(char *line, char *url, char *args) {
|
||||||
@ -760,7 +763,7 @@ void escape_shell_cmd(char *cmd) {
|
|||||||
|
|
||||||
l=strlen(cmd);
|
l=strlen(cmd);
|
||||||
for(x=0;cmd[x];x++) {
|
for(x=0;cmd[x];x++) {
|
||||||
if(ind("&;`'\"|*?~<>^()[]{}$\\",cmd[x]) != -1){
|
if(ind("&;`'\"|*?~<>^()[]{}$\\\x0A",cmd[x]) != -1){
|
||||||
for(y=l+1;y>x;y--)
|
for(y=l+1;y>x;y--)
|
||||||
cmd[y] = cmd[y-1];
|
cmd[y] = cmd[y-1];
|
||||||
l++; /* length has been increased */
|
l++; /* length has been increased */
|
||||||
@ -1039,14 +1042,14 @@ uid_t uname2id(char *name) {
|
|||||||
{
|
{
|
||||||
if (!scan_long (&name[1], &id))
|
if (!scan_long (&name[1], &id))
|
||||||
{
|
{
|
||||||
fprintf(stderr,"httpd: bad user id %s\n",name);
|
fprintf(stderr,"HTTPd: bad user id %s\n",name);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
return (uid_t) id ;
|
return (uid_t) id ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(ent = getpwnam(name))) {
|
if(!(ent = getpwnam(name))) {
|
||||||
fprintf(stderr,"httpd: bad user name %s\n",name);
|
fprintf(stderr,"HTTPd: bad user name %s\n",name);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
return(ent->pw_uid);
|
return(ent->pw_uid);
|
||||||
@ -1060,14 +1063,14 @@ gid_t gname2id(char *name) {
|
|||||||
{
|
{
|
||||||
if (!scan_long (&name[1], &id))
|
if (!scan_long (&name[1], &id))
|
||||||
{
|
{
|
||||||
fprintf(stderr,"httpd: bad group id %s\n",name);
|
fprintf(stderr,"HTTPd: group id %s\n",name);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
return (gid_t) id ;
|
return (gid_t) id ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(ent = getgrnam(name))) {
|
if(!(ent = getgrnam(name))) {
|
||||||
fprintf(stderr,"httpd: bad group name %s\n",name);
|
fprintf(stderr,"HTTPd: bad group name %s\n",name);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
return(ent->gr_gid);
|
return(ent->gr_gid);
|
||||||
@ -1102,8 +1105,6 @@ int get_remote_host_min(per_request *reqInfo) {
|
|||||||
struct in_addr *iaddr;
|
struct in_addr *iaddr;
|
||||||
struct hostent *hptr;
|
struct hostent *hptr;
|
||||||
|
|
||||||
reqInfo->ownDNS = TRUE;
|
|
||||||
|
|
||||||
len = sizeof(struct sockaddr);
|
len = sizeof(struct sockaddr);
|
||||||
|
|
||||||
if ((getpeername(reqInfo->connection_socket, &addr, &len)) < 0) {
|
if ((getpeername(reqInfo->connection_socket, &addr, &len)) < 0) {
|
||||||
@ -1113,14 +1114,20 @@ int get_remote_host_min(per_request *reqInfo) {
|
|||||||
iaddr = &(((struct sockaddr_in *)&addr)->sin_addr);
|
iaddr = &(((struct sockaddr_in *)&addr)->sin_addr);
|
||||||
hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr), AF_INET);
|
hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr), AF_INET);
|
||||||
if(hptr) {
|
if(hptr) {
|
||||||
if (reqInfo->remote_host) free(reqInfo->remote_host);
|
if (reqInfo->remote_host) {
|
||||||
reqInfo->remote_host = strdup(hptr->h_name);
|
freeString(reqInfo->remote_host);
|
||||||
|
}
|
||||||
|
reqInfo->remote_host = dupStringP(hptr->h_name,STR_REQ);
|
||||||
str_tolower(reqInfo->remote_host);
|
str_tolower(reqInfo->remote_host);
|
||||||
if (reqInfo->remote_name) free(reqInfo->remote_name);
|
if (reqInfo->remote_name) {
|
||||||
reqInfo->remote_name = strdup(reqInfo->remote_host);
|
freeString(reqInfo->remote_name);
|
||||||
|
}
|
||||||
|
reqInfo->remote_name = dupStringP(reqInfo->remote_host,STR_REQ);
|
||||||
} else {
|
} else {
|
||||||
/* shouldn't be necessary, but just in case */
|
/* shouldn't be necessary, but just in case */
|
||||||
if (reqInfo->remote_host) free(reqInfo->remote_host);
|
if (reqInfo->remote_host) {
|
||||||
|
freeString(reqInfo->remote_host);
|
||||||
|
}
|
||||||
reqInfo->remote_host = NULL;
|
reqInfo->remote_host = NULL;
|
||||||
}
|
}
|
||||||
reqInfo->dns_host_lookup = TRUE;
|
reqInfo->dns_host_lookup = TRUE;
|
||||||
@ -1134,15 +1141,13 @@ void get_remote_host(per_request *reqInfo)
|
|||||||
struct in_addr *iaddr;
|
struct in_addr *iaddr;
|
||||||
struct hostent *hptr;
|
struct hostent *hptr;
|
||||||
|
|
||||||
reqInfo->ownDNS = TRUE;
|
|
||||||
|
|
||||||
len = sizeof(struct sockaddr);
|
len = sizeof(struct sockaddr);
|
||||||
|
|
||||||
if ((getpeername(reqInfo->connection_socket, &addr, &len)) < 0) {
|
if ((getpeername(reqInfo->connection_socket, &addr, &len)) < 0) {
|
||||||
reqInfo->remote_name = strdup("UNKNOWN_HOST");
|
reqInfo->remote_name = dupStringP("UNKNOWN_HOST",STR_REQ);
|
||||||
reqInfo->remote_ip = strdup("UNKNOWN_IP");
|
reqInfo->remote_ip = dupStringP("UNKNOWN_IP",STR_REQ);
|
||||||
reqInfo->remote_host = strdup("UNKNOWN_HOST");
|
reqInfo->remote_host = dupStringP("UNKNOWN_HOST",STR_REQ);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
iaddr = &(((struct sockaddr_in *)&addr)->sin_addr);
|
iaddr = &(((struct sockaddr_in *)&addr)->sin_addr);
|
||||||
@ -1151,14 +1156,18 @@ void get_remote_host(per_request *reqInfo)
|
|||||||
{
|
{
|
||||||
hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr), AF_INET);
|
hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr), AF_INET);
|
||||||
if(hptr) {
|
if(hptr) {
|
||||||
reqInfo->remote_host = strdup(hptr->h_name);
|
reqInfo->remote_host = dupStringP(hptr->h_name,STR_REQ);
|
||||||
str_tolower(reqInfo->remote_host);
|
str_tolower(reqInfo->remote_host);
|
||||||
if (reqInfo->remote_name) free(reqInfo->remote_name);
|
if (reqInfo->remote_name) {
|
||||||
reqInfo->remote_name = strdup(reqInfo->remote_host);
|
freeString(reqInfo->remote_name);
|
||||||
|
}
|
||||||
|
reqInfo->remote_name = dupStringP(reqInfo->remote_host,STR_REQ);
|
||||||
} else reqInfo->remote_host = NULL;
|
} else reqInfo->remote_host = NULL;
|
||||||
reqInfo->dns_host_lookup = TRUE;
|
reqInfo->dns_host_lookup = TRUE;
|
||||||
} else
|
} else {
|
||||||
|
if (reqInfo->remote_host != NULL) freeString(reqInfo->remote_host);
|
||||||
reqInfo->remote_host = NULL;
|
reqInfo->remote_host = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (reqInfo->hostInfo->dns_mode == DNS_MAX) {
|
if (reqInfo->hostInfo->dns_mode == DNS_MAX) {
|
||||||
/* Grrr. Check THAT name to make sure it's really the name of the addr. */
|
/* Grrr. Check THAT name to make sure it's really the name of the addr. */
|
||||||
@ -1175,18 +1184,20 @@ void get_remote_host(per_request *reqInfo)
|
|||||||
}
|
}
|
||||||
if((!hptr) || (!(*haddr)))
|
if((!hptr) || (!(*haddr)))
|
||||||
if (reqInfo->remote_host) {
|
if (reqInfo->remote_host) {
|
||||||
free(reqInfo->remote_host);
|
freeString(reqInfo->remote_host);
|
||||||
reqInfo->remote_host = NULL;
|
reqInfo->remote_host = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reqInfo->remote_ip = strdup(inet_ntoa(*iaddr));
|
reqInfo->remote_ip = dupStringP(inet_ntoa(*iaddr),STR_REQ);
|
||||||
if(!reqInfo->remote_host){
|
if(!reqInfo->remote_host){
|
||||||
if (reqInfo->remote_name) free(reqInfo->remote_name);
|
if (reqInfo->remote_name) {
|
||||||
reqInfo->remote_name = strdup(reqInfo->remote_ip);
|
freeString(reqInfo->remote_name);
|
||||||
|
}
|
||||||
|
reqInfo->remote_name = dupStringP(reqInfo->remote_ip,STR_REQ);
|
||||||
}
|
}
|
||||||
if (!reqInfo->remote_name){
|
if (!reqInfo->remote_name){
|
||||||
reqInfo->remote_name = strdup("UNKNOWN_HOST");
|
reqInfo->remote_name = dupStringP("UNKNOWN_HOST",STR_REQ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1228,7 +1239,7 @@ void get_local_host()
|
|||||||
gethostname(str, len);
|
gethostname(str, len);
|
||||||
if((!(p=gethostbyname(str))) ||
|
if((!(p=gethostbyname(str))) ||
|
||||||
(!(gConfiguration->server_hostname = find_fqdn(p)))) {
|
(!(gConfiguration->server_hostname = find_fqdn(p)))) {
|
||||||
fprintf(stderr,"httpd: cannot determine local host name.\n");
|
fprintf(stderr,"HTTPd: cannot determine local host name.\n");
|
||||||
fprintf(stderr,"Use ServerName to set it manually.\n");
|
fprintf(stderr,"Use ServerName to set it manually.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -1251,13 +1262,18 @@ void get_local_addr(per_request *reqInfo) {
|
|||||||
sizeof(struct in_addr));
|
sizeof(struct in_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void construct_url(char *full_url, per_host *host, char *url) {
|
/* Modified: Tue Sep 5 23:18:01 1995
|
||||||
/* Since 80 is default port */
|
* This function now understands the "https" directive and the
|
||||||
if (port == 80) {
|
* default SSL port of 443.
|
||||||
sprintf(full_url,"http://%s%s",host->server_hostname,url);
|
*/
|
||||||
} else {
|
void construct_url(char *full_url, per_host *host, char *url)
|
||||||
sprintf(full_url,"http://%s:%d%s",host->server_hostname,port,url);
|
{
|
||||||
}
|
{
|
||||||
|
if (port == DEFAULT_PORT)
|
||||||
|
sprintf(full_url,"%s://%s%s", "http",host->server_hostname,url);
|
||||||
|
else
|
||||||
|
sprintf(full_url,"%s://%s:%d%s", "http",host->server_hostname,port,url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* aaaack but it's fast and const should make it shared text page. */
|
/* aaaack but it's fast and const should make it shared text page. */
|
||||||
|
11
src/util.h
11
src/util.h
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
* util.h,v 1.14 1995/11/28 09:02:22 blong Exp
|
* util.h,v 1.18 1996/03/27 20:44:32 blong Exp
|
||||||
*
|
*
|
||||||
************************************************************************
|
************************************************************************
|
||||||
*
|
*
|
||||||
@ -24,6 +24,12 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
/* getline options */
|
||||||
|
#define G_RESET_BUF 1
|
||||||
|
#define G_FLUSH 2
|
||||||
|
#define G_SINGLE_CHAR 4
|
||||||
|
|
||||||
|
|
||||||
/* util function prototypes */
|
/* util function prototypes */
|
||||||
void inststr(char *dst[], int argc, char *src);
|
void inststr(char *dst[], int argc, char *src);
|
||||||
void initproctitle(char *start, int argc, char **argv, char **envp);
|
void initproctitle(char *start, int argc, char **argv, char **envp);
|
||||||
@ -43,7 +49,8 @@ void getparents(char *name);
|
|||||||
void no2slash(char *name);
|
void no2slash(char *name);
|
||||||
uid_t uname2id(char *name);
|
uid_t uname2id(char *name);
|
||||||
gid_t gname2id(char *name);
|
gid_t gname2id(char *name);
|
||||||
int getline(int sd, char *s, int n, int reset, unsigned int timeout);
|
int getline(sock_buf *sb, char *s, int n, int options, unsigned int timeout);
|
||||||
|
sock_buf *new_sock_buf(per_request *reqInfo, int sd);
|
||||||
int eat_ws (FILE* fp);
|
int eat_ws (FILE* fp);
|
||||||
int cfg_getline(char *s, int n, FILE *f);
|
int cfg_getline(char *s, int n, FILE *f);
|
||||||
void getword(char *word, char *line, char stop);
|
void getword(char *word, char *line, char stop);
|
||||||
|
11
support/Makefile
Executable file → Normal file
11
support/Makefile
Executable file → Normal file
@ -27,7 +27,7 @@ INCLUDES = -I../src
|
|||||||
#--------------------------------------------------------------------------
|
#--------------------------------------------------------------------------
|
||||||
|
|
||||||
SUPPORT = htpasswd unescape inc2shtml htdigest dbm2std std2dbm dbmdigest \
|
SUPPORT = htpasswd unescape inc2shtml htdigest dbm2std std2dbm dbmdigest \
|
||||||
dbmgroup dbmpasswd
|
dbmgroup dbmpasswd webgrab
|
||||||
.c.o:
|
.c.o:
|
||||||
$(CC) -c $(CFLAGS) $(INCLUDES) $<
|
$(CC) -c $(CFLAGS) $(INCLUDES) $<
|
||||||
|
|
||||||
@ -60,6 +60,9 @@ next:
|
|||||||
osf1:
|
osf1:
|
||||||
make all CC=cc CFLAGS="-DOSF1"
|
make all CC=cc CFLAGS="-DOSF1"
|
||||||
|
|
||||||
|
sco5:
|
||||||
|
make all CC=cc CFLAGS="-DSCO5" EXTRA_LIBS="-ldbm -lsocket"
|
||||||
|
|
||||||
sgi4:
|
sgi4:
|
||||||
make all CC=cc CFLAGS="-DIRIX -DHEAD_GETPASS"
|
make all CC=cc CFLAGS="-DIRIX -DHEAD_GETPASS"
|
||||||
|
|
||||||
@ -67,14 +70,14 @@ sgi5:
|
|||||||
make all CC=cc CFLAGS="-DIRIX"
|
make all CC=cc CFLAGS="-DIRIX"
|
||||||
|
|
||||||
solaris:
|
solaris:
|
||||||
make all CC=gcc CFLAGS="-DSOLARIS2"
|
make all CC=gcc CFLAGS="-DSOLARIS2" EXTRA_LIBS="-lnsl -lsocket"
|
||||||
|
|
||||||
sunos:
|
sunos:
|
||||||
make all CC=gcc CFLAGS="-DSUNOS"
|
make all CC=gcc CFLAGS="-DSUNOS"
|
||||||
|
|
||||||
svr4:
|
svr4:
|
||||||
make all CC=cc CFLAGS="-I/usr/include -I/usr/ucbinclude -DSVR4" \
|
make all CC=cc CFLAGS="-I/usr/include -I/usr/ucbinclude -DSVR4" \
|
||||||
EXTRA_LIBS="-lc -L/usr/ucblib -ldbm -lucb"
|
EXTRA_LIBS="-lc -L/usr/ucblib -ldbm -lucb -lnsl -lsocket"
|
||||||
|
|
||||||
ultrix:
|
ultrix:
|
||||||
make all CC=gcc CFLAGS="-DULTRIX"
|
make all CC=gcc CFLAGS="-DULTRIX"
|
||||||
@ -114,6 +117,8 @@ unescape: unescape.c
|
|||||||
inc2shtml: inc2shtml.c
|
inc2shtml: inc2shtml.c
|
||||||
$(CC) $(CFLAGS) $(INCLUDES) inc2shtml.c -o inc2shtml
|
$(CC) $(CFLAGS) $(INCLUDES) inc2shtml.c -o inc2shtml
|
||||||
|
|
||||||
|
webgrab: webgrab.c
|
||||||
|
$(CC) $(CFLAGS) $(INCLUDES) webgrab.c -o webgrab $(EXTRA_LIBS)
|
||||||
clean:
|
clean:
|
||||||
rm -f $(SUPPORT) $(DIGESTOBJS) tags TAGS *.o
|
rm -f $(SUPPORT) $(DIGESTOBJS) tags TAGS *.o
|
||||||
|
|
||||||
|
205
support/webgrab.c
Normal file
205
support/webgrab.c
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
/***************************************************************************\
|
||||||
|
* webgrab - v1.0 - Copyright 1995, Brian J. Swetland *
|
||||||
|
* *
|
||||||
|
* Free for any personal or non-comercial use. Use at your own risk. *
|
||||||
|
\***************************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#ifdef __bsdi__
|
||||||
|
# include <sys/malloc.h>
|
||||||
|
#else
|
||||||
|
# ifndef NeXT
|
||||||
|
# include <malloc.h>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define VERSION "1.3"
|
||||||
|
|
||||||
|
/* strdup isn't portable, so we make our own. */
|
||||||
|
char *strd(char *s) {
|
||||||
|
char *d;
|
||||||
|
|
||||||
|
d=(char *)malloc(strlen(s) + 1);
|
||||||
|
strcpy(d,s);
|
||||||
|
return(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parses URL looking like blah://host[:port][/path]
|
||||||
|
will ignore anything before the first : and terminate path when it
|
||||||
|
hits >, ", or whitespace -- returns portno or 0 if bad url */
|
||||||
|
|
||||||
|
int parseURL(char *url, char **host, char **path)
|
||||||
|
{
|
||||||
|
char *p, *pp;
|
||||||
|
int port;
|
||||||
|
|
||||||
|
p = url;
|
||||||
|
|
||||||
|
/* skip anything up to the first : (the one after http, etc) */
|
||||||
|
while(*p && *p!=':') p++;
|
||||||
|
if(!*p)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* REQUIRE two '/'s */
|
||||||
|
if(!(*(++p) && (*p =='/') && *(++p) && (*p == '/')))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
p++;
|
||||||
|
|
||||||
|
/* mark the beginning of the hostname */
|
||||||
|
pp = p;
|
||||||
|
/* hostname is terminated by a '/' or '>','"',or whitespace */
|
||||||
|
while(*p && *p!=':' && *p!='/' && *p!='"' && *p!='>' && !isspace(*p))
|
||||||
|
p++;
|
||||||
|
|
||||||
|
*host = (char *) malloc(p-pp+1);
|
||||||
|
strncpy(*host,pp,p-pp);
|
||||||
|
(*host)[p-pp]=0;
|
||||||
|
|
||||||
|
/* optionally read a portnumber */
|
||||||
|
if(*p==':'){
|
||||||
|
p++;
|
||||||
|
port = 0;
|
||||||
|
while(*p && isdigit(*p)){
|
||||||
|
port = port*10 + (*p-'0');
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
if(!*p || *p!='/') {
|
||||||
|
free(*host);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
port = 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* still more */
|
||||||
|
if(*p && (*p=='/')){
|
||||||
|
pp = p;
|
||||||
|
while(*p && *p!='"' && *p!='>' && !isspace(*p)) p++;
|
||||||
|
*p = 0;
|
||||||
|
*path = strd(pp);
|
||||||
|
} else {
|
||||||
|
*path = strd("/");
|
||||||
|
}
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
void usage(char *argv)
|
||||||
|
{
|
||||||
|
printf("\nWebgrab: The Command Line Browser\tVersion %s \n",VERSION);
|
||||||
|
printf("Usage: %s [-shr] <url>\n",argv);
|
||||||
|
printf("\t-s\t: Suppress Headers\n");
|
||||||
|
printf("\t-h\t: Headers Only\n");
|
||||||
|
printf("\t<url>\t: URL to retrieve (in http:// format)\n");
|
||||||
|
printf("\t-r\t: Read HTTP headers from stdin\n\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int s, i, port;
|
||||||
|
struct sockaddr_in sa;
|
||||||
|
struct hostent *hp;
|
||||||
|
FILE *fpo,*fpi;
|
||||||
|
char buf[1024];
|
||||||
|
char *path,*host;
|
||||||
|
int ignore=0,head=0,readin=0;
|
||||||
|
|
||||||
|
if(argc<2 || (argv[1][0]=='-'&&argc<3)){
|
||||||
|
usage(argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(argv[1][0]=='-'){
|
||||||
|
for(path=&argv[1][1];*path;path++)
|
||||||
|
switch(*path){
|
||||||
|
case 'r':
|
||||||
|
readin = 1;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
ignore = 1;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
head = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s = 2;
|
||||||
|
} else {
|
||||||
|
s = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(port=parseURL(argv[s], &host, &path))){
|
||||||
|
fprintf(stderr,"error: invalid url\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find the server */
|
||||||
|
if(!(hp = gethostbyname(host))) {
|
||||||
|
fprintf(stderr,"error: can't get host %s.\n",host);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup the socket */
|
||||||
|
/* bzero((char *)&sa, sizeof(sa)); */
|
||||||
|
memset(&sa, 0, sizeof(sa));
|
||||||
|
sa.sin_port = htons(port);
|
||||||
|
/* bcopy((char *)hp->h_addr, (char *)&sa.sin_addr, hp->h_length); */
|
||||||
|
memcpy((char *)&sa.sin_addr, (char *)hp->h_addr, hp->h_length);
|
||||||
|
sa.sin_family = hp->h_addrtype;
|
||||||
|
|
||||||
|
/* allocate the socket */
|
||||||
|
if((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0){
|
||||||
|
fprintf(stderr,"error: can't get socket\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* connect to the server */
|
||||||
|
if(connect(s, &sa, sizeof(sa)) < 0){
|
||||||
|
close(s);
|
||||||
|
fprintf(stderr,"error: can't connect\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fpo = fdopen(s,"w");
|
||||||
|
fpi = fdopen(s,"r");
|
||||||
|
fprintf(fpo,"%s %s HTTP/1.0\r\n",head?"HEAD":"GET",path);
|
||||||
|
if (readin) {
|
||||||
|
/* copy headers from stdin ... */
|
||||||
|
while(!feof(stdin)){
|
||||||
|
i = fread(buf,1,1024,stdin);
|
||||||
|
if(i) fwrite(buf,1,i,fpo);
|
||||||
|
if(feof(stdin)) break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* send our normal header info */
|
||||||
|
fputs("User-Agent: WebGrab/1.2 (commandline forever)\r\n",fpo);
|
||||||
|
}
|
||||||
|
fputs("\r\n",fpo);
|
||||||
|
fflush(fpo);
|
||||||
|
|
||||||
|
/* IGNORE HEADERS */
|
||||||
|
while(!feof(fpi)){
|
||||||
|
fgets(buf,1024,fpi);
|
||||||
|
if(!ignore) fprintf(stdout,"%s",buf);
|
||||||
|
if(feof(fpi) || buf[0]<' ') break;
|
||||||
|
}
|
||||||
|
while(!feof(fpi)){
|
||||||
|
i = fread(buf,1,1024,fpi);
|
||||||
|
if(i) fwrite(buf,1,i,stdout);
|
||||||
|
if(feof(fpi)) break;
|
||||||
|
}
|
||||||
|
close(s);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user