dir2html.c

Go to the documentation of this file.
00001 /* dir2html.c by Michael Temari 3/3/96 */
00002 
00003 #include <sys/types.h>
00004 #include <stddef.h>
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <dirent.h>
00008 #include <string.h>
00009 #include <unistd.h>
00010 #include <errno.h>
00011 #include <time.h>
00012 #include <sys/stat.h>
00013 
00014 typedef struct namelist {       /* Obviously a list of names. */
00015         struct namelist *next;
00016         char            name[1];
00017 } namelist_t;
00018 
00019 _PROTOTYPE(static void sort, (namelist_t **anl));
00020 _PROTOTYPE(static namelist_t *collect, (char *dir));
00021 _PROTOTYPE(int main, (int argc, char *argv[]));
00022 
00023 static void sort(anl)
00024 namelist_t **anl;
00025 /* A stable mergesort disguised as line noise.  Must be called like this:
00026  *      if (L != NULL && L->next != NULL) sort(&L);
00027  */
00028 {
00029     /* static */ namelist_t *nl1, **mid;  /* Need not be local */
00030     namelist_t *nl2;
00031 
00032     nl1 = *(mid = &(*anl)->next);
00033     do {
00034         if ((nl1 = nl1->next) == NULL) break;
00035         mid = &(*mid)->next;
00036     } while ((nl1 = nl1->next) != NULL);
00037 
00038     nl2 = *mid;
00039     *mid = NULL;
00040 
00041     if ((*anl)->next != NULL) sort(anl);
00042     if (nl2->next != NULL) sort(&nl2);
00043 
00044     nl1 = *anl;
00045     for (;;) {
00046         if (strcmp(nl1->name, nl2->name) <= 0) {
00047             if ((nl1 = *(anl = &nl1->next)) == NULL) {
00048                 *anl = nl2;
00049                 break;
00050             }
00051         } else {
00052             *anl = nl2;
00053             nl2 = *(anl = &nl2->next);
00054             *anl = nl1;
00055             if (nl2 == NULL) break;
00056         }
00057     }
00058 }
00059 
00060 static namelist_t *collect(dir)
00061 char *dir;
00062 /* Return a sorted list of directory entries.  Returns null with errno != 0
00063  * on error.
00064  */
00065 {
00066     namelist_t *names, **pn = &names;
00067     DIR *dp;
00068     struct dirent *entry;
00069 
00070     if ((dp = opendir(dir)) == NULL) return NULL;
00071 
00072     while ((entry = readdir(dp)) != NULL) {
00073         if (strcmp(entry->d_name, ".") == 0) continue;
00074         *pn = malloc(offsetof(namelist_t, name) + strlen(entry->d_name) + 1);
00075         if (*pn == NULL) {
00076             closedir(dp);
00077             errno = ENOMEM;
00078             return NULL;
00079         }
00080         strcpy((*pn)->name, entry->d_name);
00081         pn = &(*pn)->next;
00082     }
00083     closedir(dp);
00084     *pn = NULL;
00085     if (names != NULL && names->next != NULL) sort(&names);
00086     errno = 0;
00087     return names;
00088 }
00089 
00090 int main(argc, argv)
00091 int argc;
00092 char *argv[];
00093 {
00094     namelist_t *np;
00095     char *rpath, *vpath;
00096     static char cwd[1024];
00097     static char work[64];
00098     char *filename;
00099     struct stat st;
00100     struct tm *tmp;
00101     static char month[][4] = {
00102         "Jan", "Feb", "Mar", "Apr", "May", "Jun",
00103         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
00104     };
00105 
00106     if(argc > 1) {
00107         rpath = argv[1];
00108         if (chdir(rpath) < 0) {
00109             fprintf(stderr, "dir2html: %s: %s\n", rpath, strerror(errno));
00110             return(-1);
00111         }
00112     } else {
00113         if(getcwd(cwd, sizeof(cwd)) == NULL) {
00114             fprintf(stderr, "dir2html: getcwd(): %s", strerror(errno));
00115             return(-1);
00116         }
00117         rpath = cwd;
00118     }
00119 
00120     if(argc > 2) {
00121         vpath = argv[2];
00122     } else {
00123         vpath = rpath;
00124     }
00125 
00126     if ((np = collect(".")) == NULL && errno != 0) {
00127         fprintf(stderr, "dir2html: %s: %s\n", vpath, strerror(errno));
00128         return(-1);
00129     }
00130 
00131     printf("<HTML><HEAD><TITLE>Index of %s</TITLE></HEAD>\n", vpath);
00132     printf("<BODY>\n");
00133     printf("<H1>Index of %s</H1>\n", vpath);
00134 
00135     printf("<PRE>\n");
00136     printf("%-22s  %-17s  %s\n", "Name", "Last modified", "Size/Type");
00137     printf("<HR>\n");
00138 
00139     while (np != NULL) {
00140         errno = 0;
00141         filename = np->name;
00142         np= np->next;
00143 
00144         if (stat(filename, &st) < 0) continue;
00145 
00146         printf("<A HREF=\"%s%s\">",
00147             filename, S_ISDIR(st.st_mode) ? "/" : "");
00148         sprintf(work, "%.23s%s",
00149             filename, S_ISDIR(st.st_mode) ? "/" : "");
00150         if (strcmp(filename, "..") == 0) strcpy(work, "Parent Directory");
00151         printf("%-22.22s%s</A>",
00152             work, strlen(work) > 22 ? "&gt;" : " ");
00153         tmp = localtime(&st.st_mtime);
00154         printf(" %02d %s %d %02d:%02d",
00155             tmp->tm_mday, month[tmp->tm_mon], 1900+tmp->tm_year,
00156             tmp->tm_hour, tmp->tm_min);
00157         if (S_ISREG(st.st_mode)) {
00158             if (st.st_size < 10240) {
00159                 sprintf(work, "%lu ", (unsigned long) st.st_size);
00160             } else
00161             if (st.st_size < 10240 * 1024L) {
00162                 sprintf(work, "%luK",
00163                     ((unsigned long) st.st_size - 1) / 1024 + 1);
00164             } else {
00165                 sprintf(work, "%luM",
00166                     ((unsigned long) st.st_size - 1) / (1024 * 1024L) + 1);
00167             }
00168         } else {
00169             strcpy(work,
00170                 S_ISDIR(st.st_mode) ? "[dir]" :
00171                 S_ISBLK(st.st_mode) ? "[block]" :
00172                 S_ISCHR(st.st_mode) ? "[char]" :
00173                 S_ISFIFO(st.st_mode) ? "[pipe]" :
00174                                         "[???]");
00175         }
00176         printf(" %8s\n", work);
00177     }
00178 
00179     printf("</PRE>\n");
00180 
00181     printf("<HR>\n");
00182     printf("<SMALL><i>Minix httpd 0.99</i></SMALL>\n");
00183     printf("</BODY>\n");
00184     printf("</HTML>\n");
00185 
00186     return(0);
00187 }

Generated on Fri Apr 14 22:56:54 2006 for minix by  doxygen 1.4.6