1 /* dir2html.c by Michael Temari 3/3/96 */
14 typedef struct namelist
{ /* Obviously a list of names. */
15 struct namelist
*next
;
19 _PROTOTYPE(static void sort
, (namelist_t
**anl
));
20 _PROTOTYPE(static namelist_t
*collect
, (char *dir
));
21 _PROTOTYPE(int main
, (int argc
, char *argv
[]));
25 /* A stable mergesort disguised as line noise. Must be called like this:
26 * if (L != NULL && L->next != NULL) sort(&L);
29 /* static */ namelist_t
*nl1
, **mid
; /* Need not be local */
32 nl1
= *(mid
= &(*anl
)->next
);
34 if ((nl1
= nl1
->next
) == NULL
) break;
36 } while ((nl1
= nl1
->next
) != NULL
);
41 if ((*anl
)->next
!= NULL
) sort(anl
);
42 if (nl2
->next
!= NULL
) sort(&nl2
);
46 if (strcmp(nl1
->name
, nl2
->name
) <= 0) {
47 if ((nl1
= *(anl
= &nl1
->next
)) == NULL
) {
53 nl2
= *(anl
= &nl2
->next
);
55 if (nl2
== NULL
) break;
60 static namelist_t
*collect(dir
)
62 /* Return a sorted list of directory entries. Returns null with errno != 0
66 namelist_t
*names
, **pn
= &names
;
70 if ((dp
= opendir(dir
)) == NULL
) return NULL
;
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);
80 strcpy((*pn
)->name
, entry
->d_name
);
85 if (names
!= NULL
&& names
->next
!= NULL
) sort(&names
);
96 static char cwd
[1024];
101 static char month
[][4] = {
102 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
103 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
108 if (chdir(rpath
) < 0) {
109 fprintf(stderr
, "dir2html: %s: %s\n", rpath
, strerror(errno
));
113 if(getcwd(cwd
, sizeof(cwd
)) == NULL
) {
114 fprintf(stderr
, "dir2html: getcwd(): %s", strerror(errno
));
126 if ((np
= collect(".")) == NULL
&& errno
!= 0) {
127 fprintf(stderr
, "dir2html: %s: %s\n", vpath
, strerror(errno
));
131 printf("<HTML><HEAD><TITLE>Index of %s</TITLE></HEAD>\n", vpath
);
133 printf("<H1>Index of %s</H1>\n", vpath
);
136 printf("%-22s %-17s %s\n", "Name", "Last modified", "Size/Type");
144 if (stat(filename
, &st
) < 0) continue;
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
);
161 if (st
.st_size
< 10240 * 1024L) {
162 sprintf(work
, "%luK",
163 ((unsigned long) st
.st_size
- 1) / 1024 + 1);
165 sprintf(work
, "%luM",
166 ((unsigned long) st
.st_size
- 1) / (1024 * 1024L) + 1);
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]" :
176 printf(" %8s\n", work
);
182 printf("<SMALL><i>Minix httpd 0.99</i></SMALL>\n");