Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 #include "config.h"
  2 
  3 #include <stdio.h>
  4 #include <stdlib.h>
  5 #include <string.h>
  6 #include <unistd.h>
  7 #include <fcntl.h>
  8 #include <errno.h>
  9 #include <syslog.h>
 10 #include <time.h>
 11 
 12 #include <sys/time.h>
 13 #include <sys/types.h>
 14 #include <sys/socket.h>
 15 #include <netinet/in.h>
 16 
 17 #include "httpd.h"
 18 
 19 /* ---------------------------------------------------------------------- */
 20 
 21 static struct HTTP_STATUS {
 22     int   status;
 23     char *head;
 24     char *body;
 25 } http[] = {
 26     { 200, "200 OK",                       NULL },
 27     { 400, "400 Bad Request",              "*PLONK*\n" },
 28     { 404, "404 Not Found",       "videotext page not found in cache\n" },
 29     { 408, "408 Request Timeout",          "Request Timeout\n" },
 30     { 500, "500 Internal Server Error",    "Sorry folks\n" },
 31     { 501, "501 Not Implemented",          "Sorry folks\n" },
 32     {   0, NULL,                        NULL }
 33 };
 34 
 35 /* ---------------------------------------------------------------------- */
 36 
 37 #define RESPONSE_START                  \
 38         "HTTP/1.1 %s\r\n"               \
 39         "Server: %s\r\n"                \
 40         "Connection: %s\r\n"
 41 #define RFCTIME                         \
 42         "%a, %d %b %Y %H:%M:%S GMT"
 43 #define BOUNDARY                        \
 44         "XXX_CUT_HERE_%ld_XXX"
 45 
 46 void
 47 mkerror(struct REQUEST *req, int status, int ka)
 48 {
 49     int i;
 50     for (i = 0; http[i].status != 0; i++)
 51         if (http[i].status == status)
 52             break;
 53     req->status = status;
 54     req->body   = http[i].body;
 55     req->lbody  = strlen(req->body);
 56     if (!ka)
 57         req->keep_alive = 0;
 58     req->lres = sprintf(req->hres,
 59                         RESPONSE_START
 60                         "Content-Type: text/plain\r\n"
 61                         "Content-Length: %d\r\n",
 62                         http[i].head,server_name,
 63                         req->keep_alive ? "Keep-Alive" : "Close",
 64                         req->lbody);
 65     if (401 == status)
 66         req->lres += sprintf(req->hres+req->lres,
 67                              "WWW-Authenticate: Basic, realm=\"webfs\"\r\n");
 68     req->lres += strftime(req->hres+req->lres,80,
 69                           "Date: " RFCTIME "\r\n\r\n",
 70                           gmtime(&now));
 71     req->state = STATE_WRITE_HEADER;
 72     if (debug)
 73         fprintf(stderr,"%03d: error: %d, connection=%s\n",
 74                 req->fd, status, req->keep_alive ? "Keep-Alive" : "Close");
 75 }
 76 
 77 void
 78 mkredirect(struct REQUEST *req)
 79 {
 80     req->status = 302;
 81     req->body   = req->path;
 82     req->lbody  = strlen(req->body);
 83     req->lres = sprintf(req->hres,
 84                         RESPONSE_START
 85                         "Location: http://%s:%d%s\r\n"
 86                         "Content-Type: text/plain\r\n"
 87                         "Content-Length: %d\r\n",
 88                         "302 Redirect",server_name,
 89                         req->keep_alive ? "Keep-Alive" : "Close",
 90                         req->hostname,tcp_port,req->path,
 91                         req->lbody);
 92     req->lres += strftime(req->hres+req->lres,80,
 93                           "Date: " RFCTIME "\r\n\r\n",
 94                           gmtime(&now));
 95     req->state = STATE_WRITE_HEADER;
 96     if (debug)
 97         fprintf(stderr,"%03d: 302 redirect: %s, connection=%s\n",
 98                 req->fd, req->path, req->keep_alive ? "Keep-Alive" : "Close");
 99 }
100 
101 void
102 mkheader(struct REQUEST *req, int status, time_t mtime)
103 {
104     int    i;
105     for (i = 0; http[i].status != 0; i++)
106         if (http[i].status == status)
107             break;
108     req->status = status;
109     req->lres = sprintf(req->hres,
110                         RESPONSE_START,
111                         http[i].head,server_name,
112                         req->keep_alive ? "Keep-Alive" : "Close");
113     req->lres += sprintf(req->hres+req->lres,
114                          "Content-Type: %s\r\n"
115                          "Content-Length: %d\r\n",
116                          req->mime,
117                          req->lbody);
118     if (mtime != -1)
119         req->lres += strftime(req->hres+req->lres,80,
120                               "Last-Modified: " RFCTIME "\r\n",
121                               gmtime(&mtime));
122     req->lres += strftime(req->hres+req->lres,80,
123                           "Date: " RFCTIME "\r\n\r\n",
124                           gmtime(&now));
125     req->state = STATE_WRITE_HEADER;
126     if (debug)
127         fprintf(stderr,"%03d: %d, connection=%s\n",
128                 req->fd, status, req->keep_alive ? "Keep-Alive" : "Close");
129 }
130 
131 /* ---------------------------------------------------------------------- */
132 
133 void write_request(struct REQUEST *req)
134 {
135     int rc;
136 
137     for (;;) {
138         switch (req->state) {
139         case STATE_WRITE_HEADER:
140             rc = write(req->fd,req->hres + req->written,
141                        req->lres - req->written);
142             switch (rc) {
143             case -1:
144                 if (errno == EAGAIN)
145                     return;
146                 if (errno == EINTR)
147                     continue;
148                 xperror(LOG_INFO,"write",req->peerhost);
149                 /* fall through */
150             case 0:
151                 req->state = STATE_CLOSE;
152                 return;
153             default:
154                 req->written += rc;
155                 req->bc += rc;
156                 if (req->written != req->lres)
157                     return;
158             }
159             req->written = 0;
160             if (req->head_only) {
161                 req->state = STATE_FINISHED;
162                 return;
163             } else {
164                 req->state = STATE_WRITE_BODY;
165             }
166             break;
167         case STATE_WRITE_BODY:
168             rc = write(req->fd,req->body + req->written,
169                        req->lbody - req->written);
170             switch (rc) {
171             case -1:
172                 if (errno == EAGAIN)
173                     return;
174                 if (errno == EINTR)
175                     continue;
176                 xperror(LOG_INFO,"write",req->peerhost);
177                 /* fall through */
178             case 0:
179                 req->state = STATE_CLOSE;
180                 return;
181             default:
182                 req->written += rc;
183                 req->bc += rc;
184                 if (req->written != req->lbody)
185                     return;
186             }
187             req->state = STATE_FINISHED;
188             return;
189         } /* switch(state) */
190     } /* for (;;) */
191 }
192 
  This page was automatically generated by the LXR engine.