]> git.pld-linux.org Git - packages/mathopd.git/blob - dir_cgi.c.txt
Release 6 (by relup.sh)
[packages/mathopd.git] / dir_cgi.c.txt
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
43 struct cgi_dir_entry {
44         char *name;
45         off_t size;
46         mode_t mode;
47         time_t last_modified;
48 };
49
50 static 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
55 static 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
75 static 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
118 static int hide_name(const char *s)
119 {
120         return s[0] == 0 || s[0] == '.';
121 }
122
123 static 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
176 int main(void)
177 {
178         return do_dir(".");
179 }
This page took 0.05514 seconds and 3 git commands to generate.