HTTP HTTPd 1.5.1 - This is apparently the 'export' version, presumably due to US cryptography laws at the time

This commit is contained in:
I am not me 2013-03-13 02:54:58 -04:00
parent 703e80090a
commit e843970069
125 changed files with 17374 additions and 5765 deletions

49
BUGS Normal file
View File

@ -0,0 +1,49 @@
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.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
---------------------
*) 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
---------------------
*) Typo/Thinko in http_access.c which breaks order deny/allow

251
CHANGES Normal file
View File

@ -0,0 +1,251 @@
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
------------------
*) add newline character to list of characters to strip from shell cmds
to prevent security hole
*) in_ip patch is broken, revert to the old way
*) Clean up possible memory leak in status_line code from CGI scripts
*) Fix possible SIGSEGV condition in send_fd_timed_out()
*) Fixed Mutual-Failure
*) If you don't have a require or allow line in the .htaccess LIMIT section,
it wouldn't work (ie, just deny), now fixed
*) change getuid to geteuid in httpd.c so that effectively root people can
start the server and have it change uids
*) Fix group checking
Fixes for 1.5a
-------------------
*) Typo/Thinko for http_access.c which makes order deny/allow not work as
documented
Fixes for 1.5 Final
-------------------
*) Clean up makefiles
*) Fix mixed up rfc931 strings (remote_logname)
*) Fixed multiple string lengths in get_mime_headers() and scan_script_headers()
*) set standalone to 0 after cgi fork so that errors cause exit
*) clean up local redirects
*) clean up send_fd and send_fp code
*) fixed domain restriction bug (last one, I hope)
*) changed code for checking for owner of symbolic links
*) allow SRM config in server conf with <SRMOptions> tag
*) don't leak file pointer on access_syntax_error()
*) Use send_fd for exec cgi and cmd in SSI
*) send back 204 no content as default for imagemaps which have no default
*) clear default array in imagemap first
*) TACHOMETER off by one
*) include config.h and portability.h in support programs
*) recoded no2slash to fix possible security holes
*) set ownDNS to TRUE for DNSmode Minimal
Fixes for 1.5 Beta 7
-------------------
*) typo: strncat for strncpy in DOCUMENT_URI setting for SSI
*) various domain restriction bugs
*) DNSMode support
*) DNSMode Minimum should now do the DNS lookup for authentication if necessary
*) RESOURCE_LIMIT compile time option makes MaxServers the hard limit
for number of servers to run.
*) fix imagemap for full urls
*) fix referer logging in error_log
*) fix SSI file closing
*) fixed LOCAL hack to check if remote_host is NULL
*) setrlimit (NOFILES) to try and raise the number of file descriptors
allowed as high as possible.
*) Added patch by Stuart Lynne (sl@wimsey.com) to make proc title a tachometer
*) Possible fixes for loop errors and spontaneous 403 errors
Fixes for 1.5 Beta 6
--------------------
*) Added SERVER_ADMIN CGI Variable per requests
*) Added LOCAL hack to allow matching in domain restriction of all local
hostnames (Maurizio Codogno (mau@beatles.cselt.stet.it))
*) Added support for HTTP/1.1 Host: header for virtual host support
*) Various includes file and portability fixes
*) Fixed weird special case of domain restriction failure from access.conf
in conjunction with having .htaccess files
*) Fixed new VirtualHost ErrorDocument support so as not to cause SIGSEGV
*) Moved RefererIgnore matching to log_transaction() to allow HTTP/1.1 host
support to work
*) Changed debugging dump (SIGUSR1)
*) Typo in ErrorDocument settings
*) Added Optional and Required parameters to VirtualHost configuration tag
to allow for a single host configuration failure not to bring down all
of them
*) Added patch by Elf Sternberg (elf@aaden.spry.com) to allow configuring of
process titles in SETPROCTITLE
*) Change LogType to LogOptions and added a new option (ServerName) which
will log the servername of the request to the access_log
*) Added CoreDirectory directive to tell HTTPd where to dump core
Fixes for 1.5 Beta 5
--------------------
*) Added support for Combined LogType (CLF with referer and useragent)
*) Added check at launch to attempt to keep people from leaving a security
hole open by leaving the log file directory writeable by the wrong people
*) Added support for internal imagemap support
*) Added support for VirtualHost level ErrorDocuments
*) Added date stamp to UserAgent and RefererLogs to allow for easier correlation
*) Added file descriptor wrappers for directories and DBM files
*) Fix SSI bug where index filename not added to DOCUMENT_URI
*) Don't pass PATH_INFO information to index files unless specifically
refered to (ie, do in case of /index.cgi/wow, but not in /wow)
*) Add "fix" by Sun for better performance under Solaris
*) Change children proctitle to "idle"
*) Removed getdomainname patch, its not portable and not the right thing to do
*) changed atoi() in uname2id() and gname2id() to scan_long. If the atoi
failed, it would return 0, causing the server to run as root
Fixes for 1.5 Beta 4
--------------------
*) Fixed typo in FD_LINUX support
*) Fixed support for NeXT platform
*) order of operations wrong on restart
*) Now pass environment to CGI script from SSI
*) Fix Alias/ScriptAlias/Redirects for VirtualHost
*) Fix if all of POST data read on first pass, don't try to read more
as seen through CERN proxy
*) Work around for systems which don't support numeric IP addresses passed
to gethostbyname()
*) Added log_reason for non-exec CGI
*) Pass reqInfo to init_header_vars() in local redirects from cgi scripts
*) use unbuffered i/o for file writes to fix fwrite bug on AIX 3.2.5 for PowerPC
*) fix write loop for send_script() for CGI scripts
*) use stat inplace of lstat to fix IfSymLinkOwner bug if link to link to file
*) should now recognize and use numeric IP on systems with older versions
of bind which don't support a numeric IP to gethostbyname()
*) Fix SSI, flastmod wasn't working
*) freeing ENV array at the wrong time, esp. in SSI
*) Fix refererignore again
*) Ultrix not brain dead since 4.4, so put #define in old hack for determining
which version of ultrix you are compiling on
*) possible help for get_local_host() on some systems which didn't work before
*) HEAD_GETPASS for ultrix in support directory
Fixes for 1.5 Beta 3
--------------------
*) Fixes to various scripts for cleaner compiles
*) Added KeepAlive directives to example httpd.conf
*) Fixed Makefile support for SVR4, added ConvexOS, QNX, ATTSVR3 from 1.4.2
*) Cleaned up header include directives for portability
*) Added file descriptor wrapper to prevent leaks
*) Cleaned up exec code, so forked child always dies even if exec() fails
in a funny way (should make sure no children of children get left around)
*) file descriptor leak if CGI script returns Location header closed
*) attempt to keep environment and authorization between multiple requests
like for internal redirects and on ErrorDocument
*) Added NIS_SUPPORT patch by Kevin Ruddy
*) Fixed Multiple referer ignore
*) fixed an off by one error in environment handling (env.c). Probable
cause of coredumps on Solaris machines, possibly others.
*) Now allow DocumentRoot in httpd.conf file (for VirtualHosts)
*) Added support for Linux file descriptor passing /proc hack
*) Cleaned up File Not Found error message (per HyperNews suggestion)
*) Allow restart when relative path used with -f on command line
Vince Tkac (tkac@oclc.org)
*) Cleaned up Restart code ( kill -HUP ). Should now work on all systems
regardless of optimization
*) Cleaned up sockaddr usage
*) Moved socket initialiazation to its own function
*) Now log start command to error_log
*) Improved usage function (for -v command line)
*) Made sigjmp_buf default define for JMP_BUF (missed from 1.4.2)
*) Fixed getline()
Fixes for 1.5 Beta 2
--------------------
*) To fix AddType .cgi completely, now has a single virtual path for
any method to a "standard document" and checks just before sending
if the method is valid for the document type.
*) General code reorganization, including renaming of scripts to cgi
and removing all method specific files, and creating an http_send
for the new general case
*) Moved all non-security compile time options to config.h
*) Support for profiling the code added
*) A/UX, SVR4, SCO3 support updated
*) New type of process title changing subroutine added, and made a compile
time option
*) Collapsed number of malloc()'s for performance
*) DBM support now properly #define'd
*) Duh, always initialize url/args/filename
*) fixed multihome support to allow more than 2 entries
*) fixed access control
*) log missing user attempt - Gioacchino La Vecchia (gio@di.unipi.it)
*) explicitly allow or disallow certain server configuration directives
in virtual hosts
*) strip ending / on document root at configuration time
*) stat filesystem for .htaccess files instead of checking failure of fopen()
for speed improvement
*) change order of mime initialization to get actual location of file first
*) missing LF in redirect message from die()
*) actually log the error message if using an error document for 500 errors
*) close more file descriptors on errors
*) make separate content_type variables for type as sent and type of reply
*) allow Connection header to be made into a CGI variable
*) fix signal handling during CGI
*) Only shutdown(sd,0) to disallow receives not sends and receives
This fix was for OSF/1 2.0, but may fix AIX problems of garbling ends
of images
*) attempt to lessen the number of fflush()'s called during a transaction
*) move local variables that might be clobbered by setjmp/longjmp
*) call tzset on all systems
*) log errno on some errors
*) log which URL is being aborted or timing out
*) Keberos fixes
*) Multiple referer ignore added
*) Probably some I've missed
New for 1.5 Beta 1
------------------
*) Multiple Directory Indexes allowed
*) Redirects from .htaccess files
*) RedirectPermanent
*) MD5 Digest Authentication
*) Kerberos v4 Authentication
*) Kerberos v5 Authentication
*) Connection: Keep-Alive extension
*) DBM support for .htpasswd/.htgroup files
*) Enhanced Access Control
*) Multihome/Virtual Interface support

63
COPYRIGHT Normal file
View File

@ -0,0 +1,63 @@
/*COPYRIGHT,v 1.3 1995/07/26 18:59:00 blong Exp*/
The official NCSA HTTPd copyright statement follows.
/****************************************************************************
* 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
*
* NCSA HTTPd software, both binary and source (hereafter, Software) is
* copyrighted by The Board of Trustees of the University of Illinois
* (UI), and ownership remains with the UI.
*
* The UI grants you (hereafter, Licensee) a license to use the Software
* for academic, research and internal business purposes only, without a
* fee. Licensee may distribute the binary and source code (if released)
* to third parties provided that the copyright notice and this statement
* appears on all copies and that no charge is associated with such
* copies.
*
* Licensee may make derivative works. However, if Licensee distributes
* any derivative work based on or derived from the Software, then
* Licensee will (1) notify NCSA regarding its distributing of the
* derivative work, and (2) clearly notify users that such derivative
* work is a modified version and not the original NCSA HTTPd Server software
* distributed by the UI by including a statement such as the following:
*
* "Portions developed at the National Center for Supercomputing
* Applications at the University of Illinois at Urbana-Champaign."
*
* Any Licensee wishing to make commercial use of the Software should
* contact the UI, c/o NCSA, to negotiate an appropriate license for such
* commercial use. Commercial use includes (1) integration of all or
* part of the source code into a product for sale or license by or on
* behalf of Licensee to third parties, or (2) distribution of the binary
* code or source code to third parties that need it to utilize a
* commercial product sold or licensed by or on behalf of Licensee.
*
* Any commercial company wishing to use the software as their commercial
* World Wide Web server and are not redistributing the software need not
* commercially license the software but can use it free of charge.
*
* UI MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR
* ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED
* WARRANTY. THE UI SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY THE
* USERS OF THIS SOFTWARE.
*
* By using or copying this Software, Licensee agrees to abide by the
* copyright law and all other applicable laws of the U.S. including, but
* not limited to, export control laws, and the terms of this license.
* UI shall have the right to terminate this license immediately by
* written notice upon Licensee's breach of, or non-compliance with, any
* of its terms. Licensee may be held legally responsible for any
* copyright infringement that is caused or encouraged by Licensee's
* failure to abide by the terms of this license.
*
* Comments and questions can be sent to httpd@ncsa.uiuc.edu.
****************************************************************************/

136
CREDITS Normal file
View File

@ -0,0 +1,136 @@
We like to give Credit where due. Note that most of these people
provided us help out of their own free will, and desire to get
this working for themselves. Please attempt to get help from
us (httpd@ncsa.uiuc.edu) before you bother any of them with your questions.
Thanks.
NCSA HTTPd Development Team
Even if we don't list you here, we still appreciate anything and
everything you've done for NCSA HTTPd.
We'd like to thank code contributors for HTTPd:
Rob McCool (robm@netscape.com) for versions up to 1.3
Robert S. Thau (rst@ai.mit.edu)
Roy T. Fielding (fielding@avron.ics.uci.edu)
Brian Behlendorf (brian@wired.com)
Harald Hanche-Olsen (hanche@imf.unit.no)
kluft@amdahl.com
David Robinson (drtr@ast.cam.ac.uk)
Wietse Venema
Keith Shafer (Keith.Shafer@SanDiegoCA.ATTGIS.COM)
Kevin Steves (stevesk@mayfield.hp.com)
Gioacchino La Vecchia (gio@di.unipi.it)
Kevin Ruddy (smiles@powerdog.com)
Vince Tkac (tkac@oclc.org)
Elf Sternberg (elf@aaden.spry.com)
Nathan Neulinger (nneul@umr.edu)
Stuart Lynne (sl@wimsey.com)
Martin Hamilton (martin@net.lut.ac.uk)
Tim Hudson (tjh@mincom.oz.au) SSL
And for Porting information/help:
Alex Podlecki (a.podlecki@att.com) SVR4
Sanj Kharbanda (sanj@wordsworth.com) QNX
Jeffrey Ray Thieleke (thieleke@icaen.uiowa.edu) NetBSD for m68k
David Cornejo (dave@dogwood.com) NetBSD
Leo Bicknell (bicknell@ufp.org) FreeBSD
Jim Jagielski (jim@jaguNET.com) A/UX
Steve Abatangle (sabat@velveeta.dts.harris.com) Solaris 2.3
Tom Rudnick (trudnick@ftc.nrcs.usda.gov) AT&T SYSV 3.2
Preston F. Crow (preston.crow@dancer.dartmouth.edu) Ultrix 4.3,4.4
Erik Bertelsen (erik@sockdev.uni-c.dk) Ultrix 4.4
Tom Rataski (tom@winc.com) Ultrix 4.4
Miles O'Neal (meo@pencom.com) NeXT
Eugene Mah (eugene@raddi.uah.ualberta.ca) NeXT 3.2 m68k
Kevin Steves (stevesk@mayfield.hp.com) HPUX
Vincent D. Skahan (vds7789@aw101.iasl.ca.boeing.com) HP/Apollo DomainOS
Achille Hui (eillihca@drizzle.stanford.edu) OSF/1 2.0
Miquel van Smoorenburg (miquels@cistron.nl) Linux
A. P. Harris (apharris@onshore.com) Linux
Stan Johnson (johnson@mission.jsc.nasa.gov) ConvexOS 10.1
I'd love to list all the Beta Testers of HTTPd 1.5, but
there are over 400 of them, so here's a list of extra contributors:
Brian Millet (bpm@techapp.com)
Elf Sternberg (elf@aaden.spry.com)
Morgan Davis (mdavis@cts.com)
Mike Baptiste (baptiste@bnr.ca)
Aris Stathakis (aris@sdd.com)
Stuart Lynne (sl@whiskey.wimsey.com)
Marc Evans (marc@destek.net)
Alex Podlecki (a.podlecki@att.com)
Sonia Heimann (niania@netsurf.org)
Chris Lewicki (chrisl@seds.org)
Miles O'Neal (meo@pencom.com)
Nathan Neulinger (nneul@umr.edu)
Kevin Ruddy (smiles@powerdog.com)
A. P. Harris (apharris@onshore.com)
Nikos Mouat (nikm@ixa.net)
Milton Ngan (Milton@NetLink.co.nz)
Conrad Damon (damon@netserver.stanford.edu)
Peter J. Bertoncini (pjb@anl.gov)
Achille Hui (eillihca@drizzle.stanford.edu)
Gioacchino La Vecchia (gio@di.unipi.it)
We'd like to thank the Beta Testers of HTTPd 1.4:
Jim Jagielski (jim@jaguNET.com)
Jonathan Magid (@calypso-2.oit.unc.edu)
Kevin Kadow (kadokev@ripco.com)
Alex Podlecki (a.podlecki@att.com)
Mike Baptiste (baptiste@bnr.ca)
Rob Hartill (hartill@lanl.gov)
Claude Lecommandeur (Claude.Lecommandeur@epfl.ch)
Rich (legalize@xmission.com)
Ryan Watkins (vamp@best.com)
David J. Bianco (d.j.bianco@larc.nasa.gov)
Sean Harp (sharp@utk.edu)
Stripes (stripes@uu.net)
Andrew Wilson (Andrew.Wilson@cm.cf.ac.uk)
Marc Baudoin (baudoin@ensta.fr
Dave Cornejo (dave@dogwood.com)
Charles Stephens (cfs@emory.edu)
Carlos A. Pero (cpero@ncsa.uiuc.edu)
Jeff Thieleke (thieleke@icaen.uiowa.edu)
Jennifer Myers (jmyers@marigold.eecs.nwu.edu
Miles O'Neal (meo@pencom.com)
Roger Rose (roger@neuromancer.ucr.edu)
Preston Crow (crow@cs.dartmouth.edu)
Tom Rataski (tom@winc.com)
Steve Abatangle (sabat@dts.harris.com)
Stuart Lynne (sl@wimsey.com)
Mike Chang (machang@xmission.com)
Jamie Cash (jrcash@unix.amherst.edu)
Brian Millett (bm1822@vlad.sbc.com)
Robert S. Thau (rst@ai.mit.edu)
R. E. McGrath (mcgrath@ncsa.uiuc.edu)
Gerald Oskoboiny (gerald@amisk.cs.ualberta.ca)
dl (dl@hplyot.obspm.fr)
Jim Fetters (fetters@neuromancer.ucr.edu)
Gary Schrock (root@eyelab.psy.msu.edu)
A. P. Harris (apharris@onShore.com)
Bob Breedlove (bob@sssc.slg.eds.com)
Chuck Musciano (chuck.musciano@melmac.corp.harris.com)
Christopher Lewicki (chrisl@seds.lpl.arizona.edu)
Roger May (rjm@inf.rl.ac.uk)
Steven Grimm (koreth@hyperion.com)
Maurizio Codogno (mau@beatles.cselt.stet.it)
Charles F. Randall (cfrandal@iastate.edu)
Barry Johnson (bjohnson@escape.com)
Aris Stathakis (aris@sdd.com)
Laurent Demailly (dl@hplyot.obspm.fr)
James Sanford (jsanford@shadows.winternet.com)
Victor Parada (vparada@inf.utfsm.cl)
sanj (sanj@wordsworth.com)
David Begley (d.begley@nepean.uws.edu.au)
(skip@automatrix.com)
David-Michael Lincke (dlincke@sgcl1.unisg.ch)
Gioacchino La Vecchia (gio@di.unipi.it)
Pete Ashdown (pashdown@xmission.com)
Mubashir Cheema (cheema@sparco.com)

View File

@ -1,33 +1,50 @@
### NCSA HTTPd 1.5
## Top level Makefile
all: all:
@echo Please choose a system type. @echo Please choose a system type.
@echo Valid types are aix3, aix4, sunos, sgi4, sgi5, decmips, decaxp, @echo Valid types are aix3, aix4, sunos, sgi4, sgi5,
@echo hp-cc, hp-gcc, solaris, netbsd, svr4, linux, aux @echo hp-cc, hp-gcc, solaris, netbsd, svr4, linux,
@echo next, ultrix, osf1, aux, bsdi
@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, cgi-src/Makefile, and support/Makefile @echo src/Makefile, src/portability.h, src/config.h,
@echo cgi-src/Makefile, and support/Makefile
clean: clean:
(cd src ; make clean) (cd src ; make clean)
(cd cgi-src ; make clean) (cd cgi-src ; make clean)
(cd support ; make clean) (cd support ; make clean)
tar-clean: clean
rm -f httpd rm -f httpd
aux:
cd src ; make aux ; cd ../cgi-src ; make aux ; cd ../support ; make aux
aix3: aix3:
cd src ; make aix3 ; cd ../cgi-src ; make aix3 ; cd ../support ; make aix3 cd src ; make aix3 ; cd ../cgi-src ; make aix3 ; cd ../support ; make aix3
aix4: aix4:
cd src ; make aix4 ; cd ../cgi-src ; make aix4 ; cd ../support ; make aix4 cd src ; make aix4 ; cd ../cgi-src ; make aix4 ; cd ../support ; make aix4
sunos: aux:
cd src ; make sunos ; cd ../cgi-src ; make sunos ; cd ../support ; make sunos cd src ; make aux ; cd ../cgi-src ; make aux ; cd ../support ; make aux
solaris: bsdi:
cd src ; make solaris ; cd ../cgi-src ; make solaris ; cd ../support ; make solaris cd src ; make ; cd ../cgi-src ; make ; cd ../support ; make
hp-cc:
cd src ; make hp-cc ; cd ../cgi-src ; make hp-cc ; cd ../support ; make hp-cc
hp-gcc:
cd src ; make hp-gcc ; cd ../cgi-src ; make hp-gcc ; cd ../support ; make hp-gcc
linux:
cd src ; make linux ; cd ../cgi-src ; make linux ; cd ../support ; make linux
netbsd:
cd src ; make netbsd ; cd ../cgi-src ; make netbsd ; cd ../support ; make netbsd
next:
cd src ; make next ; cd ../cgi-src ; make next; cd ../support ; make next
osf1:
cd src ; make osf1; cd ../cgi-src ; make osf1; cd ../support ; make osf1
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
@ -35,23 +52,14 @@ sgi4:
sgi5: sgi5:
cd src ; make sgi; cd ../cgi-src ; make sgi ; cd ../support ; make sgi5 cd src ; make sgi; cd ../cgi-src ; make sgi ; cd ../support ; make sgi5
decmips: solaris:
cd src ; make decmips ; cd ../cgi-src ; make decmips ; cd ../support ; make decmips cd src ; make solaris ; cd ../cgi-src ; make solaris ; cd ../support ; make solaris
decaxp: sunos:
cd src ; make decaxp ; cd ../cgi-src ; make decaxp ; cd ../support ; make decaxp cd src ; make sunos ; cd ../cgi-src ; make sunos ; cd ../support ; make sunos
hp-gcc:
cd src ; make hp-gcc ; cd ../cgi-src ; make hp-gcc ; cd ../support ; make hp-gcc
hp-cc:
cd src ; make hp-cc ; cd ../cgi-src ; make hp-cc ; cd ../support ; make hp-cc
netbsd:
cd src ; make netbsd ; cd ../cgi-src ; make netbsd ; cd ../support ; make netbsd
linux:
cd src ; make linux ; cd ../cgi-src ; make linux ; cd ../support ; make linux
svr4: svr4:
cd src ; make svr4 ; cd ../cgi-src ; make svr4 ; cd ../support ; make svr4 cd src ; make svr4 ; cd ../cgi-src ; make svr4 ; cd ../support ; make svr4
ultrix:
cd src ; make ultrix; cd ../cgi-src ; make ultrix; cd ../support ; make ultrix

158
README
View File

@ -1,22 +1,27 @@
NCSA HTTPd Server 1.5.1 Beta
Documentation for httpd has been moved online. See the URL Copyright (c) 1995 Board of Trustees, University of Illinois
<A HREF="http://hoohoo.ncsa.uiuc.edu/">here</A> for online hypertext
documentation including installation instructions, feature list,
demonstration, etc.
Documentation can also be found where you found this .tar file, in a file The NCSA HTTPd Development Team
called httpd_docs.tar.Z. Software Development Group
National Center for Supercomputing Applications
University of Illinois at Urbana/Champaign
httpd@ncsa.uiuc.edu
The NCSA httpd Development Team httpd@ncsa.uiuc.edu All documentation for NCSA HTTPd can be found on-line at
http://hoohoo.ncsa.uiuc.edu/docs/
In addition, various files in this distribution are commented in order
to make porting and configuration easier. If these files do not
contain enough information, please consult the online documentation.
You should have received a COPYRIGHT file with this distribution.
If you didn't, one is available at
http://hoohoo.ncsa.uiuc.edu/docs-1.5/Copyright.html
Please note that the COPYRIGHT status of NCSA HTTPd 1.5 is different
from previous versions.
This code is in the public domain. Specifically, we give to the public We ask that the following message be included in all derived works:
domain all rights for future licensing of the source code, all resale
rights, and all publishing rights.
We ask, but do not require, that the following message be included in
all derived works:
Portions developed at the National Center for Supercomputing Portions developed at the National Center for Supercomputing
Applications at the University of Illinois at Urbana-Champaign. Applications at the University of Illinois at Urbana-Champaign.
@ -26,84 +31,57 @@ FOR THE SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT
LIMITATION, WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A LIMITATION, WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A
PARTICULAR PURPOSE. PARTICULAR PURPOSE.
We'd like to thank code contributors for HTTPd: Parts of the code developed by the Apache HTTPd Group.
Rob McCool (robm@netscape.com) for versions up to 1.3 As requested by the Apache Group:
Robert S. Thau (rst@ai.mit.edu)
Roy T. Fielding (fielding@avron.ics.uci.edu)
Brian Behlendorf (brian@wired.com)
Harald Hanche-Olsen (hanche@imf.unit.no)
kluft@amdahl.com
David Robinson (drtr@ast.cam.ac.uk)
Wietse Venema
Keith Shafer (Keith.Shafer@SanDiegoCA.ATTGIS.COM)
Kevin Steves (stevesk@mayfield.hp.com)
And for Porting information/help: "Portions developed by the "Apache Group", taken with permission
Sanj Kharbanda (sanj@wordsworth.com) QNX from the Apache Server http://www.apache.org/apache/ "
Jeffrey Ray Thieleke (thieleke@icaen.uiowa.edu) NetBSD for m68k
Jim Jagielski (jim@jaguNET.com) A/UX
Morgan Davis (mdavis@cts.com) SCO SVR e.2
Steve Abatangle (sabat@velveeta.dts.harris.com) Solaris 2.3
Tom Rudnick (trudnick@ftc.nrcs.usda.gov) AT&T SYSV 3.2
Preston F. Crow (preston.crow@dancer.dartmouth.edu) Ultrix 4.3,4.4
Miles O'Neal (meo@pencom.com) NeXT
Kevin Steves (stevesk@mayfield.hp.com) HPUX
Vincent D. Skahan (vds7789@aw101.iasl.ca.boeing.com) HP/Apollo DomainOS
Distribution Contents
--------------------------------
You should have received the following with this distribution:
We'd like to thank the Beta Testers of HTTPd 1.4: BUGS A list of known bugs with the server. This will probably
be empty
CHANGES A list of changes between versions
COPYRIGHT The copyright which applies to this distribution
CREDITS A thank you list to all who have made NCSA HTTPd what it is
today
README this file
Makefile top level makefile
cgi-bin/ directory containing example scripts and binaries of the CGI
cgi-src/ directory containing source code example for CGI
conf/ directory conatining example configuration files
icons/ directory containing free icons and images, some used in the
example configuration
src/ directory containing source code for the server
support/ directory containing various related support programs
Files of note;
src/config.h Compile time configuration file
src/portability.h Compile time portability information
cgi-bin/mail Webmonitor mail script
cgi-bin/nph-error.pl Example ErrorDocument script
cgi-src/imagemap.c External imagemap C code
support/dbm2std Program to convert dbm auth files to std (text)
support/dbmdigest Program to make MD5 password files that use dbm
support/dbmgroup Program to make group files that use dbm
support/dbmpasswd Program to make password files that use dbm
support/htdigest Program to make MD5 password files (std/text)
support/htpasswd Program to make password files (std/text)
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
---------------------------
1.5.1a
| | ||
| | | - Portability and typos. ie, not anything special, but just to keep
| | | us honest
| | -- Bug fixes, minor features (as requested or provided) Also security
| | fixes.
| ---- Major revisions. Probably not going to be another until 2.0
------ Really major revisions, code overhauls, goal changes, language
changes
Jim Jagielski (jim@jaguNET.com)
Jonathan Magid (@calypso-2.oit.unc.edu)
Kevin Kadow (kadokev@ripco.com)
Alex Podlecki (a.podlecki@att.com)
Mike Baptiste (baptiste@bnr.ca)
Rob Hartill (hartill@lanl.gov)
Claude Lecommandeur (Claude.Lecommandeur@epfl.ch)
Rich (legalize@xmission.com)
Ryan Watkins (vamp@best.com)
David J. Bianco (d.j.bianco@larc.nasa.gov)
Sean Harp (sharp@utk.edu)
Stripes (stripes@uu.net)
Andrew Wilson (Andrew.Wilson@cm.cf.ac.uk)
Marc Baudoin (baudoin@ensta.fr
Dave Cornejo (dave@dogwood.com)
Charles Stephens (cfs@emory.edu)
Carlos A. Pero (cpero@ncsa.uiuc.edu)
Jeff Thieleke (thieleke@icaen.uiowa.edu)
Jennifer Myers (jmyers@marigold.eecs.nwu.edu
Miles O'Neal (meo@pencom.com)
Roger Rose (roger@neuromancer.ucr.edu)
Preston Crow (crow@cs.dartmouth.edu)
Tom Rataski (tom@winc.com)
Steve Abatangle (sabat@dts.harris.com)
Stuart Lynne (sl@wimsey.com)
Mike Chang (machang@xmission.com)
Jamie Cash (jrcash@unix.amherst.edu)
Brian Millett (bm1822@vlad.sbc.com)
Robert S. Thau (rst@ai.mit.edu)
R. E. McGrath (mcgrath@ncsa.uiuc.edu)
Gerald Oskoboiny (gerald@amisk.cs.ualberta.ca)
dl (dl@hplyot.obspm.fr)
Jim Fetters (fetters@neuromancer.ucr.edu)
Gary Schrock (root@eyelab.psy.msu.edu)
A. P. Harris (apharris@onShore.com)
Bob Breedlove (bob@sssc.slg.eds.com)
Chuck Musciano (chuck.musciano@melmac.corp.harris.com)
Christopher Lewicki (chrisl@seds.lpl.arizona.edu)
Roger May (rjm@inf.rl.ac.uk)
Steven Grimm (koreth@hyperion.com)
Maurizio Codogno (mau@beatles.cselt.stet.it)
Charles F. Randall (cfrandal@iastate.edu)
Barry Johnson (bjohnson@escape.com)
Aris Stathakis (aris@sdd.com)
Laurent Demailly (dl@hplyot.obspm.fr)
James Sanford (jsanford@shadows.winternet.com)
Victor Parada (vparada@inf.utfsm.cl)
sanj (sanj@wordsworth.com)
David Begley (d.begley@nepean.uws.edu.au)
(skip@automatrix.com)
David-Michael Lincke (dlincke@sgcl1.unisg.ch)
Gioacchino La Vecchia (gio@di.unipi.it)
Pete Ashdown (pashdown@xmission.com)
Mubashir Cheema (cheema@sparco.com)

5
cgi-bin/donothing Executable file
View File

@ -0,0 +1,5 @@
#!/bin/sh
echo Status: 204 Do Nothing
echo

View File

@ -21,7 +21,7 @@
# |group:leader@domain.com,member@domain.com # |group:leader@domain.com,member@domain.com
# +----------------------------------------- # +-----------------------------------------
# ====================================================================== # ======================================================================
# Carlos A. Pero (cpero@ncsa.uiuc.edu) last update 4/30/95 # Carlos A. Pero (cpero@ncsa.uiuc.edu) last update 10/17/95
# ====================================================================== # ======================================================================
# Documentation for WebMonitor can be found at # Documentation for WebMonitor can be found at
# <URL:http://hoohoo.ncsa.uiuc.edu/webmonitor/> # <URL:http://hoohoo.ncsa.uiuc.edu/webmonitor/>
@ -42,6 +42,15 @@
# LIMITATION, WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A # LIMITATION, WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A
# PARTICULAR PURPOSE. # PARTICULAR PURPOSE.
# ====================================================================== # ======================================================================
# For the greatest security, this script relies on a 'mail.list' file
# with a list of authorized nicknames and email address which can receive
# email through this mail script.
#
# For greater scalability, the '@AUTHDOMAINS' array can be used to store
# a list of domains. Any email address ending with one of these domains
# can use this script to receive email. In this case, the full email
# address becomes the 'nickname'.
# ======================================================================
# This script can be referenced 2 ways for the best flexibility: # This script can be referenced 2 ways for the best flexibility:
# #
# DIRECTLY, <A HREF="/cgi-bin/mail?nickname"> # DIRECTLY, <A HREF="/cgi-bin/mail?nickname">
@ -78,9 +87,13 @@
######################################################################## ########################################################################
########## Configurable variables ###################################### ########## Configurable variables ######################################
$SENDMAIL = '/usr/sbin/sendmail'; $SENDMAIL = '/usr/lib/sendmail';
# The location of your sendmail binary # The location of your sendmail binary
@AUTHDOMAINS = ('');
# List of lower-case Internet domains that can use this script
# such as ('ncsa.uiuc.edu', 'domain.com')
## Also, make sure the first line of this script points ## Also, make sure the first line of this script points
## to your PERL binary ## to your PERL binary
@ -88,31 +101,16 @@ $SENDMAIL = '/usr/sbin/sendmail';
######################################################################## ########################################################################
$SCRIPT = $ENV{'SCRIPT_NAME'}; $ENV{'SCRIPT_NAME'} =~ m#(/.*/)(.*)$#;
$SCRIPTDIR = $1;
$SCRIPT = $2;
#### Do standard HTTP stuff #### #### Do standard HTTP stuff ####
&cgi_receive; &cgi_receive;
&cgi_decode; &cgi_decode;
&cgi_header; &cgi_header;
#### Output email form unless you are receiving FORM input already #### #### Load mail.list into associative array ####
&print_form unless keys %FORM;
#### Make sure required fields are filled out ####
if ($FORM{'nickname'}) {
#### This section is for receiving from this form ####
&error_blank_field('your name') unless ($FORM{'from-name'});
&error_blank_field('your email address in the form of <I>name@domain</I>') unless ($FORM{'from-email'} =~ /\@/);
&error_blank_field('the subject of the message') unless ($FORM{'subject'});
&error_blank_field('your message') unless ($FORM{'message'});
}
else {
#### This section is for user's forms ####
#### Such as ACTION="/cgi-bin/mail?carlos" to have results forwarded ####
$FORM{'nickname'} = $ENV{'QUERY_STRING'};
}
#### Lookup email address based on 'nickname' ####
open (MAILNAMES, "mail.list") || die ("$SCRIPT: Can't open mail.list: $!\n"); open (MAILNAMES, "mail.list") || die ("$SCRIPT: Can't open mail.list: $!\n");
while (<MAILNAMES>) { while (<MAILNAMES>) {
chop; chop;
@ -120,33 +118,64 @@ while (<MAILNAMES>) {
$ADDRESS{$nick} = $addr; $ADDRESS{$nick} = $addr;
} }
close (MAILNAMES); close (MAILNAMES);
&error_blank_field('the nickname of the recipient') unless ($ADDRESS{$FORM{'nickname'}});
#### Make sure all necessary variables for email message are filled in #### Figure out who the information should be sent to ####
if ($ENV{'QUERY_STRING'} =~ /\@/) {
#### User specified a full email address ####
($machine = $') =~ tr/A-Z/a-z/;
undef $FLAG{'authorized'};
for ($[ .. $#AUTHDOMAINS) {
$FLAG{'authorized'} = $AUTHDOMAINS[$_], last if ($ENV{'QUERY_STRING'} =~ /$AUTHDOMAINS[$_]$/);
}
&error_blank_field('an authorized email address') unless ($FLAG{'authorized'});
$recipient = $ENV{'QUERY_STRING'};
$extraaction = "?$recipient";
}
elsif ($ENV{'QUERY_STRING'}) {
#### User specified a nickname ####
$nickname = $ENV{'QUERY_STRING'};
&error_blank_field('a valid recipient nickname') unless ($ADDRESS{$nickname});
$recipient = $ADDRESS{$nickname};
$extraaction = "?$nickname";
}
elsif ($FORM{'nickname'}) {
#### Input is coming from listbox, ready for forwarding ####
$nickname = $FORM{'nickname'};
&error_blank_field('a valid recipient nickname') unless ($ADDRESS{$nickname});
$recipient = $ADDRESS{$FORM{'nickname'}};
}
elsif ($ENV{'REQUEST_METHOD'} eq "POST") {
#### I don't know who the information was for ####
&error_blank_field('a valid recipient');
}
#### Output a default email form if not POSTing already ####
&print_form unless ($ENV{'REQUEST_METHOD'} eq "POST");
#### Check for require fields
foreach $field (@requirefields) {
&error_blank_field($field) unless ($FORM{$field});
}
#### Fill in missing fields for forwarding FORM results ####
($FORM{'subject'}) || ($FORM{'subject'} = "FORM results"); ($FORM{'subject'}) || ($FORM{'subject'} = "FORM results");
($FORM{'from-email'}) || ($FORM{'from-email'} = $ADDRESS{$FORM{'nickname'}}); ($FORM{'from-email'}) || ($FORM{'from-email'} = $recipient);
($FORM{'from-name'}) || ($FORM{'from-name'} = "WebMonitor mail"); ($FORM{'from-name'}) || ($FORM{'from-name'} = "WebMonitor mail");
open (MAIL, "| $SENDMAIL $ADDRESS{$FORM{'nickname'}}") || die ("$SCRIPT: Can't open $mailprog: $!\n"); open (MAIL, "| $SENDMAIL $recipient") || die ("$SCRIPT: Can't open $mailprog: $!\n");
print MAIL "Reply-to: $FORM{'from-email'} ($FORM{'from-name'})\n"; print MAIL "Reply-to: $FORM{'from-email'} ($FORM{'from-name'})\n";
print MAIL "From: $FORM{'from-email'} ($FORM{'from-name'})\n"; print MAIL "From: $FORM{'from-email'} ($FORM{'from-name'})\n";
print MAIL "To: $ADDRESS{$FORM{'nickname'}}\n"; print MAIL "To: $recipient\n";
print MAIL "Subject: $FORM{'subject'}\n"; print MAIL "Subject: $FORM{'subject'}\n";
print MAIL "X-Comments: =============================================================\n";
print MAIL "X-Comments: NOTE: This message was sent through the WebMonitor mail form\n";
print MAIL "X-Comments: =============================================================\n";
print MAIL "X-Comments: HOST: $ENV{'REMOTE_HOST'} ($ENV{'REMOTE_ADDR'})\n";
print MAIL "X-Comments: BROWSER: $ENV{'HTTP_USER_AGENT'}\n";
print MAIL "X-Comments: REFERER: $FORM{'previous-url'}\n" if ($FORM{'previous-url'});
print MAIL "X-Comments: =============================================================\n";
print MAIL "\n"; print MAIL "\n";
print MAIL "=============================================================\n"; &dump_values(FORM, MAIL);
print MAIL "NOTE: This message was sent through the WebMonitor mail form\n";
print MAIL "=============================================================\n";
print MAIL "REMOTE HOST: $ENV{'REMOTE_HOST'}\n";
print MAIL "REMOTE ADDRESS: $ENV{'REMOTE_ADDR'}\n";
print MAIL "HTTP_USER_AGENT: $ENV{'HTTP_USER_AGENT'}\n";
print MAIL "=============================================================\n";
print MAIL "\n";
if ($ENV{'QUERY_STRING'}) {
&dump_values(FORM, MAIL);
}
else {
print MAIL "$FORM{'message'}\n";
}
print MAIL "\n"; print MAIL "\n";
close (MAIL); close (MAIL);
@ -172,18 +201,13 @@ print qq|<HR>\n|;
print "<PRE>\n"; print "<PRE>\n";
print "Reply-to: $FORM{'from-email'} ($FORM{'from-name'})\n"; print "Reply-to: $FORM{'from-email'} ($FORM{'from-name'})\n";
print "From: $FORM{'from-email'} ($FORM{'from-name'})\n"; print "From: $FORM{'from-email'} ($FORM{'from-name'})\n";
print "To: $ADDRESS{$FORM{'nickname'}}\n"; print "To: $recipient\n";
print "Subject: $FORM{'subject'}\n"; print "Subject: $FORM{'subject'}\n";
print "\n"; print "\n";
if ($ENV{'QUERY_STRING'}) { &dump_values(FORM, STDOUT);
&dump_values(FORM, STDOUT);
}
else {
print "$FORM{'message'}\n";
}
print "\n"; print "\n";
print "</PRE>\n"; print "</PRE>\n";
print "</BODY>\n"; print "</BODY></HTML>\n";
exit; exit;
##################################################################### #####################################################################
@ -195,8 +219,7 @@ sub error_blank_field {
print "<HTML><HEAD><TITLE>WebMonitor-Email Error</TITLE></HEAD><BODY>\n"; print "<HTML><HEAD><TITLE>WebMonitor-Email Error</TITLE></HEAD><BODY>\n";
print "<H1>Error!</H1>\n"; print "<H1>Error!</H1>\n";
print "You did not fill in $variable.\n"; print "You did not fill in $variable.\n";
print "Please go back to the form and do so.\n"; print "</BODY></HTML>\n";
print "</BODY>\n";
exit; exit;
} }
@ -233,71 +256,70 @@ sub cgi_decode {
$value =~ s/\|/ /g; $value =~ s/\|/ /g;
$value =~ s/^!/ /g; ## Allow exclamation points in sentences $value =~ s/^!/ /g; ## Allow exclamation points in sentences
#### Skip blank text entry fields #### Split apart any directive prefixes
next if ($value eq ""); #### NOTE: colons are reserved to delimit these prefixes
@parts = split(/:/, $name);
#### Check for "assign-dynamic" field names $name = $parts[$#parts];
#### Mainly for on-the-fly input names, especially checkboxes if (grep(/^require$/, @parts)) {
if ($name =~ /^assign-dynamic/) { push (@requirefields, $name);
}
if (grep(/^ignore$/, @parts)) {
push (@ignorefields, $name);
}
if (grep(/^dynamic$/, @parts)) {
#### For simulating a checkbox
#### It may be dynamic, but useless if nothing entered
next if ($value eq "");
$name = $value; $name = $value;
$value = "on"; $value = "on";
} }
#### Skip generally blank fields
next if ($value eq "");
#### Allow for multiple values of a single name #### Allow for multiple values of a single name
$FORM{$name} .= ", " if ($FORM{$name}); $FORM{$name} .= ", " if ($FORM{$name});
$FORM{$name} .= $value; $FORM{$name} .= $value;
#### Add to ordered list if not on list already
push (@fields, $name) unless (grep(/^$name$/, @fields));
} }
} }
sub dump_values { sub dump_values {
local($env, $handle) = @_; local($env, $handle) = @_;
eval "\@keys = keys \%$env";
eval "\@values = values \%$env";
($handle eq "STDOUT") && (print $handle "<PRE>\n"); ($handle eq "STDOUT") && (print $handle "<PRE>\n");
while ($#keys >= 0) { foreach $field (@fields) {
$key = pop(@keys); next if (grep(/^$field$/, @ignorefields));
$value = pop(@values); if ($FORM{$field} =~ /[\cM\n]/) {
if ($value =~ /[\cM\n]/) { print $handle "($field)\n";
print $handle "($key)\n"; print $handle "-" x 75, "\n", $FORM{$field}, "\n", "-" x 75, "\n";
print $handle "-" x 70, "\n", $value, "-" x 70, "\n";
} }
else { else {
print $handle "($key) $value\n"; print $handle "($field) $FORM{$field}\n";
} }
} }
($handle eq "STDOUT") && (print $handle "</PRE>\n"); ($handle eq "STDOUT") && (print $handle "</PRE>\n");
} }
sub print_form { sub print_form {
#### Assign path_info and query_string if necessary
#### $path_info = "";
open (MAILNAMES, "mail.list") || die ("$SCRIPT: Can't open mail.list: $!\n");
while (<MAILNAMES>) {
chop;
($nickname, $address) = split(/:/, $_);
$ADDRESS{$nickname} = $address;
}
close (MAILNAMES);
print qq|<HTML><HEAD><TITLE>WebMonitor-Email Form</TITLE></HEAD><BODY>\n|; print qq|<HTML><HEAD><TITLE>WebMonitor-Email Form</TITLE></HEAD><BODY>\n|;
print qq|<H1>$ENV{'SERVER_NAME'} <A HREF="http://hoohoo.ncsa.uiuc.edu/webmonitor/module-mail.html">Email Form</A></H1>\n|; print qq|<H1>$ENV{'SERVER_NAME'} <A HREF="http://hoohoo.ncsa.uiuc.edu/webmonitor/module-mail.html">Email Form</A></H1>\n|;
print qq|<FORM METHOD="POST" ACTION="$SCRIPT$path_info$query_string">\n|; print qq|<FORM METHOD="POST" ACTION="$ENV{'SCRIPT_NAME'}$extraaction">\n|;
print qq|<HR>\n|; print qq|<HR>\n|;
print qq|<INPUT TYPE="submit" VALUE="Send Email"> to |; print qq|<INPUT TYPE="submit" VALUE="Send Email"> to |;
if ($nickname) {
if ($ADDRESS{$ENV{'QUERY_STRING'}}) { print qq|<I>$recipient</I> <B>($nickname)</B>\n|;
print qq|<B>$ENV{'QUERY_STRING'}</B> <I>($ADDRESS{$ENV{'QUERY_STRING'}})</I>\n|; }
print qq|<INPUT TYPE="hidden" NAME="nickname" VALUE="$ENV{'QUERY_STRING'}">\n|; elsif ($recipient) {
print qq|<I>$recipient</I>\n|;
} }
else { else {
print qq|<SELECT NAME="nickname">\n|; print qq|<SELECT NAME="ignore:nickname">\n|;
print qq|<OPTION>Select name...\n|; print qq|<OPTION>Select name...\n|;
foreach $nickname (sort keys %ADDRESS) { foreach $nick (sort keys %ADDRESS) {
print qq|<OPTION>$nickname\n|; print qq|<OPTION>$nick\n|;
} }
print qq|</SELECT>\n|; print qq|</SELECT>\n|;
} }
@ -305,14 +327,14 @@ sub print_form {
print qq|<HR>\n|; print qq|<HR>\n|;
print qq|<PRE>|; print qq|<PRE>|;
print qq| Your Name: <INPUT NAME="from-name" SIZE="30">\n|; print qq| Your Name: <INPUT NAME="require:ignore:from-name" SIZE="30">\n|;
print qq|Email Address: <INPUT NAME="from-email" SIZE="30">\n|; print qq|Email Address: <INPUT NAME="require:ignore:from-email" SIZE="30">\n|;
print qq| Subject: <INPUT NAME="subject" SIZE="40"> <INPUT TYPE="reset" VALUE="Clear Message">\n|; print qq| Subject: <INPUT NAME="ignore:require:subject" SIZE="40"> <INPUT TYPE="reset" VALUE="Clear Message">\n|;
print qq|</PRE>\n|; print qq|</PRE>\n|;
print qq|<TEXTAREA NAME="message" ROWS="15" COLS="70"></TEXTAREA>\n|; print qq|<TEXTAREA NAME="require:message" ROWS="15" COLS="75"></TEXTAREA>\n|;
print qq|<INPUT TYPE="hidden" NAME="previous-url" VALUE="$ENV{'HTTP_REFERER'}">\n|; print qq|<INPUT TYPE="hidden" NAME="ignore:previous-url" VALUE="$ENV{'HTTP_REFERER'}">\n|;
print qq|</FORM>\n|; print qq|</FORM>\n|;
print qq|</BODY>\n|; print qq|</BODY></HTML>\n|;
exit; exit;
} }

148
cgi-bin/nph-error.pl Executable file
View File

@ -0,0 +1,148 @@
#!/usr/local/bin/perl
#
# Non-parsed headers CGI 1.1 error script in Perl to handle error requests
# from NCSA HTTPd 1.4 via ErrorDocument. This should handle all errors in
# almost the same fashion as NCSA HTTPd 1.4 would internally.
#
# This script is in the Public Domain. NCSA and the author offer no
# guaruntee's nor claim any responsibility for it. That's as pseudo-legalise
# as I get.
#
# This script doesn't do any encryption or authentication, nor does it
# contain hooks to do so.
#
# This was written for Perl 4.016. I've heard rumours about it working with
# other versions, but I'm no Perl hacker, so how would I know?
#
# Brandon Long / NCSA HTTPd Development Team / Software Development Group
# National Center for Supercomputing Applications / University of Illinios
#
# For more information:
# NCSA HTTPd : http://hoohoo.ncsa.uiuc.edu/docs/
# CGI 1.1 : http://hoohoo.nsca.uiuc.edu/cgi/
# ErrorDocument : http://hoohoo.ncsa.uiuc.edu/docs/setup/srm/ErrorDocument.html
# Example CGI : http://hoohoo.ncsa.uiuc.edu/cgi/ErrorCGI.html
#
$error = $ENV{'QUERY_STRING'};
$redirect_request = $ENV{'REDIRECT_REQUEST'};
($redirect_method,$request_url,$redirect_protocal) = split(' ',$redirect_request);
$redirect_status = $ENV{'REDIRECT_STATUS'};
if (!defined($redirect_status)) {
$redirect_status = "200 Ok";
}
($redirect_number,$redirect_message) = split(' ',$redirect_status);
$error =~ s/error=//;
$title = "<HEAD><TITLE>".$redirect_status."</TITLE></HEAD>";
if ($redirect_method eq "HEAD") {
$head_only = 1;
} else {
$head_only = 0;
}
printf("%s %s\r\n",$ENV{'SERVER_PROTOCOL'},$redirect_status);
printf("Server: %s\r\n",$ENV{'SERVER_SOFTWARE'});
printf("Content-type: text/html\r\n");
$redirect_status = "<img alt=\"\" src=/images/icon.gif>".$redirect_status;
if ($redirect_number == 302) {
if ($error !~ /http:/) {
printf("xLocation: http://%s:%s%s\r\n",
$ENV{'SERVER_NAME'},
$ENV{'SERVER_PORT'},
$error);
if (!$head_only) {
printf("%s\n\r",$title);
printf("<BODY><H1>%s</H1>\n\r",$redirect_status);
printf("This document has moved");
printf("<A HREF=\"http://%s:%s%s\">here</A>.\r\n",
$ENV{'SERVER_NAME'},
$ENV{'SERVER_PORT'},
$error);
}
} else {
printf("Location: %s\r\n",$error);
if (!$head_only) {
printf("%s\r\n",$title);
printf("<BODY><H1>%s</H1>\r\n",$redirect_status);
printf("This document has moved");
printf("<A HREF=\"%s\">here</A>.\r\n",$error);
}
}
} elsif ($redirect_number == 400) {
printf("\r\n");
if (!$head_only) {
printf("%s\r\n",$title);
printf("<BODY><H1>%s</H1>\r\n",$redirect_status);
printf("Your client sent a request that this server didn't");
printf(" understand.<br><b>Reason:</b> %s\r\n",$error);
}
} elsif ($redirect_number == 401) {
printf("WWW-Authenticate: %s\r\n",$error);
printf("\r\n");
if (!$head_only) {
printf("%s\r\n",$title);
printf("<BODY><H1>%s</H1>\r\n",$redirect_status);
printf("Browser not authentication-capable or ");
printf("authentication failed.\r\n");
}
} elsif ($redirect_number == 403) {
printf("\r\n");
if (!$head_only) {
printf("%s\r\n",$title);
printf("<BODY><H1>%s</H1>\r\n",$redirect_status);
printf("Your client does not have permission to get");
printf("URL:%s from this server.\r\n",$ENV{'REDIRECT_URL'});
}
} elsif ($redirect_number == 404) {
printf("\r\n");
if (!$head_only) {
printf("%s\r\n",$title);
printf("<BODY><H1>%s</H1>\r\n",$redirect_status);
printf("The requested URL:<code>%s</code> ",
$ENV{'REDIRECT_URL'});
printf("was not found on this server.\r\n");
}
} elsif ($redirect_number == 500) {
printf("\r\n");
if (!$head_only) {
printf("%s\r\n",$title);
printf("<BODY><H1>%s</H1>\r\n",$redirect_status);
printf("The server encountered an internal error or ");
printf("misconfiguration and was unable to complete your ");
printf("request \"<code>%s</code>\"\r\n",$redirect_request);
}
} elsif ($redirect_number == 501) {
printf("\r\n");
if (!$head_only) {
printf("%s\r\n",$title);
printf("<BODY><H1>%s</H1>\r\n",$redirect_status);
printf("The server is unable to perform the method ");
printf("<b>%s</b> at this time.",$redirect_method);
}
} else {
printf("\r\n");
if (!$head_only) {
printf("%s\r\n",$title);
printf("<BODY><H1>%s</H1>\r\n",$redirect_status);
}
}
if (!$head_only) {
printf("<p>The following might be useful in determining the problem:");
printf("<pre>\r\n");
open(ENV,"env|");
while (<ENV>) {
printf("$_");
}
close(ENV);
printf("</pre>\r\n<hr>");
printf("<A HREF=\"http://%s:%s/\"><img alt=\"[Back to Top]\" src=\"/images/back.gif\"> Back to Root of Server</A>\r\n",
$ENV{'SERVER_NAME'},$ENV{'SERVER_PORT'});
printf("<hr><i><a href=\"mailto:webmaster\@%s\">webmaster\@%s</a></i> / ",
$ENV{'SERVER_NAME'},$ENV{'SERVER_NAME'});
printf("<i><a href=\"mailto:httpd\@ncsa.uiuc.edu\">httpd\@ncsa.uiuc.edu</a></i>");
printf("</BODY>\r\n");
}

116
cgi-bin/redirect Executable file
View File

@ -0,0 +1,116 @@
#!/usr/local/bin/perl
#
# redirect -- PERL redirection script
#
# Carlos A. Pero <cpero@ncsa.uiuc.edu>, 10/22/95
#
# For usage information, request the script's URL through the Web
# without submitting any data.
#
$ENV{'SCRIPT_NAME'} =~ m#(/.*/)(.*)$#;
$SCRIPTDIR = $1;
$SCRIPT = $2;
#### Do standard HTTP stuff ####
&cgi_receive;
&cgi_decode;
#### Output instructions if not receiving a URL ####
&print_info unless $FORM{'url'};
#### Output redirection ####
print <<"EndResponse";
Status: 302 Redirected
Content-type: text/html
Location: $FORM{'url'}
<HTML><HEAD>
<TITLE>Client Redirected</TITLE>
</HEAD><BODY>
The CGI script has redirected your browser to <A HREF="$FORM{'url'}">this location</A>.
</BODY></HTML>
EndResponse
exit;
#####################################################################
#### SUBROUTINES ####################################################
sub cgi_receive {
if ($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN, $incoming, $ENV{'CONTENT_LENGTH'});
}
else {
$incoming = $ENV{'QUERY_STRING'};
}
}
sub cgi_decode {
@pairs = split(/&/, $incoming);
foreach (@pairs) {
($name, $value) = split(/=/, $_);
$name =~ tr/+/ /;
$value =~ tr/+/ /;
$name =~ s/%([A-F0-9][A-F0-9])/pack("C", hex($1))/gie;
$value =~ s/%([A-F0-9][A-F0-9])/pack("C", hex($1))/gie;
#### Strip out semicolons unless for special character
$value =~ s/;/$$/g;
$value =~ s/&(\S{1,6})$$/&\1;/g;
$value =~ s/$$/ /g;
$value =~ s/\|/ /g;
$value =~ s/^!/ /g; ## Allow exclamation points in sentences
#### Skip generally blank fields
next if ($value eq "");
#### Allow for multiple values of a single name
$FORM{$name} .= ", " if ($FORM{$name});
#### Check to see if input NAME is the URL, i.e. SUBMIT button
if ($name =~ m|^\w+:\S+$|) { $FORM{'url'} = $name; }
$FORM{$name} .= $value;
}
}
sub print_info {
print <<"EndHelp";
Content-type: text/plain
This redirect script will accept input from a FORM, either via
METHOD GET or POST, and send a 300-level HTTP status code to
redirect the browser to a new URL.
There are two ways to use a FORM in conjunction with this script:
1. A list of URLs with a submit button
<FORM METHOD="POST" ACTION="/cgi-bin/redirect">
<SELECT NAME="url">
<OPTION VALUE="http://www.ncsa.uiuc.edu/">NCSA
<OPTION VALUE="http://hoohoo.ncsa.uiuc.edu/">HTTPd
<OPTION VALUE="http://www.uiuc.edu/">U of I
</SELECT>
<INPUT TYPE="submit" VALUE="Go to URL">
</FORM>
In this case, the script will find the input called "url" and
redirect the browser to this location.
2. Multiple submit buttons
<FORM METHOD="POST" ACTION="/cgi-bin/redirect">
<INPUT TYPE="submit" NAME="http://www.ncsa.uiuc.edu/" VALUE="NCSA">
<INPUT TYPE="submit" NAME="http://hoohoo.ncsa.uiuc.edu/" VALUE="HTTPd">
<INPUT TYPE="submit" NAME="http://www.ncsa.uiuc.edu/" VALUE="U of I">
</FORM>
In this case, the script will find an input NAME that looks like a URL,
and redirect the browser to this location.
Either method should work fine, just don't use both within the same FORM.
EndHelp
exit;
}

View File

@ -1,7 +1,4 @@
#!/bin/sh #!/bin/sh
#
# Prints out all of the environment variables as used
#
echo Content-type: text/plain echo Content-type: text/plain
echo echo
env env

View File

@ -28,36 +28,38 @@ aix3:
aix4: aix4:
make all CC=gcc make all CC=gcc
sunos:
make all CC=gcc
solaris:
make all CC=gcc
hp-gcc: hp-gcc:
make all CC=gcc make all CC=gcc
hp-cc: hp-cc:
make all CC=cc CFLAGS=-Ae make all CC=cc CFLAGS=-Ae
sgi: linux:
make all CC=cc make all CC=gcc
decmips:
make all CC=cc
decaxp:
make all CC=cc
netbsd: netbsd:
make all CC=cc make all CC=cc
linux:
next:
make all CC=cc
osf1:
make all CC=cc
sgi:
make all CC=cc
solaris:
make all CC=gcc
sunos:
make all CC=gcc make all CC=gcc
svr4: svr4:
make all CC=cc make all CC=cc
tar: query post-query imagemap jj phf ultrix:
$(RM) post-query.o util.o imagerect.o jj.o phf.o make all CC=gcc
post-query: post-query.o util.o post-query: post-query.o util.o
$(CC) post-query.o util.o -o ../cgi-bin/post-query $(CC) post-query.o util.o -o ../cgi-bin/post-query
@ -75,9 +77,8 @@ phf: phf.o util.o
$(CC) phf.o util.o -o ../cgi-bin/phf $(CC) phf.o util.o -o ../cgi-bin/phf
change-passwd: change-passwd.o util.o change-passwd: change-passwd.o util.o
$(CC) change-passwd.o util.o -o ../cgi-bin/change-passwd $(CC) change-passwd.o util.o -o ../sec-cgi/change-passwd
clean: clean:
rm -f *.o ../cgi-bin/post-query ../cgi-bin/query ../cgi-bin/change-passwd ../cgi-bin/phf ../cgi-bin/jj ../cgi-bin/imagemap rm -f *.o ../cgi-bin/post-query ../cgi-bin/query ../sec-cgi/change-passwd ../cgi-bin/phf ../cgi-bin/jj ../cgi-bin/imagemap

View File

@ -1,3 +1,12 @@
/*
** Original code by Rob McCool, robm@ncsa.uiuc.edu.
**
** 06/28/95: Carlos Varela, cvarela@isr.co.jp
** 1.1 : Additional error message if password file not changed.
** By default allows password addition, better feedback to "wizard".
**
*/
#include <sys/types.h> #include <sys/types.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -6,7 +15,7 @@
#include <time.h> #include <time.h>
#define USER_FILE "/usr/local/etc/httpd/conf/.htpasswd" #define USER_FILE "/usr/local/etc/httpd/conf/.htpasswd"
#define WIZARD "surobm" #define WIZARD "webmaster"
char *makeword(char *line, char stop); char *makeword(char *line, char stop);
char *fmakeword(FILE *f, char stop, int *len); char *fmakeword(FILE *f, char stop, int *len);
@ -76,7 +85,7 @@ main(int argc, char *argv[]) {
user=NULL; user=NULL;
p1=NULL; p1=NULL;
p2=NULL; p2=NULL;
create=0; create=1;
for(x=0;cl && (!feof(stdin));x++) { for(x=0;cl && (!feof(stdin));x++) {
t1 = fmakeword(stdin,'&',&cl); t1 = fmakeword(stdin,'&',&cl);
t2 = makeword(t1,'='); t2 = makeword(t1,'=');
@ -124,7 +133,7 @@ main(int argc, char *argv[]) {
if(strcmp(p1,p2)) { if(strcmp(p1,p2)) {
printf("<TITLE>Password Mismatch</TITLE>"); printf("<TITLE>Password Mismatch</TITLE>");
printf("<H1>Password Mismatch</H1>"); printf("<H1>Password Mismatch</H1>");
printf("The two copies of your the password do not match. Please"); printf("The two copies of your password do not match. Please");
printf(" try again."); printf(" try again.");
exit(1); exit(1);
} }
@ -163,10 +172,20 @@ main(int argc, char *argv[]) {
fclose(f); fclose(f);
fclose(tfp); fclose(tfp);
sprintf(command,"cp %s %s",tn,USER_FILE); sprintf(command,"cp %s %s",tn,USER_FILE);
system(command); if (system(command)) {
fprintf(stderr,
"Could not overwrite passwd file.\n",USER_FILE);
exit(1);
}
unlink(tn); unlink(tn);
printf("<TITLE>Successful Change</TITLE>"); if ((!found) && (create)) {
printf("<H1>Successful Change</H1>"); printf("<TITLE>Successful Addition</TITLE>");
printf("Your password has been successfully changed.<P>"); printf("<H1>Successful Addition</H1>");
printf("Your new user/password combination has been successfully added.<P>");
} else {
printf("<TITLE>Successful Change</TITLE>");
printf("<H1>Successful Change</H1>");
printf("Your password has been successfully changed.<P>");
}
exit(0); exit(0);
} }

View File

@ -43,6 +43,13 @@
** 1.8 : Fixed bug (strcat->sprintf) when reporting error. ** 1.8 : Fixed bug (strcat->sprintf) when reporting error.
** Included getline() function from util.c in NCSA httpd distribution. ** Included getline() function from util.c in NCSA httpd distribution.
** **
** 11/08/95: Brandon Long, blong@ncsa.uiuc.edu
**
** 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
** 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>
@ -53,8 +60,10 @@
#include <sys/types.h> #include <sys/types.h>
#include <ctype.h> #include <ctype.h>
char *getenv(); char *getenv();
#include <ctype.h>
#endif #endif
#include <sys/types.h> #include <sys/types.h>
#include "util.h"
#include <sys/stat.h> #include <sys/stat.h>
#define CONF_FILE "/usr/local/etc/httpd/conf/imagemap.conf" #define CONF_FILE "/usr/local/etc/httpd/conf/imagemap.conf"
@ -66,6 +75,13 @@ char *getenv();
#define LF 10 #define LF 10
#define CR 13 #define CR 13
static void servererr(char *msg);
static void sendmesg(char *url);
static int pointinpoly(double point[2], double pgon[MAXVERTS][2]);
static int pointincircle(double point[2], double coords[MAXVERTS][2]);
static int pointinrect(double point[2], double coords[MAXVERTS][2]);
int isname(char); int isname(char);
int main(int argc, char **argv) int main(int argc, char **argv)
@ -83,7 +99,7 @@ int main(int argc, char **argv)
mapname=getenv("PATH_INFO"); mapname=getenv("PATH_INFO");
if((!mapname) || (!mapname[0])) if((!mapname) || (!mapname[0]))
servererr("No map name given. Please read the <A HREF=\"http://hoohoo.ncsa.uiuc.edu/docs/setup/admin/Imagemap.html\">instructions</A>.<P>"); servererr("No map name given. Please read the <A HREF=\"http://hoohoo.ncsa.uiuc.edu/docs/tutorials/imagemapping.html\">instructions</A>.<P>");
mapname++; mapname++;
@ -103,8 +119,9 @@ int main(int argc, char **argv)
} }
if ((fp = fopen(CONF_FILE, "r")) == NULL){ if ((fp = fopen(CONF_FILE, "r")) == NULL){
sprintf(errstr, "Couldn't open configuration file: %s", CONF_FILE); /* Assume new style request if CONF_FILE doesn't exist
servererr(errstr); */
goto openconf;
} }
while(!(getline(input,MAXLINE,fp))) { while(!(getline(input,MAXLINE,fp))) {
@ -224,26 +241,50 @@ int main(int argc, char **argv)
servererr("No default specified."); servererr("No default specified.");
} }
sendmesg(char *url) static void sendmesg(char *url)
{ {
if (strchr(url, ':')) /*** It is a full URL ***/ char *port;
printf("Location: "); char *path_info;
else /*** It is a virtual URL ***/ char path[MAXLINE];
printf("Location: http://%s:%s", getenv("SERVER_NAME"),
getenv("SERVER_PORT"));
printf("%s%c%c",url,10,10); if (strchr(url, ':')) /*** It is a full URL ***/
printf("This document has moved <A HREF=\"%s\">here</A>%c",url,10); printf("Location: %s%c%c",url,LF,LF);
exit(1); else { /*** It is a virtual URL ***/
printf("Location: http://%s", getenv("SERVER_NAME"));
/* only add port if it's not the default */
if ((port = getenv("SERVER_PORT")) && strcmp(port,"80"))
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("This document has moved <A HREF=\"%s\">here</A>%c",url,LF);
exit(1);
} }
int pointinrect(double point[2], double coords[MAXVERTS][2]) static int pointinrect(double point[2], double coords[MAXVERTS][2])
{ {
return ((point[X] >= coords[0][X] && point[X] <= coords[1][X]) && return ((point[X] >= coords[0][X] && point[X] <= coords[1][X]) &&
(point[Y] >= coords[0][Y] && point[Y] <= coords[1][Y])); (point[Y] >= coords[0][Y] && point[Y] <= coords[1][Y]));
} }
int pointincircle(double point[2], double coords[MAXVERTS][2]) static int pointincircle(double point[2], double coords[MAXVERTS][2])
{ {
int radius1, radius2; int radius1, radius2;
@ -255,7 +296,7 @@ int pointincircle(double point[2], double coords[MAXVERTS][2])
return (radius2 <= radius1); return (radius2 <= radius1);
} }
int pointinpoly(double point[2], double pgon[MAXVERTS][2]) static int pointinpoly(double point[2], double pgon[MAXVERTS][2])
{ {
int i, numverts, inside_flag, xflag0; int i, numverts, inside_flag, xflag0;
int crossings; int crossings;
@ -321,9 +362,9 @@ int pointinpoly(double point[2], double pgon[MAXVERTS][2])
return (inside_flag); return (inside_flag);
} }
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>");

View File

@ -7,6 +7,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h>
#ifndef NO_STDLIB_H #ifndef NO_STDLIB_H
#include <stdlib.h> #include <stdlib.h>
#else #else
@ -14,12 +15,12 @@ char *getenv();
#endif #endif
#if 1 #if 1
#define JJ_FAX "JIMMY_JOHNS_3440603@fax.uiuc.edu" #define JJ_FAX "JIMMY_JOHNS_5555680@fax.uiuc.edu"
#else #else
#define JJ_FAX "robm@imsa.edu" #define JJ_FAX "wow@foo.bar.com"
#endif #endif
#define PASSWORD "SDGROCKS" #define PASSWORD "HTTPdRocKs"
#define LF 10 #define LF 10
void getword(char *word, char *line, char stop); void getword(char *word, char *line, char stop);

2
cgi-src/phf.c Normal file → Executable file
View File

@ -4,6 +4,8 @@
#else #else
char *getenv(); char *getenv();
#endif #endif
#include <string.h>
#include "util.h"
#define LF 10 #define LF 10
#define HTML_BREAK printf("<P>%c", LF); #define HTML_BREAK printf("<P>%c", LF);

View File

@ -7,6 +7,7 @@
#else #else
char *getenv(); char *getenv();
#endif #endif
#include <string.h>
#define MAX_ENTRIES 10000 #define MAX_ENTRIES 10000

1
cgi-src/query.c Normal file → Executable file
View File

@ -7,6 +7,7 @@
#else #else
char *getenv(); char *getenv();
#endif #endif
#include <string.h>
typedef struct { typedef struct {
char name[128]; char name[128];

View File

@ -1,4 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "util.h"
#define LF 10 #define LF 10
#define CR 13 #define CR 13
@ -136,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 */

12
cgi-src/util.h Normal file
View File

@ -0,0 +1,12 @@
void getword(char *word, char *line, char stop);
char *makeword(char *line, char stop);
char *fmakeword(FILE *f, char stop, int *cl);
char x2c(char *what);
void unescape_url(char *url);
void plustospace(char *str);
int rind(char *s, char c);
int getline(char *s, int n, FILE *f);
void send_fd(FILE *f, FILE *fd);
int ind(char *s, char c);
void escape_shell_cmd(char *cmd);

View File

@ -1,6 +1,18 @@
# access.conf: Global access configuration #===========================================================================
# Online docs at http://hoohoo.ncsa.uiuc.edu/ # NCSA HTTPd (comments, questions to httpd@ncsa.uiuc.edu)
# I suggest you consult them; this is important and confusing stuff. #===========================================================================
# This is the gloabal access configuration file.
# Documentation for NCSA HTTPd is available from
# http://hoohoo.ncsa.uiuc.edu/
# Documentation specific to this file is at
# http://hoohoo.ncsa.uiuc.edu/docs/setup/access/Overview.html
# http://hoohoo.ncsa.uiuc.edu/docs/tutorials/user.html
#
# NCSA takes no responsibilty for any problems that result from the use
# of this server. See the COPYRIGHT statement that came with this
# distribution.
#===========================================================================
# /usr/local/etc/httpd/ should be changed to whatever you set ServerRoot to. # /usr/local/etc/httpd/ should be changed to whatever you set ServerRoot to.
<Directory /usr/local/etc/httpd/cgi-bin> <Directory /usr/local/etc/httpd/cgi-bin>

View File

@ -1,27 +1,37 @@
#===========================================================================
# NCSA HTTPd (comments, questions to httpd@ncsa.uiuc.edu)
#===========================================================================
# This is the main server configuration file. It is best to # This is the main server configuration file. It is best to
# leave the directives in this file in the order they are in, or # leave the directives in this file in the order they are in, or
# things may not go the way you'd like. See URL http://hoohoo.ncsa.uiuc.edu/ # things may not go the way you'd like. See URL http://hoohoo.ncsa.uiuc.edu/
# for instructions. # for instructions.
# Do NOT simply read the instructions in here without understanding # Do NOT simply read the instructions in here without understanding
# what they do, if you are unsure consult the online docs. You have been # what they do, if you are unsure consult the online docs. You have been
# warned. # warned.
# Thanks to A. P. Harris for some of the organization and explanations
# contained here-in.
#===========================================================================
# NCSA httpd (comments, questions to httpd@ncsa.uiuc.edu) #===========================================================================
# Server Operation
#---------------------------------------------------------------------------
# ServerType is either inetd, or standalone. # ServerType is either inetd, or standalone.
# Set to 'inetd' to run from inetd, or 'standalone', to run as a daemon.
# Default: standalone
ServerType standalone ServerType standalone
# If you are running from inetd, go to "ServerAdmin". # If you are running from inetd, go to "ServerAdmin".
# Port: The port the standalone listens to. For ports < 1023, you will # Port: The port the standalone listens to. For ports < 1023, you will
# need httpd to be run as root initially. # need HTTPd to be run as root initially.
# Default: 80 (or DEFAULT_PORT)
Port 80 Port 80
# StartServers: The number of servers to launch at startup. Must be # StartServers: The number of servers to launch at startup. Must be
# compiled without the NO_PASS compile option # compiled without the NO_PASS compile option
# Default: 5 (or DEFAULT_START_DAEMON)
StartServers 5 StartServers 5
@ -29,24 +39,72 @@ StartServers 5
# scheme (new server for each connection). These servers will stay around # scheme (new server for each connection). These servers will stay around
# until the server is restarted. They will be reused as needed, however. # until the server is restarted. They will be reused as needed, however.
# See the documentation on hoohoo.ncsa.uiuc.edu for more information. # See the documentation on hoohoo.ncsa.uiuc.edu for more information.
# If compile option RESOURCE_LIMIT is used, HTTPd will not mimic the 1.3
# behavior, and MaxServers will be the maximum number of servers possible.
# Default: 10 (or DEFAULT_MAX_DAEMON)
MaxServers 20 MaxServers 20
# If you wish httpd to run as a different user or group, you must run ## TimeOut <seconds>
# httpd as root initially and it will switch. # The number of seconds the server will wait for a client to
# send its query once connected, or the maximum amount of time the
# server will spend waiting for a client to accept information.
# Default: 1200 (or DEFAULT_TIMEOUT)
# User/Group: The name (or #number) of the user/group to run httpd as. TimeOut 1200
# If you wish HTTPd to run as a different user or group, you must run
# HTTPd as root initially and it will switch.
# User/Group: The name (or #number) of the user/group to run HTTPd as.
# Default: #-1 (or DEFAULT_USER / DEFAULT_GROUP)
User nobody User nobody
Group #-1 Group #-1
# IdentityCheck: Enables or disables RFC931 compliant logging of the
# remote user name for sites which run identd or something similar.
# This information is logged in the access_log. Note that it
# *will* hurt responsiveness considerably, especially for non-unix clients.
# Default: off (or DEFAULT_RFC931)
#IdentityCheck On
# AssumeDigestSupport: Whether it's safe to assume that clients support
# md5 digesting.
# Default: off
#AssumeDigestSupport On
#===========================================================================
# Server Customization
#---------------------------------------------------------------------------
# ServerName allows you to set a host name which is sent back to clients for
# your server if it's different than the one the program would get (i.e. use
# "www" instead of the host's real name).
#
# Note: You cannot just invent host names and hope they work. The name you
# define here must be a valid DNS name for your host. If you don't understand
# this, ask your network administrator.
# Valid with <VirtualHost>
# Default: If you do not specify a ServerName, HTTPd attempts to retrieve
# it through system calls.
#ServerName new.host.name
# ServerAdmin: Your address, where problems with the server should be # ServerAdmin: Your address, where problems with the server should be
# e-mailed. # e-mailed.
# Valid within <VirtualHost>
# Default: <none> (or DEFAULT_ADMIN)
ServerAdmin you@your.address ServerAdmin you@your.address
#===========================================================================
# File Locations
#---------------------------------------------------------------------------
# ServerRoot: The directory the server's config, error, and log files # ServerRoot: The directory the server's config, error, and log files
# are kept in # are kept.
# Note: All other paths will use this as a prefix if they don't start with /
# Default: /usr/local/etc/httpd (or HTTPD_ROOT)
ServerRoot /usr/local/etc/httpd ServerRoot /usr/local/etc/httpd
@ -70,22 +128,134 @@ AgentLog logs/agent_log
RefererLog logs/referer_log RefererLog logs/referer_log
# PidFile: The file the server should log its pid to
PidFile logs/httpd.pid
# AccessConfig: The location of the access configuration file
# Default: conf/access.conf (or ACCESS_CONFIG_FILE)
AccessConfig conf/access.conf
# TypesConfig: The location of the typing configuration file, which
# maps filename extensions to MIME types.
# Default: conf/mime.types (or TYPES_CONFIG_FILE)
#TypesConfig /usr/local/lib/mime.types
# CoreDirectory: where to dump core.
# Default: SERVER_ROOT
#CoreDirectory /tmp
#===========================================================================
# Logging Directives
#---------------------------------------------------------------------------
# LogOptions: This determines the type of log file you are using,
# Valid options currently are:
# Combined for CLF with Referer and UserAgent tagged on
# Separate for CLF in one file and Referer and UserAgent in separate files
# Servername for CLF + ServerName
# Date for Referer and UserAgent logs with same date stamp as access_log
LogOptions Separate
# LogDirGroupWriteOk, LogDirOtherWriteOk: Define either of these if you
# want the server to start even if you have write permissions on the log
# directory. Having write permissions set is a potential security hole.
# Only makes a difference if the server process is started by root.
#LogDirGroupWriteOk
#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,
# keep this line commented. # keep this line commented.
#RefererIgnore servername #RefererIgnore servername
# PidFile: The file the server should log its pid to # DNSMode allows you to control the amount of DNS activity the server will
PidFile logs/httpd.pid # perform. The default is Standard, which means it does a single lookup
# on every request. Minimum means the server will only do a lookup if
# necessary to fulfill a domain restriction. Maximum means the server
# will do two lookups per request. This will be slow, and not necessarily
# that much better security. None will keep the server from doing any
# DNS resolution. Maximum is the same as the old MAXIMUM_DNS compile option,
# and none is the same as the old MINIMUM_DNS option.
# Default: Standard
# ServerName allows you to set a host name which is sent back to clients for DNSMode Standard
# your server if it's different than the one the program would get (i.e. use
# "www" instead of the host's real name).
#
# Note: You cannot just invent host names and hope they work. The name you
# define here must be a valid DNS name for your host. If you don't understand
# this, ask your network administrator.
#ServerName new.host.name #===========================================================================
# KeepAlive Directives
#---------------------------------------------------------------------------
# The directives below configure keepalive, the ability of the server
# to maintain a persistent connection with a client at the client's
# request
# The following line turns keepalive on. The default is off, so
# you can omit this line, or change 'on' to 'off'
# KeepAlive on
# The following line specifies the timeout in seconds of the
# persistent connection. If the client fails to issue another
# request on the socket within this window, the connection is closed
# KeepAliveTimeout 10
# The following line specifies the maximum number of requests
# that will be accepted on the persistent connection. If it
# is set to 0, then there will be no maximum.
# Default:
# MaxKeepAliveRequests 0
#===========================================================================
# Misc Options
#---------------------------------------------------------------------------
#ProcessName: This is the prefix for the process name if compiled with
# SETPROCTITLE.
# Default: HTTPd
#ProcessName WebServer
#Annotation-Server: Name of our annotation server. This will send back
# an Annotation: header with requests to denote where the annotation server
# is located.
#Default: None
#===========================================================================
# VirtualHost
#---------------------------------------------------------------------------
# VirtualHosting is the ability to respond differently to different IP
# addresses. It can be implemented either by having a single server respond
# to all, or by having a different server respond to each (the Unix(tm) OS
# setup precludes responding to some) Every effort has been made to allow
# a single server respond to all as effectively as possible, as this is
# more resource efficient. There are something which still aren't possible
# in that configuration, however.
# BindAddress: A '*', IP number, or host name. Binds the server to a
# specific IP address. * is all IP addresses. Should not be used in
# conjunction with <VirtualHost>
# Default: *
#BindAddress 127.0.0.1
# VirtualHost allows you to look differently depending on the hostname you
# are called by. The parameter must be either an IP address or a hostname
# that maps to a single IP address. Most of the normal httpd.conf commands
# are available, as well as the ability to denote a special ResourceConfig
# file for this host.
# You can also specify an error level with this setting, by denoting the
# VirtualHost as Optional or Required.
<VirtualHost 127.0.0.1 Optional>
DocumentRoot /local
ServerName localhost.ncsa.uiuc.edu
ResourceConfig conf/localhost_srm.conf
</VirtualHost>

View File

@ -0,0 +1,50 @@
# With this document, you define the name space that users see of your http
# server if they access it using localhost (127.0.0.1)
# See the tutorials at http://hoohoo.ncsa.uiuc.edu/docs/tutorials/ for
# more information.
# The NCSA HTTPd Development Team (httpd@ncsa.uiuc.edu)
# DocumentRoot: The directory out of which you will serve your
# documents. By default, all requests are taken from this directory, but
# symbolic links and aliases may be used to point to other locations.
DocumentRoot /
# UserDir: The name of the directory which is appended onto a user's home
# directory if a ~user request is recieved.
UserDir /
# DirectoryIndex: Name of the file to use as a pre-written HTML
# directory index
DirectoryIndex index.html
DefaultIcon /icons/unknown.xbm
AccessFileName .htaccess
# DefaultType is the default MIME type for documents which the server
# cannot find the type of from filename extensions.
DefaultType text/plain
# Redirect allows you to tell clients about documents which used to exist in
# your server's namespace, but do not anymore. This allows you to tell the
# clients where to look for the relocated document.
# Format: Redirect fakename url
# Aliases: Add here as many aliases as you need, up to 20. The format is
# Alias fakename realname
Alias /icons/ /usr/local/etc/httpd/icons/
# ScriptAlias: This controls which directories contain server scripts.
# Format: ScriptAlias fakename realname
ScriptAlias /cgi-bin/ /usr/local/etc/httpd/cgi-bin/

View File

@ -71,13 +71,13 @@ multipart/digest
multipart/mixed multipart/mixed
multipart/parallel multipart/parallel
text/html html htm text/html html htm
text/x-sgml sgml sgm text/x-sgml sgml sgm
text/plain txt text/plain txt
text/richtext rtx text/richtext rtx
text/tab-separated-values tsv text/tab-separated-values tsv
text/x-setext etx text/x-setext etx
video/mpeg mpeg mpg mpe video/mpeg mpeg mpg mpe
video/quicktime qt mov video/quicktime qt mov
video/x-fli fli
video/x-msvideo avi video/x-msvideo avi
video/x-sgi-movie movie video/x-sgi-movie movie

View File

@ -1,12 +1,20 @@
# With this document, you define the name space that users see of your http #===========================================================================
# server. # NCSA HTTPd (comments, questions to httpd@ncsa.uiuc.edu)
#===========================================================================
# See the tutorials at http://hoohoo.ncsa.uiuc.edu/docs/tutorials/ for # This is the server resource configuration file. With this document,
# more information. # you define the name space that users of your server see.
# See URL http://hoohoo.ncsa.uiuc.edu/ for HTTPd Documentation.
# NCSA httpd (httpd@ncsa.uiuc.edu) # Information specific to this file can be found at
# http://hoohoo.ncsa.uiuc.edu/docs/setup/srm/Overview.html
# Do NOT simply read the instructions in here without understanding
# what they do. If you are unsure, consult the online docs. You have been
# warned.
#===========================================================================
#===========================================================================
# Name Space Options
#---------------------------------------------------------------------------
# DocumentRoot: The directory out of which you will serve your # DocumentRoot: The directory out of which you will serve your
# documents. By default, all requests are taken from this directory, but # documents. By default, all requests are taken from this directory, but
# symbolic links and aliases may be used to point to other locations. # symbolic links and aliases may be used to point to other locations.
@ -18,26 +26,53 @@ DocumentRoot /usr/local/etc/httpd/htdocs
UserDir public_html UserDir public_html
# Redirect allows you to tell clients about documents which used to exist in
# your server's namespace, but do not anymore. This allows you to tell the
# clients where to look for the relocated document.
# Format: Redirect fakename url
Redirect /HTTPd/ http://hoohoo.ncsa.uiuc.edu/
# Aliases: Add here as many aliases as you need. The format is
# Alias fakename realname
Alias /icons/ /usr/local/etc/httpd/icons/
# ScriptAlias: This controls which directories contain server scripts.
# Format: ScriptAlias fakename realname
ScriptAlias /cgi-bin/ /usr/local/etc/httpd/cgi-bin/
#===========================================================================
# Directory Indexing
#---------------------------------------------------------------------------
# If a user requests a document (URL) from your server ending in /, the
# server will attempt to "index" the directory. It will first look for
# a file matching the DirectoryIndex directive in order. If no files
# exist, and Indexing is allowed for that directory, the server will provide
# an index that it generates itself. These options allow you to modify the
# look of that index.
# DirectoryIndex: Name of the file to use as a pre-written HTML # DirectoryIndex: Name of the file to use as a pre-written HTML
# directory index # directory index. These files are used if a directory is referenced.
DirectoryIndex index.html DirectoryIndex index.html index.shtml index.cgi
# FancyIndexing is whether you want fancy directory indexing or standard # IndexOptions
FancyIndexing on IndexOptions FancyIndexing
# AddIcon tells the server which icon to show for different files or filename # AddIcon tells the server which icon to show for different files or filename
# extensions # extensions
AddIconByType (TXT,/icons/text.xbm) text/* AddIconByType (TXT,/icons/text.gif) text/*
AddIconByType (IMG,/icons/image.xbm) image/* AddIconByType (IMG,/icons/image.gif) image/*
AddIconByType (SND,/icons/sound.xbm) audio/* AddIconByType (SND,/icons/sound.gif) audio/*
AddIcon /icons/movie.xbm .mpg .qt AddIcon /icons/movie.gif .mpg .qt
AddIcon /icons/binary.xbm .bin AddIcon /icons/binary.gif .bin
AddIcon /icons/back.xbm .. AddIcon /icons/back.xbm ..
AddIcon /icons/menu.xbm ^^DIRECTORY^^ AddIcon /icons/menu.gif ^^DIRECTORY^^
AddIcon /icons/blank.xbm ^^BLANKICON^^ AddIcon /icons/blank.xbm ^^BLANKICON^^
# DefaultIcon is which icon to show for files which do not have an icon # DefaultIcon is which icon to show for files which do not have an icon
@ -62,14 +97,18 @@ ReadmeName README
HeaderName HEADER HeaderName HEADER
# IndexIgnore is a set of filenames which directory indexing should ignore # IndexIgnore is a set of filenames which directory indexing should ignore
# This doesn't use full regexp syntax, perhaps it should . . .
# Format: IndexIgnore name1 name2... # Format: IndexIgnore name1 name2...
IndexIgnore */.??* *~ *# */HEADER* */README* IndexIgnore */.??* *~ *# */HEADER* */README*
# AccessFileName: The name of the file to look for in each directory #===========================================================================
# for access control information. # Content Type and Mime Configuration
#---------------------------------------------------------------------------
AccessFileName .htaccess # Although NCSA HTTPd doesn't fully support the content-negotiation that
# exists in HTTP/1.1, it does attempt to correctly identify different
# encodings and types of files it serves. The following options specify
# how it does this
# DefaultType is the default MIME type for documents which the server # DefaultType is the default MIME type for documents which the server
# cannot find the type of from filename extensions. # cannot find the type of from filename extensions.
@ -83,31 +122,30 @@ 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
# Redirect allows you to tell clients about documents which used to exist in # The following are known to the server as "Magic Mime Types" They allow
# your server's namespace, but do not anymore. This allows you to tell the # you to change how the server perceives a document by the extension
# clients where to look for the relocated document. # The server currently recognizes the following mime types for server side
# Format: Redirect fakename url # includes, internal imagemap, and CGI anywhere. Uncomment them to use them.
# Note: If you disallow (in access.conf) Options Includes ExecCGI, and you
# uncomment the following, the files will be passed with the magic mime type
# Aliases: Add here as many aliases as you need, up to 20. The format is # as the content type, which causes most browsers to attempt to save the
# Alias fakename realname # file to disk.
Alias /icons/ /usr/local/etc/httpd/icons/
# ScriptAlias: This controls which directories contain server scripts.
# Format: ScriptAlias fakename realname
ScriptAlias /cgi-bin/ /usr/local/etc/httpd/cgi-bin/
# If you want to use server side includes, or CGI outside
# ScriptAliased directories, uncomment the following lines.
#AddType text/x-server-parsed-html .shtml #AddType text/x-server-parsed-html .shtml
#AddType text/x-imagemap .map
#AddType application/x-httpd-cgi .cgi #AddType application/x-httpd-cgi .cgi
#===========================================================================
# Misc Server Resources
#---------------------------------------------------------------------------
# AccessFileName: The name of the file to look for in each directory
# for access control information and directory specific configuration
AccessFileName .htaccess
# If you want to have files/scripts sent instead of the built-in version # If you want to have files/scripts sent instead of the built-in version
# in case of errors, uncomment the following lines and set them as you # in case of errors, uncomment the following lines and set them as you
# will. Note: scripts must be able to be run as if the were called # will. Note: scripts must be able to be run as if the were called

BIN
icons/ball.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 B

BIN
icons/binary.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 B

BIN
icons/blue_ball.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 B

BIN
icons/ftp.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 B

BIN
icons/green_ball.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 B

BIN
icons/image.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 B

BIN
icons/index.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 B

BIN
icons/menu.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 B

BIN
icons/movie.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 B

BIN
icons/red_ball.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 B

BIN
icons/sound.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 B

BIN
icons/telnet.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 B

BIN
icons/text.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 B

View File

@ -1,9 +1,9 @@
#define gopher_text_width 20 #define text_width 20
#define gopher_text_height 23 #define text_height 23
static char gopher_text_bits[] = { static unsigned char text_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x3f, 0x00, 0x01, 0x60, 0x00, 0x01, 0xa0, 0x00, 0xf9, 0x27, 0x01, 0xff, 0x3f, 0x00, 0x01, 0x60, 0x00, 0x01, 0xa0, 0x00, 0x01, 0x20, 0x01,
0x01, 0x20, 0x02, 0xf1, 0xe7, 0x07, 0x01, 0xc0, 0x0f, 0xf9, 0x07, 0x0c, 0x01, 0x20, 0x02, 0x01, 0xe0, 0x07, 0x01, 0xc0, 0x0f, 0x01, 0x00, 0x0c,
0x01, 0x00, 0x0c, 0xe1, 0x07, 0x0c, 0x01, 0x00, 0x0c, 0xf9, 0x07, 0x0c, 0x7d, 0xf9, 0x0d, 0x11, 0x49, 0x0c, 0x11, 0x46, 0x0c, 0x11, 0x46, 0x0c,
0x01, 0x00, 0x0c, 0xe1, 0x07, 0x0c, 0x01, 0x00, 0x0c, 0xf9, 0x07, 0x0c, 0x11, 0x49, 0x0c, 0x11, 0x49, 0x0c, 0x01, 0x00, 0x0c, 0x01, 0x00, 0x0c,
0x01, 0x00, 0x0c, 0xff, 0xff, 0x0f, 0xfe, 0xff, 0x0f}; 0x01, 0x00, 0x0c, 0xff, 0xff, 0x0f, 0xfe, 0xff, 0x0f, };

BIN
icons/unknown.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 B

37
src/FEATURE_REQUESTS Normal file
View 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
View 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
View 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

View File

@ -1,42 +1,83 @@
# Makefile for NCSA's httpd. # 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. Please make sure your gcc is # For Suns or other non-ANSI platforms.
# 2.0 or later, as 1.40 seems to create bad code for the Sun 4.
CC= gcc CC= gcc
#CC = xlc
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.
#
# If you want no reverse hostname resolution, use -DMINIMAL_DNS # Note: As of version 1.5, only security and dbm defines are in the Makefile
# If you want to have more secure hostname resolution at the cost of some # All other defines are in config.h
# performance, use -DMAXIMUM_DNS
# -DPEM_AUTH No longer does anything, as the PEM/PGP hooks have been removed
# pursuant to compliance with U.S. State Department and NSA export rules
# If you want to have the server check the execute bit of an HTML file to
# determine if it is a parsed file, use -DXBITHACK
# If you don't want to use the multiple child architecture, use -DNO_PASS
# 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= -pg -DPROFILE
#CFLAGS= -g -ansi -pedantic -Wall -DAIX_BROKEN_HEADERS
# DIGEST AUTHENTICATION
# #
CFLAGS= -O2 -g # To enable Message Digest Authentication, define the DIGEST_AUTH flag
#CFLAGS= -g -Wall -ansi -pedantic
MD5_CFLAGS = -DDIGEST_AUTH
# KERBEROS
#
# If you want httpd to support Kerberos authentication, set the
# following flags appropriately. You can support Kerberos V4 and/or V5,
# although it's most likely that your realm supports one or the other.
# To enable DES-encryption of HTTP messages via Kerberos key exchange,
# define the KRB-ENCRYPT flag (not supported in Beta1 -- hopefully Beta2).
KRB4_DIR = /xdev/mosaic/libkrb4/sun
KRB4_LIBS = -L$(KRB4_DIR)/lib -lkrb -ldes
KRB4_CFLAGS = -DKRB4 -I$(KRB4_DIR)/include
KRB5_DIR = /xdev/mosaic/libkrb5/sun
KRB5_LIBS = $(KRB5_DIR)/lib/libkrb5.a $(KRB5_DIR)/lib/libcrypto.a $(KRB5_DIR)/util/et/libcom_err.a
KRB5_CFLAGS = -DKRB5 -I$(KRB5_DIR)/include -I$(KRB5_DIR)/include/krb5
# Comment out the following two lines to exclude Kerberos support
#KRB_CFLAGS = $(KRB4_CFLAGS) $(KRB5_CFLAGS) # -DKRB-ENCRYPT
#KRB_LIBS = $(KRB4_LIBS) $(KRB5_LIBS)
# DBM
#
# To enable DBM password/groupfile support, define the DBM_SUPPORT flag
DBM_CFLAGS = -DDBM_SUPPORT
#DBM_LIBS = -lndbm
#DBM_LIBS = -ldbm
#DBM_LIBS = -lgdbm
# For SVR4
#DBM_CFLAGS = -I/usr/include -I/usr/ucbinclude
#DBM_LIBS = -L/usr/ucblib -ldbm -lucb
# Place here any extra libraries you may need to link to. You # Place here any extra libraries you may need to link to. You
# shouldn't have to. # shouldn't have to.
EXTRA_LIBS= EXTRA_LIBS=
# Place here any flags you may need upon linking, such as a flag to
# prevent dynamic linking (if desired)
LFLAGS= # -pg -DPROFILE
# AUX_CFLAGS are system-specific control flags. # AUX_CFLAGS are system-specific control flags.
# NOTE: IF YOU DO NOT CHOOSE ONE OF THESE, EDIT httpd.h AND CHOOSE # NOTE: IF YOU DO NOT CHOOSE ONE OF THESE, EDIT portability.h AND CHOOSE
# SETTINGS FOR THE SYSTEM FLAGS. IF YOU DON'T, BAD THINGS WILL HAPPEN. # SETTINGS FOR THE SYSTEM FLAGS. IF YOU DON'T, BAD THINGS WILL HAPPEN.
# For SunOS 4: Only use uncomment EXTRA_LIBS if you want to circumvent # For SunOS 4: Only use uncomment EXTRA_LIBS if you want to circumvent
# NIS and /etc/hosts file. # NIS and /etc/hosts file.
# AUX_CFLAGS= -DSUNOS4 # AUX_CFLAGS= -DSUNOS4
# EXTRA_LIBS= -lresolv # EXTRA_LIBS= -lresolv
# For Solaris 2. NOTE: Lots of problems have been identified with compiling # For Solaris 2.x
# httpd under Solaris. Use with caution. If you see aberrant behavior with
# httpd under Solaris 2, please mail us.
# 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
@ -46,7 +87,7 @@ EXTRA_LIBS=
# For HP-UX # For HP-UX
# AUX_CFLAGS= -DHPUX # AUX_CFLAGS= -DHPUX
# For AIX3 # For AIX3
# AUX_CFLAGS= -DAIX3 -U__STR__ # AUX_CFLAGS= -DAIX3 -D_ALL_SOURCE # For xlc compiler
# For AIX4 # For AIX4
# AUX_CFLAGS= -DAIX4 # AUX_CFLAGS= -DAIX4
# For Ultrix # For Ultrix
@ -59,18 +100,22 @@ EXTRA_LIBS=
# 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
# 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
# EXTRA_LIBS = -lcrypt # EXTRA_LIBS = -lcrypt
# For FreeBSD 2.0.5
# AUX_CFLAGS= -DFreeBSD
# For A/UX # For A/UX
# AUX_CFLAGS= -DAUX -D_POSIX_SOURCE # AUX_CFLAGS= -DAUX -D_POSIX_SOURCE
# EXTRA_LIBS= -lposix -lbsd -s # EXTRA_LIBS= -lbsd -lposix -s
# DBM_LIBS= -ldbm
# For SCO ODT # For SCO ODT
# libcrypt_i available from sosco.sco.com, files /SLS/lng225b.Z and # libcrypt_i available from sosco.sco.com, files /SLS/lng225b.Z and
# /SLS/lng225b.ltr.Z # /SLS/lng225b.ltr.Z
# AUX_CFLAGS= -DSCO # AUX_CFLAGS= -DSCO
# EXTRA_LIBS= -lPW -lsocket -lmalloc # -lcrypt_i # EXTRA_LIBS= -lPW -lsocket -lmalloc -lcrypt_i
# 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
@ -89,86 +134,157 @@ EXTRA_LIBS=
# For QNX 4.22 # For QNX 4.22
# AUX_CFLAGS= -Osax -g1 -fi=unix.h -w4 -zc -5 # AUX_CFLAGS= -Osax -g1 -fi=unix.h -w4 -zc -5
# EXTRA_LIBS= -N 250k # EXTRA_LIBS= -N 250k
# For ConvexOS 10.1 with Convex C Compiler 5.0
# AUX_CFLAGS= -DCONVEXOS -D__STDC__
# -------------------------------------------------------------------------
# -------------- You shouldn't have to edit anything else -----------------
# -------------------------------------------------------------------------
SEC_CFLAGS = $(MD5_CFLAGS) $(KRB_CFLAGS)
SEC_LIBS = $(KRB_LIBS)
ALL_CFLAGS = $(CFLAGS) $(AUX_CFLAGS) $(SEC_CFLAGS) $(DBM_CFLAGS)
ALL_LIBS = $(EXTRA_LIBS) $(SEC_LIBS) $(DBM_LIBS)
# Place here any flags you may need upon linking, such as a flag to OBJS=httpd.o http_config.o http_request.o util.o http_dir.o \
# prevent dynamic linking (if desired)
LFLAGS=
# You shouldn't have to edit anything else.
OBJS=http_config.o httpd.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_get.o http_post.o http_script.o http_include.o rfc931.o \ http_send.o cgi.o http_include.o rfc931.o imagemap.o \
http_put.o http_delete.o http_ipc.o http_ipc.o digest.o md5.o md5c.o env.o host_config.o fdwrap.o \
open_logfile.o allocate.o debug.o blackout.o
.c.o: .c.o: Makefile config.h portability.h constants.h
$(CC) -c $(CFLAGS) $(AUX_CFLAGS) $< $(CC) -c $(ALL_CFLAGS) $<
all: httpd all: httpd
aux:
make tar AUX_CFLAGS="-DAUX -D_POSIX_SOURCE" CC=gcc \
CFLAGS="-O2" EXTRA_LIBS="-lposix -lbsd -s"
aix3: aix3:
make tar AUX_CFLAGS=-DAIX3 CC=gcc CFLAGS=-O2 make tar AUX_CFLAGS=-DAIX3 CC=gcc CFLAGS=-O2
aix4: aix4:
make tar AUX_CFLAGS=-DAIX4 CC=gcc CFLAGS=-O2 make tar AUX_CFLAGS=-DAIX4 CC=gcc
sunos: aux:
make tar AUX_CFLAGS=-DSUNOS4 CC=gcc CFLAGS=-O make tar AUX_CFLAGS="-DAUX -D_POSIX_SOURCE" CC="gcc" \
CFLAGS="-O2" EXTRA_LIBS="-lposix -lbsd -s" DBM_LIBS="-ldbm"
solaris:
make tar AUX_CFLAGS=-DSOLARIS2 EXTRA_LIBS="-lsocket -lnsl" CC=gcc CFLAGS=-O
hp-gcc: hp-gcc:
make tar AUX_CFLAGS=-DHPUX CC=gcc CFLAGS=-O2 make tar AUX_CFLAGS=-DHPUX CC=gcc CFLAGS=-O2 DBM_LIBS=-lndbm
hp-cc: hp-cc:
make tar AUX_CFLAGS=-DHPUX CC=cc CFLAGS="-O -Aa" make tar AUX_CFLAGS=-DHPUX CC=cc CFLAGS="-O -Aa" DBM_LIBS=-lndbm
sgi: linux:
make tar AUX_CFLAGS=-DIRIX EXTRA_LIBS=-lsun CC=cc CFLAGS=-O2 make tar AUX_CFLAGS=-DLINUX CC=gcc CFLAGS=-O2 DBM_LIBS=-lgdbm
decmips:
make tar AUX_CFLAGS=-DULTRIX CC=cc CFLAGS=-O2
decaxp:
make tar AUX_CFLAGS=-DOSF1 CC=cc CFLAGS=-O2
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
linux: next:
make tar AUX_CFLAGS=-DLINUX CC=gcc CFLAGS=-O2 make tar AUX_CFLAGS=-DNeXT CC=cc CFLAGS=-O2 DBM_LIBS=-ldbm
qnx: osf1:
make tar AUX_CFLAGS="-Osax -g1 -w4 -zc -fi=unix.h" EXTRA_LIBS="-N 250k" CC=cc make tar AUX_CFLAGS=-DOSF1 CC=cc CFLAGS="-O2 -Olimit 750"
sgi:
make tar AUX_CFLAGS=-DIRIX EXTRA_LIBS=-lsun CC=cc CFLAGS=-O2
solaris:
make tar AUX_CFLAGS=-DSOLARIS2 EXTRA_LIBS="-lsocket -lnsl" CC=gcc CFLAGS=-O
sunos:
make tar AUX_CFLAGS=-DSUNOS4 CC=gcc
svr4: svr4:
make tar AUX_CFLAGS=-DSVR4 EXTRA_LIBS="-lsocket -lnsl" CC=cc CFLAGS=-O2 make tar AUX_CFLAGS=-DSVR4 EXTRA_LIBS="-lsocket -lnsl -lc" CC=cc \
CFLAGS=-O2 DBM_LIBS="-L/usr/ucblib -ldbm -lucb" \
DBM_CFLAGS="-I/usr/include -I/usr/ucbinclude"
ultrix:
make tar AUX_CFLAGS=-DULTRIX CC=gcc CFLAGS=-O2
httpd: $(OBJS) httpd: $(OBJS)
$(CC) $(LFLAGS) -o httpd $(OBJS) $(EXTRA_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 \ $(CC) $(LFLAGS) -o httpd $(OBJS) $(ALL_LIBS)
$(CC) $(LFLAGS) -o httpd $(OBJS) $(EXTRA_LIBS)
quantify: $(OBJS)
$(QUANTIFY) -record-child-process-data=yes \
-record-data=no \
-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) $(CC) $(LFLAGS) -o ../httpd $(OBJS) $(ALL_LIBS)
rm -f $(OBJS)
http_ipc.o: Makefile httpd.h new.h
httpd.o: Makefile httpd.h new.h
http_log.o: Makefile httpd.h new.h
http_script.o: Makefile httpd.h new.h
$(OBJS): Makefile httpd.h http_access.o: Makefile config.h portability.h constants.h http_access.h \
http_request.h http_config.h http_auth.h http_mime.h \
util.h
http_alias.o: config.h portability.h constants.h http_alias.h \
http_config.h util.h http_log.h
http_auth.o: Makefile config.h portability.h constants.h http_auth.h \
http_mime.h http_access.h http_config.h digest.h http_log.h \
util.h
http_config.o: Makefile config.h portability.h constants.h http_config.h \
http_mime.h http_access.h host_config.h http_alias.h \
http_log.h http_dir.h util.h
host_config.o: Makefile config.h portability.h constants.h host_config.h \
http_log.h util.h
http_dir.o: config.h portability.h constants.h http_dir.h \
http_mime.h http_log.h http_config.h http_request.h \
http_alias.h util.h
http_send.o: config.h portability.h constants.h http_send.h \
cgi.h http_mime.h http_log.h http_request.h \
http_config.h http_include.h http_alias.h http_access.h util.h
http_include.o: config.h portability.h constants.h http_include.h \
util.h http_mime.h http_log.h http_config.h http_request.h \
cgi.h http_access.h http_alias.h http_dir.h env.h
http_ipc.o: config.h portability.h constants.h http_ipc.h
http_log.o: config.h portability.h constants.h http_log.h \
http_request.h http_config.h http_auth.h http_mime.h util.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_request.o: Makefile config.h portability.h constants.h http_request.h \
allocate.h cgi.h env.h http_access.h http_alias.h \
host_config.h http_config.h http_log.h http_send.h util.h
imagemap.o: Makefile constants.h imagemap.h allocate.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_auth.h http_alias.h http_config.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_dir.h http_access.h util.h http_ipc.h host_config.h \
http_mime.h cgi.h
util.o: config.h portability.h constants.h util.h \
http_request.h http_config.h host_config.h http_log.h
env.o: config.h portability.h constants.h http_log.h env.h
rfc931.o: config.h portability.h
open_logfile.o: config.h portability.h constants.h open_logfile.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
fdwrap.o: config.h portability.h constants.h fdwrap.h
# for digest authentication
digest.o: Makefile config.h portability.h constants.h digest.h \
http_request.h http_log.h http_auth.h http_mime.h util.h
md5.o: Makefile config.h portability.h global.h md5.h
md5c.o: Makefile config.h portability.h global.h md5.h
clean: clean:
rm -f httpd $(OBJS) *pure* rm -f httpd $(OBJS) *pure* TAGS tags
SRC = $(OBJS:%.o=%.c)
codecenter:
#setopt ansi
#setopt print_string 128
#setopt load_flags $(ALL_FLAGS)
#load $(LFLAGS) $(SRC) $(ALL_LIBS)

267
src/allocate.c Normal file
View 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
View 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
View 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>";
static 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
View 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 */

724
src/cgi.c Normal file
View File

@ -0,0 +1,724 @@
/************************************************************************
* 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
*
************************************************************************
*
* cgi.c,v 1.44 1996/04/05 18:54:31 blong Exp
*
************************************************************************
*
* 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 "portability.h"
#include <stdio.h>
#ifndef NO_STDLIB_H
# include <stdlib.h>
#endif /* NO_STDLIB_H */
#include <ctype.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 <errno.h>
#include <sys/stat.h>
#include <signal.h>
#include <sys/wait.h>
#include "constants.h"
#include "fdwrap.h"
#include "allocate.h"
#include "cgi.h"
#include "env.h"
#include "http_access.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"
int pid;
#ifdef KRB4
# include <krb.h>
extern AUTH_DAT kerb_kdata;
# include <string.h>
#endif /* KRB4 */
void kill_children(per_request *reqInfo) {
char errstr[MAX_STRING_LEN];
sprintf(errstr,"killing CGI process %d",pid);
log_error(errstr,reqInfo->hostInfo->error_log);
kill(pid,SIGTERM);
sleep(3); /* give them time to clean up */
kill(pid,SIGKILL);
waitpid(pid,NULL,0);
}
char **create_argv(per_request *reqInfo,char *av0) {
register int x,n;
char **av;
char *str1,*str2;
str1 = newString(HUGE_STRING_LEN,STR_TMP);
str2 = newString(HUGE_STRING_LEN,STR_TMP);
for(x=0,n=2;reqInfo->args[x];x++)
if(reqInfo->args[x] == '+') ++n;
if(!(av = (char **)malloc((n+1)*sizeof(char *)))) {
freeString(str1);
freeString(str2);
die(reqInfo,SC_NO_MEMORY,"create_argv");
}
av[0] = av0;
strcpy(str2,reqInfo->args);
for(x=1;x<n;x++) {
getword(str1,str2,'+');
unescape_url(str1);
escape_shell_cmd(str1);
if(!(av[x] = strdup(str1))) {
freeString(str1);
freeString(str2);
die(reqInfo,SC_NO_MEMORY,"create_argv");
}
}
av[n] = NULL;
freeString(str1);
freeString(str2);
return av;
}
void get_path_info(per_request *reqInfo, struct stat *finfo)
{
register int x,max;
char *str;
str = newString(HUGE_STRING_LEN,STR_TMP);
max=count_dirs(reqInfo->filename);
for(x=dirs_in_alias;x<=max;x++) {
make_dirstr(reqInfo->filename,x+1,str);
if(!(stat(str,finfo))) {
if(S_ISREG(finfo->st_mode)) {
int l=strlen(str);
strcpy(reqInfo->path_info,&(reqInfo->filename[l]));
reqInfo->filename[l] = '\0';
reqInfo->url[strlen(reqInfo->url) - strlen(reqInfo->path_info)] = '\0';
freeString(str);
return;
}
}
}
for(x=dirs_in_alias - 1; (x > 0) ;--x) {
make_dirstr(reqInfo->filename,x+1,str);
if(!(stat(str,finfo))) {
if(S_ISREG(finfo->st_mode)) {
strcpy(reqInfo->path_info,&(reqInfo->filename[strlen(str)]));
strcpy(reqInfo->filename,str);
reqInfo->url[strlen(reqInfo->url) - strlen(reqInfo->path_info)] = '\0';
freeString(str);
return;
}
}
}
log_reason(reqInfo,"script does not exist",reqInfo->filename);
freeString(str);
die(reqInfo,SC_NOT_FOUND,reqInfo->url);
}
int add_cgi_vars(per_request *reqInfo, int *content)
{
char *str;
str = newString(HUGE_STRING_LEN,STR_TMP);
make_env_str(reqInfo,"GATEWAY_INTERFACE","CGI/1.1");
make_env_str(reqInfo,"SERVER_PROTOCOL",
protocals[reqInfo->http_version]);
make_env_str(reqInfo, "REQUEST_METHOD",
methods[reqInfo->method]);
make_env_str(reqInfo,"SCRIPT_NAME",reqInfo->url);
if(reqInfo->path_info[0]) {
make_env_str(reqInfo,"PATH_INFO",reqInfo->path_info);
translate_name(reqInfo,reqInfo->path_info,str);
make_env_str(reqInfo,"PATH_TRANSLATED",str);
}
make_env_str(reqInfo,"QUERY_STRING",reqInfo->args);
if(content) {
*content=0;
if ((reqInfo->method == M_POST) || (reqInfo->method == M_PUT)) {
*content=1;
sprintf(str,"%d",reqInfo->inh_content_length);
make_env_str(reqInfo,"CONTENT_TYPE",reqInfo->inh_content_type);
make_env_str(reqInfo,"CONTENT_LENGTH",str);
}
}
freeString(str);
return TRUE;
}
int add_common_vars(per_request *reqInfo) {
char *env_path,*env_tz;
char *str;
str = newString(HUGE_STRING_LEN,STR_TMP);
if(!(env_path = getenv("PATH")))
env_path=DEFAULT_PATH;
make_env_str(reqInfo,"PATH",env_path);
if((env_tz = getenv("TZ")))
make_env_str(reqInfo,"TZ",env_tz);
make_env_str(reqInfo,"SERVER_SOFTWARE",SERVER_VERSION);
make_env_str(reqInfo,"SERVER_NAME",reqInfo->hostInfo->server_hostname);
make_env_str(reqInfo,"SERVER_ADMIN",reqInfo->hostInfo->server_admin);
sprintf(str,"%d",port);
make_env_str(reqInfo,"SERVER_PORT",str);
make_env_str(reqInfo,"REMOTE_HOST",reqInfo->remote_name);
make_env_str(reqInfo,"REMOTE_ADDR",reqInfo->remote_ip);
make_env_str(reqInfo,"DOCUMENT_ROOT",reqInfo->hostInfo->document_root);
if(reqInfo->auth_user[0])
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])
make_env_str(reqInfo,"ANNOTATION_SERVER",
reqInfo->hostInfo->annotation_server);
if (reqInfo->auth_type[0]) {
#ifdef KRB4
if(strncmp(reqInfo->auth_type, "kerberos", 8) == 0) {
make_env_str(reqInfo,"AUTH_TYPE","KERB4_MUTUAL");
make_env_str(reqInfo,"KERB4_USER",kerb_kdata.pname);
make_env_str(reqInfo,"KERB4_INSTANCE",kerb_kdata.pinst);
make_env_str(reqInfo,"KERB4_REALM",kerb_kdata.prealm);
sprintf (str, "%s.%s@%s", kerb_kdata.pname,
kerb_kdata.pinst, kerb_kdata.prealm);
make_env_str(reqInfo,"KERB4_PRINCIPAL",str);
} else
#endif /* KRB4 */
make_env_str(reqInfo,"AUTH_TYPE",reqInfo->auth_type);
}
if(do_rfc931 && remote_logname)
make_env_str(reqInfo,"REMOTE_IDENT",remote_logname);
if (ErrorStat) {
if (failed_request[0])
make_env_str(reqInfo,"REDIRECT_REQUEST",failed_request);
if (failed_url[0])
make_env_str(reqInfo,"REDIRECT_URL",failed_url);
make_env_str(reqInfo,"REDIRECT_STATUS",set_stat_line(reqInfo));
}
freeString(str);
return TRUE;
}
int scan_cgi_header(per_request *reqInfo, int pd)
{
char *l;
int p;
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
header */
keep_alive.bKeepAlive = 0;
reqInfo->cgi_buf = new_sock_buf(reqInfo,pd);
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 */
if(str[0] == '\0') {
if (reqInfo->outh_content_type[0] == '\0') {
if (reqInfo->outh_location[0] != '\0') {
strcpy(reqInfo->outh_content_type,"text/html");
} else {
if (local_default_type[0] != '\0')
strcpy(reqInfo->outh_content_type,local_default_type);
else strcpy(reqInfo->outh_content_type,
reqInfo->hostInfo->default_type);
}
}
freeString(str);
return 0;
}
if(!(l = strchr(str,':')))
l = str;
*l++ = '\0';
if(!strcasecmp(str,"Content-type")) {
/* Thanks Netscape for showing this bug to everyone */
/* delete trailing whitespace, esp. for "server push" */
char *endp = l + strlen(l) - 1;
while ((endp > l) && isspace(*endp)) *endp-- = '\0';
sscanf(l,"%s",reqInfo->outh_content_type);
}
else if(!strcasecmp(str,"Location")) {
/* If we don't already have a status line, make one */
if (!reqInfo->status_line) {
reqInfo->status = SC_REDIRECT_TEMP;
set_stat_line(reqInfo);
}
sscanf(l,"%s",reqInfo->outh_location);
}
else if(!strcasecmp(str,"Status")) {
for(p=0;isspace(l[p]);p++);
sscanf(&l[p],"%d",&(reqInfo->status));
if(!(reqInfo->status_line = dupStringP(&l[p],STR_REQ))) {
Close(pd);
freeString(str);
die(reqInfo,SC_NO_MEMORY,"CGI: scan_cgi_header");
}
}
else if(!strcasecmp(str,"Content-length")) {
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 {
*(--l) = ':';
for(p=0;str[p];p++);
str[p] = LF;
str[++p] = '\0';
if(!(reqInfo->outh_cgi)) {
if(!(reqInfo->outh_cgi = strdup(str))) {
Close(pd);
freeString(str);
die(reqInfo,SC_NO_MEMORY,"CGI: scan_cgi_header");
}
}
else {
int loh = strlen(reqInfo->outh_cgi);
reqInfo->outh_cgi = (char *) realloc(reqInfo->outh_cgi,
(loh+strlen(str)+1)*sizeof(char));
if(!(reqInfo->outh_cgi)) {
Close(pd);
freeString(str);
die(reqInfo,SC_NO_MEMORY,"CGI: scan_cgi_header");
}
strcpy(&(reqInfo->outh_cgi[loh]),str);
}
}
}
}
void internal_redirect(per_request *reqInfo)
{
char url[HUGE_STRING_LEN],args[HUGE_STRING_LEN],*argp;
per_request *newInfo;
url[0] = '\0';
args[0] = '\0';
/* Split the location header into URL and args */
strncpy(url,reqInfo->outh_location,HUGE_STRING_LEN);
if((argp = strchr(url,'?'))) {
*argp++ = '\0';
strcpy(args,argp);
}
log_transaction(reqInfo);
/* The global string the_request currently holds the request as
* read off the socket, and is used to log the information. We force
* 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);
}
int cgi_stub(per_request *reqInfo, struct stat *finfo, int allow_options)
{
int p[2], p2[2]; /* p = script-> server, p2 = server -> script */
int content, nph;
char *argv0;
char errlog[100];
FILE *fp = NULL;
if(!can_exec(finfo)) {
log_reason(reqInfo,
"client denied by server configuration (CGI non-executable)",
reqInfo->filename);
die(reqInfo,SC_FORBIDDEN,reqInfo->url);
}
if((argv0 = strrchr(reqInfo->filename,'/')) != NULL)
argv0++;
else argv0 = reqInfo->filename;
chdir_file(reqInfo->filename);
if(Pipe(p) < 0)
die(reqInfo,SC_SERVER_ERROR,"HTTPd/CGI: could not create IPC pipe");
if(Pipe(p2) < 0) {
Close(p[0]);
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';
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;
}
reqInfo->outh_content_length = -1;
/* 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],NULL) && 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;
}
/*
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_fd(per_request *reqInfo, int pd, void (*onexit)(void))
{
char *buf;
register int n,w,o;
int fd;
buf = newString(IOBUFSIZE,STR_TMP);
signal(SIGALRM,send_fd_timed_out);
signal(SIGPIPE,send_fd_timed_out);
/* Flush stdio pipe, since scripts now use non buffered i/o */
rflush(reqInfo);
fd = fileno(reqInfo->out);
alarm(timeout);
if (reqInfo->cgi_buf != NULL)
n=getline(reqInfo->cgi_buf, buf,IOBUFSIZE,G_FLUSH,timeout);
else
n = 0;
while (1) {
o=0;
while(n) {
w = write(fd, buf + o,n);
if (w < 1) {
if (errno != EINTR) break;
}
n-=w;
o+=w;
reqInfo->bytes_sent += w;
}
if((n=read(pd, buf,IOBUFSIZE)) < 1) {
if (n == -1 && errno == EINTR) {
n = 0;
continue;
}
break;
}
}
alarm(0);
signal(SIGALRM,SIG_IGN);
signal(SIGPIPE,SIG_IGN);
freeString(buf);
return reqInfo->bytes_sent;
}
/* Called for ScriptAliased directories */
void exec_cgi_script(per_request *reqInfo) {
struct stat finfo;
int stub_returns;
int allow;
char allow_options;
get_path_info(reqInfo,&finfo);
evaluate_access(reqInfo,&finfo,&allow,&allow_options);
if(!allow) {
log_reason(reqInfo,
"client denied by server configuration (CGI)",reqInfo->filename);
/* unmunge_name(reqInfo,reqInfo->filename); */
die(reqInfo,SC_FORBIDDEN,reqInfo->url);
}
add_common_vars(reqInfo);
reqInfo->bytes_sent = 0;
stub_returns = cgi_stub(reqInfo,&finfo,allow_options);
switch (stub_returns) {
case SC_REDIRECT_TEMP:
die(reqInfo,SC_REDIRECT_TEMP,reqInfo->outh_location);
break;
case SC_REDIRECT_LOCAL:
break;
default:
log_transaction(reqInfo);
break;
}
}
/* Almost exactly equalivalent to exec_cgi_script, but this one
gets all of the path info passed to it, instead of calling get_path_info
and also gets the allow information passed to it instead of calling
evaluate_access
*/
void send_cgi(per_request *reqInfo,struct stat *finfo, char allow_options)
{
int stub_returns;
if (!(allow_options & OPT_EXECCGI)) {
log_reason(reqInfo,"client denied by server configuration (CGI)",
reqInfo->filename);
die(reqInfo,SC_FORBIDDEN,reqInfo->url);
}
add_common_vars(reqInfo);
reqInfo->bytes_sent = 0;
stub_returns = cgi_stub(reqInfo,finfo,allow_options);
switch (stub_returns) {
case SC_REDIRECT_TEMP:
die(reqInfo,SC_REDIRECT_TEMP,reqInfo->outh_location);
break;
case SC_REDIRECT_LOCAL:
break;
default:
log_transaction(reqInfo);
break;
}
}

37
src/cgi.h Normal file
View File

@ -0,0 +1,37 @@
/************************************************************************
* 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
*
************************************************************************
*
* cgi.h,v 1.9 1996/04/05 18:54:40 blong Exp
*
************************************************************************
*
*
*/
#ifndef _HTTP_SCRIPT_H_
#define _HTTP_SCRIPT_H_
#include <sys/stat.h>
/* function prototypes */
void exec_cgi_script(per_request *reqInfo);
int cgi_stub(per_request *reqInfo, struct stat *finfo, int allow_options);
int add_common_vars(per_request *reqInfo);
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_nph_script(per_request *reqInfo, int pd, void (*onexit)(void));
void send_cgi(per_request *reqInfo,struct stat *finfo, char allow_options);
void internal_redirect(per_request *reqInfo);
#endif /* _HTTP_SCRIPT_H_ */

180
src/config.h Normal file
View File

@ -0,0 +1,180 @@
/************************************************************************
* 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
*
************************************************************************
*
* config.h,v 1.21 1996/03/27 20:43:51 blong Exp
*
************************************************************************
*
* config.h
* Contains user configurable constants and declarations
*
*/
#ifndef _CONFIG_H
#define _CONFIG_H 1
/*************************************************************************/
/* Compile Time Options
*/
/* To enable changing of the process title to the current request being
handled, uncomment the following. Note: Using this will cause a
performance hit (though maybe not much of one). This doesn't work
on all systems, either. It is known to work under AIX3, SunOS, OSF1,
FreeBSD, and NetBSD. */
/* #define SETPROCTITLE */
/* 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
will enable an RPM (requests per minute) indicator in the proc title. */
#ifdef SETPROCTITLE
#define TACHOMETER */
# ifdef TACHOMETER
# define MAX_TACHOMETER 30
# endif
#endif
/* To not compile with built in imagemap support, comment out the following.
Note: It is much faster to use this then the external program, but it
also makes the program size of httpd larger. */
#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
determine if the file should be parsed, uncomment the following.
Using this feature will give better performance for files which
are not parsed without the necessity of using the magic mime type */
/* #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
log files (except the error_log file), uncomment the following. */
/* #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
configuration file to match local address (ie, those without embedded
dots), uncomment the following. */
/* #define LOCALHACK */
/* 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
security information used in Basic Authentication involves sending the
password in clear text across the network on every request which requires
it. */
/* #define NIS_SUPPORT */
/* 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
option to make max_servers a hard limit. */
/* #define RESOURCE_LIMIT */
/* 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
mimic the 1.3 Forking server. This should be defined in the system
specific information in portability.h, and not here. */
/* #define NO_PASS */
/* defines for new muli-child approach
DEFAULT_START_DAEMON defines how many children start at httpd start
DEFAULT_MAX_DAEMON defines how many children can start
*/
#define DEFAULT_START_DAEMON 5
#define DEFAULT_MAX_DAEMON 10
/* defines for debugging purposes
PROFILE to set the server up to profile the code
QUANTIFY is a profiler from Pure software
PURIFY is a memory checker from Pure software
DEBUG compiles in extra debugging code (debug.c, mostly)
*/
/* #define DEBUG */
/* #define PROFILE */
/* #define QUANTIFY */
/* #define PURIFY */
/* SHELL_PATH defines where the shell path is */
#define SHELL_PATH "/bin/sh"
/* DEFAULT_PATH defines the default search PATH handed to CGI scripts
if there isn't one in the environment when HTTPd runs */
#define DEFAULT_PATH "/bin:/usr/bin:/usr/ucb:/usr/bsd:/usr/local/bin:."
/* The following define default values for options which can be over-
ridden at run time via command-line or configuration files */
#define HTTPD_ROOT "/usr/local/etc/httpd"
#define DOCUMENT_LOCATION "/usr/local/etc/httpd/htdoc"
#define DEFAULT_ADMIN "[no address given]"
#define SERVER_CONFIG_FILE "conf/httpd.conf"
#define RESOURCE_CONFIG_FILE "conf/srm.conf"
#define TYPES_CONFIG_FILE "conf/mime.types"
#define ACCESS_CONFIG_FILE "conf/access.conf"
#define DEFAULT_PORT 80
#define DEFAULT_USER "#-1"
#define DEFAULT_GROUP "#-1"
#define DEFAULT_XFERLOG "logs/access_log"
#define DEFAULT_AGENTLOG "logs/agent_log"
#define DEFAULT_REFERERLOG "logs/referer_log"
#define DEFAULT_ERRORLOG "logs/error_log"
#define DEFAULT_PIDLOG "logs/httpd.pid"
#define DEFAULT_REFERERIGNORE ""
#define DEFAULT_INDEX_NAMES "index.html index.shtml index.cgi"
#define DEFAULT_INDEXING 0
#define DEFAULT_TYPE "text/html"
#define DEFAULT_ACCESS_FNAME ".htaccess"
#define DEFAULT_RFC931 0
#define DEFAULT_USER_DIR "public_html"
#define DEFAULT_TIMEOUT 1200
#endif /* _CONFIG_H */

428
src/constants.h Normal file
View File

@ -0,0 +1,428 @@
/************************************************************************
* 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
*
************************************************************************
*
* constants.h,v 1.54 1996/04/05 18:54:42 blong Exp
*
************************************************************************
*
*
* constants.h contains all non-user configurable constants with some
* associated structures
*
* Contains HTTP_TIME_FORMAT
* SERVER_VERSION
* SERVER_PROTOCAL
* errors
* methods
* object types
* security options
* magic mime types
* directory indexing options
* struct KeepAliveData
* struct security_data
*
*/
#ifndef _CONSTANTS_H_
#define _CONSTANTS_H_
#include <stdio.h>
#include <netinet/in.h>
#define TRUE 1
#define FALSE 0
#define MAX_STRING_LEN 256
#define HUGE_STRING_LEN 8192
#define IOBUFSIZE 8192
#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.1"
#define SERVER_SOURCE "NCSA/1.5.1"
#define SERVER_PROTOCOL "HTTP/1.0"
/* Response Codes from HTTP/1.0 Spec
all 4 digit codes are internal only */
#define SC_CONTINUE 100
#define SC_SWITCHING_PROTOCOLS 101
#define SC_DOCUMENT_FOLLOWS 200
#define SC_CREATED 201
#define SC_ACCEPTED 202
#define SC_NON_AUTH_INFO 203
#define SC_NO_CONTENT 204
#define SC_RESET_CONTENT 205
#define SC_PARTIAL_CONTENT 206
#define SC_MULTIPLE_CHOICES 300
#define SC_REDIRECT_PERM 301
#define SC_REDIRECT_TEMP 302
#define SC_REDIRECT_LOCAL 3020
#define SC_SEE_OTHER 303
#define SC_USE_LOCAL_COPY 304
#define SC_USE_PROXY 305
#define SC_BAD_REQUEST 400
#define SC_AUTH_REQUIRED 401
#define SC_PAY_REQUIRED 402
#define SC_FORBIDDEN 403
#define SC_NOT_FOUND 404
#define SC_METHOD_NOT_ALLOWED 405
#define SC_NONE_ACCEPTABLE 406
#define SC_PROXY_AUTH_REQUIRED 407
#define SC_REQUEST_TIMEOUT 408
#define SC_CONFLICT 409
#define SC_GONE 410
#define SC_LENGTH_REQUIRED 411
#define SC_UNLESS_TRUE 412
#define SC_SERVER_ERROR 500
#define SC_NOT_IMPLEMENTED 501
#define SC_BAD_GATEWAY 502
#define SC_SERVICE_UNAVAIL 503
#define SC_GATEWAY_TIMEOUT 504
#define SC_NO_MEMORY 6992
#define SC_CONF_ERROR 6993
#define SC_BAD_IMAGEMAP 6994
#define SC_AUTH_NO_WWW_AUTH 7001
/* Supported Methods - sorta */
#define METHODS 8
#define M_GET 0
#define M_HEAD 1
#define M_POST 2
#define M_PUT 3
#define M_DELETE 4
#define M_SECURE 5
#define M_INVALID -1
/* Unsupported Methods */
#define M_LINK 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 */
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 */
#define A_STD_DOCUMENT 0
#define A_REDIRECT_TEMP 1
#define A_REDIRECT_PERM 2
#define A_SCRIPT_CGI 3
/* Security Options */
#define OPT_NONE 0
#define OPT_INDEXES 1
#define OPT_INCLUDES 2
#define OPT_SYM_LINKS 4
#define OPT_EXECCGI 8
#define OPT_UNSET 16
#define OPT_INCNOEXEC 32
#define OPT_SYM_OWNER 64
#define OPT_ALL (OPT_INDEXES | OPT_INCLUDES | OPT_SYM_LINKS | OPT_EXECCGI)
#define OR_NONE 0
#define OR_LIMIT 1
#define OR_OPTIONS 2
#define OR_FILEINFO 4
#define OR_AUTHCFG 8
#define OR_INDEXES 16
#define OR_REDIRECT 32
#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 */
#define CGI_MAGIC_TYPE "application/x-httpd-cgi"
#define INCLUDES_MAGIC_TYPE "text/x-server-parsed-html"
#define IMAGEMAP_MAGIC_TYPE "text/x-imagemap"
#define BLACKOUT_MAGIC_TYPE "text/x-httpd-black"
/* For directory indexing */
#define BY_PATH 0
#define BY_TYPE 1
#define BY_ENCODING 2
#define FANCY_INDEXING 1
#define LF 10
#define CR 13
#define DENY_THEN_ALLOW 0
#define ALLOW_THEN_DENY 1
#define MUTUAL_FAILURE 2
#define DIE_KEEPALIVE 2 /* used to determine if connection should */
#define DIE_NORMAL 1 /* remain up on return from die function */
#define DEFAULT_ALLOW_KEEPALIVE 0 /* default if off */
#define DEFAULT_KEEPALIVE_MAXREQUESTS 5
#define DEFAULT_KEEPALIVE_TIMEOUT 10 /* 10 sec per-request timeout*/
typedef struct {
int bAllowKeepAlive; /* non-zero if configuration allows,else 0 */
int bKeepAlive; /* non-zero if keep-alive on, else 0 */
int nTimeOut; /* per-request timeout in seconds */
int nMaxRequests; /* max requests per session, 0 for no max */
int nCurrRequests; /* # of requests so far */
} KeepAliveData;
#define MAX_SECURITY 50
#define SATISFY_ALL 0
#define SATISFY_ANY 1
#define AUTHFILETYPE_STANDARD 0
#define AUTHFILETYPE_DBM 1
#define AUTHFILETYPE_NIS 2
#define AUTHFILETYPE_RADIUS 3
typedef struct {
char d[MAX_STRING_LEN];
char opts;
char override;
int order[METHODS];
int bSatisfy; /* 0 = All, 1 = Any */
int num_allow[METHODS];
char *allow[METHODS][MAX_SECURITY];
int num_auth[METHODS];
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_name[MAX_STRING_LEN];
char auth_pwfile[MAX_STRING_LEN];
char auth_grpfile[MAX_STRING_LEN];
int auth_pwfile_type;
int auth_grpfile_type;
#ifdef DIGEST_AUTH
char auth_digestfile[MAX_STRING_LEN];
int auth_digestfile_type;
#endif /* DIGEST_AUTH */
} security_data;
typedef struct _ErrorDoc {
/* int Type; */
int DocErrorNum;
char* DocErrorFile;
} ErrorDoc;
/* DNS Mode - Formerly, this was a compile time option, but it was
limited, and this is the feature bloat version anyways. */
#define DNS_NONE 0
#define DNS_MIN 1
#define DNS_STD 2
#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 -------------------- */
/* These #defines are for keeping track of which options are links to
defaults, and which are real (for clean up in restart, presumeably) */
#define PH_HTTPD_CONF 1
#define PH_SRM_CONF 2
#define PH_PEM_CONF 3
/* Configurate data structure (for what's configurable per host)
#def's from above are used to keep track of what is allocated and
what is just a pointer. */
typedef struct _per_host {
/* httpd.conf */
int httpd_conf;
char *error_fname;
char *xfer_fname;
char *agent_fname;
char *referer_fname;
char *referer_ignore;
char *server_admin;
char *server_hostname;
char *srm_confname;
char *annotation_server;
int dns_mode;
int log_opts;
int files_open;
FILE *error_log;
FILE *agent_log;
FILE *referer_log;
int xfer_log;
int virtualhost;
char *called_hostname;
struct in_addr address_info;
/* srm.conf */
int srm_conf;
char *user_dir;
char *index_names;
char *access_name;
char *document_root;
int doc_root_len;
char *default_type;
char *default_icon;
int num_doc_errors;
ErrorDoc **doc_errors;
struct _lookup *translations;
struct _per_host *next;
} per_host;
/* --------- Per request Data Structure ------------- */
/* Request Flags */
#define DOING_PGP 1
#define DOING_SHTTP 2
#define DOING_SSL 3
typedef struct _per_request {
/* Information about Contents; */
int ownENV;
int ownDNS;
int ownSB;
int RequestFlags;
/* Request Information */
int status;
char *status_line;
long bytes_sent;
/* request stuff to be logged */
int method;
char url[HUGE_STRING_LEN];
char args[HUGE_STRING_LEN];
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];
int dirs_in_alias;
/* Authentication Information */
char auth_user[MAX_STRING_LEN];
char auth_group[MAX_STRING_LEN];
/* authentication files */
char* auth_name;
char* auth_pwfile;
char* auth_grpfile;
int auth_pwfile_type;
int auth_grpfile_type;
#ifdef DIGEST_AUTH
char* auth_digestfile;
int auth_digestfile_type;
#endif /* DIGEST_AUTH */
/* Domain Restriction Info */
int bNotifyDomainRestricted;
int bSatisfiedDomain;
int bSatisfiedReferer;
int dns_host_lookup;
int num_env;
int max_env;
char **env;
int *env_len;
/* Client Information */
char *remote_host;
char *remote_name;
char *remote_ip;
/* char *remote_logname; */
/* Server Information */
int connection_socket;
int in;
FILE *out;
sock_buf *sb;
sock_buf *cgi_buf;
per_host *hostInfo;
struct in_addr address_info;
/* Linked List of requests */
struct _per_request *next;
} per_request;
#endif /* _CONSTANTS_H_ */

83
src/debug.c Normal file
View 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 */

387
src/digest.c Normal file
View File

@ -0,0 +1,387 @@
/************************************************************************
* 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
*
************************************************************************
*
* Modified from source provided by: Eric W. Sink, Spyglass
*
*/
#include "config.h"
#include "portability.h"
#ifdef DIGEST_AUTH
#include <stdio.h>
#ifndef NO_STDLIB_H
# include <stdlib.h>
#endif /* NO_STDLIB_H */
#include <sys/types.h>
#include <sys/time.h>
#include <string.h>
#include <fcntl.h>
#include <ctype.h>
#ifdef DBM_SUPPORT
# ifndef _DBMSUPPORT_H /* moronic OSs which don't protect their own include */
# define _DBMSUPPORT_H /* files from being multiply included */
# include <ndbm.h>
# endif /* _DBMSUPPORT_H */
#endif /* DBM_SUPPORT */
#include "constants.h"
#include "fdwrap.h"
#include "digest.h"
#include "http_request.h"
#include "http_log.h"
#include "http_auth.h"
#include "http_mime.h"
#include "util.h"
int get_digest(per_request *reqInfo, char *user, char *realm, char *digest,
security_data* sec)
{
FILE *f;
char errstr[MAX_STRING_LEN];
char l[MAX_STRING_LEN];
char w[MAX_STRING_LEN];
char r[MAX_STRING_LEN];
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"))) {
sprintf(errstr,"Could not open digest file %s",
reqInfo->auth_digestfile);
die(reqInfo,SC_SERVER_ERROR,errstr);
}
while(!(cfg_getline(l,MAX_STRING_LEN,f))) {
if((l[0] == '#') || (!l[0])) continue;
getword(w,l,':');
getword(r,l,':');
if ((0 == strcmp(user,w)) && (0 == strcmp(realm,r))) {
if (strlen(l) == 32) {
strcpy(digest,l);
FClose(f);
return 1;
}
else {
FClose(f);
sprintf(errstr,
"In digest file %s, digest for %s:%s must be 32 chars",
reqInfo->auth_digestfile,user,realm);
die(reqInfo,SC_SERVER_ERROR,errstr);
}
}
}
FClose(f);
return 0;
}
#ifdef DBM_SUPPORT
else if (reqInfo->auth_digestfile_type == AUTHFILETYPE_DBM) {
DBM* db;
datum dtKey, dtRec;
char szBuf[2*MAX_STRING_LEN];
if(!(db = DBM_Open(reqInfo->auth_digestfile, O_RDONLY, 0))) {
sprintf(errstr,"Could not open user file %s",reqInfo->auth_digestfile);
die(reqInfo,SC_SERVER_ERROR,errstr);
}
sprintf (szBuf, "%s:%s", user, realm);
dtKey.dptr = szBuf;
dtKey.dsize = strlen(szBuf);
dtRec = dbm_fetch(db, dtKey);
DBM_Close(db);
if (dtRec.dptr) {
strncpy(digest, dtRec.dptr, dtRec.dsize);
digest[dtRec.dsize] = '\0';
return 1;
}
else
return 0;
}
#endif /* DBM_SUPPORT */
#ifdef NIS_SUPPORT
else if (reqInfo->auth_pwfile_type == AUTHFILETYPE_NIS) {
char *domain,
*digest,
*resptr,
szBuf[2*MAX_STRING_LEN];
int yperr,
resize;
if (init_nis(&domain) != 0)
return 0;
if (strcmp(reqInfo->auth_digestfile, "+"))
digest = reqInfo->auth_digestfile;
else
digest = "digest";
(void) sprintf(szBuf, "%s:%s", user, realm);
yperr = yp_match(domain, digest, szBuf, strlen(szBuf), &resptr, &resize);
if (yperr == 0) {
getword(w, resptr, ':');
getword(r, resptr, ':');
if (strcmp(w, user) == 0 && strcmp(w, realm) == 0) {
getword(w, resptr, ':');
(void) strcpy(digest, w);
return 1;
}
}
return 0;
}
#endif /* NIS_SUPPORT */
else
die(reqInfo,SC_SERVER_ERROR,"Invalid password file type");
return 0;
}
void Digest_Construct401(per_request *reqInfo, char *s, int stale, char* auth_name)
{
char timestamp[32];
char h_opaque[33];
char opaque[MAX_STRING_LEN];
/*
Note that the domain field isn't being sent at all. If
it were to be sent, it would probably need to be read
from the config files.
We're using timestamps as our nonce value.
*/
/*
Grab the timestamp (for the nonce). Also, then construct
the opaque value.
*/
sprintf(timestamp, "%d", time(NULL));
sprintf(opaque, "%s:%s:%s", auth_name, timestamp, reqInfo->remote_ip);
md5(opaque, h_opaque);
if (stale)
{
sprintf(s, "Digest realm=\"%s\" nonce=\"%s\" opaque=\"%s\" stale=TRUE",
auth_name, timestamp, h_opaque);
}
else
{
sprintf(s, "Digest realm=\"%s\" nonce=\"%s\" opaque=\"%s\"",
auth_name, timestamp, h_opaque);
}
}
void Digest_Check(per_request *reqInfo, char *user, security_data* sec)
{
char username[MAX_STRING_LEN];
char realm[MAX_STRING_LEN];
char nonce[MAX_STRING_LEN];
char uri[MAX_STRING_LEN];
char response[32 + 1];
char opaque[MAX_STRING_LEN];
char errstr[MAX_STRING_LEN];
char *p;
char *q;
time_t time_now;
time_t time_nonce;
/* user[0]; */ /* assume that we won't succeed */
username[0] = 0;
realm[0] = 0;
nonce[0] = 0;
uri[0] = 0;
response[0] = 0;
opaque[0] = 0;
p = q = NULL;
p = reqInfo->inh_auth_line;
while (isspace(*p)) {
p++;
}
if (!strncmp(p, reqInfo->auth_name, strlen(reqInfo->auth_name))) {
Digest_Construct401(reqInfo,errstr,1,reqInfo->auth_name);
die(reqInfo,SC_AUTH_REQUIRED,errstr);
return;
}
while (!isspace(*p)) {
p++;
}
p++;
/* p now points to the first keyword-value pair */
while (*p) {
if (!strncmp(p, "username=", 9)) {
/* skip to the quoted value */
p = strchr(p, '"');
p++;
q = username;
while (*p != '"') {
*q++ = *p++;
}
*q = 0;
}
else if (!strncmp(p, "realm=", 6)) {
/* skip to the quoted value */
p = strchr(p, '"');
p++;
q = realm;
while (*p != '"') {
*q++ = *p++;
}
*q = 0;
}
else if (!strncmp(p, "nonce=", 6)) {
/* skip to the quoted value */
p = strchr(p, '"');
p++;
q = nonce;
while (*p != '"') {
*q++ = *p++;
}
*q = 0;
}
else if (!strncmp(p, "uri=", 4)) {
/* skip to the quoted value */
p = strchr(p, '"');
p++;
q = uri;
while (*p != '"') {
*q++ = *p++;
}
*q = 0;
}
else if (!strncmp(p, "response=", 9)) {
/* skip to the quoted value */
p = strchr(p, '"');
p++;
q = response;
while (*p != '"') {
*q++ = *p++;
}
*q = 0;
}
else if (!strncmp(p, "opaque=", 7)) {
/* skip to the quoted value */
p = strchr(p, '"');
p++;
q = opaque;
while (*p && *p != '"') {
*q++ = *p++;
}
*q = 0;
}
/*
Skip to the next keyword value pair, or the end
*/
while (*p && (*p != ',')) {
p++;
}
if (*p == ',') {
while (!isalpha(*p)) {
p++;
}
}
}
{
char h_a1[32 + 1];
char a2[MAX_STRING_LEN];
char h_a2[32 + 1];
char all[MAX_STRING_LEN];
char h_all[32 + 1];
/*
First, check to make sure the nonce is not stale
*/
time_nonce = atoi(nonce);
time_now = time(NULL);
if ((time_nonce > time_now) ||
(time_nonce < (time_now - DIGEST_NONCE_WINDOW))) {
/* the nonce is stale */
Digest_Construct401(reqInfo,errstr,1,reqInfo->auth_name);
die(reqInfo,SC_AUTH_REQUIRED,errstr);
return;
}
/*
Check to make sure that the opaque string is valid.
*/
{
char h_opaque[33];
char check_opaque[MAX_STRING_LEN];
sprintf(check_opaque, "%s:%s:%s", realm, nonce,
reqInfo->remote_ip);
md5(check_opaque, h_opaque);
if (0 != strcmp(h_opaque, opaque)) {
Digest_Construct401(reqInfo,errstr,1,reqInfo->auth_name);
die(reqInfo,SC_AUTH_REQUIRED,errstr);
return;
}
}
/*
Here we should check to make sure that the URI
given is valid, but a simple strcmp may not be reliable.
*/
#if 0
if (0 != strcmp(reqInfo->url, uri)) {
Digest_Construct401(reqInfo,errstr,1,reqInfo->auth_name);
die(reqInfo,SC_AUTH_REQUIRED,errstr);
return;
}
#endif /* 0 */
/*
Now, check to make sure that the MD5 digest given
is correct.
*/
if (!get_digest(reqInfo,username, realm, h_a1, sec)) {
sprintf(errstr,"user:realm %s:%s not found",user,realm);
auth_bong(reqInfo,errstr,reqInfo->auth_name,sec->auth_type);
}
sprintf(a2, "%s:%s", methods[reqInfo->method], uri);
md5(a2, h_a2);
sprintf(all, "%s:%s:%s", h_a1, nonce, h_a2);
md5(all, h_all);
if (0 == strcmp(h_all, response)) {
strcpy(user, username);
}
else {
Digest_Construct401(reqInfo,errstr,1,reqInfo->auth_name);
die(reqInfo,SC_AUTH_REQUIRED,errstr);
return;
}
}
}
#endif /* DIGEST_AUTH */

23
src/digest.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef DIGEST_H
#define DIGEST_H
/*
The DIGEST_NONCE_WINDOW defines the amount of time, in seconds, which
a nonce is considered to be valid.
*/
#define DIGEST_NONCE_WINDOW (15*60)
/* function prototypes for functions implemented in this module */
int get_digest(per_request *reqInfo, char *user, char *realm, char *digest,
security_data* sec);
void Digest_Construct401(per_request *reqInfo, char *s, int stale,
char* auth_name);
void Digest_Check(per_request *reqInfo, char *user, security_data* sec);
#endif /* !DIGEST_H */

175
src/env.c Normal file
View File

@ -0,0 +1,175 @@
/************************************************************************
* 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
*
************************************************************************
*
*env.c,v 1.20 1996/04/05 18:54:44 blong Exp
*
************************************************************************
*
* env.c contains:
* All functions for dealing with the environment array.
*
*/
#include "config.h"
#include "portability.h"
#ifndef NO_STDLIB_H
# include <stdlib.h>
#endif /* NO_STDLIB_H */
#include <string.h>
#include "constants.h"
#include "env.h"
#include "http_request.h"
#include "http_log.h"
#include "allocate.h"
/* Older version, required external help. Newer version should be self
* 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
if found. Returns TRUE if the replace took place, FALSE otherwise */
int replace_env_str(per_request *reqInfo, char *name, char *value)
{
register int i, len;
for (i = 0, len = strlen(name); reqInfo->env[i]; i++) {
if (strncmp(reqInfo->env[i], name, len) == 0) {
free(reqInfo->env[i]);
if (i < reqInfo->num_env) {
reqInfo->env[i] = reqInfo->env[--(reqInfo->num_env)];
reqInfo->env_len[i] = reqInfo->env_len[reqInfo->num_env];
reqInfo->env[reqInfo->num_env] = NULL;
}
else {
reqInfo->env[i] = NULL;
reqInfo->num_env--;
}
make_env_str(reqInfo, name, value);
return TRUE;
}
}
return FALSE;
}
/* Go down the array of environment variables, free'ing as you go */
void free_env(per_request *reqInfo) {
int x;
for(x=0;reqInfo->env[x];x++)
freeString(reqInfo->env[x]);
free(reqInfo->env);
free(reqInfo->env_len);
reqInfo->env = NULL;
}
/* If the environment variable has already been set, this will append
the value to it, of the form "name=old, new"
Assumes that "header" is a pointer to a string that is longer than
the string it contains
*/
int merge_header(per_request *reqInfo, char *header, char *value)
{
register int l,lt;
int len, ndx;
char **t,*tmp;
len = strlen(value);
for(l=0;header[l];++l);
header[l] = '=';
header[++l] = '\0';
for(ndx = 0, t=reqInfo->env; *t; ++t, ndx++) {
if(!strncmp(*t,header,l)) {
lt = strlen(*t);
if ((lt + len + 2) > reqInfo->env_len[ndx]) {
tmp = reqInfo->env[ndx];
if ((lt+len+2) > HUGE_STRING_LEN) {
reqInfo->env[ndx] = newString(lt+len+2,STR_REQ);
} else {
reqInfo->env[ndx] = newString(HUGE_STRING_LEN,STR_REQ);
}
sprintf(reqInfo->env[ndx],"%s, %s",tmp,value);
freeString(tmp);
} else {
(*t)[lt++] = ',';
(*t)[lt++] = ' ';
strcpy(&((*t)[lt]),value);
}
header[l-1] = '\0';
return 1;
}
}
header[l-1] = '\0';
return 0;
}
/* make_env_str will add the environment variable name=value to
the environment array of a per_request structure. It will also
auto grow the structure as necessary using ENV_BEG_SIZE and ENV_INC_SIZE */
int make_env_str(per_request *reqInfo, char *name, char *value)
{
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 = (char **) malloc(ENV_BEG_SIZE * sizeof(char *)))
|| !(reqInfo->env_len = (int*) malloc(ENV_BEG_SIZE * sizeof(int))))
die(reqInfo,SC_NO_MEMORY,"make_env_str:malloc");
reqInfo->max_env = ENV_BEG_SIZE;
}
if ((reqInfo->num_env+1) >= reqInfo->max_env) {
if (!(reqInfo->env = (char **) realloc(reqInfo->env,
((reqInfo->max_env+ENV_INC_SIZE) * sizeof(char *))))
|| !(reqInfo->env_len = (int*) realloc(reqInfo->env_len,
(reqInfo->max_env + ENV_INC_SIZE) * sizeof(int))))
die(reqInfo,SC_NO_MEMORY,"make_env_str:realloc");
reqInfo->max_env += ENV_INC_SIZE;
}
strncpy(tmp, name, HUGE_STRING_LEN);
strncat(tmp,"=",HUGE_STRING_LEN - strlen(tmp));
strncat(tmp,value,HUGE_STRING_LEN - strlen(tmp));
reqInfo->env[reqInfo->num_env] = dupStringP(tmp,STR_REQ);
reqInfo->env_len[reqInfo->num_env] =
sizeofString(reqInfo->env[reqInfo->num_env]);
reqInfo->num_env++;
reqInfo->env[reqInfo->num_env] = NULL;
return 1;
}
/* Debugging dump of environment array */
/*
void print_env (FILE* fp, char** env)
{
int n = 0;
while (env[n]) {
fprintf (fp, "Var %d: %s\n", n, env[n]);
n++;
}
}
*/

42
src/env.h Normal file
View File

@ -0,0 +1,42 @@
/************************************************************************
* 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
*
************************************************************************
*
* env.h,v 1.8 1995/11/28 09:01:43 blong Exp
*
************************************************************************
*
* env.h contains:
* All functions for dealing with the environment array.
*
*/
#ifndef _ENV_H_
#define _ENV_H_ 1
/* globals defined in this module */
/* Numbers to increase env array by
These settings might affect performance quite a bit, should look into
tuning them
*/
#define ENV_BEG_SIZE 25
#define ENV_INC_SIZE 5
#define BIG_ENV_VAR_LEN 1024
/* function defined in this module */
int make_env_str(per_request *reqInfo, char *name, char *value);
int merge_header(per_request *reqInfo, char *h, char *v);
void free_env(per_request *reqInfo);
int replace_env_str(per_request *reqInfo, char *name, char *value);
#endif /* _ENV_H_ */

291
src/fdwrap.c Normal file
View File

@ -0,0 +1,291 @@
/************************************************************************
* 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
*
************************************************************************
*
* fdwrap.c,v 1.15 1996/04/05 18:54:46 blong Exp
*
************************************************************************
*
* fdwrap.c used to wrap file descriptors so that we can keep track
* of open ones and close them when errors happen. Should
* make leaks next to impossible.
*
*/
#include "config.h"
#include "portability.h"
#include <stdio.h>
#ifndef NO_STDLIB_H
# include <stdlib.h>
#endif /* NO_STDLIB_H */
#ifdef DBM_SUPPORT
# ifndef _DBMSUPPORT_H /* moronic OSs which don't protect their own include */
# define _DBMSUPPORT_H /* files from being multiply included */
# include <ndbm.h>
# endif /* _DBMSUPPORT_H */
#endif /* DBM_SUPPORT */
#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 "constants.h"
#include "fdwrap.h"
#include "host_config.h"
#include "http_log.h"
static FDTABLE* FdTab;
static int nSize;
void fd_error(char *err_msg)
{
char S[MAX_STRING_LEN];
sprintf(S,"fdwrap error: %s",err_msg);
log_error(S,gConfiguration->error_log);
exit(1);
}
void fd_warn(char *err_msg)
{
char S[MAX_STRING_LEN];
sprintf(S,"fdwrap warn: %s",err_msg);
log_error(S,gConfiguration->error_log);
}
/* Can't call fd_error in Init since error_log isn't opened yet. */
void InitFdTable (void)
{
int ndx;
/* take care of failure here */
FdTab = (FDTABLE*) malloc (INITIAL_TABSIZE * sizeof(FDTABLE));
if (!FdTab) {
fprintf(stderr,
"HTTPd: Could not allocate memory for file descriptor tracking\n");
perror("malloc");
exit(1);
}
nSize = INITIAL_TABSIZE;
for (ndx = 0; ndx < INITIAL_TABSIZE; ndx++) {
FdTab[ndx].bOpen = FDW_CLOSED;
FdTab[ndx].fp = NULL;
}
}
int GrowTable (int fd)
{
int ndx;
/* take care of failure here */
FdTab = (FDTABLE*) realloc ((char*)FdTab,
((fd + 10) * sizeof(FDTABLE)));
if (!FdTab) {
fd_warn("GrowTable Failed");
return 0;
}
for (ndx = nSize; ndx < fd + 10; ndx++) {
FdTab[ndx].bOpen = FDW_CLOSED;
FdTab[ndx].fp = NULL;
}
nSize = fd + 10;
return 1;
}
FILE* FOpen (char* fname, char* mode)
{
FILE* fp;
int fd;
if ((fp = fopen (fname, mode))) {
fd = fileno(fp);
if (fd >= nSize)
if (!GrowTable(fd)) {
fclose(fp);
return NULL;
}
FdTab[fd].bOpen = FDW_FILE_PTR;
FdTab[fd].fp = fp;
return fp;
}
else
return NULL;
}
DIR* Opendir(char* dirname)
{
DIR* dp;
int fd;
if ((dp = opendir(dirname))) {
fd = DIR_FILENO(dp);
if (fd >= nSize)
if (!GrowTable(fd)) {
closedir(dp);
return NULL;
}
FdTab[fd].bOpen = FDW_DIR_PTR;
FdTab[fd].fp = dp;
return dp;
}
else
return NULL;
}
int Pipe (int* pd)
{
if (pipe(pd) < 0)
return -1;
if (pd[0] >= nSize || pd[1] >= nSize)
if (!GrowTable(pd[0] > pd[1] ? pd[0] : pd[1])) {
close(pd[0]);
close(pd[1]);
return -1;
}
FdTab[pd[0]].bOpen = FDW_FILE_DESC;
FdTab[pd[0]].fp = NULL;
FdTab[pd[1]].bOpen = FDW_FILE_DESC;
FdTab[pd[1]].fp = NULL;
return 0;
}
FILE* FdOpen(int fd, char* mode)
{
FILE* fp;
if ((fp = fdopen(fd, mode))) {
FdTab[fd].bOpen = FDW_FILE_PTR;
FdTab[fd].fp = fp;
return fp;
}
else
return NULL;
}
#ifdef DBM_SUPPORT
DBM* DBM_Open (char *dbm_name, int flags, int mode)
{
DBM* dp;
int fd;
if ((dp = dbm_open (dbm_name, flags, mode))) {
fd = dbm_dirfno(dp); /* Hope this is portable across implementations */
if (fd >= nSize)
if (!GrowTable(fd)) {
dbm_close(dp);
return NULL;
}
FdTab[fd].bOpen = FDW_DBM_PTR;
FdTab[fd].fp = dp;
return dp;
}
else
return NULL;
}
#endif /* DBM_SUPPORT */
int FClose (FILE* fp)
{
int fd;
if (fp != NULL) {
fd = fileno(fp);
FdTab[fd].bOpen = FDW_CLOSED;
if (FdTab[fd].fp != fp) {
fd_warn("Mismatched File Pointer (FILE), closing both");
if (FdTab[fd].fp != NULL) fclose(FdTab[fd].fp);
}
FdTab[fd].fp = NULL;
return fclose(fp);
} else return -1;
}
int Closedir (DIR *dp)
{
int fd = DIR_FILENO(dp);
FdTab[fd].bOpen = FDW_CLOSED;
if (FdTab[fd].fp != dp) {
fd_warn("Mismatched File Pointer (FILE), closing both");
fclose(FdTab[fd].fp);
}
FdTab[fd].fp = NULL;
#ifndef APOLLO
return closedir(dp);
#else
closedir(dp);
return;
#endif /* APOLLO */
}
#ifdef DBM_SUPPORT
void DBM_Close (DBM *db)
{
int fd = dbm_dirfno(db);
FdTab[fd].bOpen = FDW_CLOSED;
if (FdTab[fd].fp != db) {
fd_warn("Mismatched File Pointer (DBM), closing both");
if (FdTab[fd].fp != NULL) dbm_close(FdTab[fd].fp);
}
FdTab[fd].fp = NULL;
if (db != NULL) dbm_close(db);
}
#endif /* DBM_SUPPORT */
int Close(int fd)
{
FdTab[fd].bOpen = FDW_CLOSED;
return close(fd);
}
int CloseAll(void)
{
int ndx;
int nAny = 0;
for (ndx = 0; ndx < nSize; ndx++) {
if (FdTab[ndx].bOpen) {
nAny = 1;
switch (FdTab[ndx].bOpen) {
case FDW_FILE_DESC: close(ndx);
break;
case FDW_FILE_PTR: fclose(FdTab[ndx].fp);
break;
case FDW_DIR_PTR: closedir(FdTab[ndx].fp);
break;
#ifdef DBM_SUPPORT
case FDW_DBM_PTR: dbm_close(FdTab[ndx].fp);
break;
#endif /* DBM_SUPPORT */
}
FdTab[ndx].bOpen = FDW_CLOSED;
FdTab[ndx].fp = NULL;
}
}
return nAny;
}
void DestroyFdTab(void)
{
free (FdTab);
}

62
src/fdwrap.h Normal file
View File

@ -0,0 +1,62 @@
/************************************************************************
* 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
*
************************************************************************
*
* fdwrap.h,v 1.5 1995/11/28 09:01:45 blong Exp
*
************************************************************************
*
* fdwrap.h contains all of the header information for the file descriptor
* wrapper contained in fdwrap.c
*
*/
#ifndef _FDWRAP_H
#define _FDWRAP_H 1
#ifdef DBM_SUPPORT
# ifndef _DBMSUPPORT_H /* moronic OSs which don't protect their own include */
# define _DBMSUPPORT_H /* files from being multiply included */
# include <ndbm.h>
# endif /* _DBMSUPPORT_H */
#endif /* DBM_SUPPORT */
#define INITIAL_TABSIZE 30
#define INCREMENT_TABSIZE 10
/* File descriptor types, for use in knowing how to close them */
#define FDW_CLOSED 0
#define FDW_FILE_DESC 1
#define FDW_FILE_PTR 2
#define FDW_DIR_PTR 3
#define FDW_DBM_PTR 4
typedef struct {
int bOpen;
void* fp;
} FDTABLE;
void InitFdTable(void);
int GrowFdTable(int fd);
FILE* FOpen(char*, char*);
DIR* Opendir(char*);
FILE* FdOpen(int, char*);
int Pipe(int*);
#ifdef DBM_SUPPORT
DBM* DBM_Open (char* , int, int);
void DBM_Close (DBM*);
#endif /* DBM_SUPPORT */
int FClose(FILE*);
int Closedir(DIR*);
int Close(int);
int CloseAll(void);
#endif /* _FDWRAP_H */

43
src/global.h Normal file
View File

@ -0,0 +1,43 @@
/* GLOBAL.H - RSAREF types and constants
*/
#ifndef _GLOBALS_H
#define _GLOBALS_H 1
/*****************************************************************/
/*****************************************************************/
#if defined(WIN32)
#define PROTOTYPES 1
#endif /* defined(WIN32) */
/*****************************************************************/
/*****************************************************************/
/* PROTOTYPES should be set to one if and only if the compiler supports
function argument prototyping.
The following makes PROTOTYPES default to 0 if it has not already
been defined with C compiler flags.
*/
#ifndef PROTOTYPES
#define PROTOTYPES 0
#endif /* PROTOTYPES */
/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;
/* UINT2 defines a two byte word */
typedef unsigned short int UINT2;
/* UINT4 defines a four byte word */
typedef unsigned long int UINT4;
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
returns an empty list.
*/
#if PROTOTYPES
#define PROTO_LIST(list) list
#else
#define PROTO_LIST(list) ()
#endif /* PROTOTYPES */
#endif /* _GLOBALS_H */

295
src/host_config.c Normal file
View File

@ -0,0 +1,295 @@
/************************************************************************
* 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
*
************************************************************************
*
*host_config.c,v 1.20 1996/04/05 18:54:47 blong Exp
*
************************************************************************
*
*/
#include "config.h"
#include "portability.h"
#include "constants.h"
#ifndef NO_STDLIB_H
# include <stdlib.h>
#endif /* NO_STDLIB_H */
#include <string.h>
#include "host_config.h"
#include "http_log.h"
#include "http_alias.h"
#include "http_mime.h"
#include "http_request.h"
#include "util.h"
per_host* gConfiguration;
per_host* create_host_conf(per_host *hostInfo, int virtual) {
per_host *newInfo, *tmpInfo;
newInfo = (per_host *) malloc(sizeof(per_host));
newInfo->httpd_conf = 0;
newInfo->srm_conf = 0;
newInfo->files_open = 0;
newInfo->next = NULL;
if (virtual) newInfo->virtualhost = TRUE;
else newInfo->virtualhost = FALSE;
newInfo->called_hostname = NULL;
if (hostInfo != NULL) {
if (hostInfo->files_open != TRUE) {
open_logs(hostInfo);
hostInfo->files_open = TRUE;
}
newInfo->error_fname = hostInfo->error_fname;
newInfo->xfer_fname = hostInfo->xfer_fname;
newInfo->agent_fname = hostInfo->agent_fname;
newInfo->referer_fname = hostInfo->referer_fname;
newInfo->referer_ignore = hostInfo->referer_ignore;
newInfo->server_admin = hostInfo->server_admin;
newInfo->server_hostname = hostInfo->server_hostname;
newInfo->srm_confname = hostInfo->srm_confname;
newInfo->annotation_server = hostInfo->annotation_server;
newInfo->dns_mode = hostInfo->dns_mode;
newInfo->log_opts = hostInfo->log_opts;
newInfo->error_log = hostInfo->error_log;
newInfo->agent_log = hostInfo->agent_log;
newInfo->referer_log = hostInfo->referer_log;
newInfo->xfer_log = hostInfo->xfer_log;
newInfo->user_dir = hostInfo->user_dir;
newInfo->index_names = hostInfo->index_names;
newInfo->access_name = hostInfo->access_name;
newInfo->document_root = hostInfo->document_root;
newInfo->doc_root_len = hostInfo->doc_root_len;
newInfo->default_type = hostInfo->default_type;
newInfo->default_icon = hostInfo->default_icon;
newInfo->num_doc_errors = hostInfo->num_doc_errors;
newInfo->doc_errors = hostInfo->doc_errors;
newInfo->translations = hostInfo->translations;
/* thanks to Kevin Ruddy (smiles@powerdog.com) for re-teaching me
how to make a linked list */
tmpInfo = hostInfo;
while (tmpInfo->next != NULL) tmpInfo = tmpInfo->next;
tmpInfo->next = newInfo;
} else {
gConfiguration = newInfo;
newInfo->translations = NULL;
newInfo->num_doc_errors = 0;
}
return newInfo;
}
void free_host_conf() {
per_host *host = gConfiguration;
per_host *tmp;
while (host != NULL) {
close_logs(host);
if (host->httpd_conf & HC_ERROR_FNAME) free(host->error_fname);
if (host->httpd_conf & HC_XFER_FNAME) free(host->xfer_fname);
if (host->httpd_conf & HC_AGENT_FNAME) free(host->agent_fname);
if (host->httpd_conf & HC_REFERER_FNAME) free(host->referer_fname);
if (host->httpd_conf & HC_REFERER_IGNORE) free(host->referer_ignore);
if (host->httpd_conf & HC_SERVER_ADMIN) free(host->server_admin);
if (host->httpd_conf & HC_SERVER_HOSTNAME) free(host->server_hostname);
if (host->httpd_conf & HC_SRM_CONFNAME) free(host->srm_confname);
if (host->httpd_conf & HC_ANNOT_SERVER) free(host->annotation_server);
if (host->srm_conf & SRM_USER_DIR) free(host->user_dir);
if (host->srm_conf & SRM_INDEX_NAMES) free(host->index_names);
if (host->srm_conf & SRM_ACCESS_NAME) free(host->access_name);
if (host->srm_conf & SRM_DOCUMENT_ROOT) free(host->document_root);
if (host->srm_conf & SRM_DEFAULT_TYPE) free(host->default_type);
if (host->srm_conf & SRM_DEFAULT_ICON) free(host->default_icon);
if (host->srm_conf & SRM_TRANSLATIONS) free_aliases(host->translations);
if (host->srm_conf & SRM_DOCERRORS) free_doc_errors(host);
tmp = host->next;
free(host);
host = tmp;
}
}
/* set_host_conf_value will add an option to the list, and return the former
value of the option. Used for non-string values stored in per_host
data structure */
int set_host_conf_value(per_host *hostInfo, int part, int option)
{
int tmp = 0;
switch(part) {
case PH_HTTPD_CONF:
tmp = hostInfo->httpd_conf & option;
hostInfo->httpd_conf = hostInfo->httpd_conf | option;
break;
case PH_SRM_CONF:
tmp = hostInfo->srm_conf & option;
hostInfo->srm_conf = hostInfo->srm_conf | option;
break;
}
return tmp;
}
void set_host_conf(per_host *hostInfo, int part, int option, char *value) {
char *tmp;
tmp = strdup(value);
switch(part) {
case PH_HTTPD_CONF:
switch (option) {
case HC_ERROR_FNAME:
if (hostInfo->httpd_conf & option)
free(hostInfo->error_fname);
hostInfo->error_fname = tmp;
break;
case HC_XFER_FNAME:
if (hostInfo->httpd_conf & option)
free(hostInfo->xfer_fname);
hostInfo->xfer_fname = tmp;
break;
case HC_AGENT_FNAME:
if (hostInfo->httpd_conf & option)
free(hostInfo->agent_fname);
hostInfo->agent_fname = tmp;
break;
case HC_REFERER_FNAME:
if (hostInfo->httpd_conf & option)
free(hostInfo->referer_fname);
hostInfo->referer_fname = tmp;
break;
case HC_REFERER_IGNORE:
if (hostInfo->httpd_conf & option)
free(hostInfo->referer_ignore);
hostInfo->referer_ignore = tmp;
break;
case HC_SERVER_ADMIN:
if (hostInfo->httpd_conf & option)
free(hostInfo->server_admin);
hostInfo->server_admin = tmp;
break;
case HC_SERVER_HOSTNAME:
if (hostInfo->httpd_conf & option)
free(hostInfo->server_hostname);
hostInfo->server_hostname = tmp;
break;
case HC_SRM_CONFNAME:
if (hostInfo->httpd_conf & option)
free(hostInfo->srm_confname);
hostInfo->srm_confname = tmp;
break;
case HC_ANNOT_SERVER:
if (hostInfo->httpd_conf & option)
free(hostInfo->annotation_server);
hostInfo->annotation_server = tmp;
break;
}
hostInfo->httpd_conf = hostInfo->httpd_conf | option;
break;
case PH_SRM_CONF:
switch (option) {
case SRM_USER_DIR:
if (hostInfo->srm_conf & option)
free(hostInfo->user_dir);
hostInfo->user_dir = tmp;
break;
case SRM_INDEX_NAMES:
if (hostInfo->srm_conf & option)
free(hostInfo->index_names);
hostInfo->index_names = tmp;
break;
case SRM_ACCESS_NAME:
if (hostInfo->srm_conf & option)
free(hostInfo->access_name);
hostInfo->access_name = tmp;
break;
case SRM_DOCUMENT_ROOT:
if (hostInfo->srm_conf & option)
free(hostInfo->document_root);
hostInfo->document_root = tmp;
hostInfo->doc_root_len = strlen(tmp);
break;
case SRM_DEFAULT_TYPE:
if (hostInfo->srm_conf & option)
free(hostInfo->default_type);
hostInfo->default_type = tmp;
break;
case SRM_DEFAULT_ICON:
if (hostInfo->srm_conf & option)
free(hostInfo->default_icon);
hostInfo->default_icon = tmp;
break;
}
hostInfo->srm_conf = hostInfo->srm_conf | option;
break;
}
}
void open_all_logs() {
per_host *host = gConfiguration;
while (host != NULL) {
if (!host->files_open) {
open_logs(host);
host->files_open = TRUE;
}
host = host->next;
}
}
/* Close without cleanup, should only be used by the error handlers,
(ie: bus_error and seg_fault) */
void close_all_logs() {
per_host *host = gConfiguration;
while (host != NULL) {
close_logs(host);
host = host->next;
}
}
/* Calls get_local_addr from util.c to determine the called address
of the connection, and then hunts for that down the host configuration
linked list. If none match, uses the first one (which should be INADDR_ANY,
anyways) */
void which_host_conf(per_request *reqInfo) {
per_host *host = gConfiguration;
int Found = FALSE;
get_local_addr(reqInfo);
while (host && !Found) {
if (host->address_info.s_addr == reqInfo->address_info.s_addr) {
if (!host->virtualhost && host->called_hostname) {
if (!strncasecmp(host->called_hostname,reqInfo->inh_called_hostname,
strlen(host->called_hostname))) {
Found = TRUE;
}
} else Found = TRUE;
}
if (!Found) host = host->next;
}
if (host == NULL)
reqInfo->hostInfo = gConfiguration;
else
reqInfo->hostInfo = host;
}

70
src/host_config.h Normal file
View File

@ -0,0 +1,70 @@
/************************************************************************
* 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
*
************************************************************************
*
* host_config.h,v 1.9 1995/11/28 09:01:47 blong Exp
*
************************************************************************
*
* host_config.h
*
*
*/
#ifndef _HOST_CONFIG_H_
#define _HOST_CONFIG_H_ 1
/* HTTPD_CONF OPTS - Needs at least 16 bit ints
if set, means that variable is set to something other than default */
#define HC_LOG_TYPE 1
#define HC_ERROR_FNAME 2
#define HC_XFER_FNAME 4
#define HC_AGENT_FNAME 8
#define HC_REFERER_FNAME 16
#define HC_REFERER_IGNORE 32
#define HC_SERVER_ADMIN 128
#define HC_SERVER_HOSTNAME 256
#define HC_SRM_CONFNAME 512
#define HC_ANNOT_SERVER 4096
/* SRM_CONF OPTS */
#define SRM_USER_DIR 1
#define SRM_INDEX_NAMES 2
#define SRM_ACCESS_NAME 4
#define SRM_DOCUMENT_ROOT 8
#define SRM_DEFAULT_TYPE 16
#define SRM_DEFAULT_ICON 32
#define SRM_TRANSLATIONS 64
#define SRM_DOCERRORS 128
/* PEM_CONF OPTS */
#define PEMC_PEM_ENCRYPT 1
#define PEMC_PEM_DECRYPT 2
#define PEMC_PEM_ENTITY 4
#define PEMC_PGP_ENCRYPT 8
#define PEMC_PGP_DECRYPT 16
#define PEMC_PGP_ENTITY 32
/* globals defined in this module */
extern per_host *gConfiguration;
/* function defined in this module */
per_host* create_host_conf(per_host *hostInfo, int virtual);
void free_host_conf(void);
int set_host_conf_value(per_host *hostInfo, int part, int option);
void set_host_conf(per_host *hostInfo, int part, int option, char *value);
void which_host_conf(per_request *reqInfo);
void open_all_logs(void);
void close_all_logs(void);
#endif /* _HOST_CONFIG_H_ */

View File

@ -1,123 +1,337 @@
/* /************************************************************************
* 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
*
************************************************************************
*
* http_access.c,v 1.78 1996/04/05 18:54:49 blong Exp
*
************************************************************************
*
* http_access: Security options etc. * http_access: Security options etc.
* *
* All code contained herein is covered by the Copyright as distributed
* in the README file in the main directory of the distribution of
* NCSA HTTPD.
*
* Based on NCSA HTTPd 1.3 by Rob McCool
*
* 03-12-95 blong
* Added patch to fix ALLOW_THEN_DENY
*
*/ */
#include "httpd.h" #include "config.h"
#include "new.h" #include "portability.h"
int in_domain(char *domain, char *what) { #include <stdio.h>
#ifndef NO_STDLIB_H
# include <stdlib.h>
#endif /* NO_STDLIB_H */
#include <string.h>
#include <sys/stat.h>
#include <ctype.h>
#include <errno.h>
#include "constants.h"
#include "http_access.h"
#include "http_request.h"
#include "http_config.h"
#include "http_auth.h"
#include "http_mime.h"
#include "http_log.h"
#include "util.h"
#include "allocate.h"
/*
* Modified this bad boy so he wouldn't
* match things like "allow csa.ncsa.uiuc.edu" and
* a ncsa.uiuc.edu. SSG 7/10/95
*/
int in_domain(char *domain, char *what)
{
int dl=strlen(domain); int dl=strlen(domain);
int wl=strlen(what); int wl=strlen(what);
if((wl-dl) >= 0) if(((wl-dl) >= 0) && !strcmp(domain,&what[wl-dl])) {
return(!strcmp(domain,&what[wl-dl])); if (((wl - dl) > 0) && (*domain != '.') && (what[wl-dl-1] != '.'))
else return 0; /* only a partial match - SSG */
return 1;
}
else {
return 0; return 0;
}
} }
int in_ip(char *domain, char *what) { /*
return(!strncmp(domain,what,strlen(domain))); * Modified this OTHER bad boy so he won't match
* "1.2.3.40" with "allow 1.2.3.4", "1.2.30.4" with "allow 1.2.3", etc.
* (Documentation implies that these should not match, but they did.)
* Address matching should really be done with subnet masks, though.
* mullen@itd.nrl.navy.mil 11/16/95
*
* Returned to normal, as the patch didn't work. For now, I think
* 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 dl=strlen(domain);
return (!strncmp(domain,what,dl)) &&
(domain[dl-1]=='.' && strlen(what)<=dl && what[dl]=='.'); */
return(!strncmp(domain,what,strlen(domain)));
} }
int find_allow(int x, int m) { /* find_host_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_host_allow(per_request *reqInfo, int x)
{
register int y; register int y;
if(sec[x].num_allow[m] < 0) /* If no allows are specified, then allow */
return 1; if(sec[x].num_allow[reqInfo->method] == 0)
return FA_ALLOW;
for(y=0;y<sec[x].num_allow[m];y++) { for(y=0;y<sec[x].num_allow[reqInfo->method];y++) {
if(!strcmp("all",sec[x].allow[m][y])) if(!strcmp("all",sec[x].allow[reqInfo->method][y]))
return 1; return FA_ALLOW;
if(remote_host && isalpha(remote_host[0])) #ifdef LOCALHACK
if(in_domain(sec[x].allow[m][y],remote_host)) if((!strcmp("LOCAL",sec[x].allow[reqInfo->method][y])) &&
return 1; reqInfo->remote_host &&
if(in_ip(sec[x].allow[m][y],remote_ip)) (ind(reqInfo->remote_host,'.') == -1))
return 1; {
reqInfo->bSatisfiedDomain = TRUE;
return FA_ALLOW;
}
#endif /* LOCALHACK */
if(in_ip(sec[x].allow[reqInfo->method][y],reqInfo->remote_ip))
{
reqInfo->bSatisfiedDomain = TRUE;
return FA_ALLOW;
}
/* If we haven't done a lookup, and the DNS type is Minimum, then
* we do a lookup now
*/
if (!reqInfo->dns_host_lookup &&
(reqInfo->hostInfo->dns_mode == DNS_MIN))
get_remote_host_min(reqInfo);
if(reqInfo->remote_host) {
if(in_domain(sec[x].allow[reqInfo->method][y],reqInfo->remote_host))
{
reqInfo->bSatisfiedDomain = TRUE;
return FA_ALLOW;
}
}
} }
return 0; /* Default is to deny */
return FA_DENY;
} }
int find_deny(int x, int m) { /* find_host_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_host_deny(per_request *reqInfo, int x)
{
register int y; register int y;
if(sec[x].num_deny[m] < 0) /* If there aren't any denies, then it is allowed
return 1; */
if(sec[x].num_deny[reqInfo->method] == 0)
return FA_ALLOW;
for(y=0;y<sec[x].num_deny[m];y++) { for(y=0;y<sec[x].num_deny[reqInfo->method];y++) {
if(!strcmp("all",sec[x].deny[m][y])) if(!strcmp("all",sec[x].deny[reqInfo->method][y]))
return 1; {
if(remote_host && isalpha(remote_host[0])) reqInfo->bSatisfiedDomain = FALSE;
if(in_domain(sec[x].deny[m][y],remote_host)) return FA_DENY;
return 1; }
if(in_ip(sec[x].deny[m][y],remote_ip)) #ifdef LOCALHACK
return 1; if((!strcmp("LOCAL",sec[x].deny[reqInfo->method][y])) &&
reqInfo->remote_host &&
(ind(reqInfo->remote_host,'.') == -1))
{
reqInfo->bSatisfiedDomain = FALSE;
return FA_DENY;
}
#endif /* LOCALHACK */
if(in_ip(sec[x].deny[reqInfo->method][y],reqInfo->remote_ip))
{
reqInfo->bSatisfiedDomain = FALSE;
return FA_DENY;
}
if (!reqInfo->dns_host_lookup &&
(reqInfo->hostInfo->dns_mode == DNS_MIN))
get_remote_host_min(reqInfo);
if(reqInfo->remote_host) {
if(in_domain(sec[x].deny[reqInfo->method][y],reqInfo->remote_host))
{
reqInfo->bSatisfiedDomain = FALSE;
return FA_DENY;
}
}
} }
return 0; /* Default is to allow */
reqInfo->bSatisfiedDomain = TRUE;
return FA_ALLOW;
} }
void check_dir_access(int x, int m, int *w, int *n) { /* match_referer()
if(sec[x].auth_type) * currently matches restriction with sent for only as long as restricted
auth_type = sec[x].auth_type; */
if(sec[x].auth_name) int match_referer(char *restrict, char *sent) {
auth_name = sec[x].auth_name; return !(strcmp_match(sent,restrict));
if(sec[x].auth_pwfile)
auth_pwfile = sec[x].auth_pwfile;
if(sec[x].auth_grpfile)
auth_grpfile = sec[x].auth_grpfile;
if(sec[x].order[m] == ALLOW_THEN_DENY) {
*w=0;
if(find_allow(x,m))
*w=1;
if(find_deny(x,m))
*w=0;
} else if(sec[x].order[m] == DENY_THEN_ALLOW) {
if(find_deny(x,m))
*w=0;
if(find_allow(x,m))
*w=1;
}
else
*w = find_allow(x,m) && (!find_deny(x,m));
if(sec[x].num_auth[m])
*n=x;
} }
void evaluate_access(char *p, struct stat *finfo, int m, int *allow, /* find_referer_allow()
char *allow_options,FILE *out) * 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,
int *allow, int *allow_options, int *other)
{
if(sec[x].auth_name[0])
reqInfo->auth_name = sec[x].auth_name;
if(sec[x].auth_pwfile[0]) {
reqInfo->auth_pwfile = sec[x].auth_pwfile;
reqInfo->auth_pwfile_type = sec[x].auth_pwfile_type;
}
if(sec[x].auth_grpfile[0]) {
reqInfo->auth_grpfile = sec[x].auth_grpfile;
reqInfo->auth_grpfile_type = sec[x].auth_grpfile_type;
}
#ifdef DIGEST_AUTH
if(sec[x].auth_digestfile[0]) {
reqInfo->auth_digestfile = sec[x].auth_digestfile;
reqInfo->auth_digestfile_type = sec[x].auth_digestfile_type;
}
#endif /* DIGEST_AUTH */
if (sec[x].auth_type[0])
strcpy(reqInfo->auth_type,sec[x].auth_type);
if(sec[x].order[reqInfo->method] == ALLOW_THEN_DENY) {
*allow=FA_DENY;
if ((find_host_allow(reqInfo,x) == FA_ALLOW) &&
(find_referer_allow(reqInfo,x) == FA_ALLOW))
*allow = FA_ALLOW;
if ((find_host_deny(reqInfo,x) == FA_DENY) ||
(find_referer_deny(reqInfo,x) == FA_DENY))
*allow = FA_DENY;
}
else if(sec[x].order[reqInfo->method] == DENY_THEN_ALLOW) {
if ((find_host_deny(reqInfo,x) == FA_DENY) ||
(find_referer_deny(reqInfo,x) == FA_DENY))
*allow = FA_DENY;
if ((find_host_allow(reqInfo,x) == FA_ALLOW) &&
(find_referer_allow(reqInfo,x) == FA_ALLOW))
*allow = FA_ALLOW;
}
else { /* order == MUTUAL_FAILURE: allowed and not denied */
*allow = FA_DENY;
if ((find_host_allow(reqInfo,x) == FA_ALLOW) &&
(find_referer_allow(reqInfo,x) == FA_ALLOW) &&
!(find_host_deny(reqInfo,x) == FA_DENY) &&
!(find_referer_deny(reqInfo,x) == FA_DENY))
*allow = FA_ALLOW;
}
if(sec[x].num_auth[reqInfo->method])
*allow_options=x;
}
void evaluate_access(per_request *reqInfo,struct stat *finfo,int *allow,
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];
register int x,y,z,n; register int x,y,z,n;
if(S_ISDIR(finfo->st_mode)) strcpy_dir(path,p); if(S_ISDIR(finfo->st_mode))
else lim_strcpy(path,p, MAX_STRING_LEN); strncpy_dir(path,reqInfo->filename,MAX_STRING_LEN);
else lim_strcpy(path,reqInfo->filename,MAX_STRING_LEN);
no2slash(path); no2slash(path);
num_dirs = count_dirs(path); num_dirs = count_dirs(path);
will_allow = 1; will_allow = FA_ALLOW;
need_auth = -1; need_auth = -1;
auth_type = NULL; need_enhance = -1;
auth_name = NULL;
auth_pwfile = NULL; reqInfo->auth_user[0] = '\0';
auth_grpfile = NULL; reqInfo->auth_group[0] = '\0';
user[0] = '\0';
groupname[0] = '\0';
reset_mime_vars(); reset_mime_vars();
for(x=0;x<num_dirs;x++) { for(x=0;x<num_dirs;x++) {
@ -125,6 +339,9 @@ void evaluate_access(char *p, struct stat *finfo, int m, int *allow,
override[x] = OR_ALL; override[x] = OR_ALL;
} }
/* assume not domain restricted */
reqInfo->bSatisfiedDomain = 0;
n=num_dirs-1; n=num_dirs-1;
for(x=0;x<num_sec;x++) { for(x=0;x<num_sec;x++) {
if(is_matchexp(sec[x].d)) { if(is_matchexp(sec[x].d)) {
@ -134,7 +351,7 @@ void evaluate_access(char *p, struct stat *finfo, int m, 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(x,m,&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))) {
@ -143,89 +360,102 @@ void evaluate_access(char *p, struct stat *finfo, int m, 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(x,m,&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)) ||
(opts[n] & OPT_SYM_OWNER)) (opts[n] & OPT_SYM_OWNER)) {
{ for(x=0;x<num_dirs;x++) {
for(x=0;x<num_dirs;x++) { y = num_sec;
y = num_sec; make_dirstr(path,x+1,d);
make_dirstr(path,x+1,d); if((!(opts[x] & OPT_SYM_LINKS)) || (opts[x] & OPT_SYM_OWNER)) {
if((!(opts[x] & OPT_SYM_LINKS)) || (opts[x] & OPT_SYM_OWNER)) { struct stat lfi,fi;
struct stat lfi,fi;
lstat(d,&lfi); if(lstat(d,&lfi) != 0)
if(!(S_ISDIR(lfi.st_mode))) { {
if(opts[x] & OPT_SYM_OWNER) { sprintf(errstr,"HTTPd: can't lstat %s, errno = %d",d, errno);
char realpath[512]; log_error(errstr,reqInfo->hostInfo->error_log);
int bsz; *allow=FA_DENY;
*allow_options = OPT_NONE;
if((bsz = readlink(d,realpath,256)) == -1) return;
goto bong; }
realpath[bsz] = '\0'; if(!(S_ISDIR(lfi.st_mode))) {
if(realpath[0] != '/') { if(opts[x] & OPT_SYM_OWNER) {
char t[260]; if(stat(d,&fi) != 0)
strcpy(t,"../"); {
strcpy(&t[3],realpath); sprintf(errstr,"HTTPd: can't stat %s, errno = %d",d, errno);
make_full_path(d,t,realpath); log_error(errstr,reqInfo->hostInfo->error_log);
getparents(realpath); *allow=FA_DENY;
} *allow_options = OPT_NONE;
lstat(realpath,&fi); return;
if(fi.st_uid != lfi.st_uid) }
goto bong; if(fi.st_uid != lfi.st_uid)
} goto bong;
else { }
bong: else {
sprintf(errstr,"httpd: will not follow link %s",d); bong:
log_error(errstr); sprintf(errstr,"HTTPd: will not follow link %s",d);
*allow=0; log_error(errstr,reqInfo->hostInfo->error_log);
*allow_options = OPT_NONE; *allow=FA_DENY;
return; *allow_options = OPT_NONE;
} return;
} }
} }
if(override[x]) { }
parse_htaccess(d,override[x],out); if(override[x]) {
if(num_sec != y) { parse_htaccess(reqInfo,d,override[x]);
for(z=count_dirs(sec[y].d) - 1;z<num_dirs;z++) { if(num_sec != y) {
if(!(sec[y].opts & OPT_UNSET)) for(z=count_dirs(sec[y].d) - 1;z<num_dirs;z++) {
opts[z] = sec[y].opts; if(!(sec[y].opts & OPT_UNSET))
override[z] = sec[y].override; opts[z] = sec[y].opts;
} override[z] = sec[y].override;
check_dir_access(y,m,&will_allow,&need_auth); }
} if ((sec[y].num_auth[reqInfo->method] > 0) ||
} (sec[y].num_allow[reqInfo->method] > 0) ||
} (sec[y].num_deny[reqInfo->method] > 0) ||
} (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]);
}
}
}
}
}
if((!(S_ISDIR(finfo->st_mode))) && if((!(S_ISDIR(finfo->st_mode))) &&
((!(opts[n] & OPT_SYM_LINKS)) || (opts[n] & OPT_SYM_OWNER))) { ((!(opts[n] & OPT_SYM_LINKS)) || (opts[n] & OPT_SYM_OWNER))) {
struct stat fi,lfi; struct stat fi,lfi;
lstat(path,&fi); if(lstat(path,&fi)!=0)
{
sprintf(errstr,"HTTPd: can't lstat %s, errno = %d",path, errno);
log_error(errstr,reqInfo->hostInfo->error_log);
*allow=FA_DENY;
*allow_options = OPT_NONE;
return;
}
if(!(S_ISREG(fi.st_mode))) { if(!(S_ISREG(fi.st_mode))) {
if(opts[n] & OPT_SYM_OWNER) { if(opts[n] & OPT_SYM_OWNER) {
char realpath[512]; if(stat(path,&lfi)!=0)
int bsz; {
sprintf(errstr,"HTTPd: can't stat %s, errno = %d",path, errno);
if((bsz = readlink(path,realpath,256)) == -1) log_error(errstr,reqInfo->hostInfo->error_log);
goto gong; *allow=FA_DENY;
realpath[bsz] = '\0'; *allow_options = OPT_NONE;
if(realpath[0] != '/') { return;
char t[260]; }
strcpy(t,"../");
strcpy(&t[3],realpath);
make_full_path(path,t,realpath);
getparents(realpath);
}
lstat(realpath,&lfi);
if(fi.st_uid != lfi.st_uid) if(fi.st_uid != lfi.st_uid)
goto gong; goto gong;
} }
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); log_error(errstr,reqInfo->hostInfo->error_log);
*allow=0; *allow=FA_DENY;
*allow_options = OPT_NONE; *allow_options = OPT_NONE;
return; return;
} }
@ -234,17 +464,24 @@ void evaluate_access(char *p, struct stat *finfo, int m, 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) if ((need_auth >= 0) && (sec[need_auth].bSatisfy == SATISFY_ALL)) {
check_auth(&sec[need_auth],m,out); reqInfo->bSatisfiedDomain = 0;
check_auth(reqInfo,&sec[need_auth], reqInfo->inh_auth_line);
}
} else if ((need_auth >= 0) && (sec[need_auth].bSatisfy == SATISFY_ANY)) {
check_auth(reqInfo,&sec[need_auth], reqInfo->inh_auth_line);
*allow_options = opts[num_dirs-1];
*allow = FA_ALLOW;
} }
else *allow_options = 0; else *allow_options = 0;
} }
void kill_security() { void kill_security(void)
{
register int x,y,m; register int x,y,m;
for(x=0;x<num_sec;x++) { for(x=0;x<num_sec;x++) {
free(sec[x].d); /*free(sec[x].d);*/
for(m=0;m<METHODS;m++) { for(m=0;m<METHODS;m++) {
for(y=0;y<sec[x].num_allow[m];y++) for(y=0;y<sec[x].num_allow[m];y++)
free(sec[x].allow[m][y]); free(sec[x].allow[m][y]);
@ -252,8 +489,13 @@ void kill_security() {
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);
if(sec[x].auth_name) if(sec[x].auth_name)
free(sec[x].auth_name); free(sec[x].auth_name);
@ -261,18 +503,24 @@ void kill_security() {
free(sec[x].auth_pwfile); free(sec[x].auth_pwfile);
if(sec[x].auth_grpfile) if(sec[x].auth_grpfile)
free(sec[x].auth_grpfile); free(sec[x].auth_grpfile);
#ifdef DIGEST_AUTH
if(sec[x].auth_digestfile)
free(sec[x].auth_digestfile);
#endif*/ /* DIGEST_AUTH */
} }
} }
/* This function should reset the security data structure to contain only /* This function should reset the security data structure to contain only
the information given in the access configuration file. It should be the information given in the access configuration file. It should be
called after any transactions */ called after any transactions */
void reset_security() { void reset_security(void)
{
register int x,y,m; register int x,y,m;
for(x=num_sec_config;x<num_sec;x++) { for(x=num_sec_config;x<num_sec;x++) {
free(sec[x].d); /*free(sec[x].d);*/
for(m=0;m<METHODS;m++) { for(m=0;m<METHODS;m++) {
for(y=0;y<sec[x].num_allow[m];y++) for(y=0;y<sec[x].num_allow[m];y++)
free(sec[x].allow[m][y]); free(sec[x].allow[m][y]);
@ -280,8 +528,13 @@ void reset_security() {
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);
if(sec[x].auth_name) if(sec[x].auth_name)
free(sec[x].auth_name); free(sec[x].auth_name);
@ -289,6 +542,10 @@ void reset_security() {
free(sec[x].auth_pwfile); free(sec[x].auth_pwfile);
if(sec[x].auth_grpfile) if(sec[x].auth_grpfile)
free(sec[x].auth_grpfile); free(sec[x].auth_grpfile);
#ifdef DIGEST_AUTH
if(sec[x].auth_digestfile)
free(sec[x].auth_digestfile);
#endif*/ /* DIGEST_AUTH */
} }
num_sec = num_sec_config; num_sec = num_sec_config;

34
src/http_access.h Normal file
View File

@ -0,0 +1,34 @@
/************************************************************************
* 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
*
************************************************************************
*
* http_access.h,v 1.12 1996/02/22 23:46:41 blong Exp
*
************************************************************************
*
*/
#ifndef _HTTP_ACCESS_H_
#define _HTTP_ACCESS_H_
#include <sys/stat.h>
/* globals defined in this module */
#define FA_DENY 0
#define FA_ALLOW 1
/* http_access function prototypes */
void evaluate_access(per_request *reqInfo, struct stat *finfo,int *allow,
char *op);
void kill_security(void);
void reset_security(void);
#endif /* _HTTP_ACCESS_H_ */

View File

@ -1,138 +1,139 @@
/* /************************************************************************
* 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
*
************************************************************************
*
* http_alias.c: Stuff for dealing with directory aliases * http_alias.c: Stuff for dealing with directory aliases
* *
* All code contained herein is covered by the Copyright as distributed
* in the README file in the main directory of the distribution of
* NCSA HTTPD.
*
* 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.
*/ */
#include "httpd.h" #include "config.h"
#include "portability.h"
typedef struct { #include <stdio.h>
char fake[MAX_STRING_LEN]; #ifndef NO_STDLIB_H
char real[MAX_STRING_LEN]; # include <stdlib.h>
int script; #endif /* NO_STDLIB_H */
} alias; #include <string.h>
#include <pwd.h>
#include "constants.h"
#include "http_alias.h"
#include "http_config.h"
#include "http_log.h"
#include "http_request.h"
#include "util.h"
static int Saved_num_alias = 0; /* To send stat() information to cgi.c */
static int num_a = 0;
static alias a[MAX_ALIASES];
static int Saved_num_redirect = 0;
static int num_v = 0;
static alias v[MAX_ALIASES];
/* To send stat() information to http_script.c */
int dirs_in_alias; int dirs_in_alias;
void reset_aliases() { void free_aliases(lookup *trans) {
num_a = 0; int x;
num_v = 0;
for (x=0; x < trans->num_aliases ; x++) {
free(trans->aliases[x].fake);
free(trans->aliases[x].real);
}
free(trans->aliases);
free(trans);
} }
void save_aliases() { void add_lookup(per_host *host, char *fake, char *real, int type) {
Saved_num_alias = num_a; lookup *translations = host->translations;
Saved_num_redirect = num_v; int n;
if (translations == NULL) {
translations = (lookup *) malloc(sizeof(lookup));
translations->aliases = (lookupRec *) malloc(TRANS_BEG_SIZE *
sizeof(lookupRec));
translations->num_aliases = 0;
translations->max_aliases = TRANS_BEG_SIZE;
host->translations = translations;
}
if (translations->num_aliases >= translations->max_aliases) {
translations->aliases = (lookupRec *) realloc(translations->aliases,
((translations->max_aliases+
TRANS_INC_SIZE) *
sizeof(lookupRec)));
translations->max_aliases += TRANS_INC_SIZE;
}
n = translations->num_aliases;
translations->aliases[n].fake = strdup(fake);
translations->aliases[n].fake_len = strlen(fake);
translations->aliases[n].real = strdup(real);
translations->aliases[n].real_len = strlen(real);
translations->aliases[n].type = type;
translations->num_aliases++;
} }
void reset_to_saved_aliases() {
num_a = Saved_num_alias; void add_alias(per_host *host, char *fake, char *real, int is_script) {
num_v = Saved_num_redirect; char tmp[MAX_STRING_LEN];
if (real[0] != '/') {
make_full_path(((is_script == A_SCRIPT_CGI) ? server_root :
host->document_root),
real,tmp);
add_lookup(host,fake,tmp,is_script);
} else
add_lookup(host,fake,real,is_script);
} }
void add_alias(char *f, char *r, int is_script) { void add_redirect(per_host *host, char *fake, char *url,int type) {
if (num_a >= MAX_ALIASES) add_lookup(host,fake,url,type);
num_a = Saved_num_alias;
strcpy(a[num_a].fake,f);
a[num_a].script = is_script;
if(r[0] != '/')
make_full_path((is_script ? server_root : document_root),r,
a[num_a++].real);
else
strcpy(a[num_a++].real,r);
} }
void add_redirect(char *f, char *url) { char fake[MAX_STRING_LEN+2],real[MAX_STRING_LEN],dname[HUGE_STRING_LEN];
if (num_v >= MAX_ALIASES)
num_v = Saved_num_redirect;
strcpy(v[num_v].fake,f);
strcpy(v[num_v++].real,url);
}
char fake[MAX_STRING_LEN + 2],real[MAX_STRING_LEN],dname[HUGE_STRING_LEN]; int translate_name(per_request *reqInfo, char* url, char *filename)
{
int translate_name(char *name, FILE *fd) { register int x;
register int x,l;
char w[MAX_STRING_LEN]; char w[MAX_STRING_LEN];
struct passwd *pw; struct passwd *pw;
getparents(name); getparents(url);
for(x=0;x<num_v;x++) { if (reqInfo->hostInfo->translations != NULL) {
l=strlen(v[x].fake); lookup *trans = reqInfo->hostInfo->translations;
if(!strncmp(name,v[x].fake,l)) {
strsubfirst(l,name,v[x].real); for(x=0; x < trans->num_aliases ;x++) {
return REDIRECT_URL; if(!strncmp(url,trans->aliases[x].fake,
} trans->aliases[x].fake_len)) {
strncpy(filename,trans->aliases[x].real,HUGE_STRING_LEN);
strncat(filename,url+trans->aliases[x].fake_len,
HUGE_STRING_LEN - trans->aliases[x].real_len);
return trans->aliases[x].type;
}
}
} }
for(x=0; x < num_a; x++) { if((reqInfo->hostInfo->user_dir[0]) && (url[0] == '/')
l=strlen(a[x].fake); && (url[1] == '~')) {
if(!strncmp(name,a[x].fake,l)) { strcpy(dname,&url[2]);
strsubfirst(l,name,a[x].real); getword(w,dname,'/');
dirs_in_alias = count_dirs(a[x].real); if(!(pw=getpwnam(w))) {
return(a[x].script); /* log missing user attempt as suggested by
Gioacchino La Vecchia (gio@di.unipi.it) */
log_reason(reqInfo,"user does not exist",reqInfo->url);
die(reqInfo,SC_NOT_FOUND,reqInfo->url);
} }
} fake[0] = '/';
fake[1] = '~';
if((user_dir[0]) && (name[0] == '/') && (name[1] == '~')) { strcpy(&fake[2],w);
strcpy(dname,&name[2]); make_full_path(pw->pw_dir,reqInfo->hostInfo->user_dir,real);
getword(w,dname,'/'); strcpy(filename,real);
if(!(pw=getpwnam(w))) strcat(filename,url+strlen(w)+2);
die(NOT_FOUND,name,fd); return A_STD_DOCUMENT;
fake[0] = '/';
fake[1] = '~';
strcpy(&fake[2],w);
make_full_path(pw->pw_dir,user_dir,real);
add_alias(fake,real,STD_DOCUMENT);
strsubfirst(strlen(w) + 2,name,real);
return STD_DOCUMENT;
} }
/* no alias, add document root */ /* no alias, add document root */
strsubfirst(0,name,document_root); strncpy(filename,reqInfo->hostInfo->document_root,HUGE_STRING_LEN);
return STD_DOCUMENT; strncat(filename,url, HUGE_STRING_LEN - reqInfo->hostInfo->doc_root_len);
} return A_STD_DOCUMENT;
void unmunge_name(char *name) {
register int x,l;
l=strlen(document_root);
if(!strncmp(name,document_root,l)) {
strsubfirst(l,name,"");
if(!name[0]) {
name[0] = '/';
name[1] = '\0';
}
return;
}
for(x=0;x < num_a; x++) {
l=strlen(a[x].real);
if(!strncmp(name,a[x].real,l)) {
strsubfirst(l,name,a[x].fake);
if(!name[0]) {
name[0] = '/';
name[1] = '\0';
}
return;
}
}
} }

66
src/http_alias.h Normal file
View File

@ -0,0 +1,66 @@
/************************************************************************
* 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
*
************************************************************************
*
* http_alias.h,v 1.9 1995/11/28 09:01:52 blong Exp
*
************************************************************************
*
*
*
* http_alias.h contains:
* struct alias
*
*/
#ifndef _HTTP_ALIAS_H_
#define _HTTP_ALIAS_H_
/* globals defined in this module */
extern int dirs_in_alias;
/* structures defined in this module */
/* ------------------ aliases/redirects structures ------------------- */
#define TRANS_BEG_SIZE 20
#define TRANS_INC_SIZE 5
/* Include the string lengths instead of having to compute them on
every connection */
typedef struct _lookupRec {
char *fake;
int fake_len;
char *real;
int real_len;
int type;
} lookupRec;
typedef struct _lookup {
lookupRec *aliases;
int num_aliases;
int max_aliases;
} lookup;
/* function prototypes */
void reset_aliases(void);
void dump_aliases(void);
void add_alias(per_host *host, char *f, char *r, int is_script);
void free_aliases(lookup *trans);
void add_redirect(per_host *host, char *f, char *url,int type);
int translate_name(per_request *reqInfo, char *url, char *name);
void unmunge_name(per_request *reqInfo, char *name);
#endif /* _HTTP_ALIAS_H_ */

File diff suppressed because it is too large Load Diff

74
src/http_auth.h Normal file
View File

@ -0,0 +1,74 @@
/************************************************************************
* 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
*
************************************************************************
*
* http_auth.h,v 1.22 1996/03/27 20:43:57 blong Exp
*
************************************************************************
*
*/
#ifndef _HTTP_AUTH_H_
#define _HTTP_AUTH_H_
#ifdef DBM_SUPPORT
# ifndef _DBMSUPPORT_H
# define _DBMSUPPORT_H
# include <ndbm.h>
# endif /* _DBMSUPPORT_H */
#endif /* DBM_SUPPORT */
#include "global.h"
/* globals defined in this module */
/* http_auth */
void check_auth(per_request *reqInfo, security_data *s, char* auth_line);
int get_pw(per_request *reqInfo, char *user, char *pw, security_data* sec);
#ifdef DBM_SUPPORT
int in_group(per_request *reqInfo, char *user, char *group, char* pchGrps,
DBM* db);
#else
int in_group(per_request *reqInfo, char *user, char *group, char* pchGrps);
#endif /* DBM_SUPPORT */
char* init_group(per_request *reqInfo,char* grpfile);
void auth_bong(per_request *reqInfo,char *s,char* auth_name, char* auth_type);
#if defined(KRB4) || defined(KRB5)
typedef struct _krbdata {
char client_name[MAX_STRING_LEN];
char client_realm[MAX_STRING_LEN];
char server_realm[MAX_STRING_LEN];
int ver;
} KerberosInfo;
#define KERBEROSV4 0
#define KERBEROSV5 1
int check_krb_restrict(per_request* reqInfo, security_data* sec, KerberosInfo* kdat);
int krb_in_group(KerberosInfo* kdat, char *group, char* pchGrps);
#endif /* KRB4 or KRB5 */
#ifdef KRB4
extern char k4_srvtab[];
int k4_server_auth(char* authline, char* reply,FILE* error_log,
KerberosInfo *kdat);
#endif /* KRB4 */
#ifdef KRB5
extern char k5_srvtab[];
int k5_server_auth(char* authline, char* reply, KerberosInfo *kdat);
#endif /* KRB5 */
#endif /* _HTTP_AUTH_H_ */

File diff suppressed because it is too large Load Diff

64
src/http_config.h Normal file
View File

@ -0,0 +1,64 @@
/************************************************************************
* 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
*
************************************************************************
*
* http_config.h,v 1.15 1996/03/27 20:44:01 blong Exp
*
************************************************************************
*
*/
#ifndef _HTTP_CONFIG_H_
#define _HTTP_CONFIG_H_
/* globals defined in this module */
extern int num_sec;
/* num_sec_config: Number of security directories in access.conf file */
extern int num_sec_config;
extern security_data sec[];
/* Server config globals */
extern int standalone;
extern int port;
extern uid_t user_id;
extern gid_t group_id;
extern int timeout;
extern int do_rfc931;
extern char server_confname[];
extern char server_root[];
extern char core_dir[];
#ifdef SETPROCTITLE
extern char process_name[];
#endif /* SETPROCTITLE */
extern char pid_fname[];
extern char access_confname[];
extern char types_confname[];
extern char local_default_type[];
extern char local_default_icon[];
extern int log_directory_group_write_ok;
extern int log_directory_other_write_ok;
#ifndef NO_PASS
extern int max_servers;
extern int start_servers;
#endif /* NO_PASS */
extern KeepAliveData keep_alive;
/* function prototypes */
void read_config(FILE *errors);
void process_server_config(per_host *host, FILE *cfg, FILE *errors,int virtual);
void process_resource_config(per_host *host, FILE *open, FILE *errors, int virtual);
void parse_htaccess(per_request *reqInfo, char *dir, char override);
#endif /* _HTTP_CONFIG_H_ */

View File

@ -1,60 +0,0 @@
/*
* http_delete.c: Handles DELETE
*
* All code contained herein is covered by the Copyright as distributed
* in the README file in the main directory of the distribution of
* NCSA HTTPD.
*
* Based on NCSA HTTPd 1.3 by Rob McCool
*
*/
#include "httpd.h"
void handle_delete(char *name, char *args, int in, FILE *out) {
struct stat finfo;
char ct_bak[MAX_STRING_LEN];
if(stat(name,&finfo) == -1) {
if(find_script("DELETE",name,args,in,out))
return;
if(errno==ENOENT) {
log_reason("file does not exist",name);
unmunge_name(name);
die(NOT_FOUND,name,out);
}
else {
log_reason("file permissions deny server access",name);
unmunge_name(name);
die(FORBIDDEN,name,out);
}
}
probe_content_type(name);
if(!strcmp(content_type,CGI_MAGIC_TYPE)) {
strcpy(content_type,ct_bak);
send_cgi("DELETE",name,"",args,&finfo,in,out);
return;
}
/* Not a script, do group ann thang */
die(NOT_IMPLEMENTED,"DELETE to non-script",out);
}
void delete_node(char *name, char *args, int in, FILE *out) {
int s;
s=translate_name(name,out);
switch(s) {
case STD_DOCUMENT:
handle_delete(name,args,in,out);
return;
case REDIRECT_URL:
die(REDIRECT,name,out);
case SCRIPT_CGI:
exec_cgi_script("DELETE",name,args,in,out);
default:
die(NOT_IMPLEMENTED,"NCSA script exeuction of delete",out);
}
}

View File

@ -1,56 +1,78 @@
/* /************************************************************************
* 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
*
************************************************************************
*
* http_dir.c: Handles the on-the-fly html index generation * http_dir.c: Handles the on-the-fly html index generation
* *
* All code contained herein is covered by the Copyright as distributed
* in the README file in the main directory of the distribution of
* NCSA HTTPD.
*
* 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
*/ */
/* httpd.h includes proper directory file */ #include "config.h"
#include "httpd.h" #include "portability.h"
struct ent { #include <stdio.h>
char *name; #ifndef NO_STDLIB_H
char *icon; # include <stdlib.h>
char *alt; #endif /* NO_STDLIB_H */
char *desc; #ifndef NO_MALLOC_H
size_t size; # ifdef NEED_SYS_MALLOC_H
time_t lm; # include <sys/malloc.h>
struct ent *next; # else
}; # include <malloc.h>
# endif /* NEED_SYS_MALLOC_H */
#endif /* NO_MALLOC_H */
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <ctype.h>
#include "constants.h"
#include "http_request.h"
#include "http_dir.h"
#include "http_mime.h"
#include "http_log.h"
#include "http_config.h"
#include "http_send.h"
#include "http_alias.h"
#include "util.h"
#include "fdwrap.h"
#include "allocate.h"
/* 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
* the life time of the server. -achille
*/
struct item { static struct item *icon_list[2], *alt_list[2], *desc_list[2], *ign_list[2];
int type; static struct item *hdr_list[2], *rdme_list[2], *opts_list[2];
char *apply_to;
char *apply_path;
char *data;
struct item *next;
};
static struct item *icon_list, *alt_list, *desc_list, *ign_list;
static struct item *hdr_list, *rdme_list, *opts_list;
static int dir_opts; static int dir_opts;
void init_indexing() { void init_indexing(int local) {
icon_list = NULL; icon_list[FI_LOCAL] = NULL;
alt_list = NULL; alt_list[FI_LOCAL] = NULL;
desc_list = NULL; desc_list[FI_LOCAL] = NULL;
ign_list = NULL; ign_list[FI_LOCAL] = NULL;
hdr_list[FI_LOCAL] = NULL;
hdr_list = NULL; rdme_list[FI_LOCAL] = NULL;
rdme_list = NULL; opts_list[FI_LOCAL] = NULL;
opts_list = NULL; if (local == FI_GLOBAL) {
icon_list[FI_GLOBAL] = NULL;
alt_list[FI_GLOBAL] = NULL;
desc_list[FI_GLOBAL] = NULL;
ign_list[FI_GLOBAL] = NULL;
hdr_list[FI_GLOBAL] = NULL;
rdme_list[FI_GLOBAL] = NULL;
opts_list[FI_GLOBAL] = NULL;
}
} }
void kill_item_list(struct item *p) { void kill_item_list(struct item *p) {
@ -66,34 +88,45 @@ void kill_item_list(struct item *p) {
} }
} }
void kill_indexing() { void kill_indexing(int local) {
kill_item_list(icon_list);
kill_item_list(alt_list);
kill_item_list(desc_list);
kill_item_list(ign_list);
kill_item_list(hdr_list); kill_item_list(icon_list[FI_LOCAL]);
kill_item_list(rdme_list); kill_item_list(alt_list[FI_LOCAL]);
kill_item_list(opts_list); kill_item_list(desc_list[FI_LOCAL]);
kill_item_list(ign_list[FI_LOCAL]);
kill_item_list(hdr_list[FI_LOCAL]);
kill_item_list(rdme_list[FI_LOCAL]);
kill_item_list(opts_list[FI_LOCAL]);
if (local == FI_GLOBAL) {
kill_item_list(icon_list[FI_GLOBAL]);
kill_item_list(alt_list[FI_GLOBAL]);
kill_item_list(desc_list[FI_GLOBAL]);
kill_item_list(ign_list[FI_GLOBAL]);
kill_item_list(hdr_list[FI_GLOBAL]);
kill_item_list(rdme_list[FI_GLOBAL]);
kill_item_list(opts_list[FI_GLOBAL]);
}
init_indexing(local);
} }
struct item *new_item(int type, char *to, char *path, char *data, FILE *out) struct item *new_item(per_request *reqInfo,int type,
{ char *to, char *path, char *data) {
struct item *p; struct item *p;
if(!(p = (struct item *)malloc(sizeof(struct item)))) if(!(p = (struct item *)malloc(sizeof(struct item))))
die(NO_MEMORY,"new_item",out); die(reqInfo,SC_NO_MEMORY,"new_item");
p->type = type; p->type = type;
if(data) { if(data) {
if(!(p->data = strdup(data))) if(!(p->data = strdup(data)))
die(NO_MEMORY,"new_item",out); die(reqInfo,SC_NO_MEMORY,"new_item");
} else } else
p->data = NULL; p->data = NULL;
if(to) { if(to) {
if(!(p->apply_to = (char *)malloc(strlen(to) + 2))) if(!(p->apply_to = (char *)malloc(strlen(to) + 2)))
die(NO_MEMORY,"new_item",out); die(reqInfo,SC_NO_MEMORY,"new_item");
if((type == BY_PATH) && (!is_matchexp(to))) { if((type == BY_PATH) && (!is_matchexp(to))) {
p->apply_to[0] = '*'; p->apply_to[0] = '*';
strcpy(&p->apply_to[1],to); strcpy(&p->apply_to[1],to);
@ -103,25 +136,29 @@ struct item *new_item(int type, char *to, char *path, char *data, FILE *out)
p->apply_to = NULL; p->apply_to = NULL;
if(!(p->apply_path = (char *)malloc(strlen(path) + 2))) if(!(p->apply_path = (char *)malloc(strlen(path) + 2)))
die(NO_MEMORY,"new_item",out); die(reqInfo,SC_NO_MEMORY,"new_item");
sprintf(p->apply_path,"%s*",path); sprintf(p->apply_path,"%s*",path);
return p; return p;
} }
void add_alt(int type, char *alt, char *to, char *path, FILE *out) { void add_alt(per_request *reqInfo, int local, int type,
char *alt, char *to, char *path)
{
struct item *p; struct item *p;
if(type == BY_PATH) { if(type == BY_PATH) {
if(!strcmp(to,"**DIRECTORY**")) if(!strcmp(to,"**DIRECTORY**"))
strcpy(to,"^^DIRECTORY^^"); strcpy(to,"^^DIRECTORY^^");
} }
p = new_item(type,to,path,alt,out); p = new_item(reqInfo,type,to,path,alt);
p->next = alt_list; p->next = alt_list[local];
alt_list = p; alt_list[local] = p;
} }
void add_icon(int type, char *icon, char *to, char *path, FILE *out) { void add_icon(per_request *reqInfo, int local, int type,
char *icon, char *to, char *path)
{
struct item *p; struct item *p;
char iconbak[MAX_STRING_LEN]; char iconbak[MAX_STRING_LEN];
@ -129,61 +166,68 @@ void add_icon(int type, char *icon, char *to, char *path, FILE *out) {
if(icon[0] == '(') { if(icon[0] == '(') {
char alt[MAX_STRING_LEN]; char alt[MAX_STRING_LEN];
getword(alt,iconbak,','); getword(alt,iconbak,',');
add_alt(type,&alt[1],to,path,out); add_alt(reqInfo,local,type,&alt[1],to,path);
iconbak[strlen(iconbak) - 1] = '\0'; iconbak[strlen(iconbak) - 1] = '\0';
} }
if(type == BY_PATH) { if(type == BY_PATH) {
if(!strcmp(to,"**DIRECTORY**")) if(!strcmp(to,"**DIRECTORY**"))
strcpy(to,"^^DIRECTORY^^"); strcpy(to,"^^DIRECTORY^^");
} }
p = new_item(type,to,path,iconbak,out); p = new_item(reqInfo,type,to,path,iconbak);
p->next = icon_list; p->next = icon_list[local];
icon_list = p; icon_list[local] = p;
} }
void add_desc(int type, char *desc, char *to, char *path, FILE *out) { void add_desc(per_request *reqInfo, int local, int type,
char *desc, char *to, char *path)
{
struct item *p; struct item *p;
p = new_item(type,to,path,desc,out); p = new_item(reqInfo,type,to,path,desc);
p->next = desc_list; p->next = desc_list[local];
desc_list = p; desc_list[local] = p;
} }
void add_ignore(char *ext, char *path, FILE *out) { void add_ignore(per_request *reqInfo, int local, char *ext, char *path)
{
struct item *p; struct item *p;
p = new_item(0,ext,path,NULL,out); p = new_item(reqInfo,0,ext,path,NULL);
p->next = ign_list; p->next = ign_list[local];
ign_list = p; ign_list[local] = p;
} }
void add_header(char *name, char *path, FILE *out) { void add_header(per_request *reqInfo, int local, char *name, char *path)
{
struct item *p; struct item *p;
p = new_item(0,NULL,path,name,out); p = new_item(reqInfo,0,NULL,path,name);
p->next = hdr_list; p->next = hdr_list[local];
hdr_list = p; hdr_list[local] = p;
} }
void add_readme(char *name, char *path, FILE *out) { void add_readme(per_request *reqInfo, int local, char *name, char *path)
{
struct item *p; struct item *p;
p = new_item(0,NULL,path,name,out); p = new_item(reqInfo,0,NULL,path,name);
p->next = rdme_list; p->next = rdme_list[local];
rdme_list = p; rdme_list[local] = p;
} }
void add_opts_int(int opts, char *path, FILE *out) { void add_opts_int(per_request *reqInfo, int local, int opts, char *path)
{
struct item *p; struct item *p;
p = new_item(0,NULL,path,NULL,out); p = new_item(reqInfo,0,NULL,path,NULL);
p->type = opts; p->type = opts;
p->next = opts_list; p->next = opts_list[local];
opts_list = p; opts_list[local] = p;
} }
void add_opts(char *optstr, char *path, FILE *out) { void add_opts(per_request *reqInfo, int local, char *optstr, char *path)
{
char w[MAX_STRING_LEN]; char w[MAX_STRING_LEN];
int opts = 0; int opts = 0;
@ -204,76 +248,93 @@ void add_opts(char *optstr, char *path, FILE *out) {
else if(!strcasecmp(w,"None")) else if(!strcasecmp(w,"None"))
opts = 0; opts = 0;
} }
add_opts_int(opts,path,out); add_opts_int(reqInfo,local,opts,path);
} }
char *find_item(struct item *list, char *path, int path_only) { char *find_item(per_request *reqInfo, struct item *list[2], char *path,
struct item *p = list; int path_only)
{
struct item *p = NULL;
int i;
char *file_type,*file_encoding;
while(p) { file_type = newString(MAX_STRING_LEN,STR_TMP);
file_encoding = newString(MAX_STRING_LEN,STR_TMP);
for (i=0; i < 2; i++) {
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(pathbak); if(!file_encoding[0]) {
if(!content_encoding[0]) { if(p->type == BY_TYPE) {
if(p->type == BY_TYPE) { if(!strcmp_match(file_type,p->apply_to))
if(!strcmp_match(content_type,p->apply_to)) goto found_item;
return p->data; }
} } else {
} else { if(p->type == BY_ENCODING) {
if(p->type == BY_ENCODING) { if(!strcmp_match(file_encoding,p->apply_to))
if(!strcmp_match(content_encoding,p->apply_to)) goto found_item;
return p->data; }
} }
} }
}
} }
p = p->next; }
} }
freeString(file_type);
freeString(file_encoding);
return NULL; return NULL;
found_item:
freeString(file_type);
freeString(file_encoding);
return p->data;
} }
#define find_icon(p,t) find_item(icon_list,p,t) #define find_icon(r,p,t) find_item(r,icon_list,p,t)
#define find_alt(p,t) find_item(alt_list,p,t) #define find_alt(r,p,t) find_item(r,alt_list,p,t)
#define find_desc(p) find_item(desc_list,p,0) #define find_desc(r,p) find_item(r,desc_list,p,0)
#define find_header(p) find_item(hdr_list,p,0) #define find_header(r,p) find_item(r,hdr_list,p,0)
#define find_readme(p) find_item(rdme_list,p,0) #define find_readme(r,p) find_item(r,rdme_list,p,0)
int ignore_entry(char *path) { int ignore_entry(char *path)
struct item *p = ign_list; {
int i;
struct item *p = NULL;
while(p) { for (i=0; i < 2; i++)
if(!strcmp_match(path,p->apply_path)) for (p = ign_list[i]; p; p = p->next)
if(!strcmp_match(path,p->apply_to)) if(!strcmp_match(path,p->apply_path))
return 1; if(!strcmp_match(path,p->apply_to))
p = p->next; return 1;
} return 0;
return 0;
} }
int find_opts(char *path) { int find_opts(char *path)
struct item *p = opts_list; {
int i;
struct item *p = NULL;
while(p) { for (i=0; i < 2; i++)
if(!strcmp_match(path,p->apply_path)) for (p = opts_list[i]; p; p = p->next)
return p->type; if(!strcmp_match(path,p->apply_path))
p = p->next; return p->type;
} return 0;
return 0;
} }
int insert_readme(char *name, char *readme_fname, int rule, FILE *fd) { int insert_readme(per_request *reqInfo, char *name,
char *readme_fname, int rule) {
char fn[MAX_STRING_LEN]; char fn[MAX_STRING_LEN];
FILE *r; FILE *r;
struct stat finfo; struct stat finfo;
@ -286,35 +347,36 @@ int insert_readme(char *name, char *readme_fname, int rule, FILE *fd) {
if(stat(fn,&finfo) == -1) if(stat(fn,&finfo) == -1)
return 0; return 0;
plaintext=1; plaintext=1;
if(rule) bytes_sent += fprintf(fd,"<HR>%c",LF); if(rule) rprintf(reqInfo,"<HR>%c",LF);
bytes_sent += fprintf(fd,"<PRE>%c",LF); rprintf(reqInfo,"<PRE>%c",LF);
} }
else if(rule) bytes_sent += fprintf(fd,"<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_fd(r,fd,NULL); send_fp(reqInfo,r,NULL);
fclose(r); FClose(r);
if(plaintext) if(plaintext) rprintf(reqInfo,"</PRE>%c",LF);
bytes_sent += fprintf(fd,"</PRE>%c",LF);
return 1; return 1;
} }
char *find_title(char *filename) { char *find_title(per_request *reqInfo, char *filename) {
char titlebuf[MAX_STRING_LEN], *find = "<TITLE>"; char titlebuf[MAX_STRING_LEN], *find = "<TITLE>";
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(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"))) goto not_found;
return NULL;
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++) {
@ -326,15 +388,18 @@ char *find_title(char *filename) {
for(y=x;titlebuf[y];y++) for(y=x;titlebuf[y];y++)
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;
} }
@ -363,7 +428,8 @@ void escape_html(char *fn) {
fn[x] = '\0'; fn[x] = '\0';
} }
struct ent *make_dir_entry(char *path, char *name, FILE *out) { struct ent *make_dir_entry(per_request *reqInfo, char *path,
char *name) {
struct ent *p; struct ent *p;
struct stat finfo; struct stat finfo;
char t[MAX_STRING_LEN]; char t[MAX_STRING_LEN];
@ -378,9 +444,9 @@ struct ent *make_dir_entry(char *path, char *name, FILE *out) {
return(NULL); return(NULL);
if(!(p=(struct ent *)malloc(sizeof(struct ent)))) if(!(p=(struct ent *)malloc(sizeof(struct ent))))
die(NO_MEMORY,"make_dir_entry",out); die(reqInfo,SC_NO_MEMORY,"make_dir_entry");
if(!(p->name=(char *)malloc(strlen(name) + 2))) if(!(p->name=(char *)malloc(strlen(name) + 2)))
die(NO_MEMORY,"make_dir_entry",out); die(reqInfo,SC_NO_MEMORY,"make_dir_entry");
if(dir_opts & FANCY_INDEXING) { if(dir_opts & FANCY_INDEXING) {
if((!(dir_opts & FANCY_INDEXING)) || stat(t,&finfo) == -1) { if((!(dir_opts & FANCY_INDEXING)) || stat(t,&finfo) == -1) {
@ -393,35 +459,36 @@ struct ent *make_dir_entry(char *path, char *name, FILE *out) {
} }
else { else {
p->lm = finfo.st_mtime; p->lm = finfo.st_mtime;
p->size = -1; p->size = -1;
p->icon = NULL; p->icon = NULL;
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(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("^^DIRECTORY^^",1); p->icon = find_icon(reqInfo,"^^DIRECTORY^^",1);
if(!(tmp = find_alt(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");
} else { }
p->alt = strdup(tmp); else {
} p->alt = strdup(tmp);
}
p->size = -1; p->size = -1;
strncpy_dir(p->name,name,MAX_STRING_LEN); strncpy_dir(p->name,name, MAX_STRING_LEN);
} }
else { else {
p->icon = find_icon(t,0); p->icon = find_icon(reqInfo,t,0);
tmp = find_alt(t,0); tmp = find_alt(reqInfo,t,0);
if (tmp != NULL) p->alt = strdup(tmp); if (tmp != NULL) p->alt = strdup(tmp);
p->size = finfo.st_size; p->size = finfo.st_size;
strcpy(p->name,name); strcpy(p->name,name);
} }
} }
if(p->desc = find_desc(t)) if((p->desc = find_desc(reqInfo,t)))
p->desc = strdup(p->desc); p->desc = strdup(p->desc);
if((!p->desc) && (dir_opts & SCAN_HTML_TITLES)) if((!p->desc) && (dir_opts & SCAN_HTML_TITLES))
p->desc = find_title(t); p->desc = find_title(reqInfo,t);
} }
else { else {
p->icon = NULL; p->icon = NULL;
@ -435,25 +502,22 @@ struct ent *make_dir_entry(char *path, char *name, FILE *out) {
} }
void send_size(size_t size, FILE *fd) { void send_size(per_request *reqInfo, size_t size) {
if(size == -1) { if(size == -1) {
fputs(" -",fd); rputs(" -",reqInfo);
bytes_sent += 5;
} }
else { else {
if(!size) { if(!size) {
fputs(" 0K",fd); rputs(" 0K",reqInfo);
bytes_sent += 5;
} }
else if(size < 1024) { else if(size < 1024) {
fputs(" 1K",fd); rputs(" 1K",reqInfo);
bytes_sent += 5;
} }
else if(size < 1048576) else if(size < 1048576)
bytes_sent += fprintf(fd,"%4dK",size / 1024); rprintf(reqInfo,"%4dK",size / 1024);
else else
bytes_sent += fprintf(fd,"%4dM",size / 1048576); rprintf(reqInfo,"%4dM",size / 1048576);
} }
} }
@ -483,7 +547,7 @@ void terminate_description(char *desc) {
} }
void output_directories(struct ent **ar,int n,char *name,FILE *fd) void output_directories(per_request *reqInfo, struct ent **ar,int n,char *name)
{ {
int x; int x;
char anchor[2 * MAX_STRING_LEN + 64],t[MAX_STRING_LEN],t2[MAX_STRING_LEN]; char anchor[2 * MAX_STRING_LEN + 64],t[MAX_STRING_LEN],t2[MAX_STRING_LEN];
@ -493,29 +557,28 @@ void output_directories(struct ent **ar,int n,char *name,FILE *fd)
name[0] = '/'; name[1] = '\0'; name[0] = '/'; name[1] = '\0';
} }
/* aaaaargh Solaris sucks. */ /* aaaaargh Solaris sucks. */
fflush(fd); rflush(reqInfo);
if(dir_opts & FANCY_INDEXING) { if(dir_opts & FANCY_INDEXING) {
fputs("<PRE>",fd); rputs("<PRE>",reqInfo);
bytes_sent += 5; if((tp = find_icon(reqInfo,"^^BLANKICON^^",1)))
if(tp = find_icon("^^BLANKICON^^",1)) rprintf(reqInfo,"<IMG SRC=\"%s\" ALT=\" \"> ",tp);
bytes_sent += (fprintf(fd,"<IMG SRC=\"%s\" ALT=\" \"> ",tp)); rprintf(reqInfo,"Name ");
bytes_sent += fprintf(fd,"Name ");
if(!(dir_opts & SUPPRESS_LAST_MOD)) if(!(dir_opts & SUPPRESS_LAST_MOD))
bytes_sent += fprintf(fd,"Last modified "); rprintf(reqInfo,"Last modified ");
if(!(dir_opts & SUPPRESS_SIZE)) if(!(dir_opts & SUPPRESS_SIZE))
bytes_sent += fprintf(fd,"Size "); rprintf(reqInfo,"Size ");
if(!(dir_opts & SUPPRESS_DESC)) if(!(dir_opts & SUPPRESS_DESC))
bytes_sent += fprintf(fd,"Description"); rprintf(reqInfo,"Description");
bytes_sent += fprintf(fd,"%c<HR>%c",LF,LF); rprintf(reqInfo,"%c<HR>%c",LF,LF);
} }
else { else {
fputs("<UL>",fd); rputs("<UL>",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);
@ -523,6 +586,10 @@ void output_directories(struct ent **ar,int n,char *name,FILE *fd)
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>");
@ -544,56 +611,51 @@ void output_directories(struct ent **ar,int n,char *name,FILE *fd)
if(dir_opts & FANCY_INDEXING) { if(dir_opts & FANCY_INDEXING) {
if(dir_opts & ICONS_ARE_LINKS) if(dir_opts & ICONS_ARE_LINKS)
bytes_sent += fprintf(fd,"%s",anchor); rprintf(reqInfo,"%s",anchor);
if((ar[x]->icon) || default_icon[0] || local_default_icon[0]) { if((ar[x]->icon) || reqInfo->hostInfo->default_icon[0]
bytes_sent += fprintf(fd,"<IMG SRC=\"%s\" ALT=\"[%s]\">", || local_default_icon[0]) {
ar[x]->icon ? ar[x]->icon : rprintf(reqInfo,"<IMG SRC=\"%s\" ALT=\"[%s]\">",
local_default_icon[0] ? ar[x]->icon ? ar[x]->icon :
local_default_icon : default_icon, local_default_icon[0] ?
ar[x]->alt ? ar[x]->alt : " "); local_default_icon :
reqInfo->hostInfo->default_icon,
ar[x]->alt ? ar[x]->alt : " ");
} }
if(dir_opts & ICONS_ARE_LINKS) { if(dir_opts & ICONS_ARE_LINKS) {
fputs("</A>",fd); rputs("</A>",reqInfo);
bytes_sent += 4;
} }
bytes_sent += fprintf(fd," %s",anchor); rprintf(reqInfo," %s",anchor);
bytes_sent += fprintf(fd,"%-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,fd); rputs(t,reqInfo);
bytes_sent += strlen(t);
} }
else { else {
fputs(" ",fd); rputs(" ",reqInfo);
bytes_sent += 17;
} }
} }
if(!(dir_opts & SUPPRESS_SIZE)) { if(!(dir_opts & SUPPRESS_SIZE)) {
send_size(ar[x]->size,fd); send_size(reqInfo,ar[x]->size);
fputs(" ",fd); rputs(" ",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);
bytes_sent += fprintf(fd,"%s",ar[x]->desc); rprintf(reqInfo,"%s",ar[x]->desc);
} }
} }
} }
else else
bytes_sent += fprintf(fd,"<LI> %s %s",anchor,t2); rprintf(reqInfo,"<LI> %s %s",anchor,t2);
fputc(LF,fd); rputc(LF,reqInfo);
++bytes_sent;
} }
if(dir_opts & FANCY_INDEXING) { if(dir_opts & FANCY_INDEXING) {
fputs("</PRE>",fd); rputs("</PRE>",reqInfo);
bytes_sent += 6;
} }
else { else {
fputs("</UL>",fd); rputs("</UL>",reqInfo);
bytes_sent += 5;
} }
} }
@ -604,59 +666,57 @@ int dsortf(struct ent **s1,struct ent **s2)
} }
void index_directory(char *name, FILE *fd) void index_directory(per_request *reqInfo)
{ {
DIR *d; DIR *d;
struct DIR_TYPE *dstruct; struct DIR_TYPE *dstruct;
int num_ent=0,x; int num_ent=0,x;
struct ent *head,*p,*q; struct ent *head,*p,*q;
struct ent **ar; struct ent **ar;
char unmunged_name[HUGE_STRING_LEN];
char *tmp; char *tmp;
strncpy_dir(unmunged_name,name,HUGE_STRING_LEN);
unmunge_name(unmunged_name);
if(!(d=opendir(name))) if(!(d=Opendir(reqInfo->filename)))
die(FORBIDDEN,unmunged_name,fd); die(reqInfo,SC_FORBIDDEN,reqInfo->url);
strcpy(content_type,"text/html"); strcpy(reqInfo->outh_content_type,"text/html");
if(!assbackwards) if(reqInfo->http_version != P_HTTP_0_9)
send_http_header(fd); send_http_header(reqInfo);
if(header_only) { if(reqInfo->method == M_HEAD) {
closedir(d); Closedir(d);
return; log_transaction(reqInfo);
return;
} }
bytes_sent = 0; reqInfo->bytes_sent = 0;
dir_opts = find_opts(name); dir_opts = find_opts(reqInfo->filename);
/* Spew HTML preamble */ /* Spew HTML preamble */
bytes_sent += fprintf(fd,"<HEAD><TITLE>Index of %s</TITLE></HEAD><BODY>", rprintf(reqInfo,"<HEAD><TITLE>Index of %s</TITLE></HEAD><BODY>",
unmunged_name); reqInfo->url);
fputc(LF,fd); rputc(LF,reqInfo);
++bytes_sent;
if((!(tmp = find_header(name))) || (!(insert_readme(name,tmp,0,fd)))) if((!(tmp = find_header(reqInfo, reqInfo->filename))) ||
bytes_sent += fprintf(fd,"<H1>Index of %s</H1>%c",unmunged_name,LF); (!(insert_readme(reqInfo,reqInfo->filename,tmp,0))))
rprintf(reqInfo, "<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
* linked list and then arrayificate them so qsort can use them. * linked list and then arrayificate them so qsort can use them.
*/ */
head=NULL; head=NULL;
while(dstruct=readdir(d)) { while((dstruct=readdir(d))) {
if(p = make_dir_entry(name,dstruct->d_name,fd)) { if((p = make_dir_entry(reqInfo,reqInfo->filename,dstruct->d_name))) {
p->next = head; p->next = head;
head = p; head = p;
num_ent++; num_ent++;
} }
} }
if(!(ar=(struct ent **) malloc(num_ent*sizeof(struct ent *)))) { if(!(ar=(struct ent **) malloc(num_ent*sizeof(struct ent *)))) {
closedir(d); Closedir(d);
die(NO_MEMORY,"index_directory",fd); die(reqInfo,SC_NO_MEMORY,"index_directory");
} }
p=head; p=head;
x=0; x=0;
@ -670,8 +730,8 @@ void index_directory(char *name, FILE *fd)
(int (*))dsortf); (int (*))dsortf);
#else #else
(int (*)(const void *,const void *))dsortf); (int (*)(const void *,const void *))dsortf);
#endif #endif /* ULTRIX_BRAIN_DEATH */
output_directories(ar,num_ent,unmunged_name,fd); output_directories(reqInfo,ar,num_ent,reqInfo->url);
free(ar); free(ar);
q = head; q = head;
while(q) { while(q) {
@ -684,18 +744,15 @@ void index_directory(char *name, FILE *fd)
free(q); free(q);
q=p; q=p;
} }
closedir(d); Closedir(d);
if(dir_opts & FANCY_INDEXING) if(dir_opts & FANCY_INDEXING)
if(tmp = find_readme(name)) if((tmp = find_readme(reqInfo,reqInfo->filename)))
insert_readme(name,tmp,1,fd); insert_readme(reqInfo,reqInfo->filename,tmp,1);
else { else {
fputs("</UL>",fd); rputs("</UL>",reqInfo);
bytes_sent += 5;
} }
fputs("</BODY>",fd); rputs("</BODY>", reqInfo);
fflush(fd); rflush(reqInfo);
bytes_sent += 7; log_transaction(reqInfo);
fflush(fd);
log_transaction();
} }

73
src/http_dir.h Normal file
View File

@ -0,0 +1,73 @@
/************************************************************************
* 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
*
************************************************************************
*
* http_dir.h,v 1.6 1995/11/28 09:02:01 blong Exp
*
************************************************************************
*
* http_dir.h contains the following information including:
* struct ent
* struct item
*
*/
#ifndef _HTTP_DIR_H_
#define _HTTP_DIR_H_
/* constants used in this module */
/* Fancy Indexing Locality */
#define FI_LOCAL 0
#define FI_GLOBAL 1
/* Fancy Indexing Options */
#define ICONS_ARE_LINKS 2
#define SCAN_HTML_TITLES 4
#define SUPPRESS_LAST_MOD 8
#define SUPPRESS_SIZE 16
#define SUPPRESS_DESC 32
struct ent {
char *name;
char *icon;
char *alt;
char *desc;
size_t size;
time_t lm;
struct ent *next;
};
struct item {
int type;
char *apply_to;
char *apply_path;
char *data;
struct item *next;
};
/* http_dir function prototypes */
void index_directory(per_request *reqInfo);
void add_icon(per_request *reqInfo, int local, int type, char *icon, char *to, char *path);
void add_alt(per_request *reqInfo, int local, int type, char *alt, char *to, char *path);
void add_desc(per_request *reqInfo, int local, int type, char *desc, char *to, char *path);
void add_ignore(per_request *reqInfo, int local, char *ext, char *path);
void add_header(per_request *reqInfo, int local, char *name, char *path);
void add_readme(per_request *reqInfo, int local, char *name, char *path);
void add_opts(per_request *reqInfo, int local, char *optstr, char *path);
void add_opts_int(per_request *reqInfo, int local, int opts, char *path);
void send_size(per_request *reqInfo, size_t size);
void init_indexing(int local);
void kill_indexing(int local);
#endif /* _HTTP_DIR_H_ */

View File

@ -1,252 +0,0 @@
/*
* http_get.c: Handles things associated with GET
*
* All code contained herein is covered by the Copyright as distributed
* in the README file in the main directory of the distribution of
* NCSA HTTPD.
*
* 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.
*/
#include "httpd.h"
int header_only;
int num_includes;
int allow;
char allow_options;
void send_file(char *file, FILE *fd, struct stat *fi,
char *path_args, char *args)
{
FILE *f;
set_content_type(file);
if((allow_options & OPT_INCLUDES) && (!content_encoding[0])) {
#ifdef XBITHACK
if((fi->st_mode & S_IXUSR) ||
(!strcmp(content_type,INCLUDES_MAGIC_TYPE))) {
#else
if(!strcmp(content_type,INCLUDES_MAGIC_TYPE)) {
#endif
bytes_sent = 0;
send_parsed_file(file,fd,path_args,args,
allow_options & OPT_INCNOEXEC);
log_transaction();
return;
}
}
if(!(f=fopen(file,"r"))) {
log_reason("file permissions deny server access",file);
unmunge_name(file);
die(FORBIDDEN,file,fd); /* we've already established that it exists */
}
bytes_sent = 0;
if(!assbackwards) {
set_content_length(fi->st_size);
if (set_last_modified(fi->st_mtime,fd)) {
fclose(f);
return;
}
send_http_header(fd);
}
num_includes=0;
if(!header_only)
send_fd(f,fd,NULL);
log_transaction();
fclose(f);
}
/* Almost exactly equalivalent to exec_cgi_script, but this one
gets all of the path info passed to it, instead of calling get_path_info */
void send_cgi(char *method, char *file, char *path_args, char *args,
struct stat *finfo, int in, FILE *fd)
{
int m = M_GET;
int stub_returns;
if((!strcmp(method,"GET")) || (!strcmp(method,"HEAD")))
m = M_GET;
else if(!strcmp(method,"POST"))
m = M_POST;
else if(!strcmp(method,"PUT"))
m = M_PUT;
else if(!strcmp(method,"DELETE"))
m = M_DELETE;
evaluate_access(file,finfo,m,&allow,&allow_options,fd);
if((!allow) || (!(allow_options & OPT_EXECCGI))) {
log_reason("client denied by server configuration",file);
unmunge_name(file);
die(FORBIDDEN,file,fd);
}
if(!(in_headers_env = add_common_vars(in_headers_env,fd)))
die(NO_MEMORY,"send_cgi",fd);
bytes_sent = 0;
stub_returns = cgi_stub(method,file,path_args,args,in_headers_env,finfo,in,fd);
free_env(in_headers_env);
in_headers_env = NULL;
switch (stub_returns) {
case REDIRECT_URL:
die(REDIRECT,location,fd);
break;
case REDIRECT_LOCAL:
break;
default:
log_transaction();
break;
}
}
void send_node(char *file, char *args, int in, FILE *fd)
{
struct stat finfo;
char pa[MAX_STRING_LEN];
int length = 0;
register x = 0;
/* Remove all of the trailing slashes from the filename in order
to fix security hole. All trailing slashes are placed in the
path alias (pa) array */
length = strlen(file);
while (length && (file[length-1] == '/') && (x < MAX_STRING_LEN)) {
pa[x] = '/';
x++;
file[length-1] = '\0';
length--;
}
pa[x] = '\0';
if(stat(file,&finfo) == -1) {
/* Look for script or include document */
int n=count_dirs(file),i,l;
char t[MAX_STRING_LEN];
for(i=n;i;--i) {
make_dirstr(file,i,t);
probe_content_type(t);
if(!strcmp(content_type,CGI_MAGIC_TYPE)) {
if(stat(t,&finfo) == -1)
continue;
if(!(S_ISREG(finfo.st_mode)))
break;
l=strlen(t);
strncat(pa,&file[l],MAX_STRING_LEN - strlen(pa));
file[l] = '\0';
send_cgi("GET",file,pa,args,&finfo,in,fd);
return;
} else if(!strcmp(content_type,INCLUDES_MAGIC_TYPE)) {
if(stat(t,&finfo) == -1)
continue;
l=strlen(t);
strncat(pa,&file[l],MAX_STRING_LEN - strlen(pa));
file[l] = '\0';
goto send_regular;
}
}
if(errno==ENOENT) {
log_reason("file does not exist",file);
unmunge_name(file);
die(NOT_FOUND,file,fd);
}
else {
log_reason("file permissions deny server access",file);
unmunge_name(file);
die(FORBIDDEN,file,fd);
}
}
/*
probe_content_type(file);
if(S_ISREG(finfo.st_mode) && (!strcmp(content_type,CGI_MAGIC_TYPE))) {
send_cgi("GET",file,pa,args,&finfo,in,fd);
return;
}
*/
send_regular: /* aaaaack */
evaluate_access(file,&finfo,M_GET,&allow,&allow_options, fd);
if(!allow) {
log_reason("client denied by server configuration",file);
unmunge_name(file);
die(FORBIDDEN,file,fd);
}
if(S_ISDIR(finfo.st_mode)) {
char ifile[HUGE_STRING_LEN];
/* Path Alias (pa) array should now have the trailing slash */
/* if(file[strlen(file) - 1] != '/') { */
if (pa[0] != '/') {
char url[HUGE_STRING_LEN];
strcpy_dir(ifile,file);
unmunge_name(ifile);
construct_url(url,ifile);
escape_url(url);
die(REDIRECT,url,fd);
}
make_full_path(file,index_name,ifile);
if(stat(ifile,&finfo) == -1) {
if(allow_options & OPT_INDEXES)
index_directory(file,fd);
else {
log_reason("file permissions deny server access",file);
unmunge_name(file);
die(FORBIDDEN,file,fd);
}
}
else {
probe_content_type(ifile);
if(!strcmp(content_type,CGI_MAGIC_TYPE))
send_cgi("GET",ifile,pa,args,&finfo,in,fd);
else
send_file(ifile,fd,&finfo,pa,args);
}
return;
}
if(S_ISREG(finfo.st_mode)) {
probe_content_type(file);
if (!strcmp(content_type, CGI_MAGIC_TYPE))
send_cgi("GET",file,pa,args,&finfo,in,fd);
else
send_file(file,fd,&finfo,pa,args);
} else {
log_reason("improper file type",file);
unmunge_name(file);
die(FORBIDDEN,file,fd); /* device driver or pipe, no permission */
}
}
void process_get(int in, FILE *out, char *m, char *url, char *args) {
int s;
if(assbackwards && header_only) {
header_only = 0;
die(BAD_REQUEST,"Invalid HTTP/0.9 method.",out);
}
s=translate_name(url,out);
switch(s) {
case STD_DOCUMENT:
send_node(url,args,in,out);
return;
case REDIRECT_URL:
die(REDIRECT,url,out);
case SCRIPT_NCSA:
exec_get_NCSA(url,args,in,out);
return;
case SCRIPT_CGI:
exec_cgi_script(m,url,args,in,out);
return;
}
}

File diff suppressed because it is too large Load Diff

40
src/http_include.h Normal file
View File

@ -0,0 +1,40 @@
/************************************************************************
* 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
*
************************************************************************
*
* http_include.h,v 1.7 1996/03/27 20:44:04 blong Exp
*
************************************************************************
*
*/
#ifndef _HTTP_INCLUDE_H_
#define _HTTP_INCLUDE_H_
/* defines used in this module */
#define STARTING_SEQUENCE "<!--#"
#define ENDING_SEQUENCE "-->"
#define DEFAULT_ERROR_MSG "[an error occurred while processing this directive]"
#define DEFAULT_TIME_FORMAT "%A, %d-%b-%y %T %Z"
#define SIZEFMT_BYTES 0
#define SIZEFMT_KMG 1
#define NUM_INCLUDE_VARS 5
/* http_include */
void send_parsed_file(per_request *reqInfo, int noexec);
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_ */

View File

@ -1,41 +1,59 @@
/* /************************************************************************
* 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
*
************************************************************************
*
* http_ipc.c,v 1.22 1996/02/22 23:46:59 blong Exp
*
************************************************************************
*
* http_ipc.c * http_ipc.c
* Handles the file descriptor passing. Should work under BSD and * Handles the file descriptor passing. Should work under BSD and
* SYSV. * SYSV.
* *
* All code contained herein is covered by the Copyright as distributed
* in the README file in the main directory of the distribution of
* NCSA HTTPD.
*
* 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.
*/ */
#include "config.h"
#include "portability.h"
#ifndef NO_PASS #ifndef NO_PASS
#include "httpd.h"
#include <sys/types.h> #include <sys/types.h>
#if defined(FD_BSD) #include <sys/socket.h>
#include <sys/uio.h> #include <stdio.h>
#include <errno.h> #ifndef NO_STDLIB_H
#include <stddef.h> # include <stdlib.h>
#endif /* NO_STDLIB_H */
#include "constants.h"
#include "host_config.h"
#include "http_log.h"
#include "http_ipc.h"
#ifdef FD_BSD
# include <sys/uio.h>
# include <errno.h>
# include <stddef.h>
#elif defined(FD_SYSV) #elif defined(FD_SYSV)
#ifdef NEED_SPIPE # ifdef NEED_SPIPE
#define SPX_DEVICE "/dev/spx" # include <sys/fcntl.h>
#include <sys/stream.h> # define SPX_DEVICE "/dev/spx"
#endif # include <sys/stream.h>
#include <stropts.h> # endif /* NEED_SPIPE */
#endif # include <stropts.h>
#include "new.h" #elif defined(FD_LINUX)
# include <fcntl.h>
#endif /* FD_BSD */
#ifdef FD_SYSV #ifdef FD_SYSV
@ -65,7 +83,8 @@ int pass_fd(int clifd, int fd) {
return 0; return 0;
} }
int recv_fd(int servfd) { int recv_fd(int servfd)
{
int newfd, nread, flag, status; int newfd, nread, flag, status;
char *ptr, buf[IOBUFSIZE]; char *ptr, buf[IOBUFSIZE];
struct strbuf dat; struct strbuf dat;
@ -77,20 +96,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);
} }
@ -122,8 +141,10 @@ int s_pipe(int fd[2]) {
if ((fd[0] = open(SPX_DEVICE, O_RDWR)) < 0) if ((fd[0] = open(SPX_DEVICE, O_RDWR)) < 0)
return -1; return -1;
if ((fd[1] = open(SPX_DEVICE, O_RDWR)) < 0) if ((fd[1] = open(SPX_DEVICE, O_RDWR)) < 0) {
close(fd[0]);
return -1; return -1;
}
/* /*
* Now link these two streams together with an I_FDINSERT ioctl * Now link these two streams together with an I_FDINSERT ioctl
@ -160,7 +181,7 @@ int s_pipe(int fd[2]) {
#ifdef FD_BSDRENO #ifdef FD_BSDRENO
static struct cmsghdr *cmptr = NULL; static struct cmsghdr *cmptr = NULL;
#define CONTROLLEN (sizeof(struct cmsghdr) + sizeof(int)) #define CONTROLLEN (sizeof(struct cmsghdr) + sizeof(int))
#endif #endif /* FD_BSDRENO */
int pass_fd(int clifd, int fd) { int pass_fd(int clifd, int fd) {
struct iovec iov[1]; struct iovec iov[1];
@ -180,7 +201,7 @@ int pass_fd(int clifd, int fd) {
#else #else
msg.msg_accrights = NULL; msg.msg_accrights = NULL;
msg.msg_accrightslen = 0; msg.msg_accrightslen = 0;
#endif #endif /* FD_BSDRENO */
buf[1] = -fd; buf[1] = -fd;
if (buf[1] == 0) if (buf[1] == 0)
buf[1] = 1; buf[1] = 1;
@ -197,7 +218,7 @@ int pass_fd(int clifd, int fd) {
#else #else
msg.msg_accrights = (caddr_t) &fd; msg.msg_accrights = (caddr_t) &fd;
msg.msg_accrightslen = sizeof(int); msg.msg_accrightslen = sizeof(int);
#endif #endif /* FD_BSDRENO */
buf[1] = 0; buf[1] = 0;
} }
buf[0] = 0; buf[0] = 0;
@ -235,21 +256,21 @@ int recv_fd(int servfd) {
#else #else
msg.msg_accrights = (caddr_t) &newfd; msg.msg_accrights = (caddr_t) &newfd;
msg.msg_accrightslen = sizeof(int); msg.msg_accrightslen = sizeof(int);
#endif #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;
@ -258,14 +279,14 @@ int recv_fd(int servfd) {
if (msg.msg_controllen != CONTROLLEN) if (msg.msg_controllen != CONTROLLEN)
#else #else
if (msg.msg_accrightslen != sizeof(int)) if (msg.msg_accrightslen != sizeof(int))
#endif #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
newfd = *(int *)CMSG_DATA(cmptr); newfd = *(int *)CMSG_DATA(cmptr);
#endif #endif /* FD_BSDRENO */
} else } else
newfd = -status; newfd = -status;
nread -= 2; nread -= 2;
@ -279,6 +300,40 @@ int recv_fd(int servfd) {
} }
#endif #endif /* FD_BSD */
#endif #ifdef FD_LINUX
int pass_fd(int clifd, int fd) {
char buf[128];
sprintf(buf, "/proc/%d/fd/%d", (int)getpid(), fd);
if (write(clifd, buf, sizeof(buf)) < 0) {
log_error("pass_fd: write failed",gConfiguration->error_log);
return(-1);
}
read(clifd, buf, 2); /* Wait for OK */
return(0);
}
int recv_fd(int servfd) {
char buf[128];
int fd;
if (read(servfd, buf, sizeof(buf)) != sizeof(buf)) {
log_error("recv_fd: read failed",gConfiguration->error_log);
return(-1);
}
fd = open(buf, O_RDWR);
(void) write(servfd, "OK", 2); /* Tell 'em we've aquired the fd */
if (fd < 0) {
log_error(strerror(errno),gConfiguration->error_log);
log_error(buf,gConfiguration->error_log);
log_error("recv_fd: open failed",gConfiguration->error_log);
}
return(fd);
}
#endif /* FD_LINUX */
#endif /* NO_PASS */

27
src/http_ipc.h Normal file
View File

@ -0,0 +1,27 @@
/************************************************************************
* 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
*
************************************************************************
*
* http_ipc.h,v 1.3 1995/07/25 06:43:36 blong Exp
*
************************************************************************
*
*/
#ifndef _HTTP_IPC_H_
#define _HTTP_IPC_H_
/* http_ipc function prototypes */
int pass_fd(int spipefd, int filedes);
int recv_fd(int spipefd);
#endif /* _HTTP_IPC_H_ */

File diff suppressed because it is too large Load Diff

81
src/http_log.h Normal file
View File

@ -0,0 +1,81 @@
/************************************************************************
* 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
*
************************************************************************
*
* http_log.h,v 1.18 1996/03/06 23:21:06 blong Exp
*
************************************************************************
*
*
* http_log.h contains information for http_log.c including
* SERVER_SUPPORT
* NUM_ERRORS
* struct _ErrorMessage -> ErrorMessage
*
*/
#ifndef _HTTP_LOG_H_
#define _HTTP_LOG_H_
/* constants used in this module */
#define LOG_NONE 0
#define LOG_COMBINED 1
#define LOG_SEPARATE ~(LOG_COMBINED)
#define LOG_SERVERNAME 2
#define LOG_DATE 4
#define SERVER_SUPPORT "httpd@ncsa.uiuc.edu"
/* For Document Error Handling */
#define NUM_DOC_ERRORS 10
/* globals defined in this module */
extern const char StatLine200[];
extern const char StatLine204[];
extern const char StatLine301[];
extern const char StatLine302[];
extern const char StatLine304[];
extern const char StatLine400[];
extern const char StatLine401[];
extern const char StatLine403[];
extern const char StatLine404[];
extern const char StatLine408[];
extern const char StatLine500[];
extern const char StatLine501[];
extern const char StatLine503[];
extern char error_msg[];
extern int ErrorStat;
/* http_log function prototypes */
void log_pid(void);
void log_error(char *err, FILE *fp);
void log_reason(per_request *reqInfo, char *reason, char *file);
void log_transaction(per_request *reqInfo);
void open_logs(per_host *host);
void close_logs(per_host *host);
void error_log2stderr(FILE *error_log);
void title_html(per_request *reqInfo, char *msg);
void begin_http_header(per_request *reqInfo);
int die(per_request *reqInfo, int type, char *err_string);
int GoErrorDoc(per_request *reqInfo, int x, char *ErrString);
int add_doc_error(per_host *host, char* errornum, char* name);
void free_doc_errors(per_host *host);
int have_doc_error(per_request *reqInfo, int errornum);
#endif /* _HTTP_LOG_H_ */

View File

@ -1,36 +1,66 @@
/* /************************************************************************
* http_mime.c: Sends/gets MIME headers for requests * 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
* *
* All code contained herein is covered by the Copyright as distributed * Copyright (C) 1995, Board of Trustees of the University of Illinois
* in the README file in the main directory of the distribution of
* NCSA HTTPD.
* *
* Based on NCSA HTTPd 1.3 by Rob McCool ************************************************************************
* *
* http_mime.c,v 1.106 1996/03/13 18:28:39 blong Exp
* *
* 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 * http_mime.c: maintains the list of mime types, encodings. Currently
* still contains functions for setting some HTTP headers, probably be
* moved eventually.
* *
* 04/20/95 blong
* Added a modified "B18" from apache patches by Rob Hartill
*/ */
#include "httpd.h" #include "config.h"
#include "new.h" #include "portability.h"
struct mime_ext { #include <stdio.h>
char *ext; #ifndef NO_STDLIB_H
char *ct; # include <stdlib.h>
struct mime_ext *next; #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 <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <ctype.h>
#include "constants.h"
#include "fdwrap.h"
#include "allocate.h"
#include "http_mime.h"
#include "http_log.h"
#include "http_config.h"
#include "http_access.h"
#include "env.h"
#include "http_request.h"
#include "util.h"
#if defined(KRB4) || defined(KRB5)
#define HAVE_KERBEROS
#endif /* defined(KRB4) || defined(KRB5) */
#if 1 #if 1
#define hash(i) (isalpha(i) ? (tolower(i)) - 'a' : 26) #define hash(i) (isalpha(i) ? (tolower(i)) - 'a' : 26)
#else #else
#define hash(i) ((i) % 27) #define hash(i) ((i) % 27)
#endif #endif /* 1 */
/* Hash table */ /* Hash table */
struct mime_ext *types[27]; struct mime_ext *types[27];
@ -39,25 +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_encoding[MAX_STRING_LEN];
char location[MAX_STRING_LEN];
static char last_modified[MAX_STRING_LEN];
char auth_line[MAX_STRING_LEN];
char *out_headers = NULL;
char **in_headers_env = NULL;
char *status_line = NULL;
char ims[MAX_STRING_LEN]; /* If-modified-since */
extern FILE *agent_log;
extern FILE *referer_log;
extern char referer_ignore[MAX_STRING_LEN];
char referer[HUGE_STRING_LEN];
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;
@ -80,7 +91,8 @@ void hash_insert(struct mime_ext *me) {
q->next=me; q->next=me;
} }
void kill_mime() { void kill_mime(void)
{
register struct mime_ext *p,*q; register struct mime_ext *p,*q;
register int x; register int x;
@ -112,14 +124,18 @@ void kill_mime() {
} }
} }
void init_mime() { void init_mime(void)
{
char l[MAX_STRING_LEN],w[MAX_STRING_LEN],*ct; char l[MAX_STRING_LEN],w[MAX_STRING_LEN],*ct;
FILE *f; FILE *f;
per_request reqInfo;
register struct mime_ext *me; register struct mime_ext *me;
register int x; register int x;
if(!(f = fopen(types_confname,"r"))) { reqInfo.out = stderr;
fprintf(stderr,"httpd: could not open mime types file %s\n",
if(!(f = FOpen(types_confname,"r"))) {
fprintf(stderr,"HTTPd: could not open mime types file %s\n",
types_confname); types_confname);
perror("fopen"); perror("fopen");
exit(1); exit(1);
@ -134,51 +150,52 @@ void init_mime() {
if(l[0] == '#') continue; if(l[0] == '#') continue;
cfg_getword(w,l); cfg_getword(w,l);
if(!(ct = (char *)malloc(sizeof(char) * (strlen(w) + 1)))) if(!(ct = (char *)malloc(sizeof(char) * (strlen(w) + 1))))
die(NO_MEMORY,"init_mime",stderr); die(&reqInfo,SC_NO_MEMORY,"init_mime");
strcpy(ct,w); strcpy(ct,w);
while(l[0]) { while(l[0]) {
cfg_getword(w,l); cfg_getword(w,l);
if(!(me = (struct mime_ext *)malloc(sizeof(struct mime_ext)))) if(!(me = (struct mime_ext *)malloc(sizeof(struct mime_ext))))
die(NO_MEMORY,"init_mime",stderr); die(&reqInfo,SC_NO_MEMORY,"init_mime");
if(!(me->ext = (char *)malloc(sizeof(char) * (strlen(w)+1)))) if(!(me->ext = (char *)malloc(sizeof(char) * (strlen(w)+1))))
die(NO_MEMORY,"init_mime",stderr); die(&reqInfo,SC_NO_MEMORY,"init_mime");
for(x=0;w[x];x++) for(x=0;w[x];x++)
me->ext[x] = (islower(w[x]) ? w[x] : tolower(w[x])); me->ext[x] = (islower(w[x]) ? w[x] : tolower(w[x]));
me->ext[x] = '\0'; me->ext[x] = '\0';
if(!(me->ct=strdup(ct))) if(!(me->ct=strdup(ct)))
die(NO_MEMORY,"init_mime",stderr); die(&reqInfo,SC_NO_MEMORY,"init_mime");
me->next=NULL; me->next=NULL;
hash_insert(me); hash_insert(me);
} }
free(ct); free(ct);
} }
fclose(f); FClose(f);
} }
void dump_types() { #ifdef DEBUG
void dump_types(void)
{
struct mime_ext *p; struct mime_ext *p;
register int x; register int x;
/* for(x=0;x<27;x++) { for(x=0;x<27;x++) {
p=types[x]; p=types[x];
while(p) { while(p) {
fprintf(stderr,"ext %s: %s\n",p->ext,p->ct); printf("ext %s: %s\n",p->ext,p->ct);
p=p->next; p=p->next;
} }
} */ }
p=forced_types; p=forced_types;
while(p) { while(p) {
fprintf(stderr,"file %s: %s\n",p->ext,p->ct); printf("file %s: %s\n",p->ext,p->ct);
p=p->next; p=p->next;
} }
} }
#endif /* DEBUG */
int is_content_type(char *type) { void find_ct(per_request *reqInfo, char *file,
return(!strcmp(content_type,type)); char *content_type, char *content_encoding)
} {
void find_ct(char *file, int store_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];
@ -195,7 +212,7 @@ void find_ct(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);
@ -225,10 +242,10 @@ void find_ct(char *file, int store_encoding) {
} }
if((i = rind(fn,'.')) < 0) { if((i = rind(fn,'.')) < 0) {
if (local_default_type[0] != '\0') if (local_default_type[0] != '\0')
strcpy(content_type,local_default_type); strcpy(content_type,local_default_type);
else strcpy(content_type,default_type); else strcpy(content_type,reqInfo->hostInfo->default_type);
return; return;
} }
++i; ++i;
p=types[hash(fn[i])]; p=types[hash(fn[i])];
@ -242,97 +259,37 @@ void find_ct(char *file, int store_encoding) {
} }
if (local_default_type[0] != '\0') if (local_default_type[0] != '\0')
strcpy(content_type,local_default_type); strcpy(content_type,local_default_type);
else strcpy(content_type,default_type); else strcpy(content_type,reqInfo->hostInfo->default_type);
} }
void probe_content_type(per_request *reqInfo, char *file)
void probe_content_type(char *file) { {
find_ct(file,0); find_ct(reqInfo,file,reqInfo->outh_content_type,NULL);
} }
void set_content_type(char *file) { void set_content_type(per_request *reqInfo, char *file)
find_ct(file,1); {
find_ct(reqInfo,file,reqInfo->outh_content_type,
reqInfo->outh_content_encoding);
} }
int scan_script_header(FILE *f, FILE *fd) { void get_content_type(per_request *reqInfo, char *file,
char w[MAX_STRING_LEN]; char *content_type, char *content_encoding)
char *l; {
int p; find_ct(reqInfo,file,content_type,content_encoding);
while(1) {
if(getline(w,MAX_STRING_LEN-1,fileno(f),timeout))
die(SERVER_ERROR,"httpd: malformed header from script",fd);
/* Always return zero, so as not to cause redirect+sleep3+kill */
if(w[0] == '\0') {
if (content_type[0] == '\0') {
if (location[0] != '\0') {
strcpy(content_type,"text/html");
} else {
if (local_default_type[0] != '\0')
strcpy(content_type,local_default_type);
else strcpy(content_type,default_type);
}
}
return 0;
}
if(!(l = strchr(w,':')))
l = w;
*l++ = '\0';
if(!strcasecmp(w,"Content-type")) {
/* Thanks Netscape for showing this bug to everyone */
/* delete trailing whitespace, esp. for "server push" */
char *endp = l + strlen(l) - 1;
while ((endp > l) && isspace(*endp)) *endp-- = '\0';
sscanf(l,"%s",content_type);
}
else if(!strcasecmp(w,"Location")) {
/* If we don't already have a status line, make one */
if (!&status_line[0]) {
status = 302;
set_stat_line();
}
sscanf(l,"%s",location);
}
else if(!strcasecmp(w,"Status")) {
for(p=0;isspace(l[p]);p++);
sscanf(&l[p],"%d",&status);
if(!(status_line = strdup(&l[p])))
die(NO_MEMORY,"scan_script_header",fd);
}
else {
*(--l) = ':';
for(p=0;w[p];p++);
w[p] = LF;
w[++p] = '\0';
if(!out_headers) {
if(!(out_headers = strdup(w)))
die(NO_MEMORY,"scan_script_header",fd);
}
else {
int loh = strlen(out_headers);
out_headers = (char *) realloc(out_headers,
(loh+strlen(w)+1)*sizeof(char));
if(!out_headers)
die(NO_MEMORY,"scan_script_header",fd);
strcpy(&out_headers[loh],w);
}
}
}
} }
/* 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 */
void reset_mime_vars() { void reset_mime_vars(void)
{
struct mime_ext *mimes,*tmp; struct mime_ext *mimes,*tmp;
mimes = forced_types; mimes = forced_types;
tmp = mimes; tmp = mimes;
while (mimes != Saved_Forced) { while (mimes && (mimes != Saved_Forced)) {
mimes = mimes->next; mimes = mimes->next;
free(tmp->ext); free(tmp->ext);
free(tmp->ct); free(tmp->ct);
@ -345,7 +302,7 @@ void reset_mime_vars() {
mimes = encoding_types; mimes = encoding_types;
tmp = mimes; tmp = mimes;
while (mimes != Saved_Encoding) { while (mimes && (mimes != Saved_Encoding)) {
mimes = mimes->next; mimes = mimes->next;
free(tmp->ext); free(tmp->ext);
free(tmp->ct); free(tmp->ct);
@ -356,236 +313,105 @@ void reset_mime_vars() {
encoding_types = Saved_Encoding; encoding_types = Saved_Encoding;
} }
void add_type(char *fn, char *t, FILE *out) { void add_type(per_request *reqInfo, char *fn, char *t) {
struct mime_ext *n; struct mime_ext *n;
if(!(n=(struct mime_ext *)malloc(sizeof(struct mime_ext)))) if(!(n=(struct mime_ext *)malloc(sizeof(struct mime_ext))))
die(NO_MEMORY,"add_type",out); die(reqInfo,SC_NO_MEMORY,"add_type");
if(!(n->ext = strdup(fn))) if(!(n->ext = strdup(fn)))
die(NO_MEMORY,"add_type",out); die(reqInfo,SC_NO_MEMORY,"add_type");
if(!(n->ct = strdup(t))) if(!(n->ct = strdup(t)))
die(NO_MEMORY,"add_type",out); die(reqInfo,SC_NO_MEMORY,"add_type");
n->next = forced_types; n->next = forced_types;
forced_types = n; forced_types = n;
} }
void add_encoding(char *fn, char *t,FILE *out) { void add_encoding(per_request *reqInfo, char *fn, char *t) {
struct mime_ext *n; struct mime_ext *n;
if(!(n=(struct mime_ext *)malloc(sizeof(struct mime_ext)))) if(!(n=(struct mime_ext *)malloc(sizeof(struct mime_ext))))
die(NO_MEMORY,"add_encoding",out); die(reqInfo, SC_NO_MEMORY,"add_encoding");
if(!(n->ext = strdup(fn))) if(!(n->ext = strdup(fn)))
die(NO_MEMORY,"add_encoding",out); die(reqInfo, SC_NO_MEMORY,"add_encoding");
if(!(n->ct = strdup(t))) if(!(n->ct = strdup(t)))
die(NO_MEMORY,"add_encoding",out); die(reqInfo, SC_NO_MEMORY,"add_encoding");
n->next = encoding_types; n->next = encoding_types;
encoding_types = n; encoding_types = n;
} }
void set_content_length(int l) { void set_content_length(per_request *reqInfo, int l) {
content_length = l; reqInfo->outh_content_length = l;
} }
int set_last_modified(time_t t, FILE *out) { 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(USE_LOCAL_COPY,NULL,out); return die(reqInfo,SC_USE_LOCAL_COPY,NULL);
return 0; return 0;
} }
void init_header_vars()
/* This needs to malloc in case a CGI script passes back its own
* status_line, so we can free without problem.
*/
char* set_stat_line(per_request *reqInfo)
{ {
referer[0] = '\0'; if (reqInfo->status_line) {
content_type[0] = '\0'; freeString(reqInfo->status_line);
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;
if (in_headers_env != NULL) {
free_env(in_headers_env);
in_headers_env = NULL;
} }
} switch (reqInfo->status) {
case 200:
int merge_header(char *h, char *v, FILE *out) { reqInfo->status_line = dupStringP((char *)StatLine200,STR_REQ);
register int l,lt; break;
char **t; case 204:
reqInfo->status_line = dupStringP((char *)StatLine204,STR_REQ);
for(l=0;h[l];++l); break;
h[l] = '='; case 301:
h[++l] = '\0'; reqInfo->status_line = dupStringP((char *)StatLine301,STR_REQ);
break;
for(t=in_headers_env;*t;++t) {
if(!strncmp(*t,h,l)) {
lt = strlen(*t);
if(!(*t = (char *) realloc(*t,(lt+strlen(v)+3)*sizeof(char))))
die(NO_MEMORY,"merge_header",out);
(*t)[lt++] = ',';
(*t)[lt++] = ' ';
strcpy(&((*t)[lt]),v);
return 1;
}
}
h[l-1] = '\0';
return 0;
}
void get_mime_headers(int fd, FILE *out, char* url) {
char w[MAX_STRING_LEN];
char l[MAX_STRING_LEN];
int num_inh, num_processed;
char *t;
num_inh = 0;
num_processed = 0;
while(!(getline(w,MAX_STRING_LEN-1,fd,timeout))) {
if(!w[0])
return;
if((++num_processed) > MAX_HEADERS)
die(BAD_REQUEST,"too many header lines",out);
if(!(t = strchr(w,':')))
continue;
*t++ = '\0';
while(isspace(*t)) ++t;
strcpy(l,t);
if(!strcasecmp(w,"Content-type")) {
strcpy(content_type,l);
continue;
}
if(!strcasecmp(w,"Authorization")) {
strcpy(auth_line,l);
continue;
}
if(!strcasecmp(w,"Content-length")) {
sscanf(l,"%d",&content_length);
continue;
}
if(!strcasecmp(w,"User-agent")) {
fprintf(agent_log, "%s\n", l);
fflush(agent_log);
}
if(!strcasecmp(w,"Referer")) {
strcpy(referer,l);
if ((!strlen(referer_ignore)) || (!strstr(l,referer_ignore))){
fprintf(referer_log, "%s -> %s\n", l, url);
fflush(referer_log);
}
}
if(!strcasecmp(w,"If-modified-since"))
strcpy(ims,l);
http2cgi(w);
if(in_headers_env) {
if(!merge_header(w,l,out)) {
in_headers_env =
(char **) realloc(in_headers_env,
(num_inh+2)*sizeof(char *));
if(!in_headers_env)
die(NO_MEMORY,"get_mime_headers",out);
in_headers_env[num_inh++] = make_env_str(w,l,out);
in_headers_env[num_inh] = NULL;
}
}
else {
if(!(in_headers_env = (char **) malloc(2*sizeof(char *))))
die(NO_MEMORY,"get_mime_headers",out);
in_headers_env[num_inh++] = make_env_str(w,l,out);
in_headers_env[num_inh] = NULL;
}
}
}
void dump_default_header(FILE *fd) {
fprintf(fd,"Date: %s%c",gm_timestr_822(time(NULL)),LF);
fprintf(fd,"Server: %s%c",SERVER_VERSION,LF);
if (annotation_server[0])
fprintf(fd,"Annotations-cgi: %s%c",annotation_server,LF);
/* Not part of HTTP spec, removed. */
/* fprintf(fd,"MIME-version: 1.0%c",LF); */
}
char* set_stat_line() {
if (status_line) free(status_line);
switch (status) {
case 302: case 302:
status_line = strdup((char *)StatLine302); reqInfo->status_line = dupStringP((char *)StatLine302,STR_REQ);
break; break;
case 304: case 304:
status_line = strdup((char *)StatLine304); 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(FILE *fd) {
if(!status_line) {
if(location[0]) {
status = 302;
status_line = strdup((char *)StatLine302);
}
else {
set_stat_line();
}
}
begin_http_header(fd,status_line);
if(content_type[0])
fprintf(fd,"Content-type: %s%c",content_type,LF);
if(last_modified[0])
fprintf(fd,"Last-modified: %s%c",last_modified,LF);
if(content_length >= 0)
fprintf(fd,"Content-length: %d%c",content_length,LF);
if(location[0])
fprintf(fd,"Location: %s%c",location,LF);
if(content_encoding[0])
fprintf(fd,"Content-encoding: %s%c",content_encoding,LF);
if(out_headers)
fprintf(fd,"%s",out_headers);
fprintf(fd,"%c",LF);
fflush(fd);
} }

60
src/http_mime.h Normal file
View File

@ -0,0 +1,60 @@
/************************************************************************
* 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
*
************************************************************************
*
* http_mime.h,v 1.19 1996/02/22 23:47:04 blong Exp
*
************************************************************************
*
*/
#ifndef _HTTP_MIME_H_
#define _HTTP_MIME_H_
/* constants used in this module */
#define MAX_HEADERS 200
struct mime_ext {
char *ext;
char *ct;
struct mime_ext *next;
};
/* globals defined in this module */
extern struct mime_ext *Saved_Forced;
extern struct mime_ext *Saved_Encoding;
extern struct mime_ext *forced_types;
extern struct mime_ext *encoding_types;
/* http_mime function prototypes */
void set_content_type(per_request *reqInfo, char *fn);
void probe_content_type(per_request *reqInfo, char *fn);
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_encoding(per_request *reqInfo, char *fn, char *t);
void dump_types(void);
void init_mime(void);
void kill_mime(void);
void reset_mime_vars(void);
char* set_stat_line(per_request *reqInfo);
#endif /* _HTTP_MIME_H_ */

View File

@ -1,62 +0,0 @@
/*
* http_post.c: Handles POST
*
* All code contained herein is covered by the Copyright as distributed
* in the README file in the main directory of the distribution of
* NCSA HTTPD.
*
* Based on NCSA HTTPd 1.3 by Rob McCool
*
*/
#include "httpd.h"
void handle_post(char *name, char *args, int in, FILE *out) {
struct stat finfo;
char ct_bak[MAX_STRING_LEN];
strcpy(ct_bak,content_type); /* oop ack */
if(stat(name,&finfo) == -1) {
if(find_script("POST",name,args,in,out))
return;
if(errno==ENOENT) {
log_reason("file does not exist",name);
unmunge_name(name);
die(NOT_FOUND,name,out);
}
else {
log_reason("file permissions deny server access",name);
unmunge_name(name);
die(FORBIDDEN,name,out);
}
}
probe_content_type(name);
if(!strcmp(content_type,CGI_MAGIC_TYPE)) {
strcpy(content_type,ct_bak);
send_cgi("POST",name,"",args,&finfo,in,out);
return;
}
/* Not a script, do group ann thang */
die(NOT_IMPLEMENTED,"POST to non-script",out);
}
void post_node(char *name, char *args, int in, FILE *out) {
int s;
s=translate_name(name,out);
switch(s) {
case STD_DOCUMENT:
handle_post(name,args,in,out);
return;
case REDIRECT_URL:
die(REDIRECT,name,out);
case SCRIPT_NCSA:
exec_post_NCSA(name,args,in,out);
return;
case SCRIPT_CGI:
exec_cgi_script("POST",name,args,in,out);
}
}

View File

@ -1,61 +0,0 @@
/*
* http_put.c: Handles PUT
*
* All code contained herein is covered by the Copyright as distributed
* in the README file in the main directory of the distribution of
* NCSA HTTPD.
*
* Based on NCSA HTTPd 1.3 by Rob McCool
*
*/
#include "httpd.h"
void handle_put(char *name, char *args, int in, FILE *out) {
struct stat finfo;
char ct_bak[MAX_STRING_LEN];
strcpy(ct_bak,content_type); /* oop ack */
if(stat(name,&finfo) == -1) {
if(find_script("PUT",name,args,in,out))
return;
if(errno==ENOENT) {
log_reason("file does not exist",name);
unmunge_name(name);
die(NOT_FOUND,name,out);
}
else {
log_reason("file permissions deny server access",name);
unmunge_name(name);
die(FORBIDDEN,name,out);
}
}
probe_content_type(name);
if(!strcmp(content_type,CGI_MAGIC_TYPE)) {
strcpy(content_type,ct_bak);
send_cgi("PUT",name,"",args,&finfo,in,out);
return;
}
/* Not a script, do group ann thang */
die(NOT_IMPLEMENTED,"PUT to non-script",out);
}
void put_node(char *name, char *args, int in, FILE *out) {
int s;
s=translate_name(name,out);
switch(s) {
case STD_DOCUMENT:
handle_put(name,args,in,out);
return;
case REDIRECT_URL:
die(REDIRECT,name,out);
case SCRIPT_CGI:
exec_cgi_script("PUT",name,args,in,out);
default:
die(NOT_IMPLEMENTED,"NCSA script exeuction of delete",out);
}
}

View File

@ -1,230 +1,637 @@
/* /************************************************************************
* http_request.c: functions to get and process requests * 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
* *
* All code contained herein is covered by the Copyright as distributed * Copyright (C) 1995, Board of Trustees of the University of Illinois
* in the README file in the main directory of the distribution of *
* NCSA HTTPD. ************************************************************************
*
* http_request.c,v 1.113 1996/04/05 18:55:02 blong Exp
*
************************************************************************
*
* 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
*/ */
#include "httpd.h" #include "config.h"
#include "portability.h"
#include <stdio.h>
#ifndef NO_STDLIB_H
# include <stdlib.h>
#endif /* NO_STDLIB_H */
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <setjmp.h> #include <setjmp.h>
#include "new.h" #include "constants.h"
#include "allocate.h" /* for freeString() */
#include "cgi.h" /* for exec_cgi_script() */
#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"
int assbackwards; int req_count = 0;
char *remote_host = NULL; int cgibuf_count = 0;
char *remote_ip = NULL; int sockbuf_count = 0;
char *remote_name = NULL;
FILE *time_out_fd;
extern JMP_BUF jmpbuffer;
extern int getline_seen_cmd;
extern int getline_buffered_fd;
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;
static void (*exit_callback)();
void send_fd_timed_out(int sigcode) { /* Per request information */
char errstr[MAX_STRING_LEN];
fclose(time_out_fd);
if(exit_callback) (*exit_callback)();
if (sigcode != SIGPIPE) {
sprintf(errstr,"httpd: send timed out for %s",remote_name);
} else {
sprintf(errstr,"httpd: send aborted for %s",remote_name);
}
log_error(errstr);
log_transaction();
if (in_headers_env) {
free_env(in_headers_env);
in_headers_env = NULL;
}
if (!standalone) {
fclose(stdin);
fclose(stdout);
exit(0);
} else {
if (remote_host) {
free(remote_host);
remote_host = NULL;
}
/* Duh. Free memory in bss */
/* if (remote_ip) free(remote_ip); */
if (remote_name) {
free(remote_name);
remote_name = NULL;
}
#if defined(NeXT) || defined(__mc68000__)
longjmp(jmpbuffer,1);
#else
siglongjmp(jmpbuffer,1);
#endif
}
}
/*
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_fd(FILE *f, FILE *fd, void (*onexit)())
{
char buf[IOBUFSIZE];
long total_bytes_sent;
register int n,o,w;
time_out_fd = f;
exit_callback = onexit;
signal(SIGALRM,send_fd_timed_out);
signal(SIGPIPE,send_fd_timed_out);
total_bytes_sent = 0;
while (1) {
alarm(timeout);
if((n=fread(buf,sizeof(char),IOBUFSIZE,f)) < 1) {
break;
}
o=0;
if(bytes_sent != -1)
bytes_sent += n;
while(n) {
w=fwrite(&buf[o],sizeof(char),n,fd);
n-=w;
o+=w;
total_bytes_sent += w;
}
}
fflush(fd);
alarm(0);
signal(SIGALRM,SIG_IGN);
signal(SIGPIPE,SIG_IGN);
return total_bytes_sent;
}
int find_script(char *method, char *name, char *args, int in, FILE *out)
{
int n=count_dirs(name),i;
char t[HUGE_STRING_LEN],ct_bak[MAX_STRING_LEN];
struct stat finfo;
strcpy(ct_bak,content_type);
for(i=n;i;--i) {
make_dirstr(name,i,t);
probe_content_type(t);
if(!strcmp(content_type,CGI_MAGIC_TYPE)) {
char pa[HUGE_STRING_LEN];
int l=strlen(t);
if(stat(t,&finfo) == -1)
continue;
if(!(S_ISREG(finfo.st_mode)))
return 0;
strcpy(pa,&name[l]);
name[l] = '\0';
strcpy(content_type,ct_bak);
send_cgi(method,name,pa,args,&finfo,in,out);
return 1;
}
}
return 0;
}
char method[HUGE_STRING_LEN];
char protocal[HUGE_STRING_LEN];
char the_request[HUGE_STRING_LEN]; char the_request[HUGE_STRING_LEN];
char failed_request[HUGE_STRING_LEN];
char as_requested[HUGE_STRING_LEN]; char as_requested[HUGE_STRING_LEN];
char url2[HUGE_STRING_LEN]; char failed_request[HUGE_STRING_LEN];
char failed_url[HUGE_STRING_LEN]; char failed_url[HUGE_STRING_LEN];
char args2[HUGE_STRING_LEN]; #ifdef LOG_DURATION
time_t request_time = 0;
#endif /* LOG_DURATION */
void initialize_request() { /* String constants for the request. Numbers are in constants.h */
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)
{
int RealInit = 0;
per_request *newInfo;
RealInit = (reqInfo == NULL) ? 1 : 0;
if (RealInit) {
newInfo = (per_request *) malloc(sizeof(per_request));
req_count++;
reqInfo = newInfo;
reqInfo->ownDNS = TRUE;
reqInfo->dns_host_lookup = FALSE;
reqInfo->remote_name = NULL;
reqInfo->remote_ip = NULL;
reqInfo->remote_host = NULL;
reqInfo->next = NULL;
reqInfo->ownENV = TRUE;
reqInfo->env = NULL;
reqInfo->outh_cgi = NULL;
reqInfo->RequestFlags = 0;
reqInfo->sb = NULL;
reqInfo->ownSB = TRUE;
reqInfo->cgi_buf = NULL;
}
reqInfo->hostInfo = gConfiguration;
/* Can't think (now) of any case where environment should transfer
from last request during KeepAlive, but in other cases, perhaps */
if (reqInfo->ownENV && reqInfo->env) {
free_env(reqInfo);
}
reqInfo->ownENV = TRUE;
reqInfo->env = NULL;
reqInfo->env_len = NULL;
reqInfo->num_env = 0;
reqInfo->max_env = 0;
/* initialize auth stuff */
reqInfo->bNotifyDomainRestricted = 0;
reqInfo->bSatisfiedDomain = 0;
reqInfo->bSatisfiedReferer = 0;
reqInfo->auth_name = "ByPassword";
reqInfo->auth_pwfile = NULL;
reqInfo->auth_pwfile_type = 0;
reqInfo->auth_grpfile = NULL;
reqInfo->auth_grpfile_type = 0;
#ifdef DIGEST_AUTH
reqInfo->auth_digestfile = NULL;
reqInfo->auth_digestfile_type = 0;
#endif /* DIGEST_AUTH */
/* eventually, we'll figure out how to let send_fd_timed_out know
which request. Until then, keep a global pointer to list */
gCurrentRequest = reqInfo;
/* reset security information to access config defaults */ /* reset security information to access config defaults */
reset_security(); reset_security();
reset_mime_vars();
/* Initialize Error codes */ /* Initialize Error codes */
ErrorStat = 0; ErrorStat = 0;
status = 200; reqInfo->status = SC_DOCUMENT_FOLLOWS;
reqInfo->status_line = NULL;
reqInfo->bytes_sent = -1;
reqInfo->auth_type[0] = '\0';
reqInfo->url[0] = '\0';
reqInfo->args[0] = '\0';
reqInfo->path_info[0] = '\0';
reqInfo->filename[0] = '\0';
reqInfo->inh_agent[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();
reset_to_saved_aliases();
exit_callback = NULL;
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 */ /* reset keep-alive, client will indicate desire on next request */
header_only = 0; keep_alive.bKeepAlive = 0;
bytes_sent = -1; return reqInfo;
}
/* Initialize buffered getline */ /* continue_request()
getline_buffered_fd = -1; * Used (especially in SSI and ErrorDocs) to handle "multiple"
getline_seen_cmd = 0; * 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 *newInfo;
newInfo = (per_request *)malloc(sizeof(per_request));
req_count++;
newInfo->status = reqInfo->status;
newInfo->status_line = NULL;
if (options & KEEP_ENV) {
newInfo->ownENV = FALSE;
newInfo->env = reqInfo->env;
newInfo->env_len = reqInfo->env_len;
newInfo->num_env = reqInfo->num_env;
newInfo->max_env = reqInfo->max_env;
} else {
newInfo->ownENV = TRUE;
newInfo->env = NULL;
newInfo->env_len = NULL;
newInfo->num_env = 0;
newInfo->max_env = 0;
}
if (options & KEEP_AUTH) {
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_pwfile = reqInfo->auth_pwfile;
newInfo->auth_grpfile = reqInfo->auth_grpfile;
newInfo->auth_pwfile_type = reqInfo->auth_pwfile_type;
newInfo->auth_grpfile_type = reqInfo->auth_grpfile_type;
#ifdef DIGEST_AUTH
newInfo->auth_digestfile = reqInfo->auth_digestfile;
newInfo->auth_digestfile_type = newInfo->auth_digestfile_type;
#endif /* DIGEST_AUTH */
newInfo->bSatisfiedDomain = reqInfo->bSatisfiedDomain;
newInfo->bSatisfiedReferer = reqInfo->bSatisfiedReferer;
} else {
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_pwfile = NULL;
newInfo->auth_grpfile = NULL;
newInfo->auth_pwfile_type = 0;
newInfo->auth_grpfile_type = 0;
#ifdef DIGEST_AUTH
newInfo->auth_digestfile = NULL;
newInfo->auth_digestfile_type = 0;
#endif /* DIGEST_AUTH */
newInfo->bSatisfiedDomain = FALSE;
newInfo->bSatisfiedReferer = FALSE;
}
newInfo->bNotifyDomainRestricted = reqInfo->bNotifyDomainRestricted;
newInfo->bytes_sent = 0;
if (options & FORCE_GET) {
if (reqInfo->method != M_HEAD) newInfo->method = M_GET;
else newInfo->method = M_HEAD;
} else {
newInfo->method = reqInfo->method;
}
newInfo->http_version = reqInfo->http_version;
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 & COPY_URL) {
strcpy(newInfo->url, reqInfo->url);
strcpy(newInfo->args, reqInfo->args);
strcpy(newInfo->path_info, reqInfo->path_info);
strcpy(newInfo->filename, reqInfo->filename);
} else {
newInfo->url[0] = '\0';
newInfo->args[0] = '\0';
newInfo->path_info[0] = '\0';
newInfo->filename[0] = '\0';
}
/* Copy all in headers */
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->in = reqInfo->in;
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;
gCurrentRequest = 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) {
per_request *tmp = reqInfo;
while (reqInfo != NULL) {
/* We'll just let the freeAllStrings clean up these instead. */
reqInfo->remote_name = NULL;
reqInfo->remote_host = NULL;
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) {
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;
free(reqInfo);
req_count--;
reqInfo = tmp;
gCurrentRequest = reqInfo;
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)
{
char *protocal;
char *method, *url;
char *chp;
/* extract the method */
method = strtok (request, "\t ");
if (method) {
if ((reqInfo->method = MapMethod (method)) == M_INVALID)
die(reqInfo,SC_BAD_REQUEST,"Invalid or unsupported method.");
}
else
die(reqInfo,SC_BAD_REQUEST,"Invalid or unsupported method.");
/* extract the URL, and args if present */
url = strtok (NULL, "\t\r ");
if (url && (chp = strchr (url, '?'))) {
*chp++ = '\0';
strcpy (reqInfo->args, chp);
}
strcpy (reqInfo->url, url);
protocal = strtok (NULL, "\r");
if(!protocal) {
reqInfo->http_version = P_HTTP_0_9;
}
else {
if (!strcmp(protocal,protocals[P_HTTP_1_0]))
reqInfo->http_version = P_HTTP_1_0;
else if (!strcmp(protocal,protocals[P_HTTP_1_0]))
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;
/* dummy call to eat LF at end of protocal */
strtok (NULL, "\n");
get_http_headers(reqInfo);
}
/* fprintf(stderr,"method:%s url:%s args:%s prot:%s\n",method,
reqInfo->url,reqInfo->args, protocal); */
} }
void process_request(int in, FILE *out) { /* Returns a method number for a given method string. SHTTP requires
get_remote_host(in); * case independent (as per standard network protocal). HTTP is broken,
* and is case dependent.
*/
int MapMethod (char* method)
{
if(!strcmp(method,methods[M_HEAD]))
return M_HEAD;
else if(!strcmp(method,methods[M_GET]))
return M_GET;
else if(!strcmp(method,methods[M_POST]))
return M_POST;
else if(!strcmp(method,methods[M_PUT]))
return M_PUT;
else if(!strcmp(method,methods[M_DELETE]))
return M_DELETE;
else if(!strcasecmp(method,methods[M_SECURE]))
return M_SECURE;
else
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
this from other places (on LOCAL_REDIRECTs and ErrorDocument handling) */
void process_request(per_request *reqInfo)
{
int s;
s = translate_name(reqInfo,reqInfo->url,reqInfo->filename);
switch(s) {
case A_STD_DOCUMENT:
if ((reqInfo->method == M_HEAD) &&
(reqInfo->http_version == P_HTTP_0_9)) {
reqInfo->method = M_GET;
die(reqInfo,SC_BAD_REQUEST,"Invalid HTTP/0.9 method.");
}
send_node(reqInfo);
break;
case A_REDIRECT_TEMP:
die(reqInfo,SC_REDIRECT_TEMP,reqInfo->filename);
break;
case A_REDIRECT_PERM:
die(reqInfo,SC_REDIRECT_PERM,reqInfo->filename);
break;
case A_SCRIPT_CGI:
exec_cgi_script(reqInfo);
break;
}
}
/* 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); signal(SIGPIPE,send_fd_timed_out);
#ifdef LOG_DURATION
request_time = 0;
#endif /* LOG_DURATION */
if(getline(as_requested,HUGE_STRING_LEN,in,timeout)) 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; return;
if(!as_requested[0]) if(!as_requested[0])
return; return;
#ifdef LOG_DURATION
request_time = time(NULL);
#endif /* LOG_DURATION */
strcpy(the_request, as_requested); strcpy(the_request, as_requested);
getword(method,as_requested,' '); #ifdef SETPROCTITLE
getword(args2,as_requested,' '); setproctitle(the_request);
getword(url2,args2,'?'); #endif /* SETPROCTITLE */
decode_request(reqInfo, as_requested);
unescape_url(reqInfo->url);
unescape_url(url2); /* Moved this to later so we can read the headers first for HTTP/1.1
getword(protocal,as_requested,'\0'); * Host: support
*/
which_host_conf(reqInfo);
if(protocal[0] != '\0') { if (reqInfo->dns_host_lookup == FALSE) {
assbackwards = 0; /* Only when we haven't done DNS do we call get_remote_host().
get_mime_headers(in,out, url2); * If we aren't supposed to, get_remote_host() will not do it.
*/
get_remote_host(reqInfo);
} }
else
assbackwards = 1;
if(!strcmp(method,"HEAD")) {
header_only=1;
process_get(in,out,method,url2,args2);
}
else if(!strcmp(method,"GET")) {
process_get(in,out,method,url2,args2);
}
else if(!strcmp(method,"POST")) {
post_node(url2,args2,in,out);
}
else if(!strcmp(method,"PUT")) {
put_node(url2,args2,in,out);
}
else if(!strcmp(method,"DELETE")) {
delete_node(url2,args2,in,out);
}
else
die(BAD_REQUEST,"Invalid or unsupported method.",out);
process_request(reqInfo);
} }

56
src/http_request.h Normal file
View File

@ -0,0 +1,56 @@
/************************************************************************
* 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
*
************************************************************************
*
* http_request.h,v 1.20 1996/04/05 18:55:04 blong Exp
*
************************************************************************
*
*
*/
#ifndef _HTTP_REQUEST_H_
#define _HTTP_REQUEST_H_
#include <setjmp.h>
/* globals defined in this module */
extern per_request *gCurrentRequest;
extern char *remote_logname;
extern char failed_request[];
extern char failed_url[];
extern char the_request[];
/* Continue Request Options */
#define COPY_URL 1
#define FORCE_GET 2
#define NOT_LAST 4
#define ONLY_LAST 8
#define KEEP_ENV 16
#define KEEP_AUTH 32
#define NEW_SOCK_BUF 64
extern int req_count;
extern int cgibuf_count;
extern int sockbuf_count;
/* function prototypes */
per_request *initialize_request(per_request *reqInfo);
per_request *continue_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 RequestMain(per_request *reqInfo);
int MapMethod (char* method);
#endif /* _HTTP_REQUEST_H_ */

View File

@ -1,591 +0,0 @@
/*
* http_script: keeps all script-related ramblings together.
*
* All code contained herein is covered by the Copyright as distributed
* in the README file in the main directory of the distribution of
* NCSA HTTPD.
*
* 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_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 "httpd.h"
#include "new.h"
int pid;
void kill_children() {
char errstr[MAX_STRING_LEN];
sprintf(errstr,"killing CGI process %d",pid);
log_error_noclose(errstr);
kill(pid,SIGTERM);
sleep(3); /* give them time to clean up */
kill(pid,SIGKILL);
waitpid(pid,NULL,0);
}
char **create_argv(char *av0, char *args, FILE *out) {
register int x,n;
char **av;
char w[HUGE_STRING_LEN];
char l[HUGE_STRING_LEN];
for(x=0,n=2;args[x];x++)
if(args[x] == '+') ++n;
if(!(av = (char **)malloc((n+1)*sizeof(char *))))
die(NO_MEMORY,"create_argv",out);
av[0] = av0;
strcpy(l,args);
for(x=1;x<n;x++) {
getword(w,l,'+');
unescape_url(w);
escape_shell_cmd(w);
if(!(av[x] = strdup(w)))
die(NO_MEMORY,"create_argv",out);
}
av[n] = NULL;
return av;
}
void get_path_info(char *path, char *path_args, FILE *out,
struct stat *finfo)
{
register int x,max;
char t[HUGE_STRING_LEN];
path_args[0] = '\0';
max=count_dirs(path);
for(x=dirs_in_alias;x<=max;x++) {
make_dirstr(path,x+1,t);
if(!(stat(t,finfo))) {
if(S_ISREG(finfo->st_mode)) {
int l=strlen(t);
strcpy(path_args,&path[l]);
path[l] = '\0';
return;
}
}
}
for(x=dirs_in_alias - 1;x;--x) {
make_dirstr(path,x+1,t);
if(!(stat(t,finfo))) {
if(S_ISREG(finfo->st_mode)) {
strcpy(path_args,&path[strlen(t)]);
strcpy(path,t);
return;
}
}
}
unmunge_name(path);
log_reason("script does not exist",path);
die(NOT_FOUND,path,out);
}
#define MAX_COMMON_VARS 16
#define MAX_CGI_VARS (MAX_COMMON_VARS+16)
char **add_cgi_vars(char **env,
char *method, char *path, char *path_args, char *args,
int *content,
FILE *out)
{
int x;
char t[HUGE_STRING_LEN],t2[HUGE_STRING_LEN];
if(!(env = new_env(env,MAX_CGI_VARS,&x)))
die(NO_MEMORY,"add_cgi_vars",out);
env[x++] = make_env_str("GATEWAY_INTERFACE","CGI/1.1",out);
env[x++] = make_env_str("SERVER_PROTOCOL",
(assbackwards ? "HTTP/0.9" : "HTTP/1.0"),out);
env[x++] = make_env_str("REQUEST_METHOD",method,out);
strcpy(t,path);
unmunge_name(t);
env[x++] = make_env_str("SCRIPT_NAME",t,out);
if(path_args[0]) {
env[x++] = make_env_str("PATH_INFO",path_args,out);
strcpy(t2,path_args);
translate_name(t2,out);
env[x++] = make_env_str("PATH_TRANSLATED",t2,out);
}
env[x++] = make_env_str("QUERY_STRING",args,out);
if(content) {
*content=0;
if((!strcmp(method,"POST")) || (!strcmp(method,"PUT"))) {
*content=1;
sprintf(t,"%d",content_length);
env[x++] = make_env_str("CONTENT_TYPE",content_type,out);
env[x++] = make_env_str("CONTENT_LENGTH",t,out);
}
}
if (ErrorStat) {
if (failed_request[0])
env[x++] = make_env_str("REDIRECT_REQUEST",failed_request,out);
if (failed_url[0])
env[x++] = make_env_str("REDIRECT_URL",failed_url,out);
env[x++] = make_env_str("REDIRECT_STATUS",set_stat_line(),out);
}
env[x] = NULL;
return env;
}
char **add_common_vars(char **env,FILE *out) {
char t[MAX_STRING_LEN],*env_path,*env_tz;
int x;
if(!(env = new_env(env,MAX_COMMON_VARS,&x)))
die(NO_MEMORY,"add_common_vars",out);
if(!(env_path = getenv("PATH")))
env_path=DEFAULT_PATH;
env[x++] = make_env_str("PATH",env_path,out);
if((env_tz = getenv("TZ")))
env[x++] = make_env_str("TZ",env_tz,out);
env[x++] = make_env_str("SERVER_SOFTWARE",SERVER_VERSION,out);
env[x++] = make_env_str("SERVER_NAME",server_hostname,out);
sprintf(t,"%d",port);
env[x++] = make_env_str("SERVER_PORT",t,out);
env[x++] = make_env_str("REMOTE_HOST",remote_name,out);
env[x++] = make_env_str("REMOTE_ADDR",remote_ip,out);
env[x++] = make_env_str("DOCUMENT_ROOT",document_root,out);
if(user[0])
env[x++] = make_env_str("REMOTE_USER",user,out);
if(annotation_server[0])
env[x++] = make_env_str("ANNOTATION_SERVER",annotation_server,out);
if(groupname[0])
env[x++] = make_env_str("REMOTE_GROUP",groupname,out);
if(auth_type)
env[x++] = make_env_str("AUTH_TYPE",auth_type,out);
if(do_rfc931)
env[x++] = make_env_str("REMOTE_IDENT",remote_logname,out);
if (ErrorStat) {
if (failed_request[0])
env[x++] = make_env_str("REDIRECT_REQUEST",failed_request,out);
if (failed_url[0])
env[x++] = make_env_str("REDIRECT_URL",failed_url,out);
env[x++] = make_env_str("REDIRECT_STATUS",set_stat_line(),out);
}
env[x] = NULL;
return env;
}
int cgi_stub(char *method, char *path, char *path_args, char *args,
char **env, struct stat *finfo, int in, FILE *out)
{
int p[2];
int content, nph;
char *argv0;
FILE *psin;
char errlog[100];
if(!can_exec(finfo)) {
unmunge_name(path);
die(FORBIDDEN,path,out);
}
if((argv0 = strrchr(path,'/')) != NULL)
argv0++;
else argv0 = path;
chdir_file(path);
if(pipe(p) < 0)
die(SERVER_ERROR,"httpd: could not create IPC pipe",out);
if((pid = fork()) < 0) {
sprintf(errlog,"httpd: could not fork new process: 2/%d",errno);
die(SERVER_ERROR,errlog,out);
}
nph = (strncmp(argv0,"nph-",4) ? 0 : 1);
if(!pid) {
close(p[0]);
in_headers_env = add_cgi_vars(in_headers_env,method,path,path_args,args,&content,out);
if(content)
if(in != STDIN_FILENO) {
dup2(in,STDIN_FILENO);
close(in);
}
if(nph) {
if(fileno(out) != STDOUT_FILENO) {
dup2(fileno(out),STDOUT_FILENO);
fclose(out);
}
} else {
if(p[1] != STDOUT_FILENO) {
dup2(p[1],STDOUT_FILENO);
close(p[1]);
}
}
error_log2stderr();
/* To make the signal handling work on HPUX, according to
David-Michael Lincke (dlincke@bandon.unisg.ch) */
#ifdef HPUX
signal(SIGCHLD, SIG_DFL);
#endif
/* Only ISINDEX scripts get decoded arguments. */
if((!args[0]) || (ind(args,'=') >= 0)) {
if(execle(path,argv0,(char *)0,in_headers_env) == -1) {
fprintf(stderr,"httpd: exec of %s failed, errno is %d\n",
path,errno);
exit(1);
}
}
else {
if(execve(path,create_argv(argv0,args,out),in_headers_env) == -1) {
fprintf(stderr,"httpd: exec of %s failed, errno is %d\n",
path,errno);
exit(1);
}
}
}
else {
if (nph) close(p[0]);
close(p[1]);
}
if(!nph) {
if(!(psin = fdopen(p[0],"r")))
die(SERVER_ERROR,"could not read from script",out);
content_type[0] = '\0';
scan_script_header(psin,out);
/* we never redirect and die now
if(scan_script_header(psin,out)) {
kill_children();
return REDIRECT_URL;
}
*/
if(location[0] == '/') {
char t[HUGE_STRING_LEN],a[HUGE_STRING_LEN],*argp;
a[0] = '\0';
fclose(psin);
waitpid(pid,NULL,0);
strcpy(t,location);
if(argp = strchr(t,'?')) {
*argp++ = '\0';
strcpy(a,argp);
}
status = 302;
log_transaction();
status = 200;
init_header_vars(); /* clear in_header_env and 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,protocal, HUGE_STRING_LEN - strlen(the_request));
process_get(in,out,"GET",t,a);
return REDIRECT_LOCAL;
}
content_length = -1;
if(!assbackwards)
send_http_header(out);
if(!header_only) {
/* Send a default body of text if the script
failed to produce any, but ONLY for redirects */
if (!send_fd(psin,out,NULL) && location[0]) {
title_html(out,"Document moved");
fprintf(out,"This document has moved <A HREF=\"%s\">here</A>.<P>%c",location,LF);
}
} else
kill_children();
fclose(psin);
}
else bytes_sent = -1;
waitpid(pid,NULL,0);
return 0;
}
/* Called for ScriptAliased directories */
void exec_cgi_script(char *method, char *path, char *args, int in, FILE *out)
{
struct stat finfo;
char path_args[HUGE_STRING_LEN];
int m = M_GET;
int stub_returns;
get_path_info(path,path_args,out,&finfo);
if((!strcmp(method,"GET")) || (!strcmp(method,"HEAD"))) m=M_GET;
else if(!strcmp(method,"POST")) m=M_POST;
else if(!strcmp(method,"PUT")) m=M_PUT;
else if(!strcmp(method,"DELETE")) m=M_DELETE;
evaluate_access(path,&finfo,m,&allow,&allow_options,out);
if(!allow) {
log_reason("client denied by server configuration",path);
unmunge_name(path);
die(FORBIDDEN,path,out);
}
if(!(in_headers_env = add_common_vars(in_headers_env,out))) {
free_env(in_headers_env);
in_headers_env = NULL;
die(NO_MEMORY,"exec_cgi_script",out);
}
bytes_sent = 0;
stub_returns = cgi_stub(method,path,path_args,args,in_headers_env,&finfo,in,out);
if (in_headers_env != NULL) {
free_env(in_headers_env);
in_headers_env = NULL;
}
switch (stub_returns) {
case REDIRECT_URL:
die(REDIRECT,location,out);
break;
case REDIRECT_LOCAL:
break;
default:
log_transaction();
break;
}
}
char **set_env_NCSA(FILE *out) {
char **env;
int n;
char t[MAX_STRING_LEN];
if(!(env = (char **) malloc ((4+2)*sizeof(char *))))
die(NO_MEMORY,"set_env_NCSA",out);
n=0;
env[n++] = make_env_str("PATH",getenv("PATH"),out);
env[n++] = make_env_str("DOCUMENT_ROOT",document_root,out);
env[n++] = make_env_str("SERVER_ROOT",server_root,out);
env[n++] = make_env_str("REMOTE_HOST",remote_name,out);
sprintf(t,"SERVER_NAME=%s:%d",server_hostname,port);
if(!(env[n++] = strdup(t)))
die(NO_MEMORY,"set_env_NCSA",out);
env[n] = NULL;
return env;
}
void exec_get_NCSA(char *path, char *args, int in, FILE *fd) {
FILE *tfp;
struct stat finfo;
int pfd[2];
char path_args[MAX_STRING_LEN];
char t[MAX_STRING_LEN];
register int n,x;
char **env;
env = set_env_NCSA(fd);
path_args[0] = '\0';
/* check if it's really a script with extra args */
n=count_dirs(path);
for(x=0;x<=n;x++) {
make_dirstr(path,x+1,t);
if(!(stat(t,&finfo))) {
if(S_ISREG(finfo.st_mode)) {
strcpy(path_args,&path[strlen(t)]);
strcpy(path,t);
goto run_script;
}
}
}
log_reason("script not found or unable to stat",path);
unmunge_name(path);
die(NOT_FOUND,path,fd);
run_script:
if(!can_exec(&finfo)) {
log_reason("file permissions deny server execution",path);
unmunge_name(path);
die(FORBIDDEN,path,fd);
}
evaluate_access(path,&finfo,M_GET,&allow,&allow_options,fd);
if(!allow) {
unmunge_name(path);
die(FORBIDDEN,path,fd);
}
if(pipe(pfd) < 0)
die(SERVER_ERROR,"could not open pipe",fd);
signal(SIGALRM,send_fd_timed_out);
signal(SIGPIPE,send_fd_timed_out);
alarm(timeout);
if((pid = fork()) < 0)
die(SERVER_ERROR,"could not fork",fd);
else if(!pid) {
char *argv0;
close(pfd[0]);
if(pfd[1] != STDOUT_FILENO) {
dup2(pfd[1],STDOUT_FILENO);
close(pfd[1]);
}
if(argv0 = strrchr(path,'/'))
argv0++;
else
argv0 = path;
if(args[0] && path_args[0]) {
if(execle(path,argv0,path_args,args,(char *)0,env) == -1)
exit(1);
}
else if(args[0]) {
if(execle(path,argv0,args,(char *)0,env) == -1)
exit(1);
}
else if(path_args[0]) {
if(execle(path,argv0,path_args,(char *)0,env) == -1)
exit(1);
}
else
if(execle(path,argv0,(char *)0,env) == -1)
exit(1);
}
else
close(pfd[1]);
tfp = fdopen(pfd[0],"r");
scan_script_header(tfp,fd);
/* don't force the redirect.. it'll happen
if(scan_script_header(tfp,fd))
die(REDIRECT,location,fd);
*/
if(location[0] == '/') {
char *t;
if(!(t = strdup(location)))
die(NO_MEMORY,"exec_get_NCSA",fd);
location[0] = '\0';
send_node(t,"",in,fd);
fclose(tfp);
htexit(0,fd);
}
if(!assbackwards)
send_http_header(fd);
if(!header_only) {
/* Send a default body of text if the script
failed to produce any, but ONLY for redirects */
if (!send_fd(tfp,fd,NULL) && location[0]) {
title_html(fd,"Document moved");
fprintf(fd,"This document has moved <A HREF=\"%s\">here</A>.<P>%c",location,LF);
}
} else
kill_children();
fclose(tfp);
waitpid(pid,NULL,0);
}
void exec_post_NCSA(char *path, char *args, int in, FILE *out) {
int inpipe[2],outpipe[2];
char cl[MAX_STRING_LEN];
FILE *psin;
struct stat finfo;
char **env;
char errlog[100];
env = set_env_NCSA(out);
sprintf(cl,"%d",content_length);
if(stat(path,&finfo) == -1) {
unmunge_name(path);
if(errno == ENOENT) die(NOT_FOUND,path,out);
die(FORBIDDEN,path,out);
}
evaluate_access(path,&finfo,M_POST,&allow,&allow_options,out);
if(!allow)
die(FORBIDDEN,path,out);
if(pipe(inpipe) < 0)
die(SERVER_ERROR,"httpd: could not create IPC pipe",out);
if(pipe(outpipe) < 0)
die(SERVER_ERROR,"httpd: could not create IPC pipe",out);
if((pid = fork()) < 0) {
sprintf(errlog,"httpd: could not fork new process 1/%d",errno);
die(SERVER_ERROR,errlog,out);
}
if(!pid) {
char *argv0;
if(outpipe[1] != STDOUT_FILENO) {
dup2(outpipe[1],STDOUT_FILENO);
close(outpipe[1]);
}
if(in != STDIN_FILENO) {
dup2(in,STDIN_FILENO);
close(in);
}
if((argv0 = strrchr(path,'/')) != NULL)
argv0++;
else argv0 = path;
if(execle(path,argv0,cl,args,(char *)0,env) == -1)
exit(1);
}
else {
close(outpipe[1]);
close(inpipe[0]);
}
if(!(psin = fdopen(outpipe[0],"r")))
die(SERVER_ERROR,"could not read from script",out);
scan_script_header(psin,out);
/* don't force the redirect, it'll happen
if(scan_script_header(psin,out))
die(REDIRECT,location,out);
*/
if(location[0] == '/') {
char *t;
if(!(t = strdup(location)))
die(NO_MEMORY,"exec_post_NCSA",out);
location[0] = '\0';
send_node(t,"",in,out);
fclose(psin);
htexit(0,out);
}
content_length = -1;
if(!assbackwards)
send_http_header(out);
/* send a default body of text if the script
failed to produce any, but ONLY for redirects */
if (!send_fd(psin,out,NULL) && location[0]) {
title_html(out,"Document moved");
fprintf(out,"This document has moved <A HREF=\"%s\">here</A>.<P>%c",location,LF);
}
fclose(psin);
waitpid(pid,NULL,0);
}

579
src/http_send.c Normal file
View File

@ -0,0 +1,579 @@
/************************************************************************
* 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
*
************************************************************************
*
* 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
* type of request it is if its not for a regular file
*
*
*/
#include "config.h"
#include "portability.h"
#include <stdio.h>
#ifndef NO_STDLIB_H
# include <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 <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"
#include "blackout.h"
static void (*exit_callback)(void);
void send_node(per_request *reqInfo)
{
struct stat finfo;
register x = 0;
int allow;
char allow_options;
int ErrReturn = 0;
exit_callback = NULL;
/* It is no longer necessary to move all but one of the trailing slashes
* to the path_info string, since all multiple slashes are now compressed
* to one as a security precaution.
*/
if(stat(reqInfo->filename,&finfo) == -1) {
ErrReturn = extract_path_info(reqInfo,&finfo);
}
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) {
log_reason(reqInfo,"client denied by server configuration",
reqInfo->filename);
die(reqInfo,SC_FORBIDDEN,reqInfo->url);
}
if (S_ISDIR(finfo.st_mode)) {
send_dir(reqInfo,&finfo,allow_options);
} 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);
if (!strcmp(reqInfo->outh_content_type, CGI_MAGIC_TYPE))
send_cgi(reqInfo,&finfo,allow_options);
#ifdef IMAGEMAP_SUPPORT
else if (!strcmp(reqInfo->outh_content_type, IMAGEMAP_MAGIC_TYPE))
send_imagemap(reqInfo,&finfo,allow_options);
#endif /* IMAGEMAP_SUPPORT */
else
send_file(reqInfo,&finfo,allow_options);
} else {
log_reason(reqInfo,"improper file type",reqInfo->filename);
/* device driver or pipe, no permission */
die(reqInfo,SC_FORBIDDEN,reqInfo->url);
}
}
void send_file(per_request *reqInfo, struct stat *fi, char allow_options)
{
FILE *f;
#ifdef BLACKOUT_CODE
int isblack = FALSE;
#endif /* BLACKOUT_CODE */
if ((reqInfo->method != M_GET) && (reqInfo->method != M_HEAD)) {
sprintf(error_msg,"%s to non-script",methods[reqInfo->method]);
die(reqInfo,SC_NOT_IMPLEMENTED,error_msg);
}
set_content_type(reqInfo,reqInfo->filename);
if((allow_options & OPT_INCLUDES) && (!reqInfo->outh_content_encoding[0])) {
#ifdef XBITHACK
if((fi->st_mode & S_IXUSR) ||
(!strcmp(reqInfo->outh_content_type,INCLUDES_MAGIC_TYPE))) {
#else
if(!strcmp(reqInfo->outh_content_type,INCLUDES_MAGIC_TYPE)) {
#endif /* XBITHACK */
reqInfo->bytes_sent = 0;
send_parsed_file(reqInfo, allow_options & OPT_INCNOEXEC);
log_transaction(reqInfo);
return;
}
}
if (reqInfo->path_info[0]) {
strcat(reqInfo->filename,reqInfo->path_info);
strcat(reqInfo->url,reqInfo->path_info);
sprintf(error_msg,"No file matching URL: %s",reqInfo->url);
log_reason(reqInfo, error_msg, reqInfo->filename);
die(reqInfo,SC_NOT_FOUND,reqInfo->url);
}
if(!(f=FOpen(reqInfo->filename,"r"))) {
if (errno == EACCES) {
log_reason(reqInfo,"(1) file permissions deny server access",
reqInfo->filename);
/* we've already established that it exists */
die(reqInfo,SC_FORBIDDEN,reqInfo->url);
} else {
/* We know an error occured, of an unexpected variety.
* This could be due to no more file descriptors. We have this
* child exit after this stage so that errors of state are
* swept under the carpet.
*/
standalone = 0;
sprintf(error_msg,"File Open error, errno=%d",errno);
log_reason(reqInfo,error_msg,reqInfo->filename);
die(reqInfo,SC_SERVER_ERROR,error_msg);
}
}
reqInfo->bytes_sent = 0;
#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);
if (set_last_modified(reqInfo,fi->st_mtime)) {
FClose(f);
return;
}
}
if (reqInfo->http_version != P_HTTP_0_9) {
send_http_header(reqInfo);
}
#ifdef BLACKOUT_CODE
}
#endif /* BLACKOUT_CODE */
if(reqInfo->method != M_HEAD) {
#ifdef BLACKOUT_CODE
if (isblack == TRUE)
send_fp_black(reqInfo,f,NULL);
else
#endif /* BLACKOUT_CODE */
send_fp(reqInfo,f,NULL);
}
log_transaction(reqInfo);
FClose(f);
}
void send_dir(per_request *reqInfo,struct stat *finfo, char allow_options) {
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 */
/* if (pa[0] != '/') { */
if ((reqInfo->filename[strlen(reqInfo->filename) - 1] != '/') &&
(reqInfo->path_info[0] != '/')) {
strcpy_dir(ifile,reqInfo->url);
construct_url(temp_name,reqInfo->hostInfo,ifile);
escape_url(temp_name);
die(reqInfo,SC_REDIRECT_PERM,temp_name);
}
/* Don't allow PATH_INFO to directory indexes as a compromise for
error messages for files which don't exist */
if ((reqInfo->path_info[0] != '\0') || (strlen(reqInfo->path_info) > 1)) {
strcat(reqInfo->filename,reqInfo->path_info);
strcat(reqInfo->url,reqInfo->path_info);
sprintf(error_msg,"No file matching URL: %s",reqInfo->url);
log_reason(reqInfo, error_msg, reqInfo->filename);
freeString(temp_name);
freeString(ifile);
die(reqInfo,SC_NOT_FOUND,reqInfo->url);
}
strncpy(temp_name, reqInfo->hostInfo->index_names, HUGE_STRING_LEN-1);
end_ptr = name_ptr = temp_name;
while (*name_ptr) {
while (*name_ptr && isspace (*name_ptr)) ++name_ptr;
end_ptr = name_ptr;
if (strchr(end_ptr, ' ') ) {
end_ptr = strchr(name_ptr, ' ');
*end_ptr = '\0';
end_ptr++;
} else
end_ptr += strlen(end_ptr);
make_full_path(reqInfo->filename,name_ptr,ifile);
if(stat(ifile,finfo) == -1) {
if(! *end_ptr && (allow_options & OPT_INDEXES)) {
if (reqInfo->path_info[0]) {
strcat(reqInfo->filename,reqInfo->path_info);
strcat(reqInfo->url,reqInfo->path_info);
log_reason(reqInfo,"file does not exist",reqInfo->filename);
freeString(ifile);
freeString(temp_name);
die(reqInfo,SC_NOT_FOUND,reqInfo->url);
}
if ((reqInfo->method != M_GET) && (reqInfo->method != M_HEAD)) {
sprintf(error_msg,"%s to non-script",methods[reqInfo->method]);
freeString(ifile);
freeString(temp_name);
die(reqInfo,SC_NOT_IMPLEMENTED,error_msg);
}
index_directory(reqInfo);
freeString(ifile);
freeString(temp_name);
return;
} else if (! *end_ptr) {
log_reason(reqInfo,"(2) file permissions deny server access",
reqInfo->filename);
freeString(ifile);
freeString(temp_name);
die(reqInfo,SC_FORBIDDEN,reqInfo->url);
}
} else {
strcpy(reqInfo->filename,ifile);
probe_content_type(reqInfo,reqInfo->filename);
if(!strcmp(reqInfo->outh_content_type,CGI_MAGIC_TYPE))
send_cgi(reqInfo,finfo,allow_options);
else
send_file(reqInfo,finfo,allow_options);
freeString(ifile);
freeString(temp_name);
return;
}
name_ptr = end_ptr;
}
}
/* Search down given translated URL searching for actual file name and filling
* in path_info string. Doesn't make any claims about file type, must be
* handled elsewhere.
* Returns 0 on success, errno on failure
*/
int extract_path_info(per_request *reqInfo, struct stat *finfo)
{
register int x,max;
char *str;
str = newString(HUGE_STRING_LEN,STR_TMP);
max=count_dirs(reqInfo->filename);
for(x=max ; x > 0 ; x--) {
make_dirstr(reqInfo->filename,x+1,str);
if(!(stat(str,finfo))) {
int l=strlen(str);
strcat(reqInfo->path_info,&(reqInfo->filename[l]));
reqInfo->filename[l] = '\0';
reqInfo->url[strlen(reqInfo->url) - strlen(reqInfo->path_info)]='\0';
freeString(str);
return 0;
}
}
freeString(str);
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)
{
char *errstr;
errstr = newString(HUGE_STRING_LEN,STR_TMP);
if(exit_callback) (*exit_callback)();
if (sigcode != SIGPIPE) {
sprintf(errstr,"HTTPd: send timed out for %s, URL: %s",
(gCurrentRequest->remote_name ?
gCurrentRequest->remote_name : "remote host"),
(gCurrentRequest->url ? gCurrentRequest->url : "-"));
}
else {
sprintf(errstr,"HTTPd: send aborted for %s, URL: %s",
(gCurrentRequest->remote_name ?
gCurrentRequest->remote_name : "remote host"),
(gCurrentRequest->url ? gCurrentRequest->url : "-"));
}
log_error(errstr,gCurrentRequest->hostInfo->error_log);
log_transaction(gCurrentRequest);
alarm(0);
signal(SIGALRM,SIG_IGN);
signal(SIGPIPE,SIG_IGN);
CloseAll(); /* close all spurious file descriptors */
if (!standalone) {
fclose(stdin);
fclose(stdout);
exit(0);
} else {
#ifdef NO_SIGLONGJMP
longjmp(jmpbuffer,1);
#else
siglongjmp(jmpbuffer,1);
#endif /* NO_SIGLONGJMP */
}
}
/* send_fp(): sends a file pointer to the socket. Uses fread to read,
* but uses non-buffered I/O for writes (write())
*
* 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))
{
char *buf;
long total_bytes_sent;
register int n,o,w;
buf = newString(IOBUFSIZE,STR_TMP);
exit_callback = onexit;
signal(SIGALRM,send_fd_timed_out);
signal(SIGPIPE,send_fd_timed_out);
total_bytes_sent = 0;
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;
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.
*/
w = write(fileno(reqInfo->out),&buf[o],n);
if (w < 0) {
if (errno != EINTR) break;
}
n-=w;
o+=w;
total_bytes_sent += w;
}
}
alarm(0);
signal(SIGALRM,SIG_IGN);
signal(SIGPIPE,SIG_IGN);
freeString(buf);
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);
}

38
src/http_send.h Normal file
View File

@ -0,0 +1,38 @@
/************************************************************************
* 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
*
************************************************************************
*
* http_send.h,v 1.10 1996/03/27 20:44:12 blong Exp
*
************************************************************************
*
*/
#ifndef _HTTP_SEND_H_
#define _HTTP_SEND_H_
/* function prototypes */
void send_node(per_request *reqInfo);
void send_file(per_request *reqInfo, struct stat *fi, char allow_options);
void send_dir(per_request *reqInfo,struct stat *finfo, char allow_options);
int extract_path_info(per_request *reqInfo, struct stat *finfo);
long send_fp(per_request *reqInfo, FILE *f, void (*onexit)(void));
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_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,824 +1,63 @@
/* /************************************************************************
* 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
*
************************************************************************
*
* httpd.h,v 1.97 1996/03/27 20:44:19 blong Exp
*
************************************************************************
*
* httpd.h: header for simple (ha! not anymore) http daemon * httpd.h: header for simple (ha! not anymore) http daemon
* *
* All code contained herein is covered by the Copyright as distributed * contains:
* in the README file in the main directory of the distribution of * struct _ChildInfo -> ChildInfo
* NCSA HTTPD.
* *
*/ */
/* Define one of these according to your system. */ #ifndef _HTTPD_H_
#if defined(SUNOS4) #define _HTTPD_H_
#define BSD
#undef NO_KILLPG #include <setjmp.h>
#undef NO_SETSID #include "http_request.h"
#define FD_BSD
char *crypt(char *pw, char *salt); typedef struct _ChildInfo {
int parentfd;
#elif defined(SOLARIS2) int childfd;
#undef BSD int pid;
#define NO_KILLPG int busy;
#undef NO_SETSID #ifdef NOT_READY
#define FD_BSD int status;
#define bzero(a,b) memset(a,0,b) KeepAliveData keep_alive; /* Child's keep alive info */
#define getwd(d) getcwd(d,MAX_STRING_LEN) int csd; /* Current Socket Descriptor */
#define JMP_BUF sigjmp_buf JMP_BUF restart_child; /* Return buffer for siglongjmp */
per_request *gCurrentRequest; /* Current Request of Child */
#elif defined(IRIX) #endif /* NOT_READY */
#undef BSD } ChildInfo;
#undef NO_KILLPG
#undef NO_SETSID #ifndef NOT_READY
#define FD_BSD extern KeepAliveData keep_alive; /* global keep alive info */
#define JMP_BUF sigjmp_buf extern JMP_BUF jmpbuffer; /* Return buffer for siglongjmp */
extern int csd; /* Current Socket Descriptor */
#elif defined(HPUX) #endif /* NOT_READY */
#undef BSD
#define NO_KILLPG
#undef NO_SETSID /* function prototypes */
#define FD_BSD
#ifndef _HPUX_SOURCE void set_signals(void);
#define _HPUX_SOURCE
#endif
#define getwd(d) getcwd(d,MAX_STRING_LEN)
#define JMP_BUF sigjmp_buf
#elif defined(AIX3)
#undef BSD
#undef NO_KILLPG
#undef NO_SETSID
#define FD_BSD
#define NEED_SELECT_H
#define JMP_BUF sigjmp_buf
#elif defined(AIX4)
#undef BSD
#undef NO_KILLPG
#undef NO_SETSID
#define FD_BSD
#define FD_BSDRENO
#define NEED_SELECT_H
#define JMP_BUF sigjmp_buf
#elif defined(ULTRIX)
#define BSD
#define FD_BSD
#undef NO_KILLPG
#undef NO_SETSID
#define ULTRIX_BRAIN_DEATH
#define NEED_STRDUP
/* If you have Ultrix 4.3, and are using cc, const is broken */
#ifndef __ultrix__ /* Hack to check for pre-Ultrix 4.4 cc */
#define const /* Not implemented */
#endif
#define JMP_BUF sigjmp_buf
#elif defined(OSF1)
#define BSD
#define FD_BSD
#undef NO_KILLPG
#undef NO_SETSID
#define JMP_BUF sigjmp_buf
#elif defined(SEQUENT)
#define BSD
#undef NO_KILLPG
#define NO_SETSID
#define NEED_STRDUP
#define tolower(c) (isupper(c) ? tolower(c) : c)
#elif defined(NeXT)
#define BSD
#define FD_BSD
#undef NO_KILLPG
#define NO_SETSID
#define NEED_STRDUP
#undef _POSIX_SOURCE
#ifndef S_IXUSR
#define S_IXUSR _S_IXUSR
#endif
#ifndef S_IXGRP
#define S_IXGRP 0000010
#endif
#ifndef S_IXOTH
#define S_IXOTH 0000001
#endif
#ifndef S_IRUSR
#define S_IRUSR _S_IRUSR
#endif
#ifndef S_IWUSR
#define S_IWUSR _S_IWUSR
#endif
#ifndef S_IRGRP
#define S_IRGRP 0000040
#endif
#ifndef S_IROTH
#define S_IROTH 0000004
#endif
#ifndef S_IWGRP
#define S_IWGRP 0000020
#endif
#ifndef S_IWOTH
#define S_IWOTH 0000002
#endif
#ifndef S_IRWXU
#define S_IRWXU 0000700
#endif
#ifndef S_IRWXG
#define S_IRWXG 0000070
#endif
#ifndef S_IRWXO
#define S_IRWXO 0000007
#endif
#ifndef S_ISBLK
#define S_ISBLK(m) (((m)&(_S_IFMT)) == (_S_IFBLK))
#endif
#ifndef S_ISCHR
#define S_ISCHR(m) (((m)&(_S_IFMT)) == (_S_IFCHR))
#endif
#ifndef S_ISDIR
#define S_ISDIR(m) (((m)&(_S_IFMT)) == (_S_IFDIR))
#endif
#ifndef S_ISFIFO
#define S_ISFIFO(m) (((m)&(_S_IFMT)) == (_S_IFIFO))
#endif
#ifndef S_ISREG
#define S_ISREG(m) (((m)&(_S_IFMT)) == (_S_IFREG))
#endif
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#define waitpid(a,b,c) wait4(a,b,c,NULL)
typedef int pid_t;
typedef int mode_t;
#define JMP_BUF jmp_buf
#elif defined(LINUX)
#define NO_PASS
#undef BSD
#undef NO_KILLPG
#undef NO_SETSID
#undef NEED_STRDUP
#define FD_SET __FD_SET
#define FD_ZERO __FD_ZERO
#define FD_ISSET __FD_ISSET
#define JMP_BUF sigjmp_buf
#elif defined(NETBSD)
#define BSD
#define FD_BSD
#define FD_BSDRENO
#elif defined(SCO)
#undef BSD
#undef NO_KILLPG
#undef NO_SETSID
#define NEED_INITGROUPS
#elif defined(SCO3)
#undef BSD
#define FD_SYSV
#define NEED_SPIPE
#undef NO_KILLPG
#undef NO_SETSID
#define NEED_INITGROUPS
#define CALL_TZSET
#define getwd(d) getcwd(d,MAX_STRING_LEN)
#define JMPBUF sigjmp_buf
#elif defined(CONVEXOS)
#define BSD
#define NEED_STRDUP
#define getwd(d) getcwd(d,MAX_STRING_LEN)
#elif defined(AUX)
#define BSD
#undef NO_KILLPG
#undef NO_SETSID
#define NEED_STRDUP
#ifdef _POSIX_SOURCE
# define JMP_BUF sigjmp_buf
#else
# define siglongjmp longjmp
# define sigsetjmp setjmp
# define JMP_BUF jmp_buf
# define STDIN_FILENO 0
# define STDOUT_FILENO 1
# define STDERR_FILENO 2
#endif
#elif defined(SVR4)
#define NO_KILLPG
#undef NO_SETSID
#undef NEED_STRDUP
#define NEED_STRCASECMP
#define NEED_STRNCASECMP
#define bzero(a,b) memset(a,0,b)
#define JMP_BUF sigjmp_buf
#define getwd(d) getcwd(d,MAX_STRING_LEN)
#elif defined(__NetBSD__)
#define BSD
#define FD_BSD
#define FD_BSDRENO
#undef NO_KILLPG
#undef NO_SETSID
#elif defined(__bsdi__)
#undef BSD
#define FD_BSD
#define FD_BSDRENO
#undef NO_KILLPG
#undef NO_SETSID
#elif defined(UTS21)
#undef BSD
#undef NO_KILLPG
#define NO_SETSID
#define NEED_WAITPID
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#define strftime(buf,bufsize,fmt,tm) ascftime(buf,fmt,tm)
#include <sys/types.h>
#elif defined(APOLLO)
#define BSD
#undef NO_KILLPG
#undef NO_SETSID
#define timezone _bky_timezone
#elif defined(ATTSVR3)
#define NO_SETSID
#undef BSD
#undef NO_KILLPG
#define NO_STRFTIME
#undef NEED_STRDUP
#undef NEED_STRCASECMP
#undef NEED_STRNCASECMP
#define SIGCHLD SIGCLD
#define STDIN_FILENO fileno(stdin)
#define STDOUT_FILENO fileno(stdout)
#define STDERR_FILENO fileno(stderr)
#ifndef S_ISDIR
#define S_ISDIR(m) (((m)&(S_IFMT)) == (S_IFDIR))
#endif
#ifndef S_ISREG
#define S_ISREG(m) (((m)&(S_IFMT)) == (S_IFREG))
#endif
#define lstat stat
#define strftime(buf,bufsize,fmt,tm) ascftime(buf,fmt,tm)
#define getwd(d) getcwd(d,MAX_STRING_LEN)
#define readlink(a,b,c) -1
typedef int uid_t;
typedef int gid_t;
typedef int pid_t;
extern struct group *getgrnam();
extern char *getenv();
#elif defined(__QNX__)
#define _POSIX_SOURCE
#define NEED_SELECT_H
#define NEED_INITGROUPS
#define wait3(a,b,c) waitpid(-1,a,b)
/* Unknown system - Edit these to match */
#else
/* BSD is whether your system uses BSD calls or System V calls. */
#define BSD
/* NO_KILLPG is set on systems that don't have killpg */
#undef NO_KILLPG
/* NO_SETSID is set on systems that don't have setsid */
#undef NO_SETSID
/* NEED_STRDUP is set on stupid systems that don't have strdup. */
#undef NEED_STRDUP
/* NO_PASS is set on systems that don't allow file descriptor passing */
#undef NO_PASS
/* FD_BSD is set on systems which pass file descriptors in a BSD way */
#undef FD_BSD
/* FD_BSDRENO is for BSD 4.3RENO systems for file descriptor passing */
#undef FD_BSDRENO
/* FD_SYSV is set on systems which pass file descriptor in a SYSV way */
#undef FD_SYSV
/* NEED_SPIPE is set on systems which are using FD_SYSV but don't have
socketpair */
#undef NEED_SPIPE
/* CALL_TZSET on systems which need to call tzset() before detaching from
the shell (some systems don't keep environment variables after detach) */
#undef CALL_TZSET
#endif
/* If we haven't set anything about file descriptor passing, set NO_PASS */
#if !defined(FD_BSD) && !defined(FD_SYSV) && !defined(NO_PASS)
#define NO_PASS
#endif
/*
* The particular directory style your system supports. If you have dirent.h
* in /usr/include (POSIX) or /usr/include/sys (SYSV), #include
* that file and define DIR_TYPE to be dirent. Otherwise, if you have
* /usr/include/sys/dir.h, define DIR_TYPE to be direct and include that
* file. If you have neither, I'm confused.
*/
#include <sys/types.h>
#if !defined(NeXT) && !defined(CONVEXOS) && !defined(APOLLO)
#if defined(ATTSVR3)
#include <malloc.h>
#endif
#include <dirent.h>
#define DIR_TYPE dirent
#else
#include <sys/dir.h>
#define DIR_TYPE direct
#endif
/* ----------------------------- config dir ------------------------------ */
/* Define this to be the default server home dir. Anything later in this
* file with a relative pathname will have this added.
*/
#define HTTPD_ROOT "/usr/local/etc/httpd"
/* Root of server */
#define DOCUMENT_LOCATION "/usr/local/etc/httpd/htdocs"
/* Max. number of aliases */
#define MAX_ALIASES 20
/* Max. number of security defines */
#define MAX_SECURITY 50
/* Default administrator's address */
#define DEFAULT_ADMIN "[no address given]"
/*
* --------- You shouldn't have to edit anything below this line ----------
*
* Any modifications to any defaults not defined above should be done in the
* respective config. file.
*
*/
/* -------------- Port number for server running standalone --------------- */
#define DEFAULT_PORT 80
/* --------- Default user name and group name running standalone ---------- */
/* --- These may be specified as numbers by placing a # before a number --- */
#define DEFAULT_USER "#-1"
#define DEFAULT_GROUP "#-1"
/* The name of the log files */
#define DEFAULT_XFERLOG "logs/access_log"
#define DEFAULT_AGENTLOG "logs/agent_log"
#define DEFAULT_REFERERLOG "logs/referer_log"
#define DEFAULT_ERRORLOG "logs/error_log"
#define DEFAULT_PIDLOG "logs/httpd.pid"
/* The referer documents to ignore */
#define DEFAULT_REFERERIGNORE ""
/* Define this to be what your HTML directory content files are called */
#define DEFAULT_INDEX "index.html"
/* Define this to 1 if you want fancy indexing, 0 otherwise */
#define DEFAULT_INDEXING 0
/* Define this to be what type you'd like returned for files with unknown */
/* suffixes */
#define DEFAULT_TYPE "text/html"
/* Define this to be what your per-directory security files are called */
#define DEFAULT_ACCESS_FNAME ".htaccess"
/* The name of the server config file */
#define SERVER_CONFIG_FILE "conf/httpd.conf"
/* The name of the document config file */
#define RESOURCE_CONFIG_FILE "conf/srm.conf"
/* The name of the MIME types file */
#define TYPES_CONFIG_FILE "conf/mime.types"
/* The name of the access file */
#define ACCESS_CONFIG_FILE "conf/access.conf"
/* Whether we should enable rfc931 identity checking */
#define DEFAULT_RFC931 0
/* The default directory in user's home dir */
#define DEFAULT_USER_DIR "public_html"
/* The default path for CGI scripts if none is currently set */
#define DEFAULT_PATH "/bin:/usr/bin:/usr/ucb:/usr/bsd:/usr/local/bin"
/* The path to the Bourne shell, for parsed docs */
#define SHELL_PATH "/bin/sh"
/* The default string lengths */
#define MAX_STRING_LEN 256
#define HUGE_STRING_LEN 8192
/* The timeout for waiting for messages */
#define DEFAULT_TIMEOUT 1200
/* The size of the server's internal read-write buffers */
#define IOBUFSIZE 8192
/* The number of header lines we will accept from a client */
#define MAX_HEADERS 200
/* Hi Roy. */
/* #define HTTP_TIME_FORMAT "%A, %d-%b-%y %T GMT" */
/* HTTP/1.0 specifies we use RFC 822 type date strings, so here we do */
/* RFC 1123 format for date */
#define HTTP_TIME_FORMAT "%a, %d %b %Y %T GMT"
/* ------------------------------ error types ------------------------------ */
#define SERVER_VERSION "NCSA/1.4.2"
#define SERVER_PROTOCOL "HTTP/1.0"
#define SERVER_SUPPORT "httpd@void.ncsa.uiuc.edu"
#define DOCUMENT_FOLLOWS 200
#define REDIRECT 302
#define REDIRECT_LOCAL 3020
#define USE_LOCAL_COPY 304
#define BAD_REQUEST 400
#define AUTH_REQUIRED 401
#define FORBIDDEN 403
#define NOT_FOUND 404
#define SERVER_ERROR 500
#define NOT_IMPLEMENTED 501
#define NO_MEMORY 6992
#define CONF_ERROR 6993
#define METHODS 4
#define M_GET 0
#define M_PUT 1
#define M_POST 2
#define M_DELETE 3
/* Object types */
#define REDIRECT_URL -1
#define STD_DOCUMENT 0
#define SCRIPT_NCSA 1
#define SCRIPT_CGI 2
#define OPT_NONE 0
#define OPT_INDEXES 1
#define OPT_INCLUDES 2
#define OPT_SYM_LINKS 4
#define OPT_EXECCGI 8
#define OPT_UNSET 16
#define OPT_INCNOEXEC 32
#define OPT_SYM_OWNER 64
#define OPT_ALL (OPT_INDEXES|OPT_INCLUDES|OPT_SYM_LINKS|OPT_EXECCGI)
#define OR_NONE 0
#define OR_LIMIT 1
#define OR_OPTIONS 2
#define OR_FILEINFO 4
#define OR_AUTHCFG 8
#define OR_INDEXES 16
#define OR_ALL (OR_LIMIT|OR_OPTIONS|OR_FILEINFO|OR_AUTHCFG|OR_INDEXES)
#define CGI_MAGIC_TYPE "application/x-httpd-cgi"
#define INCLUDES_MAGIC_TYPE "text/x-server-parsed-html"
/* For directory indexing */
#define BY_PATH 0
#define BY_TYPE 1
#define BY_ENCODING 2
#define FANCY_INDEXING 1
#define ICONS_ARE_LINKS 2
#define SCAN_HTML_TITLES 4
#define SUPPRESS_LAST_MOD 8
#define SUPPRESS_SIZE 16
#define SUPPRESS_DESC 32
#include <stdio.h>
#ifndef ATTSVR3
# include <stdlib.h>
# include <sys/wait.h>
#endif
#include <string.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/socket.h>
#ifdef NEED_SELECT_H
# include <sys/select.h>
#endif
#include <ctype.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/ioctl.h>
#include <arpa/inet.h> /* for inet_ntoa */
#ifndef MAXPATHLEN
# include <sys/param.h>
#endif
#include <time.h> /* for ctime */
#include <signal.h>
#include <errno.h>
#include <pwd.h>
#include <grp.h>
#include <fcntl.h>
#ifndef NeXT
# include <unistd.h>
#endif
#ifdef ultrix
# define ULTRIX_BRAIN_DEATH
#endif
#ifndef JMP_BUF
# define JMP_BUF sigjmp_buf
#endif
/* Just in case your linefeed isn't the one the other end is expecting. */
#define LF 10
#define CR 13
/* For access control */
#define DENY_THEN_ALLOW 0
#define ALLOW_THEN_DENY 1
#define MUTUAL_FAILURE 2
/* Struct shared by access and auth */
typedef struct {
char *d;
char opts;
char override;
int order[METHODS];
int num_allow[METHODS];
char *allow[METHODS][MAX_SECURITY];
int num_auth[METHODS];
char *auth[METHODS][MAX_SECURITY];
char *auth_type;
char *auth_name;
char *auth_pwfile;
char *auth_grpfile;
int num_deny[METHODS];
char *deny[METHODS][MAX_SECURITY];
} security_data;
/* Global, global, who's got the globals? */
/* Server config */
extern int standalone;
extern int port;
extern uid_t user_id;
extern gid_t group_id;
extern char server_root[MAX_STRING_LEN];
extern char annotation_server[MAX_STRING_LEN]; /* SSG 4/4/95 */
extern char error_fname[MAX_STRING_LEN];
extern char xfer_fname[MAX_STRING_LEN];
extern char agent_fname[MAX_STRING_LEN];
extern char referer_fname[MAX_STRING_LEN];
extern char pid_fname[MAX_STRING_LEN];
extern char server_admin[MAX_STRING_LEN];
extern char *server_hostname;
extern char server_confname[MAX_STRING_LEN];
extern char srm_confname[MAX_STRING_LEN];
extern char access_confname[MAX_STRING_LEN];
extern char types_confname[MAX_STRING_LEN];
extern int timeout;
extern int do_rfc931;
/* Document config */
extern char user_dir[MAX_STRING_LEN];
extern char index_name[MAX_STRING_LEN];
extern char access_name[MAX_STRING_LEN];
extern char document_root[MAX_STRING_LEN];
extern char default_type[MAX_STRING_LEN];
extern char local_default_type[MAX_STRING_LEN];
extern char default_icon[MAX_STRING_LEN];
extern char local_default_icon[MAX_STRING_LEN];
extern char blank_icon[MAX_STRING_LEN];
extern int fancy_indexing;
extern char readme_fname[MAX_STRING_LEN];
/* Security config */
extern int num_sec;
extern security_data sec[MAX_SECURITY];
/* Auth config */
extern char *auth_type;
extern char *auth_name;
extern char *auth_pwfile;
extern char *auth_grpfile;
extern char user[MAX_STRING_LEN];
extern char groupname[MAX_STRING_LEN];
/* Request information */
extern int assbackwards;
extern int header_only;
extern char *remote_host;
extern char *remote_ip;
extern char *remote_name;
extern char *remote_logname;
extern int allow;
extern char allow_options;
extern int num_includes;
extern int dirs_in_alias;
/* MIME */
extern char auth_line[MAX_STRING_LEN];
extern int content_length;
extern char content_type[MAX_STRING_LEN];
extern char content_encoding[MAX_STRING_LEN];
extern char location[MAX_STRING_LEN];
extern char **in_headers_env;
/* http_log */
extern FILE *error_log;
extern int bytes_sent;
extern int status;
/* Function prototypes. */
/* http_config */
void read_config();
void parse_htaccess(char *dir, char override, FILE *out);
int get_pw(char *user, char *pw, FILE *errors);
int in_group(char *user, char *group);
int init_group(char *grpfile, FILE *out);
void kill_group();
/* http_alias */
void reset_aliases();
void dump_aliases();
void add_alias(char *f, char *r, int is_script);
void add_redirect(char *f, char *url);
int translate_name(char *name,FILE *fd);
void unmunge_name(char *name);
void save_aliases();
void reset_to_saved_aliases();
/* http_request */
void process_request(int in, FILE *out);
long send_fd(FILE *f, FILE *fd, void (*onexit)());
void send_fd_timed_out();
int find_script(char *method, char *name, char *args, int in, FILE *out);
/* http_get */
void send_cgi(char *method, char *file, char *path_args, char *args,
struct stat *finfo, int in, FILE *fd);
void send_file(char *file, FILE *fd, struct stat *fi,
char *path_args, char *args);
void process_include(FILE *f, FILE *fd, char *incstring, char *args);
void send_node(char *name, char *args, int in, FILE *fd);
void process_get(int in, FILE *out, char *m, char *url, char *args);
/* http_post */
void post_node(char *name, char *args, int in, FILE *out);
/* http_put */
void put_node(char *name, char *args, int in, FILE *out);
/* http_delete */
void delete_node(char *name, char *args, int in, FILE *out);
/* http_script */
void exec_cgi_script(char *method, char *path, char *args, int in, FILE *out);
int cgi_stub(char *method, char *path, char *path_args, char *args,
char **env, struct stat *finfo, int in, FILE *out);
void exec_get_NCSA(char *path, char *args, int in, FILE *fd);
void exec_post_NCSA(char *path, char *args, int in, FILE *out);
char **add_common_vars(char **env, FILE *out);
void get_path_info(char *path, char *path_args, FILE *out,
struct stat *finfo);
/* http_dir */
void index_directory(char *name, FILE *fd);
void add_icon(int type, char *icon, char *to, char *path, FILE *out);
void add_alt(int type, char *alt, char *to, char *path, FILE *out);
void add_desc(int type, char *desc, char *to, char *path, FILE *out);
void add_ignore(char *ext, char *path, FILE *out);
void add_header(char *name, char *path, FILE *out);
void add_readme(char *name, char *path, FILE *out);
void add_opts(char *optstr, char *path, FILE *out);
void add_opts_int(int opts, char *path, FILE *out);
void send_size(size_t size, FILE *fd);
void init_indexing();
void kill_indexing();
/* http_log */
void record_request(char *cmd_line);
void log_error(char *err);
void log_error_noclose(char *err);
void log_reason(char *reason, char *file);
int die(int type, char *err_string, FILE *fd);
void open_logs();
void close_logs();
void begin_http_header(FILE *fd, const char *msg);
void error_log2stderr();
void log_transaction();
void htexit(int status, FILE *out);
/* http_mime */
void get_mime_headers(int fd, FILE *out, char* url);
void init_header_vars();
void send_http_header(FILE *fd);
void set_content_type(char *fn);
int set_last_modified(time_t t, FILE *out);
void probe_content_type(char *fn);
int scan_script_header(FILE *f, FILE *fd);
void add_type(char *fn, char *t,FILE *out);
void add_encoding(char *fn, char *t,FILE *out);
void set_content_length(int l);
void dump_types();
void init_mime();
void kill_mime();
int is_content_type(char *type);
void dump_default_header(FILE *fd);
/* http_access */
void evaluate_access(char *path, struct stat *finfo,int m, int *allow,
char *op, FILE *out);
void kill_security();
/* http_auth */
void check_auth(security_data *s, int m, FILE *out);
/* http_include */
void send_parsed_file(char *file, FILE *fd, char *path_args, char *args,
int noexec);
/* util */
void inststr(char *dst[], int argc, char *src);
void chdir_file(char *file);
void http2cgi(char *w);
int later_than(struct tm *tms, char *i);
int strcmp_match(char *str, char *exp);
int is_matchexp(char *str);
void strsubfirst(int start,char *dest, char *src);
void make_full_path(char *src1,char *src2,char *dst);
int is_directory(char *name);
int is_url(char *u);
void getparents(char *name);
void no2slash(char *name);
uid_t uname2id(char *name);
gid_t gname2id(char *name);
int getline(char *s, int n, int f, unsigned int timeout);
int eat_ws (FILE* fp);
int cfg_getline(char *s, int n, FILE *f);
void getword(char *word, char *line, char stop);
void cfg_getword(char *word, char *line);
void get_remote_host(int fd);
char *get_time();
char *gm_timestr_822(time_t t);
char *ht_time(time_t t, char *fmt, int gmt);
struct tm *get_gmtoff(long *tz);
void make_dirstr(char *s, int n, char *d);
int count_dirs(char *path);
void strcpy_dir(char *d, char *s);
void unescape_url(char *url);
void escape_url(char *url);
void escape_shell_cmd(char *cmd);
void plustospace(char *str);
void spacetoplus(char *str);
void str_tolower(char *str);
void uudecode(char *s,unsigned char *d,int dl);
#ifdef NEED_STRDUP
char *strdup (char *str);
#endif
#ifdef NEED_STRCASECMP
int strcasecmp(const char *s1, const char *s2);
#endif
#ifdef NEED_STRNCASECMP
int strncasecmp(const char *s1, const char *s2, int n);
#endif
char *make_env_str(char *n, char *v, FILE *out);
char **new_env(char **env, int to_add, int *pos);
void free_env(char **env);
int ind(char *s, char c);
int rind(char *s, char c);
void construct_url(char *d, char *s);
void get_local_host();
int get_portnum(int sd,FILE *out);
int can_exec(struct stat *finfo);
#ifdef NEED_INITGROUPS
int initgroups(const char *name, gid_t basegid);
#endif
char *get_remote_logname(FILE *fd);
char *rfc931(struct sockaddr_in *rmt_sin,struct sockaddr_in *our_sin); char *rfc931(struct sockaddr_in *rmt_sin,struct sockaddr_in *our_sin);
void strncpy_dir(char *d, char *s, int n); char *get_remote_logname(FILE *fd);
void lim_strcpy(char *d, char *s, int n);
int WaitForRequest(int, KeepAliveData*);
void CompleteRequest(per_request *reqInfo,int pipe);
void GetDescriptor(int parent_pipe);
char* GetRemoteLogName(SERVER_SOCK_ADDR *sa_server);
void htexit(per_request *reqInfo, int status, int die_type);
#endif /* _HTTPD_H_ */

66
src/httpd.man Normal file
View File

@ -0,0 +1,66 @@
.TH httpd 1m "October 1995"
.SH NAME
httpd \- NCSA HTTPd (hypertext transfer protocol daemon)
.SH SYNOPSIS
.B httpd
[
.B \-v
] [
.B \-X
] [
.BI \-d " serverroot"
] [
.BI \-f " config"
]
.SH DESCRIPTION
.B httpd
is the NCSA HTTPd (HyperText Transfer Protocol daemon) server. The server may
be invoked by the Internet daemon inetd(1M) each time a connection to the
HTTP service is made, or alternatively it may run as a daemon. We suggest
if you have any real amount of traffic to your server that you run NCSA
HTTPd as a daemon.
.SH OPTIONS
.TP 12
.BI \-d serverroot
Set the inital value for the ServerRoot variable to \fIserverroot\fP. This
can be overriden by the ServerRoot command in the configuration file. The
default is \fB/usr/local/etc/httpd\fP.
.TP
.BI \-f config
Execute the commands in the file \fIconfig\fP on startup. If \fIconfig\fP
does not begin with a /, then it is taken to be a path relative to
the ServerRoot. The default is \fBconf/httpd.conf\fP.
.TP
.B \-v
Print the version of httpd, including compiled defaults and
command line options.
.TP
.B \-X
Execute in single request debugging mode, with no fork, no detach.
Useful for profiling and debugging.
.SH FILES
.PD 0
.B /usr/local/etc/httpd/conf/httpd.conf
.br
.B /usr/local/etc/httpd/conf/srm.conf
.br
.B /usr/local/etc/httpd/conf/access.conf
.br
.B /usr/local/etc/httpd/conf/mime.types
.br
.B /usr/local/etc/httpd/logs/error_log
.br
.B /usr/local/etc/httpd/logs/access_log
.br
.B /usr/local/etc/httpd/logs/agent_log
.br
.B /usr/local/etc/httpd/logs/referer_log
.br
.B /usr/local/etc/httpd/logs/httpd.pid
.PD
.SH SEE ALSO
.BR inetd (1m).
.PP
Documentation for the NCSA HTTPd server is available from
http://hoohoo.ncsa.uiuc.edu/

563
src/httpy.h Normal file
View File

@ -0,0 +1,563 @@
/* zippy.c
*
* Print a quotation from Zippy the Pinhead.
* Qux <Kaufman-David@Yale> March 6, 1986
*
*/
/*
* Zippy the pinhead data base.
* The official copy of this is in the file "MLY;YOW >" on AI.AI.MIT.EDU
* Everything up to the first ascii \000 (`null') character is a comment.
* The file consits of zippy quotations (from various comic books and
* strips by Bill Griffith) followed by a null character. Newline chracters
* following a quotation are ignored and are present only for readability.
* Have FUN!
* This file is currently used by:
* - the FORTUNE program on OZ.AI.MIT.EDU
* - the m-x yow command in GNU Emacs.
* - NIL (MIT Common Lisp)'s debugger
* - NCSA HTTPd 1.5
*/
#define MAX_YOW 537
char *yow_lines[] = { "- if it GLISTENS, gobble it!!",
"-- In 1962, you could buy a pair of SHARKSKIN SLACKS, with a ``Continental Belt,'' for $10.99!!",
"--``I love KATRINKA because she drives a PONTIAC. We're going away now. I fed the cat. - Zippy''",
"--- I have seen the FUN ---",
".. Do you like ``TENDER VITTLES?''?",
".. I don't know why but, suddenly, I want to discuss declining I.Q. LEVELS with a blue ribbon SENATE SUB-COMMITTEE!",
".. I don't understand the HUMOUR of the THREE STOOGES!!",
".. I feel.. JUGULAR..",
".. I have a VISION! It's a RANCID double-FISHWICH on an ENRICHED BUN!!",
".. I see TOILET SEATS...",
".. I think I'd better go back to my DESK and toy with a few common MISAPPREHENSIONS...",
".. I think I'll KILL myself by leaping out of this 14th STOREY WINDOW while reading ERICA JONG'S poetry!!",
".. I want FORTY-TWO TRYNEL FLOATATION SYSTEMS installed within SIX AND A HALF HOURS!!!",
".. I want a COLOR T.V. and a VIBRATING BED!!!",
".. I want to perform cranial activities with Tuesday Weld!!",
".. I wonder if I ought to tell them about my PREVIOUS LIFE as a COMPLETE STRANGER?",
".. I'm IMAGINING a sensuous GIRAFFE, CAVORTING in the BACK ROOM of a KOSHER DELI --",
".. If I had heart failure right now, I couldn't be a more fortunate man!!",
".. Like I always say -- nothing can beat the BRATWURST here in DUSSELDORF!!",
".. My pants just went on a wild rampage through a Long Island Bowling Alley!!",
".. My vaseline is RUNNING...",
".. Now I think I just reached the state of HYPERTENSION that comes JUST BEFORE you see the TOTAL at the SAFEWAY CHECKOUT COUNTER!",
".. Now KEN and BARBIE are PERMANENTLY ADDICTED to MIND-ALTERING DRUGS..",
".. Once upon a time, four AMPHIBIOUS HOG CALLERS attacked a family of DEFENSELESS, SENSITIVE COIN COLLECTORS and brought DOWN their PROPERTY VALUES!!",
".. One FISHWICH coming up!!",
".. Should I get locked in the PRINCICAL'S OFFICE today -- or have a VASECTOMY??",
".. So, if we convert SUPPLY-SIDE SOYABEAN FUTURES into HIGH-YIELD T-BILL INDICATORS, the PRE-INFLATIONARY risks will DWINDLE to a rate of 2 SHOPPING SPREES per EGGPLANT!!",
".. are the STEWED PRUNES still in the HAIR DRYER?",
".. bleakness.... desolation.... plastic forks...",
".. does your DRESSING ROOM have enough ASPARAGUS?",
".. he dominates the DECADENT SUBWAY SCENE.",
".. here I am in 53 B.C. and all I want is a dill pickle!!",
".. hubub, hubub, HUBUB, hubub, hubub, hubub, HUBUB, hubub, hubub, hubub.",
".. ich bin in einem dusenjet ins jahr 53 vor chr... ich lande im antiken Rom... einige gladiatoren spielen scrabble... ich rieche PIZZA...",
".. my NOSE is NUMB!",
".. or were you driving the PONTIAC that HONKED at me in MIAMI last Tuesday?",
".. over in west Philadelphia a puppy is vomiting..",
".. someone in DAYTON, Ohio is selling USED CARPETS to a SERBO-CROATIAN",
".. the HIGHWAY is made out of LIME JELLO and my HONDA is a barbequeued OYSTER! Yum!",
".. the MYSTERIANS are in here with my CORDUROY SOAP DISH!!",
".. this must be what it's like to be a COLLEGE GRADUATE!!",
"A can of ASPARAGUS, 73 pigeons, some LIVE ammo, and a FROZEN DAQUIRI!!",
"A dwarf is passing out somewhere in Detroit!",
"A shapely CATHOLIC SCHOOLGIRL is FIDGETING inside my costume..",
"A wide-eyed, innocent UNICORN, poised delicately in a MEADOW filled with LILACS, LOLLIPOPS & small CHILDREN at the HUSH of twilight??",
"ANN JILLIAN'S HAIR makes LONI ANDERSON'S HAIR look like RICARDO MONTALBAN'S HAIR!",
"Actually, what I'd like is a little toy spaceship!!",
"All I can think of is a platter of organic PRUNE CRISPS being trampled by an army of swarthy, Italian LOUNGE SINGERS...",
"All of a sudden, I want to THROW OVER my promising ACTING CAREER, grow a LONG BLACK BEARD and wear a BASEBALL HAT!! ... Although I don't know WHY!!",
"All of life is a blur of Republicans and meat!",
"All right, you degenerates! I want this place evacuated in 20 seconds!",
"All this time I've been VIEWING a RUSSIAN MIDGET SODOMIZE a HOUSECAT!",
"Alright, you!! Imitate a WOUNDED SEAL pleading for a PARKING SPACE!!",
"Am I SHOPLIFTING?",
"Am I accompanied by a PARENT or GUARDIAN?",
"Am I elected yet?",
"Am I in GRADUATE SCHOOL yet?",
"America!! I saw it all!! Vomiting! Waving! JERRY FALWELLING into your void tube of UHF oblivion!! SAFEWAY of the mind --",
"An INK-LING? Sure -- TAKE one!! Did you BUY any COMMUNIST UNIFORMS??",
"An Italian is COMBING his hair in suburban DES MOINES!",
"An air of FRENCH FRIES permeates my nostrils!!",
"And furthermore, my bowling average is unimpeachable!!!",
"<blockquote><i>And the beast shall come forth surrounded by a roiling <b>cloud</b> of <b>vengeance.</b>The house of the unbelievers shall be <b>razed</b> and they shall be <b>scorched</b> to the earth. Their tags shall <blink>blink</blink> until the end of <b>days.</b></i><H2>from The Book of Mozilla, 12:10</H2></blockquote>",
"Are we THERE yet?",
"Are we THERE yet? My MIND is a SUBMARINE!!",
"Are we live or on tape?",
"Are we on STRIKE yet?",
"Are you mentally here at Pizza Hut??",
"Are you selling NYLON OIL WELLS?? If so, we can use TWO DOZEN!!",
"Are you still an ALCOHOLIC?",
"As President I have to go vacuum my coin collection!",
"Awright, which one of you hid my PENIS ENVY?",
"BARBARA STANWYCK makes me nervous!!",
"BARRY.. That was the most HEART-WARMING rendition of ``I DID IT MY WAY'' I've ever heard!!",
"BELA LUGOSI is my co-pilot..",
"BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-BI-",
"Barbie says, Take quaaludes in gin and go to a disco right away! But Ken says, WOO-WOO!! No credit at ``Mr. Liquor''!!",
"Being a BALD HERO is almost as FESTIVE as a TATTOOED KNOCKWURST.",
"Bo Derek ruined my life!",
"Boy, am I glad it's only 1971...",
"Boys, you have ALL been selected to LEAVE th' PLANET in 15 minutes!!",
"But was he mature enough last night at the lesbian masquerade?",
"CHUBBY CHECKER just had a CHICKEN SANDWICH in downtown DULUTH!",
"CONGRATULATIONS! Now should I make thinly veiled comments about DIGNITY, self-esteem and finding TRUE FUN in your RIGHT VENTRICLE??",
"Can I have an IMPULSE ITEM instead?",
"Can you MAIL a BEAN CAKE?",
"Catsup and Mustard all over the place! It's the Human Hamburger!",
"Civilization is fun! Anyway, it keeps me busy!!",
"Clear the laundromat!! This whirl-o-matic just had a nuclear meltdown!!",
"Concentrate on th'cute, li'l CARTOON GUYS! Remember the SERIAL NUMBERS!! Follow the WHIPPLE AVE EXIT!! Have a FREE PEPSI!! Turn LEFT at th'HOLIDAY INN!! JOIN the CREDIT WORLD!! MAKE me an OFFER!!!",
"Content: 80% POLYESTER, 20% DACRON.. The waitress's UNIFORM sheds TARTAR SAUCE like an 8'' by 10'' GLOSSY..",
"Could I have a drug overdose?",
"DIDI... is that a MARTIAN name, or, are we in ISRAEL?",
"DON'T go!! I'm not HOWARD COSELL!! I know POLISH JOKES... WAIT!! Don't go!! I AM Howard Cosell!... And I DON'T know Polish jokes!!",
"Did I SELL OUT yet??",
"Did I do an INCORRECT THING??",
"Did I say I was a sardine? Or a bus???",
"Did YOU find a DIGITAL WATCH in YOUR box of VELVEETA?",
"Did an Italian CRANE OPERATOR just experience uninhibited sensations in a MALIBU HOT TUB?",
"Did you move a lot of KOREAN STEAK KNIVES this trip, Dingy?",
"Didn't I buy a 1951 Packard from you last March in Cairo?",
"Disco oil bussing will create a throbbing naugahide pipeline running straight to the tropics from the rug producing regions and devalue the dollar!",
"Do I have a lifestyle yet?",
"Do you guys know we just passed thru a BLACK HOLE in space?",
"Do you have exactly what I want in a plaid poindexter bar bat??",
"Do you think the ``Monkees'' should get gas on odd or even days?",
"Does someone from PEORIA have a SHORTER ATTENTION span than me?",
"Don't SANFORIZE me!!",
"Don't hit me!! I'm in the Twilight Zone!!!",
"Don't worry, nobody really LISTENS to lectures in MOSCOW, either! .. FRENCH, HISTORY, ADVANCED CALCULUS, COMPUTER PROGRAMMING, BLACK STUDIES, SOCIOBIOLOGY!.. Are there any QUESTIONS??",
"Edwin Meese made me wear CORDOVANS!!",
"Eisenhower!! Your mimeograph machine upsets my stomach!!",
"Either CONFESS now or we go to ``PEOPLE'S COURT''!!",
"Everybody gets free BORSCHT!",
"Everybody is going somewhere!! It's probably a garage sale or a disaster Movie!!",
"Everywhere I look I see NEGATIVITY and ASPHALT...",
"Excuse me, but didn't I tell you there's NO HOPE for the survival of OFFSET PRINTING?",
"FEELINGS are cascading over me!!!",
"FOOLED you! Absorb EGO SHATTERING impulse rays, polyester poltroon!!",
"FROZEN ENTREES may be flung by members of opposing SWANSON SECTS..",
"FUN is never having to say you're SUSHI!!",
"Finally, Zippy drives his 1958 RAMBLER METROPOLITAN into the faculty dining room.",
"First, I'm going to give you all the ANSWERS to today's test.. So just plug in your SONY WALKMANS and relax!!",
"Four thousand different MAGNATES, MOGULS & NABOBS are romping in my gothic solarium!!",
"GOOD-NIGHT, everybody.. Now I have to go administer FIRST-AID to my pet LEISURE SUIT!!",
"Gee, I feel kind of LIGHT in the head now, knowing I can't make my satellite dish PAYMENTS!",
"Gibble, Gobble, we ACCEPT YOU ---",
"Give them RADAR-GUIDED SKEE-BALL LANES and VELVEETA BURRITOS!!",
"Go on, EMOTE! I was RAISED on thought balloons!!",
"HAIR TONICS, please!!",
"HELLO KITTY gang terrorizes town, family STICKERED to death!",
"HELLO, everybody, I'm a HUMAN!!",
"HOORAY, Ronald!! Now YOU can marry LINDA RONSTADT too!!",
"HUGH BEAUMONT died in 1982!!",
"HUMAN REPLICAS are inserted into VATS of NUTRITIONAL YEAST...",
"Half a mind is a terrible thing to waste!",
"Hand me a pair of leather pants and a CASIO keyboard -- I'm living for today!",
"Has everybody got HALVAH spread all over their ANKLES??... Now, it's time to ``HAVE A NAGEELA''!!",
"He is the MELBA-BEING... the ANGEL CAKE... XEROX him... XEROX him --",
"He probably just wants to take over my CELLS and then EXPLODE inside me like a BARREL of runny CHOPPED LIVER! Or maybe he'd like to PSYCHOLIGICALLY TERRORISE ME until I have no objection to a RIGHT-WING MILITARY TAKEOVER of my apartment!! I guess I should call AL PACINO!",
"Hello, GORRY-O!! I'm a GENIUS from HARVARD!!",
"Hello. I know the divorce rate among unmarried Catholic Alaskan females!!",
"Hello. Just walk along and try NOT to think about your INTESTINES being almost FORTY YARDS LONG!!",
"Hello... IRON CURTAIN? Send over a SAUSAGE PIZZA! World War III? No thanks!",
"Hello? Enema Bondage? I'm calling because I want to be happy, I guess..",
"Here I am at the flea market but nobody is buying my urine sample bottles..",
"Here I am in the POSTERIOR OLFACTORY LOBULE but I don't see CARL SAGAN anywhere!!",
"Here we are in America... when do we collect unemployment?",
"Hey, wait a minute!! I want a divorce!!.. you're not Clint Eastwood!!",
"Hey, waiter! I want a NEW SHIRT and a PONY TAIL with lemon sauce!",
"Hiccuping & trembling into the WASTE DUMPS of New Jersey like some drunken CABBAGE PATCH DOLL, coughing in line at FIORUCCI'S!!",
"Hmmm.. A hash-singer and a cross-eyed guy were SLEEPING on a deserted island, when...",
"Hmmm.. a CRIPPLED ACCOUNTANT with a FALAFEL sandwich is HIT by a TROLLEY-CAR..",
"Hmmm... a PINHEAD, during an EARTHQUAKE, encounters an ALL-MIDGET FIDDLE ORCHESTRA... ha.. ha..",
"Hmmm... an arrogant bouquet with a subtle suggestion of POLYVINYL CHLORIDE...",
"Hold the MAYO & pass the COSMIC AWARENESS...",
"How do I get HOME?",
"How do you explain Wayne Newton's POWER over millions? It's th' MOUSTACHE... Have you ever noticed th' way it radiates SINCERITY, HONESTY & WARMTH? It's a MOUSTACHE you want to take HOME and introduce to NANCY SINATRA!",
"How many retured bricklayers from FLORIDA are out purchasing PENCIL SHARPENERS right NOW??",
"How's it going in those MODULAR LOVE UNITS??",
"How's the wife? Is she at home enjoying capitalism?",
"I HAVE to buy a new ``DODGE MISER'' and two dozen JORDACHE JEANS because my viewscreen is ``USER-FRIENDLY''!!",
"I KAISER ROLL?! What good is a Kaiser Roll without a little COLE SLAW on the SIDE?",
"I Know A Joke",
"I always have fun because I'm out of my mind!!!",
"I am NOT a nut....",
"I am a jelly donut. I am a jelly donut.",
"I am a traffic light, and Alan Ginzberg kidnapped my laundry in 1927!",
"I am covered with pure vegetable oil and I am writing a best seller!",
"I am deeply CONCERNED and I want something GOOD for BREAKFAST!",
"I am having FUN... I wonder if it's NET FUN or GROSS FUN?",
"I appoint you ambassador to Fantasy Island!!!",
"I brought my BOWLING BALL - and some DRUGS!!",
"I can't decide which WRONG TURN to make first!! I wonder if BOB GUCCIONE has these problems!",
"I can't think about that. It doesn't go with HEDGES in the shape of LITTLE LULU -- or ROBOTS making BRICKS...",
"I demand IMPUNITY!",
"I didn't order any WOO-WOO... Maybe a YUBBA.. But no WOO-WOO!",
"I don't believe there really IS a GAS SHORTAGE.. I think it's all just a BIG HOAX on the part of the plastic sign salesmen-- .. to sell more numbers!!",
"I don't know WHY I said that.. I think it came from the FILLINGS in my rear molars..",
"I feel better about world problems now!",
"I feel like I am sharing a ``CORN-DOG'' with NIKITA KHRUSCHEV..",
"I feel like I'm in a Toilet Bowl with a thumbtack in my forehead!!",
"I feel like a wet parking meter on Darvon!",
"I feel partially hydrogenated!",
"I fill MY industrial waste containers with old copies of the ``WATCHTOWER'' and then add HAWAIIAN PUNCH to the top.. They look NICE in the yard--",
"I guess it was all a DREAM.. or an episode of HAWAII FIVE-O...",
"I guess you guys got BIG MUSCLES from doing too much STUDYING!",
"I had a lease on an OEDIPUS COMPLEX back in '81...",
"I had pancake makeup for brunch!",
"I have a TINY BOWL in my HEAD",
"I have a very good DENTAL PLAN. Thank you.",
"I have accepted Provolone into my life!",
"I have many CHARTS and DIAGRAMS..",
"I have seen these EGG EXTENDERS in my Supermarket.. .. I have read the INSTRUCTIONS...",
"I have the power to HALT PRODUCTION on all TEENAGE SEX COMEDIES!!",
"I haven't been married in over six years, but we had sexual counseling every day from Oral Roberts!!",
"I hope I bought the right relish... zzzzzzzzz...",
"I hope something GOOD came in the mail today so I have a REASON to live!!",
"I hope the ``Eurythmics'' practice birth control...",
"I hope you millionaires are having fun! I just invested half your life savings in yeast!!",
"I invented skydiving in 1989!",
"I joined scientology at a garage sale!!",
"I just forgot my whole philosophy of life!!!",
"I just got my PRINCE bumper sticker.. But now I can't remember WHO he is...",
"I just had a NOSE JOB!!",
"I just had my entire INTESTINAL TRACT coated with TEFLON!",
"I just heard the SEVENTIES were over!! And I was just getting in touch with my LEISURE SUIT!!",
"I just remembered something about a TOAD!",
"I know how to do SPECIAL EFFECTS!!",
"I know th'MAMBO!! I have a TWO-TONE CHEMISTRY SET!!",
"I know things about TROY DONAHUE that can't even be PRINTED!!",
"I left my WALLET in the BATHROOM!!",
"I like the way ONLY their mouths move.. They look like DYING OYSTERS",
"I like your SNOOPY POSTER!!",
"I love ROCK 'N ROLL! I memorized the all WORDS to ``WIPE-OUT'' in 1965!!",
"I need to discuss BUY-BACK PROVISIONS with at least six studio SLEAZEBALLS!!",
"I once decorated my apartment entirely in ten foot salad forks!!",
"I own seven-eighths of all the artists in downtown Burbank!",
"I put aside my copy of ``BOWLING WORLD'' and think about GUN CONTROL legislation..",
"I represent a sardine!!",
"I request a weekend in Havana with Phil Silvers!",
"I selected E5... but I didn't hear ``Sam the Sham and the Pharoahs''!",
"I smell a RANCID CORN DOG!",
"I smell like a wet reducing clinic on Columbus Day!",
"I think I am an overnight sensation right now!!",
"I think my career is ruined!",
"I used to be a FUNDAMENTALIST, but then I heard about the HIGH RADIATION LEVELS and bought an ENCYCLOPEDIA!!",
"I want EARS! I want two ROUND BLACK EARS to make me feel warm 'n secure!!",
"I want a VEGETARIAN BURRITO to go.. with EXTRA MSG!!",
"I want a WESSON OIL lease!!",
"I want another RE-WRITE on my CEASAR SALAD!!",
"I want the presidency so bad I can already taste the hors d'oeuvres.",
"I want to dress you up as TALLULAH BANKHEAD and cover you with VASELINE and WHEAT THINS..",
"I want to kill everyone here with a cute colorful Hydrogen Bomb!!",
"I want to read my new poem about pork brains and outer space...",
"I want to so HAPPY, the VEINS in my neck STAND OUT!!",
"I want you to MEMORIZE the collected poems of EDNA ST VINCENT MILLAY.. BACKWARDS!!",
"I want you to organize my PASTRY trays... my TEA-TINS are gleaming in formation like a ROW of DRUM MAJORETTES -- please don't be FURIOUS with me --",
"I was born in a Hostess Cupcake factory before the sexual revolution!",
"I was making donuts and now I'm on a bus!",
"I wish I was a sex-starved manicurist found dead in the Bronx!!",
"I wish I was on a Cincinnati street corner holding a clean dog!",
"I wonder if I could ever get started in the credit world?",
"I wonder if I should put myself in ESCROW!!",
"I wonder if there's anything GOOD on tonight?",
"I would like to urinate in an OVULAR, porcelain pool --",
"I'd like MY data-base JULIENNED and stir-fried!",
"I'd like some JUNK FOOD... and then I want to be ALONE --",
"I'll eat ANYTHING that's BRIGHT BLUE!!",
"I'll show you MY telex number if you show me YOURS...",
"I'm ANN LANDERS!! I can SHOPLIFT!!",
"I'm DESPONDENT... I hope there's something DEEP-FRIED under this miniature DOMED STADIUM...",
"I'm EMOTIONAL now because I have MERCHANDISING CLOUT!!",
"I'm GLAD I remembered to XEROX all my UNDERSHIRTS!!",
"I'm QUIETLY reading the latest issue of ``BOWLING WORLD'' while my wife and two children stand QUIETLY BY..",
"I'm RELIGIOUS!! I love a man with a HAIRPIECE!! Equip me with MISSILES!!",
"I'm ZIPPY the PINHEAD and I'm totally committed to the festive mode.",
"I'm a GENIUS! I want to dispute sentence structure with SUSAN SONTAG!!",
"I'm a fuschia bowling ball somewhere in Brittany",
"I'm a nuclear submarine under the polar ice cap and I need a Kleenex!",
"I'm also against BODY-SURFING!!",
"I'm also pre-POURED pre-MEDITATED and pre-RAPHAELITE!!",
"I'm changing the CHANNEL.. But all I get is commercials for ``RONCO MIRACLE BAMBOO STEAMERS''!",
"I'm continually AMAZED at th'breathtaking effects of WIND EROSION!!",
"I'm definitely not in Omaha!",
"I'm dressing up in an ill-fitting IVY-LEAGUE SUIT!! Too late...",
"I'm encased in the lining of a pure pork sausage!!",
"I'm gliding over a NUCLEAR WASTE DUMP near ATLANTA, Georgia!!",
"I'm having BEAUTIFUL THOUGHTS about the INSIPID WIVES of smug and wealthy CORPORATE LAWYERS..",
"I'm having a BIG BANG THEORY!!",
"I'm having a MID-WEEK CRISIS!",
"I'm having a RELIGIOUS EXPERIENCE.. and I don't take any DRUGS",
"I'm having a tax-deductible experience! I need an energy crunch!!",
"I'm having an EMOTIONAL OUTBURST!! But, uh, WHY is there a WAFFLE in my PAJAMA POCKET??",
"I'm having an emotional outburst!!",
"I'm having fun HITCHHIKING to CINCINNATI or FAR ROCKAWAY!!",
"I'm in direct contact with many advanced fun CONCEPTS.",
"I'm into SOFTWARE!",
"I'm meditating on the FORMALDEHYDE and the ASBESTOS leaking into my PERSONAL SPACE!!",
"I'm mentally OVERDRAWN! What's that SIGNPOST up ahead? Where's ROD STERLING when you really need him?",
"I'm not an Iranian!! I voted for Dianne Feinstein!!",
"I'm not available for comment..",
"I'm pretending I'm pulling in a TROUT! Am I doing it correctly??",
"I'm pretending that we're all watching PHIL SILVERS instead of RICARDO MONTALBAN!",
"I'm rated PG-34!!",
"I'm receiving a coded message from EUBIE BLAKE!!",
"I'm reporting for duty as a modern person. I want to do the Latin Hustle now!",
"I'm shaving!! I'M SHAVING!!",
"I'm sitting on my SPEED QUEEN.. To me, it's ENJOYABLE.. I'm WARM.. I'm VIBRATORY..",
"I'm thinking about DIGITAL READ-OUT systems and computer-generated IMAGE FORMATIONS..",
"I'm totally DESPONDENT over the LIBYAN situation and the price of CHICKEN..",
"I'm using my X-RAY VISION to obtain a rare glimpse of the INNER WORKINGS of this POTATO!!",
"I'm wearing PAMPERS!!",
"I'm wet! I'm wild!",
"I'm young.. I'm HEALTHY.. I can HIKE THRU CAPT GROGAN'S LUMBAR REGIONS!",
"I've got a COUSIN who works in the GARMENT DISTRICT...",
"I've got an IDEA!! Why don't I STARE at you so HARD, you forget your SOCIAL SECURITY NUMBER!!",
"I've read SEVEN MILLION books!!",
"INSIDE, I have the same personality disorder as LUCY RICARDO!!",
"If I am elected no one will ever have to do their laundry again!",
"If I am elected, the concrete barriers around the WHITE HOUSE will be replaced by tasteful foam replicas of ANN MARGARET!",
"If I felt any more SOPHISTICATED I would DIE of EMBARRASSMENT!",
"If I had a Q-TIP, I could prevent th'collapse of NEGOTIATIONS!!",
"If I pull this SWITCH I'll be RITA HAYWORTH!! Or a SCIENTOLOGIST!",
"If Robert Di Niro assassinates Walter Slezak, will Jodie Foster marry Bonzo??",
"If a person is FAMOUS in this country, they have to go on the ROAD for MONTHS at a time and have their name misspelled on the SIDE of a GREYHOUND SCENICRUISER!!",
"If elected, Zippy pledges to each and every American a 55-year-old houseboy...",
"If our behavior is strict, we do not need fun!",
"In Newark the laundromats are open 24 hours a day!",
"Inside, I'm already SOBBING!",
"Is a tattoo real, like a curb or a battleship? Or are we suffering in Safeway?",
"Is it 1974? What's for SUPPER? Can I spend my COLLEGE FUND in one wild afternoon??",
"Is it NOUVELLE CUISINE when 3 olives are struggling with a scallop in a plate of SAUCE MORNAY?",
"Is it clean in other dimensions?",
"Is something VIOLENT going to happen to a GARBAGE CAN?",
"Is this TERMINAL fun?",
"Is this an out-take from the ``BRADY BUNCH''?",
"Is this going to involve RAW human ecstasy?",
"Is this the line for the latest whimsical YUGOSLAVIAN drama which also makes you want to CRY and reconsider the VIETNAM WAR?",
"Isn't this my STOP?!",
"It don't mean a THING if you ain't got that SWING!!",
"It was a JOKE!! Get it?? I was receiving messages from DAVID LETTERMAN!! YOW!!",
"It's NO USE.. I've gone to ``CLUB MED''!!",
"It's OBVIOUS.. The FURS never reached ISTANBUL.. You were an EXTRA in the REMAKE of ``TOPKAPI''.. Go home to your WIFE.. She's making FRENCH TOAST!",
"It's OKAY --- I'm an INTELLECTUAL, too.",
"It's a lot of fun being alive... I wonder if my bed is made?!?",
"It's the RINSE CYCLE!! They've ALL IGNORED the RINSE CYCLE!!",
"JAPAN is a WONDERFUL planet -- I wonder if we'll ever reach their level of COMPARATIVE SHOPPING...",
"Jesus is my POSTMASTER GENERAL..",
"Kids, don't gross me off.. ``Adventures with MENTAL HYGIENE'' can be carried too FAR!",
"Kids, the seven basic food groups are GUM, PUFF PASTRY, PIZZA, PESTICIDES, ANTIBIOTICS, NUTRA-SWEET and MILK DUDS!!",
"LBJ, LBJ, how many JOKES did you tell today??!",
"LOOK!! Sullen American teens wearing MADRAS shorts and ``Flock of Seagulls'' HAIRCUTS!",
"Laundry is the fifth dimension!! ...um...um... th' washing machine is a black hole and the pink socks are bus drivers who just fell in!!",
"Leona, I want to CONFESS things to you.. I want to WRAP you in a SCARLET ROBE trimmed with POLYVINYL CHLORIDE.. I want to EMPTY your ASHTRAYS...",
"Let me do my TRIBUTE to FISHNET STOCKINGS...",
"Let's all show human CONCERN for REVERAND MOON's legal difficulties!!",
"Let's send the Russians defective lifestyle accessories!",
"Life is a POPULARITY CONTEST! I'm REFRESHINGLY CANDID!!",
"Loni Anderson's hair should be LEGALIZED!!",
"Look DEEP into the OPENINGS!! Do you see any ELVES or EDSELS... or a HIGHBALL??...",
"Look into my eyes and try to forget that you have a Macy's charge card!",
"Look! A ladder! Maybe it leads to heaven, or a sandwich!",
"MERYL STREEP is my obstetrician!",
"MMM-MM!! So THIS is BIO-NEBULATION!",
"MY income is ALL disposable!",
"Make me look like LINDA RONSTADT again!!",
"Mary Tyler Moore's SEVENTH HUSBAND is wearing my DACRON TANK TOP in a cheap hotel in HONOLULU!",
"Maybe we could paint GOLDIE HAWN a rich PRUSSIAN BLUE--",
"Mmmmmm-MMMMMM!! A plate of STEAMING PIECES of a PIG mixed with the shreds of SEVERAL CHICKENS!!... Oh BOY!! I'm about to swallow a TORN-OFF section of a COW'S LEFT LEG soaked in COTTONSEED OIL and SUGAR!! .. Let's see.. Next, I'll have the GROUND-UP flesh of CUTE, BABY LAMBS fried in the MELTED, FATTY TISSUES from a warm-blooded animal someone once PETTED!! ... YUM!! That was GOOD!! For DESSERT, I'll have a TOFU BURGER with BEAN SPROUTS on a stone-ground, WHOLE WHEAT BUN!!",
"Mozilla is sipping Java with Barney!!",
"Mr and Mrs PED, can I borrow 26.7% of the RAYON TEXTILE production of the INDONESIAN archipelago?",
"My Aunt MAUREEN was a military advisor to IKE & TINA TURNER!!",
"My BIOLOGICAL ALARM CLOCK just went off.. It has noiseless DOZE FUNCTION and full kitchen!!",
"My CODE of ETHICS is vacationing at famed SCHROON LAKE in upstate New York!!",
"My EARS are GONE!!",
"My LESLIE GORE record is BROKEN..",
"My face is new, my license is expired, and I'm under a doctor's care!!!!",
"My haircut is totally traditional!",
"My life is a patio of fun!",
"My mind is a potato field...",
"My mind is making ashtrays in Dayton....",
"My nose feels like a bad Ronald Reagan movie...",
"My pants just went to high school in the Carlsbad Caverns!!!",
"My polyvinyl cowboy wallet was made in Hong Kong by Montgomery Clift!",
"My uncle Murray conquered Egypt in 53 B.C. And I can prove it too!!",
"NANCY!! Why is everything RED?!",
"NATHAN... your PARENTS were in a CARCRASH!! They're VOIDED - They COLLAPSED They had no CHAINSAWS... They had no MONEY MACHINES... They did PILLS in SKIMPY GRASS SKIRTS... Nathan, I EMULATED them... but they were OFF-KEY...",
"NEWARK has been REZONED!! DES MOINES has been REZONED!!",
"Not SENSUOUS... only ``FROLICSOME''... and in need of DENTAL WORK... in PAIN!!!",
"Now I am depressed...",
"Now I understand the meaning of ``THE MOD SQUAD''!",
"Now I'm being INVOLUNTARILY shuffled closer to the CLAM DIP with the BROKEN PLASTIC FORKS in it!!",
"Now I'm concentrating on a specific tank battle toward the end of World War II!",
"Now I'm having INSIPID THOUGHTS about the beatiful, round wives of HOLLYWOOD MOVIE MOGULS encased in PLEXIGLASS CARS and being approached by SMALL BOYS selling FRUIT..",
"Now my EMOTIONAL RESOURCES are heavily committed to 23% of the SMELTING and REFINING industry of the state of NEVADA!!",
"Now that I have my ``APPLE,'' I comprehend COST ACCOUNTING!!",
"Now, I think it would be GOOD to buy FIVE or SIX STUDEBAKERS and CRUISE for ARTIFICIAL FLAVORING!!",
"Now, let's SEND OUT for QUICHE!!",
"OKAY!! Turn on the sound ONLY for TRYNEL CARPETING, FULLY-EQUIPPED R.V.'S and FLOATATION SYSTEMS!!",
"OMNIVERSAL AWARENESS?? Oh, YEH!! First you need 4 GALLONS of JELL-O and a BIG WRENCH!!... I think you drop th'WRENCH in the JELL-O as if it was a FLAVOR, or an INGREDIENT... ...or...I...um... WHERE'S the WASHING MACHINES?",
"ONE: I will donate my entire ``BABY HUEY'' comic book collection to the downtown PLASMA CENTER.. TWO: I won't START a BAND called ``KHADAFY & THE HIT SQUAD''.. THREE: I won't ever TUMBLE DRY my FOX TERRIER again!!",
"OVER the underpass! UNDER the overpass! Around the FUTURE and BEYOND REPAIR!!",
"Of course, you UNDERSTAND about the PLAIDS in the SPIN CYCLE --",
"Oh my GOD -- the SUN just fell into YANKEE STADIUM!!",
"Oh, I get it!! ``The BEACH goes on,'' huh, SONNY??",
"Okay.. I'm going home to write the ``I HATE RUBIK's CUBE HANDBOOK FOR DEAD CAT LOVERS''..",
"On SECOND thought, maybe I'll heat up some BAKED BEANS and watch REGIS PHILBIN.. It's GREAT to be ALIVE!!",
"On the other hand, life can be an endless parade of TRANSSEXUAL QUILTING BEES aboard a cruise ship to DISNEYWORLD if only we let it!!",
"On the road, ZIPPY is a pinhead without a purpose, but never without a POINT.",
"Once, there was NO fun... This was before MENU planning, FASHION statements or NAUTILUS equipment... Then, in 1985.. FUN was completely encoded in this tiny MICROCHIP.. It contain 14,768 vaguely amusing SIT-COM pilots!! We had to wait FOUR BILLION years but we finally got JERRY LEWIS, MTV and a large selection of creme-filled snack cakes!",
"Our father who art in heaven.. I sincerely pray that SOMEBODY at this table will PAY for my SHREDDED WHAT and ENGLISH MUFFIN.. and also leave a GENEROUS TIP...",
"PARDON me, am I speaking ENGLISH?",
"PEGGY FLEMMING is stealing BASKET BALLS to feed the babies in VERMONT.",
"PIZZA!!",
"PUNK ROCK!! DISCO DUCK!! BIRTH CONTROL!!",
"Pardon me, but do you know what it means to be TRULY ONE with your BOOTH!",
"Place me on a BUFFER counter while you BELITTLE several BELLHOPS in the Trianon Room!! Let me one of your SUBSIDIARIES!",
"Please come home with me... I have Tylenol!!",
"Psychoanalysis?? I thought this was a nude rap session!!!",
"Quick, sing me the BUDAPEST NATIONAL ANTHEM!!",
"RELATIVES!!",
"RHAPSODY in Glue!",
"Remember, in 2039, MOUSSE & PASTA will be available ONLY by prescription!!",
"SANTA CLAUS comes down a FIRE ESCAPE wearing bright blue LEG WARMERS.. He scrubs the POPE with a mild soap or detergent for 15 minutes, starring JANE FONDA!!",
"SHHHH!! I hear SIX TATTOOED TRUCK-DRIVERS tossing ENGINE BLOCKS into empty OIL DRUMS..",
"Send your questions to ``ASK ZIPPY'', Box 40474, San Francisco, CA 94140, USA",
"Should I do my BOBBIE VINTON medley?",
"Should I start with the time I SWITCHED personalities with a BEATNIK hair stylist or my failure to refer five TEENAGERS to a good OCULIST?",
"Sign my PETITION.",
"So this is what it feels like to be potato salad",
"Sometime in 1993 NANCY SINATRA will lead a BLOODLESS COUP on GUAM!!",
"Somewhere in DOWNTOWN BURBANK a prostitute is OVERCOOKING a LAMB CHOP!!",
"Somewhere in Tenafly, New Jersey, a chiropractor is viewing ``Leave it to Beaver''!",
"Somewhere in suburban Honolulu, an unemployed bellhop is whipping up a batch of illegal psilocybin chop suey!!",
"Spreading peanut butter reminds me of opera!! I wonder why?",
"TAILFINS!! ...click...",
"TAPPING? You POLITICIANS! Don't you realize that the END of the ``Wash Cycle'' is a TREASURED MOMENT for most people?!",
"TONY RANDALL! Is YOUR life a PATIO of FUN??",
"Talking Pinhead Blues: Oh, I LOST my ``HELLO KITTY'' DOLL and I get BAD reception on channel TWENTY-SIX!! Th'HOSTESS FACTORY is closin' down and I just heard ZASU PITTS has been DEAD for YEARS.. (sniff) My PLATFORM SHOE collection was CHEWED up by th'dog, ALEXANDER HAIG won't let me take a SHOWER 'til Easter.. (snurf) So I went to the kitchen, but WALNUT PANELING whup me upside mah HAID!! (on no, no, no.. Heh, heh)",
"Tex SEX! The HOME of WHEELS! The dripping of COFFEE!! Take me to Minnesota but don't EMBARRASS me!!",
"Th' MIND is the Pizza Palace of th' SOUL",
"Thank god!!.. It's HENNY YOUNGMAN!!",
"The FALAFEL SANDWICH lands on my HEAD and I become a VEGETARIAN...",
"The Korean War must have been fun.",
"The Osmonds! You are all Osmonds!! Throwing up on a freeway at dawn!!!",
"The PILLSBURY DOUGHBOY is CRYING for an END to BURT REYNOLDS movies!!",
"The PINK SOCKS were ORIGINALLY from 1952!! But they went to MARS around 1953!!",
"The SAME WAVE keeps coming in and COLLAPSING like a rayon MUU-MUU..",
"The appreciation of the average visual graphisticator alone is worth the whole suaveness and decadence which abounds!!",
"The entire CHINESE WOMEN'S VOLLEYBALL TEAM all share ONE personality -- and have since BIRTH!!",
"The fact that 47 PEOPLE are yelling and sweat is cascading down my SPINAL COLUMN is fairly enjoyable!!",
"There's a little picture of ED MCMAHON doing BAD THINGS to JOAN RIVERS in a $200,000 MALIBU BEACH HOUSE!!",
"There's enough money here to buy 5000 cans of Noodle-Roni!",
"These PRESERVES should be FORCE-FED to PENTAGON OFFICIALS!!",
"They collapsed.... like nuns in the street... they had no teen appeal!",
"This ASEXUAL PIG really BOILS my BLOOD... He's so..so.....URGENT!!",
"This MUST be a good party -- My RIB CAGE is being painfully pressed up against someone's MARTINI!!",
"This PIZZA symbolizes my COMPLETE EMOTIONAL RECOVERY!!",
"This PORCUPINE knows his ZIPCODE.. And he has ``VISA''!!",
"This TOPS OFF my partygoing experience! Someone I DON'T LIKE is talking to me about a HEART-WARMING European film..",
"This is a NO-FRILLS flight -- hold th' CANADIAN BACON!!",
"Those aren't WINOS--that's my JUGGLER, my AERIALIST, my SWORD SWALLOWER, and my LATEX NOVELTY SUPPLIER!!",
"Thousands of days of civilians ... have produced a... feeling for the aesthetic modules --",
"Today, THREE WINOS from DETROIT sold me a framed photo of TAB HUNTER before his MAKEOVER!",
"Toes, knees, NIPPLES. Toes, knees, nipples, KNUCKLES... Nipples, dimples, knuckles, NICKLES, wrinkles, pimples!! I don't like FRANK SINATRA or his CHILDREN.",
"UH-OH!! I put on ``GREAT HEAD-ON TRAIN COLLISIONS of the 50's'' by mistake!!!",
"UH-OH!! I think KEN is OVER-DUE on his R.V. PAYMENTS and HE'S having a NERVOUS BREAKDOWN too!! Ha ha.",
"UH-OH!! We're out of AUTOMOBILE PARTS and RUBBER GOODS!",
"Uh-oh -- WHY am I suddenly thinking of a VENERABLE religious leader frolicking on a FORT LAUDERDALE weekend?",
"Uh-oh!! I forgot to submit to COMPULSORY URINALYSIS!",
"Uh-oh!! I'm having TOO MUCH FUN!!",
"Used staples are good with SOY SAUCE!",
"Vote for ME -- I'm well-tapered, half-cocked, ill-conceived and TAX-DEFERRED!",
"WHO sees a BEACH BUNNY sobbing on a SHAG RUG?!",
"WHOA!! Ken and Barbie are having TOO MUCH FUN!! It must be the NEGATIVE IONS!!",
"Wait.. is this a FUN THING or the END of LIFE in Petticoat Junction??",
"Was my SOY LOAF left out in th'RAIN? It tastes REAL GOOD!!",
"We are now enjoying total mutual interaction in an imaginary hot tub...",
"We have DIFFERENT amounts of HAIR --",
"We just joined the civil hair patrol!",
"We place two copies of PEOPLE magazine in a DARK, HUMID mobile home. 45 minutes later CYNDI LAUPER emerges wearing a BIRD CAGE on her head!",
"Well, I'm INVISIBLE AGAIN.. I might as well pay a visit to the LADIES ROOM...",
"Well, I'm a classic ANAL RETENTIVE!! And I'm looking for a way to VICARIOUSLY experience some reason to LIVE!!",
"Well, O.K. I'll compromise with my principles because of EXISTENTIAL DESPAIR!",
"Well, here I am in AMERICA.. I LIKE it. I HATE it. I LIKE it. I HATE it. I LIKE it. I HATE it. I LIKE it.I HATE it. I LIKE.. EMOTIONS are SWEEPING over me!!",
"Were these parsnips CORRECTLY MARINATED in TACO SAUCE?",
"What GOOD is a CARDBOARD suitcase ANYWAY?",
"What I need is a MATURE RELATIONSHIP with a FLOPPY DISK...",
"What I want to find out is -- do parrots know much about Astro-Turf?",
"What PROGRAM are they watching?",
"What UNIVERSE is this, please??",
"What a COINCIDENCE! I'm an authorized ``SNOOTS OF THE STARS'' dealer!!",
"What's the MATTER Sid?.. Is your BEVERAGE unsatisfactory?",
"When I met th'POPE back in '58, I scrubbed him with a MILD SOAP or DETERGENT for 15 minutes. He seemed to enjoy it..",
"When this load is DONE I think I'll wash it AGAIN..",
"When you get your PH.D. will you get able to work at BURGER KING?",
"When you said ``HEAVILY FORESTED'' it reminded me of an overdue CLEANING BILL.. Don't you SEE? O'Grogan SWALLOWED a VALUABLE COIN COLLECTION and HAD to murder the ONLY MAN who KNEW!!",
"Where do your SOCKS go when you lose them in th' WASHER?",
"Where does it go when you flush?",
"Where's SANDY DUNCAN?",
"Where's th' DAFFY DUCK EXHIBIT??",
"Where's the Coke machine? Tell me a joke!!",
"While my BRAINPAN is being refused service in BURGER KING, Jesuit priests are DATING CAREER DIPLOMATS!!",
"While you're chewing, think of STEVEN SPIELBERG'S bank account.. This will have the same effect as two ``STARCH BLOCKERS''!",
"Why are these athletic shoe salesmen following me??",
"Why don't you ever enter and CONTESTS, Marvin?? Don't you know your own ZIPCODE?",
"Why is everything made of Lycra Spandex?",
"Why is it that when you DIE, you can't take your HOME ENTERTAINMENT CENTER with you??",
"Will it improve my CASH FLOW?",
"Will the third world war keep ``Bosom Buddies'' off the air?",
"Will this never-ending series of PLEASURABLE EVENTS never cease?",
"With YOU, I can be MYSELF.. We don't NEED Dan Rather..",
"World War Three can be averted by adherence to a strictly enforced dress code!",
"Wow! Look!! A stray meatball!! Let's interview it!",
"Xerox your lunch and file it under ``sex offenders!''",
"YOU PICKED KARL MALDEN'S NOSE!!",
"YOU!! Give me the CUTEST, PINKEST, most charming little VICTORIAN DOLLHOUSE you can find!! An make it SNAPPY!!",
"YOW!! Everybody out of the GENETIC POOL!",
"YOW!! I'm in a very clever and adorable INSANE ASYLUM!!",
"YOW!! Now I understand advanced MICROBIOLOGY and th' new TAX REFORM laws!!",
"YOW!! The land of the rising SONY!!",
"YOW!! Up ahead! It's a DONUT HUT!!",
"YOW!! What should the entire human race DO?? Consume a fifth of CHIVAS REGAL, ski NUDE down MT. EVEREST, and have a wild SEX WEEKEND!",
"YOW!!! I am having fun!!!",
"Yes, but will I see the EASTER BUNNY in skintight leather at an IRON MAIDEN concert?",
"You can't hurt me!! I have an ASSUMABLE MORTGAGE!!",
"You mean now I can SHOOT YOU in the back and further BLUR th' distinction between FANTASY and REALITY?",
"You mean you don't want to watch WRESTLING from ATLANTA?",
"You should all JUMP UP AND DOWN for TWO HOURS while I decide on a NEW CAREER!!",
"You were s'posed to laugh!",
"Your CHEEKS sit like twin NECTARINES above a MOUTH that knows no BOUNDS --",
"Youth of today! Join me in a mass rally for traditional mental attitudes!",
"Yow!",
"Yow! Am I having fun yet?",
"Yow! Am I in Milwaukee?",
"Yow! And then we could sit on the hoods of cars at stop lights!",
"Yow! Are we laid back yet?",
"Yow! Are we wet yet?",
"Yow! Are you the self-frying president?",
"Yow! Did something bad happen or am I in a drive-in movie??",
"Yow! I just went below the poverty line!",
"Yow! I threw up on my window!",
"Yow! I want my nose in lights!",
"Yow! I want to mail a bronzed artichoke to Nicaragua!",
"Yow! I'm having a quadrophonic sensation of two winos alone in a steel mill!",
"Yow! I'm imagining a surfer van filled with soy sauce!",
"Yow! Is my fallout shelter termite proof?",
"Yow! Is this sexual intercourse yet?? Is it, huh, is it??",
"Yow! It's a hole all the way to downtown Burbank!",
"Yow! It's some people inside the wall! This is better than mopping!",
"Yow! Maybe I should have asked for my Neutron Bomb in PAISLEY--",
"Yow! Now I get to think about all the BAD THINGS I did to a BOWLING BALL when I was in JUNIOR HIGH SCHOOL!",
"Yow! Now we can become alcoholics!",
"Yow! Those people look exactly like Donnie and Marie Osmond!!",
"Yow! We're going to a new disco!",
"Zippy's brain cells are straining to bridge synapses...",
};

374
src/imagemap.c Normal file
View File

@ -0,0 +1,374 @@
/************************************************************************
* 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
*
************************************************************************
*
* $Id: imagemap.c,v 1.16 1996/04/05 21:14:15 blong Exp $
*
************************************************************************
*
* imagemap.c: Contains all of the code for the internal imagemap
*
*/
#include "config.h"
#include "portability.h"
#include <stdio.h>
#include <string.h>
#ifndef NO_STDLIB_H
#include <stdlib.h>
#endif /* NO_STDLIB_H */
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include "constants.h"
#include "fdwrap.h"
#include "allocate.h"
#include "http_log.h"
#include "http_config.h"
#include "http_request.h"
#include "imagemap.h"
#include "cgi.h"
#ifdef IMAGEMAP_SUPPORT
/* Error messages for imagemaps */
#define IMAP_ERR_INCORRECT_ARGS 1
#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, *def, *szPoint, *url, *type;
double testpoint[2], pointarray[MAXVERTS][2];
int i, j, k;
int error_num = 0;
FILE *fp;
char *t;
double dist, mindist = -1;
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';
strcpy(szPoint, reqInfo->args);
if(!(t = strchr(szPoint,','))) {
error_num = IMAP_ERR_INCORRECT_ARGS;
goto imagemap_error;
}
*t++ = '\0';
testpoint[X] = (double) atoi(szPoint);
testpoint[Y] = (double) atoi(t);
if(!(fp=FOpen(reqInfo->filename,"r"))){
log_reason(reqInfo, "File permissions deny server access",
reqInfo->filename);
freeString(input);
freeString(def);
freeString(szPoint);
freeString(url);
freeString(type);
die(reqInfo, SC_FORBIDDEN, reqInfo->url);
}
while (!Found && fgets(input,HUGE_STRING_LEN,fp)) {
char num[10];
/* Skip lines with # as comments and blank lines */
if((input[0] == '#') || (!input[0]))
continue;
type[0] = '\0';url[0] = '\0';
/* Copy the shape keyword into type */
for(i=0;!isspace(input[i]) && (input[i]);i++)
type[i] = input[i];
type[i] = '\0';
/* Forward to next word */
while(isspace(input[i])) ++i;
/* 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) {
strcpy(def,url);
continue;
}
/* Looking for Coordinates */
k=0;
while (input[i]) {
/* Move over spaces and commas */
while (isspace(input[i]) || input[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;
while (isdigit(input[i]))
num[j++] = input[i++];
num[j] = '\0';
if (!j && !sawparen && k > 0) {
pointarray[k++][Y] = -127;
break;
}
if (j)
pointarray[k++][Y] = (double) atoi(num);
else {
error_num = IMAP_ERR_INCORRECT_COORDS;
FClose(fp);
goto imagemap_error;
}
/* 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;
if(!strncmp(type, "poly", 4))
if(pointinpoly(testpoint,pointarray))
Found = 1;
if(!strncmp(type, "circ", 4))
if(pointincircle(testpoint,pointarray))
Found = 1;
if(!strncmp(type, "rect", 4))
if(pointinrect(testpoint,pointarray))
Found = 1;
if(!strcmp(type,"point")) {
/* Don't need to take square root. */
dist = ((testpoint[X] - pointarray[0][X])
* (testpoint[X] - pointarray[0][X]))
+ ((testpoint[Y] - pointarray[0][Y])
* (testpoint[Y] - pointarray[0][Y]));
/* If this is the first point, or the nearest, set the default. */
if ((! sawpoint) || (dist < mindist)) {
mindist = dist;
strcpy(def,url);
}
sawpoint++;
}
}
if(Found) {
sendmesg(reqInfo, url, fp);
goto imagemap_ok;
} else {
if(def[0]) {
sendmesg(reqInfo, def, fp);
goto imagemap_ok;
}
}
/* No reason to log each of these as an "error" */
/* log_reason(reqInfo, "No default defined in imagemap.",
reqInfo->filename); */
FClose(fp);
freeString(input);
freeString(def);
freeString(szPoint);
freeString(url);
freeString(type);
die(reqInfo, SC_NO_CONTENT, reqInfo->url);
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)
{
char *loc, *furl;
loc = newString(HUGE_STRING_LEN,STR_REQ);
furl = newString(HUGE_STRING_LEN,STR_REQ);
FClose(fp);
if (!strchr(url, ':')) { /*** If not a full URL ***/
if (url[0] != '/') { /*** Relative URL ***/
char *last = strrchr(reqInfo->url,'/');
int x = 0, y = 0;
while (((reqInfo->url+x) <= last) && (y < HUGE_STRING_LEN)) {
loc[y] = *(reqInfo->url+x);
x++; y++;
}
loc[y] = '\0';
} else {
strncpy(loc,url,HUGE_STRING_LEN);
}
construct_url(furl, reqInfo->hostInfo, loc);
die(reqInfo,SC_REDIRECT_TEMP,furl);
} else {
die(reqInfo,SC_REDIRECT_TEMP,url);
}
}
int pointinrect(double point[2], double coords[MAXVERTS][2])
{
return ((point[X] >= coords[0][X] && point[X] <= coords[1][X]) &&
(point[Y] >= coords[0][Y] && point[Y] <= coords[1][Y]));
}
int pointincircle(double point[2], double coords[MAXVERTS][2])
{
int radius1, radius2;
/* If given a radius instead of a coordinate */
if (coords[1][Y] == -127)
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])) +
((coords[0][X] - point[X]) * (coords[0][X] - point[X]));
return (radius2 <= radius1);
}
int pointinpoly(double point[2], double pgon[MAXVERTS][2])
{
int i, numverts, inside_flag, xflag0;
int crossings;
double *p, *stop;
double tx, ty, y;
for (i = 0; pgon[i][X] != -1 && i < MAXVERTS; i++)
;
numverts = i;
crossings = 0;
tx = point[X];
ty = point[Y];
y = pgon[numverts - 1][Y];
p = (double *) pgon + 1;
if ((y >= ty) != (*p >= ty)) {
if ((xflag0 = (pgon[numverts - 1][X] >= tx)) ==
(*(double *) pgon >= tx)) {
if (xflag0)
crossings++;
}
else {
crossings += (pgon[numverts - 1][X] - (y - ty) *
(*(double *) pgon - pgon[numverts - 1][X]) /
(*p - y)) >= tx;
}
}
stop = pgon[numverts];
for (y = *p, p += 2; p < stop; y = *p, p += 2) {
if (y >= ty) {
while ((p < stop) && (*p >= ty))
p += 2;
if (p >= stop)
break;
if ((xflag0 = (*(p - 3) >= tx)) == (*(p - 1) >= tx)) {
if (xflag0)
crossings++;
}
else {
crossings += (*(p - 3) - (*(p - 2) - ty) *
(*(p - 1) - *(p - 3)) / (*p - *(p - 2))) >= tx;
}
}
else {
while ((p < stop) && (*p < ty))
p += 2;
if (p >= stop)
break;
if ((xflag0 = (*(p - 3) >= tx)) == (*(p - 1) >= tx)) {
if (xflag0)
crossings++;
}
else {
crossings += (*(p - 3) - (*(p - 2) - ty) *
(*(p - 1) - *(p - 3)) / (*p - *(p - 2))) >= tx;
}
}
}
inside_flag = crossings & 0x01;
return (inside_flag);
}
#endif /* IMAGEMAP_SUPPORT */

41
src/imagemap.h Normal file
View File

@ -0,0 +1,41 @@
/************************************************************************
* 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
*
************************************************************************
*
* imagemap.h,v 1.6 1996/04/05 18:55:18 blong Exp
*
************************************************************************
*
* imagemap.h: This file contains all of the header information for the
* built in imagemap support for NCSA HTTPd
*
*/
#ifndef _IMAGEMAP_H
#define _IMAGEMAP_H 1
#define MAXVERTS 100
#define X 0
#define Y 1
#define IMAP_NCSA 1
#define IMAP_CERN 2
void sendmesg(per_request* reqInfo, char *url, FILE* fp);
int pointinpoly(double point[2], double pgon[MAXVERTS][2]);
int pointincircle(double point[2], double coords[MAXVERTS][2]);
int pointinrect(double point[2], double coords[MAXVERTS][2]);
int isname(char);
int send_imagemap(per_request* reqInfo, struct stat* fi, char allow_options);
#endif /* _IMAGE_MAP_H */

160
src/md5.c Normal file
View File

@ -0,0 +1,160 @@
/************************************************************************
* 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. */
/* Jeff Hostetler, Spyglass, Inc., 1994. */
#include "config.h"
#include "portability.h"
#include "constants.h"
#include <stdio.h>
#include <string.h>
#ifndef SHTTP
#include "global.h"
#endif /* SHTTP */
#include "md5.h"
void md5 (unsigned char *string, char result[33])
{
MD5_CTX my_md5;
unsigned char hash[16];
char *p;
int i;
/*
* Take the MD5 hash of the string argument.
*/
MD5Init(&my_md5);
MD5Update(&my_md5, string, strlen((const char *)string));
MD5Final(hash, &my_md5);
for (i=0, p=result; i<16; i++, p+=2)
sprintf(p, "%02x", hash[i]);
*p = '\0';
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 */

41
src/md5.h Normal file
View File

@ -0,0 +1,41 @@
/* MD5.H - header file for MD5C.C
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#ifndef _MD5_H
#define _MD5_H 1
/* MD5 context. */
typedef struct {
UINT4 state[4]; /* state (ABCD) */
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} MD5_CTX;
void MD5Init (MD5_CTX *);
void MD5Update (MD5_CTX *, unsigned char *, unsigned int);
void MD5Final (unsigned char [16], MD5_CTX *);
void md5 (unsigned char *string, char result[33]);
#endif /* _MD5_H */

337
src/md5c.c Normal file
View File

@ -0,0 +1,337 @@
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#include "config.h"
#include "portability.h"
#include "global.h"
#include "md5.h"
/* Constants for MD5Transform routine.
*/
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
static void Encode PROTO_LIST
((unsigned char *, UINT4 *, unsigned int));
static void Decode PROTO_LIST
((UINT4 *, unsigned char *, unsigned int));
static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
void MD5Init (context)
MD5_CTX *context; /* context */
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants.
*/
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
void MD5Update (context, input, inputLen)
MD5_CTX *context; /* context */
unsigned char *input; /* input block */
unsigned int inputLen; /* length of input block */
{
unsigned int i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((UINT4)inputLen << 3))
< ((UINT4)inputLen << 3))
context->count[1]++;
context->count[1] += ((UINT4)inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible.
*/
if (inputLen >= partLen) {
MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)input, partLen);
MD5Transform (context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform (context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)&input[i],
inputLen-i);
}
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context.
*/
void MD5Final (digest, context)
unsigned char digest[16]; /* message digest */
MD5_CTX *context; /* context */
{
unsigned char bits[8];
unsigned int index, padLen;
/* Save number of bits */
Encode (bits, context->count, 8);
/* Pad out to 56 mod 64.
*/
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5Update (context, PADDING, padLen);
/* Append length (before padding) */
MD5Update (context, bits, 8);
/* Store state in digest */
Encode (digest, context->state, 16);
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)context, 0, sizeof (*context));
}
/* MD5 basic transformation. Transforms state based on block.
*/
static void MD5Transform (state, block)
UINT4 state[4];
unsigned char block[64];
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)x, 0, sizeof (x));
}
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
static void Encode (output, input, len)
unsigned char *output;
UINT4 *input;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4.
*/
static void Decode (output, input, len)
UINT4 *output;
unsigned char *input;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}
/* Note: Replace "for loop" with standard memcpy if possible.
*/
static void MD5_memcpy (output, input, len)
POINTER output;
POINTER input;
unsigned int len;
{
unsigned int i;
for (i = 0; i < len; i++)
output[i] = input[i];
}
/* Note: Replace "for loop" with standard memset if possible.
*/
static void MD5_memset (output, value, len)
POINTER output;
int value;
unsigned int len;
{
unsigned int i;
for (i = 0; i < len; i++)
((char *)output)[i] = (char)value;
}

View File

@ -1,99 +0,0 @@
/*
* New Header file, since I didn't like recompiling the whole thing
* every time I wanted to do anything.
*
* One of these days, I'll have to make some real header files for this code.
*
* All code contained herein is covered by the Copyright as distributed
* in the README file in the main directory of the distribution of
* NCSA HTTPD.
*
*/
#include <setjmp.h>
/* #defines for new muli-child approach
DEFAULT_START_DAEMON defines how many children start at httpd start
DEFAULT_MAX_DAEMON defines how many children can start
*/
#define DEFAULT_START_DAEMON 5
#define DEFAULT_MAX_DAEMON 10
/* For New Error Handling */
#define NUM_ERRORS 10
#define CGI_ERROR 1
#define TEXT_ERROR 2
typedef struct _ChildInfo {
int parentfd;
int childfd;
int pid;
int busy;
} ChildInfo;
typedef struct _ErrorMessage {
int Type;
int ErrorNum;
char* ErrorFile;
} ErrorMessage;
/* in http_log.c */
extern const char StatLine200[];
extern const char StatLine302[];
extern const char StatLine304[];
extern const char StatLine400[];
extern const char StatLine401[];
extern const char StatLine403[];
extern const char StatLine404[];
extern const char StatLine500[];
extern const char StatLine501[];
extern int ErrorStat;
extern int numErrorsDefined;
/* in http_mime.c */
extern char *status_line;
extern struct mime_ext *types[27];
extern struct mime_ext *forced_types;
extern struct mime_ext *encoding_types;
extern struct mime_ext *Saved_Forced;
extern struct mime_ext *Saved_Encoding;
char* set_stat_line();
void reset_mime_vars();
/* for http_ipc.c */
int pass_fd(int spipefd, int filedes);
int recv_fd(int spipefd);
#ifdef NEED_SPIPE
int s_pipe(int fd[2]);
#endif
/* for http_log.c */
int add_error(char* errornum, char* name);
int have_error(int errornum);
void reset_error();
/* for http_config.c */
extern int max_servers;
extern int start_servers;
/* number of security directives in access config file */
extern int num_sec_config;
/* for httpd.c */
void speed_hack_libs();
void set_group_privs();
void set_signals();
/* new globals in http_request.c */
extern char method[];
extern char protocal[];
extern char the_request[];
extern char failed_request[];
extern char as_requested[];
extern char url2[];
extern char failed_url[];
extern char args2[];
void initialize_request();
/* for http_access.c */
void reset_security();

View File

@ -1,12 +0,0 @@
*** ../../sgi5/httpd_1.4.2/src/http_get.c Thu Jun 22 18:48:27 1995
--- http_get.c Fri Jun 23 11:09:57 1995
***************
*** 208,214 ****
}
else {
probe_content_type(ifile);
- fprintf(stderr,"content_type: %s\n",content_type);
if(!strcmp(content_type,CGI_MAGIC_TYPE))
send_cgi("GET",ifile,pa,args,&finfo,in,fd);
else
--- 208,213 ----

Some files were not shown because too many files have changed in this diff Show More