]> git.pld-linux.org Git - packages/mathopd.git/blame - dir_cgi.c.txt
Release 6 (by relup.sh)
[packages/mathopd.git] / dir_cgi.c.txt
CommitLineData
9492a34b 1/*
2 * Copyright 2003 Michiel Boland.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or
6 * without modification, are permitted provided that the following
7 * conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer.
12 *
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.
17 *
18 * 3. The name of the author may not be used to endorse or promote
19 * products derived from this software without specific prior
20 * written permission.
21 *
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.
34 */
35
36#include <sys/types.h>
37#include <sys/stat.h>
38#include <dirent.h>
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42
43struct cgi_dir_entry {
44 char *name;
45 off_t size;
46 mode_t mode;
47 time_t last_modified;
48};
49
50static int cde_compare(const void *a, const void *b)
51{
52 return strcmp(((struct cgi_dir_entry *) a)->name, ((struct cgi_dir_entry *) b)->name);
53}
54
55static void escape_html_print(const char *s)
56{
57 int c;
58
59 while ((c = *s++) != 0)
60 switch (c) {
61 case '<':
62 printf("&lt;");
63 break;
64 case '&':
65 printf("&amp;");
66 break;
67 case '"':
68 printf("&quot;");
69 break;
70 default:
71 putchar(c);
72 }
73}
74
75static int sort_and_print(struct cgi_dir_entry *p, size_t n)
76{
77 size_t i;
78 const char *path_info;
79
80 if (n)
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");
87 if (path_info)
88 printf(" of %s", path_info);
89 printf("</title></head><body><p><b>index");
90 if (path_info)
91 printf(" of %s", path_info);
92 printf("</b></p>\n");
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);
99 printf("/\">");
100 escape_html_print(p[i].name);
101 printf("</a></div>\n");
102 }
103 }
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);
109 printf("\">");
110 escape_html_print(p[i].name);
111 printf("</a></div>\n");
112 }
113 }
114 printf("</body></html>\n");
115 return 0;
116}
117
118static int hide_name(const char *s)
119{
120 return s[0] == 0 || s[0] == '.';
121}
122
123static int do_dir(const char *dirname)
124{
125 struct cgi_dir_entry *p, *q;
126 size_t n;
127 int rv;
128 struct stat finfo;
129 DIR *d;
130 struct dirent *e;
131
132 p = 0;
133 n = 0;
134 rv = 0;
135 d = opendir(dirname);
136 if (d == 0) {
137 perror("opendir");
138 return 1;
139 }
140 while ((e = readdir(d)) != 0) {
141 if (hide_name(e->d_name))
142 continue;
143 if (lstat(e->d_name, &finfo) == -1) {
144 perror("lstat");
145 rv = 1;
146 break;
147 }
148 q = realloc(p, (n + 1) * sizeof *p);
149 if (q == 0) {
150 rv = 1;
151 break;
152 }
153 p = q;
154 p[n].name = strdup(e->d_name);
155 if (p[n].name == 0) {
156 rv = 1;
157 break;
158 }
159 p[n].size = finfo.st_size;
160 p[n].mode = finfo.st_mode;
161 p[n].last_modified = finfo.st_mtime;
162 ++n;
163 }
164 closedir(d);
165 if (rv == 0)
166 rv = sort_and_print(p, n);
167 while (n) {
168 --n;
169 free(p[n].name);
170 }
171 if (p)
172 free(p);
173 return rv;
174}
175
176int main(void)
177{
178 return do_dir(".");
179}
This page took 0.087886 seconds and 4 git commands to generate.