/[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.7 - (show annotations)
Sun Jan 26 11:25:39 2003 UTC (18 years, 10 months ago) by nmav
Branch: MAIN
CVS Tags: hydra_0_1_6_without_hic, hydra_0_1_7, hydra_0_1_6, hydra_0_1_4, hydra_0_1_8, HEAD
Changes since 1.6: +2 -2 lines
File MIME type: text/plain
Better large file support (now uses the included autoconf macros).
(++some indentation)

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.6 2002/10/26 20:58:48 nmav 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 * 5];
197 int i;
198
199 if (chdir(dir) == -1) {
200 send_error(3);
201 return -1;
202 }
203
204 numdir = scandir(".", &array, select_files, alphasort);
205 if (numdir == -1) {
206 send_error(2);
207 return -1;
208 } else if (numdir == -2) {
209 send_error(6);
210 return -1;
211 }
212
213 if (html_escape_string(title, html_filename, strlen(title)) == NULL) {
214 send_error(4);
215 return -1;
216 }
217
218 printf("<html>\n"
219 "<head>\n<title>Index of %s</title>\n</head>\n\n"
220 "<body bgcolor=\"#ffffff\">\n"
221 "<H2>Index of %s</H2>\n"
222 "<table>\n%s",
223 html_filename, html_filename,
224 (strcmp(title, "/") == 0 ? "" :
225 "<tr><td colspan=3><h3>Directories</h3></td></tr>"
226 "<tr><td colspan=3><a href=\"../\">Parent Directory</a></td></tr>\n"));
227
228 for (i = 0; i < numdir; ++i) {
229 dirbuf = array[i];
230
231 if (stat(dirbuf->d_name, &statbuf) == -1)
232 continue;
233
234 if (!S_ISDIR(statbuf.st_mode))
235 continue;
236
237 if (html_escape_string(dirbuf->d_name, html_filename,
238 NAMLEN(dirbuf)) == NULL) {
239 send_error(4);
240 return -1;
241 }
242 if (http_escape_string(dirbuf->d_name, http_filename,
243 NAMLEN(dirbuf)) == NULL) {
244 send_error(4);
245 return -1;
246 }
247 #ifndef USE_LONG_OFFSETS
248 printf("<tr>"
249 "<td width=\"40%%\"><a href=\"%s/\">%s/</a></td>"
250 "<td align=right>%s</td>"
251 "<td align=right>%ld bytes</td>"
252 "</tr>\n",
253 http_filename, html_filename,
254 ctime(&statbuf.st_mtime), (long) statbuf.st_size);
255 #else
256 printf("<tr>"
257 "<td width=\"40%%\"><a href=\"%s/\">%s/</a></td>"
258 "<td align=right>%s</td>"
259 "<td align=right>%lld bytes</td>"
260 "</tr>\n",
261 http_filename, html_filename,
262 ctime(&statbuf.st_mtime), statbuf.st_size);
263 #endif
264 }
265
266 printf
267 ("<tr><td colspan=3>&nbsp;</td></tr>\n<tr><td colspan=3><h3>Files</h3></td></tr>\n");
268
269 for (i = 0; i < numdir; ++i) {
270 int len;
271 dirbuf = array[i];
272
273 if (stat(dirbuf->d_name, &statbuf) == -1)
274 continue;
275
276
277 if (S_ISDIR(statbuf.st_mode))
278 continue;
279
280 if (html_escape_string(dirbuf->d_name, html_filename,
281 NAMLEN(dirbuf)) == NULL) {
282 send_error(4);
283 return -1;
284 }
285 if (http_escape_string(dirbuf->d_name, http_filename,
286 NAMLEN(dirbuf)) == NULL) {
287 send_error(4);
288 return -1;
289 }
290
291 len = strlen(http_filename);
292 #ifndef HAVE_STAT64
293 printf("<tr>"
294 "<td width=\"40%%\"><a href=\"%s\">%s</a></td>"
295 "<td align=right>%s</td>"
296 "<td align=right>%ld bytes</td>"
297 "</tr>\n",
298 http_filename, html_filename,
299 ctime(&statbuf.st_mtime), (long) statbuf.st_size);
300 #else
301 printf("<tr>"
302 "<td width=\"40%%\"><a href=\"%s\">%s</a></td>"
303 "<td align=right>%s</td>"
304 "<td align=right>%lld bytes</td>"
305 "</tr>\n",
306 http_filename, html_filename,
307 ctime(&statbuf.st_mtime), statbuf.st_size);
308 #endif
309 }
310 /* hey -- even though this is a one-shot deal, we should
311 * still free memory we ought to free
312 * You never know -- this code might get used elsewhere!
313 */
314 for (i = 0; i < numdir; ++i) {
315 free(array[i]);
316 array[i] = NULL;
317 }
318 free(array);
319 array = NULL;
320
321 return 0; /* success */
322 }
323
324 int main(int argc, char *argv[])
325 {
326 time_t timep;
327 struct tm *timeptr;
328 char *now;
329
330 if (argc < 3) {
331 send_error(1);
332 return -1;
333 } else if (argc > 3) {
334 send_error(5);
335 return -1;
336 }
337
338 build_needs_escape();
339
340 if (argv[2] == NULL)
341 index_directory(argv[1], argv[1]);
342 else
343 index_directory(argv[1], argv[2]);
344
345 time(&timep);
346 #ifdef USE_LOCALTIME
347 timeptr = localtime(&timep);
348 #else
349 timeptr = gmtime(&timep);
350 #endif
351 now = strdup(asctime(timeptr));
352 now[strlen(now) - 1] = '\0';
353 #ifdef USE_LOCALTIME
354 printf("</table>\n<hr noshade>\nIndex generated %s %s\n"
355 "<!-- This program is part of the Boa Webserver Copyright (C) 1991-2002 http://www.boa.org -->\n"
356 "</body>\n</html>\n", now, TIMEZONE(timeptr));
357 #else
358 printf("</table>\n<hr noshade>\nIndex generated %s UTC\n"
359 "<!-- This program is part of the Boa Webserver Copyright (C) 1991-2002 http://www.boa.org -->\n"
360 "</body>\n</html>\n", now);
361 #endif
362
363 return 0;
364 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26