2 * Copyright 2003 Michiel Boland.
5 * Redistribution and use in source and binary forms, with or
6 * without modification, are permitted provided that the following
9 * 1. Redistributions of source code must retain the above
10 * copyright notice, this list of conditions and the following
13 * 2. Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials
16 * provided with the distribution.
18 * 3. The name of the author may not be used to endorse or promote
19 * products derived from this software without specific prior
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
23 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
28 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
32 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
33 * THE POSSIBILITY OF SUCH DAMAGE.
36 #include <sys/types.h>
43 struct cgi_dir_entry {
50 static int cde_compare(const void *a, const void *b)
52 return strcmp(((struct cgi_dir_entry *) a)->name, ((struct cgi_dir_entry *) b)->name);
55 static void escape_html_print(const char *s)
59 while ((c = *s++) != 0)
75 static int sort_and_print(struct cgi_dir_entry *p, size_t n)
78 const char *path_info;
81 qsort(p, n, sizeof *p, cde_compare);
82 setvbuf(stdout, 0, _IOFBF, 0);
83 printf("Cache-Control: max-age=900\n");
84 printf("Content-Type: text/html\n\n");
85 path_info = getenv("PATH_INFO");
86 printf("<html><head><title>index");
88 printf(" of %s", path_info);
89 printf("</title></head><body><p><b>index");
91 printf(" of %s", path_info);
93 printf("<p>directories:</p>\n");
94 printf("<div><a href=\"../\">[parent directory]</a></div>\n");
95 for (i = 0; i < n; i++) {
96 if (S_ISDIR(p[i].mode)) {
97 printf("<div><a href=\"");
98 escape_html_print(p[i].name);
100 escape_html_print(p[i].name);
101 printf("</a></div>\n");
104 printf("<p>files:</p>\n");
105 for (i = 0; i < n; i++) {
106 if (S_ISREG(p[i].mode)) {
107 printf("<div><a href=\"");
108 escape_html_print(p[i].name);
110 escape_html_print(p[i].name);
111 printf("</a></div>\n");
114 printf("</body></html>\n");
118 static int hide_name(const char *s)
120 return s[0] == 0 || s[0] == '.';
123 static int do_dir(const char *dirname)
125 struct cgi_dir_entry *p, *q;
135 d = opendir(dirname);
140 while ((e = readdir(d)) != 0) {
141 if (hide_name(e->d_name))
143 if (lstat(e->d_name, &finfo) == -1) {
148 q = realloc(p, (n + 1) * sizeof *p);
154 p[n].name = strdup(e->d_name);
155 if (p[n].name == 0) {
159 p[n].size = finfo.st_size;
160 p[n].mode = finfo.st_mode;
161 p[n].last_modified = finfo.st_mtime;
166 rv = sort_and_print(p, n);