1 /* $NetBSD: dir-index-bozo.c,v 1.4 2008/03/03 22:15:09 mrg Exp $ */ 2 3 /* $eterna: dir-index-bozo.c,v 1.10 2008/03/03 03:36:11 mrg Exp $ */ 4 5 /* 6 * Copyright (c) 1997-2008 Matthew R. Green 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer and 16 * dedication in the documentation and/or other materials provided 17 * with the distribution. 18 * 3. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 */ 34 35 /* this code implements directory index generation for bozohttpd */ 36 37 #ifndef NO_DIRINDEX_SUPPORT 38 39 #include <sys/param.h> 40 41 #include <dirent.h> 42 #include <errno.h> 43 #include <string.h> 44 #include <time.h> 45 #include <assert.h> 46 47 #include "bozohttpd.h" 48 49 int Xflag; /* do directory indexing */ 50 int Hflag; /* hide .* */ 51 52 static void 53 directory_hr(void) 54 { 55 56 bozoprintf("<hr noshade align=\"left\" width=\"80%%\">\r\n\r\n"); 57 } 58 59 /* 60 * output a directory index. return 1 if it actually did something.. 61 */ 62 int 63 directory_index(http_req *request, const char *dirname, int isindex) 64 { 65 struct stat sb; 66 struct dirent *de; 67 struct tm *tm; 68 DIR *dp; 69 char buf[MAXPATHLEN]; 70 char spacebuf[48]; 71 int l, i; 72 73 if (!isindex || !Xflag) 74 return 0; 75 76 if (strlen(dirname) <= strlen(index_html)) 77 dirname = "."; 78 else { 79 char *file = bozostrdup(dirname); 80 81 file[strlen(file) - strlen(index_html)] = '\0'; 82 dirname = file; 83 } 84 debug((DEBUG_FAT, "directory_index: dirname ``%s''", dirname)); 85 if (stat(dirname, &sb) < 0 || 86 (dp = opendir(dirname)) == NULL) { 87 if (errno == EPERM) 88 http_error(403, request, 89 "no permission to open directory"); 90 else if (errno == ENOENT) 91 http_error(404, request, "no file"); 92 else 93 http_error(500, request, "open directory"); 94 /* NOTREACHED */ 95 } 96 97 bozoprintf("%s 200 OK\r\n", request->hr_proto); 98 99 if (request->hr_proto != http_09) { 100 print_header(request, NULL, "text/html", ""); 101 bozoprintf("\r\n"); 102 } 103 bozoflush(stdout); 104 105 if (request->hr_method == HTTP_HEAD) { 106 closedir(dp); 107 return 1; 108 } 109 110 bozoprintf("<html><head><title>Index of %s</title></head>\r\n", 111 request->hr_url); 112 bozoprintf("<body><h1>Index of %s</h1>\r\n", request->hr_url); 113 bozoprintf("<pre>\r\n"); 114 #define NAMELEN 40 115 #define LMODLEN 19 116 bozoprintf("Name " 117 "Last modified " 118 "Size\n"); 119 bozoprintf("</pre>"); 120 directory_hr(); 121 bozoprintf("<pre>"); 122 123 while ((de = readdir(dp)) != NULL) { 124 int nostat = 0; 125 char *name = de->d_name; 126 127 if (strcmp(name, ".") == 0 || 128 (strcmp(name, "..") != 0 && Hflag && name[0] == '.')) 129 continue; 130 131 snprintf(buf, sizeof buf, "%s/%s", dirname, name); 132 if (stat(buf, &sb)) 133 nostat = 1; 134 135 l = 0; 136 137 if (strcmp(name, "..") == 0) { 138 bozoprintf("<a href=\"../\">"); 139 l += bozoprintf("Parent Directory"); 140 } else if (S_ISDIR(sb.st_mode)) { 141 bozoprintf("<a href=\"%s/\">", name); 142 l += bozoprintf("%s/", name); 143 } else { 144 bozoprintf("<a href=\"%s\">", name); 145 l += bozoprintf("%s", name); 146 } 147 bozoprintf("</a>"); 148 149 /* NAMELEN spaces */ 150 assert(sizeof(spacebuf) > NAMELEN); 151 i = (l < NAMELEN) ? (NAMELEN - l) : 0; 152 i++; 153 memset(spacebuf, ' ', i); 154 spacebuf[i] = '\0'; 155 bozoprintf(spacebuf); 156 l += i; 157 158 if (nostat) 159 bozoprintf("? ?"); 160 else { 161 tm = gmtime(&sb.st_mtime); 162 strftime(buf, sizeof buf, "%d-%b-%Y %R", tm); 163 l += bozoprintf("%s", buf); 164 165 /* LMODLEN spaces */ 166 assert(sizeof(spacebuf) > LMODLEN); 167 i = (l < (LMODLEN+NAMELEN+1)) ? ((LMODLEN+NAMELEN+1) - l) : 0; 168 i++; 169 memset(spacebuf, ' ', i); 170 spacebuf[i] = '\0'; 171 bozoprintf(spacebuf); 172 173 bozoprintf("%7ukB", 174 ((unsigned int)(sb.st_size >> 10))); 175 } 176 bozoprintf("\r\n"); 177 } 178 179 closedir(dp); 180 bozoprintf("</pre>"); 181 directory_hr(); 182 bozoprintf("</body></html>\r\n\r\n"); 183 bozoflush(stdout); 184 185 return 1; 186 } 187 #endif /* NO_DIRINDEX_SUPPORT */ 188