ReactOS 0.4.16-dev-306-g647d351
makefsdata.c
Go to the documentation of this file.
1
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17#include <time.h>
18#include <sys/stat.h>
19
20#include "tinydir.h"
21
28#ifndef MAKEFS_SUPPORT_DEFLATE
29#define MAKEFS_SUPPORT_DEFLATE 0
30#ifndef MAKEFS_SUPPORT_DEFLATE_ZLIB
31#define MAKEFS_SUPPORT_DEFLATE_ZLIB 0
32#endif /* MAKEFS_SUPPORT_DEFLATE_ZLIB */
33#endif /* MAKEFS_SUPPORT_DEFLATE */
34
35#define COPY_BUFSIZE (1024*1024) /* 1 MByte */
36
37#if MAKEFS_SUPPORT_DEFLATE
38#if MAKEFS_SUPPORT_DEFLATE_ZLIB
39#include <zlib.h>
40#else
41#include "../miniz.c"
42#endif /* MAKEFS_SUPPORT_DEFLATE */
43
44typedef unsigned char uint8;
45typedef unsigned short uint16;
46typedef unsigned int uint;
47
48#define my_max(a,b) (((a) > (b)) ? (a) : (b))
49#define my_min(a,b) (((a) < (b)) ? (a) : (b))
50
51/* COMP_OUT_BUF_SIZE is the size of the output buffer used during compression.
52 COMP_OUT_BUF_SIZE must be >= 1 and <= OUT_BUF_SIZE */
53#define COMP_OUT_BUF_SIZE COPY_BUFSIZE
54
55/* OUT_BUF_SIZE is the size of the output buffer used during decompression.
56 OUT_BUF_SIZE must be a power of 2 >= TINFL_LZ_DICT_SIZE (because the low-level decompressor not only writes, but reads from the output buffer as it decompresses) */
57#define OUT_BUF_SIZE COPY_BUFSIZE
58static uint8 s_outbuf[OUT_BUF_SIZE];
59static uint8 s_checkbuf[OUT_BUF_SIZE];
60
61#ifndef MAKEFS_SUPPORT_DEFLATE_ZLIB
62/* tdefl_compressor contains all the state needed by the low-level compressor so it's a pretty big struct (~300k).
63 This example makes it a global vs. putting it on the stack, of course in real-world usage you'll probably malloc() or new it. */
64tdefl_compressor g_deflator;
65#endif /* MAKEFS_SUPPORT_DEFLATE_ZLIB */
66
67static int deflate_level; /* default compression level, can be changed via command line */
68#define USAGE_ARG_DEFLATE " [-defl<:compr_level>]"
69#else /* MAKEFS_SUPPORT_DEFLATE */
70#define USAGE_ARG_DEFLATE ""
71#endif /* MAKEFS_SUPPORT_DEFLATE */
72
73#ifdef WIN32
74
75#define GETCWD(path, len) GetCurrentDirectoryA(len, path)
76#define GETCWD_SUCCEEDED(ret) (ret != 0)
77#define CHDIR(path) SetCurrentDirectoryA(path)
78#define CHDIR_SUCCEEDED(ret) (ret == TRUE)
79
80#elif __linux__
81
82#define GETCWD(path, len) getcwd(path, len)
83#define GETCWD_SUCCEEDED(ret) (ret != NULL)
84#define CHDIR(path) chdir(path)
85#define CHDIR_SUCCEEDED(ret) (ret == 0)
86
87#else
88
89#error makefsdata not supported on this platform
90
91#endif
92
93#define NEWLINE "\r\n"
94#define NEWLINE_LEN 2
95
96/* Define this here since we don't include any external C files and ports might override it */
97#define LWIP_PLATFORM_ASSERT(x) do {printf("Assertion \"%s\" failed at line %d in %s\n", \
98 x, __LINE__, __FILE__); fflush(NULL); abort();} while(0)
99
100/* define this to get the header variables we use to build HTTP headers */
101#define LWIP_HTTPD_DYNAMIC_HEADERS 1
102#define LWIP_HTTPD_SSI 1
103#include "lwip/init.h"
104#include "../httpd_structs.h"
105#include "lwip/apps/fs.h"
106
107#include "../core/inet_chksum.c"
108#include "../core/def.c"
109
111static const char *serverID = "Server: "HTTPD_SERVER_AGENT"\r\n";
112static char serverIDBuffer[1024];
113
114/* change this to suit your MEM_ALIGNMENT */
115#define PAYLOAD_ALIGNMENT 4
116/* set this to 0 to prevent aligning payload */
117#define ALIGN_PAYLOAD 1
118/* define this to a type that has the required alignment */
119#define PAYLOAD_ALIGN_TYPE "unsigned int"
121
122#define HEX_BYTES_PER_LINE 16
123
124#define MAX_PATH_LEN 256
125
128 const char *filename_c;
129};
130
131int process_sub(FILE *data_file, FILE *struct_file);
132int process_file(FILE *data_file, FILE *struct_file, const char *filename);
133int file_write_http_header(FILE *data_file, const char *filename, int file_size, u16_t *http_hdr_len,
134 u16_t *http_hdr_chksum, u8_t provide_content_len, int is_compressed);
135int file_put_ascii(FILE *file, const char *ascii_string, int len, int *i);
136int s_put_ascii(char *buf, const char *ascii_string, int len, int *i);
137void concat_files(const char *file1, const char *file2, const char *targetfile);
138int check_path(char *path, size_t size);
139static int checkSsiByFilelist(const char* filename_listfile);
140static int ext_in_list(const char* filename, const char *ext_list);
141static int file_to_exclude(const char* filename);
142static int file_can_be_compressed(const char* filename);
143
144/* 5 bytes per char + 3 bytes per line */
146
147static char curSubdir[MAX_PATH_LEN-3];
149static char hdr_buf[4096];
150
151static unsigned char processSubs = 1;
152static unsigned char includeHttpHeader = 1;
153static unsigned char useHttp11 = 0;
154static unsigned char supportSsi = 1;
155static unsigned char precalcChksum = 0;
156static unsigned char includeLastModified = 0;
157#if MAKEFS_SUPPORT_DEFLATE
158static unsigned char deflateNonSsiFiles = 0;
159static size_t deflatedBytesReduced = 0;
160static size_t overallDataBytes = 0;
161#endif
162static const char *exclude_list = NULL;
163static const char *ncompress_list = NULL;
164
165static struct file_entry *first_file = NULL;
166static struct file_entry *last_file = NULL;
167
168static char *ssi_file_buffer;
169static char **ssi_file_lines;
170static size_t ssi_file_num_lines;
171
172static void print_usage(void)
173{
174 printf(" Usage: htmlgen [targetdir] [-s] [-e] [-11] [-nossi] [-ssi:<filename>] [-c] [-f:<filename>] [-m] [-svr:<name>] [-x:<ext_list>] [-xc:<ext_list>" USAGE_ARG_DEFLATE NEWLINE NEWLINE);
175 printf(" targetdir: relative or absolute path to files to convert" NEWLINE);
176 printf(" switch -s: toggle processing of subdirectories (default is on)" NEWLINE);
177 printf(" switch -e: exclude HTTP header from file (header is created at runtime, default is off)" NEWLINE);
178 printf(" switch -11: include HTTP 1.1 header (1.0 is default)" NEWLINE);
179 printf(" switch -nossi: no support for SSI (cannot calculate Content-Length for SSI)" NEWLINE);
180 printf(" switch -ssi: ssi filename (ssi support controlled by file list, not by extension)" NEWLINE);
181 printf(" switch -c: precalculate checksums for all pages (default is off)" NEWLINE);
182 printf(" switch -f: target filename (default is \"fsdata.c\")" NEWLINE);
183 printf(" switch -m: include \"Last-Modified\" header based on file time" NEWLINE);
184 printf(" switch -svr: server identifier sent in HTTP response header ('Server' field)" NEWLINE);
185 printf(" switch -x: comma separated list of extensions of files to exclude (e.g., -x:json,txt)" NEWLINE);
186 printf(" switch -xc: comma separated list of extensions of files to not compress (e.g., -xc:mp3,jpg)" NEWLINE);
187#if MAKEFS_SUPPORT_DEFLATE
188 printf(" switch -defl: deflate-compress all non-SSI files (with opt. compr.-level, default=10)" NEWLINE);
189 printf(" ATTENTION: browser has to support \"Content-Encoding: deflate\"!" NEWLINE);
190#endif
191 printf(" if targetdir not specified, htmlgen will attempt to" NEWLINE);
192 printf(" process files in subdirectory 'fs'" NEWLINE);
193}
194
195int main(int argc, char *argv[])
196{
197 char path[MAX_PATH_LEN];
198 char appPath[MAX_PATH_LEN];
199 FILE *data_file;
200 FILE *struct_file;
201 int filesProcessed;
202 int i;
203 char targetfile[MAX_PATH_LEN];
204 strcpy(targetfile, "fsdata.c");
205
206 memset(path, 0, sizeof(path));
207 memset(appPath, 0, sizeof(appPath));
208
209 printf(NEWLINE " makefsdata v" LWIP_VERSION_STRING " - HTML to C source converter" NEWLINE);
210 printf(" by Jim Pettinato - circa 2003 " NEWLINE);
211 printf(" extended by Simon Goldschmidt - 2009 " NEWLINE NEWLINE);
212
213 LWIP_ASSERT("sizeof(hdr_buf) must fit into an u16_t", sizeof(hdr_buf) <= 0xffff);
214
215 strcpy(path, "fs");
216 for (i = 1; i < argc; i++) {
217 if (argv[i] == NULL) {
218 continue;
219 }
220 if (argv[i][0] == '-') {
221 if (strstr(argv[i], "-svr:") == argv[i]) {
222 snprintf(serverIDBuffer, sizeof(serverIDBuffer), "Server: %s\r\n", &argv[i][5]);
224 printf("Using Server-ID: \"%s\"\n", serverID);
225 } else if (!strcmp(argv[i], "-s")) {
226 processSubs = 0;
227 } else if (!strcmp(argv[i], "-e")) {
229 } else if (!strcmp(argv[i], "-11")) {
230 useHttp11 = 1;
231 } else if (!strcmp(argv[i], "-nossi")) {
232 supportSsi = 0;
233 } else if (strstr(argv[i], "-ssi:") == argv[i]) {
234 const char* ssi_list_filename = &argv[i][5];
235 if (checkSsiByFilelist(ssi_list_filename)) {
236 printf("Reading list of SSI files from \"%s\"\n", ssi_list_filename);
237 } else {
238 printf("Failed to load list of SSI files from \"%s\"\n", ssi_list_filename);
239 }
240 } else if (!strcmp(argv[i], "-c")) {
241 precalcChksum = 1;
242 } else if (strstr(argv[i], "-f:") == argv[i]) {
243 strncpy(targetfile, &argv[i][3], sizeof(targetfile) - 1);
244 targetfile[sizeof(targetfile) - 1] = 0;
245 printf("Writing to file \"%s\"\n", targetfile);
246 } else if (!strcmp(argv[i], "-m")) {
248 } else if (strstr(argv[i], "-defl") == argv[i]) {
249#if MAKEFS_SUPPORT_DEFLATE
250 const char *colon = &argv[i][5];
251 if (*colon == ':') {
252 int defl_level = atoi(&colon[1]);
253 if ((colon[1] != 0) && (defl_level >= 0) && (defl_level <= 10)) {
254 deflate_level = defl_level;
255 } else {
256 printf("ERROR: deflate level must be [0..10]" NEWLINE);
257 exit(0);
258 }
259 } else {
260 /* default to highest compression */
261 deflate_level = 10;
262 }
263 deflateNonSsiFiles = 1;
264 printf("Deflating all non-SSI files with level %d (but only if size is reduced)" NEWLINE, deflate_level);
265#else
266 printf("WARNING: Deflate support is disabled\n");
267#endif
268 } else if (strstr(argv[i], "-x:") == argv[i]) {
269 exclude_list = &argv[i][3];
270 printf("Excluding files with extensions %s" NEWLINE, exclude_list);
271 } else if (strstr(argv[i], "-xc:") == argv[i]) {
272 ncompress_list = &argv[i][4];
273 printf("Skipping compression for files with extensions %s" NEWLINE, ncompress_list);
274 } else if ((strstr(argv[i], "-?")) || (strstr(argv[i], "-h"))) {
275 print_usage();
276 exit(0);
277 }
278 } else if ((argv[i][0] == '/') && (argv[i][1] == '?') && (argv[i][2] == 0)) {
279 print_usage();
280 exit(0);
281 } else {
282 strncpy(path, argv[i], sizeof(path) - 1);
283 path[sizeof(path) - 1] = 0;
284 }
285 }
286
287 if (!check_path(path, sizeof(path))) {
288 printf("Invalid path: \"%s\"." NEWLINE, path);
289 exit(-1);
290 }
291
292 if(!GETCWD_SUCCEEDED(GETCWD(appPath, MAX_PATH_LEN))) {
293 printf("Unable to get current dir." NEWLINE);
294 exit(-1);
295 }
296 /* if command line param or subdir named 'fs' not found spout usage verbiage */
297 if (!CHDIR_SUCCEEDED(CHDIR(path))) {
298 /* if no subdir named 'fs' (or the one which was given) exists, spout usage verbiage */
299 printf(" Failed to open directory \"%s\"." NEWLINE NEWLINE, path);
300 print_usage();
301 exit(-1);
302 }
303 if(!CHDIR_SUCCEEDED(CHDIR(appPath))) {
304 printf("Invalid path: \"%s\"." NEWLINE, appPath);
305 exit(-1);
306 }
307
308 printf("HTTP %sheader will %s statically included." NEWLINE,
309 (includeHttpHeader ? (useHttp11 ? "1.1 " : "1.0 ") : ""),
310 (includeHttpHeader ? "be" : "not be"));
311
312 curSubdir[0] = '\0'; /* start off in web page's root directory - relative paths */
313 printf(" Processing all files in directory %s", path);
314 if (processSubs) {
315 printf(" and subdirectories..." NEWLINE NEWLINE);
316 } else {
317 printf("..." NEWLINE NEWLINE);
318 }
319
320 data_file = fopen("fsdata.tmp", "wb");
321 if (data_file == NULL) {
322 printf("Failed to create file \"fsdata.tmp\"\n");
323 exit(-1);
324 }
325 struct_file = fopen("fshdr.tmp", "wb");
326 if (struct_file == NULL) {
327 printf("Failed to create file \"fshdr.tmp\"\n");
328 fclose(data_file);
329 exit(-1);
330 }
331
332 if(!CHDIR_SUCCEEDED(CHDIR(path))) {
333 printf("Invalid path: \"%s\"." NEWLINE, path);
334 exit(-1);
335 }
336
337 fprintf(data_file, "#include \"lwip/apps/fs.h\"" NEWLINE);
338 fprintf(data_file, "#include \"lwip/def.h\"" NEWLINE NEWLINE NEWLINE);
339
340 fprintf(data_file, "#define file_NULL (struct fsdata_file *) NULL" NEWLINE NEWLINE NEWLINE);
341 /* define FS_FILE_FLAGS_HEADER_INCLUDED to 1 if not defined (compatibility with older httpd/fs) */
342 fprintf(data_file, "#ifndef FS_FILE_FLAGS_HEADER_INCLUDED" NEWLINE "#define FS_FILE_FLAGS_HEADER_INCLUDED 1" NEWLINE "#endif" NEWLINE);
343 /* define FS_FILE_FLAGS_HEADER_PERSISTENT to 0 if not defined (compatibility with older httpd/fs: wasn't supported back then) */
344 fprintf(data_file, "#ifndef FS_FILE_FLAGS_HEADER_PERSISTENT" NEWLINE "#define FS_FILE_FLAGS_HEADER_PERSISTENT 0" NEWLINE "#endif" NEWLINE);
345
346 /* define alignment defines */
347#if ALIGN_PAYLOAD
348 fprintf(data_file, "/* FSDATA_FILE_ALIGNMENT: 0=off, 1=by variable, 2=by include */" NEWLINE "#ifndef FSDATA_FILE_ALIGNMENT" NEWLINE "#define FSDATA_FILE_ALIGNMENT 0" NEWLINE "#endif" NEWLINE);
349#endif
350 fprintf(data_file, "#ifndef FSDATA_ALIGN_PRE" NEWLINE "#define FSDATA_ALIGN_PRE" NEWLINE "#endif" NEWLINE);
351 fprintf(data_file, "#ifndef FSDATA_ALIGN_POST" NEWLINE "#define FSDATA_ALIGN_POST" NEWLINE "#endif" NEWLINE);
352#if ALIGN_PAYLOAD
353 fprintf(data_file, "#if FSDATA_FILE_ALIGNMENT==2" NEWLINE "#include \"fsdata_alignment.h\"" NEWLINE "#endif" NEWLINE);
354#endif
355
356 sprintf(lastFileVar, "NULL");
357
358 filesProcessed = process_sub(data_file, struct_file);
359
360 /* data_file now contains all of the raw data.. now append linked list of
361 * file header structs to allow embedded app to search for a file name */
362 fprintf(data_file, NEWLINE NEWLINE);
363 fprintf(struct_file, "#define FS_ROOT file_%s" NEWLINE, lastFileVar);
364 fprintf(struct_file, "#define FS_NUMFILES %d" NEWLINE NEWLINE, filesProcessed);
365
366 fclose(data_file);
367 fclose(struct_file);
368
369 if(!CHDIR_SUCCEEDED(CHDIR(appPath))) {
370 printf("Invalid path: \"%s\"." NEWLINE, appPath);
371 exit(-1);
372 }
373
374 /* append struct_file to data_file */
375 printf(NEWLINE "Creating target file..." NEWLINE NEWLINE);
376 concat_files("fsdata.tmp", "fshdr.tmp", targetfile);
377
378 /* if succeeded, delete the temporary files */
379 if (remove("fsdata.tmp") != 0) {
380 printf("Warning: failed to delete fsdata.tmp\n");
381 }
382 if (remove("fshdr.tmp") != 0) {
383 printf("Warning: failed to delete fshdr.tmp\n");
384 }
385
386 printf(NEWLINE "Processed %d files - done." NEWLINE, filesProcessed);
387#if MAKEFS_SUPPORT_DEFLATE
388 if (deflateNonSsiFiles) {
389 printf("(Deflated total byte reduction: %d bytes -> %d bytes (%.02f%%)" NEWLINE,
390 (int)overallDataBytes, (int)deflatedBytesReduced, (float)((deflatedBytesReduced * 100.0) / overallDataBytes));
391 }
392#endif
394
395 while (first_file != NULL) {
396 struct file_entry *fe = first_file;
397 first_file = fe->next;
398 free(fe);
399 }
400
401 if (ssi_file_buffer) {
403 }
404 if (ssi_file_lines) {
406 }
407
408 return 0;
409}
410
411int check_path(char *path, size_t size)
412{
413 size_t slen;
414 if (path[0] == 0) {
415 /* empty */
416 return 0;
417 }
418 slen = strlen(path);
419 if (slen >= size) {
420 /* not NULL-terminated */
421 return 0;
422 }
423 while ((slen > 0) && ((path[slen] == '\\') || (path[slen] == '/'))) {
424 /* path should not end with trailing backslash */
425 path[slen] = 0;
426 slen--;
427 }
428 if (slen == 0) {
429 return 0;
430 }
431 return 1;
432}
433
434static void copy_file(const char *filename_in, FILE *fout)
435{
436 FILE *fin;
437 size_t len;
438 void *buf;
439 fin = fopen(filename_in, "rb");
440 if (fin == NULL) {
441 printf("Failed to open file \"%s\"\n", filename_in);
442 exit(-1);
443 }
445 while ((len = fread(buf, 1, COPY_BUFSIZE, fin)) > 0) {
446 fwrite(buf, 1, len, fout);
447 }
448 free(buf);
449 fclose(fin);
450}
451
452void concat_files(const char *file1, const char *file2, const char *targetfile)
453{
454 FILE *fout;
455 fout = fopen(targetfile, "wb");
456 if (fout == NULL) {
457 printf("Failed to open file \"%s\"\n", targetfile);
458 exit(-1);
459 }
460 copy_file(file1, fout);
461 copy_file(file2, fout);
462 fclose(fout);
463}
464
465int process_sub(FILE *data_file, FILE *struct_file)
466{
468 int filesProcessed = 0;
469
470 if (processSubs) {
471 /* process subs recursively */
472 size_t sublen = strlen(curSubdir);
473 size_t freelen = sizeof(curSubdir) - sublen - 1;
474 int ret;
475 LWIP_ASSERT("sublen < sizeof(curSubdir)", sublen < sizeof(curSubdir));
476
478
479 if (ret == 0) {
480 unsigned int i;
481 for (i = 0; i < dir.n_files; i++) {
483
485
486 if (ret == 0) {
487#if (defined _MSC_VER || defined __MINGW32__) && (defined _UNICODE)
488 size_t num_char_converted;
489 char currName[256];
490 wcstombs_s(&num_char_converted, currName, sizeof(currName), file.name, sizeof(currName));
491#else
492 const char *currName = file.name;
493#endif
494
495 if (currName[0] == '.') {
496 continue;
497 }
498 if (!file.is_dir) {
499 continue;
500 }
501 if (freelen > 0) {
502 if(!CHDIR_SUCCEEDED(CHDIR(currName))) {
503 printf("Invalid path: \"%s\"." NEWLINE, currName);
504 exit(-1);
505 }
506 strncat(curSubdir, "/", freelen);
507 strncat(curSubdir, currName, freelen - 1);
508 curSubdir[sizeof(curSubdir) - 1] = 0;
509 printf("processing subdirectory %s/..." NEWLINE, curSubdir);
510 filesProcessed += process_sub(data_file, struct_file);
511 if(!CHDIR_SUCCEEDED(CHDIR(".."))) {
512 printf("Unable to get back to parent dir of: \"%s\"." NEWLINE, currName);
513 exit(-1);
514 }
515 curSubdir[sublen] = 0;
516 } else {
517 printf("WARNING: cannot process sub due to path length restrictions: \"%s/%s\"\n", curSubdir, currName);
518 }
519 }
520 }
521 }
522
524 if (ret == 0) {
525 unsigned int i;
526 for (i = 0; i < dir.n_files; i++) {
528
530
531 if (ret == 0) {
532 if (!file.is_dir) {
533#if (defined _MSC_VER || defined __MINGW32__) && (defined _UNICODE)
534 size_t num_char_converted;
535 char curName[256];
536 wcstombs_s(&num_char_converted, curName, sizeof(curName), file.name, sizeof(curName));
537#else
538 const char *curName = file.name;
539#endif
540
541 if (strcmp(curName, "fsdata.tmp") == 0) {
542 continue;
543 }
544 if (strcmp(curName, "fshdr.tmp") == 0) {
545 continue;
546 }
547 if (file_to_exclude(curName)) {
548 printf("skipping %s/%s by exclude list (-x option)..." NEWLINE, curSubdir, curName);
549 continue;
550 }
551
552 printf("processing %s/%s..." NEWLINE, curSubdir, curName);
553
554 if (process_file(data_file, struct_file, curName) < 0) {
555 printf(NEWLINE "Error... aborting" NEWLINE);
556 return -1;
557 }
558 filesProcessed++;
559 }
560 }
561 }
562 }
563 }
564
565 return filesProcessed;
566}
567
568static u8_t *get_file_data(const char *filename, int *file_size, int can_be_compressed, int *is_compressed)
569{
570 FILE *inFile;
571 size_t fsize = 0;
572 u8_t *buf;
573 size_t r;
574 int rs;
575 LWIP_UNUSED_ARG(r); /* for LWIP_NOASSERT */
576 inFile = fopen(filename, "rb");
577 if (inFile == NULL) {
578 printf("Failed to open file \"%s\"\n", filename);
579 exit(-1);
580 }
581 fseek(inFile, 0, SEEK_END);
582 rs = ftell(inFile);
583 if (rs < 0) {
584 printf("ftell failed with %d\n", errno);
585 exit(-1);
586 }
587 fsize = (size_t)rs;
588 fseek(inFile, 0, SEEK_SET);
589 buf = (u8_t *)malloc(fsize);
590 LWIP_ASSERT("buf != NULL", buf != NULL);
591 r = fread(buf, 1, fsize, inFile);
592 LWIP_ASSERT("r == fsize", r == fsize);
593 *file_size = fsize;
594 *is_compressed = 0;
595#if MAKEFS_SUPPORT_DEFLATE
596 overallDataBytes += fsize;
597 if (deflateNonSsiFiles) {
598 if (can_be_compressed) {
599 if (fsize < OUT_BUF_SIZE) {
600 u8_t *ret_buf;
601#ifndef MAKEFS_SUPPORT_DEFLATE_ZLIB
602 tdefl_status status;
603#else /* MAKEFS_SUPPORT_DEFLATE_ZLIB */
604 int status;
605#endif /* MAKEFS_SUPPORT_DEFLATE_ZLIB */
606 size_t in_bytes = fsize;
607 size_t out_bytes = OUT_BUF_SIZE;
608 const void *next_in = buf;
609 void *next_out = s_outbuf;
610 memset(s_outbuf, 0, sizeof(s_outbuf));
611#ifndef MAKEFS_SUPPORT_DEFLATE_ZLIB
612 /* create tdefl() compatible flags (we have to compose the low-level flags ourselves, or use tdefl_create_comp_flags_from_zip_params() but that means MINIZ_NO_ZLIB_APIS can't be defined). */
613 mz_uint comp_flags = s_tdefl_num_probes[MZ_MIN(10, deflate_level)] | ((deflate_level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0);
614 if (!deflate_level) {
615 comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS;
616 }
617 status = tdefl_init(&g_deflator, NULL, NULL, comp_flags);
618 if (status != TDEFL_STATUS_OKAY) {
619 printf("tdefl_init() failed!\n");
620 exit(-1);
621 }
622 status = tdefl_compress(&g_deflator, next_in, &in_bytes, next_out, &out_bytes, TDEFL_FINISH);
623 if (status != TDEFL_STATUS_DONE) {
624 printf("deflate failed: %d\n", status);
625 exit(-1);
626 }
627#else /* MAKEFS_SUPPORT_DEFLATE_ZLIB */
628 status = compress2(next_out, &out_bytes, next_in, in_bytes, deflate_level);
629 if (status != Z_OK) {
630 printf("deflate failed: %d\n", status);
631 exit(-1);
632 }
633#endif /* MAKEFS_SUPPORT_DEFLATE_ZLIB */
634 LWIP_ASSERT("out_bytes <= COPY_BUFSIZE", out_bytes <= OUT_BUF_SIZE);
635 if (out_bytes < fsize) {
636 ret_buf = (u8_t *)malloc(out_bytes);
637 LWIP_ASSERT("ret_buf != NULL", ret_buf != NULL);
638 memcpy(ret_buf, s_outbuf, out_bytes);
639 {
640 /* sanity-check compression be inflating and comparing to the original */
641 size_t dec_in_bytes = out_bytes;
642 size_t dec_out_bytes = OUT_BUF_SIZE;
643 next_out = s_checkbuf;
644 memset(s_checkbuf, 0, sizeof(s_checkbuf));
645#ifndef MAKEFS_SUPPORT_DEFLATE_ZLIB
646 tinfl_status dec_status;
647 tinfl_decompressor inflator;
648
649 tinfl_init(&inflator);
650 dec_status = tinfl_decompress(&inflator, (const mz_uint8 *)ret_buf, &dec_in_bytes, s_checkbuf, (mz_uint8 *)next_out, &dec_out_bytes, 0);
651 LWIP_ASSERT("tinfl_decompress failed", dec_status == TINFL_STATUS_DONE);
652#else /* MAKEFS_SUPPORT_DEFLATE_ZLIB */
653 int dec_status;
654 dec_status = uncompress2 (s_checkbuf, &dec_out_bytes, ret_buf, &dec_in_bytes);
655 LWIP_ASSERT("tinfl_decompress failed", dec_status == Z_OK);
656#endif /* MAKEFS_SUPPORT_DEFLATE_ZLIB */
657 LWIP_ASSERT("tinfl_decompress size mismatch", fsize == dec_out_bytes);
658 LWIP_ASSERT("decompressed memcmp failed", !memcmp(s_checkbuf, buf, fsize));
659 }
660 /* free original buffer, use compressed data + size */
661 free(buf);
662 buf = ret_buf;
663 *file_size = out_bytes;
664 printf(" - deflate: %d bytes -> %d bytes (%.02f%%)" NEWLINE, (int)fsize, (int)out_bytes, (float)((out_bytes * 100.0) / fsize));
665 deflatedBytesReduced += (size_t)(fsize - out_bytes);
666 *is_compressed = 1;
667 } else {
668 printf(" - uncompressed: (would be %d bytes larger using deflate)" NEWLINE, (int)(out_bytes - fsize));
669 }
670 } else {
671 printf(" - uncompressed: (file is larger than deflate buffer)" NEWLINE);
672 }
673 } else {
674 printf(" - cannot be compressed" NEWLINE);
675 }
676 }
677#else
678 LWIP_UNUSED_ARG(can_be_compressed);
679#endif
680 fclose(inFile);
681 return buf;
682}
683
684static void process_file_data(FILE *data_file, u8_t *file_data, size_t file_size)
685{
686 size_t written, i, src_off = 0;
687 size_t off = 0;
688 LWIP_UNUSED_ARG(written); /* for LWIP_NOASSERT */
689 for (i = 0; i < file_size; i++) {
690 LWIP_ASSERT("file_buffer_c overflow", off < sizeof(file_buffer_c) - 5);
691 sprintf(&file_buffer_c[off], "0x%02x,", file_data[i]);
692 off += 5;
693 if ((++src_off % HEX_BYTES_PER_LINE) == 0) {
694 LWIP_ASSERT("file_buffer_c overflow", off < sizeof(file_buffer_c) - NEWLINE_LEN);
696 off += NEWLINE_LEN;
697 }
698 if (off + 20 >= sizeof(file_buffer_c)) {
699 written = fwrite(file_buffer_c, 1, off, data_file);
700 LWIP_ASSERT("written == off", written == off);
701 off = 0;
702 }
703 }
704 written = fwrite(file_buffer_c, 1, off, data_file);
705 LWIP_ASSERT("written == off", written == off);
706}
707
708static int write_checksums(FILE *struct_file, const char *varname,
709 u16_t hdr_len, u16_t hdr_chksum, const u8_t *file_data, size_t file_size)
710{
711 int chunk_size = TCP_MSS;
712 int offset, src_offset;
713 size_t len;
714 int i = 0;
715#if LWIP_TCP_TIMESTAMPS
716 /* when timestamps are used, usable space is 12 bytes less per segment */
717 chunk_size -= 12;
718#endif
719
720 fprintf(struct_file, "#if HTTPD_PRECALCULATED_CHECKSUM" NEWLINE);
721 fprintf(struct_file, "const struct fsdata_chksum chksums_%s[] = {" NEWLINE, varname);
722
723 if (hdr_len > 0) {
724 /* add checksum for HTTP header */
725 fprintf(struct_file, "{%d, 0x%04x, %d}," NEWLINE, 0, hdr_chksum, hdr_len);
726 i++;
727 }
728 src_offset = 0;
729 for (offset = hdr_len; ; offset += len) {
730 unsigned short chksum;
731 const void *data = (const void *)&file_data[src_offset];
732 len = LWIP_MIN(chunk_size, (int)file_size - src_offset);
733 if (len == 0) {
734 break;
735 }
736 chksum = ~inet_chksum(data, (u16_t)len);
737 /* add checksum for data */
738 fprintf(struct_file, "{%d, 0x%04x, %"SZT_F"}," NEWLINE, offset, chksum, len);
739 i++;
740 }
741 fprintf(struct_file, "};" NEWLINE);
742 fprintf(struct_file, "#endif /* HTTPD_PRECALCULATED_CHECKSUM */" NEWLINE);
743 return i;
744}
745
747{
748 if (((x >= 'A') && (x <= 'Z')) ||
749 ((x >= 'a') && (x <= 'z')) ||
750 ((x >= '0') && (x <= '9')) ||
751 (x == '_')) {
752 return 1;
753 }
754 return 0;
755}
756
757static void fix_filename_for_c(char *qualifiedName, size_t max_len)
758{
759 struct file_entry *f;
760 size_t len = strlen(qualifiedName);
761 char *new_name = (char *)malloc(len + 2);
762 int filename_ok;
763 int cnt = 0;
764 size_t i;
765 if (len + 3 == max_len) {
766 printf("File name too long: \"%s\"\n", qualifiedName);
767 exit(-1);
768 }
769 strcpy(new_name, qualifiedName);
770 for (i = 0; i < len; i++) {
771 if (!is_valid_char_for_c_var(new_name[i])) {
772 new_name[i] = '_';
773 }
774 }
775 do {
776 filename_ok = 1;
777 for (f = first_file; f != NULL; f = f->next) {
778 if (!strcmp(f->filename_c, new_name)) {
779 filename_ok = 0;
780 cnt++;
781 /* try next unique file name */
782 sprintf(&new_name[len], "%d", cnt);
783 break;
784 }
785 }
786 } while (!filename_ok && (cnt < 999));
787 if (!filename_ok) {
788 printf("Failed to get unique file name: \"%s\"\n", qualifiedName);
789 exit(-1);
790 }
791 strcpy(qualifiedName, new_name);
792 free(new_name);
793}
794
795static void register_filename(const char *qualifiedName)
796{
797 struct file_entry *fe = (struct file_entry *)malloc(sizeof(struct file_entry));
798 fe->filename_c = strdup(qualifiedName);
799 fe->next = NULL;
800 if (first_file == NULL) {
801 first_file = last_file = fe;
802 } else {
803 last_file->next = fe;
804 last_file = fe;
805 }
806}
807
808static int checkSsiByFilelist(const char* filename_listfile)
809{
810 FILE *f = fopen(filename_listfile, "r");
811 if (f != NULL) {
812 char *buf;
813 long rs;
814 size_t fsize, readcount;
815 size_t i, l, num_lines;
816 char **lines;
817 int state;
818
819 fseek(f, 0, SEEK_END);
820 rs = ftell(f);
821 if (rs < 0) {
822 printf("ftell failed with %d\n", errno);
823 fclose(f);
824 return 0;
825 }
826 fsize = (size_t)rs;
827 fseek(f, 0, SEEK_SET);
828 buf = (char*)malloc(fsize);
829 if (!buf) {
830 printf("failed to allocate ssi file buffer\n");
831 fclose(f);
832 return 0;
833 }
834 memset(buf, 0, fsize);
835 readcount = fread(buf, 1, fsize, f);
836 fclose(f);
837 if ((readcount > fsize) || !readcount) {
838 printf("failed to read data from ssi file\n");
839 free(buf);
840 return 0;
841 }
842
843 /* first pass: get the number of lines (and convert newlines to '0') */
844 num_lines = 1;
845 for (i = 0; i < readcount; i++) {
846 if (buf[i] == '\n') {
847 num_lines++;
848 buf[i] = 0;
849 } else if (buf[i] == '\r') {
850 buf[i] = 0;
851 }
852 }
853 /* allocate the line pointer array */
854 lines = (char**)malloc(sizeof(char*) * num_lines);
855 if (!lines) {
856 printf("failed to allocate ssi line buffer\n");
857 free(buf);
858 return 0;
859 }
860 memset(lines, 0, sizeof(char*) * num_lines);
861 l = 0;
862 state = 0;
863 for (i = 0; i < readcount; i++) {
864 if (state) {
865 /* waiting for null */
866 if (buf[i] == 0) {
867 state = 0;
868 }
869 } else {
870 /* waiting for beginning of new string */
871 if (buf[i] != 0) {
872 LWIP_ASSERT("lines array overflow", l < num_lines);
873 lines[l] = &buf[i];
874 state = 1;
875 l++;
876 }
877 }
878 }
879 LWIP_ASSERT("lines array overflow", l < num_lines);
880
884 }
885 return 0;
886}
887
888static int is_ssi_file(const char *filename)
889{
890 if (supportSsi) {
891 if (ssi_file_buffer) {
892 /* compare by list */
893 size_t i;
894 int ret = 0;
895 /* build up the relative path to this file */
896 size_t sublen = strlen(curSubdir);
897 size_t freelen = sizeof(curSubdir) - sublen - 1;
898 strncat(curSubdir, "/", freelen);
899 strncat(curSubdir, filename, freelen - 1);
900 curSubdir[sizeof(curSubdir) - 1] = 0;
901 for (i = 0; i < ssi_file_num_lines; i++) {
902 const char *listed_file = ssi_file_lines[i];
903 /* compare without the leading '/' */
904 if (!strcmp(&curSubdir[1], listed_file)) {
905 ret = 1;
906 }
907 }
908 curSubdir[sublen] = 0;
909 return ret;
910#if LWIP_HTTPD_SSI_BY_FILE_EXTENSION
911 } else {
912 /* check file extension */
913 size_t loop;
914 for (loop = 0; loop < NUM_SHTML_EXTENSIONS; loop++) {
915 if (strstr(filename, g_pcSSIExtensions[loop])) {
916 return 1;
917 }
918 }
919#endif /* LWIP_HTTPD_SSI_BY_FILE_EXTENSION */
920 }
921 }
922 return 0;
923}
924
925static int ext_in_list(const char* filename, const char *ext_list)
926{
927 int found = 0;
928 const char *ext = ext_list;
929 if (ext_list == NULL) {
930 return 0;
931 }
932 while(*ext != '\0') {
933 const char *comma = strchr(ext, ',');
934 size_t ext_size;
935 size_t filename_size = strlen(filename);
936 if (comma == NULL) {
937 comma = strchr(ext, '\0');
938 }
939 ext_size = comma - ext;
940 if ((filename[filename_size - ext_size - 1] == '.') &&
941 !strncmp(&filename[filename_size - ext_size], ext, ext_size)) {
942 found = 1;
943 break;
944 }
945 ext = comma + 1;
946 }
947
948 return found;
949}
950
951static int file_to_exclude(const char *filename)
952{
954}
955
956static int file_can_be_compressed(const char *filename)
957{
959}
960
961int process_file(FILE *data_file, FILE *struct_file, const char *filename)
962{
963 char varname[MAX_PATH_LEN];
964 int i = 0;
965 char qualifiedName[MAX_PATH_LEN];
966 int file_size;
967 u16_t http_hdr_chksum = 0;
968 u16_t http_hdr_len = 0;
969 int chksum_count = 0;
970 u8_t flags = 0;
971 u8_t has_content_len;
972 u8_t *file_data;
973 int is_ssi;
974 int can_be_compressed;
975 int is_compressed = 0;
976 int flags_printed;
977
978 /* create qualified name (@todo: prepend slash or not?) */
979 snprintf(qualifiedName, sizeof(qualifiedName), "%s/%s", curSubdir, filename);
980 /* create C variable name */
981 strncpy(varname, qualifiedName, sizeof(varname));
982 /* convert slashes & dots to underscores */
984 register_filename(varname);
985#if ALIGN_PAYLOAD
986 /* to force even alignment of array, type 1 */
987 fprintf(data_file, "#if FSDATA_FILE_ALIGNMENT==1" NEWLINE);
988 fprintf(data_file, "static const " PAYLOAD_ALIGN_TYPE " dummy_align_%s = %d;" NEWLINE, varname, payload_alingment_dummy_counter++);
989 fprintf(data_file, "#endif" NEWLINE);
990#endif /* ALIGN_PAYLOAD */
991 fprintf(data_file, "static const unsigned char FSDATA_ALIGN_PRE data_%s[] FSDATA_ALIGN_POST = {" NEWLINE, varname);
992 /* encode source file name (used by file system, not returned to browser) */
993 fprintf(data_file, "/* %s (%"SZT_F" chars) */" NEWLINE, qualifiedName, strlen(qualifiedName) + 1);
994 file_put_ascii(data_file, qualifiedName, strlen(qualifiedName) + 1, &i);
995#if ALIGN_PAYLOAD
996 /* pad to even number of bytes to assure payload is on aligned boundary */
997 while (i % PAYLOAD_ALIGNMENT != 0) {
998 fprintf(data_file, "0x%02x,", 0);
999 i++;
1000 }
1001#endif /* ALIGN_PAYLOAD */
1002 fprintf(data_file, NEWLINE);
1003
1004 is_ssi = is_ssi_file(filename);
1005 if (is_ssi) {
1007 }
1008 has_content_len = !is_ssi;
1009 can_be_compressed = includeHttpHeader && !is_ssi && file_can_be_compressed(filename);
1010 file_data = get_file_data(filename, &file_size, can_be_compressed, &is_compressed);
1011 if (includeHttpHeader) {
1012 file_write_http_header(data_file, filename, file_size, &http_hdr_len, &http_hdr_chksum, has_content_len, is_compressed);
1014 if (has_content_len) {
1016 if (useHttp11) {
1018 }
1019 }
1020 }
1021 if (precalcChksum) {
1022 chksum_count = write_checksums(struct_file, varname, http_hdr_len, http_hdr_chksum, file_data, file_size);
1023 }
1024
1025 /* build declaration of struct fsdata_file in temp file */
1026 fprintf(struct_file, "const struct fsdata_file file_%s[] = { {" NEWLINE, varname);
1027 fprintf(struct_file, "file_%s," NEWLINE, lastFileVar);
1028 fprintf(struct_file, "data_%s," NEWLINE, varname);
1029 fprintf(struct_file, "data_%s + %d," NEWLINE, varname, i);
1030 fprintf(struct_file, "sizeof(data_%s) - %d," NEWLINE, varname, i);
1031
1032 flags_printed = 0;
1034 fputs("FS_FILE_FLAGS_HEADER_INCLUDED", struct_file);
1035 flags_printed = 1;
1036 }
1038 if (flags_printed) {
1039 fputs(" | ", struct_file);
1040 }
1041 fputs("FS_FILE_FLAGS_HEADER_PERSISTENT", struct_file);
1042 flags_printed = 1;
1043 }
1045 if (flags_printed) {
1046 fputs(" | ", struct_file);
1047 }
1048 fputs("FS_FILE_FLAGS_HEADER_HTTPVER_1_1", struct_file);
1049 flags_printed = 1;
1050 }
1051 if (flags & FS_FILE_FLAGS_SSI) {
1052 if (flags_printed) {
1053 fputs(" | ", struct_file);
1054 }
1055 fputs("FS_FILE_FLAGS_SSI", struct_file);
1056 flags_printed = 1;
1057 }
1058 if (!flags_printed) {
1059 fputs("0", struct_file);
1060 }
1061 fputs("," NEWLINE, struct_file);
1062 if (precalcChksum) {
1063 fprintf(struct_file, "#if HTTPD_PRECALCULATED_CHECKSUM" NEWLINE);
1064 fprintf(struct_file, "%d, chksums_%s," NEWLINE, chksum_count, varname);
1065 fprintf(struct_file, "#endif /* HTTPD_PRECALCULATED_CHECKSUM */" NEWLINE);
1066 }
1067 fprintf(struct_file, "}};" NEWLINE NEWLINE);
1068 strcpy(lastFileVar, varname);
1069
1070 /* write actual file contents */
1071 i = 0;
1072 fprintf(data_file, NEWLINE "/* raw file data (%d bytes) */" NEWLINE, file_size);
1073 process_file_data(data_file, file_data, file_size);
1074 fprintf(data_file, "};" NEWLINE NEWLINE);
1075 free(file_data);
1076 return 0;
1077}
1078
1079int file_write_http_header(FILE *data_file, const char *filename, int file_size, u16_t *http_hdr_len,
1080 u16_t *http_hdr_chksum, u8_t provide_content_len, int is_compressed)
1081{
1082 int i = 0;
1083 int response_type = HTTP_HDR_OK;
1084 const char *file_type;
1085 const char *cur_string;
1086 size_t cur_len;
1087 int written = 0;
1088 size_t hdr_len = 0;
1089 u16_t acc;
1090 const char *file_ext;
1091 size_t j;
1092 u8_t provide_last_modified = includeLastModified;
1093
1094 memset(hdr_buf, 0, sizeof(hdr_buf));
1095
1096 if (useHttp11) {
1097 response_type = HTTP_HDR_OK_11;
1098 }
1099
1100 fprintf(data_file, NEWLINE "/* HTTP header */");
1101 if (strstr(filename, "404.") == filename) {
1102 response_type = HTTP_HDR_NOT_FOUND;
1103 if (useHttp11) {
1104 response_type = HTTP_HDR_NOT_FOUND_11;
1105 }
1106 } else if (strstr(filename, "400.") == filename) {
1107 response_type = HTTP_HDR_BAD_REQUEST;
1108 if (useHttp11) {
1109 response_type = HTTP_HDR_BAD_REQUEST_11;
1110 }
1111 } else if (strstr(filename, "501.") == filename) {
1112 response_type = HTTP_HDR_NOT_IMPL;
1113 if (useHttp11) {
1114 response_type = HTTP_HDR_NOT_IMPL_11;
1115 }
1116 }
1117 cur_string = g_psHTTPHeaderStrings[response_type];
1118 cur_len = strlen(cur_string);
1119 fprintf(data_file, NEWLINE "/* \"%s\" (%"SZT_F" bytes) */" NEWLINE, cur_string, cur_len);
1120 written += file_put_ascii(data_file, cur_string, cur_len, &i);
1121 i = 0;
1122 if (precalcChksum) {
1123 memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
1124 hdr_len += cur_len;
1125 }
1126
1127 cur_string = serverID;
1128 cur_len = strlen(cur_string);
1129 fprintf(data_file, NEWLINE "/* \"%s\" (%"SZT_F" bytes) */" NEWLINE, cur_string, cur_len);
1130 written += file_put_ascii(data_file, cur_string, cur_len, &i);
1131 i = 0;
1132 if (precalcChksum) {
1133 memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
1134 hdr_len += cur_len;
1135 }
1136
1137 file_ext = filename;
1138 if (file_ext != NULL) {
1139 while (strstr(file_ext, ".") != NULL) {
1140 file_ext = strstr(file_ext, ".");
1141 file_ext++;
1142 }
1143 }
1144 if ((file_ext == NULL) || (*file_ext == 0)) {
1145 printf("failed to get extension for file \"%s\", using default.\n", filename);
1146 file_type = HTTP_HDR_DEFAULT_TYPE;
1147 } else {
1148 file_type = NULL;
1149 for (j = 0; j < NUM_HTTP_HEADERS; j++) {
1150 if (!strcmp(file_ext, g_psHTTPHeaders[j].extension)) {
1151 file_type = g_psHTTPHeaders[j].content_type;
1152 break;
1153 }
1154 }
1155 if (file_type == NULL) {
1156 printf("failed to get file type for extension \"%s\", using default.\n", file_ext);
1157 file_type = HTTP_HDR_DEFAULT_TYPE;
1158 }
1159 }
1160
1161 /* Content-Length is used for persistent connections in HTTP/1.1 but also for
1162 download progress in older versions
1163 @todo: just use a big-enough buffer and let the HTTPD send spaces? */
1164 if (provide_content_len) {
1165 char intbuf[MAX_PATH_LEN];
1166 int content_len = file_size;
1167 memset(intbuf, 0, sizeof(intbuf));
1168 cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONTENT_LENGTH];
1169 cur_len = strlen(cur_string);
1170 fprintf(data_file, NEWLINE "/* \"%s%d\r\n\" (%"SZT_F"+ bytes) */" NEWLINE, cur_string, content_len, cur_len + 2);
1171 written += file_put_ascii(data_file, cur_string, cur_len, &i);
1172 if (precalcChksum) {
1173 memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
1174 hdr_len += cur_len;
1175 }
1176
1177 lwip_itoa(intbuf, sizeof(intbuf), content_len);
1178 strcat(intbuf, "\r\n");
1179 cur_len = strlen(intbuf);
1180 written += file_put_ascii(data_file, intbuf, cur_len, &i);
1181 i = 0;
1182 if (precalcChksum) {
1183 memcpy(&hdr_buf[hdr_len], intbuf, cur_len);
1184 hdr_len += cur_len;
1185 }
1186 }
1187 if (provide_last_modified) {
1188 char modbuf[256];
1189 struct stat stat_data;
1190 struct tm *t;
1191 memset(modbuf, 0, sizeof(modbuf));
1192 memset(&stat_data, 0, sizeof(stat_data));
1193 cur_string = modbuf;
1194 strcpy(modbuf, "Last-Modified: ");
1195 if (stat(filename, &stat_data) != 0) {
1196 printf("stat(%s) failed with error %d\n", filename, errno);
1197 exit(-1);
1198 }
1199 t = gmtime(&stat_data.st_mtime);
1200 if (t == NULL) {
1201 printf("gmtime() failed with error %d\n", errno);
1202 exit(-1);
1203 }
1204 strftime(&modbuf[15], sizeof(modbuf) - 15, "%a, %d %b %Y %H:%M:%S GMT", t);
1205 cur_len = strlen(cur_string);
1206 fprintf(data_file, NEWLINE "/* \"%s\"\r\n\" (%"SZT_F"+ bytes) */" NEWLINE, cur_string, cur_len + 2);
1207 written += file_put_ascii(data_file, cur_string, cur_len, &i);
1208 if (precalcChksum) {
1209 memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
1210 hdr_len += cur_len;
1211 }
1212
1213 modbuf[0] = 0;
1214 strcat(modbuf, "\r\n");
1215 cur_len = strlen(modbuf);
1216 written += file_put_ascii(data_file, modbuf, cur_len, &i);
1217 i = 0;
1218 if (precalcChksum) {
1219 memcpy(&hdr_buf[hdr_len], modbuf, cur_len);
1220 hdr_len += cur_len;
1221 }
1222 }
1223
1224 /* HTTP/1.1 implements persistent connections */
1225 if (useHttp11) {
1226 if (provide_content_len) {
1227 cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONN_KEEPALIVE];
1228 } else {
1229 /* no Content-Length available, so a persistent connection is no possible
1230 because the client does not know the data length */
1231 cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONN_CLOSE];
1232 }
1233 cur_len = strlen(cur_string);
1234 fprintf(data_file, NEWLINE "/* \"%s\" (%"SZT_F" bytes) */" NEWLINE, cur_string, cur_len);
1235 written += file_put_ascii(data_file, cur_string, cur_len, &i);
1236 i = 0;
1237 if (precalcChksum) {
1238 memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
1239 hdr_len += cur_len;
1240 }
1241 }
1242
1243#if MAKEFS_SUPPORT_DEFLATE
1244 if (is_compressed) {
1245 /* tell the client about the deflate encoding */
1246 LWIP_ASSERT("error", deflateNonSsiFiles);
1247 cur_string = "Content-Encoding: deflate\r\n";
1248 cur_len = strlen(cur_string);
1249 fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len);
1250 written += file_put_ascii(data_file, cur_string, cur_len, &i);
1251 i = 0;
1252 }
1253#else
1254 LWIP_UNUSED_ARG(is_compressed);
1255#endif
1256
1257 /* write content-type, ATTENTION: this includes the double-CRLF! */
1258 cur_string = file_type;
1259 cur_len = strlen(cur_string);
1260 fprintf(data_file, NEWLINE "/* \"%s\" (%"SZT_F" bytes) */" NEWLINE, cur_string, cur_len);
1261 written += file_put_ascii(data_file, cur_string, cur_len, &i);
1262 i = 0;
1263
1264 /* ATTENTION: headers are done now (double-CRLF has been written!) */
1265
1266 if (precalcChksum) {
1267 LWIP_ASSERT("hdr_len + cur_len <= sizeof(hdr_buf)", hdr_len + cur_len <= sizeof(hdr_buf));
1268 memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
1269 hdr_len += cur_len;
1270
1271 LWIP_ASSERT("strlen(hdr_buf) == hdr_len", strlen(hdr_buf) == hdr_len);
1272 acc = ~inet_chksum(hdr_buf, (u16_t)hdr_len);
1273 *http_hdr_len = (u16_t)hdr_len;
1274 *http_hdr_chksum = acc;
1275 }
1276
1277 return written;
1278}
1279
1280int file_put_ascii(FILE *file, const char *ascii_string, int len, int *i)
1281{
1282 int x;
1283 for (x = 0; x < len; x++) {
1284 unsigned char cur = ascii_string[x];
1285 fprintf(file, "0x%02x,", cur);
1286 if ((++(*i) % HEX_BYTES_PER_LINE) == 0) {
1288 }
1289 }
1290 return len;
1291}
1292
1293int s_put_ascii(char *buf, const char *ascii_string, int len, int *i)
1294{
1295 int x;
1296 int idx = 0;
1297 for (x = 0; x < len; x++) {
1298 unsigned char cur = ascii_string[x];
1299 sprintf(&buf[idx], "0x%02x,", cur);
1300 idx += 5;
1301 if ((++(*i) % HEX_BYTES_PER_LINE) == 0) {
1302 sprintf(&buf[idx], NEWLINE);
1303 idx += NEWLINE_LEN;
1304 }
1305 }
1306 return len;
1307}
static int argc
Definition: ServiceArgs.c:12
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
char * strncat(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:605
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define stat
Definition: acwin.h:99
static int state
Definition: maze.c:121
unsigned int dir
Definition: maze.c:112
unsigned short uint16
Definition: types.h:30
unsigned char uint8
Definition: types.h:28
r l[0]
Definition: byte_order.h:168
#define SEEK_END
Definition: cabinet.c:29
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define LWIP_MIN(x, y)
Definition: def.h:66
#define NULL
Definition: types.h:112
UINT32 uint
Definition: types.h:83
unsigned int idx
Definition: utils.c:41
static const WCHAR *const ext[]
Definition: module.c:53
#define Z_OK
Definition: zlib.h:114
int main()
Definition: test.c:6
__kernel_size_t size_t
Definition: linux.h:237
#define FS_FILE_FLAGS_HEADER_HTTPVER_1_1
Definition: fs.h:55
#define FS_FILE_FLAGS_SSI
Definition: fs.h:56
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:116
#define printf
Definition: freeldr.h:97
#define FS_FILE_FLAGS_HEADER_INCLUDED
Definition: fsdata.c:9
#define FS_FILE_FLAGS_HEADER_PERSISTENT
Definition: fsdata.c:12
FxCollectionEntry * cur
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble GLdouble t
Definition: gl.h:2047
GLsizeiptr size
Definition: glext.h:5919
GLfloat f
Definition: glext.h:7540
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLbitfield flags
Definition: glext.h:7161
GLenum GLsizei len
Definition: glext.h:6722
GLintptr offset
Definition: glext.h:5920
GLint fsize
Definition: glext.h:9408
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
uint8_t u8_t
Definition: arch.h:125
#define SZT_F
Definition: arch.h:171
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:373
uint16_t u16_t
Definition: arch.h:127
#define HTTPD_SERVER_AGENT
Definition: httpd_opts.h:172
#define LWIP_VERSION_STRING
Definition: init.h:87
void lwip_itoa(char *result, size_t bufsize, int number)
Definition: def.c:222
_Check_return_opt_ _CRTIMP int __cdecl fputs(_In_z_ const char *_Str, _Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_opt_ _CRTIMP size_t __cdecl fread(_Out_writes_bytes_(_ElementSize *_Count) void *_DstBuf, _In_ size_t _ElementSize, _In_ size_t _Count, _Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP long __cdecl ftell(_Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
#define TCP_MSS
Definition: lwipopts.h:46
const char * filename
Definition: ioapi.h:137
#define SEEK_SET
Definition: jmemansi.c:26
JSAMPARRAY JDIMENSION num_lines
Definition: jpeglib.h:1017
#define f
Definition: ke_i.h:83
#define HEX_BYTES_PER_LINE
Definition: makefsdata.c:122
static char * ssi_file_buffer
Definition: makefsdata.c:168
int s_put_ascii(char *buf, const char *ascii_string, int len, int *i)
Definition: makefsdata.c:1293
static const char * serverID
Definition: makefsdata.c:111
static void print_usage(void)
Definition: makefsdata.c:172
static const char * exclude_list
Definition: makefsdata.c:162
int check_path(char *path, size_t size)
Definition: makefsdata.c:411
#define COPY_BUFSIZE
Definition: makefsdata.c:35
int process_sub(FILE *data_file, FILE *struct_file)
Definition: makefsdata.c:465
#define PAYLOAD_ALIGN_TYPE
Definition: makefsdata.c:119
static int is_ssi_file(const char *filename)
Definition: makefsdata.c:888
static int checkSsiByFilelist(const char *filename_listfile)
Definition: makefsdata.c:808
static size_t ssi_file_num_lines
Definition: makefsdata.c:170
static char ** ssi_file_lines
Definition: makefsdata.c:169
static unsigned char precalcChksum
Definition: makefsdata.c:155
#define USAGE_ARG_DEFLATE
Definition: makefsdata.c:70
static int file_can_be_compressed(const char *filename)
Definition: makefsdata.c:956
static int write_checksums(FILE *struct_file, const char *varname, u16_t hdr_len, u16_t hdr_chksum, const u8_t *file_data, size_t file_size)
Definition: makefsdata.c:708
static struct file_entry * first_file
Definition: makefsdata.c:165
int file_write_http_header(FILE *data_file, const char *filename, int file_size, u16_t *http_hdr_len, u16_t *http_hdr_chksum, u8_t provide_content_len, int is_compressed)
Definition: makefsdata.c:1079
static int ext_in_list(const char *filename, const char *ext_list)
Definition: makefsdata.c:925
#define NEWLINE
Definition: makefsdata.c:93
static u8_t * get_file_data(const char *filename, int *file_size, int can_be_compressed, int *is_compressed)
Definition: makefsdata.c:568
void concat_files(const char *file1, const char *file2, const char *targetfile)
Definition: makefsdata.c:452
static char lastFileVar[MAX_PATH_LEN]
Definition: makefsdata.c:148
static unsigned char processSubs
Definition: makefsdata.c:151
static void process_file_data(FILE *data_file, u8_t *file_data, size_t file_size)
Definition: makefsdata.c:684
#define PAYLOAD_ALIGNMENT
Definition: makefsdata.c:115
static char hdr_buf[4096]
Definition: makefsdata.c:149
static int file_to_exclude(const char *filename)
Definition: makefsdata.c:951
static char curSubdir[MAX_PATH_LEN-3]
Definition: makefsdata.c:147
static void register_filename(const char *qualifiedName)
Definition: makefsdata.c:795
static struct file_entry * last_file
Definition: makefsdata.c:166
static void copy_file(const char *filename_in, FILE *fout)
Definition: makefsdata.c:434
static int payload_alingment_dummy_counter
Definition: makefsdata.c:120
#define MAX_PATH_LEN
Definition: makefsdata.c:124
static const char * ncompress_list
Definition: makefsdata.c:163
static void fix_filename_for_c(char *qualifiedName, size_t max_len)
Definition: makefsdata.c:757
#define NEWLINE_LEN
Definition: makefsdata.c:94
static unsigned char includeHttpHeader
Definition: makefsdata.c:152
static char file_buffer_c[COPY_BUFSIZE *5+((COPY_BUFSIZE/HEX_BYTES_PER_LINE) *3)]
Definition: makefsdata.c:145
static unsigned char includeLastModified
Definition: makefsdata.c:156
int file_put_ascii(FILE *file, const char *ascii_string, int len, int *i)
Definition: makefsdata.c:1280
static unsigned char useHttp11
Definition: makefsdata.c:153
int process_file(FILE *data_file, FILE *struct_file, const char *filename)
Definition: makefsdata.c:961
static int is_valid_char_for_c_var(char x)
Definition: makefsdata.c:746
static unsigned char supportSsi
Definition: makefsdata.c:154
static char serverIDBuffer[1024]
Definition: makefsdata.c:112
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
_Check_return_wat_ _CRTIMP errno_t __cdecl wcstombs_s(_Out_opt_ size_t *pcchConverted, _Out_writes_bytes_to_opt_(cjDstSize, *pcchConverted) char *pmbsDst, _In_ size_t cjDstSize, _In_z_ const wchar_t *pwszSrc, _In_ size_t cjMaxCount)
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define argv
Definition: mplay32.c:18
int remove
Definition: msacm.c:1366
static unsigned int file_size
Definition: regtests2xml.c:47
#define errno
Definition: errno.h:18
_Check_return_ _CRTIMP char *__cdecl strdup(_In_opt_z_ const char *_Src)
_CRTIMP struct tm *__cdecl gmtime(const time_t *_Time)
Definition: time.h:415
#define exit(n)
Definition: config.h:202
int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level)
Definition: compress.c:22
FD_TYPE file_type(FDSC **curr, char *fixed)
Definition: file.c:221
#define memset(x, y, z)
Definition: compat.h:39
LOCAL int ext_size(UInt32_t starting_extent)
Definition: write.c:2503
size_t CDECL strftime(char *str, size_t max, const char *format, const struct tm *mstm)
Definition: strftime.c:294
struct define * next
Definition: compiler.c:65
Definition: makefsdata.c:126
struct file_entry * next
Definition: makefsdata.c:127
const char * filename_c
Definition: makefsdata.c:128
Definition: fci.c:127
char name[1]
Definition: fci.c:135
Definition: stat.h:55
time_t st_mtime
Definition: stat.h:65
Definition: ps.c:97
Definition: time.h:68
_TINYDIR_FUNC int tinydir_readfile_n(const tinydir_dir *dir, tinydir_file *file, size_t i)
Definition: tinydir.h:587
_TINYDIR_FUNC int tinydir_open_sorted(tinydir_dir *dir, const _tinydir_char_t *path)
Definition: tinydir.h:356
#define TINYDIR_STRING(s)
Definition: tinydir.h:80
eMaj lines
Definition: tritemp.h:206
int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, uLong *sourceLen)
Definition: uncompr.c:27
int ret
#define snprintf
Definition: wintirpc.h:48