summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Bogatov <KAction@debian.org>2018-11-15 15:59:22 +0000
committerDmitry Bogatov <KAction@debian.org>2018-11-15 15:59:22 +0000
commitef18215493fbf5180b9a9b016ac70e0f3766f59c (patch)
tree50d0a9326af5bde662af0c9d68a30e7fa9da32da
parentf8fad52c70a50762444785c2cfdbf617d288684e (diff)
Import Upstream version 1.21
-rw-r--r--Makefile46
-rw-r--r--README8
-rw-r--r--contrib/redhat-rpm/mini_httpd.spec28
-rw-r--r--htpasswd.c10
-rw-r--r--match.h2
-rw-r--r--mime_types.txt29
-rw-r--r--mini_httpd.820
-rw-r--r--mini_httpd.c367
-rw-r--r--port.h8
-rwxr-xr-xscripts/500.mini_httpd-rotate16
-rwxr-xr-xscripts/mini_httpd.sh59
-rwxr-xr-xscripts/mini_httpd_wrapper27
-rw-r--r--tdate_parse.c11
-rw-r--r--tdate_parse.h2
-rw-r--r--version.h2
15 files changed, 389 insertions, 246 deletions
diff --git a/Makefile b/Makefile
index 04766ae..79c5e81 100644
--- a/Makefile
+++ b/Makefile
@@ -16,33 +16,31 @@ CRYPT_LIB = -lcrypt
# it may be in /usr/local instead of /usr/local/ssl.
#SSL_TREE = /usr/local/ssl
#SSL_DEFS = -DUSE_SSL
-#SSL_INC = -I${SSL_TREE}/include
-#SSL_LIBS = -L${SSL_TREE}/lib -lssl -lcrypto
+#SSL_INC = -I$(SSL_TREE)/include
+#SSL_LIBS = -L$(SSL_TREE)/lib -lssl -lcrypto
BINDIR = /usr/local/sbin
MANDIR = /usr/local/man
-CC = gcc
-CDEFS = ${SSL_DEFS} ${SSL_INC}
-CFLAGS = -O ${CDEFS}
-#CFLAGS = -g ${CDEFS}
+CC = cc
+CDEFS = $(SSL_DEFS) $(SSL_INC)
+CFLAGS = -O $(CDEFS) -ansi -pedantic -U__STRICT_ANSI__ -Wall -Wpointer-arith -Wshadow -Wcast-qual -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wno-long-long
LDFLAGS = -s
-#LDFLAGS = -g
-LDLIBS = ${SSL_LIBS} ${SYSV_LIBS} ${CRYPT_LIB}
+LDLIBS = $(CRYPT_LIB) $(SSL_LIBS) $(SYSV_LIBS)
all: mini_httpd htpasswd
mini_httpd: mini_httpd.o match.o tdate_parse.o
- ${CC} ${CFLAGS} ${LDFLAGS} mini_httpd.o match.o tdate_parse.o ${LDLIBS} -o mini_httpd
+ $(CC) $(LDFLAGS) mini_httpd.o match.o tdate_parse.o $(LDLIBS) -o mini_httpd
mini_httpd.o: mini_httpd.c version.h port.h match.h tdate_parse.h mime_encodings.h mime_types.h
- ${CC} ${CFLAGS} -c mini_httpd.c
+ $(CC) $(CFLAGS) -c mini_httpd.c
match.o: match.c match.h
- ${CC} ${CFLAGS} -c match.c
+ $(CC) $(CFLAGS) -c match.c
tdate_parse.o: tdate_parse.c tdate_parse.h
- ${CC} ${CFLAGS} -c tdate_parse.c
+ $(CC) $(CFLAGS) -c tdate_parse.c
mime_encodings.h: mime_encodings.txt
rm -f mime_encodings.h
@@ -58,34 +56,34 @@ mime_types.h: mime_types.txt
htpasswd: htpasswd.o
- ${CC} ${CFLAGS} ${LDFLAGS} htpasswd.o ${CRYPT_LIB} -o htpasswd
+ $(CC) $(LDFLAGS) htpasswd.o $(CRYPT_LIB) -o htpasswd
htpasswd.o: htpasswd.c
- ${CC} ${CFLAGS} -c htpasswd.c
+ $(CC) $(CFLAGS) -c htpasswd.c
cert: mini_httpd.pem
mini_httpd.pem: mini_httpd.cnf
- openssl req -new -x509 -days 365 -nodes -config mini_httpd.cnf -out mini_httpd.pem -keyout mini_httpd.pem
+ openssl req -new -x509 -days 3650 -nodes -config mini_httpd.cnf -out mini_httpd.pem -keyout mini_httpd.pem
openssl x509 -subject -dates -fingerprint -noout -in mini_httpd.pem
chmod 600 mini_httpd.pem
install: all
- rm -f ${BINDIR}/mini_httpd ${BINDIR}/htpasswd
- -mkdir -p ${BINDIR}
- cp mini_httpd htpasswd ${BINDIR}
- rm -f ${MANDIR}/man8/mini_httpd.8 ${MANDIR}/man1/htpasswd.1
- -mkdir -p ${MANDIR}/man8
- cp mini_httpd.8 ${MANDIR}/man8
- -mkdir -p ${MANDIR}/man1
- cp htpasswd.1 ${MANDIR}/man1
+ rm -f $(BINDIR)/mini_httpd $(BINDIR)/htpasswd
+ -mkdir -p $(BINDIR)
+ cp mini_httpd htpasswd $(BINDIR)
+ rm -f $(MANDIR)/man8/mini_httpd.8 $(MANDIR)/man1/htpasswd.1
+ -mkdir -p $(MANDIR)/man8
+ cp mini_httpd.8 $(MANDIR)/man8
+ -mkdir -p $(MANDIR)/man1
+ cp htpasswd.1 $(MANDIR)/man1
clean:
rm -f mini_httpd mime_encodings.h mime_types.h htpasswd mini_httpd.rnd *.o core core.* *.core
tar:
- @name=`sed -n -e '/SERVER_SOFTWARE/!d' -e 's,.*mini_httpd/,mini_httpd-,' -e 's, .*,,p' version.h` ; \
+ @name=`sed -n -e '/#define SERVER_SOFTWARE /!d' -e 's,.*mini_httpd/,mini_httpd-,' -e 's, .*,,p' version.h` ; \
rm -rf $$name ; \
mkdir $$name ; \
tar cf - `cat FILES` | ( cd $$name ; tar xfBp - ) ; \
diff --git a/README b/README
index 8a7b9f7..14c1cc5 100644
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
mini_httpd - small HTTP server
- version 1.19 of 19dec2003
+ version 1.21 of 18oct2004
mini_httpd is a small HTTP server. Its performance is not great, but for
low or medium traffic sites it's quite adequate. It implements all the
@@ -48,9 +48,9 @@ If you're doing SSL, uncomment those lines too. Otherwise, just do a make.
On Red Hat Linux systems you can use RPM to install mini_httpd, like so:
cd /usr/src/redhat/SOURCES
- wget http://www.acme.com/software/mini_httpd/mini_httpd-1.19.tar.gz
- rpm -ta mini_httpd-1.19.tar.gz
- rpm -i /usr/src/redhat/RPMS/i386/mini_httpd-1.19-1.i386.rpm
+ wget http://www.acme.com/software/mini_httpd/mini_httpd-1.20.tar.gz
+ rpm -ta mini_httpd-1.20.tar.gz
+ rpm -i /usr/src/redhat/RPMS/i386/mini_httpd-1.20-1.i386.rpm
Feedback is welcome - send bug reports, enhancements, checks, money
orders, etc. to the addresses below.
diff --git a/contrib/redhat-rpm/mini_httpd.spec b/contrib/redhat-rpm/mini_httpd.spec
index 14d88ad..3f52202 100644
--- a/contrib/redhat-rpm/mini_httpd.spec
+++ b/contrib/redhat-rpm/mini_httpd.spec
@@ -1,6 +1,6 @@
Summary: small, simple http daemon, supports SSL
Name: mini_httpd
-Version: 1.19
+Version: 1.21
Release: 1
Copyright: Freely Redistributable
Packager: Bennett Todd <bet@mordor.net>
@@ -57,18 +57,20 @@ install contrib/redhat-rpm/mini_httpd.init \
%changelog
-* Mon Oct 27 2003 <jef@acme.com> Version 1.19
-* Sat Sep 13 2003 <jef@acme.com> Version 1.18
-* Sat May 25 2002 <jef@acme.com> Version 1.17
-* Mon May 07 2001 <jef@acme.com> Version 1.16
-* Tue May 01 2001 <jef@acme.com> Version 1.15c
-* Sat Apr 21 2001 <jef@acme.com> Version 1.15b
-* Wed Sep 20 2000 <jef@acme.com> Version 1.15
-* Thu Jun 15 2000 <jef@acme.com> Version 1.14
-* Fri May 26 2000 <jef@acme.com> Version 1.13
-* Wed Mar 01 2000 <jef@acme.com> Version 1.12
-* Sun Feb 06 2000 <jef@acme.com> Version 1.11
-* Wed Feb 02 2000 <jef@acme.com> Version 1.10
+* Sat Oct 18 2014 <jef@mail.acme.com> Version 1.21
+* Thu Jan 08 2004 <jef@mail.acme.com> Version 1.20
+* Mon Oct 27 2003 <jef@mail.acme.com> Version 1.19
+* Sat Sep 13 2003 <jef@mail.acme.com> Version 1.18
+* Sat May 25 2002 <jef@mail.acme.com> Version 1.17
+* Mon May 07 2001 <jef@mail.acme.com> Version 1.16
+* Tue May 01 2001 <jef@mail.acme.com> Version 1.15c
+* Sat Apr 21 2001 <jef@mail.acme.com> Version 1.15b
+* Wed Sep 20 2000 <jef@mail.acme.com> Version 1.15
+* Thu Jun 15 2000 <jef@mail.acme.com> Version 1.14
+* Fri May 26 2000 <jef@mail.acme.com> Version 1.13
+* Wed Mar 01 2000 <jef@mail.acme.com> Version 1.12
+* Sun Feb 06 2000 <jef@mail.acme.com> Version 1.11
+* Wed Feb 02 2000 <jef@mail.acme.com> Version 1.10
* Mon Jan 31 2000 <bet@rahul.net> Version 1.09, added init script
* Wed Jan 19 2000 <bet@rahul.net> Version 1.08, reset release to 1
* Mon Dec 13 1999 <bet@mordor.net>
diff --git a/htpasswd.c b/htpasswd.c
index e01ea1d..8ffda29 100644
--- a/htpasswd.c
+++ b/htpasswd.c
@@ -16,8 +16,6 @@
#include <time.h>
#include <unistd.h>
-extern char *crypt(const char *key, const char *setting);
-
#define LF 10
#define CR 13
@@ -49,8 +47,8 @@ static void getword(char *word, char *line, char stop) {
while((line[y++] = line[x++]));
}
-static int getline(char *s, int n, FILE *f) {
- register int i=0;
+static int my_getline(char *s, int n, FILE *f) {
+ int i=0;
while(1) {
s[i] = (char)fgetc(f);
@@ -78,7 +76,7 @@ static void putline(FILE *f,char *l) {
static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-static void to64(register char *s, register long v, register int n) {
+static void to64(char *s, long v, int n) {
while (--n >= 0) {
*s++ = itoa64[v&0x3f];
v >>= 6;
@@ -189,7 +187,7 @@ int main(int argc, char *argv[]) {
strcpy(user,argv[2]);
found = 0;
- while(!(getline(line,MAX_STRING_LEN,f))) {
+ while(!(my_getline(line,MAX_STRING_LEN,f))) {
if(found || (line[0] == '#') || (!line[0])) {
putline(tfp,line);
continue;
diff --git a/match.h b/match.h
index f46dd00..01c5f2a 100644
--- a/match.h
+++ b/match.h
@@ -31,6 +31,6 @@
/* Simple shell-style filename pattern matcher. Only does ? * and **, and
** multiple patterns separated by |. Returns 1 or 0.
*/
-extern int match( const char* pattern, const char* string );
+int match( const char* pattern, const char* string );
#endif /* _MATCH_H_ */
diff --git a/mime_types.txt b/mime_types.txt
index db49c54..d4725d9 100644
--- a/mime_types.txt
+++ b/mime_types.txt
@@ -11,7 +11,7 @@ ai application/postscript
aif audio/x-aiff
aifc audio/x-aiff
aiff audio/x-aiff
-asc text/plain
+asc text/plain; charset=%s
asf video/x-ms-asf
asx video/x-ms-asf
au audio/basic
@@ -26,7 +26,7 @@ cpt application/mac-compactpro
crl application/x-pkcs7-crl
crt application/x-x509-ca-cert
csh application/x-csh
-css text/css
+css text/css; charset=%s
dcr application/x-director
dir application/x-director
djv image/vnd.djvu
@@ -34,7 +34,7 @@ djvu image/vnd.djvu
dll application/octet-stream
dms application/octet-stream
doc application/msword
-dtd text/xml
+dtd text/xml; charset=%s
dump application/octet-stream
dvi application/x-dvi
dxr application/x-director
@@ -66,8 +66,11 @@ jpeg image/jpeg
jpg image/jpeg
js application/x-javascript
kar audio/midi
+kml application/vnd.google-earth.kml+xml
+kmz application/vnd.google-earth.kmz
latex application/x-latex
lha application/octet-stream
+loc application/xml-loc
lzh application/octet-stream
m3u audio/x-mpegurl
man application/x-troff-man
@@ -95,7 +98,7 @@ mxu video/vnd.mpegurl
nc application/x-netcdf
o application/octet-stream
oda application/oda
-ogg application/x-ogg
+ogg application/ogg
pac application/x-ns-proxy-autoconfig
pbm image/x-portable-bitmap
pdb chemical/x-pdb
@@ -117,10 +120,10 @@ rm audio/x-pn-realaudio
roff application/x-troff
rpm audio/x-pn-realaudio-plugin
rss application/rss+xml
-rtf text/rtf
-rtx text/richtext
-sgm text/sgml
-sgml text/sgml
+rtf text/rtf; charset=%s
+rtx text/richtext; charset=%s
+sgm text/sgml; charset=%s
+sgml text/sgml; charset=%s
sh application/x-sh
shar application/x-shar
silo model/mesh
@@ -160,7 +163,7 @@ tif image/tiff
tiff image/tiff
tr application/x-troff
tsp application/dsptype
-tsv text/tab-separated-values
+tsv text/tab-separated-values; charset=%s
txt text/plain; charset=%s
ustar application/x-ustar
vcd application/x-cdlink
@@ -184,12 +187,12 @@ wrl model/vrml
wsrc application/x-wais-source
wvx video/x-ms-wvx
xbm image/x-xbitmap
-xht application/xhtml+xml
-xhtml application/xhtml+xml
+xht application/xhtml+xml; charset=%s
+xhtml application/xhtml+xml; charset=%s
xls application/vnd.ms-excel
-xml text/xml
+xml text/xml; charset=%s
xpm image/x-xpixmap
-xsl text/xml
+xsl text/xml; charset=%s
xwd image/x-xwindowdump
xyz chemical/x-xyz
zip application/zip
diff --git a/mini_httpd.8 b/mini_httpd.8
index 8c4695e..f4d4dd4 100644
--- a/mini_httpd.8
+++ b/mini_httpd.8
@@ -153,7 +153,7 @@ The config-file option name for this flag is "pidfile".
.TP
.B -T
Specifies the character set to use with text MIME types.
-The default is "iso-8859-1".
+The default is "UTF-8".
The config-file option name for this flag is "charset".
.TP
.B -P
@@ -362,34 +362,34 @@ virtual host's web tree.
mini_httpd will look first in the virtual host errors directory, and
then in the server-wide errors directory, and if neither of those
has an appropriate error file then it will generate the built-in error.
-.SH "NON-LOCAL REFERERS"
+.SH "NON-LOCAL REFERRERS"
.PP
Sometimes another site on the net will embed your image files in their
HTML files, which basically means they're stealing your bandwidth.
-You can prevent them from doing this by using non-local referer filtering.
-With this option, certain files can only be fetched via a local referer.
+You can prevent them from doing this by using non-local referrer filtering.
+With this option, certain files can only be fetched via a local referrer.
The files have to be referenced by a local web page.
If a web page on some other site references the files, that fetch will
be blocked.
There are three config-file variables for this feature:
.TP
.B urlpat
-A wildcard pattern for the URLs that should require a local referer.
+A wildcard pattern for the URLs that should require a local referrer.
This is typically just image files, sound files, and so on.
For example:
.nf
urlpat=**.jpg|**.gif|**.au|**.wav
.fi
-For most sites, that one setting is all you need to enable referer filtering.
+For most sites, that one setting is all you need to enable referrer filtering.
.TP
-.B noemptyreferers
-By default, requests with no referer at all, or a null referer, or a
-referer with no apparent hostname, are allowed.
+.B noemptyreferrers
+By default, requests with no referrer at all, or a null referrer, or a
+referrer with no apparent hostname, are allowed.
With this variable set, such requests are disallowed.
.TP
.B localpat
A wildcard pattern that specifies the local host or hosts.
-This is used to determine if the host in the referer is local or not.
+This is used to determine if the host in the referrer is local or not.
If not specified it defaults to the actual local hostname.
.SH SIGNALS
.PP
diff --git a/mini_httpd.c b/mini_httpd.c
index f2a00b1..881843f 100644
--- a/mini_httpd.c
+++ b/mini_httpd.c
@@ -65,13 +65,16 @@
# endif /* HAVE_LINUX_SENDFILE */
#endif /* HAVE_SENDFILE */
+#if defined(TCP_CORK) && !defined(TCP_NOPUSH)
+#define TCP_NOPUSH TCP_CORK
+/* (Linux's TCP_CORK is basically the same as BSD's TCP_NOPUSH.) */
+#endif
+
#ifdef USE_SSL
#include <openssl/ssl.h>
#include <openssl/err.h>
#endif /* USE_SSL */
-extern char* crypt( const char* key, const char* setting );
-
#if defined(AF_INET6) && defined(IN6_IS_ADDR_V4MAPPED)
#define USE_IPV6
@@ -147,8 +150,11 @@ typedef long long int64_t;
#define WRITE_TIMEOUT 300
#endif /* WRITE_TIMEOUT */
#ifndef DEFAULT_CHARSET
-#define DEFAULT_CHARSET "iso-8859-1"
+#define DEFAULT_CHARSET "UTF-8"
#endif /* DEFAULT_CHARSET */
+#ifndef MAX_SEND_BUFFER_SIZE
+#define MAX_SEND_BUFFER_SIZE 1048576
+#endif /* MAX_SEND_BUFFER_SIZE */
#define METHOD_UNKNOWN 0
@@ -178,7 +184,7 @@ static int vhost;
static char* user;
static char* cgi_pattern;
static char* url_pattern;
-static int no_empty_referers;
+static int no_empty_referrers;
static char* local_pattern;
static char* hostname;
static char hostname_buf[500];
@@ -224,7 +230,7 @@ static char* content_type;
static char* cookie;
static char* host;
static time_t if_modified_since;
-static char* referer;
+static char* referrer;
static char* useragent;
static char* remoteuser;
@@ -237,12 +243,12 @@ static void value_required( char* name, char* value );
static void no_value_required( char* name, char* value );
static int initialize_listen_socket( usockaddr* usaP );
static void handle_request( void );
-static void de_dotdot( char* file );
+static void de_dotdot( char* f );
static int get_pathinfo( void );
static void do_file( void );
static void do_dir( void );
#ifdef HAVE_SCANDIR
-static char* file_details( const char* dir, const char* name );
+static char* file_details( const char* d, const char* name );
static void strencode( char* to, size_t tosize, const char* from );
#endif /* HAVE_SCANDIR */
static void do_cgi( void );
@@ -254,7 +260,7 @@ static char** make_envp( void );
static char* build_env( char* fmt, char* arg );
static void auth_check( char* dirname );
static void send_authenticate( char* realm );
-static char* virtual_file( char* file );
+static char* virtual_file( char* f );
static void send_error( int s, char* title, char* extra_header, char* text );
static void send_error_body( int s, char* title, char* text );
static int send_error_file( char* filename );
@@ -267,15 +273,16 @@ static void start_response( void );
static void add_to_response( char* str, size_t len );
static void send_response( void );
static void send_via_write( int fd, off_t size );
+static void send_via_sendfile( int fd, int s, off_t size );
static ssize_t my_read( char* buf, size_t size );
-static ssize_t my_write( char* buf, size_t size );
+static ssize_t my_write( void* buf, size_t size );
#ifdef HAVE_SENDFILE
-static int my_sendfile( int fd, int socket, off_t offset, size_t nbytes );
+static int my_sendfile( int fd, int s, off_t offset, size_t nbytes );
#endif /* HAVE_SENDFILE */
static void add_to_buf( char** bufP, size_t* bufsizeP, size_t* buflenP, char* str, size_t len );
static void make_log_entry( void );
-static void check_referer( void );
-static int really_check_referer( void );
+static void check_referrer( void );
+static int really_check_referrer( void );
static char* get_method_str( int m );
static void init_mime( void );
static const char* figure_mime( char* name, char* me, size_t me_size );
@@ -315,7 +322,8 @@ main( int argc, char** argv )
fd_set lfdset;
int maxfd;
usockaddr usa;
- int sz, r;
+ socklen_t sz;
+ int r;
char* cp;
/* Parse args. */
@@ -328,7 +336,7 @@ main( int argc, char** argv )
vhost = 0;
cgi_pattern = (char*) 0;
url_pattern = (char*) 0;
- no_empty_referers = 0;
+ no_empty_referrers = 0;
local_pattern = (char*) 0;
charset = DEFAULT_CHARSET;
p3p = (char*) 0;
@@ -543,6 +551,7 @@ main( int argc, char** argv )
SSL_load_error_strings();
SSLeay_add_ssl_algorithms();
ssl_ctx = SSL_CTX_new( SSLv23_server_method() );
+ SSL_CTX_set_options( ssl_ctx, SSL_OP_NO_SSLv3 );
if ( certfile[0] != '\0' )
if ( SSL_CTX_use_certificate_file( ssl_ctx, certfile, SSL_FILETYPE_PEM ) == 0 ||
SSL_CTX_use_PrivateKey_file( ssl_ctx, certfile, SSL_FILETYPE_PEM ) == 0 ||
@@ -676,6 +685,7 @@ main( int argc, char** argv )
** tree.
*/
if ( logfile != (char*) 0 )
+ {
if ( strncmp( logfile, cwd, strlen( cwd ) ) == 0 )
{
(void) strcpy( logfile, &logfile[strlen( cwd ) - 1] );
@@ -689,6 +699,7 @@ main( int argc, char** argv )
syslog( LOG_WARNING, "logfile is not within the chroot tree, you will not be able to re-open it" );
(void) fprintf( stderr, "%s: logfile is not within the chroot tree, you will not be able to re-open it\n", argv0 );
}
+ }
(void) strcpy( cwd, "/" );
/* Always chdir to / after a chroot. */
if ( chdir( cwd ) < 0 )
@@ -816,7 +827,7 @@ main( int argc, char** argv )
}
if ( conn_fd < 0 )
{
- if ( errno == EINTR || errno == EAGAIN )
+ if ( errno == EINTR || errno == EAGAIN || errno == ECONNABORTED )
continue; /* try again */
#ifdef EPROTO
if ( errno == EPROTO )
@@ -950,10 +961,11 @@ read_config( char* filename )
value_required( name, value );
url_pattern = e_strdup( value );
}
- else if ( strcasecmp( name, "noemptyreferers" ) == 0 )
+ else if ( strcasecmp( name, "noemptyreferers" ) == 0 ||
+ strcasecmp( name, "noemptyreferrers" ) == 0 )
{
value_required( name, value );
- no_empty_referers = 1;
+ no_empty_referrers = 1;
}
else if ( strcasecmp( name, "localpat" ) == 0 )
{
@@ -1157,7 +1169,7 @@ handle_request( void )
cookie = (char*) 0;
host = (char*) 0;
if_modified_since = (time_t) -1;
- referer = "";
+ referrer = "";
useragent = "";
#ifdef TCP_NOPUSH
@@ -1189,13 +1201,13 @@ handle_request( void )
for (;;)
{
char buf[10000];
- int r = my_read( buf, sizeof(buf) );
- if ( r < 0 && ( errno == EINTR || errno == EAGAIN ) )
+ int rr = my_read( buf, sizeof(buf) );
+ if ( rr < 0 && ( errno == EINTR || errno == EAGAIN ) )
continue;
- if ( r <= 0 )
+ if ( rr <= 0 )
break;
(void) alarm( READ_TIMEOUT );
- add_to_request( buf, r );
+ add_to_request( buf, rr );
if ( strstr( request, "\015\012\015\012" ) != (char*) 0 ||
strstr( request, "\012\012" ) != (char*) 0 )
break;
@@ -1268,7 +1280,13 @@ handle_request( void )
{
cp = &line[8];
cp += strspn( cp, " \t" );
- referer = cp;
+ referrer = cp;
+ }
+ else if ( strncasecmp( line, "Referrer:", 9 ) == 0 )
+ {
+ cp = &line[9];
+ cp += strspn( cp, " \t" );
+ referrer = cp;
}
else if ( strncasecmp( line, "User-Agent:", 11 ) == 0 )
{
@@ -1368,14 +1386,14 @@ handle_request( void )
static void
-de_dotdot( char* file )
+de_dotdot( char* f )
{
char* cp;
char* cp2;
int l;
/* Collapse any multiple / sequences. */
- while ( ( cp = strstr( file, "//") ) != (char*) 0 )
+ while ( ( cp = strstr( f, "//") ) != (char*) 0 )
{
for ( cp2 = cp + 2; *cp2 == '/'; ++cp2 )
continue;
@@ -1383,31 +1401,31 @@ de_dotdot( char* file )
}
/* Remove leading ./ and any /./ sequences. */
- while ( strncmp( file, "./", 2 ) == 0 )
- (void) strcpy( file, file + 2 );
- while ( ( cp = strstr( file, "/./") ) != (char*) 0 )
+ while ( strncmp( f, "./", 2 ) == 0 )
+ (void) strcpy( f, f + 2 );
+ while ( ( cp = strstr( f, "/./") ) != (char*) 0 )
(void) strcpy( cp, cp + 2 );
/* Alternate between removing leading ../ and removing xxx/../ */
for (;;)
{
- while ( strncmp( file, "../", 3 ) == 0 )
- (void) strcpy( file, file + 3 );
- cp = strstr( file, "/../" );
+ while ( strncmp( f, "../", 3 ) == 0 )
+ (void) strcpy( f, f + 3 );
+ cp = strstr( f, "/../" );
if ( cp == (char*) 0 )
break;
- for ( cp2 = cp - 1; cp2 >= file && *cp2 != '/'; --cp2 )
+ for ( cp2 = cp - 1; cp2 >= f && *cp2 != '/'; --cp2 )
continue;
(void) strcpy( cp2 + 1, cp + 4 );
}
/* Also elide any xxx/.. at the end. */
- while ( ( l = strlen( file ) ) > 3 &&
- strcmp( ( cp = file + l - 3 ), "/.." ) == 0 )
+ while ( ( l = strlen( f ) ) > 3 &&
+ strcmp( ( cp = f + l - 3 ), "/.." ) == 0 )
{
- for ( cp2 = cp - 1; cp2 >= file && *cp2 != '/'; --cp2 )
+ for ( cp2 = cp - 1; cp2 >= f && *cp2 != '/'; --cp2 )
continue;
- if ( cp2 < file )
+ if ( cp2 < f )
break;
*cp2 = '\0';
}
@@ -1475,8 +1493,8 @@ do_file( void )
send_error( 403, "Forbidden", "", "File is protected." );
}
- /* Referer check. */
- check_referer();
+ /* Referrer check. */
+ check_referrer();
/* Is it CGI? */
if ( cgi_pattern != (char*) 0 && match( cgi_pattern, file ) )
@@ -1519,12 +1537,12 @@ do_file( void )
#ifdef HAVE_SENDFILE
#ifndef USE_SSL
- (void) my_sendfile( fd, conn_fd, 0, sb.st_size );
+ send_via_sendfile( fd, conn_fd, sb.st_size );
#else /* USE_SSL */
if ( do_ssl )
send_via_write( fd, sb.st_size );
else
- (void) my_sendfile( fd, conn_fd, 0, sb.st_size );
+ send_via_sendfile( fd, conn_fd, sb.st_size );
#endif /* USE_SSL */
#else /* HAVE_SENDFILE */
@@ -1560,8 +1578,8 @@ do_dir( void )
/* Check authorization for this directory. */
auth_check( file );
- /* Referer check. */
- check_referer();
+ /* Referrer check. */
+ check_referrer();
#ifdef HAVE_SCANDIR
n = scandir( file, &dl, NULL, alphasort );
@@ -1576,11 +1594,18 @@ do_dir( void )
contents_size = 0;
buflen = snprintf( buf, sizeof(buf), "\
-<HTML>\n\
-<HEAD><TITLE>Index of %s</TITLE></HEAD>\n\
-<BODY BGCOLOR=\"#99cc99\" TEXT=\"#000000\" LINK=\"#2020ff\" VLINK=\"#4040cc\">\n\
-<H4>Index of %s</H4>\n\
-<PRE>\n",
+<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n\
+\n\
+<html>\n\
+\n\
+ <head>\n\
+ <meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\">\n\
+ <title>Index of %s</title>\n\
+ </head>\n\
+\n\
+ <body bgcolor=\"#99cc99\" text=\"#000000\" link=\"#2020ff\" vlink=\"#4040cc\">\n\
+ <h4>Index of %s</h4>\n\
+ <pre>\n",
file, file );
add_to_buf( &contents, &contents_size, &contents_len, buf, buflen );
@@ -1600,7 +1625,7 @@ do_dir( void )
{
(void) snprintf(
command, sizeof(command),
- "ls -lgF '%s' | tail +2 | sed -e 's/^\\([^ ][^ ]*\\)\\( *[^ ][^ ]* *[^ ][^ ]* *[^ ][^ ]*\\)\\( *[^ ][^ ]*\\) *\\([^ ][^ ]* *[^ ][^ ]* *[^ ][^ ]*\\) *\\(.*\\)$/\\1 \\3 \\4 |\\5/' -e '/ -> /!s,|\\([^*]*\\)$,|<A HREF=\"\\1\">\\1</A>,' -e '/ -> /!s,|\\(.*\\)\\([*]\\)$,|<A HREF=\"\\1\">\\1</A>\\2,' -e '/ -> /s,|\\([^@]*\\)\\(@* -> \\),|<A HREF=\"\\1\">\\1</A>\\2,' -e 's/|//'",
+ "ls -lgF '%s' | tail +2 | sed -e 's/^\\([^ ][^ ]*\\)\\( *[^ ][^ ]* *[^ ][^ ]* *[^ ][^ ]*\\)\\( *[^ ][^ ]*\\) *\\([^ ][^ ]* *[^ ][^ ]* *[^ ][^ ]*\\) *\\(.*\\)$/\\1 \\3 \\4 |\\5/' -e '/ -> /!s,|\\([^*]*\\)$,|<a href=\"\\1\">\\1</a>,' -e '/ -> /!s,|\\(.*\\)\\([*]\\)$,|<a href=\"\\1\">\\1</a>\\2,' -e '/ -> /s,|\\([^@]*\\)\\(@* -> \\),|<a href=\"\\1\">\\1</a>\\2,' -e 's/|//'",
file );
fp = popen( command, "r" );
for (;;)
@@ -1616,11 +1641,15 @@ do_dir( void )
#endif /* HAVE_SCANDIR */
buflen = snprintf( buf, sizeof(buf), "\
-</PRE>\n\
-<HR>\n\
-<ADDRESS><A HREF=\"%s\">%s</A></ADDRESS>\n\
-</BODY>\n\
-</HTML>\n",
+ </pre>\n\
+\n\
+ <hr>\n\
+\n\
+ <address><a href=\"%s\">%s</a></address>\n\
+ \n\
+ </body>\n\
+\n\
+</html>\n",
SERVER_URL, SERVER_SOFTWARE );
add_to_buf( &contents, &contents_size, &contents_len, buf, buflen );
@@ -1634,21 +1663,21 @@ do_dir( void )
#ifdef HAVE_SCANDIR
static char*
-file_details( const char* dir, const char* name )
+file_details( const char* d, const char* name )
{
- struct stat sb;
- char f_time[20];
+ struct stat sb2;
+ char timestr[16];
static char encname[1000];
static char buf[2000];
- (void) snprintf( buf, sizeof(buf), "%s/%s", dir, name );
- if ( lstat( buf, &sb ) < 0 )
+ (void) snprintf( buf, sizeof(buf), "%s/%s", d, name );
+ if ( lstat( buf, &sb2 ) < 0 )
return "???";
- (void) strftime( f_time, sizeof( f_time ), "%d%b%Y %H:%M", localtime( &sb.st_mtime ) );
+ (void) strftime( timestr, sizeof(timestr), "%d%b%Y %H:%M", localtime( &sb2.st_mtime ) );
strencode( encname, sizeof(encname), name );
(void) snprintf(
- buf, sizeof( buf ), "<A HREF=\"%s\">%-32.32s</A> %15s %14lld\n",
- encname, name, f_time, (int64_t) sb.st_size );
+ buf, sizeof( buf ), "<a href=\"%s\">%-32.32s</a> %15s %14lld\n",
+ encname, name, timestr, (long long) sb2.st_size );
return buf;
}
@@ -1952,7 +1981,7 @@ cgi_interpose_output( int rfd, int parse_headers )
size_t headers_size, headers_len;
char* headers;
char* br;
- int status;
+ int s;
char* title;
char* cp;
@@ -1983,22 +2012,22 @@ cgi_interpose_output( int rfd, int parse_headers )
return;
/* Figure out the status. */
- status = 200;
+ s = 200;
+ if ( ( cp = strstr( headers, "Location:" ) ) != (char*) 0 &&
+ cp < br &&
+ ( cp == headers || *(cp-1) == '\012' ) )
+ s = 302;
if ( ( cp = strstr( headers, "Status:" ) ) != (char*) 0 &&
cp < br &&
( cp == headers || *(cp-1) == '\012' ) )
{
cp += 7;
cp += strspn( cp, " \t" );
- status = atoi( cp );
+ s = atoi( cp );
}
- if ( ( cp = strstr( headers, "Location:" ) ) != (char*) 0 &&
- cp < br &&
- ( cp == headers || *(cp-1) == '\012' ) )
- status = 302;
/* Write the status line. */
- switch ( status )
+ switch ( s )
{
case 200: title = "OK"; break;
case 302: title = "Found"; break;
@@ -2008,13 +2037,14 @@ cgi_interpose_output( int rfd, int parse_headers )
case 403: title = "Forbidden"; break;
case 404: title = "Not Found"; break;
case 408: title = "Request Timeout"; break;
+ case 451: title = "Unavailable For Legal Reasons"; break;
case 500: title = "Internal Error"; break;
case 501: title = "Not Implemented"; break;
case 503: title = "Service Temporarily Overloaded"; break;
default: title = "Something"; break;
}
(void) snprintf(
- buf, sizeof(buf), "HTTP/1.0 %d %s\015\012", status, title );
+ buf, sizeof(buf), "HTTP/1.0 %d %s\015\012", s, title );
(void) my_write( buf, strlen( buf ) );
/* Write the saved headers. */
@@ -2122,10 +2152,12 @@ make_envp( void )
envp[envn++] = build_env( "PATH=%s", CGI_PATH );
envp[envn++] = build_env( "LD_LIBRARY_PATH=%s", CGI_LD_LIBRARY_PATH );
envp[envn++] = build_env( "SERVER_SOFTWARE=%s", SERVER_SOFTWARE );
- if ( ! vhost )
- cp = hostname;
- else
+ if ( vhost && req_hostname != (char*) 0 && req_hostname[0] != '\0' )
cp = req_hostname; /* already computed by virtual_file() */
+ else if ( host != (char*) 0 && host[0] != '\0' )
+ cp = host;
+ else
+ cp = hostname;
if ( cp != (char*) 0 )
envp[envn++] = build_env( "SERVER_NAME=%s", cp );
envp[envn++] = "GATEWAY_INTERFACE=CGI/1.1";
@@ -2144,8 +2176,11 @@ make_envp( void )
if ( query[0] != '\0' )
envp[envn++] = build_env( "QUERY_STRING=%s", query );
envp[envn++] = build_env( "REMOTE_ADDR=%s", ntoa( &client_addr ) );
- if ( referer[0] != '\0' )
- envp[envn++] = build_env( "HTTP_REFERER=%s", referer );
+ if ( referrer[0] != '\0' )
+ {
+ envp[envn++] = build_env( "HTTP_REFERER=%s", referrer );
+ envp[envn++] = build_env( "HTTP_REFERRER=%s", referrer );
+ }
if ( useragent[0] != '\0' )
envp[envn++] = build_env( "HTTP_USER_AGENT=%s", useragent );
if ( cookie != (char*) 0 )
@@ -2204,7 +2239,7 @@ static void
auth_check( char* dirname )
{
char authpath[10000];
- struct stat sb;
+ struct stat sb2;
char authinfo[500];
char* authpass;
char* colon;
@@ -2220,7 +2255,7 @@ auth_check( char* dirname )
(void) snprintf( authpath, sizeof(authpath), "%s/%s", dirname, AUTH_FILE );
/* Does this directory have an auth file? */
- if ( stat( authpath, &sb ) < 0 )
+ if ( stat( authpath, &sb2 ) < 0 )
/* Nope, let the request go through. */
return;
@@ -2307,7 +2342,7 @@ send_authenticate( char* realm )
static char*
-virtual_file( char* file )
+virtual_file( char* f )
{
char* cp;
static char vfile[10000];
@@ -2318,7 +2353,7 @@ virtual_file( char* file )
else
{
usockaddr usa;
- int sz = sizeof(usa);
+ socklen_t sz = sizeof(usa);
if ( getsockname( conn_fd, &usa.sa, &sz ) < 0 )
req_hostname = "UNKNOWN_HOST";
else
@@ -2328,7 +2363,7 @@ virtual_file( char* file )
for ( cp = req_hostname; *cp != '\0'; ++cp )
if ( isupper( *cp ) )
*cp = tolower( *cp );
- (void) snprintf( vfile, sizeof(vfile), "%s/%s", req_hostname, file );
+ (void) snprintf( vfile, sizeof(vfile), "%s/%s", req_hostname, f );
return vfile;
}
@@ -2378,10 +2413,18 @@ send_error_body( int s, char* title, char* text )
/* Send built-in error page. */
buflen = snprintf(
buf, sizeof(buf), "\
-<HTML>\n\
-<HEAD><TITLE>%d %s</TITLE></HEAD>\n\
-<BODY BGCOLOR=\"#cc9999\" TEXT=\"#000000\" LINK=\"#2020ff\" VLINK=\"#4040cc\">\n\
-<H4>%d %s</H4>\n",
+<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n\
+\n\
+<html>\n\
+\n\
+ <head>\n\
+ <meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\">\n\
+ <title>%d %s</title>\n\
+ </head>\n\
+\n\
+ <body bgcolor=\"#cc9999\" text=\"#000000\" link=\"#2020ff\" vlink=\"#4040cc\">\n\
+\n\
+ <h4>%d %s</h4>\n",
s, title, s, title );
add_to_response( buf, buflen );
buflen = snprintf( buf, sizeof(buf), "%s\n", text );
@@ -2432,10 +2475,13 @@ send_error_tail( void )
}
buflen = snprintf( buf, sizeof(buf), "\
-<HR>\n\
-<ADDRESS><A HREF=\"%s\">%s</A></ADDRESS>\n\
-</BODY>\n\
-</HTML>\n",
+ <hr>\n\
+\n\
+ <address><a href=\"%s\">%s</a></address>\n\
+\n\
+ </body>\n\
+\n\
+</html>\n",
SERVER_URL, SERVER_SOFTWARE );
add_to_response( buf, buflen );
}
@@ -2487,7 +2533,7 @@ add_headers( int s, char* title, char* extra_header, char* me, char* mt, off_t b
if ( bytes >= 0 )
{
buflen = snprintf(
- buf, sizeof(buf), "Content-Length: %lld\015\012", (int64_t) bytes );
+ buf, sizeof(buf), "Content-Length: %lld\015\012", (long long) bytes );
add_to_response( buf, buflen );
}
if ( p3p != (char*) 0 && p3p[0] != '\0' )
@@ -2580,31 +2626,59 @@ send_response( void )
static void
send_via_write( int fd, off_t size )
{
+ /* On some systems an off_t is 64 bits while a size_t is still only
+ ** 32 bits. The mmap() system call takes a size_t as the length argument,
+ ** so we can only use mmap() if the size will fit into a size_t.
+ */
if ( size <= SIZE_T_MAX )
{
size_t size_size = (size_t) size;
- void* ptr = mmap( 0, size_size, PROT_READ, MAP_PRIVATE, fd, 0 );
- if ( ptr != (void*) -1 )
+ unsigned char* ptr = mmap( 0, size_size, PROT_READ, MAP_PRIVATE, fd, 0 );
+ if ( ptr != (unsigned char*) -1 )
{
- (void) my_write( ptr, size_size );
- (void) munmap( ptr, size_size );
- }
+ unsigned char* p = ptr;
+ size_t remaining_size = size_size;
#ifdef MADV_SEQUENTIAL
- /* If we have madvise, might as well call it. Although sequential
- ** access is probably already the default.
- */
- (void) madvise( ptr, size_size, MADV_SEQUENTIAL );
+ /* If we have madvise, might as well call it. Although sequential
+ ** access is probably already the default.
+ */
+ (void) madvise( ptr, size_size, MADV_SEQUENTIAL );
#endif /* MADV_SEQUENTIAL */
+ /* We could send the whole file in a single write, but if
+ ** it's huge then we run the risk of hitting the timeout.
+ ** So we do a loop writing large segments, and reseting the
+ ** timeout each time through.
+ */
+ while ( remaining_size > 0 )
+ {
+ size_t buf_size = MIN( remaining_size, MAX_SEND_BUFFER_SIZE );
+ ssize_t r = my_write( p, buf_size );
+ if ( r < 0 && ( errno == EINTR || errno == EAGAIN ) )
+ {
+ sleep( 1 );
+ continue;
+ }
+ if ( r != buf_size )
+ return;
+ remaining_size -= r;
+ p += r;
+ (void) alarm( WRITE_TIMEOUT );
+ }
+ (void) munmap( ptr, size_size );
+ }
}
else
{
- /* mmap can't deal with files larger than 2GB. */
+ /* The file is too big for mmap, so we'll send it via read & write
+ ** instead. This would be less efficient for small files because
+ ** it bypasses the buffer cache, but with a file this huge the
+ ** cache will get blown anyway.
+ */
char buf[30000];
- ssize_t r, r2;
for (;;)
{
- r = read( fd, buf, sizeof(buf) );
+ ssize_t r = read( fd, buf, sizeof(buf) );
if ( r < 0 && ( errno == EINTR || errno == EAGAIN ) )
{
sleep( 1 );
@@ -2614,7 +2688,7 @@ send_via_write( int fd, off_t size )
return;
for (;;)
{
- r2 = my_write( buf, r );
+ ssize_t r2 = my_write( buf, r );
if ( r2 < 0 && ( errno == EINTR || errno == EAGAIN ) )
{
sleep( 1 );
@@ -2629,6 +2703,37 @@ send_via_write( int fd, off_t size )
}
+static void
+send_via_sendfile( int fd, int s, off_t size )
+ {
+ /* We could send the whole file in a single sendfile, but if
+ ** it's huge then we run the risk of hitting the timeout.
+ ** So we do a loop writing large segments, and reseting the
+ ** timeout each time through.
+ **
+ ** This also avoids the problem of using sendfile on a file larger
+ ** than 2GB, since each segment size will now fit into a size_t.
+ */
+ off_t remaining_size = size;
+ off_t off = 0;
+ while ( remaining_size > 0 )
+ {
+ size_t buf_size = MIN( remaining_size, MAX_SEND_BUFFER_SIZE );
+ ssize_t r = my_sendfile( fd, s, off, buf_size );
+ if ( r < 0 && ( errno == EINTR || errno == EAGAIN ) )
+ {
+ sleep( 1 );
+ continue;
+ }
+ if ( r != buf_size )
+ return;
+ remaining_size -= r;
+ off += r;
+ (void) alarm( WRITE_TIMEOUT );
+ }
+ }
+
+
static ssize_t
my_read( char* buf, size_t size )
{
@@ -2644,7 +2749,7 @@ my_read( char* buf, size_t size )
static ssize_t
-my_write( char* buf, size_t size )
+my_write( void* buf, size_t size )
{
#ifdef USE_SSL
if ( do_ssl )
@@ -2659,13 +2764,13 @@ my_write( char* buf, size_t size )
#ifdef HAVE_SENDFILE
static int
-my_sendfile( int fd, int socket, off_t offset, size_t nbytes )
+my_sendfile( int fd, int s, off_t offset, size_t nbytes )
{
#ifdef HAVE_LINUX_SENDFILE
off_t lo = offset;
- return sendfile( socket, fd, &lo, nbytes );
+ return sendfile( s, fd, &lo, nbytes );
#else /* HAVE_LINUX_SENDFILE */
- return sendfile( fd, socket, offset, nbytes, (struct sf_hdtr*) 0, (off_t*) 0, 0 );
+ return sendfile( fd, s, offset, nbytes, (struct sf_hdtr*) 0, (off_t*) 0, 0 );
#endif /* HAVE_LINUX_SENDFILE */
}
#endif /* HAVE_SENDFILE */
@@ -2733,7 +2838,7 @@ make_log_entry( void )
/* Format the bytes. */
if ( bytes >= 0 )
(void) snprintf(
- bytes_str, sizeof(bytes_str), "%lld", (int64_t) bytes );
+ bytes_str, sizeof(bytes_str), "%lld", (long long) bytes );
else
(void) strcpy( bytes_str, "-" );
/* Format the time, forcing a numeric timezone (some log analyzers
@@ -2760,7 +2865,7 @@ make_log_entry( void )
(void) fprintf( logfp,
"%.80s - %.80s [%s] \"%.80s %.200s %.80s\" %d %s \"%.200s\" \"%.200s\"\n",
ntoa( &client_addr ), ru, date, get_method_str( method ), url,
- protocol, status, bytes_str, referer, useragent );
+ protocol, status, bytes_str, referrer, useragent );
(void) fflush( logfp );
}
@@ -2769,16 +2874,16 @@ make_log_entry( void )
** and exits.
*/
static void
-check_referer( void )
+check_referrer( void )
{
char* cp;
- /* Are we doing referer checking at all? */
+ /* Are we doing referrer checking at all? */
if ( url_pattern == (char*) 0 )
return;
/* Is it ok? */
- if ( really_check_referer() )
+ if ( really_check_referrer() )
return;
/* Lose. */
@@ -2789,15 +2894,15 @@ check_referer( void )
if ( cp == (char*) 0 )
cp = "";
syslog(
- LOG_INFO, "%.80s non-local referer \"%.80s%.80s\" \"%.80s\"",
- ntoa( &client_addr ), cp, path, referer );
- send_error( 403, "Forbidden", "", "You must supply a local referer." );
+ LOG_INFO, "%.80s non-local referrer \"%.80s%.80s\" \"%.80s\"",
+ ntoa( &client_addr ), cp, path, referrer );
+ send_error( 403, "Forbidden", "", "You must supply a local referrer." );
}
/* Returns 1 if ok to serve the url, 0 if not. */
static int
-really_check_referer( void )
+really_check_referrer( void )
{
char* cp1;
char* cp2;
@@ -2805,18 +2910,18 @@ really_check_referer( void )
char* refhost;
char *lp;
- /* Check for an empty referer. */
- if ( referer == (char*) 0 || referer[0] == '\0' ||
- ( cp1 = strstr( referer, "//" ) ) == (char*) 0 )
+ /* Check for an empty referrer. */
+ if ( referrer == (char*) 0 || referrer[0] == '\0' ||
+ ( cp1 = strstr( referrer, "//" ) ) == (char*) 0 )
{
- /* Disallow if we require a referer and the url matches. */
- if ( no_empty_referers && match( url_pattern, path ) )
+ /* Disallow if we require a referrer and the url matches. */
+ if ( no_empty_referrers && match( url_pattern, path ) )
return 0;
/* Otherwise ok. */
return 1;
}
- /* Extract referer host. */
+ /* Extract referrer host. */
cp1 += 2;
for ( cp2 = cp1; *cp2 != '/' && *cp2 != ':' && *cp2 != '\0'; ++cp2 )
continue;
@@ -2856,7 +2961,7 @@ really_check_referer( void )
}
}
- /* If the referer host doesn't match the local host pattern, and
+ /* If the referrer host doesn't match the local host pattern, and
** the URL does match the url pattern, it's an illegal reference.
*/
if ( ! match( lp, refhost ) && match( url_pattern, path ) )
@@ -2895,13 +3000,13 @@ static struct mime_entry typ_tab[] = {
static const int n_typ_tab = sizeof(typ_tab) / sizeof(*typ_tab);
-/* qsort comparison routine - declared old-style on purpose, for portability. */
+/* qsort comparison routine */
static int
-ext_compare( a, b )
- struct mime_entry* a;
- struct mime_entry* b;
+ext_compare( const void* v1, const void* v2 )
{
- return strcmp( a->ext, b->ext );
+ const struct mime_entry* m1 = (const struct mime_entry*) v1;
+ const struct mime_entry* m2 = (const struct mime_entry*) v2;
+ return strcmp( m1->ext, m2->ext );
}
@@ -3065,7 +3170,7 @@ handle_sigchld( int sig )
{
const int oerrno = errno;
pid_t pid;
- int status;
+ int s;
#ifndef HAVE_SIGSET
/* Set up handler again. */
@@ -3076,9 +3181,9 @@ handle_sigchld( int sig )
for (;;)
{
#ifdef HAVE_WAITPID
- pid = waitpid( (pid_t) -1, &status, WNOHANG );
+ pid = waitpid( (pid_t) -1, &s, WNOHANG );
#else /* HAVE_WAITPID */
- pid = wait3( &status, WNOHANG, (struct rusage*) 0 );
+ pid = wait3( &s, WNOHANG, (struct rusage*) 0 );
#endif /* HAVE_WAITPID */
if ( (int) pid == 0 ) /* none left */
break;
@@ -3422,7 +3527,7 @@ b64_decode( const char* str, unsigned char* space, int size )
phase = 0;
for ( cp = str; *cp != '\0'; ++cp )
{
- d = b64_decode_table[(int) *cp];
+ d = b64_decode_table[(int) ((unsigned char) *cp)];
if ( d != -1 )
{
switch ( phase )
diff --git a/port.h b/port.h
index ac57d2c..7d451a9 100644
--- a/port.h
+++ b/port.h
@@ -37,6 +37,7 @@
# define HAVE_SENDFILE
# define HAVE_SCANDIR
# define HAVE_INT64T
+# define HAVE_SRANDOMDEV
# ifdef SO_ACCEPTFILTER
# define HAVE_ACCEPT_FILTERS
# if ( __FreeBSD_version >= 411000 )
@@ -86,6 +87,7 @@
# define HAVE_MEMORY_H
# define HAVE_SIGSET
# define HAVE_INT64T
+# define HAVE_RAND
#endif /* OS_Solaris */
#ifdef OS_DigitalUnix
@@ -103,4 +105,10 @@
# define HAVE_WAITPID
# define HAVE_MEMORY_H
# define HAVE_SIGSET
+# define HAVE_RAND
#endif /* OS_Solaris */
+
+#ifdef HAVE_RAND
+# define srandom srand
+# define random rand
+#endif /* HAVE_RAND */
diff --git a/scripts/500.mini_httpd-rotate b/scripts/500.mini_httpd-rotate
index 5af4573..ccce57e 100755
--- a/scripts/500.mini_httpd-rotate
+++ b/scripts/500.mini_httpd-rotate
@@ -6,12 +6,14 @@
# tells mini_httpd to re-open its log file.
cd /usr/local/www/chroot/logs
-rm -f mini_httpd_log.7
-mv mini_httpd_log.6 mini_httpd_log.7
-mv mini_httpd_log.5 mini_httpd_log.6
-mv mini_httpd_log.4 mini_httpd_log.5
-mv mini_httpd_log.3 mini_httpd_log.4
-mv mini_httpd_log.2 mini_httpd_log.3
-mv mini_httpd_log.1 mini_httpd_log.2
+rm -f mini_httpd_log.7.gz
+mv mini_httpd_log.6.gz mini_httpd_log.7.gz
+mv mini_httpd_log.5.gz mini_httpd_log.6.gz
+mv mini_httpd_log.4.gz mini_httpd_log.5.gz
+mv mini_httpd_log.3.gz mini_httpd_log.4.gz
+mv mini_httpd_log.2.gz mini_httpd_log.3.gz
+mv mini_httpd_log.1.gz mini_httpd_log.2.gz
mv mini_httpd_log mini_httpd_log.1
kill -HUP `cat /var/run/mini_httpd.pid`
+sleep 1
+gzip -f mini_httpd_log.1
diff --git a/scripts/mini_httpd.sh b/scripts/mini_httpd.sh
index 0dde12e..372ecee 100755
--- a/scripts/mini_httpd.sh
+++ b/scripts/mini_httpd.sh
@@ -3,23 +3,46 @@
# mini_httpd.sh - startup script for mini_httpd on FreeBSD
#
# This goes in /usr/local/etc/rc.d and gets run at boot-time.
+#
+# Variables available:
+# mini_httpd_enable='YES/NO'
+# mini_httpd_program='path'
+# mini_httpd_pidfile='path'
+# mini_httpd_devfs='path'
+#
+# PROVIDE: mini_httpd
+# REQUIRE: LOGIN FILESYSTEMS
+# KEYWORD: shutdown
+
+. /etc/rc.subr
+
+name='mini_httpd'
+rcvar='mini_httpd_enable'
+
+load_rc_config "$name"
-case "$1" in
-
- start)
- if [ -x /usr/local/sbin/mini_httpd_wrapper ] ; then
- echo -n " mini_httpd"
- /usr/local/sbin/mini_httpd_wrapper &
+# Defaults.
+mini_httpd_enable="${mini_httpd_enable:-'NO'}"
+mini_httpd_program="${mini_httpd_program:-'/usr/local/sbin/mini_httpd'}"
+mini_httpd_pidfile="${mini_httpd_pidfile:-'/var/run/mini_httpd.pid'}"
+
+mini_httpd_precmd ()
+ {
+ if [ '' != "$mini_httpd_devfs" ] ; then
+ mount -t devfs devfs "$mini_httpd_devfs"
+ devfs -m "$mini_httpd_devfs" rule -s 1 applyset
+ devfs -m "$mini_httpd_devfs" rule -s 2 applyset
fi
- ;;
-
- stop)
- kill -USR1 `cat /var/run/mini_httpd.pid`
- ;;
-
- *)
- echo "usage: $0 { start | stop }" >&2
- exit 1
- ;;
-
-esac
+ }
+
+mini_httpd_stop ()
+ {
+ kill -USR1 `cat "$pidfile"`
+ }
+
+command="$mini_httpd_program"
+pidfile="$mini_httpd_pidfile"
+start_precmd='mini_httpd_precmd'
+stop_cmd='mini_httpd_stop'
+
+run_rc_command "$1"
diff --git a/scripts/mini_httpd_wrapper b/scripts/mini_httpd_wrapper
index d197d79..9980a11 100755
--- a/scripts/mini_httpd_wrapper
+++ b/scripts/mini_httpd_wrapper
@@ -2,20 +2,23 @@
#
# mini_httpd_wrapper - wrapper script for mini_httpd on FreeBSD
#
-# This goes in /usr/local/sbin. It runs mini_httpd in a loop. If mini_httpd
-# exits then the script restarts it automatically.
+# This goes in /usr/local/sbin. It backgrounds itself, and then runs
+# mini_httpd in a loop. If mini_httpd exits then the script restarts
+# it automatically.
#
# The -D flag tells mini_httpd to *not* put itself into the background,
# and the -C flag tells it to get the rest of its configuration from
# the specified config file.
-while true ; do
- /usr/local/sbin/mini_httpd -D -C /usr/local/www/mini_httpd_config
- if [ -f /var/run/nologin ] ; then
- exit
- fi
- sleep 10
- egrep ' mini_httpd\[' /var/log/messages |
- tail -33 |
- mail -s "mini_httpd on `hostname` restarted" root
-done
+(
+ while true ; do
+ /usr/local/sbin/mini_httpd -D -C /usr/local/www/mini_httpd_config
+ if [ -f /var/run/nologin ] ; then
+ exit
+ fi
+ sleep 10
+ egrep ' mini_httpd[:\[]' /var/log/messages |
+ tail -33 |
+ mail -s "mini_httpd on `hostname` restarted" root
+ done
+) &
diff --git a/tdate_parse.c b/tdate_parse.c
index ac9d2ca..a7ea7fa 100644
--- a/tdate_parse.c
+++ b/tdate_parse.c
@@ -59,12 +59,13 @@ pound_case( char* str )
}
}
+
static int
-strlong_compare( v1, v2 )
- char* v1;
- char* v2;
+strlong_compare( const void* v1, const void* v2 )
{
- return strcmp( ((struct strlong*) v1)->s, ((struct strlong*) v2)->s );
+ const struct strlong* s1 = (const struct strlong*) v1;
+ const struct strlong* s2 = (const struct strlong*) v2;
+ return strcmp( s1->s, s2->s );
}
@@ -170,7 +171,7 @@ tm_to_time( struct tm* tmP )
/* Years since epoch, converted to days. */
t = ( tmP->tm_year - 70 ) * 365;
- /* Leap days for previous years. */
+ /* Leap days for previous years - this will break in 2100! */
t += ( tmP->tm_year - 69 ) / 4;
/* Days for the beginning of this month. */
t += monthtab[tmP->tm_mon];
diff --git a/tdate_parse.h b/tdate_parse.h
index b4c5720..aaf0b66 100644
--- a/tdate_parse.h
+++ b/tdate_parse.h
@@ -28,6 +28,6 @@
#ifndef _TDATE_PARSE_H_
#define _TDATE_PARSE_H_
-extern time_t tdate_parse( char* str );
+time_t tdate_parse( char* str );
#endif /* _TDATE_PARSE_H_ */
diff --git a/version.h b/version.h
index 36e606e..b94e6a9 100644
--- a/version.h
+++ b/version.h
@@ -3,7 +3,7 @@
#ifndef _VERSION_H_
#define _VERSION_H_
-#define SERVER_SOFTWARE "mini_httpd/1.19 19dec2003"
+#define SERVER_SOFTWARE "mini_httpd/1.21 18oct2014"
#define SERVER_URL "http://www.acme.com/software/mini_httpd/"
#endif /* _VERSION_H_ */