Re: khttpd rotten?

From: Luigi Genoni (kernel@Expansa.sns.it)
Date: Mon May 06 2002 - 12:23:11 EST


Oh well, I suppose I should be sorry. I have been using khttpd
since more than 1 year, and it was well working for me...

On Mon, 6 May 2002, Christoph Hellwig wrote:

> 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/
>

-
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/



This archive was generated by hypermail 2b29 : Tue May 07 2002 - 22:00:27 EST