dir-index-bozo.c revision 1.1 1 /* $eterna: dir-index-bozo.c,v 1.7 2006/05/17 08:18:44 mrg Exp $ */
2
3 /*
4 * Copyright (c) 1997-2006 Matthew R. Green
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer and
14 * dedication in the documentation and/or other materials provided
15 * with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 */
32
33 /* this code implements directory index generation for bozohttpd */
34
35 #ifndef NO_DIRINDEX_SUPPORT
36
37 #include <sys/param.h>
38
39 #include <dirent.h>
40 #include <errno.h>
41 #include <string.h>
42 #include <time.h>
43 #include <assert.h>
44
45 #include "bozohttpd.h"
46
47 int Xflag; /* do directory indexing */
48 int Hflag; /* hide .* */
49
50 /*
51 * output a directory index. return 1 if it actually did something..
52 */
53 int
54 directory_index(http_req *request, const char *dirname, int isindex)
55 {
56 struct stat sb;
57 struct dirent *de;
58 struct tm *tm;
59 DIR *dp;
60 char buf[MAXPATHLEN];
61 char spacebuf[48];
62 int l, i;
63
64 dp = NULL; /* XXX */
65
66 if (!isindex || !Xflag)
67 return 0;
68
69 if (strlen(dirname) <= strlen(index_html))
70 dirname = ".";
71 else {
72 char *file = bozostrdup(dirname);
73
74 file[strlen(file) - strlen(index_html)] = '\0';
75 dirname = file;
76 }
77 debug((DEBUG_FAT, "directory_index: dirname ``%s''", dirname));
78 if (stat(dirname, &sb) < 0 ||
79 (dp = opendir(dirname)) == NULL) {
80 if (errno == EPERM)
81 http_error(403, request,
82 "no permission to open directory");
83 else if (errno == ENOENT)
84 http_error(404, request, "no file");
85 else
86 http_error(500, request, "open directory");
87 /* NOTREACHED */
88 }
89
90 bozoprintf("%s 200 OK\r\n", request->hr_proto);
91
92 if (request->hr_proto != http_09) {
93 print_header(request, NULL, "text/html", "");
94 bozoprintf("\r\n");
95 }
96 bozoflush(stdout);
97
98 if (request->hr_method == HTTP_HEAD) {
99 closedir(dp);
100 return 1;
101 }
102
103 bozoprintf("<html><head><title>Index of %s</title></head>\r\n",
104 request->hr_url);
105 bozoprintf("<body><h1>Index of %s</h1>\r\n", request->hr_url);
106 bozoprintf("<pre>\r\n");
107 #define NAMELEN 40
108 #define LMODLEN 19
109 bozoprintf("Name "
110 "Last modified "
111 "Size\n");
112 bozoprintf("<hr noshade align=\"left\" width=\"80%%\">\r\n\r\n");
113
114 while ((de = readdir(dp)) != NULL) {
115 int nostat = 0;
116 char *name = de->d_name;
117
118 if (strcmp(name, ".") == 0 ||
119 (strcmp(name, "..") != 0 && Hflag && name[0] == '.'))
120 continue;
121
122 snprintf(buf, sizeof buf, "%s/%s", dirname, name);
123 if (stat(buf, &sb))
124 nostat = 1;
125
126 l = 0;
127
128 if (strcmp(name, "..") == 0) {
129 bozoprintf("<a href=\"../\">");
130 l += bozoprintf("Parent Directory");
131 } else if (S_ISDIR(sb.st_mode)) {
132 bozoprintf("<a href=\"%s/\">", name);
133 l += bozoprintf("%s/", name);
134 } else {
135 bozoprintf("<a href=\"%s\">", name);
136 l += bozoprintf("%s", name);
137 }
138 bozoprintf("</a>");
139
140 /* NAMELEN spaces */
141 assert(sizeof(spacebuf) > NAMELEN);
142 i = (l < NAMELEN) ? (NAMELEN - l) : 0;
143 i++;
144 memset(spacebuf, ' ', i);
145 spacebuf[i] = '\0';
146 bozoprintf(spacebuf);
147 l += i;
148
149 if (nostat)
150 bozoprintf("? ?");
151 else {
152 tm = gmtime(&sb.st_mtime);
153 strftime(buf, sizeof buf, "%d-%b-%Y %R", tm);
154 l += bozoprintf("%s", buf);
155
156 /* LMODLEN spaces */
157 assert(sizeof(spacebuf) > LMODLEN);
158 i = (l < (LMODLEN+NAMELEN+1)) ? ((LMODLEN+NAMELEN+1) - l) : 0;
159 i++;
160 memset(spacebuf, ' ', i);
161 spacebuf[i] = '\0';
162 bozoprintf(spacebuf);
163
164 bozoprintf("%7ukB",
165 ((unsigned int)(sb.st_size >> 10)));
166 }
167 bozoprintf("\r\n");
168 }
169
170 closedir(dp);
171 bozoprintf("</pre><hr></body></html>\r\n");
172 bozoflush(stdout);
173
174 return 1;
175 }
176 #endif /* NO_DIRINDEX_SUPPORT */
177