Magellan Linux

Annotation of /trunk/mkinitrd-magellan/busybox/networking/httpd_ssi.c

Parent Directory Parent Directory | Revision Log 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)
-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     }