3636#include <arpa/inet.h>
3737#include <sys/wait.h>
3838
39- #define DEF_PORT 80
40- #define DEF_CONTENT "text/html"
39+ #define DEF_PORT 80
40+ #define DEF_CONTENT "text/html"
4141
42- #define WS (c ) ( ((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) == '\n') )
42+ #define WS (c ) ( ((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) == '\n') )
4343
4444int listen_sock ;
4545char buf [1536 ];
@@ -50,163 +50,163 @@ char* get_mime_type(char *name)
5050
5151 dot = strrchr ( name , '.' );
5252 if ( dot == (char * ) 0 )
53- return "text/plain" ;
53+ return "text/plain" ;
5454 if ( strcmp ( dot , ".html" ) == 0 || strcmp ( dot , ".htm" ) == 0 )
55- return "text/html" ;
55+ return "text/html" ;
5656 if ( strcmp ( dot , ".jpg" ) == 0 || strcmp ( dot , ".jpeg" ) == 0 )
57- return "image/jpeg" ;
57+ return "image/jpeg" ;
5858 if ( strcmp ( dot , ".gif" ) == 0 )
59- return "image/gif" ;
59+ return "image/gif" ;
6060 if ( strcmp ( dot , ".png" ) == 0 )
61- return "image/png" ;
61+ return "image/png" ;
6262 if ( strcmp ( dot , ".css" ) == 0 )
63- return "text/css" ;
63+ return "text/css" ;
6464 if ( strcmp ( dot , ".vrml" ) == 0 || strcmp ( dot , ".wrl" ) == 0 )
65- return "model/vrml" ;
65+ return "model/vrml" ;
6666 if ( strcmp ( dot , ".midi" ) == 0 || strcmp ( dot , ".mid" ) == 0 )
67- return "audio/midi" ;
67+ return "audio/midi" ;
6868 return "text/plain" ;
6969}
7070
7171void send_header (int fd , char * ct )
7272{
73- buf [0 ] = 0 ;
74- sprintf (buf , "HTTP/1.0 200 OK\r\nServer: nanoHTTPd/0.1\r\nDate: Thu Apr 26 15:37:46 GMT 2001\r\nContent-Type: %s\r\n" ,ct );
75- write (fd , buf , strlen (buf ));
73+ buf [0 ] = 0 ;
74+ sprintf (buf , "HTTP/1.0 200 OK\r\nServer: nanoHTTPd/0.1\r\nDate: Thu Apr 26 15:37:46 GMT 2001\r\nContent-Type: %s\r\n" ,ct );
75+ write (fd , buf , strlen (buf ));
7676}
7777
7878void send_error (int fd , int errnum , char * str )
7979{
80- sprintf (buf ,"HTTP/1.0 %d %s\r\nContent-type: %s\r\n" , errnum , str , DEF_CONTENT );
81- write (fd , buf , strlen (buf ));
82- sprintf (buf ,"Connection: close\r\nDate: Thu Apr 26 15:37:46 GMT 2001\r\n\r\n%s\r\n" ,str );
83- write (fd , buf , strlen (buf ));
80+ sprintf (buf ,"HTTP/1.0 %d %s\r\nContent-type: %s\r\n" , errnum , str , DEF_CONTENT );
81+ write (fd , buf , strlen (buf ));
82+ sprintf (buf ,"Connection: close\r\nDate: Thu Apr 26 15:37:46 GMT 2001\r\n\r\n%s\r\n" ,str );
83+ write (fd , buf , strlen (buf ));
8484}
8585
8686void process_request (int fd )
8787{
88- int fin , ret ;
89- off_t size ;
90- char * c , * file , fullpath [PATH_MAX ];
91- struct stat st ;
92-
93- ret = read (fd , buf , sizeof (buf ));
94-
95- c = buf ;
96- while (* c && !WS (* c ) && c < (buf + sizeof (buf ))){
97- c ++ ;
98- }
99- * c = 0 ;
100-
101- if (strcasecmp (buf , "get" )){
102- send_error (fd , 404 , "Method not supported" );
103- return ;
104- }
105-
106- file = ++ c ;
107- while (* c && !WS (* c ) && c < (buf + sizeof (buf ))){
108- c ++ ;
109- }
110- * c = 0 ;
111-
112- /* TODO : Use strncat when security is the only problem of this server! */
113- strcpy (fullpath , _PATH_DOCBASE );
114- strcat (fullpath , file );
115-
116- if (!stat (fullpath , & st ) && (st .st_mode & S_IFMT ) == S_IFDIR ) {
117- if (file [strlen (fullpath ) - 1 ] != '/' ){
118- strcat (fullpath , "/" );
119- }
120- strcat (fullpath , "index.html" );
121- }
122-
123- fin = open (fullpath , O_RDONLY );
124- if (fin < 0 ){
125- send_error (fd , 404 , "Document (probably) not found" );
126- return ;
127- }
128- size = lseek (fin , (off_t )0 , SEEK_END );
129- lseek (fin , (off_t )0 , SEEK_SET );
130- send_header (fd , get_mime_type (fullpath ));
131- sprintf (buf ,"Content-Length: %ld\r\n\r\n" , size );
132- write (fd , buf , strlen (buf ));
133-
134- do {
135- ret = read (fin , buf , sizeof (buf ));
136- if (ret > 0 )
137- ret = write (fd , buf , ret );
138- } while (ret == sizeof (buf ));
139-
140- close (fin );
141-
88+ int fin , ret ;
89+ off_t size ;
90+ char * c , * file , fullpath [PATH_MAX ];
91+ struct stat st ;
92+
93+ ret = read (fd , buf , sizeof (buf ));
94+
95+ c = buf ;
96+ while (* c && !WS (* c ) && c < (buf + sizeof (buf ))){
97+ c ++ ;
98+ }
99+ * c = 0 ;
100+
101+ if (strcasecmp (buf , "get" )){
102+ send_error (fd , 404 , "Method not supported" );
103+ return ;
104+ }
105+
106+ file = ++ c ;
107+ while (* c && !WS (* c ) && c < (buf + sizeof (buf ))){
108+ c ++ ;
109+ }
110+ * c = 0 ;
111+
112+ /* TODO : Use strncat when security is the only problem of this server! */
113+ strcpy (fullpath , _PATH_DOCBASE );
114+ strcat (fullpath , file );
115+
116+ if (!stat (fullpath , & st ) && (st .st_mode & S_IFMT ) == S_IFDIR ) {
117+ if (file [strlen (fullpath ) - 1 ] != '/' ){
118+ strcat (fullpath , "/" );
119+ }
120+ strcat (fullpath , "index.html" );
121+ }
122+
123+ fin = open (fullpath , O_RDONLY );
124+ if (fin < 0 ){
125+ send_error (fd , 404 , "Document (probably) not found" );
126+ return ;
127+ }
128+ size = lseek (fin , (off_t )0 , SEEK_END );
129+ lseek (fin , (off_t )0 , SEEK_SET );
130+ send_header (fd , get_mime_type (fullpath ));
131+ sprintf (buf ,"Content-Length: %ld\r\n\r\n" , size );
132+ write (fd , buf , strlen (buf ));
133+
134+ do {
135+ ret = read (fin , buf , sizeof (buf ));
136+ if (ret > 0 )
137+ ret = write (fd , buf , ret );
138+ } while (ret == sizeof (buf ));
139+
140+ close (fin );
141+
142142}
143143
144144int main (int argc , char * * argv )
145145{
146- int ret , conn_sock ;
147- struct sockaddr_in localadr ;
148-
149- if ((listen_sock = socket (AF_INET , SOCK_STREAM , 0 )) < 0 ) {
150- perror ("httpd" );
151- return -1 ;
152- }
153-
154- /* set local port reuse, allows server to be restarted in less than 10 secs */
155- ret = 1 ;
156- if (setsockopt (listen_sock , SOL_SOCKET , SO_REUSEADDR , & ret , sizeof (int )) < 0 )
157- perror ("SO_REUSEADDR" );
158-
159- /* set small listen buffer to save ktcp memory */
160- ret = SO_LISTEN_BUFSIZ ;
161- if (setsockopt (listen_sock , SOL_SOCKET , SO_RCVBUF , & ret , sizeof (int )) < 0 )
162- perror ("SO_RCVBUF" );
163-
164- localadr .sin_family = AF_INET ;
165- localadr .sin_port = htons (DEF_PORT );
166- localadr .sin_addr .s_addr = INADDR_ANY ;
167-
168- if (bind (listen_sock , (struct sockaddr * )& localadr , sizeof (struct sockaddr_in )) < 0 ) {
169- fprintf (stderr , "httpd: bind error (may already be running)\n" );
170- return 1 ;
171- }
172- if (listen (listen_sock , 5 ) < 0 ) {
173- perror ("listen" );
174- return 1 ;
175- }
176-
177- /* become daemon, debug output on 1 and 2*/
178- if ((ret = fork ()) == -1 ) {
179- perror ("httpd" );
180- return 1 ;
181- }
182- if (ret ) exit (0 );
183- ret = open ("/dev/null" , O_RDWR ); /* our log file! */
184- dup2 (ret , 0 );
185- dup2 (ret , 1 );
186- dup2 (ret , 2 );
187- if (ret > 2 )
188- close (ret );
189- setsid ();
190-
191- while (1 ) {
192- conn_sock = accept (listen_sock , NULL , NULL );
193-
194- if (conn_sock < 0 ) {
195- if (errno == ENOTSOCK )
196- exit (1 );
197- continue ;
198- }
199-
200- if ((ret = fork ()) == -1 )
201- perror ("httpd" );
202- else if (ret == 0 ) {
203- close (listen_sock );
204- process_request (conn_sock );
205- close (conn_sock );
206- exit (0 );
207- } else {
208- close (conn_sock );
209- waitpid (ret , NULL , 0 );
210- }
211- }
146+ int ret , conn_sock ;
147+ struct sockaddr_in localadr ;
148+
149+ if ((listen_sock = socket (AF_INET , SOCK_STREAM , 0 )) < 0 ) {
150+ perror ("httpd" );
151+ return -1 ;
152+ }
153+
154+ /* set local port reuse, allows server to be restarted in less than 10 secs */
155+ ret = 1 ;
156+ if (setsockopt (listen_sock , SOL_SOCKET , SO_REUSEADDR , & ret , sizeof (int )) < 0 )
157+ perror ("SO_REUSEADDR" );
158+
159+ /* set small listen buffer to save ktcp memory */
160+ ret = SO_LISTEN_BUFSIZ ;
161+ if (setsockopt (listen_sock , SOL_SOCKET , SO_RCVBUF , & ret , sizeof (int )) < 0 )
162+ perror ("SO_RCVBUF" );
163+
164+ localadr .sin_family = AF_INET ;
165+ localadr .sin_port = htons (DEF_PORT );
166+ localadr .sin_addr .s_addr = INADDR_ANY ;
167+
168+ if (bind (listen_sock , (struct sockaddr * )& localadr , sizeof (struct sockaddr_in )) < 0 ) {
169+ fprintf (stderr , "httpd: bind error (may already be running)\n" );
170+ return 1 ;
171+ }
172+ if (listen (listen_sock , 5 ) < 0 ) {
173+ perror ("listen" );
174+ return 1 ;
175+ }
176+
177+ /* become daemon, debug output on 1 and 2*/
178+ if ((ret = fork ()) == -1 ) {
179+ perror ("httpd" );
180+ return 1 ;
181+ }
182+ if (ret ) exit (0 );
183+ ret = open ("/dev/null" , O_RDWR ); /* our log file! */
184+ dup2 (ret , 0 );
185+ dup2 (ret , 1 );
186+ dup2 (ret , 2 );
187+ if (ret > 2 )
188+ close (ret );
189+ setsid ();
190+
191+ while (1 ) {
192+ conn_sock = accept (listen_sock , NULL , NULL );
193+
194+ if (conn_sock < 0 ) {
195+ if (errno == ENOTSOCK )
196+ exit (1 );
197+ continue ;
198+ }
199+
200+ if ((ret = fork ()) == -1 )
201+ perror ("httpd" );
202+ else if (ret == 0 ) {
203+ close (listen_sock );
204+ process_request (conn_sock );
205+ close (conn_sock );
206+ exit (0 );
207+ } else {
208+ close (conn_sock );
209+ waitpid (ret , NULL , 0 );
210+ }
211+ }
212212}
0 commit comments