Annotation of src/libexec/httpd/dir-index-bozo.c, Revision 1.1.1.6
1.1.1.6 ! mrg 1: /* $eterna: dir-index-bozo.c,v 1.20 2011/11/18 09:21:15 mrg Exp $ */
1.1 tls 2:
3: /*
1.1.1.6 ! mrg 4: * Copyright (c) 1997-2011 Matthew R. Green
1.1 tls 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: *
17: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22: * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24: * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27: * SUCH DAMAGE.
28: *
29: */
30:
31: /* this code implements directory index generation for bozohttpd */
32:
33: #ifndef NO_DIRINDEX_SUPPORT
34:
35: #include <sys/param.h>
36:
37: #include <dirent.h>
38: #include <errno.h>
39: #include <string.h>
1.1.1.3 mrg 40: #include <stdlib.h>
1.1 tls 41: #include <time.h>
42: #include <assert.h>
43:
44: #include "bozohttpd.h"
45:
1.1.1.2 mrg 46: static void
1.1.1.4 mrg 47: directory_hr(bozohttpd_t *httpd)
1.1.1.2 mrg 48: {
49:
1.1.1.4 mrg 50: bozo_printf(httpd,
51: "<hr noshade align=\"left\" width=\"80%%\">\r\n\r\n");
1.1.1.2 mrg 52: }
53:
1.1 tls 54: /*
55: * output a directory index. return 1 if it actually did something..
56: */
57: int
1.1.1.4 mrg 58: bozo_dir_index(bozo_httpreq_t *request, const char *dirname, int isindex)
1.1 tls 59: {
1.1.1.4 mrg 60: bozohttpd_t *httpd = request->hr_httpd;
1.1 tls 61: struct stat sb;
1.1.1.5 mrg 62: struct dirent **de, **deo;
1.1 tls 63: struct tm *tm;
64: DIR *dp;
65: char buf[MAXPATHLEN];
66: char spacebuf[48];
1.1.1.3 mrg 67: char *file = NULL;
1.1.1.5 mrg 68: int l, k, j, i;
1.1 tls 69:
1.1.1.4 mrg 70: if (!isindex || !httpd->dir_indexing)
1.1 tls 71: return 0;
72:
1.1.1.4 mrg 73: if (strlen(dirname) <= strlen(httpd->index_html))
1.1 tls 74: dirname = ".";
75: else {
1.1.1.4 mrg 76: file = bozostrdup(httpd, dirname);
1.1 tls 77:
1.1.1.4 mrg 78: file[strlen(file) - strlen(httpd->index_html)] = '\0';
1.1 tls 79: dirname = file;
80: }
1.1.1.4 mrg 81: debug((httpd, DEBUG_FAT, "bozo_dir_index: dirname ``%s''", dirname));
1.1 tls 82: if (stat(dirname, &sb) < 0 ||
83: (dp = opendir(dirname)) == NULL) {
84: if (errno == EPERM)
1.1.1.4 mrg 85: (void)bozo_http_error(httpd, 403, request,
1.1 tls 86: "no permission to open directory");
87: else if (errno == ENOENT)
1.1.1.4 mrg 88: (void)bozo_http_error(httpd, 404, request, "no file");
1.1 tls 89: else
1.1.1.4 mrg 90: (void)bozo_http_error(httpd, 500, request,
91: "open directory");
1.1.1.3 mrg 92: goto done;
1.1 tls 93: /* NOTREACHED */
94: }
95:
1.1.1.4 mrg 96: bozo_printf(httpd, "%s 200 OK\r\n", request->hr_proto);
1.1 tls 97:
1.1.1.4 mrg 98: if (request->hr_proto != httpd->consts.http_09) {
99: bozo_print_header(request, NULL, "text/html", "");
100: bozo_printf(httpd, "\r\n");
1.1 tls 101: }
1.1.1.4 mrg 102: bozo_flush(httpd, stdout);
1.1 tls 103:
104: if (request->hr_method == HTTP_HEAD) {
105: closedir(dp);
1.1.1.3 mrg 106: goto done;
1.1 tls 107: }
108:
1.1.1.4 mrg 109: bozo_printf(httpd,
110: "<html><head><title>Index of %s</title></head>\r\n",
111: request->hr_file);
112: bozo_printf(httpd, "<body><h1>Index of %s</h1>\r\n",
113: request->hr_file);
114: bozo_printf(httpd, "<pre>\r\n");
1.1 tls 115: #define NAMELEN 40
116: #define LMODLEN 19
1.1.1.4 mrg 117: bozo_printf(httpd, "Name "
1.1 tls 118: "Last modified "
119: "Size\n");
1.1.1.4 mrg 120: bozo_printf(httpd, "</pre>");
121: directory_hr(httpd);
122: bozo_printf(httpd, "<pre>");
1.1 tls 123:
1.1.1.5 mrg 124: for (j = k = scandir(dirname, &de, NULL, alphasort), deo = de;
125: j--; de++) {
1.1 tls 126: int nostat = 0;
1.1.1.5 mrg 127: char *name = (*de)->d_name;
1.1 tls 128:
1.1.1.5 mrg 129: if (strcmp(name, ".") == 0 ||
1.1.1.4 mrg 130: (strcmp(name, "..") != 0 &&
131: httpd->hide_dots && name[0] == '.'))
1.1 tls 132: continue;
133:
134: snprintf(buf, sizeof buf, "%s/%s", dirname, name);
135: if (stat(buf, &sb))
136: nostat = 1;
137:
138: l = 0;
139:
140: if (strcmp(name, "..") == 0) {
1.1.1.4 mrg 141: bozo_printf(httpd, "<a href=\"../\">");
142: l += bozo_printf(httpd, "Parent Directory");
1.1 tls 143: } else if (S_ISDIR(sb.st_mode)) {
1.1.1.4 mrg 144: bozo_printf(httpd, "<a href=\"%s/\">", name);
145: l += bozo_printf(httpd, "%s/", name);
1.1.1.6 ! mrg 146: } else if (strchr(name, ':') != NULL) {
! 147: /* RFC 3986 4.2 */
! 148: bozo_printf(httpd, "<a href=\"./%s\">", name);
! 149: l += bozo_printf(httpd, "%s", name);
1.1 tls 150: } else {
1.1.1.4 mrg 151: bozo_printf(httpd, "<a href=\"%s\">", name);
152: l += bozo_printf(httpd, "%s", name);
1.1 tls 153: }
1.1.1.4 mrg 154: bozo_printf(httpd, "</a>");
1.1 tls 155:
156: /* NAMELEN spaces */
1.1.1.4 mrg 157: /*LINTED*/
158: assert(/*CONSTCOND*/sizeof(spacebuf) > NAMELEN);
1.1 tls 159: i = (l < NAMELEN) ? (NAMELEN - l) : 0;
160: i++;
1.1.1.4 mrg 161: memset(spacebuf, ' ', (size_t)i);
1.1 tls 162: spacebuf[i] = '\0';
1.1.1.4 mrg 163: bozo_printf(httpd, spacebuf);
1.1 tls 164: l += i;
165:
166: if (nostat)
1.1.1.4 mrg 167: bozo_printf(httpd, "? ?");
1.1 tls 168: else {
169: tm = gmtime(&sb.st_mtime);
170: strftime(buf, sizeof buf, "%d-%b-%Y %R", tm);
1.1.1.4 mrg 171: l += bozo_printf(httpd, "%s", buf);
1.1 tls 172:
173: /* LMODLEN spaces */
1.1.1.4 mrg 174: /*LINTED*/
175: assert(/*CONSTCOND*/sizeof(spacebuf) > LMODLEN);
176: i = (l < (LMODLEN+NAMELEN+1)) ?
177: ((LMODLEN+NAMELEN+1) - l) : 0;
1.1 tls 178: i++;
1.1.1.4 mrg 179: memset(spacebuf, ' ', (size_t)i);
1.1 tls 180: spacebuf[i] = '\0';
1.1.1.4 mrg 181: bozo_printf(httpd, spacebuf);
1.1 tls 182:
1.1.1.4 mrg 183: bozo_printf(httpd, "%7ukB",
184: ((unsigned)((unsigned)(sb.st_size) >> 10)));
1.1 tls 185: }
1.1.1.4 mrg 186: bozo_printf(httpd, "\r\n");
1.1 tls 187: }
188:
189: closedir(dp);
1.1.1.5 mrg 190: while (k--)
191: free(deo[k]);
192: free(deo);
1.1.1.4 mrg 193: bozo_printf(httpd, "</pre>");
194: directory_hr(httpd);
195: bozo_printf(httpd, "</body></html>\r\n\r\n");
196: bozo_flush(httpd, stdout);
1.1.1.5 mrg 197:
1.1.1.3 mrg 198: done:
199: if (file)
200: free(file);
1.1 tls 201: return 1;
202: }
203: #endif /* NO_DIRINDEX_SUPPORT */
1.1.1.5 mrg 204:
CVSweb <webmaster@jp.NetBSD.org>