[BACK]Return to dir-index-bozo.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / libexec / httpd

Annotation of src/libexec/httpd/dir-index-bozo.c, Revision 1.1.1.6

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

CVSweb <webmaster@jp.NetBSD.org>