misc.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:5k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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