aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2026-01-29 02:39:31 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2026-01-29 02:39:31 +0100
commit768ab5384ced12cb263fcfc7fba23cebf705c15f (patch)
treee9a1ebec64733350ff5f10cd1f04713e3e2ce757
parentdf1ef312a081a7aa9e16ef21020ee895aa5ab893 (diff)
downloadbusybox-w32-768ab5384ced12cb263fcfc7fba23cebf705c15f.tar.gz
busybox-w32-768ab5384ced12cb263fcfc7fba23cebf705c15f.tar.bz2
busybox-w32-768ab5384ced12cb263fcfc7fba23cebf705c15f.zip
httpd: do not use a global variable in index.cgi
text data bss dec hex filename 3255 0 0 3255 cb7 httpd_indexcgi.o 3253 0 4 3257 cb9 httpd_indexcgi.o.old Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/httpd_indexcgi.c127
1 files changed, 53 insertions, 74 deletions
diff --git a/networking/httpd_indexcgi.c b/networking/httpd_indexcgi.c
index 2e4e0b80e..aeed8ccb1 100644
--- a/networking/httpd_indexcgi.c
+++ b/networking/httpd_indexcgi.c
@@ -152,44 +152,16 @@ static int compare_dl(dir_list_t **aa, dir_list_t **bb)
152 return strcmp(a->d_name, b->d_name); 152 return strcmp(a->d_name, b->d_name);
153} 153}
154 154
155enum {
156 /* Must be >= 64k (all Linux arches have pages <= 64k) */
157 BUFFER_SIZE = 8 * 1024*1024,
158//one dirent is typically <= 100 bytes, 1M is enough for ~10k files
159//FIXME: change code to *iterate* getdents64 if need to support giant file lists
160};
161
162static char *buffer;
163#if 0
164/* Use global "dst" pointer */
165static char *dst;
166# define INIT_DST dst = buffer;
167# define CHARP void
168# define CHARP_DST /*nothing*/
169# define DST /*nothing*/
170# define SET_DST /*nothing*/
171# define RETURN_DST ((void)0)
172#else
173/* Propagate "dst" pointer as parameter */
174/* This is usually more efficient (uses a register for it) */
175# define INIT_DST char *dst = buffer;
176# define CHARP char*
177# define CHARP_DST char *dst,
178# define DST dst,
179# define SET_DST dst =
180# define RETURN_DST return dst
181#endif
182
183/* NB: formatters do not store terminating NUL! */ 155/* NB: formatters do not store terminating NUL! */
184 156
185static CHARP fmt_str(CHARP_DST const char *src) 157static char *fmt_str(char *dst, const char *src)
186{ 158{
187 unsigned len = strlen(src); 159 unsigned len = strlen(src);
188 dst = mempcpy(dst, src, len); 160 dst = mempcpy(dst, src, len);
189 RETURN_DST; 161 return dst;
190} 162}
191 163
192static CHARP fmt_url(CHARP_DST const char *name) 164static char *fmt_url(char *dst, const char *name)
193{ 165{
194 while (*name) { 166 while (*name) {
195 unsigned c = (unsigned char)*name++; 167 unsigned c = (unsigned char)*name++;
@@ -203,29 +175,29 @@ static CHARP fmt_url(CHARP_DST const char *name)
203 } 175 }
204 *dst++ = c; 176 *dst++ = c;
205 } 177 }
206 RETURN_DST; 178 return dst;
207} 179}
208 180
209static CHARP fmt_html(CHARP_DST const char *name) 181static char *fmt_html(char *dst, const char *name)
210{ 182{
211 while (*name) { 183 while (*name) {
212 char c = *name++; 184 char c = *name++;
213 if (c == '<') 185 if (c == '<')
214 SET_DST fmt_str(DST "&lt;"); 186 dst = fmt_str(dst, "&lt;");
215 else if (c == '>') 187 else if (c == '>')
216 SET_DST fmt_str(DST "&gt;"); 188 dst = fmt_str(dst, "&gt;");
217 else if (c == '&') { 189 else if (c == '&') {
218 SET_DST fmt_str(DST "&amp;"); 190 dst = fmt_str(dst, "&amp;");
219 } else { 191 } else {
220 *dst++ = c; 192 *dst++ = c;
221 continue; 193 continue;
222 } 194 }
223 } 195 }
224 RETURN_DST; 196 return dst;
225} 197}
226 198
227/* HEADROOM bytes are available after dst after this call */ 199/* HEADROOM bytes are available after dst after this call */
228static CHARP fmt_ull(CHARP_DST unsigned long long n) 200static char *fmt_ull(char *dst, unsigned long long n)
229{ 201{
230 char buf[sizeof(n)*3 + 2]; 202 char buf[sizeof(n)*3 + 2];
231 char *p; 203 char *p;
@@ -236,29 +208,37 @@ static CHARP fmt_ull(CHARP_DST unsigned long long n)
236 *--p = (n % 10) + '0'; 208 *--p = (n % 10) + '0';
237 n /= 10; 209 n /= 10;
238 } while (n); 210 } while (n);
239 SET_DST fmt_str(DST p); 211 dst = fmt_str(dst, p);
240 RETURN_DST; 212 return dst;
241} 213}
242 214
243static CHARP fmt_02u(CHARP_DST unsigned n) 215static char *fmt_02u(char *dst, unsigned n)
244{ 216{
245 /* n %= 100; - not needed, callers don't pass big n */ 217 /* n %= 100; - not needed, callers don't pass big n */
246 dst[0] = (n / 10) + '0'; 218 dst[0] = (n / 10) + '0';
247 dst[1] = (n % 10) + '0'; 219 dst[1] = (n % 10) + '0';
248 dst += 2; 220 dst += 2;
249 RETURN_DST; 221 return dst;
250} 222}
251 223
252static CHARP fmt_04u(CHARP_DST unsigned n) 224static char *fmt_04u(char *dst, unsigned n)
253{ 225{
254 /* n %= 10000; - not needed, callers don't pass big n */ 226 /* n %= 10000; - not needed, callers don't pass big n */
255 SET_DST fmt_02u(DST n / 100); 227 dst = fmt_02u(dst, n / 100);
256 SET_DST fmt_02u(DST n % 100); 228 dst = fmt_02u(dst, n % 100);
257 RETURN_DST; 229 return dst;
258} 230}
259 231
232enum {
233 /* Must be >= 64k (all Linux arches have pages <= 64k) */
234 BUFFER_SIZE = 8 * 1024*1024,
235//one dirent is typically <= 100 bytes, 1M is enough for ~10k files
236//FIXME: change code to *iterate* getdents64 if need to support giant file lists
237};
238
260int main(int argc, char **argv) 239int main(int argc, char **argv)
261{ 240{
241 char *buffer, *dst;
262 char *location; 242 char *location;
263 dir_list_t **dir_list; 243 dir_list_t **dir_list;
264 dir_list_t *cdir; 244 dir_list_t *cdir;
@@ -343,22 +323,22 @@ int main(int argc, char **argv)
343 qsort(dir_list, dir_list_count, sizeof(dir_list[0]), (void*)compare_dl); 323 qsort(dir_list, dir_list_count, sizeof(dir_list[0]), (void*)compare_dl);
344 324
345 buffer += 2*BUFFER_SIZE; 325 buffer += 2*BUFFER_SIZE;
346 { 326 dst = buffer;
347 INIT_DST 327
348 SET_DST fmt_str(DST 328 dst = fmt_str(dst,
349 "" /* Additional headers (currently none) */ 329 "" /* Additional headers (currently none) */
350 "\r\n" /* Mandatory empty line after headers */ 330 "\r\n" /* Mandatory empty line after headers */
351 "<html><head><title>Index of "); 331 "<html><head><title>Index of ");
352 /* Guard against directories with &, > etc */ 332 /* Guard against directories with &, > etc */
353 SET_DST fmt_html(DST location); 333 dst = fmt_html(dst, location);
354 SET_DST fmt_str(DST 334 dst = fmt_str(dst,
355 "</title>\n" 335 "</title>\n"
356 STYLE_STR 336 STYLE_STR
357 "</head>" "\n" 337 "</head>" "\n"
358 "<body>" "\n" 338 "<body>" "\n"
359 "<h1>Index of "); 339 "<h1>Index of ");
360 SET_DST fmt_html(DST location); 340 dst = fmt_html(dst, location);
361 SET_DST fmt_str(DST 341 dst = fmt_str(dst,
362 "</h1>" "\n" 342 "</h1>" "\n"
363 "<table>" "\n" 343 "<table>" "\n"
364 "<col class=nm><col class=sz><col class=dt>" "\n" 344 "<col class=nm><col class=sz><col class=dt>" "\n"
@@ -382,30 +362,30 @@ int main(int argc, char **argv)
382 continue; 362 continue;
383//fprintf(stderr, "%d '%s'\n", dir_list_count, cdir->d_name); 363//fprintf(stderr, "%d '%s'\n", dir_list_count, cdir->d_name);
384 364
385 SET_DST fmt_str(DST "<tr><td class=nm><a href='"); 365 dst = fmt_str(dst, "<tr><td class=nm><a href='");
386 SET_DST fmt_url(DST cdir->d_name); /* %20 etc */ 366 dst = fmt_url(dst, cdir->d_name); /* %20 etc */
387 if (S_ISDIR(cdir->D_MODE)) 367 if (S_ISDIR(cdir->D_MODE))
388 *dst++ = '/'; 368 *dst++ = '/';
389 SET_DST fmt_str(DST "'>"); 369 dst = fmt_str(dst, "'>");
390 SET_DST fmt_html(DST cdir->d_name); /* &lt; etc */ 370 dst = fmt_html(dst, cdir->d_name); /* &lt; etc */
391 if (S_ISDIR(cdir->D_MODE)) 371 if (S_ISDIR(cdir->D_MODE))
392 *dst++ = '/'; 372 *dst++ = '/';
393 SET_DST fmt_str(DST "</a><td class=sz>"); 373 dst = fmt_str(dst, "</a><td class=sz>");
394 if (S_ISREG(cdir->D_MODE)) 374 if (S_ISREG(cdir->D_MODE))
395 SET_DST fmt_ull(DST cdir->D_SIZE); 375 dst = fmt_ull(dst, cdir->D_SIZE);
396 SET_DST fmt_str(DST "<td class=dt>"); 376 dst = fmt_str(dst, "<td class=dt>");
397 if (sizeof(cdir->D_MTIME) == sizeof(tt)) 377 if (sizeof(cdir->D_MTIME) == sizeof(tt))
398 ptm = gmtime((time_t*)&cdir->D_MTIME); 378 ptm = gmtime((time_t*)&cdir->D_MTIME);
399 else { 379 else {
400 tt = cdir->D_MTIME; 380 tt = cdir->D_MTIME;
401 ptm = gmtime(&tt); 381 ptm = gmtime(&tt);
402 } 382 }
403 SET_DST fmt_04u(DST 1900 + ptm->tm_year); *dst++ = '-'; 383 dst = fmt_04u(dst, 1900 + ptm->tm_year); *dst++ = '-';
404 SET_DST fmt_02u(DST ptm->tm_mon + 1); *dst++ = '-'; 384 dst = fmt_02u(dst, ptm->tm_mon + 1); *dst++ = '-';
405 SET_DST fmt_02u(DST ptm->tm_mday); *dst++ = ' '; 385 dst = fmt_02u(dst, ptm->tm_mday); *dst++ = ' ';
406 SET_DST fmt_02u(DST ptm->tm_hour); *dst++ = ':'; 386 dst = fmt_02u(dst, ptm->tm_hour); *dst++ = ':';
407 SET_DST fmt_02u(DST ptm->tm_min); *dst++ = ':'; 387 dst = fmt_02u(dst, ptm->tm_min); *dst++ = ':';
408 SET_DST fmt_02u(DST ptm->tm_sec); 388 dst = fmt_02u(dst, ptm->tm_sec);
409 *dst++ = '\n'; 389 *dst++ = '\n';
410 390
411 /* Flush after every 256 files (typically around 50k of output) */ 391 /* Flush after every 256 files (typically around 50k of output) */
@@ -415,18 +395,17 @@ int main(int argc, char **argv)
415 } 395 }
416 } 396 }
417 397
418 SET_DST fmt_str(DST "<tr class=foot><th class=cnt>Files: "); 398 dst = fmt_str(dst, "<tr class=foot><th class=cnt>Files: ");
419 SET_DST fmt_ull(DST count_files); 399 dst = fmt_ull(dst, count_files);
420 /* count_dirs - 1: we don't want to count ".." */ 400 /* count_dirs - 1: we don't want to count ".." */
421 SET_DST fmt_str(DST ", directories: "); 401 dst = fmt_str(dst, ", directories: ");
422 SET_DST fmt_ull(DST count_dirs - 1); 402 dst = fmt_ull(dst, count_dirs - 1);
423 SET_DST fmt_str(DST "<th class=sz>"); 403 dst = fmt_str(dst, "<th class=sz>");
424 SET_DST fmt_ull(DST size_total); 404 dst = fmt_ull(dst, size_total);
425 SET_DST fmt_str(DST "<th class=dt>\n"); 405 dst = fmt_str(dst, "<th class=dt>\n");
426 /* "</table></body></html>" - why bother? */ 406 /* "</table></body></html>" - why bother? */
427 407
428 full_write(STDOUT_FILENO, buffer, dst - buffer); 408 full_write(STDOUT_FILENO, buffer, dst - buffer);
429 409
430 return 0; 410 return 0;
431 }
432} 411}