Re: khttpd rotten?

Christoph Hellwig (hch@infradead.org)
Mon, 6 May 2002 11:23:00 +0100


On Sun, May 05, 2002 at 07:39:42PM -0700, Dan Kegel wrote:
> > We are going to pull it from the kernel.
>
> Right. If khttpd had been pulled from 2.4.17, I would have
> had weeks of warning that khttpd is unstable; instead, I learned
> only when someone started doing his own stress testing, and I
> have little time to fix it. I say pull it from
> 2.4.19-pre9. Marcello, put it out of its misery asap, please...
> it'd time for khttpd to become a standalone patch again.

Okay, what about the following:

- the below patch remove khttpd from 2.4.19-pre, but lets the
sysctls in so it can compile out-of-tree
- http://verein.lst.de/~hch/khttpd/khttpd-20020506.tar.gz has a tarball
with khttpd as of 2.4.19-pre8, a simple makefile to build it and
a simple patch to allow loading it when CONFIG_IPV6 != m,
Arjan, could you please put it on the official khttpd website if one
still exists.
- for 2.5 the sysctls can go aswell

diff -uNr -Xdontdiff linux-2.4.19-pre8/Documentation/Configure.help linux/Documentation/Configure.help
--- linux-2.4.19-pre8/Documentation/Configure.help Fri May 3 23:02:47 2002
+++ linux/Documentation/Configure.help Mon May 6 13:05:24 2002
@@ -5406,25 +5406,6 @@
say Y to "Kernel/User network link driver" and to "Routing
messages" instead.

-Kernel httpd acceleration
-CONFIG_KHTTPD
- The kernel httpd acceleration daemon (kHTTPd) is a (limited) web
- server built into the kernel. It is limited since it can only serve
- files from the file system and cannot deal with executable content
- such as CGI scripts. Serving files is sped up if you use kHTTPd.
- If kHTTPd is not able to fulfill a request, it can transparently
- pass it through to a user space web server such as apache.
-
- Saying "M" here builds the kHTTPd module; this is NOT enough to have
- a working kHTTPd. For safety reasons, the module has to be activated
- by doing a "echo 1 > /proc/sys/net/khttpd/start" after inserting the
- module.
-
- Before using this, read the README in net/khttpd !
-
- The kHTTPd is experimental. Be careful when using it on a production
- machine. Also note that kHTTPd doesn't support virtual servers yet.
-
The IPX protocol
CONFIG_IPX
This is support for the Novell networking protocol, IPX, commonly
@@ -25233,7 +25214,7 @@
# LocalWords: Unixware cymru Computone IntelliPort Intelliport computone SI sx
# LocalWords: adbmouse DRI DRM dlabs GMX PLCs Applicom fieldbus applicom int
# LocalWords: VWSND eg ESSSOLO CFU CFNR scribed eiconctrl eicon hylafax KFPU
-# LocalWords: EXTRAPREC fpu mainboards KHTTPD kHTTPd khttpd Xcelerator SBNI tw
+# LocalWords: EXTRAPREC fpu mainboards Xcelerator SBNI tw
# LocalWords: LOGIBUSMOUSE Granch granch sbni Raylink NOHIGHMEM Athlon SIM sim
# LocalWords: hpl Tourrilhes DuraLAN starfire Davicom davicom dmfe auk tms tr
# LocalWords: TokenExpress Belkin Peracom eTek DVDs infradead Cxxx Adlib AV ZX
diff -uNr -Xdontdiff linux-2.4.19-pre8/Makefile linux/Makefile
--- linux-2.4.19-pre8/Makefile Fri May 3 23:02:46 2002
+++ linux/Makefile Mon May 6 13:05:36 2002
@@ -214,8 +214,6 @@
drivers/scsi/aic7xxx/aicasm/aicdb.h \
drivers/scsi/aic7xxx/aicasm/y.tab.h \
drivers/scsi/53c700_d.h \
- net/khttpd/make_times_h \
- net/khttpd/times.h \
submenu*
# directories removed with 'make clean'
CLEAN_DIRS = \
diff -uNr -Xdontdiff linux-2.4.19-pre8/include/linux/sysctl.h linux/include/linux/sysctl.h
--- linux-2.4.19-pre8/include/linux/sysctl.h Fri May 3 23:02:46 2002
+++ linux/include/linux/sysctl.h Mon May 6 13:06:25 2002
@@ -487,6 +487,8 @@
};

/* /proc/sys/net/khttpd/ */
+/* khttpd has been removed from the main kernel.
+ please keep this to allow out-of-tree compilation for 2.4. --hch */
enum {
NET_KHTTPD_DOCROOT = 1,
NET_KHTTPD_START = 2,
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/Config.in linux/net/Config.in
--- linux-2.4.19-pre8/net/Config.in Fri May 3 13:36:27 2002
+++ linux/net/Config.in Mon May 6 12:54:18 2002
@@ -26,9 +26,6 @@
source net/ipv6/Config.in
fi
fi
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- source net/khttpd/Config.in
- fi
fi
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool 'Asynchronous Transfer Mode (ATM) (EXPERIMENTAL)' CONFIG_ATM
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/Makefile linux/net/Makefile
--- linux-2.4.19-pre8/net/Makefile Fri May 3 13:37:42 2002
+++ linux/net/Makefile Mon May 6 12:54:10 2002
@@ -26,7 +26,6 @@
endif
endif

-subdir-$(CONFIG_KHTTPD) += khttpd
subdir-$(CONFIG_PACKET) += packet
subdir-$(CONFIG_NET_SCHED) += sched
subdir-$(CONFIG_BRIDGE) += bridge
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/Config.in linux/net/khttpd/Config.in
--- linux-2.4.19-pre8/net/khttpd/Config.in Fri May 3 13:36:06 2002
+++ linux/net/khttpd/Config.in Thu Jan 1 01:00:00 1970
@@ -1,4 +0,0 @@
-#
-# kHTTPd
-#
-tristate ' Kernel httpd acceleration (EXPERIMENTAL)' CONFIG_KHTTPD
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/Makefile linux/net/khttpd/Makefile
--- linux-2.4.19-pre8/net/khttpd/Makefile Fri May 3 13:38:44 2002
+++ linux/net/khttpd/Makefile Thu Jan 1 01:00:00 1970
@@ -1,25 +0,0 @@
-#
-# Makefile for kHTTPd
-#
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
-
-O_TARGET := khttpd.o
-
-obj-m := $(O_TARGET)
-obj-y := main.o accept.o datasending.o logging.o misc.o rfc.o rfc_time.o security.o \
- sockets.o sysctl.o userspace.o waitheaders.o
-
-
-include $(TOPDIR)/Rules.make
-
-rfc_time.o: times.h
-
-make_times_h: make_times_h.c
- $(HOSTCC) $(HOSTCFLAGS) -o make_times_h make_times_h.c
-
-times.h: make_times_h
- ./make_times_h
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/README linux/net/khttpd/README
--- linux-2.4.19-pre8/net/khttpd/README Fri May 3 13:35:57 2002
+++ linux/net/khttpd/README Thu Jan 1 01:00:00 1970
@@ -1,224 +0,0 @@
-=====
-
-kHTTPd - Kernel httpd accelerator
-
-(C) 1999 by Arjan van de Ven
-Licensed under the terms of the GNU General Public License
-
-=====
-
-
-1. Introduction
----------------
- kHTTPd is a http-daemon (webserver) for Linux. kHTTPd is different from
- other webservers in that it runs from within the Linux-kernel as a module
- (device-driver).
-
- kHTTPd handles only static (file based) web-pages, and passes all requests
- for non-static information to a regular userspace-webserver such as Apache or
- Zeus. The userspace-daemon doesn't have to be altered in any way.
-
- Static web-pages are not a very complex thing to serve, but these are very
- important nevertheless, since virtually all images are static, and a large
- portion of the html-pages are static also. A "regular" webserver has little
- added value for static pages, it is simply a "copy file to network"-operation.
- This can be done very efficiently from within the Linux-kernel, for example
- the nfs (network file system) daemon performs a similar task and also runs
- in the kernel.
-
- By "accelerating" the simple case within the kernel, userspace daemons can
- do what they are very good at: Generating user-specific, dynamic content.
-
- Note: This document sometimes uses "Apache" instead of "any webserver you
- ever might want to use", just for reasons of readability.
-
-
-2. Quick Start
---------------
-
- 1) compile and load the module
- 2) configure the module in /proc/sys/net/khttpd if needed
- 3) echo 1 > /proc/sys/net/khttpd/start
-
- unloading:
-
- echo 1 > /proc/sys/net/khttpd/stop
- echo 1 > /proc/sys/net/khttpd/unload
- rmmod khttpd
-
-
-
-3. Configuration
-----------------
-
- Modes of operation
- ==================
-
-
- There are two recommended modes of operation:
-
- 1) "Apache" is main webserver, kHTTPd is assistant
- clientport -> 80
- serverport -> 8080 (or whatever)
-
- 2) kHTTPd is main webserver, "Apache" is assistant
- clientport -> 8080 (or whatever)
- serverport -> 80
-
-
- Configuring kHTTPd
- ==================
-
- Before you can start using kHTTPd, you have to configure it. This
- is done through the /proc filesystem, and can thus be done from inside
- a script. Most parameters can only be set when kHTTPd is not active.
-
- The following things need configuration:
-
- 1) The port where kHTTPd should listen for requests
- 2) The port (on "localhost") where "Apache" is listening
- 3) The location of the documents (documentroot)
- 4) The strings that indicate dynamic content (optional)
- [ "cgi-bin" is added by default ]
-
- It is very important that the documentroot for kHTTPd matches the
- documentroot for the userspace-daemon, as kHTTPd might "redirect"
- any request to this userspace-daemon.
-
- A typical script (for the first mode of operation) to do this would
- look like:
-
-#!/bin/sh
-modprobe khttpd
-echo 80 > /proc/sys/net/khttpd/clientport
-echo 8080 > /proc/sys/net/khttpd/serverport
-echo /var/www > /proc/sys/net/khttpd/documentroot
-echo php3 > /proc/sys/net/khttpd/dynamic
-echo shtml > /proc/sys/net/khttpd/dynamic
-echo 1 > /proc/sys/net/khttpd/start
-
- For the second mode of operation, this would be:
-
-#!/bin/sh
-modprobe khttpd
-echo 8080 > /proc/sys/net/khttpd/clientport
-echo 80 > /proc/sys/net/khttpd/serverport
-echo /var/www > /proc/sys/net/khttpd/documentroot
-echo php3 > /proc/sys/net/khttpd/dynamic
-echo shtml > /proc/sys/net/khttpd/dynamic
-echo 1 > /proc/sys/net/khttpd/start
-
- In this case, you also have to change the configuration of the
- userspace-daemon. For Apache, you do this by changing
-
- Port 80
-
- to
-
- Port 8080
-
-
-
- Stopping kHTTPd
- ===============
- In order to change the configuration, you should stop kHTTPd by typing
- echo 1 > /proc/sys/net/khttpd/stop
- on a command-prompt.
-
- If you want to unload the module, you should type
- echo 1 > /proc/sys/net/khttpd/unload
- after stopping kHTTPd first.
-
- If this doesn't work fast enough for you (the commands above can wait for
- a remote connection to close down), you can send the daemons a "HUP"
- signal after you told them to stop. This will cause the daemon-threads to
- stop immediately.
-
- Note that the daemons will restart immediately if they are not told to
- stop.
-
-
-
-4. Permissions
---------------
- The security model of kHTTPd is very strict. It can be, since there is a
- userspace daemon that can handle the complex exceptions.
-
- kHTTPd only serves a file if
-
- 1) There is no "?" in the URL
- 2) The URL starts with a "/"
- 3) The file indicated by the URL exists
- 4) The file is world-readable (*)
- 5) The file is not a directory, executable or has the Sticky-bit
- set (*)
- 6) The URL doesn't contain any "forbidden" substrings such as ".."
- and "cgi-bin" (*)
- 7) The mime-type is known (*)
-
- The items marked with a (*) are configurable through the
- sysctl-parameters in /proc/sys/net/khttpd.
-
-
- In all cases where any of the above conditions isn't met, the
- userspace-daemon is handed the request.
-
-
-
-5. Parameters
--------------
- The following parameters are settable through /proc/sys/net/khttpd:
-
- Name Default Description
-
- serverport 8080 The port where kHTTPd listens on
-
- clientport 80 The port of the userspace
- http-daemon
-
- threads 2 The number of server-threads. Should
- be 1 per CPU for small websites, 2
- per CPU for big (the active files
- do not fit in the RAM) websites.
-
- documentroot /var/www the directory where the
- document-files are
-
- start 0 Set to 1 to start kHTTPd
- (this also resets "stop" to 0)
-
- stop 0 Set to 1 to stop kHTTPd
- (this also resets "start" to 0)
-
- unload 0 Set to 1 to prepare kHTTPd for
- unloading of the module
-
- sloppymime 0 If set to 1, unknown mime-types are
- set to text/html. If set to 0,
- files with unknown mime-types are
- handled by the userspace daemon
-
- perm_required S_IROTH Minimum permissions required
- (for values see "man 2 stat")
-
- perm_forbid dir+sticky+ Permission-mask with "forbidden"
- execute permissions.
- (for values see "man 2 stat")
-
- dynamic cgi-bin .. Strings that, if they are a subset
- of the URL, indicate "dynamic
- content"
-
- maxconnect 1000 Maximum number of concurrent
- connections
-
-6. More information
--------------------
- More information about the architecture of kHTTPd, the mailinglist and
- configuration-examples can be found at the kHTTPd homepage:
-
- http://www.fenrus.demon.nl
-
- Bugreports, patches, etc can be send to the mailinglist
- (khttpd-users@zgp.org) or to khttpd@fenrus.demon.nl
-
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/accept.c linux/net/khttpd/accept.c
--- linux-2.4.19-pre8/net/khttpd/accept.c Fri May 3 13:35:46 2002
+++ linux/net/khttpd/accept.c Thu Jan 1 01:00:00 1970
@@ -1,127 +0,0 @@
-/*
-
-kHTTPd -- the next generation
-
-Accept connections
-
-*/
-/****************************************************************
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ****************************************************************/
-
-#include "structure.h"
-#include "prototypes.h"
-#include "sysctl.h"
-
-#include <linux/smp_lock.h>
-
-/*
-
-Purpose:
-
-AcceptConnections puts all "accepted" connections in the
-"WaitForHeader" queue.
-
-Return value:
- The number of accepted connections
-*/
-
-
-int AcceptConnections(const int CPUNR, struct socket *Socket)
-{
- struct http_request *NewRequest;
- struct socket *NewSock;
- int count = 0;
- int error;
-
- EnterFunction("AcceptConnections");
-
- if (atomic_read(&ConnectCount)>sysctl_khttpd_maxconnect)
- {
- LeaveFunction("AcceptConnections - to many active connections");
- return 0;
- }
-
- if (Socket==NULL) return 0;
-
- /*
- Quick test to see if there are connections on the queue.
- This is cheaper than accept() itself because this saves us
- the allocation of a new socket. (Which doesn't seem to be
- used anyway)
- */
- if (Socket->sk->tp_pinfo.af_tcp.accept_queue==NULL)
- {
- return 0;
- }
-
- error = 0;
- while (error>=0)
- {
- NewSock = sock_alloc();
- if (NewSock==NULL)
- break;
-
-
- NewSock->type = Socket->type;
- NewSock->ops = Socket->ops;
-
-
- error = Socket->ops->accept(Socket,NewSock,O_NONBLOCK);
-
-
- if (error<0)
- {
- sock_release(NewSock);
- break;
- }
-
- if (NewSock->sk->state==TCP_CLOSE)
- {
- sock_release(NewSock);
- continue;
- }
-
- /* Allocate a request-entry for the connection */
- NewRequest = kmalloc(sizeof(struct http_request),(int)GFP_KERNEL);
-
- if (NewRequest == NULL)
- {
- Send50x(NewSock); /* Service not available. Try again later */
- sock_release(NewSock);
- break;
- }
- memset(NewRequest,0,sizeof(struct http_request));
-
- NewRequest->sock = NewSock;
-
- NewRequest->Next = threadinfo[CPUNR].WaitForHeaderQueue;
-
- init_waitqueue_entry(&NewRequest->sleep,current);
-
- add_wait_queue(NewSock->sk->sleep,&(NewRequest->sleep));
-
- threadinfo[CPUNR].WaitForHeaderQueue = NewRequest;
-
- atomic_inc(&ConnectCount);
-
-
- count++;
- }
-
- LeaveFunction("AcceptConnections");
- return count;
-}
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/datasending.c linux/net/khttpd/datasending.c
--- linux-2.4.19-pre8/net/khttpd/datasending.c Fri May 3 13:36:56 2002
+++ linux/net/khttpd/datasending.c Thu Jan 1 01:00:00 1970
@@ -1,241 +0,0 @@
-/*
-
-kHTTPd -- the next generation
-
-Send actual file-data to the connections
-
-*/
-/****************************************************************
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ****************************************************************/
-
-/*
-
-Purpose:
-
-DataSending does the actual sending of file-data to the socket.
-
-Note: Since asynchronous reads do not -yet- exists, this might block!
-
-Return value:
- The number of requests that changed status (ie: made some progress)
-*/
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/locks.h>
-#include <linux/skbuff.h>
-
-#include <net/tcp.h>
-
-#include <asm/uaccess.h>
-#include <linux/smp_lock.h>
-
-#include "structure.h"
-#include "prototypes.h"
-
-static char *Block[CONFIG_KHTTPD_NUMCPU];
-
-/*
-
-This send_actor is for use with do_generic_file_read (ie sendfile())
-It sends the data to the socket indicated by desc->buf.
-
-*/
-static int sock_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size)
-{
- int written;
- char *kaddr;
- unsigned long count = desc->count;
- struct socket *sock = (struct socket *) desc->buf;
- mm_segment_t old_fs;
-
- if (size > count)
- size = count;
- old_fs = get_fs();
- set_fs(KERNEL_DS);
-
- kaddr = kmap(page);
- written = SendBuffer_async(sock, kaddr + offset, size);
- kunmap(page);
- set_fs(old_fs);
- if (written < 0) {
- desc->error = written;
- written = 0;
- }
- desc->count = count - written;
- desc->written += written;
- return written;
-}
-
-
-
-
-int DataSending(const int CPUNR)
-{
- struct http_request *CurrentRequest,**Prev;
- int count = 0;
-
- EnterFunction("DataSending");
-
- Prev = &(threadinfo[CPUNR].DataSendingQueue);
- CurrentRequest = threadinfo[CPUNR].DataSendingQueue;
- while (CurrentRequest!=NULL)
- {
- int ReadSize,Space;
- int retval;
-
-
- /* First, test if the socket has any buffer-space left.
- If not, no need to actually try to send something. */
-
-
- Space = sock_wspace(CurrentRequest->sock->sk);
-
- ReadSize = min_t(int, 4 * 4096, CurrentRequest->FileLength - CurrentRequest->BytesSent);
- ReadSize = min_t(int, ReadSize, Space);
-
- if (ReadSize>0)
- {
- struct inode *inode;
-
- inode = CurrentRequest->filp->f_dentry->d_inode;
-
- if (inode->i_mapping->a_ops->readpage) {
- /* This does the actual transfer using sendfile */
- read_descriptor_t desc;
- loff_t *ppos;
-
- CurrentRequest->filp->f_pos = CurrentRequest->BytesSent;
-
- ppos = &CurrentRequest->filp->f_pos;
-
- desc.written = 0;
- desc.count = ReadSize;
- desc.buf = (char *) CurrentRequest->sock;
- desc.error = 0;
- do_generic_file_read(CurrentRequest->filp, ppos, &desc, sock_send_actor);
- if (desc.written>0)
- {
- CurrentRequest->BytesSent += desc.written;
- count++;
- }
- }
- else /* FS doesn't support sendfile() */
- {
- mm_segment_t oldfs;
- CurrentRequest->filp->f_pos = CurrentRequest->BytesSent;
-
- oldfs = get_fs(); set_fs(KERNEL_DS);
- retval = CurrentRequest->filp->f_op->read(CurrentRequest->filp, Block[CPUNR], ReadSize, &CurrentRequest->filp->f_pos);
- set_fs(oldfs);
-
- if (retval>0)
- {
- retval = SendBuffer_async(CurrentRequest->sock,Block[CPUNR],(size_t)retval);
- if (retval>0)
- {
- CurrentRequest->BytesSent += retval;
- count++;
- }
- }
- }
-
- }
-
- /*
- If end-of-file or closed connection: Finish this request
- by moving it to the "logging" queue.
- */
- if ((CurrentRequest->BytesSent>=CurrentRequest->FileLength)||
- (CurrentRequest->sock->sk->state!=TCP_ESTABLISHED
- && CurrentRequest->sock->sk->state!=TCP_CLOSE_WAIT))
- {
- struct http_request *Next;
- Next = CurrentRequest->Next;
-
- lock_sock(CurrentRequest->sock->sk);
- if (CurrentRequest->sock->sk->state == TCP_ESTABLISHED ||
- CurrentRequest->sock->sk->state == TCP_CLOSE_WAIT)
- {
- CurrentRequest->sock->sk->tp_pinfo.af_tcp.nonagle = 0;
- tcp_push_pending_frames(CurrentRequest->sock->sk,&(CurrentRequest->sock->sk->tp_pinfo.af_tcp));
- }
- release_sock(CurrentRequest->sock->sk);
-
- (*Prev) = CurrentRequest->Next;
-
- CurrentRequest->Next = threadinfo[CPUNR].LoggingQueue;
- threadinfo[CPUNR].LoggingQueue = CurrentRequest;
-
- CurrentRequest = Next;
- continue;
-
- }
-
-
- Prev = &(CurrentRequest->Next);
- CurrentRequest = CurrentRequest->Next;
- }
-
- LeaveFunction("DataSending");
- return count;
-}
-
-int InitDataSending(int ThreadCount)
-{
- int I,I2;
-
- EnterFunction("InitDataSending");
- I=0;
- while (I<ThreadCount)
- {
- Block[I] = (char*)get_free_page((int)GFP_KERNEL);
- if (Block[I] == NULL)
- {
- I2=0;
- while (I2<I-1)
- {
- free_page((unsigned long)Block[I2++]);
- }
- LeaveFunction("InitDataSending - abort");
- return -1;
- }
- I++;
- }
- LeaveFunction("InitDataSending");
- return 0;
-}
-
-void StopDataSending(const int CPUNR)
-{
- struct http_request *CurrentRequest,*Next;
-
- EnterFunction("StopDataSending");
- CurrentRequest = threadinfo[CPUNR].DataSendingQueue;
-
- while (CurrentRequest!=NULL)
- {
- Next = CurrentRequest->Next;
- CleanUpRequest(CurrentRequest);
- CurrentRequest=Next;
- }
-
- threadinfo[CPUNR].DataSendingQueue = NULL;
-
- free_page( (unsigned long)Block[CPUNR]);
- LeaveFunction("StopDataSending");
-}
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/logging.c linux/net/khttpd/logging.c
--- linux-2.4.19-pre8/net/khttpd/logging.c Fri May 3 13:36:20 2002
+++ linux/net/khttpd/logging.c Thu Jan 1 01:00:00 1970
@@ -1,95 +0,0 @@
-/*
-
-kHTTPd -- the next generation
-
-logging.c takes care of shutting down a connection.
-
-*/
-/****************************************************************
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ****************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/skbuff.h>
-#include <linux/smp_lock.h>
-#include <net/tcp.h>
-#include <asm/uaccess.h>
-#include "structure.h"
-#include "prototypes.h"
-
-/*
-
-Purpose:
-
-Logging() terminates "finished" connections and will eventually log them to a
-userspace daemon.
-
-Return value:
- The number of requests that changed status, thus the number of connections
- that shut down.
-*/
-
-
-int Logging(const int CPUNR)
-{
- struct http_request *CurrentRequest,*Req;
- int count = 0;
-
- EnterFunction("Logging");
-
- CurrentRequest = threadinfo[CPUNR].LoggingQueue;
-
- /* For now, all requests are removed immediatly, but this changes
- when userspace-logging is added. */
-
- while (CurrentRequest!=NULL)
- {
-
- Req = CurrentRequest->Next;
-
- CleanUpRequest(CurrentRequest);
-
- threadinfo[CPUNR].LoggingQueue = Req;
-
- CurrentRequest = Req;
-
- count++;
-
- }
-
- LeaveFunction("Logging");
- return count;
-}
-
-
-
-void StopLogging(const int CPUNR)
-{
- struct http_request *CurrentRequest,*Next;
-
- EnterFunction("StopLogging");
- CurrentRequest = threadinfo[CPUNR].LoggingQueue;
-
- while (CurrentRequest!=NULL)
- {
- Next=CurrentRequest->Next;
- CleanUpRequest(CurrentRequest);
- CurrentRequest=Next;
- }
-
- threadinfo[CPUNR].LoggingQueue = NULL;
- LeaveFunction("StopLogging");
-}
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/main.c linux/net/khttpd/main.c
--- linux-2.4.19-pre8/net/khttpd/main.c Fri May 3 13:35:12 2002
+++ linux/net/khttpd/main.c Thu Jan 1 01:00:00 1970
@@ -1,394 +0,0 @@
-/*
-
-kHTTPd -- the next generation
-
-Main program
-
-
-kHTTPd TNG consists of 1 thread, this main-thread handles ALL connections
-simultanious. It does this by keeping queues with the requests in different
-stages.
-
-The stages are
-
-<not accepted> - TCP/IP connection is not accepted yet
-WaitForHeaders - Connection is accepted, waiting for headers
-DataSending - Headers decoded, sending file-data
-Userspace - Requires userspace daemon
-Logging - The request is finished, cleanup and logging
-
-A typical flow for a request would be:
-
-<not accepted>
-WaitForHeaders
-DataSending
-Logging
-
-or
-
-<not accepted>
-WaitForHeaders
-Userspace
-
-
-
-*/
-/****************************************************************
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ****************************************************************/
-
-
-static int errno;
-#define __KERNEL_SYSCALLS__
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/init.h>
-#include <linux/wait.h>
-#include <linux/smp_lock.h>
-#include <asm/unistd.h>
-
-#include "structure.h"
-#include "prototypes.h"
-#include "sysctl.h"
-
-struct khttpd_threadinfo threadinfo[CONFIG_KHTTPD_NUMCPU]; /* The actual work-queues */
-
-
-atomic_t ConnectCount;
-atomic_t DaemonCount;
-
-static int ActualThreads; /* The number of actual, active threads */
-
-
-static int ConnectionsPending(int CPUNR)
-{
- if (threadinfo[CPUNR].DataSendingQueue!=NULL) return O_NONBLOCK;
- if (threadinfo[CPUNR].WaitForHeaderQueue!=NULL) return O_NONBLOCK;
- if (threadinfo[CPUNR].LoggingQueue!=NULL) return O_NONBLOCK;
- if (threadinfo[CPUNR].UserspaceQueue!=NULL) return O_NONBLOCK;
- return 0;
-}
-
-
-
-static wait_queue_head_t DummyWQ[CONFIG_KHTTPD_NUMCPU];
-static atomic_t Running[CONFIG_KHTTPD_NUMCPU];
-
-static int MainDaemon(void *cpu_pointer)
-{
- int CPUNR;
- sigset_t tmpsig;
-
- DECLARE_WAITQUEUE(main_wait,current);
-
- MOD_INC_USE_COUNT;
-
-
- CPUNR=0;
- if (cpu_pointer!=NULL)
- CPUNR=(int)*(int*)cpu_pointer;
-
- sprintf(current->comm,"khttpd - %i",CPUNR);
- daemonize();
-
- init_waitqueue_head(&(DummyWQ[CPUNR]));
-
-
- /* Block all signals except SIGKILL, SIGSTOP and SIGHUP */
- spin_lock_irq(&current->sigmask_lock);
- tmpsig = current->blocked;
- siginitsetinv(&current->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP)| sigmask(SIGHUP));
- recalc_sigpending(current);
- spin_unlock_irq(&current->sigmask_lock);
-
-
- if (MainSocket->sk==NULL)
- return 0;
- add_wait_queue_exclusive(MainSocket->sk->sleep,&(main_wait));
- atomic_inc(&DaemonCount);
- atomic_set(&Running[CPUNR],1);
-
- while (sysctl_khttpd_stop==0)
- {
- int changes = 0;
-
-
-
- changes +=AcceptConnections(CPUNR,MainSocket);
- if (ConnectionsPending(CPUNR))
- {
- changes +=WaitForHeaders(CPUNR);
- changes +=DataSending(CPUNR);
- changes +=Userspace(CPUNR);
- changes +=Logging(CPUNR);
- /* Test for incoming connections _again_, because it is possible
- one came in during the other steps, and the wakeup doesn't happen
- then.
- */
- changes +=AcceptConnections(CPUNR,MainSocket);
- }
-
- if (changes==0)
- {
- (void)interruptible_sleep_on_timeout(&(DummyWQ[CPUNR]),1);
- if (CPUNR==0)
- UpdateCurrentDate();
- }
-
- if (signal_pending(current)!=0)
- {
- (void)printk(KERN_NOTICE "kHTTPd: Ring Ring - signal received\n");
- break;
- }
-
- }
-
- remove_wait_queue(MainSocket->sk->sleep,&(main_wait));
-
- StopWaitingForHeaders(CPUNR);
- StopDataSending(CPUNR);
- StopUserspace(CPUNR);
- StopLogging(CPUNR);
-
- atomic_set(&Running[CPUNR],0);
- atomic_dec(&DaemonCount);
- (void)printk(KERN_NOTICE "kHTTPd: Daemon %i has ended\n",CPUNR);
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-static int CountBuf[CONFIG_KHTTPD_NUMCPU];
-
-
-
-/*
-
-The ManagementDaemon has a very simple task: Start the real daemons when the user wants us
-to, and cleanup when the users wants to unload the module.
-
-Initially, kHTTPd didn't have this thread, but it is the only way to have "delayed activation",
-a feature required to prevent accidental activations resulting in unexpected backdoors.
-
-*/
-static int ManagementDaemon(void *unused)
-{
- sigset_t tmpsig;
- int waitpid_result;
-
- DECLARE_WAIT_QUEUE_HEAD(WQ);
-
-
- sprintf(current->comm,"khttpd manager");
- daemonize();
-
-
- /* Block all signals except SIGKILL and SIGSTOP */
- spin_lock_irq(&current->sigmask_lock);
- tmpsig = current->blocked;
- siginitsetinv(&current->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP) );
- recalc_sigpending(current);
- spin_unlock_irq(&current->sigmask_lock);
-
-
- /* main loop */
- while (sysctl_khttpd_unload==0)
- {
- int I;
-
-
- /* First : wait for activation */
-
- sysctl_khttpd_start = 0;
-
- while ( (sysctl_khttpd_start==0) && (!signal_pending(current)) && (sysctl_khttpd_unload==0) )
- {
- current->state = TASK_INTERRUPTIBLE;
- interruptible_sleep_on_timeout(&WQ,HZ);
- }
-
- if ( (signal_pending(current)) || (sysctl_khttpd_unload!=0) )
- break;
-
- /* Then start listening and spawn the daemons */
-
- if (StartListening(sysctl_khttpd_serverport)==0)
- {
- continue;
- }
-
- ActualThreads = sysctl_khttpd_threads;
- if (ActualThreads<1)
- ActualThreads = 1;
-
- if (ActualThreads>CONFIG_KHTTPD_NUMCPU)
- ActualThreads = CONFIG_KHTTPD_NUMCPU;
-
- /* Write back the actual value */
-
- sysctl_khttpd_threads = ActualThreads;
-
- InitUserspace(ActualThreads);
-
- if (InitDataSending(ActualThreads)!=0)
- {
- StopListening();
- continue;
- }
- if (InitWaitHeaders(ActualThreads)!=0)
- {
- I=0;
- while (I<ActualThreads)
- {
- StopDataSending(I);
- I++;
- }
- StopListening();
- continue;
- }
-
- /* Clean all queues */
- memset(threadinfo, 0, sizeof(struct khttpd_threadinfo));
-
-
-
- I=0;
- while (I<ActualThreads)
- {
- atomic_set(&Running[I],1);
- (void)kernel_thread(MainDaemon,&(CountBuf[I]), CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
- I++;
- }
-
- /* Then wait for deactivation */
- sysctl_khttpd_stop = 0;
-
- while ( (sysctl_khttpd_stop==0) && (!signal_pending(current)) && (sysctl_khttpd_unload==0) )
- {
- if (atomic_read(&DaemonCount)<ActualThreads)
- {
- I=0;
- while (I<ActualThreads)
- {
- if (atomic_read(&Running[I])==0)
- {
- atomic_set(&Running[I],1);
- (void)kernel_thread(MainDaemon,&(CountBuf[I]), CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
- (void)printk(KERN_CRIT "kHTTPd: Restarting daemon %i \n",I);
- }
- I++;
- }
- }
- interruptible_sleep_on_timeout(&WQ,HZ);
-
- /* reap the daemons */
- waitpid_result = waitpid(-1,NULL,__WCLONE|WNOHANG);
-
- }
-
-
- /* The user wants us to stop. So stop listening on the socket. */
- if (sysctl_khttpd_stop!=0)
- {
- /* Wait for the daemons to stop, one second per iteration */
- while (atomic_read(&DaemonCount)>0)
- interruptible_sleep_on_timeout(&WQ,HZ);
- StopListening();
- }
-
-
-
- }
-
- sysctl_khttpd_stop = 1;
-
- /* Wait for the daemons to stop, one second per iteration */
- while (atomic_read(&DaemonCount)>0)
- interruptible_sleep_on_timeout(&WQ,HZ);
-
-
- waitpid_result = 1;
- /* reap the zombie-daemons */
- while (waitpid_result>0)
- waitpid_result = waitpid(-1,NULL,__WCLONE|WNOHANG);
-
- StopListening();
-
-
- (void)printk(KERN_NOTICE "kHTTPd: Management daemon stopped. \n You can unload the module now.\n");
-
- MOD_DEC_USE_COUNT;
-
- return 0;
-}
-
-int __init khttpd_init(void)
-{
- int I;
-
- MOD_INC_USE_COUNT;
-
- I=0;
- while (I<CONFIG_KHTTPD_NUMCPU)
- {
- CountBuf[I]=I;
-
- I++;
- }
-
- atomic_set(&ConnectCount,0);
- atomic_set(&DaemonCount,0);
-
-
- /* Maybe the mime-types will be set-able through sysctl in the future */
-
- AddMimeType(".htm","text/html");
- AddMimeType("html","text/html");
- AddMimeType(".gif","image/gif");
- AddMimeType(".jpg","image/jpeg");
- AddMimeType(".png","image/png");
- AddMimeType("tiff","image/tiff");
- AddMimeType(".zip","application/zip");
- AddMimeType(".pdf","application/pdf");
- AddMimeType("r.gz","application/x-gtar");
- AddMimeType(".tgz","application/x-gtar");
- AddMimeType(".deb","application/x-debian-package");
- AddMimeType("lass","application/x-java");
- AddMimeType(".mp3","audio/mpeg");
- AddMimeType(".txt","text/plain");
-
- AddDynamicString("..");
- AddDynamicString("cgi-bin");
-
- StartSysctl();
-
- (void)kernel_thread(ManagementDaemon,NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-
- return 0;
-}
-
-void khttpd_cleanup(void)
-{
- EndSysctl();
-}
-
- module_init(khttpd_init)
- module_exit(khttpd_cleanup)
-
- MODULE_LICENSE("GPL");
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/make_times_h.c linux/net/khttpd/make_times_h.c
--- linux-2.4.19-pre8/net/khttpd/make_times_h.c Fri May 3 13:36:34 2002
+++ linux/net/khttpd/make_times_h.c Thu Jan 1 01:00:00 1970
@@ -1,122 +0,0 @@
-/*
-
-This program generates the "times.h" file with the zulu-times of the first of
-every month of a decade.
-
-*/
-/****************************************************************
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ****************************************************************/
-
-#include <time.h>
-#include <stdio.h>
-
-static time_t GetDay(int D,int M,int Y)
-{
- struct tm TM;
-
- TM.tm_sec = 0;
- TM.tm_min = 0;
- TM.tm_hour = 0;
- TM.tm_mday = D;
- TM.tm_mon = M;
- TM.tm_wday = 0;
- TM.tm_yday = 0;
- TM.tm_year = Y-1900;
- TM.tm_isdst = 0;
-
- return mktime(&TM);
-
-}
-static int WeekGetDay(int D,int M,int Y)
-{
- struct tm TM;
-
- TM.tm_sec = 0;
- TM.tm_min = 0;
- TM.tm_hour = 0;
- TM.tm_mday = D;
- TM.tm_mon = M;
- TM.tm_year = Y-1900;
- TM.tm_isdst = 0;
- TM.tm_wday = 0;
- TM.tm_yday = 0;
-
- (void)mktime(&TM);
-
- return TM.tm_wday;
-
-}
-
-int main(void)
-{
- int M,Y;
- FILE *file;
-
- file=fopen("times.h","w");
-
- if (file==NULL)
- return 0;
-
- fprintf(file,"static time_t TimeDays[10][13] = { \n");
-
- Y=1997;
- while (Y<2007)
- {
- M=0;
- fprintf(file," { ");
- while (M<12)
- {
- fprintf(file,"%i",(int)GetDay(1,M,Y));
- fprintf(file,",\t");
-
- M++;
- }
-
- fprintf(file,"%i } ",(int)GetDay(1,0,Y+1));
- if (Y!=2006) fprintf(file,",");
- fprintf(file,"\n");
- Y++;
- }
- fprintf(file,"};\n");
-
- fprintf(file,"static int WeekDays[10][13] = { \n");
-
- Y=1997;
- while (Y<2007)
- {
- M=0;
- fprintf(file," { ");
- while (M<12)
- {
- fprintf(file,"%i",(int)WeekGetDay(1,M,Y));
- fprintf(file,",\t");
-
- M++;
- }
-
- fprintf(file,"%i } ",(int)WeekGetDay(1,0,Y+1));
- if (Y!=2006) fprintf(file,",");
- fprintf(file,"\n");
- Y++;
- }
- fprintf(file,"};\n");
- fprintf(file,"#define KHTTPD_YEAROFFSET 1997\n");
- fprintf(file,"#define KHTTPD_NUMYEARS 10\n");
- (void)fclose(file);
-
- return 0;
-}
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/misc.c linux/net/khttpd/misc.c
--- linux-2.4.19-pre8/net/khttpd/misc.c Fri May 3 13:37:41 2002
+++ linux/net/khttpd/misc.c Thu Jan 1 01:00:00 1970
@@ -1,242 +0,0 @@
-/*
-
-kHTTPd -- the next generation
-
-General functions
-
-*/
-/****************************************************************
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ****************************************************************/
-
-#include <linux/kernel.h>
-
-#include <linux/ctype.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/net.h>
-#include <linux/sched.h>
-#include <linux/skbuff.h>
-#include <linux/unistd.h>
-#include <linux/file.h>
-#include <linux/smp_lock.h>
-
-#include <net/ip.h>
-#include <net/sock.h>
-
-#include <asm/atomic.h>
-#include <asm/errno.h>
-#include <asm/semaphore.h>
-#include <asm/processor.h>
-#include <asm/uaccess.h>
-
-#include "structure.h"
-#include "prototypes.h"
-
-#ifndef ECONNRESET
-#define ECONNRESET 102
-#endif
-
-
-/*
-
-Readrest reads and discards all pending input on a socket. This is required
-before closing the socket.
-
-*/
-static void ReadRest(struct socket *sock)
-{
- struct msghdr msg;
- struct iovec iov;
- int len;
-
- mm_segment_t oldfs;
-
-
- EnterFunction("ReadRest");
-
-
- if (sock->sk==NULL)
- return;
-
- len = 1;
-
- while (len>0)
- {
- static char Buffer[1024]; /* Never read, so doesn't need to
- be SMP safe */
-
- msg.msg_name = 0;
- msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- msg.msg_flags = MSG_DONTWAIT;
-
- msg.msg_iov->iov_base = &Buffer[0];
- msg.msg_iov->iov_len = (__kernel_size_t)1024;
-
- len = 0;
- oldfs = get_fs(); set_fs(KERNEL_DS);
- len = sock_recvmsg(sock,&msg,1024,MSG_DONTWAIT);
- set_fs(oldfs);
- }
- LeaveFunction("ReadRest");
-}
-
-
-/*
-
-CleanUpRequest takes care of shutting down the connection, closing the file-pointer
-and releasing the memory of the request-structure. Do not try to access it afterwards!
-
-*/
-void CleanUpRequest(struct http_request *Req)
-{
- EnterFunction("CleanUpRequest");
-
- /* Close the socket ....*/
- if ((Req->sock!=NULL)&&(Req->sock->sk!=NULL))
- {
- ReadRest(Req->sock);
- remove_wait_queue(Req->sock->sk->sleep,&(Req->sleep));
- sock_release(Req->sock);
- }
-
- /* ... and the file-pointer ... */
- if (Req->filp!=NULL)
- {
- fput(Req->filp);
- Req->filp = NULL;
- }
-
-
- /* ... and release the memory for the structure. */
- kfree(Req);
-
- atomic_dec(&ConnectCount);
- LeaveFunction("CleanUpRequest");
-}
-
-
-/*
-
-SendBuffer and Sendbuffer_async send "Length" bytes from "Buffer" to the "sock"et.
-The _async-version is non-blocking.
-
-A positive return-value indicates the number of bytes sent, a negative value indicates
-an error-condition.
-
-*/
-int SendBuffer(struct socket *sock, const char *Buffer,const size_t Length)
-{
- struct msghdr msg;
- mm_segment_t oldfs;
- struct iovec iov;
- int len;
-
- EnterFunction("SendBuffer");
-
- msg.msg_name = 0;
- msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- msg.msg_flags = MSG_NOSIGNAL;
- msg.msg_iov->iov_len = (__kernel_size_t)Length;
- msg.msg_iov->iov_base = (char*) Buffer;
-
-
- len = 0;
-
- oldfs = get_fs(); set_fs(KERNEL_DS);
- len = sock_sendmsg(sock,&msg,(size_t)(Length-len));
- set_fs(oldfs);
- LeaveFunction("SendBuffer");
- return len;
-}
-
-int SendBuffer_async(struct socket *sock, const char *Buffer,const size_t Length)
-{
- struct msghdr msg;
- mm_segment_t oldfs;
- struct iovec iov;
- int len;
-
- EnterFunction("SendBuffer_async");
- msg.msg_name = 0;
- msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- msg.msg_flags = MSG_DONTWAIT|MSG_NOSIGNAL;
- msg.msg_iov->iov_base = (char*) Buffer;
- msg.msg_iov->iov_len = (__kernel_size_t)Length;
-
-
- if (sock->sk)
- {
- oldfs = get_fs(); set_fs(KERNEL_DS);
- len = sock_sendmsg(sock,&msg,(size_t)(Length));
- set_fs(oldfs);
- } else
- {
- return -ECONNRESET;
- }
-
- LeaveFunction("SendBuffer_async");
- return len;
-}
-
-
-
-
-/*
-
-HTTP header shortcuts. Hardcoded since these might be called in a low-memory
-situation, and they don't change anyhow.
-
-*/
-
-static char NoPerm[] = "HTTP/1.0 403 Forbidden\r\nServer: kHTTPd 0.1.6\r\n\r\n";
-static char TryLater[] = "HTTP/1.0 503 Service Unavailable\r\nServer: kHTTPd 0.1.6\r\nContent-Length: 15\r\n\r\nTry again later";
-static char NotModified[] = "HTTP/1.0 304 Not Modified\r\nServer: kHTTPd 0.1.6\r\n\r\n";
-
-
-void Send403(struct socket *sock)
-{
- EnterFunction("Send403");
- (void)SendBuffer(sock,NoPerm,strlen(NoPerm));
- LeaveFunction("Send403");
-}
-
-void Send304(struct socket *sock)
-{
- EnterFunction("Send304");
- (void)SendBuffer(sock,NotModified,strlen(NotModified));
- LeaveFunction("Send304");
-}
-
-void Send50x(struct socket *sock)
-{
- EnterFunction("Send50x");
- (void)SendBuffer(sock,TryLater,strlen(TryLater));
- LeaveFunction("Send50x");
-}
-
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/prototypes.h linux/net/khttpd/prototypes.h
--- linux-2.4.19-pre8/net/khttpd/prototypes.h Fri May 3 13:38:39 2002
+++ linux/net/khttpd/prototypes.h Thu Jan 1 01:00:00 1970
@@ -1,120 +0,0 @@
-#ifndef _INCLUDE_GUARD_PROTOTYPES_H
-#define _INCLUDE_GUARD_PROTOTYPES_H
-
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/net.h>
-#include <linux/time.h>
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <net/sock.h>
-#include <asm/uaccess.h>
-
-#include "structure.h"
-
-
-/* General defines and stuff */
-
-
-#define CONFIG_KHTTPD_NUMCPU 16 /* Maximum number of threads */
-
-#ifdef OOPSTRACE
-#define EnterFunction(x) printk("Enter: %s, %s line %i\n",x,__FILE__,__LINE__)
-#define LeaveFunction(x) printk("Leave: %s, %s line %i\n",x,__FILE__,__LINE__)
-#else
-#define EnterFunction(x) do {} while (0)
-#define LeaveFunction(x) do {} while (0)
-#endif
-
-
-
-/* sockets.c */
-int StartListening(const int Port);
-void StopListening(void);
-
-extern struct socket *MainSocket;
-
-
-/* sysctl.c */
-void StartSysctl(void);
-void EndSysctl(void);
-
-extern int sysctl_khttpd_stop;
-
-
-/* main.c */
-
-
-extern struct khttpd_threadinfo threadinfo[CONFIG_KHTTPD_NUMCPU];
-extern char CurrentTime[];
-extern atomic_t ConnectCount;
-extern struct wait_queue main_wait[CONFIG_KHTTPD_NUMCPU];
-
-/* misc.c */
-
-void CleanUpRequest(struct http_request *Req);
-int SendBuffer(struct socket *sock, const char *Buffer,const size_t Length);
-int SendBuffer_async(struct socket *sock, const char *Buffer,const size_t Length);
-void Send403(struct socket *sock);
-void Send304(struct socket *sock);
-void Send50x(struct socket *sock);
-
-/* accept.c */
-
-int AcceptConnections(const int CPUNR,struct socket *Socket);
-
-/* waitheaders.c */
-
-int WaitForHeaders(const int CPUNR);
-void StopWaitingForHeaders(const int CPUNR);
-int InitWaitHeaders(int ThreadCount);
-
-/* datasending.c */
-
-int DataSending(const int CPUNR);
-void StopDataSending(const int CPUNR);
-int InitDataSending(int ThreadCount);
-
-
-/* userspace.c */
-
-int Userspace(const int CPUNR);
-void StopUserspace(const int CPUNR);
-void InitUserspace(const int CPUNR);
-
-
-/* rfc_time.c */
-
-void time_Unix2RFC(const time_t Zulu,char *Buffer);
-void UpdateCurrentDate(void);
-time_t mimeTime_to_UnixTime(char *Q);
-extern int CurrentTime_i;
-
-/* rfc.c */
-
-void ParseHeader(char *Buffer,const int length, struct http_request *Head);
-char *ResolveMimeType(const char *File,__kernel_size_t *Len);
-void AddMimeType(const char *Ident,const char *Type);
-void SendHTTPHeader(struct http_request *Request);
-
-
-
-/* security.c */
-
-struct file *OpenFileForSecurity(char *Filename);
-void AddDynamicString(const char *String);
-void GetSecureString(char *String);
-
-
-/* logging.c */
-
-int Logging(const int CPUNR);
-void StopLogging(const int CPUNR);
-
-
-/* Other prototypes */
-
-
-
-#endif
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/rfc.c linux/net/khttpd/rfc.c
--- linux-2.4.19-pre8/net/khttpd/rfc.c Fri May 3 13:37:47 2002
+++ linux/net/khttpd/rfc.c Thu Jan 1 01:00:00 1970
@@ -1,374 +0,0 @@
-/*
-
-kHTTPd -- the next generation
-
-RFC related functions (headers and stuff)
-
-*/
-
-/****************************************************************
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ****************************************************************/
-
-
-#include <linux/kernel.h>
-
-#include <linux/ctype.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/net.h>
-#include <linux/sched.h>
-#include <linux/skbuff.h>
-#include <linux/unistd.h>
-#include <linux/file.h>
-#include <linux/smp_lock.h>
-
-#include <net/ip.h>
-#include <net/sock.h>
-
-#include <asm/atomic.h>
-#include <asm/semaphore.h>
-#include <asm/processor.h>
-#include <asm/uaccess.h>
-
-
-#include "prototypes.h"
-#include "structure.h"
-#include "sysctl.h"
-
-
-#define KHTTPD_NUMMIMETYPES 40
-
-static atomic_t MimeCount;
-
-struct MimeType
-{
- __u32 identifier;
- char type[64-sizeof(__u32)-sizeof(__kernel_size_t)];
- __kernel_size_t len;
-};
-
-static struct MimeType MimeTypes[KHTTPD_NUMMIMETYPES];
-
-
-void AddMimeType(const char *Ident,const char *Type)
-{
- __u32 *I;
-
- EnterFunction("AddMimeType");
-
- if (strlen(Ident)!=4)
- {
- (void)printk(KERN_ERR "httpd: Only 4-byte mime-identifiers are accepted\n");
- return;
- }
-
- if (strlen(Type)>(64-sizeof(__u32)-sizeof(__kernel_size_t) ) )
- {
- (void)printk(KERN_ERR "httpd: Mime-string too long.\n");
- return;
- }
-
- I=(__u32*)Ident;
-
- /* FIXME: Need to lock-down all access to the mime-structure here */
- /* For now, just don't add mime-types after initialisation */
-
-
- MimeTypes[atomic_read(&MimeCount)].identifier=*I;
- strncpy(MimeTypes[atomic_read(&MimeCount)].type,Type,(64-sizeof(__u32)-sizeof(__kernel_size_t)));
- MimeTypes[atomic_read(&MimeCount)].len = strlen(Type);
-
- atomic_inc(&MimeCount);
- LeaveFunction("AddMimeType");
-}
-
-
-char *ResolveMimeType(const char *File,__kernel_size_t *Len)
-/*
-
- The returned string is for READ ONLY, ownership of the memory is NOT
- transferred.
-
-*/
-{
- __u32 *I;
- int pos,lc,filelen;
-
- EnterFunction("ResolveMimeType");
-
- *Len = 0;
-
- if (File==NULL)
- return NULL;
-
- filelen = (int)strlen(File);
-
- if (filelen<4)
- {
- return NULL;
- }
-
- /* The Merced-people are NOT going to like this! So this has to be fixed
- in a later stage. */
-
- pos = filelen-4;
- I=(__u32*)(File+pos);
-
- lc=0;
-
- while (lc<atomic_read(&MimeCount))
- {
- if (MimeTypes[lc].identifier == *I)
- {
- *Len = MimeTypes[lc].len;
- LeaveFunction("ResolveMimeType - success");
- return MimeTypes[lc].type;
- }
- lc++;
- }
-
- if (sysctl_khttpd_sloppymime)
- {
- *Len = MimeTypes[0].len;
- LeaveFunction("ResolveMimeType - unknown");
- return MimeTypes[0].type;
- }
- else
- {
- LeaveFunction("ResolveMimeType - failure");
- return NULL;
- }
-}
-
-
-static char HeaderPart1[] = "HTTP/1.0 200 OK\r\nServer: kHTTPd/0.1.6\r\nDate: ";
-#ifdef BENCHMARK
-static char HeaderPart1b[] ="HTTP/1.0 200 OK";
-#endif
-static char HeaderPart3[] = "\r\nContent-type: ";
-static char HeaderPart5[] = "\r\nLast-modified: ";
-static char HeaderPart7[] = "\r\nContent-length: ";
-static char HeaderPart9[] = "\r\n\r\n";
-
-#ifdef BENCHMARK
-/* In BENCHMARK-mode, just send the bare essentials */
-void SendHTTPHeader(struct http_request *Request)
-{
- struct msghdr msg;
- mm_segment_t oldfs;
- struct iovec iov[9];
- int len,len2;
-
-
- EnterFunction("SendHTTPHeader");
-
- msg.msg_name = 0;
- msg.msg_namelen = 0;
- msg.msg_iov = &iov[0];
- msg.msg_iovlen = 6;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- msg.msg_flags = 0; /* Synchronous for now */
-
- iov[0].iov_base = HeaderPart1b;
- iov[0].iov_len = 15;
- iov[1].iov_base = HeaderPart3;
- iov[1].iov_len = 16;
- iov[2].iov_base = Request->MimeType;
- iov[2].iov_len = Request->MimeLength;
-
- iov[3].iov_base = HeaderPart7;
- iov[3].iov_len = 18;
-
-
- sprintf(Request->LengthS,"%i",Request->FileLength);
- iov[4].iov_base = Request->LengthS;
- iov[4].iov_len = strlen(Request->LengthS);
- iov[5].iov_base = HeaderPart9;
- iov[5].iov_len = 4;
-
- len2=15+16+18+iov[2].iov_len+iov[4].iov_len+4;
-
-
- len = 0;
-
-
- oldfs = get_fs(); set_fs(KERNEL_DS);
- len = sock_sendmsg(Request->sock,&msg,len2);
- set_fs(oldfs);
-
-
- return;
-}
-#else
-void SendHTTPHeader(struct http_request *Request)
-{
- struct msghdr msg;
- mm_segment_t oldfs;
- struct iovec iov[9];
- int len,len2;
- __kernel_size_t slen;
-
- EnterFunction("SendHTTPHeader");
-
- msg.msg_name = 0;
- msg.msg_namelen = 0;
- msg.msg_iov = &(iov[0]);
- msg.msg_iovlen = 9;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- msg.msg_flags = 0; /* Synchronous for now */
-
- iov[0].iov_base = HeaderPart1;
- iov[0].iov_len = 45;
- iov[1].iov_base = CurrentTime;
- iov[1].iov_len = 29;
- iov[2].iov_base = HeaderPart3;
- iov[2].iov_len = 16;
-
- iov[3].iov_base = Request->MimeType;
- iov[3].iov_len = Request->MimeLength;
-
- iov[4].iov_base = HeaderPart5;
- iov[4].iov_len = 17;
- iov[5].iov_base = &(Request->TimeS[0]);
- iov[5].iov_len = 29;
- iov[6].iov_base = HeaderPart7;
- iov[6].iov_len = 18;
- iov[7].iov_base = &(Request->LengthS[0]);
- slen = strlen(Request->LengthS);
- iov[7].iov_len = slen;
- iov[8].iov_base = HeaderPart9;
- iov[8].iov_len = 4;
-
- len2=45+2*29+16+17+18+slen+4+iov[3].iov_len;
-
- len = 0;
-
- oldfs = get_fs(); set_fs(KERNEL_DS);
- len = sock_sendmsg(Request->sock,&msg,len2);
- set_fs(oldfs);
- LeaveFunction("SendHTTPHeader");
-
-
- return;
-}
-#endif
-
-
-
-/*
-
-Parse a HTTP-header. Be careful for buffer-overflows here, this is the most important
-place for this, since the remote-user controls the data.
-
-*/
-void ParseHeader(char *Buffer,const int length, struct http_request *Head)
-{
- char *Endval,*EOL,*tmp;
-
- EnterFunction("ParseHeader");
- Endval = Buffer + length;
-
- /* We want to parse only the first header if multiple headers are present */
- tmp = strstr(Buffer,"\r\n\r\n");
- if (tmp!=NULL)
- Endval = tmp;
-
-
- while (Buffer<Endval)
- {
- if (isspace(Buffer[0]))
- {
- Buffer++;
- continue;
- }
-
-
- EOL=strchr(Buffer,'\n');
-
- if (EOL==NULL) EOL=Endval;
-
- if (EOL-Buffer<4)
- {
- Buffer++;
- continue;
- }
-
- if (strncmp("GET ",Buffer,4)==0)
- {
- int PrefixLen;
- Buffer+=4;
-
- tmp=strchr(Buffer,' ');
- if (tmp==0)
- {
- tmp=EOL-1;
- Head->HTTPVER = 9;
- } else
- Head->HTTPVER = 10;
-
- if (tmp>Endval) continue;
-
- strncpy(Head->FileName,sysctl_khttpd_docroot,sizeof(Head->FileName));
- PrefixLen = strlen(sysctl_khttpd_docroot);
- Head->FileNameLength = min_t(unsigned int, 255, tmp - Buffer + PrefixLen);
-
- strncat(Head->FileName,Buffer,min_t(unsigned int, 255 - PrefixLen, tmp - Buffer));
-
- Buffer=EOL+1;
-#ifdef BENCHMARK
- break;
-#endif
- continue;
- }
-#ifndef BENCHMARK
- if (strncmp("If-Modified-Since: ",Buffer,19)==0)
- {
- Buffer+=19;
-
- strncpy(Head->IMS,Buffer,min_t(unsigned int, 127,EOL-Buffer-1));
-
- Buffer=EOL+1;
- continue;
- }
-
- if (strncmp("User-Agent: ",Buffer,12)==0)
- {
- Buffer+=12;
-
- strncpy(Head->Agent,Buffer,min_t(unsigned int, 127,EOL-Buffer-1));
-
- Buffer=EOL+1;
- continue;
- }
-
-
- if (strncmp("Host: ",Buffer,6)==0)
- {
- Buffer+=6;
-
- strncpy(Head->Host,Buffer,min_t(unsigned int, 127,EOL-Buffer-1));
-
- Buffer=EOL+1;
- continue;
- }
-#endif
- Buffer = EOL+1; /* Skip line */
- }
- LeaveFunction("ParseHeader");
-}
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/rfc_time.c linux/net/khttpd/rfc_time.c
--- linux-2.4.19-pre8/net/khttpd/rfc_time.c Fri May 3 13:35:37 2002
+++ linux/net/khttpd/rfc_time.c Thu Jan 1 01:00:00 1970
@@ -1,227 +0,0 @@
-/*
-
-Functions related to time:
-
-1) rfc (string) time to unix-time
-2) unix-time to rfc (string) time
-3) current time to rfc (string) time for the "Date:" header
-
-*/
-
-/****************************************************************
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ****************************************************************/
-
-#include <linux/time.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-
-
-#include "times.h"
-#include "prototypes.h"
-static char *dayName[7] = {
- "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
-};
-
-static char *monthName[12] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-
-char CurrentTime[64];
-int CurrentTime_i;
-
-
-static char itoa_h[60]={'0','0','0','0','0','0','0','0','0','0',
- '1','1','1','1','1','1','1','1','1','1',
- '2','2','2','2','2','2','2','2','2','2',
- '3','3','3','3','3','3','3','3','3','3',
- '4','4','4','4','4','4','4','4','4','4',
- '5','5','5','5','5','5','5','5','5','5'};
-
-static char itoa_l[60]={'0','1','2','3','4','5','6','7','8','9',
- '0','1','2','3','4','5','6','7','8','9',
- '0','1','2','3','4','5','6','7','8','9',
- '0','1','2','3','4','5','6','7','8','9',
- '0','1','2','3','4','5','6','7','8','9',
- '0','1','2','3','4','5','6','7','8','9'};
-void time_Unix2RFC(const time_t Zulu,char *Buffer)
-{
- int Y=0,M=0,D=0;
- int H=0,Min=0,S=0,WD=0;
- int I,I2;
- time_t rest;
-
-
-
- I=0;
- while (I<KHTTPD_NUMYEARS)
- {
- if (TimeDays[I][0]>Zulu)
- break;
- I++;
- }
-
- Y=--I;
- if (I<0)
- {
- Y=0;
- goto BuildYear;
- }
- I2=0;
- while (I2<=12)
- {
- if (TimeDays[I][I2]>Zulu)
- break;
- I2++;
- }
-
- M=I2-1;
-
- rest=Zulu - TimeDays[Y][M];
- WD=WeekDays[Y][M];
- D=rest/86400;
- rest=rest%86400;
- WD+=D;
- WD=WD%7;
- H=rest/3600;
- rest=rest%3600;
- Min=rest/60;
- rest=rest%60;
- S=rest;
-
-BuildYear:
- Y+=KHTTPD_YEAROFFSET;
-
-
- /* Format: Day, 01 Mon 1999 01:01:01 GMT */
-
-/*
- We want to do
-
- sprintf( Buffer, "%s, %02i %s %04i %02i:%02i:%02i GMT",
- dayName[ WD ], D+1, monthName[ M ], Y,
- H, Min, S
- );
-
- but this is very expensive. Since the string is fixed length,
- it is filled manually.
-*/
- Buffer[0]=dayName[WD][0];
- Buffer[1]=dayName[WD][1];
- Buffer[2]=dayName[WD][2];
- Buffer[3]=',';
- Buffer[4]=' ';
- Buffer[5]=itoa_h[D+1];
- Buffer[6]=itoa_l[D+1];
- Buffer[7]=' ';
- Buffer[8]=monthName[M][0];
- Buffer[9]=monthName[M][1];
- Buffer[10]=monthName[M][2];
- Buffer[11]=' ';
- Buffer[12]=itoa_l[Y/1000];
- Buffer[13]=itoa_l[(Y/100)%10];
- Buffer[14]=itoa_l[(Y/10)%10];
- Buffer[15]=itoa_l[Y%10];
- Buffer[16]=' ';
- Buffer[17]=itoa_h[H];
- Buffer[18]=itoa_l[H];
- Buffer[19]=':';
- Buffer[20]=itoa_h[Min];
- Buffer[21]=itoa_l[Min];
- Buffer[22]=':';
- Buffer[23]=itoa_h[S];
- Buffer[24]=itoa_l[S];
- Buffer[25]=' ';
- Buffer[26]='G';
- Buffer[27]='M';
- Buffer[28]='T';
- Buffer[29]=0;
-
-
-
-
-}
-
-void UpdateCurrentDate(void)
-{
- struct timeval tv;
-
- do_gettimeofday(&tv);
- if (CurrentTime_i!=tv.tv_sec)
- time_Unix2RFC(tv.tv_sec,CurrentTime);
-
- CurrentTime_i = tv.tv_sec;
-}
-
-static int MonthHash[32] = {0,0,7,0,0,0,0,0,0,0,0,3,0,0,0,2,6,0,5,0,9,8,4,0,0,11,1,10,0,0,0,0};
-
-#define is_digit(c) ((c) >= '0' && (c) <= '9')
-
-__inline static int skip_atoi(char **s)
-{
- int i=0;
-
- while (is_digit(**s))
- i = i*10 + *((*s)++) - '0';
- return i;
-}
-
-time_t mimeTime_to_UnixTime(char *Q)
-{
- int Y,M,D,H,Min,S;
- unsigned int Hash;
- time_t Temp;
- char *s,**s2;
-
- s=Q;
- s2=&s;
-
- if (strlen(s)<30) return 0;
- if (s[3]!=',') return 0;
- if (s[19]!=':') return 0;
-
- s+=5; /* Skip day of week */
- D = skip_atoi(s2); /* Day of month */
- s++;
- Hash = (unsigned char)s[0]+(unsigned char)s[2];
- Hash = (Hash<<1) + (unsigned char)s[1];
- Hash = (Hash&63)>>1;
- M = MonthHash[Hash];
- s+=4;
- Y = skip_atoi(s2); /* Year */
- s++;
- H = skip_atoi(s2); /* Hour */
- s++;
- Min = skip_atoi(s2); /* Minutes */
- s++;
- S = skip_atoi(s2); /* Seconds */
- s++;
- if ((s[0]!='G')||(s[1]!='M')||(s[2]!='T'))
- {
- return 0; /* No GMT */
- }
-
- if (Y<KHTTPD_YEAROFFSET) Y = KHTTPD_YEAROFFSET;
- if (Y>KHTTPD_YEAROFFSET+9) Y = KHTTPD_YEAROFFSET+9;
-
- Temp = TimeDays[Y-KHTTPD_YEAROFFSET][M];
- Temp += D*86400+H*3600+Min*60+S;
-
- return Temp;
-}
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/security.c linux/net/khttpd/security.c
--- linux-2.4.19-pre8/net/khttpd/security.c Fri May 3 13:35:31 2002
+++ linux/net/khttpd/security.c Thu Jan 1 01:00:00 1970
@@ -1,267 +0,0 @@
-/*
-
-kHTTPd -- the next generation
-
-Permissions/Security functions
-
-*/
-
-/****************************************************************
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ****************************************************************/
-
-
-#include <linux/kernel.h>
-
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/net.h>
-#include <linux/sched.h>
-#include <linux/skbuff.h>
-#include <linux/smp_lock.h>
-#include <linux/un.h>
-#include <linux/unistd.h>
-
-#include <net/ip.h>
-#include <net/sock.h>
-#include <net/tcp.h>
-
-#include <asm/atomic.h>
-#include <asm/semaphore.h>
-#include <asm/processor.h>
-#include <asm/uaccess.h>
-
-#include <linux/file.h>
-
-#include "sysctl.h"
-#include "security.h"
-#include "prototypes.h"
-
-/*
-
-The basic security function answers "Userspace" when any one of the following
-conditions is met:
-
-1) The filename contains a "?" (this is before % decoding, all others are
- after % decoding)
-2) The filename doesn't start with a "/"
-3) The file does not exist
-4) The file does not have enough permissions
- (sysctl-configurable, default = worldreadble)
-5) The file has any of the "forbidden" permissions
- (sysctl-configurable, default = execute, directory and sticky)
-6) The filename contains a string as defined in the "Dynamic" list.
-
-*/
-
-
-/* Prototypes */
-
-static void DecodeHexChars(char *URL);
-static struct DynamicString *DynamicList=NULL;
-
-
-
-/*
-
-The function "OpenFileForSecurity" returns either the "struct file" pointer
-of the file, or NULL. NULL means "let userspace handle it".
-
-*/
-struct file *OpenFileForSecurity(char *Filename)
-{
- struct file *filp;
- struct DynamicString *List;
- umode_t permission;
-
-
-
- EnterFunction("OpenFileForSecurity");
- if (Filename==NULL)
- return NULL;
-
- if (strlen(Filename)>=256 ) return NULL; /* Sanity check */
-
- /* Rule no. 1 -- No "?" characters */
-#ifndef BENCHMARK
- if (strchr(Filename,'?')!=NULL)
- return NULL;
-
- /* Intermediate step: decode all %hex sequences */
-
- DecodeHexChars(Filename);
-
- /* Rule no. 2 -- Must start with a "/" */
-
-
- if (Filename[0]!='/')
- return NULL;
-
-#endif
- /* Rule no. 3 -- Does the file exist ? */
-
- filp = filp_open(Filename, O_RDONLY, 0);
-
- if (IS_ERR(filp))
- return NULL;
-
-#ifndef BENCHMARK
- permission = filp->f_dentry->d_inode->i_mode;
-
- /* Rule no. 4 : must have enough permissions */
-
-
- if ((permission & sysctl_khttpd_permreq)==0)
- {
- if (filp!=NULL)
- fput(filp);
- filp=NULL;
- return NULL;
- }
-
- /* Rule no. 5 : cannot have "forbidden" permission */
-
-
- if ((permission & sysctl_khttpd_permforbid)!=0)
- {
- if (filp!=NULL)
- fput(filp);
- filp=NULL;
- return NULL;
- }
-
- /* Rule no. 6 : No string in DynamicList can be a
- substring of the filename */
-
-
- List = DynamicList;
-
- while (List!=NULL)
- {
- if (strstr(Filename,List->value)!=NULL)
- {
- if (filp!=NULL)
- fput(filp);
- filp=NULL;
- return NULL;
- }
- List = List->Next;
- }
-
-#endif
- LeaveFunction("OpenFileForSecurity - success");
-
- return filp;
-}
-
-/*
-
-DecodeHexChars does the actual %HEX decoding, in place.
-In place is possible because strings only get shorter by this.
-
-*/
-static void DecodeHexChars(char *URL)
-{
- char *Source,*Dest;
- int val,val2;
-
- EnterFunction("DecodeHexChars");
-
- Source = strchr(URL,'%');
-
- if (Source==NULL)
- return;
-
- Dest = Source;
-
- while (*Source!=0)
- {
- if (*Source=='%')
- {
- Source++;
- val = *Source;
-
- if (val>'Z') val-=0x20;
- val = val - '0';
- if (val<0) val=0;
- if (val>9) val-=7;
- if (val>15) val=15;
-
- Source++;
-
- val2 = *Source;
-
- if (val2>'Z') val2-=0x20;
- val2 = val2 - '0';
- if (val2<0) val2=0;
- if (val2>9) val2-=7;
- if (val2>15) val2=15;
-
- *Dest=val*16+val2;
- } else *Dest = *Source;
- Dest++;
- Source++;
- }
- *Dest=0;
-
- LeaveFunction("DecodeHexChars");
-}
-
-
-void AddDynamicString(const char *String)
-{
- struct DynamicString *Temp;
-
- EnterFunction("AddDynamicString");
-
- Temp = (struct DynamicString*)kmalloc(sizeof(struct DynamicString),(int)GFP_KERNEL);
-
- if (Temp==NULL)
- return;
-
- memset(Temp->value,0,sizeof(Temp->value));
- strncpy(Temp->value,String,sizeof(Temp->value)-1);
-
- Temp->Next = DynamicList;
- DynamicList = Temp;
-
- LeaveFunction("AddDynamicString");
-}
-
-void GetSecureString(char *String)
-{
- struct DynamicString *Temp;
- int max;
-
- EnterFunction("GetSecureString");
-
- *String = 0;
-
- memset(String,0,255);
-
- strncpy(String,"Dynamic strings are : -",255);
- Temp = DynamicList;
- while (Temp!=NULL)
- {
- max=253 - strlen(String) - strlen(Temp->value);
- strncat(String,Temp->value,max);
- max=253 - strlen(String) - 3;
- strncat(String,"- -",max);
- Temp = Temp->Next;
- }
-
- LeaveFunction("GetSecureString");
-}
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/security.h linux/net/khttpd/security.h
--- linux-2.4.19-pre8/net/khttpd/security.h Fri May 3 13:35:46 2002
+++ linux/net/khttpd/security.h Thu Jan 1 01:00:00 1970
@@ -1,12 +0,0 @@
-#ifndef _INCLUDE_GUARD_SECURITY_H
-#define _INCLUDE_GUARD_SECURITY_H
-
-struct DynamicString;
-
-struct DynamicString
-{
- struct DynamicString* Next;
- char value[32-sizeof(void*)]; /* fill 1 cache-line */
-};
-
-#endif
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/sockets.c linux/net/khttpd/sockets.c
--- linux-2.4.19-pre8/net/khttpd/sockets.c Fri May 3 13:35:39 2002
+++ linux/net/khttpd/sockets.c Thu Jan 1 01:00:00 1970
@@ -1,101 +0,0 @@
-/*
-
-kHTTPd -- the next generation
-
-Basic socket functions
-
-*/
-/****************************************************************
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ****************************************************************/
-
-#include "prototypes.h"
-#include <linux/kernel.h>
-#include <linux/net.h>
-#include <linux/version.h>
-#include <linux/smp_lock.h>
-#include <net/sock.h>
-
-
-/*
-
-MainSocket is shared by all threads, therefore it has to be
-a global variable.
-
-*/
-struct socket *MainSocket=NULL;
-
-
-int StartListening(const int Port)
-{
- struct socket *sock;
- struct sockaddr_in sin;
- int error;
-
- EnterFunction("StartListening");
-
- /* First create a socket */
-
- error = sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&sock);
- if (error<0)
- (void)printk(KERN_ERR "Error during creation of socket; terminating\n");
-
-
-
- /* Now bind the socket */
-
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = INADDR_ANY;
- sin.sin_port = htons((unsigned short)Port);
-
- error = sock->ops->bind(sock,(struct sockaddr*)&sin,sizeof(sin));
- if (error<0)
- {
- (void)printk(KERN_ERR "kHTTPd: Error binding socket. This means that some other \n");
- (void)printk(KERN_ERR " daemon is (or was a short time ago) using port %i.\n",Port);
- return 0;
- }
-
- /* Grrr... setsockopt() does this. */
- sock->sk->reuse = 1;
-
- /* Now, start listening on the socket */
-
- /* I have no idea what a sane backlog-value is. 48 works so far. */
-
- error=sock->ops->listen(sock,48);
- if (error!=0)
- (void)printk(KERN_ERR "kHTTPd: Error listening on socket \n");
-
- MainSocket = sock;
-
- LeaveFunction("StartListening");
- return 1;
-}
-
-void StopListening(void)
-{
- struct socket *sock;
-
- EnterFunction("StopListening");
- if (MainSocket==NULL) return;
-
- sock=MainSocket;
- MainSocket = NULL;
- sock_release(sock);
-
- LeaveFunction("StopListening");
-}
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/structure.h linux/net/khttpd/structure.h
--- linux-2.4.19-pre8/net/khttpd/structure.h Fri May 3 13:34:57 2002
+++ linux/net/khttpd/structure.h Thu Jan 1 01:00:00 1970
@@ -1,68 +0,0 @@
-#ifndef _INCLUDE_GUARD_STRUCTURE_H_
-#define _INCLUDE_GUARD_STRUCTURE_H_
-
-#include <linux/time.h>
-#include <linux/wait.h>
-
-
-struct http_request;
-
-struct http_request
-{
- /* Linked list */
- struct http_request *Next;
-
- /* Network and File data */
- struct socket *sock;
- struct file *filp;
-
- /* Raw data about the file */
-
- int FileLength; /* File length in bytes */
- int Time; /* mtime of the file, unix format */
- int BytesSent; /* The number of bytes already sent */
- int IsForUserspace; /* 1 means let Userspace handle this one */
-
- /* Wait queue */
-
- wait_queue_t sleep; /* For putting in the socket's waitqueue */
-
- /* HTTP request information */
- char FileName[256]; /* The requested filename */
- int FileNameLength; /* The length of the string representing the filename */
- char Agent[128]; /* The agent-string of the remote browser */
- char IMS[128]; /* If-modified-since time, rfc string format */
- char Host[128]; /* Value given by the Host: header */
- int HTTPVER; /* HTTP-version; 9 for 0.9, 10 for 1.0 and above */
-
-
- /* Derived date from the above fields */
- int IMS_Time; /* if-modified-since time, unix format */
- char TimeS[64]; /* File mtime, rfc string representation */
- char LengthS[14]; /* File length, string representation */
- char *MimeType; /* Pointer to a string with the mime-type
- based on the filename */
- __kernel_size_t MimeLength; /* The length of this string */
-
-};
-
-
-
-/*
-
-struct khttpd_threadinfo represents the four queues that 1 thread has to deal with.
-It is padded to occupy 1 (Intel) cache-line, to avoid "cacheline-pingpong".
-
-*/
-struct khttpd_threadinfo
-{
- struct http_request* WaitForHeaderQueue;
- struct http_request* DataSendingQueue;
- struct http_request* LoggingQueue;
- struct http_request* UserspaceQueue;
- char dummy[16]; /* Padding for cache-lines */
-};
-
-
-
-#endif
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/sysctl.c linux/net/khttpd/sysctl.c
--- linux-2.4.19-pre8/net/khttpd/sysctl.c Fri May 3 13:39:20 2002
+++ linux/net/khttpd/sysctl.c Thu Jan 1 01:00:00 1970
@@ -1,320 +0,0 @@
-/*
-
-kHTTPd -- the next generation
-
-Sysctl interface
-
-*/
-/****************************************************************
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ****************************************************************/
-
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/net.h>
-#include <linux/sched.h>
-#include <linux/skbuff.h>
-#include <linux/smp_lock.h>
-#include <linux/sysctl.h>
-#include <linux/un.h>
-#include <linux/unistd.h>
-
-#include <net/ip.h>
-#include <net/sock.h>
-#include <net/tcp.h>
-
-#include <asm/atomic.h>
-#include <asm/semaphore.h>
-#include <asm/processor.h>
-#include <asm/uaccess.h>
-
-#include <linux/file.h>
-#include "prototypes.h"
-
-
-
-char sysctl_khttpd_docroot[200] = "/var/www";
-int sysctl_khttpd_stop = 0;
-int sysctl_khttpd_start = 0;
-int sysctl_khttpd_unload = 0;
-int sysctl_khttpd_clientport = 80;
-int sysctl_khttpd_permreq = S_IROTH; /* "other" read-access is required by default*/
-int sysctl_khttpd_permforbid = S_IFDIR | S_ISVTX | S_IXOTH | S_IXGRP | S_IXUSR;
- /* forbidden is execute, directory and sticky*/
-int sysctl_khttpd_logging = 0;
-int sysctl_khttpd_serverport= 8080;
-
-char sysctl_khttpd_dynamicstring[200];
-int sysctl_khttpd_sloppymime= 0;
-int sysctl_khttpd_threads = 2;
-int sysctl_khttpd_maxconnect = 1000;
-
-
-static struct ctl_table_header *khttpd_table_header;
-
-static int sysctl_SecureString(ctl_table *table, int *name, int nlen,
- void *oldval, size_t *oldlenp,
- void *newval, size_t newlen, void **context);
-static int proc_dosecurestring(ctl_table *table, int write, struct file *filp,
- void *buffer, size_t *lenp);
-
-
-static ctl_table khttpd_table[] = {
- { NET_KHTTPD_DOCROOT,
- "documentroot",
- &sysctl_khttpd_docroot,
- sizeof(sysctl_khttpd_docroot),
- 0644,
- NULL,
- proc_dostring,
- &sysctl_string,
- NULL,
- NULL,
- NULL
- },
- { NET_KHTTPD_STOP,
- "stop",
- &sysctl_khttpd_stop,
- sizeof(int),
- 0644,
- NULL,
- proc_dointvec,
- &sysctl_intvec,
- NULL,
- NULL,
- NULL
- },
- { NET_KHTTPD_START,
- "start",
- &sysctl_khttpd_start,
- sizeof(int),
- 0644,
- NULL,
- proc_dointvec,
- &sysctl_intvec,
- NULL,
- NULL,
- NULL
- },
- { NET_KHTTPD_UNLOAD,
- "unload",
- &sysctl_khttpd_unload,
- sizeof(int),
- 0644,
- NULL,
- proc_dointvec,
- &sysctl_intvec,
- NULL,
- NULL,
- NULL
- },
- { NET_KHTTPD_THREADS,
- "threads",
- &sysctl_khttpd_threads,
- sizeof(int),
- 0644,
- NULL,
- proc_dointvec,
- &sysctl_intvec,
- NULL,
- NULL,
- NULL
- },
- { NET_KHTTPD_MAXCONNECT,
- "maxconnect",
- &sysctl_khttpd_maxconnect,
- sizeof(int),
- 0644,
- NULL,
- proc_dointvec,
- &sysctl_intvec,
- NULL,
- NULL,
- NULL
- },
- { NET_KHTTPD_SLOPPYMIME,
- "sloppymime",
- &sysctl_khttpd_sloppymime,
- sizeof(int),
- 0644,
- NULL,
- proc_dointvec,
- &sysctl_intvec,
- NULL,
- NULL,
- NULL
- },
- { NET_KHTTPD_CLIENTPORT,
- "clientport",
- &sysctl_khttpd_clientport,
- sizeof(int),
- 0644,
- NULL,
- proc_dointvec,
- &sysctl_intvec,
- NULL,
- NULL,
- NULL
- },
- { NET_KHTTPD_PERMREQ,
- "perm_required",
- &sysctl_khttpd_permreq,
- sizeof(int),
- 0644,
- NULL,
- proc_dointvec,
- &sysctl_intvec,
- NULL,
- NULL,
- NULL
- },
- { NET_KHTTPD_PERMFORBID,
- "perm_forbid",
- &sysctl_khttpd_permforbid,
- sizeof(int),
- 0644,
- NULL,
- proc_dointvec,
- &sysctl_intvec,
- NULL,
- NULL,
- NULL
- },
- { NET_KHTTPD_LOGGING,
- "logging",
- &sysctl_khttpd_logging,
- sizeof(int),
- 0644,
- NULL,
- proc_dointvec,
- &sysctl_intvec,
- NULL,
- NULL,
- NULL
- },
- { NET_KHTTPD_SERVERPORT,
- "serverport",
- &sysctl_khttpd_serverport,
- sizeof(int),
- 0644,
- NULL,
- proc_dointvec,
- &sysctl_intvec,
- NULL,
- NULL,
- NULL
- },
- { NET_KHTTPD_DYNAMICSTRING,
- "dynamic",
- &sysctl_khttpd_dynamicstring,
- sizeof(sysctl_khttpd_dynamicstring),
- 0644,
- NULL,
- proc_dosecurestring,
- &sysctl_SecureString,
- NULL,
- NULL,
- NULL
- },
- {0,0,0,0,0,0,0,0,0,0,0} };
-
-
-static ctl_table khttpd_dir_table[] = {
- {NET_KHTTPD, "khttpd", NULL, 0, 0555, khttpd_table,0,0,0,0,0},
- {0,0,0,0,0,0,0,0,0,0,0}
-};
-
-static ctl_table khttpd_root_table[] = {
- {CTL_NET, "net", NULL, 0, 0555, khttpd_dir_table,0,0,0,0,0},
- {0,0,0,0,0,0,0,0,0,0,0}
-};
-
-
-void StartSysctl(void)
-{
- khttpd_table_header = register_sysctl_table(khttpd_root_table,1);
-}
-
-
-void EndSysctl(void)
-{
- unregister_sysctl_table(khttpd_table_header);
-}
-
-static int proc_dosecurestring(ctl_table *table, int write, struct file *filp,
- void *buffer, size_t *lenp)
-{
- size_t len;
- char *p, c=0;
- char String[256];
-
- if ((table->data==0) || (table->maxlen==0) || (*lenp==0) ||
- ((filp->f_pos!=0) && (write==0))) {
- *lenp = 0;
- return 0;
- }
-
- if (write!=0) {
- len = 0;
- p = buffer;
- while (len < *lenp) {
- if(get_user(c, p++))
- return -EFAULT;
- if (c == 0 || c == '\n')
- break;
- len++;
- }
- if (len >= table->maxlen)
- len = table->maxlen-1;
- if(copy_from_user(String, buffer,(unsigned long)len))
- return -EFAULT;
- ((char *) String)[len] = 0;
- filp->f_pos += *lenp;
- AddDynamicString(String);
- } else {
- GetSecureString(String);
- len = strlen(String);
- if (len > table->maxlen)
- len = table->maxlen;
- if (len > *lenp)
- len = *lenp;
- if (len!=0)
- if(copy_to_user(buffer, String,(unsigned long)len))
- return -EFAULT;
- if (len < *lenp) {
- if(put_user('\n', ((char *) buffer) + len))
- return -EFAULT;
- len++;
- }
- *lenp = len;
- filp->f_pos += len;
- }
- return 0;
-}
-
-static int sysctl_SecureString (/*@unused@*/ctl_table *table,
- /*@unused@*/int *name,
- /*@unused@*/int nlen,
- /*@unused@*/void *oldval,
- /*@unused@*/size_t *oldlenp,
- /*@unused@*/void *newval,
- /*@unused@*/size_t newlen,
- /*@unused@*/void **context)
-{
- return -ENOSYS;
-}
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/sysctl.h linux/net/khttpd/sysctl.h
--- linux-2.4.19-pre8/net/khttpd/sysctl.h Fri May 3 13:36:47 2002
+++ linux/net/khttpd/sysctl.h Thu Jan 1 01:00:00 1970
@@ -1,17 +0,0 @@
-#ifndef _KHTTPD_INCLUDE_GUARD_SYSCTL_H
-#define _KHTTPD_INCLUDE_GUARD_SYSCTL_H
-
-extern char sysctl_khttpd_docroot[200];
-extern int sysctl_khttpd_stop;
-extern int sysctl_khttpd_start;
-extern int sysctl_khttpd_unload;
-extern int sysctl_khttpd_clientport;
-extern int sysctl_khttpd_permreq;
-extern int sysctl_khttpd_permforbid;
-extern int sysctl_khttpd_logging;
-extern int sysctl_khttpd_serverport;
-extern int sysctl_khttpd_sloppymime;
-extern int sysctl_khttpd_threads;
-extern int sysctl_khttpd_maxconnect;
-
-#endif
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/userspace.c linux/net/khttpd/userspace.c
--- linux-2.4.19-pre8/net/khttpd/userspace.c Fri May 3 13:35:53 2002
+++ linux/net/khttpd/userspace.c Thu Jan 1 01:00:00 1970
@@ -1,243 +0,0 @@
-/*
-
-kHTTPd -- the next generation
-
-Pass connections to userspace-daemons
-
-*/
-/****************************************************************
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ****************************************************************/
-
-/*
-
-Purpose:
-
-Userspace() hands all requests in the queue to the userspace-daemon, if
-such beast exists.
-
-Return value:
- The number of requests that changed status
-*/
-#include <linux/kernel.h>
-
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/net.h>
-#include <linux/sched.h>
-#include <linux/skbuff.h>
-#include <linux/smp_lock.h>
-#include <linux/un.h>
-#include <linux/unistd.h>
-#include <linux/wait.h>
-
-#include <net/ip.h>
-#include <net/sock.h>
-#include <net/tcp.h>
-
-#include <asm/atomic.h>
-#include <asm/semaphore.h>
-#include <asm/processor.h>
-#include <asm/uaccess.h>
-
-#include <linux/file.h>
-
-
-#include "structure.h"
-#include "prototypes.h"
-#include "sysctl.h"
-
-/* prototypes of local, static functions */
-static int AddSocketToAcceptQueue(struct socket *sock,const int Port);
-
-
-int Userspace(const int CPUNR)
-{
- struct http_request *CurrentRequest,**Prev,*Next;
-
- EnterFunction("Userspace");
-
-
-
-
- CurrentRequest = threadinfo[CPUNR].UserspaceQueue;
- Prev = &(threadinfo[CPUNR].UserspaceQueue);
-
- while (CurrentRequest!=NULL)
- {
-
- /* Clean-up the waitqueue of the socket.. Bad things happen if
- this is forgotten. */
- if (CurrentRequest->sock!=NULL)
- {
- if ((CurrentRequest->sock!=NULL)&&(CurrentRequest->sock->sk!=NULL))
- {
- remove_wait_queue(CurrentRequest->sock->sk->sleep,&(CurrentRequest->sleep));
- }
- }
-
-
- if (AddSocketToAcceptQueue(CurrentRequest->sock,sysctl_khttpd_clientport)>=0)
- {
-
- (*Prev) = CurrentRequest->Next;
- Next = CurrentRequest->Next;
-
-
- sock_release(CurrentRequest->sock);
- CurrentRequest->sock = NULL; /* We no longer own it */
-
- CleanUpRequest(CurrentRequest);
-
- CurrentRequest = Next;
- continue;
-
- }
- else /* No userspace-daemon present, or other problems with it */
- {
- (*Prev) = CurrentRequest->Next;
- Next = CurrentRequest->Next;
-
- Send403(CurrentRequest->sock); /* Sorry, no go... */
-
- CleanUpRequest(CurrentRequest);
-
- CurrentRequest = Next;
- continue;
-
- }
-
-
- Prev = &(CurrentRequest->Next);
- CurrentRequest = CurrentRequest->Next;
- }
-
- LeaveFunction("Userspace");
- return 0;
-}
-
-void StopUserspace(const int CPUNR)
-{
- struct http_request *CurrentRequest,*Next;
-
- EnterFunction("StopUserspace");
- CurrentRequest = threadinfo[CPUNR].UserspaceQueue;
-
- while (CurrentRequest!=NULL)
- {
- Next= CurrentRequest->Next;
- CleanUpRequest(CurrentRequest);
- CurrentRequest=Next;
- }
- threadinfo[CPUNR].UserspaceQueue = NULL;
-
- LeaveFunction("StopUserspace");
-}
-
-
-/*
- "FindUserspace" returns the struct sock of the userspace-daemon, so that we can
- "drop" our request in the accept-queue
-*/
-
-static struct sock *FindUserspace(const unsigned short Port)
-{
- struct sock *sk;
-
- EnterFunction("FindUserspace");
-
- local_bh_disable();
- sk = tcp_v4_lookup_listener(INADDR_ANY,Port,0);
- local_bh_enable();
- return sk;
-}
-
-static void dummy_destructor(struct open_request *req)
-{
-}
-
-static struct or_calltable Dummy =
-{
- 0,
- NULL,
- NULL,
- &dummy_destructor,
- NULL
-};
-
-static int AddSocketToAcceptQueue(struct socket *sock,const int Port)
-{
- struct open_request *req;
- struct sock *sk, *nsk;
-
- EnterFunction("AddSocketToAcceptQueue");
-
-
- sk = FindUserspace((unsigned short)Port);
-
- if (sk==NULL) /* No userspace-daemon found */
- {
- return -1;
- }
-
- lock_sock(sk);
-
- if (sk->state != TCP_LISTEN || tcp_acceptq_is_full(sk))
- {
- release_sock(sk);
- sock_put(sk);
- return -1;
- }
-
- req = tcp_openreq_alloc();
-
- if (req==NULL)
- {
- release_sock(sk);
- sock_put(sk);
- return -1;
- }
-
- nsk = sock->sk;
- sock->sk = NULL;
- sock->state = SS_UNCONNECTED;
-
- req->class = &Dummy;
- write_lock_bh(&nsk->callback_lock);
- nsk->socket = NULL;
- nsk->sleep = NULL;
- write_unlock_bh(&nsk->callback_lock);
-
- tcp_acceptq_queue(sk, req, nsk);
-
- sk->data_ready(sk, 0);
-
- release_sock(sk);
- sock_put(sk);
-
- LeaveFunction("AddSocketToAcceptQueue");
-
- return +1;
-
-
-
-}
-
-void InitUserspace(const int CPUNR)
-{
-}
-
-
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/waitheaders.c linux/net/khttpd/waitheaders.c
--- linux-2.4.19-pre8/net/khttpd/waitheaders.c Fri May 3 13:36:59 2002
+++ linux/net/khttpd/waitheaders.c Thu Jan 1 01:00:00 1970
@@ -1,296 +0,0 @@
-/*
-
-kHTTPd -- the next generation
-
-Wait for headers on the accepted connections
-
-*/
-/****************************************************************
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ****************************************************************/
-
-/*
-
-Purpose:
-
-WaitForHeaders polls all connections in "WaitForHeaderQueue" to see if
-headers have arived. If so, the headers are decoded and the request is
-moved to either the "SendingDataQueue" or the "UserspaceQueue".
-
-Return value:
- The number of requests that changed status
-*/
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/skbuff.h>
-#include <linux/smp_lock.h>
-#include <linux/file.h>
-
-#include <asm/uaccess.h>
-
-#include "structure.h"
-#include "prototypes.h"
-
-static char *Buffer[CONFIG_KHTTPD_NUMCPU];
-
-
-static int DecodeHeader(const int CPUNR, struct http_request *Request);
-
-
-int WaitForHeaders(const int CPUNR)
-{
- struct http_request *CurrentRequest,**Prev;
- struct sock *sk;
- int count = 0;
-
- EnterFunction("WaitForHeaders");
-
- CurrentRequest = threadinfo[CPUNR].WaitForHeaderQueue;
-
- Prev = &(threadinfo[CPUNR].WaitForHeaderQueue);
-
- while (CurrentRequest!=NULL)
- {
-
- /* If the connection is lost, remove from queue */
-
- if (CurrentRequest->sock->sk->state != TCP_ESTABLISHED
- && CurrentRequest->sock->sk->state != TCP_CLOSE_WAIT)
- {
- struct http_request *Next;
-
- Next = CurrentRequest->Next;
-
- *Prev = CurrentRequest->Next;
- CurrentRequest->Next = NULL;
-
-
- CleanUpRequest(CurrentRequest);
- CurrentRequest = Next;
- continue;
- }
-
-
-
- /* If data pending, take action */
-
- sk = CurrentRequest->sock->sk;
-
- if (!skb_queue_empty(&(sk->receive_queue))) /* Do we have data ? */
- {
- struct http_request *Next;
-
-
-
- /* Decode header */
-
- if (DecodeHeader(CPUNR,CurrentRequest)<0)
- {
- CurrentRequest = CurrentRequest->Next;
- continue;
- }
-
-
- /* Remove from WaitForHeaderQueue */
-
- Next= CurrentRequest->Next;
-
- *Prev = Next;
- count++;
-
- /* Add to either the UserspaceQueue or the DataSendingQueue */
-
- if (CurrentRequest->IsForUserspace!=0)
- {
- CurrentRequest->Next = threadinfo[CPUNR].UserspaceQueue;
- threadinfo[CPUNR].UserspaceQueue = CurrentRequest;
- } else
- {
- CurrentRequest->Next = threadinfo[CPUNR].DataSendingQueue;
- threadinfo[CPUNR].DataSendingQueue = CurrentRequest;
- }
-
- CurrentRequest = Next;
- continue;
-
- }
-
-
- Prev = &(CurrentRequest->Next);
- CurrentRequest = CurrentRequest->Next;
- }
-
- LeaveFunction("WaitHeaders");
- return count;
-}
-
-void StopWaitingForHeaders(const int CPUNR)
-{
- struct http_request *CurrentRequest,*Next;
-
- EnterFunction("StopWaitingForHeaders");
- CurrentRequest = threadinfo[CPUNR].WaitForHeaderQueue;
-
- while (CurrentRequest!=NULL)
- {
- Next = CurrentRequest->Next;
- CleanUpRequest(CurrentRequest);
- CurrentRequest=Next;
- }
-
- threadinfo[CPUNR].WaitForHeaderQueue = NULL; /* The queue is empty now */
-
- free_page((unsigned long)Buffer[CPUNR]);
- Buffer[CPUNR]=NULL;
-
- EnterFunction("StopWaitingForHeaders");
-}
-
-
-/*
-
-DecodeHeader peeks at the TCP/IP data, determines what the request is,
-fills the request-structure and sends the HTTP-header when apropriate.
-
-*/
-
-static int DecodeHeader(const int CPUNR, struct http_request *Request)
-{
- struct msghdr msg;
- struct iovec iov;
- int len;
-
- mm_segment_t oldfs;
-
- EnterFunction("DecodeHeader");
-
- /* First, read the data */
-
- msg.msg_name = 0;
- msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- msg.msg_flags = 0;
-
- msg.msg_iov->iov_base = &Buffer[CPUNR][0];
- msg.msg_iov->iov_len = (size_t)4095;
-
- len = 0;
- oldfs = get_fs(); set_fs(KERNEL_DS);
- /* 4095 leaves a "0" to terminate the string */
-
- len = sock_recvmsg(Request->sock,&msg,4095,MSG_PEEK);
- set_fs(oldfs);
-
- if (len<0) {
- /* WONDERFUL. NO COMMENTS. --ANK */
- Request->IsForUserspace = 1;
- return 0;
- }
-
- if (len>=4094) /* BIG header, we cannot decode it so leave it to userspace */
- {
- Request->IsForUserspace = 1;
- return 0;
- }
-
- /* Then, decode the header */
-
-
- ParseHeader(Buffer[CPUNR],len,Request);
-
- Request->filp = OpenFileForSecurity(Request->FileName);
-
-
- Request->MimeType = ResolveMimeType(Request->FileName,&Request->MimeLength);
-
-
- if (Request->MimeType==NULL) /* Unknown mime-type */
- {
- if (Request->filp!=NULL)
- {
- fput(Request->filp);
- Request->filp = NULL;
- }
- Request->IsForUserspace = 1;
-
- return 0;
- }
-
- if (Request->filp==NULL)
- {
- Request->IsForUserspace = 1;
- return 0;
- }
- else
- {
- Request->FileLength = (int)Request->filp->f_dentry->d_inode->i_size;
- Request->Time = Request->filp->f_dentry->d_inode->i_mtime;
- Request->IMS_Time = mimeTime_to_UnixTime(Request->IMS);
- sprintf(Request->LengthS,"%i",Request->FileLength);
- time_Unix2RFC(min_t(unsigned int, Request->Time,CurrentTime_i),Request->TimeS);
- /* The min() is required by rfc1945, section 10.10:
- It is not allowed to send a filetime in the future */
-
- if (Request->IMS_Time>Request->Time)
- { /* Not modified since last time */
- Send304(Request->sock);
- Request->FileLength=0;
- }
- else /* Normal Case */
- {
- Request->sock->sk->tp_pinfo.af_tcp.nonagle = 2; /* this is TCP_CORK */
- if (Request->HTTPVER!=9) /* HTTP/0.9 doesn't allow a header */
- SendHTTPHeader(Request);
- }
-
-
- }
-
- LeaveFunction("DecodeHeader");
- return 0;
-}
-
-
-int InitWaitHeaders(int ThreadCount)
-{
- int I,I2;
-
- EnterFunction("InitWaitHeaders");
- I=0;
- while (I<ThreadCount)
- {
- Buffer[I] = (char*)get_free_page((int)GFP_KERNEL);
- if (Buffer[I] == NULL)
- {
- printk(KERN_CRIT "kHTTPd: Not enough memory for basic needs\n");
- I2=0;
- while (I2<I-1)
- {
- free_page( (unsigned long)Buffer[I2++]);
- }
- return -1;
- }
- I++;
- }
-
- LeaveFunction("InitWaitHeaders");
- return 0;
-
-}
diff -uNr -Xdontdiff linux-2.4.19-pre8/net/netsyms.c linux/net/netsyms.c
--- linux-2.4.19-pre8/net/netsyms.c Fri May 3 13:37:36 2002
+++ linux/net/netsyms.c Mon May 6 12:53:39 2002
@@ -56,7 +56,7 @@

extern struct net_proto_family inet_family_ops;

-#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) || defined (CONFIG_KHTTPD) || defined (CONFIG_KHTTPD_MODULE)
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
#include <linux/in6.h>
#include <linux/icmpv6.h>
#include <net/ipv6.h>
@@ -295,7 +295,7 @@
#include <net/ip6_route.h>
EXPORT_SYMBOL(ip6_route_output);
#endif
-#if defined (CONFIG_IPV6_MODULE) || defined (CONFIG_KHTTPD) || defined (CONFIG_KHTTPD_MODULE)
+#if defined (CONFIG_IPV6_MODULE)
/* inet functions common to v4 and v6 */
EXPORT_SYMBOL(inet_release);
EXPORT_SYMBOL(inet_stream_connect);

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/