1 | /* dir2html.c by Michael Temari 3/3/96 */
|
---|
2 |
|
---|
3 | #include <sys/types.h>
|
---|
4 | #include <stddef.h>
|
---|
5 | #include <stdio.h>
|
---|
6 | #include <stdlib.h>
|
---|
7 | #include <dirent.h>
|
---|
8 | #include <string.h>
|
---|
9 | #include <unistd.h>
|
---|
10 | #include <errno.h>
|
---|
11 | #include <time.h>
|
---|
12 | #include <sys/stat.h>
|
---|
13 |
|
---|
14 | typedef struct namelist { /* Obviously a list of names. */
|
---|
15 | struct namelist *next;
|
---|
16 | char name[1];
|
---|
17 | } namelist_t;
|
---|
18 |
|
---|
19 | _PROTOTYPE(static void sort, (namelist_t **anl));
|
---|
20 | _PROTOTYPE(static namelist_t *collect, (char *dir));
|
---|
21 | _PROTOTYPE(int main, (int argc, char *argv[]));
|
---|
22 |
|
---|
23 | static void sort(anl)
|
---|
24 | namelist_t **anl;
|
---|
25 | /* A stable mergesort disguised as line noise. Must be called like this:
|
---|
26 | * if (L != NULL && L->next != NULL) sort(&L);
|
---|
27 | */
|
---|
28 | {
|
---|
29 | /* static */ namelist_t *nl1, **mid; /* Need not be local */
|
---|
30 | namelist_t *nl2;
|
---|
31 |
|
---|
32 | nl1 = *(mid = &(*anl)->next);
|
---|
33 | do {
|
---|
34 | if ((nl1 = nl1->next) == NULL) break;
|
---|
35 | mid = &(*mid)->next;
|
---|
36 | } while ((nl1 = nl1->next) != NULL);
|
---|
37 |
|
---|
38 | nl2 = *mid;
|
---|
39 | *mid = NULL;
|
---|
40 |
|
---|
41 | if ((*anl)->next != NULL) sort(anl);
|
---|
42 | if (nl2->next != NULL) sort(&nl2);
|
---|
43 |
|
---|
44 | nl1 = *anl;
|
---|
45 | for (;;) {
|
---|
46 | if (strcmp(nl1->name, nl2->name) <= 0) {
|
---|
47 | if ((nl1 = *(anl = &nl1->next)) == NULL) {
|
---|
48 | *anl = nl2;
|
---|
49 | break;
|
---|
50 | }
|
---|
51 | } else {
|
---|
52 | *anl = nl2;
|
---|
53 | nl2 = *(anl = &nl2->next);
|
---|
54 | *anl = nl1;
|
---|
55 | if (nl2 == NULL) break;
|
---|
56 | }
|
---|
57 | }
|
---|
58 | }
|
---|
59 |
|
---|
60 | static namelist_t *collect(dir)
|
---|
61 | char *dir;
|
---|
62 | /* Return a sorted list of directory entries. Returns null with errno != 0
|
---|
63 | * on error.
|
---|
64 | */
|
---|
65 | {
|
---|
66 | namelist_t *names, **pn = &names;
|
---|
67 | DIR *dp;
|
---|
68 | struct dirent *entry;
|
---|
69 |
|
---|
70 | if ((dp = opendir(dir)) == NULL) return NULL;
|
---|
71 |
|
---|
72 | while ((entry = readdir(dp)) != NULL) {
|
---|
73 | if (strcmp(entry->d_name, ".") == 0) continue;
|
---|
74 | *pn = malloc(offsetof(namelist_t, name) + strlen(entry->d_name) + 1);
|
---|
75 | if (*pn == NULL) {
|
---|
76 | closedir(dp);
|
---|
77 | errno = ENOMEM;
|
---|
78 | return NULL;
|
---|
79 | }
|
---|
80 | strcpy((*pn)->name, entry->d_name);
|
---|
81 | pn = &(*pn)->next;
|
---|
82 | }
|
---|
83 | closedir(dp);
|
---|
84 | *pn = NULL;
|
---|
85 | if (names != NULL && names->next != NULL) sort(&names);
|
---|
86 | errno = 0;
|
---|
87 | return names;
|
---|
88 | }
|
---|
89 |
|
---|
90 | int main(argc, argv)
|
---|
91 | int argc;
|
---|
92 | char *argv[];
|
---|
93 | {
|
---|
94 | namelist_t *np;
|
---|
95 | char *rpath, *vpath;
|
---|
96 | static char cwd[1024];
|
---|
97 | static char work[64];
|
---|
98 | char *filename;
|
---|
99 | struct stat st;
|
---|
100 | struct tm *tmp;
|
---|
101 | static char month[][4] = {
|
---|
102 | "Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
---|
103 | "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
|
---|
104 | };
|
---|
105 |
|
---|
106 | if(argc > 1) {
|
---|
107 | rpath = argv[1];
|
---|
108 | if (chdir(rpath) < 0) {
|
---|
109 | fprintf(stderr, "dir2html: %s: %s\n", rpath, strerror(errno));
|
---|
110 | return(-1);
|
---|
111 | }
|
---|
112 | } else {
|
---|
113 | if(getcwd(cwd, sizeof(cwd)) == NULL) {
|
---|
114 | fprintf(stderr, "dir2html: getcwd(): %s", strerror(errno));
|
---|
115 | return(-1);
|
---|
116 | }
|
---|
117 | rpath = cwd;
|
---|
118 | }
|
---|
119 |
|
---|
120 | if(argc > 2) {
|
---|
121 | vpath = argv[2];
|
---|
122 | } else {
|
---|
123 | vpath = rpath;
|
---|
124 | }
|
---|
125 |
|
---|
126 | if ((np = collect(".")) == NULL && errno != 0) {
|
---|
127 | fprintf(stderr, "dir2html: %s: %s\n", vpath, strerror(errno));
|
---|
128 | return(-1);
|
---|
129 | }
|
---|
130 |
|
---|
131 | printf("<HTML><HEAD><TITLE>Index of %s</TITLE></HEAD>\n", vpath);
|
---|
132 | printf("<BODY>\n");
|
---|
133 | printf("<H1>Index of %s</H1>\n", vpath);
|
---|
134 |
|
---|
135 | printf("<PRE>\n");
|
---|
136 | printf("%-22s %-17s %s\n", "Name", "Last modified", "Size/Type");
|
---|
137 | printf("<HR>\n");
|
---|
138 |
|
---|
139 | while (np != NULL) {
|
---|
140 | errno = 0;
|
---|
141 | filename = np->name;
|
---|
142 | np= np->next;
|
---|
143 |
|
---|
144 | if (stat(filename, &st) < 0) continue;
|
---|
145 |
|
---|
146 | printf("<A HREF=\"%s%s\">",
|
---|
147 | filename, S_ISDIR(st.st_mode) ? "/" : "");
|
---|
148 | sprintf(work, "%.23s%s",
|
---|
149 | filename, S_ISDIR(st.st_mode) ? "/" : "");
|
---|
150 | if (strcmp(filename, "..") == 0) strcpy(work, "Parent Directory");
|
---|
151 | printf("%-22.22s%s</A>",
|
---|
152 | work, strlen(work) > 22 ? ">" : " ");
|
---|
153 | tmp = localtime(&st.st_mtime);
|
---|
154 | printf(" %02d %s %d %02d:%02d",
|
---|
155 | tmp->tm_mday, month[tmp->tm_mon], 1900+tmp->tm_year,
|
---|
156 | tmp->tm_hour, tmp->tm_min);
|
---|
157 | if (S_ISREG(st.st_mode)) {
|
---|
158 | if (st.st_size < 10240) {
|
---|
159 | sprintf(work, "%lu ", (unsigned long) st.st_size);
|
---|
160 | } else
|
---|
161 | if (st.st_size < 10240 * 1024L) {
|
---|
162 | sprintf(work, "%luK",
|
---|
163 | ((unsigned long) st.st_size - 1) / 1024 + 1);
|
---|
164 | } else {
|
---|
165 | sprintf(work, "%luM",
|
---|
166 | ((unsigned long) st.st_size - 1) / (1024 * 1024L) + 1);
|
---|
167 | }
|
---|
168 | } else {
|
---|
169 | strcpy(work,
|
---|
170 | S_ISDIR(st.st_mode) ? "[dir]" :
|
---|
171 | S_ISBLK(st.st_mode) ? "[block]" :
|
---|
172 | S_ISCHR(st.st_mode) ? "[char]" :
|
---|
173 | S_ISFIFO(st.st_mode) ? "[pipe]" :
|
---|
174 | "[???]");
|
---|
175 | }
|
---|
176 | printf(" %8s\n", work);
|
---|
177 | }
|
---|
178 |
|
---|
179 | printf("</PRE>\n");
|
---|
180 |
|
---|
181 | printf("<HR>\n");
|
---|
182 | printf("<SMALL><i>Minix httpd 0.99</i></SMALL>\n");
|
---|
183 | printf("</BODY>\n");
|
---|
184 | printf("</HTML>\n");
|
---|
185 |
|
---|
186 | return(0);
|
---|
187 | }
|
---|