⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_autoindex.c

📁 apache 安装教程 apache 安装教程
💻 C
📖 第 1 页 / 共 4 页
字号:
    pool *scratch = ap_make_sub_pool(r->pool);    int name_width;    int desc_width;    char *name_scratch;    char *pad_scratch;    if (name[0] == '\0') {	name = "/";    }    desc_width = d->desc_width;    if (d->desc_adjust == K_ADJUST) {	for (x = 0; x < n; x++) {	    if (ar[x]->desc != NULL) {		int t = strlen(ar[x]->desc);		if (t > desc_width) {		    desc_width = t;		}	    }	}    }    name_width = d->name_width;    if (d->name_adjust == K_ADJUST) {	for (x = 0; x < n; x++) {	    int t = strlen(ar[x]->name);	    if (t > name_width) {		name_width = t;	    }	}    }    name_scratch = ap_palloc(r->pool, name_width + 1);    pad_scratch = ap_palloc(r->pool, name_width + 1);    memset(pad_scratch, ' ', name_width);    pad_scratch[name_width] = '\0';    if (autoindex_opts & FANCY_INDEXING) {	ap_rputs("<PRE>", r);	if ((tp = find_default_icon(d, "^^BLANKICON^^"))) {	    ap_rvputs(r, "<IMG SRC=\"", ap_escape_html(scratch, tp),		   "\" ALT=\"     \"", NULL);	    if (d->icon_width && d->icon_height) {		ap_rprintf		    (			r,			" HEIGHT=\"%d\" WIDTH=\"%d\"",			d->icon_height,			d->icon_width		    );	    }	    ap_rputs("> ", r);	}        emit_link(r, "Name", K_NAME, keyid, direction, static_columns);	ap_rputs(pad_scratch + 4, r);	/*	 * Emit the guaranteed-at-least-one-space-between-columns byte.	 */	ap_rputs(" ", r);	if (!(autoindex_opts & SUPPRESS_LAST_MOD)) {            emit_link(r, "Last modified", K_LAST_MOD, keyid, direction,                      static_columns);	    ap_rputs("       ", r);	}	if (!(autoindex_opts & SUPPRESS_SIZE)) {            emit_link(r, "Size", K_SIZE, keyid, direction, static_columns);	    ap_rputs("  ", r);	}	if (!(autoindex_opts & SUPPRESS_DESC)) {            emit_link(r, "Description", K_DESC, keyid, direction,                      static_columns);	}	ap_rputs("\n<HR>\n", r);    }    else {	ap_rputs("<UL>", r);    }    for (x = 0; x < n; x++) {	char *anchor, *t, *t2;	int nwidth;	ap_clear_pool(scratch);	if (is_parent(ar[x]->name)) {	    t = ap_make_full_path(scratch, name, "../");	    ap_getparents(t);	    if (t[0] == '\0') {		t = "/";	    }	    t2 = "Parent Directory";	    anchor = ap_escape_html(scratch, ap_os_escape_path(scratch, t, 0));	}	else {	    t = ar[x]->name;	    t2 = t;	    anchor = ap_escape_html(scratch, ap_os_escape_path(scratch, t, 0));	}	if (autoindex_opts & FANCY_INDEXING) {	    if (autoindex_opts & ICONS_ARE_LINKS) {		ap_rvputs(r, "<A HREF=\"", anchor, "\">", NULL);	    }	    if ((ar[x]->icon) || d->default_icon) {		ap_rvputs(r, "<IMG SRC=\"",			  ap_escape_html(scratch,					 ar[x]->icon ? ar[x]->icon					             : d->default_icon),			  "\" ALT=\"[", (ar[x]->alt ? ar[x]->alt : "   "),			  "]\"", NULL);		if (d->icon_width && d->icon_height) {		    ap_rprintf(r, " HEIGHT=\"%d\" WIDTH=\"%d\"",			       d->icon_height, d->icon_width);		}		ap_rputs(">", r);	    }	    if (autoindex_opts & ICONS_ARE_LINKS) {		ap_rputs("</A>", r);	    }	    nwidth = strlen(t2);	    if (nwidth > name_width) {		memcpy(name_scratch, t2, name_width - 3);		name_scratch[name_width - 3] = '.';		name_scratch[name_width - 2] = '.';		name_scratch[name_width - 1] = '>';		name_scratch[name_width] = 0;		t2 = name_scratch;		nwidth = name_width;	    }	    ap_rvputs(r, " <A HREF=\"", anchor, "\">",		      ap_escape_html(scratch, t2), "</A>",		      pad_scratch + nwidth, NULL);	    /*	     * The blank before the storm.. er, before the next field.	     */	    ap_rputs(" ", r);	    if (!(autoindex_opts & SUPPRESS_LAST_MOD)) {		if (ar[x]->lm != -1) {		    char time_str[MAX_STRING_LEN];		    struct tm *ts = localtime(&ar[x]->lm);		    strftime(time_str, MAX_STRING_LEN, "%d-%b-%Y %H:%M  ", ts);		    ap_rputs(time_str, r);		}		else {		    /*Length="22-Feb-1998 23:42  " (see 4 lines above) */		    ap_rputs("                   ", r);		}	    }	    if (!(autoindex_opts & SUPPRESS_SIZE)) {		ap_send_size(ar[x]->size, r);		ap_rputs("  ", r);	    }	    if (!(autoindex_opts & SUPPRESS_DESC)) {		if (ar[x]->desc) {		    ap_rputs(terminate_description(d, ar[x]->desc,						   autoindex_opts,						   desc_width), r);		}	    }	}	else {	    ap_rvputs(r, "<LI><A HREF=\"", anchor, "\"> ", t2,		      "</A>", NULL);	}	ap_rputc('\n', r);    }    if (autoindex_opts & FANCY_INDEXING) {	ap_rputs("</PRE>", r);    }    else {	ap_rputs("</UL>", r);    }}/* * Compare two file entries according to the sort criteria.  The return * is essentially a signum function value. */static int dsortf(struct ent **e1, struct ent **e2){    struct ent *c1;    struct ent *c2;    int result = 0;    int ignorecase;    /*     * First, see if either of the entries is for the parent directory.     * If so, that *always* sorts lower than anything else.     */    if (is_parent((*e1)->name)) {        return -1;    }    if (is_parent((*e2)->name)) {        return 1;    }    /*     * Now see if one's a directory and one isn't, AND we're listing     * directories first.     */    if ((*e1)->checkdir) {	if ((*e1)->isdir != (*e2)->isdir) {	    return (*e1)->isdir ? -1 : 1;	}    }    /*     * All of our comparisons will be of the c1 entry against the c2 one,     * so assign them appropriately to take care of the ordering.     */    if ((*e1)->ascending) {        c1 = *e1;        c2 = *e2;    }    else {        c1 = *e2;        c2 = *e1;    }    switch (c1->key) {    case K_LAST_MOD:	if (c1->lm > c2->lm) {            return 1;        }        else if (c1->lm < c2->lm) {            return -1;        }        break;    case K_SIZE:        if (c1->size > c2->size) {            return 1;        }        else if (c1->size < c2->size) {            return -1;        }        break;    case K_DESC:        result = strcmp(c1->desc ? c1->desc : "", c2->desc ? c2->desc : "");        if (result) {            return result;        }        break;    }    ignorecase = c1->ignorecase;    if (ignorecase) {        result = strcasecmp(c1->name, c2->name);        if (result == 0) {            /*             * They're identical when treated case-insensitively, so             * pretend they weren't and let strcmp() put them in a             * deterministic order.  This means that 'ABC' and 'abc'             * will always appear in the same order, rather than             * unpredictably 'ABC abc' or 'abc ABC'.             */            ignorecase = 0;        }    }    if (! ignorecase) {        result = strcmp(c1->name, c2->name);    }    return result;}static int index_directory(request_rec *r,			   autoindex_config_rec *autoindex_conf){    char *title_name = ap_escape_html(r->pool, r->uri);    char *title_endp;    char *name = r->filename;    DIR *d;    struct DIR_TYPE *dstruct;    int num_ent = 0, x;    struct ent *head, *p;    struct ent **ar = NULL;    const char *qstring;    int autoindex_opts = autoindex_conf->opts;    char keyid;    char direction;    if (!(d = ap_popendir(r->pool, name))) {	ap_log_rerror(APLOG_MARK, APLOG_ERR, r,		    "Can't open directory for index: %s", r->filename);	return HTTP_FORBIDDEN;    }    r->content_type = "text/html";    if (autoindex_opts & TRACK_MODIFIED) {        ap_update_mtime(r, r->finfo.st_mtime);        ap_set_last_modified(r);        ap_set_etag(r);    }    ap_send_http_header(r);#ifdef CHARSET_EBCDIC    /* Server-generated response, converted */    ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, r->ebcdic.conv_out = 1);#endif    if (r->header_only) {	ap_pclosedir(r->pool, d);	return 0;    }    ap_hard_timeout("send directory", r);    /* Spew HTML preamble */    title_endp = title_name + strlen(title_name) - 1;    while (title_endp > title_name && *title_endp == '/') {	*title_endp-- = '\0';    }    emit_head(r, find_header(autoindex_conf, r),	      autoindex_opts & SUPPRESS_PREAMBLE, title_name);    /*     * Figure out what sort of indexing (if any) we're supposed to use.     *     * If no QUERY_STRING was specified or column sorting has been     * explicitly disabled, we use the default specified by the     * IndexOrderDefault directive (if there is one); otherwise,     * we fall back to ascending by name.     */    qstring = r->args;    if ((autoindex_opts & SUPPRESS_COLSORT)	|| ((qstring == NULL) || (*qstring == '\0'))) {	qstring = autoindex_conf->default_order;    }    /*     * If there is no specific ordering defined for this directory,     * default to ascending by filename.     */    if ((qstring == NULL) || (*qstring == '\0')) {	keyid = K_NAME;	direction = D_ASCENDING;    }    else {	keyid = *qstring;	ap_getword(r->pool, &qstring, '=');	if (*qstring == D_DESCENDING) {	    direction = D_DESCENDING;	}	else {	    direction = D_ASCENDING;	}    }    /*      * Since we don't know how many dir. entries there are, put them into a      * linked list and then arrayificate them so qsort can use them.      */    head = NULL;    while ((dstruct = readdir(d))) {	p = make_autoindex_entry(dstruct->d_name, autoindex_opts,				 autoindex_conf, r, keyid, direction);	if (p != NULL) {	    p->next = head;	    head = p;	    num_ent++;	}    }    if (num_ent > 0) {	ar = (struct ent **) ap_palloc(r->pool,				       num_ent * sizeof(struct ent *));	p = head;	x = 0;	while (p) {	    ar[x++] = p;	    p = p->next;	}	qsort((void *) ar, num_ent, sizeof(struct ent *),	      (int (*)(const void *, const void *)) dsortf);    }    output_directories(ar, num_ent, autoindex_conf, r, autoindex_opts, keyid,		       direction);    ap_pclosedir(r->pool, d);    if (autoindex_opts & FANCY_INDEXING) {	ap_rputs("<HR>\n", r);    }    emit_tail(r, find_readme(autoindex_conf, r),	      autoindex_opts & SUPPRESS_PREAMBLE);    ap_kill_timeout(r);    return 0;}/* The formal handler... */static int handle_autoindex(request_rec *r){    autoindex_config_rec *d;    int allow_opts = ap_allow_options(r);    d = (autoindex_config_rec *) ap_get_module_config(r->per_dir_config,						      &autoindex_module);    r->allowed |= (1 << M_GET);    if (r->method_number != M_GET) {	return DECLINED;    }    /* OK, nothing easy.  Trot out the heavy artillery... */    if (allow_opts & OPT_INDEXES) {	/* KLUDGE --- make the sub_req lookups happen in the right directory.	 * Fixing this in the sub_req_lookup functions themselves is difficult,	 * and would probably break virtual includes...	 */	if (r->filename[strlen(r->filename) - 1] != '/') {	    r->filename = ap_pstrcat(r->pool, r->filename, "/", NULL);	}	return index_directory(r, d);    }    else {	ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,		     "Directory index forbidden by rule: %s", r->filename);	return HTTP_FORBIDDEN;    }}static const handler_rec autoindex_handlers[] ={    {DIR_MAGIC_TYPE, handle_autoindex},    {NULL}};module MODULE_VAR_EXPORT autoindex_module ={    STANDARD_MODULE_STUFF,    NULL,			/* initializer */    create_autoindex_config,	/* dir config creater */    merge_autoindex_configs,	/* dir merger --- default is to override */    NULL,			/* server config */    NULL,			/* merge server config */    autoindex_cmds,		/* command table */    autoindex_handlers,		/* handlers */    NULL,			/* filename translation */    NULL,			/* check_user_id */    NULL,			/* check auth */    NULL,			/* check access */    NULL,			/* type_checker */    NULL,			/* fixups */    NULL,			/* logger */    NULL,			/* header parser */    NULL,			/* child_init */    NULL,			/* child_exit */    NULL			/* post read-request */};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -