Annotation of /trunk/mkinitrd-magellan/busybox/networking/httpd_ssi.c
Parent Directory | Revision Log
Revision 984 -
(hide annotations)
(download)
Sun May 30 11:32:42 2010 UTC (13 years, 11 months ago) by niro
File MIME type: text/plain
File size: 4248 byte(s)
Sun May 30 11:32:42 2010 UTC (13 years, 11 months ago) by niro
File MIME type: text/plain
File size: 4248 byte(s)
-updated to busybox-1.16.1 and enabled blkid/uuid support in default config
1 | niro | 984 | /* |
2 | * Copyright (c) 2009 Denys Vlasenko <vda.linux@googlemail.com> | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this tarball for details. | ||
5 | */ | ||
6 | |||
7 | /* | ||
8 | * This program is a CGI application. It processes server-side includes: | ||
9 | * <!--#include file="file.html" --> | ||
10 | * | ||
11 | * Usage: put these lines in httpd.conf: | ||
12 | * | ||
13 | * *.html:/bin/httpd_ssi | ||
14 | * *.htm:/bin/httpd_ssi | ||
15 | */ | ||
16 | |||
17 | /* Build a-la | ||
18 | i486-linux-uclibc-gcc \ | ||
19 | -static -static-libgcc \ | ||
20 | -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 \ | ||
21 | -Wall -Wshadow -Wwrite-strings -Wundef -Wstrict-prototypes -Werror \ | ||
22 | -Wold-style-definition -Wdeclaration-after-statement -Wno-pointer-sign \ | ||
23 | -Wmissing-prototypes -Wmissing-declarations \ | ||
24 | -Os -fno-builtin-strlen -finline-limit=0 -fomit-frame-pointer \ | ||
25 | -ffunction-sections -fdata-sections -fno-guess-branch-probability \ | ||
26 | -funsigned-char \ | ||
27 | -falign-functions=1 -falign-jumps=1 -falign-labels=1 -falign-loops=1 \ | ||
28 | -march=i386 -mpreferred-stack-boundary=2 \ | ||
29 | -Wl,-Map -Wl,link.map -Wl,--warn-common -Wl,--sort-common -Wl,--gc-sections \ | ||
30 | httpd_ssi.c -o httpd_ssi | ||
31 | */ | ||
32 | |||
33 | /* Size (i386, static uclibc, approximate): | ||
34 | * text data bss dec hex filename | ||
35 | * 9487 160 68552 78199 13177 httpd_ssi | ||
36 | * | ||
37 | * Note: it wouldn't be too hard to get rid of stdio and strdup, | ||
38 | * (especially that fgets() mangles NULs...) | ||
39 | */ | ||
40 | |||
41 | #include <sys/types.h> | ||
42 | #include <sys/stat.h> | ||
43 | #include <errno.h> | ||
44 | #include <fcntl.h> | ||
45 | #include <stdint.h> | ||
46 | #include <stdlib.h> | ||
47 | #include <string.h> | ||
48 | #include <unistd.h> | ||
49 | #include <stdio.h> | ||
50 | #include <dirent.h> | ||
51 | #include <time.h> | ||
52 | |||
53 | static char* skip_whitespace(char *s) | ||
54 | { | ||
55 | while (*s == ' ' || *s == '\t') ++s; | ||
56 | |||
57 | return s; | ||
58 | } | ||
59 | |||
60 | static char line[64 * 1024]; | ||
61 | |||
62 | static void process_includes(const char *filename) | ||
63 | { | ||
64 | int curdir_fd; | ||
65 | char *end; | ||
66 | FILE *fp = fopen(filename, "r"); | ||
67 | if (!fp) | ||
68 | exit(1); | ||
69 | |||
70 | /* Ensure that nested includes are relative: | ||
71 | * if we include a/1.htm and it includes b/2.htm, | ||
72 | * we need to include a/b/2.htm, not b/2.htm | ||
73 | */ | ||
74 | curdir_fd = -1; | ||
75 | end = strrchr(filename, '/'); | ||
76 | if (end) { | ||
77 | curdir_fd = open(".", O_RDONLY); | ||
78 | /* *end = '\0' would mishandle "/file.htm" */ | ||
79 | end[1] = '\0'; | ||
80 | chdir(filename); | ||
81 | } | ||
82 | |||
83 | #define INCLUDE "<!--#include" | ||
84 | while (fgets(line, sizeof(line), fp)) { | ||
85 | unsigned preceding_len; | ||
86 | char *include_directive; | ||
87 | |||
88 | include_directive = strstr(line, INCLUDE); | ||
89 | if (!include_directive) { | ||
90 | fputs(line, stdout); | ||
91 | continue; | ||
92 | } | ||
93 | preceding_len = include_directive - line; | ||
94 | if (memchr(line, '\"', preceding_len) | ||
95 | || memchr(line, '\'', preceding_len) | ||
96 | ) { | ||
97 | /* INCLUDE string may be inside "str" or 'str', | ||
98 | * ignore it */ | ||
99 | fputs(line, stdout); | ||
100 | continue; | ||
101 | } | ||
102 | /* Small bug: we accept #includefile="file" too */ | ||
103 | include_directive = skip_whitespace(include_directive + sizeof(INCLUDE)-1); | ||
104 | if (strncmp(include_directive, "file=\"", 6) != 0) { | ||
105 | /* "<!--#include virtual=..."? - not supported */ | ||
106 | fputs(line, stdout); | ||
107 | continue; | ||
108 | } | ||
109 | include_directive += 6; /* now it points to file name */ | ||
110 | end = strchr(include_directive, '\"'); | ||
111 | if (!end) { | ||
112 | fputs(line, stdout); | ||
113 | continue; | ||
114 | } | ||
115 | /* We checked that this is a valid include directive */ | ||
116 | |||
117 | /* Print everything before directive */ | ||
118 | if (preceding_len) { | ||
119 | line[preceding_len] = '\0'; | ||
120 | fputs(line, stdout); | ||
121 | } | ||
122 | /* Save everything after directive */ | ||
123 | *end++ = '\0'; | ||
124 | end = strchr(end, '>'); | ||
125 | if (end) | ||
126 | end = strdup(end + 1); | ||
127 | |||
128 | /* FIXME: | ||
129 | * (1) are relative paths with /../ etc ok? | ||
130 | * (2) what to do with absolute paths? | ||
131 | * are they relative to doc root or to real root? | ||
132 | */ | ||
133 | process_includes(include_directive); | ||
134 | |||
135 | /* Print everything after directive */ | ||
136 | if (end) { | ||
137 | fputs(end, stdout); | ||
138 | free(end); | ||
139 | } | ||
140 | } | ||
141 | if (curdir_fd >= 0) | ||
142 | fchdir(curdir_fd); | ||
143 | fclose(fp); | ||
144 | } | ||
145 | |||
146 | int main(int argc, char *argv[]) | ||
147 | { | ||
148 | if (!argv[1]) | ||
149 | return 1; | ||
150 | |||
151 | /* Seen from busybox.net's Apache: | ||
152 | * HTTP/1.1 200 OK | ||
153 | * Date: Thu, 10 Sep 2009 18:23:28 GMT | ||
154 | * Server: Apache | ||
155 | * Accept-Ranges: bytes | ||
156 | * Connection: close | ||
157 | * Content-Type: text/html | ||
158 | */ | ||
159 | fputs( | ||
160 | /* "Date: Thu, 10 Sep 2009 18:23:28 GMT\r\n" */ | ||
161 | /* "Server: Apache\r\n" */ | ||
162 | /* "Accept-Ranges: bytes\r\n" - do we really accept bytes?! */ | ||
163 | "Connection: close\r\n" | ||
164 | "Content-Type: text/html\r\n" | ||
165 | "\r\n", | ||
166 | stdout | ||
167 | ); | ||
168 | process_includes(argv[1]); | ||
169 | return 0; | ||
170 | } |