source: trunk/minix/commands/httpd/dir2html.c@ 21

Last change on this file since 21 was 9, checked in by Mattia Monga, 13 years ago

Minix 3.1.2a

File size: 4.3 KB
Line 
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
14typedef 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
23static void sort(anl)
24namelist_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
60static namelist_t *collect(dir)
61char *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
90int main(argc, argv)
91int argc;
92char *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 ? "&gt;" : " ");
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}
Note: See TracBrowser for help on using the repository browser.