Annotation of src/libexec/httpd/dir-index-bozo.c, Revision 1.1.1.1
1.1 tls 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 */
CVSweb <webmaster@jp.NetBSD.org>