/[hydra]/hydra/src/index_dir.c
ViewVC logotype

Contents of /hydra/src/index_dir.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (show annotations) (vendor branch)
Sat Sep 21 13:53:44 2002 UTC (21 years, 7 months ago) by nmav
Branch: boas
CVS Tags: BOAS_WITH_RANGES_AND_CGI, start
Changes since 1.1: +0 -0 lines
File MIME type: text/plain
Imported sources

1 /*
2 * Copyright (C) 1997-2002 Jon Nelson <jnelson@boa.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 1, or (at your option)
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *
18 */
19
20 /* $Id: index_dir.c,v 1.32 2002/01/30 03:41:45 jnelson Exp $*/
21
22 #include <stdio.h>
23 #include <sys/stat.h>
24 #include <limits.h> /* for PATH_MAX */
25 #include <time.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include "compat.h"
31
32 #define MAX_FILE_LENGTH MAXNAMLEN
33 #define MAX_PATH_LENGTH PATH_MAX
34
35 #define INT_TO_HEX(x) \
36 ((((x)-10)>=0)?('A'+((x)-10)):('0'+(x)))
37
38 #include "escape.h"
39
40 char *html_escape_string(char *inp, char *buf, const int len);
41 char *http_escape_string(char *inp, char *buf, const int len);
42
43 #if defined __GNUC__ && \
44 (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 0))
45 #define CONST const
46 #else
47 #define CONST
48 #endif
49
50 int select_files(CONST struct dirent *d);
51 int index_directory(char *dir, char *title);
52
53 /*
54 * Name: html_escape_string
55 */
56 char *html_escape_string(char *inp, char *dest, const int len)
57 {
58 int max;
59 char *buf;
60 unsigned char c;
61
62 max = len * 5;
63
64 if (dest == NULL && max)
65 dest = malloc(sizeof (unsigned char) * (max + 1));
66
67 if (dest == NULL)
68 return NULL;
69
70 buf = dest;
71 while ((c = *inp++)) {
72 switch (c) {
73 case '>':
74 *dest++ = '&';
75 *dest++ = 'g';
76 *dest++ = 't';
77 *dest++ = ';';
78 break;
79 case '<':
80 *dest++ = '&';
81 *dest++ = 'l';
82 *dest++ = 't';
83 *dest++ = ';';
84 break;
85 case '&':
86 *dest++ = '&';
87 *dest++ = 'a';
88 *dest++ = 'm';
89 *dest++ = 'p';
90 *dest++ = ';';
91 break;
92 default:
93 *dest++ = c;
94 }
95 }
96 *dest = '\0';
97 return buf;
98 }
99
100
101 /*
102 * Name: escape_string
103 *
104 * Description: escapes the string inp. Uses variable buf. If buf is
105 * NULL when the program starts, it will attempt to dynamically allocate
106 * the space that it needs, otherwise it will assume that the user
107 * has already allocated enough space for the variable buf, which
108 * could be up to 3 times the size of inp. If the routine dynamically
109 * allocates the space, the user is responsible for freeing it afterwords
110 * Returns: NULL on error, pointer to string otherwise.
111 */
112
113 char *http_escape_string(char *inp, char *buf, const int len)
114 {
115 int max;
116 char *index;
117 unsigned char c;
118
119 max = len * 3;
120
121 if (buf == NULL && max)
122 buf = malloc(sizeof (unsigned char) * (max + 1));
123
124 if (buf == NULL)
125 return NULL;
126
127 index = buf;
128 while ((c = *inp++)) {
129 if (needs_escape((unsigned int) c)) {
130 *index++ = '%';
131 *index++ = INT_TO_HEX(c >> 4);
132 *index++ = INT_TO_HEX(c & 15);
133 } else
134 *index++ = c;
135 }
136 *index = '\0';
137
138 return buf;
139 }
140
141 void send_error(int error)
142 {
143 char *the_error;
144
145 switch (error) {
146
147 case 1:
148 the_error = "Not enough arguments were passed to the indexer.";
149 break;
150 case 2:
151 the_error = "The Directory Sorter ran out of Memory";
152 break;
153 case 3:
154 the_error =
155 "The was a problem changing to the appropriate directory.";
156 break;
157 case 4:
158 the_error = "There was an error escaping a string.";
159 case 5:
160 the_error = "Too many arguments were passed to the indexer.";
161 break;
162 case 6:
163 the_error = "No files in this directory.";
164 break;
165 default:
166 the_error = "An unknown error occurred producing the directory.";
167 break;
168 }
169 printf("<html>\n<head>\n<title>\n%s\n</title>\n"
170 "<body>\n%s\n</body>\n</html>\n", the_error, the_error);
171 }
172
173 int select_files(CONST struct dirent *dirbuf)
174 {
175 if (dirbuf->d_name[0] == '.')
176 return 0;
177 else
178 return 1;
179 }
180
181 /*
182 * Name: index_directory
183 * Description: Called from get_dir_mapping if a directory html
184 * has to be generated on the fly
185 * If no_slash is true, prepend slashes to hrefs
186 * returns -1 for problem, else 0
187 */
188
189 int index_directory(char *dir, char *title)
190 {
191 struct dirent *dirbuf;
192 int numdir;
193 struct dirent **array;
194 struct stat statbuf;
195 char http_filename[MAX_FILE_LENGTH * 3];
196 char html_filename[MAX_FILE_LENGTH * 4];
197 int i;
198
199 if (chdir(dir) == -1) {
200 send_error(3);
201 return -1;
202 }
203 numdir = scandir(".", &array, select_files, alphasort);
204 if (numdir == -1) {
205 send_error(2);
206 return -1;
207 } else if (numdir == -2) {
208 send_error(6);
209 return -1;
210 }
211 printf("<html>\n"
212 "<head>\n<title>Index of %s</title>\n</head>\n\n"
213 "<body bgcolor=\"#ffffff\">\n"
214 "<H2>Index of %s</H2>\n"
215 "<table>\n%s",
216 title, title,
217 (strcmp(title, "/") == 0 ? "" :
218 "<tr><td colspan=3><h3>Directories</h3></td></tr>"
219 "<tr><td colspan=3><a href=\"../\">Parent Directory</a></td></tr>\n"));
220
221 for (i = 0; i < numdir; ++i) {
222 dirbuf = array[i];
223
224 if (stat(dirbuf->d_name, &statbuf) == -1)
225 continue;
226
227 if (!S_ISDIR(statbuf.st_mode))
228 continue;
229
230 if (html_escape_string(dirbuf->d_name, html_filename,
231 NAMLEN(dirbuf)) == NULL) {
232 send_error(4);
233 return -1;
234 }
235 if (http_escape_string(dirbuf->d_name, http_filename,
236 NAMLEN(dirbuf)) == NULL) {
237 send_error(4);
238 return -1;
239 }
240 printf("<tr>"
241 "<td width=\"40%%\"><a href=\"%s/\">%s/</a></td>"
242 "<td align=right>%s</td>"
243 "<td align=right>%ld bytes</td>"
244 "</tr>\n",
245 http_filename, html_filename,
246 ctime(&statbuf.st_mtime), (long) statbuf.st_size);
247 }
248
249 printf
250 ("<tr><td colspan=3>&nbsp;</td></tr>\n<tr><td colspan=3><h3>Files</h3></td></tr>\n");
251
252 for (i = 0; i < numdir; ++i) {
253 int len;
254 dirbuf = array[i];
255
256 if (stat(dirbuf->d_name, &statbuf) == -1)
257 continue;
258
259
260 if (S_ISDIR(statbuf.st_mode))
261 continue;
262
263 if (html_escape_string(dirbuf->d_name, html_filename,
264 NAMLEN(dirbuf)) == NULL) {
265 send_error(4);
266 return -1;
267 }
268 if (http_escape_string(dirbuf->d_name, http_filename,
269 NAMLEN(dirbuf)) == NULL) {
270 send_error(4);
271 return -1;
272 }
273
274 len = strlen(http_filename);
275 #ifdef GUNZIP
276 if (len > 3 && !memcmp(http_filename + len - 3, ".gz", 3)) {
277 http_filename[len - 3] = '\0';
278 html_filename[strlen(html_filename) - 3] = '\0';
279
280 printf("<tr>"
281 "<td width=\"40%%\"><a href=\"%s\">%s</a> "
282 "<a href=\"%s.gz\">(.gz)</a></td>"
283 "<td align=right>%s</td>"
284 "<td align=right>%ld bytes</td>"
285 "</tr>\n",
286 http_filename, html_filename, http_filename,
287 ctime(&statbuf.st_mtime), (long) statbuf.st_size);
288 } else {
289 #endif
290 printf("<tr>"
291 "<td width=\"40%%\"><a href=\"%s\">%s</a></td>"
292 "<td align=right>%s</td>"
293 "<td align=right>%ld bytes</td>"
294 "</tr>\n",
295 http_filename, html_filename,
296 ctime(&statbuf.st_mtime), (long) statbuf.st_size);
297 #ifdef GUNZIP
298 }
299 #endif
300 }
301 /* hey -- even though this is a one-shot deal, we should
302 * still free memory we ought to free
303 * You never know -- this code might get used elsewhere!
304 */
305 for (i = 0; i < numdir; ++i) {
306 free(array[i]);
307 array[i] = NULL;
308 }
309 free(array);
310 array = NULL;
311
312 return 0; /* success */
313 }
314
315 int main(int argc, char *argv[])
316 {
317 time_t timep;
318 struct tm *timeptr;
319 char *now;
320
321 if (argc < 3) {
322 send_error(1);
323 return -1;
324 } else if (argc > 3) {
325 send_error(5);
326 return -1;
327 }
328
329 build_needs_escape();
330
331 if (argv[2] == NULL)
332 index_directory(argv[1], argv[1]);
333 else
334 index_directory(argv[1], argv[2]);
335
336 time(&timep);
337 #ifdef USE_LOCALTIME
338 timeptr = localtime(&timep);
339 #else
340 timeptr = gmtime(&timep);
341 #endif
342 now = strdup(asctime(timeptr));
343 now[strlen(now) - 1] = '\0';
344 #ifdef USE_LOCALTIME
345 printf("</table>\n<hr noshade>\nIndex generated %s %s\n"
346 "<!-- This program is part of the Boa Webserver Copyright (C) 1991-2002 http://www.boa.org -->\n"
347 "</body>\n</html>\n", now, TIMEZONE(timeptr));
348 #else
349 printf("</table>\n<hr noshade>\nIndex generated %s UTC\n"
350 "<!-- This program is part of the Boa Webserver Copyright (C) 1991-2002 http://www.boa.org -->\n"
351 "</body>\n</html>\n", now);
352 #endif
353
354 return 0;
355 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26