1 /* $NetBSD: dir-index-bozo.c,v 1.3 2007/10/18 18:53:59 ad Exp $ */ 2 3 /* $eterna: dir-index-bozo.c,v 1.7 2006/05/17 08:18:44 mrg Exp $ */ 4 5 /* 6 * Copyright (c) 1997-2006 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 dp = NULL; /* XXX */ 74 75 if (!isindex || !Xflag) 76 return 0; 77 78 if (strlen(dirname) <= strlen(index_html)) 79 dirname = "."; 80 else { 81 char *file = bozostrdup(dirname); 82 83 file[strlen(file) - strlen(index_html)] = '\0'; 84 dirname = file; 85 } 86 debug((DEBUG_FAT, "directory_index: dirname ``%s''", dirname)); 87 if (stat(dirname, &sb) < 0 || 88 (dp = opendir(dirname)) == NULL) { 89 if (errno == EPERM) 90 http_error(403, request, 91 "no permission to open directory"); 92 else if (errno == ENOENT) 93 http_error(404, request, "no file"); 94 else 95 http_error(500, request, "open directory"); 96 /* NOTREACHED */ 97 } 98 99 bozoprintf("%s 200 OK\r\n", request->hr_proto); 100 101 if (request->hr_proto != http_09) { 102 print_header(request, NULL, "text/html", ""); 103 bozoprintf("\r\n"); 104 } 105 bozoflush(stdout); 106 107 if (request->hr_method == HTTP_HEAD) { 108 closedir(dp); 109 return 1; 110 } 111 112 bozoprintf("<html><head><title>Index of %s</title></head>\r\n", 113 request->hr_url); 114 bozoprintf("<body><h1>Index of %s</h1>\r\n", request->hr_url); 115 bozoprintf("<pre>\r\n"); 116 #define NAMELEN 40 117 #define LMODLEN 19 118 bozoprintf("Name " 119 "Last modified " 120 "Size\n"); 121 bozoprintf("</pre>"); 122 directory_hr(); 123 bozoprintf("<pre>"); 124 125 while ((de = readdir(dp)) != NULL) { 126 int nostat = 0; 127 char *name = de->d_name; 128 129 if (strcmp(name, ".") == 0 || 130 (strcmp(name, "..") != 0 && Hflag && name[0] == '.')) 131 continue; 132 133 snprintf(buf, sizeof buf, "%s/%s", dirname, name); 134 if (stat(buf, &sb)) 135 nostat = 1; 136 137 l = 0; 138 139 if (strcmp(name, "..") == 0) { 140 bozoprintf("<a href=\"../\">"); 141 l += bozoprintf("Parent Directory"); 142 } else if (S_ISDIR(sb.st_mode)) { 143 bozoprintf("<a href=\"%s/\">", name); 144 l += bozoprintf("%s/", name); 145 } else { 146 bozoprintf("<a href=\"%s\">", name); 147 l += bozoprintf("%s", name); 148 } 149 bozoprintf("</a>"); 150 151 /* NAMELEN spaces */ 152 assert(sizeof(spacebuf) > NAMELEN); 153 i = (l < NAMELEN) ? (NAMELEN - l) : 0; 154 i++; 155 memset(spacebuf, ' ', i); 156 spacebuf[i] = '\0'; 157 bozoprintf(spacebuf); 158 l += i; 159 160 if (nostat) 161 bozoprintf("? ?"); 162 else { 163 tm = gmtime(&sb.st_mtime); 164 strftime(buf, sizeof buf, "%d-%b-%Y %R", tm); 165 l += bozoprintf("%s", buf); 166 167 /* LMODLEN spaces */ 168 assert(sizeof(spacebuf) > LMODLEN); 169 i = (l < (LMODLEN+NAMELEN+1)) ? ((LMODLEN+NAMELEN+1) - l) : 0; 170 i++; 171 memset(spacebuf, ' ', i); 172 spacebuf[i] = '\0'; 173 bozoprintf(spacebuf); 174 175 bozoprintf("%7ukB", 176 ((unsigned int)(sb.st_size >> 10))); 177 } 178 bozoprintf("\r\n"); 179 } 180 181 closedir(dp); 182 bozoprintf("</pre>"); 183 directory_hr(); 184 bozoprintf("</body></html>\r\n"); 185 bozoflush(stdout); 186 187 return 1; 188 } 189 #endif /* NO_DIRINDEX_SUPPORT */ 190