Seregon/zftpd

Zero-copy FTP/HTTP Daemon compatible with all POSIX systems

C/11.0 KB/No license
tools/generate_resources.py
zftpd / tools / generate_resources.py
1#!/usr/bin/env python3
2"""
3Generate embedded HTTP resources from web/ directory.
4 
5Usage:
6 python3 tools/generate_resources.py > src/http_resources.c
7"""
8 
9import os
10import sys
11 
12def file_to_c_array(filepath, varname):
13 with open(filepath, "rb") as f:
14 data = f.read()
15 
16 print(f"/* {os.path.basename(filepath)} - {len(data)} bytes */")
17 print(f"static const unsigned char {varname}[] = {{")
18 
19 for i in range(0, len(data), 12):
20 chunk = data[i : i + 12]
21 items = ", ".join(f"0x{b:02x}" for b in chunk)
22 if i + 12 < len(data):
23 print(f" {items},")
24 else:
25 print(f" {items}")
26 
27 print("};")
28 print()
29 
30 return len(data)
31 
32def main():
33 web_dir = os.path.join(os.path.dirname(__file__), '..', 'web')
34
35 print("/* Auto-generated HTTP resources */")
36 print("#include <stddef.h>")
37 print("#include <string.h>")
38 print()
39 print("const char *http_get_resource(const char *path, size_t *size);")
40 print()
41
42 resources = []
43
44 for filename in ['index.html', 'style.css', 'app.js', 'zftpd-logo.png']:
45 filepath = os.path.join(web_dir, filename)
46 if not os.path.exists(filepath):
47 continue
48
49 varname = filename.replace('.', '_').replace('-', '_')
50 size = file_to_c_array(filepath, varname)
51 resources.append((filename, varname, size))
52
53 print("const char *http_get_resource(const char *path, size_t *size) {")
54
55 for filename, varname, fsize in resources:
56 print(f" if (strcmp(path, \"{filename}\") == 0) {{")
57 print(f" *size = sizeof({varname});")
58 print(f" return (const char *){varname};")
59 print(f" }}")
60
61 print(" return NULL;")
62 print("}")
63 
64if __name__ == '__main__':
65 main()
66