~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/net/khttpd/misc.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2 
  3 kHTTPd -- the next generation
  4 
  5 General functions
  6 
  7 */
  8 /****************************************************************
  9  *      This program is free software; you can redistribute it and/or modify
 10  *      it under the terms of the GNU General Public License as published by
 11  *      the Free Software Foundation; either version 2, or (at your option)
 12  *      any later version.
 13  *
 14  *      This program is distributed in the hope that it will be useful,
 15  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 16  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17  *      GNU General Public License for more details.
 18  *
 19  *      You should have received a copy of the GNU General Public License
 20  *      along with this program; if not, write to the Free Software
 21  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 22  *
 23  ****************************************************************/
 24 
 25 #include <linux/kernel.h>
 26 
 27 #include <linux/ctype.h>
 28 #include <linux/errno.h>
 29 #include <linux/malloc.h>
 30 #include <linux/net.h>
 31 #include <linux/sched.h>
 32 #include <linux/skbuff.h>
 33 #include <linux/unistd.h>
 34 #include <linux/file.h>
 35 #include <linux/smp_lock.h>
 36 
 37 #include <net/ip.h>
 38 #include <net/sock.h>
 39 
 40 #include <asm/atomic.h>
 41 #include <asm/errno.h>
 42 #include <asm/semaphore.h>
 43 #include <asm/processor.h>
 44 #include <asm/uaccess.h>
 45 
 46 #include "structure.h"
 47 #include "prototypes.h"
 48 
 49 #ifndef ECONNRESET
 50 #define ECONNRESET 102
 51 #endif
 52 
 53 
 54 /*
 55 
 56 Readrest reads and discards all pending input on a socket. This is required
 57 before closing the socket.
 58 
 59 */
 60 static void ReadRest(struct socket *sock)
 61 {
 62         struct msghdr           msg;
 63         struct iovec            iov;
 64         int                     len;
 65 
 66         mm_segment_t            oldfs;
 67         
 68         
 69         EnterFunction("ReadRest");
 70         
 71         
 72         if (sock->sk==NULL)
 73                 return;
 74 
 75         len = 1;
 76                 
 77         while (len>0)
 78         {
 79                 static char             Buffer[1024];   /* Never read, so doesn't need to
 80                                                            be SMP safe */
 81 
 82                 msg.msg_name     = 0;
 83                 msg.msg_namelen  = 0;
 84                 msg.msg_iov      = &iov;
 85                 msg.msg_iovlen   = 1;
 86                 msg.msg_control  = NULL;
 87                 msg.msg_controllen = 0;
 88                 msg.msg_flags    = MSG_DONTWAIT;
 89         
 90                 msg.msg_iov->iov_base = &Buffer[0];
 91                 msg.msg_iov->iov_len  = (__kernel_size_t)1024;
 92         
 93                 len = 0;
 94                 oldfs = get_fs(); set_fs(KERNEL_DS);
 95                 len = sock_recvmsg(sock,&msg,1024,MSG_DONTWAIT);
 96                 set_fs(oldfs);
 97         }
 98         LeaveFunction("ReadRest");
 99 }
100 
101 
102 /*
103 
104 CleanUpRequest takes care of shutting down the connection, closing the file-pointer
105 and releasing the memory of the request-structure. Do not try to access it afterwards!
106 
107 */
108 void CleanUpRequest(struct http_request *Req)
109 {
110         EnterFunction("CleanUpRequest");        
111         
112         /* Close the socket ....*/
113         if ((Req->sock!=NULL)&&(Req->sock->sk!=NULL))
114         {
115                 ReadRest(Req->sock);
116                 remove_wait_queue(Req->sock->sk->sleep,&(Req->sleep));
117                 sock_release(Req->sock);
118         }
119         
120         /* ... and the file-pointer ... */
121         if (Req->filp!=NULL)
122         {
123                 fput(Req->filp);
124                 Req->filp = NULL;
125         }
126         
127         
128         /* ... and release the memory for the structure. */
129         kfree(Req);
130         
131         atomic_dec(&ConnectCount);
132         LeaveFunction("CleanUpRequest");
133 }
134 
135 
136 /*
137 
138 SendBuffer and Sendbuffer_async send "Length" bytes from "Buffer" to the "sock"et.
139 The _async-version is non-blocking.
140 
141 A positive return-value indicates the number of bytes sent, a negative value indicates
142 an error-condition.
143 
144 */
145 int SendBuffer(struct socket *sock, const char *Buffer,const size_t Length)
146 {
147         struct msghdr   msg;
148         mm_segment_t    oldfs;
149         struct iovec    iov;
150         int             len;
151         
152         EnterFunction("SendBuffer");
153         
154         msg.msg_name     = 0;
155         msg.msg_namelen  = 0;
156         msg.msg_iov      = &iov;
157         msg.msg_iovlen   = 1;
158         msg.msg_control  = NULL;
159         msg.msg_controllen = 0;
160         msg.msg_flags    = MSG_NOSIGNAL;    
161         msg.msg_iov->iov_len = (__kernel_size_t)Length;
162         msg.msg_iov->iov_base = (char*) Buffer;
163         
164         
165         len = 0;
166         
167         oldfs = get_fs(); set_fs(KERNEL_DS);
168         len = sock_sendmsg(sock,&msg,(size_t)(Length-len));
169         set_fs(oldfs);
170         LeaveFunction("SendBuffer");
171         return len;     
172 }
173 
174 int SendBuffer_async(struct socket *sock, const char *Buffer,const size_t Length)
175 {
176         struct msghdr   msg;
177         mm_segment_t    oldfs;
178         struct iovec    iov;
179         int             len;
180         
181         EnterFunction("SendBuffer_async");
182         msg.msg_name     = 0;
183         msg.msg_namelen  = 0;
184         msg.msg_iov      = &iov;
185         msg.msg_iovlen   = 1;
186         msg.msg_control  = NULL;
187         msg.msg_controllen = 0;
188         msg.msg_flags    = MSG_DONTWAIT|MSG_NOSIGNAL;    
189         msg.msg_iov->iov_base = (char*) Buffer;
190         msg.msg_iov->iov_len  = (__kernel_size_t)Length;
191         
192 
193         if (sock->sk)
194         {       
195                 oldfs = get_fs(); set_fs(KERNEL_DS);
196                 len = sock_sendmsg(sock,&msg,(size_t)(Length));
197                 set_fs(oldfs);
198         } else
199         {
200                 return -ECONNRESET;
201         }
202         
203         LeaveFunction("SendBuffer_async");
204         return len;     
205 }
206 
207 
208 
209 
210 /* 
211 
212 HTTP header shortcuts. Hardcoded since these might be called in a low-memory
213 situation, and they don't change anyhow.
214 
215 */
216 
217 static char NoPerm[] = "HTTP/1.0 403 Forbidden\r\nServer: kHTTPd 0.1.6\r\n\r\n";
218 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";
219 static char NotModified[] = "HTTP/1.0 304 Not Modified\r\nServer: kHTTPd 0.1.6\r\n\r\n";
220 
221 
222 void Send403(struct socket *sock)
223 {
224         EnterFunction("Send403");
225         (void)SendBuffer(sock,NoPerm,strlen(NoPerm));
226         LeaveFunction("Send403");
227 }
228 
229 void Send304(struct socket *sock)
230 {
231         EnterFunction("Send304");
232         (void)SendBuffer(sock,NotModified,strlen(NotModified));
233         LeaveFunction("Send304");
234 }
235 
236 void Send50x(struct socket *sock)
237 {
238         EnterFunction("Send50x");
239         (void)SendBuffer(sock,TryLater,strlen(TryLater));
240         LeaveFunction("Send50x");
241 }
242 
243 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.