1 /* $NetBSD: dir-index-bozo.c,v 1.21 2015/08/27 17:12:18 mrg Exp $ */
3 /* $eterna: dir-index-bozo.c,v 1.20 2011/11/18 09:21:15 mrg Exp $ */
6 * Copyright (c) 1997-2014 Matthew R. Green
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer and
16 * dedication in the documentation and/or other materials provided
17 * with the distribution.
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
33 /* this code implements directory index generation for bozohttpd */
35 #ifndef NO_DIRINDEX_SUPPORT
37 #include <sys/param.h>
46 #include "bozohttpd.h"
49 directory_hr(bozohttpd_t
*httpd
)
53 "<hr noshade align=\"left\" width=\"80%%\">\r\n\r\n");
57 * output a directory index. return 1 if it actually did something..
60 bozo_dir_index(bozo_httpreq_t
*request
, const char *dirpath
, int isindex
)
62 bozohttpd_t
*httpd
= request
->hr_httpd
;
64 struct dirent
**de
, **deo
;
72 if (!isindex
|| !httpd
->dir_indexing
)
75 if (strlen(dirpath
) <= strlen(httpd
->index_html
))
78 file
= bozostrdup(httpd
, dirpath
);
80 file
[strlen(file
) - strlen(httpd
->index_html
)] = '\0';
83 debug((httpd
, DEBUG_FAT
, "bozo_dir_index: dirpath ``%s''", dirpath
));
84 if (stat(dirpath
, &sb
) < 0 ||
85 (dp
= opendir(dirpath
)) == NULL
) {
87 (void)bozo_http_error(httpd
, 403, request
,
88 "no permission to open directory");
89 else if (errno
== ENOENT
)
90 (void)bozo_http_error(httpd
, 404, request
, "no file");
92 (void)bozo_http_error(httpd
, 500, request
,
98 bozo_printf(httpd
, "%s 200 OK\r\n", request
->hr_proto
);
100 if (request
->hr_proto
!= httpd
->consts
.http_09
) {
101 bozo_print_header(request
, NULL
, "text/html", "");
102 bozo_printf(httpd
, "\r\n");
104 bozo_flush(httpd
, stdout
);
106 if (request
->hr_method
== HTTP_HEAD
) {
112 "<html><head><title>Index of %s</title></head>\r\n",
114 bozo_printf(httpd
, "<body><h1>Index of %s</h1>\r\n",
116 bozo_printf(httpd
, "<pre>\r\n");
119 bozo_printf(httpd
, "Name "
122 bozo_printf(httpd
, "</pre>");
124 bozo_printf(httpd
, "<pre>");
126 for (j
= k
= scandir(dirpath
, &de
, NULL
, alphasort
), deo
= de
;
129 char *name
= (*de
)->d_name
;
130 char *urlname
, *htmlname
;
132 if (strcmp(name
, ".") == 0 ||
133 (strcmp(name
, "..") != 0 &&
134 httpd
->hide_dots
&& name
[0] == '.'))
137 snprintf(buf
, sizeof buf
, "%s/%s", dirpath
, name
);
143 urlname
= bozo_escape_rfc3986(httpd
, name
);
144 htmlname
= bozo_escape_html(httpd
, name
);
145 if (htmlname
== NULL
)
147 if (strcmp(name
, "..") == 0) {
148 bozo_printf(httpd
, "<a href=\"../\">");
149 l
+= bozo_printf(httpd
, "Parent Directory");
150 } else if (S_ISDIR(sb
.st_mode
)) {
151 bozo_printf(httpd
, "<a href=\"%s/\">", urlname
);
152 l
+= bozo_printf(httpd
, "%s/", htmlname
);
153 } else if (strchr(name
, ':') != NULL
) {
155 bozo_printf(httpd
, "<a href=\"./%s\">", urlname
);
156 l
+= bozo_printf(httpd
, "%s", htmlname
);
158 bozo_printf(httpd
, "<a href=\"%s\">", urlname
);
159 l
+= bozo_printf(httpd
, "%s", htmlname
);
161 if (htmlname
!= name
)
163 bozo_printf(httpd
, "</a>");
167 assert(/*CONSTCOND*/sizeof(spacebuf
) > NAMELEN
);
168 i
= (l
< NAMELEN
) ? (NAMELEN
- l
) : 0;
170 memset(spacebuf
, ' ', (size_t)i
);
172 bozo_printf(httpd
, "%s", spacebuf
);
176 bozo_printf(httpd
, "? ?");
178 tm
= gmtime(&sb
.st_mtime
);
179 strftime(buf
, sizeof buf
, "%d-%b-%Y %R", tm
);
180 l
+= bozo_printf(httpd
, "%s", buf
);
184 assert(/*CONSTCOND*/sizeof(spacebuf
) > LMODLEN
);
185 i
= (l
< (LMODLEN
+NAMELEN
+1)) ?
186 ((LMODLEN
+NAMELEN
+1) - l
) : 0;
188 memset(spacebuf
, ' ', (size_t)i
);
190 bozo_printf(httpd
, "%s", spacebuf
);
192 bozo_printf(httpd
, "%12llukB",
193 (unsigned long long)sb
.st_size
>> 10);
195 bozo_printf(httpd
, "\r\n");
202 bozo_printf(httpd
, "</pre>");
204 bozo_printf(httpd
, "</body></html>\r\n\r\n");
205 bozo_flush(httpd
, stdout
);
211 #endif /* NO_DIRINDEX_SUPPORT */