aboutsummaryrefslogtreecommitdiff
path: root/src/examples/fileserver_example_dirs.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-01-18 22:14:09 +0000
committerChristian Grothoff <christian@grothoff.org>2016-01-18 22:14:09 +0000
commit9363e91e9476c489852c4f6c0a70ea6570ec469c (patch)
tree9bfb0beb76825f6b292211129d36da9356db1721 /src/examples/fileserver_example_dirs.c
parenta0f69a6671f46af1a436e18dd6bf99ec1f9a6a56 (diff)
downloadlibmicrohttpd-9363e91e9476c489852c4f6c0a70ea6570ec469c.tar.gz
libmicrohttpd-9363e91e9476c489852c4f6c0a70ea6570ec469c.zip
fixing another one of the open/stat clones
Diffstat (limited to 'src/examples/fileserver_example_dirs.c')
-rw-r--r--src/examples/fileserver_example_dirs.c52
1 files changed, 37 insertions, 15 deletions
diff --git a/src/examples/fileserver_example_dirs.c b/src/examples/fileserver_example_dirs.c
index 9d4a1935..e0a6362c 100644
--- a/src/examples/fileserver_example_dirs.c
+++ b/src/examples/fileserver_example_dirs.c
@@ -18,7 +18,7 @@
18*/ 18*/
19 19
20/** 20/**
21 * @file fileserver_example.c 21 * @file fileserver_example_dirs.c
22 * @brief example for how to use libmicrohttpd to serve files (with directory support) 22 * @brief example for how to use libmicrohttpd to serve files (with directory support)
23 * @author Christian Grothoff 23 * @author Christian Grothoff
24 */ 24 */
@@ -30,6 +30,7 @@
30 30
31#define PAGE "<html><head><title>File not found</title></head><body>File not found</body></html>" 31#define PAGE "<html><head><title>File not found</title></head><body>File not found</body></html>"
32 32
33
33static ssize_t 34static ssize_t
34file_reader (void *cls, uint64_t pos, char *buf, size_t max) 35file_reader (void *cls, uint64_t pos, char *buf, size_t max)
35{ 36{
@@ -39,6 +40,7 @@ file_reader (void *cls, uint64_t pos, char *buf, size_t max)
39 return fread (buf, 1, max, file); 40 return fread (buf, 1, max, file);
40} 41}
41 42
43
42static void 44static void
43file_free_callback (void *cls) 45file_free_callback (void *cls)
44{ 46{
@@ -46,6 +48,7 @@ file_free_callback (void *cls)
46 fclose (file); 48 fclose (file);
47} 49}
48 50
51
49static void 52static void
50dir_free_callback (void *cls) 53dir_free_callback (void *cls)
51{ 54{
@@ -54,6 +57,7 @@ dir_free_callback (void *cls)
54 closedir (dir); 57 closedir (dir);
55} 58}
56 59
60
57static ssize_t 61static ssize_t
58dir_reader (void *cls, uint64_t pos, char *buf, size_t max) 62dir_reader (void *cls, uint64_t pos, char *buf, size_t max)
59{ 63{
@@ -88,6 +92,7 @@ ahc_echo (void *cls,
88 struct MHD_Response *response; 92 struct MHD_Response *response;
89 int ret; 93 int ret;
90 FILE *file; 94 FILE *file;
95 int fd;
91 DIR *dir; 96 DIR *dir;
92 struct stat buf; 97 struct stat buf;
93 char emsg[1024]; 98 char emsg[1024];
@@ -101,17 +106,31 @@ ahc_echo (void *cls,
101 return MHD_YES; 106 return MHD_YES;
102 } 107 }
103 *ptr = NULL; /* reset when done */ 108 *ptr = NULL; /* reset when done */
104 if ( (0 == stat (&url[1], &buf)) && 109
105 (S_ISREG (buf.st_mode)) ) 110 file = fopen (&url[1], "rb");
106 file = fopen (&url[1], "rb"); 111 if (NULL != file)
107 else 112 {
108 file = NULL; 113 fd = fileno (file);
109 if (file == NULL) 114 if (-1 == fd)
115 {
116 (void) fclose (file);
117 return MHD_NO; /* internal error */
118 }
119 if ( (0 != fstat (fd, &buf)) ||
120 (! S_ISREG (buf.st_mode)) )
121 {
122 /* not a regular file, refuse to serve */
123 fclose (file);
124 file = NULL;
125 }
126 }
127
128 if (NULL == file)
110 { 129 {
111 dir = opendir ("."); 130 dir = opendir (".");
112 if (dir == NULL) 131 if (NULL == dir)
113 { 132 {
114 /* most likely cause: more concurrent requests than 133 /* most likely cause: more concurrent requests than
115 available file descriptors / 2 */ 134 available file descriptors / 2 */
116 snprintf (emsg, 135 snprintf (emsg,
117 sizeof (emsg), 136 sizeof (emsg),
@@ -120,9 +139,11 @@ ahc_echo (void *cls,
120 response = MHD_create_response_from_buffer (strlen (emsg), 139 response = MHD_create_response_from_buffer (strlen (emsg),
121 emsg, 140 emsg,
122 MHD_RESPMEM_MUST_COPY); 141 MHD_RESPMEM_MUST_COPY);
123 if (response == NULL) 142 if (NULL == response)
124 return MHD_NO; 143 return MHD_NO;
125 ret = MHD_queue_response (connection, MHD_HTTP_SERVICE_UNAVAILABLE, response); 144 ret = MHD_queue_response (connection,
145 MHD_HTTP_SERVICE_UNAVAILABLE,
146 response);
126 MHD_destroy_response (response); 147 MHD_destroy_response (response);
127 } 148 }
128 else 149 else
@@ -132,7 +153,7 @@ ahc_echo (void *cls,
132 &dir_reader, 153 &dir_reader,
133 dir, 154 dir,
134 &dir_free_callback); 155 &dir_free_callback);
135 if (response == NULL) 156 if (NULL == response)
136 { 157 {
137 closedir (dir); 158 closedir (dir);
138 return MHD_NO; 159 return MHD_NO;
@@ -147,7 +168,7 @@ ahc_echo (void *cls,
147 &file_reader, 168 &file_reader,
148 file, 169 file,
149 &file_free_callback); 170 &file_free_callback);
150 if (response == NULL) 171 if (NULL == response)
151 { 172 {
152 fclose (file); 173 fclose (file);
153 return MHD_NO; 174 return MHD_NO;
@@ -158,6 +179,7 @@ ahc_echo (void *cls,
158 return ret; 179 return ret;
159} 180}
160 181
182
161int 183int
162main (int argc, char *const *argv) 184main (int argc, char *const *argv)
163{ 185{
@@ -171,7 +193,7 @@ main (int argc, char *const *argv)
171 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, 193 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
172 atoi (argv[1]), 194 atoi (argv[1]),
173 NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END); 195 NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END);
174 if (d == NULL) 196 if (NULL == d)
175 return 1; 197 return 1;
176 (void) getc (stdin); 198 (void) getc (stdin);
177 MHD_stop_daemon (d); 199 MHD_stop_daemon (d);