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

📄 mod_autoindex.c

📁 apache简化版
💻 C
📖 第 1 页 / 共 3 页
字号:
static void emit_link(request_rec *r, char *anchor, char fname, char curkey,                      char curdirection, int nosort){    char qvalue[5];    int reverse;    if (!nosort) {	qvalue[0] = '?';	qvalue[1] = fname;	qvalue[2] = '=';	qvalue[4] = '\0';	reverse = ((curkey == fname) && (curdirection == D_ASCENDING));	qvalue[3] = reverse ? D_DESCENDING : D_ASCENDING;	ap_rvputs(r, "<A HREF=\"", qvalue, "\">", anchor, "</A>", NULL);    }    else {        ap_rputs(anchor, r);    }}/* * Fit a string into a specified buffer width, marking any * truncation.  The size argument is the actual buffer size, including * the \0 termination byte.  The buffer will be prefilled with blanks. * If the pad argument is false, any extra spaces at the end of the * buffer are omitted.  (Used when constructing anchors.) */static ap_inline char *widthify(const char *s, char *buff, int size, int pad){    int s_len;    memset(buff, ' ', size);    buff[size - 1] = '\0';    s_len = strlen(s);    if (s_len > (size - 1)) {	ap_cpystrn(buff, s, size);	if (size > 1) {	    buff[size - 2] = '>';	}	if (size > 2) {	    buff[size - 3] = '.';	}	if (size > 3) {	    buff[size - 4] = '.';	}    }    else {	ap_cpystrn(buff, s, s_len + 1);	if (pad) {	    buff[s_len] = ' ';	}    }    return buff;}static void output_directories(struct ent **ar, int n,			       autoindex_config_rec *d, request_rec *r,			       int autoindex_opts, char keyid, char direction){    int x;    char *name = r->uri;    char *tp;    int static_columns = (autoindex_opts & SUPPRESS_COLSORT);    pool *scratch = ap_make_sub_pool(r->pool);    int name_width;    char *name_scratch;    if (name[0] == '\0') {	name = "/";    }    name_width = d->name_width;    if (d->name_adjust) {	for (x = 0; x < n; x++) {	    int t = strlen(ar[x]->name);	    if (t > name_width) {		name_width = t;	    }	}    }    ++name_width;    name_scratch = ap_palloc(r->pool, name_width + 1);    memset(name_scratch, ' ', name_width);    name_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, widthify("Name", name_scratch,			      (name_width > 5) ? 5 : name_width, K_NOPAD),		  K_NAME, keyid, direction, static_columns);	if (name_width > 5) {	    memset(name_scratch, ' ', name_width);	    name_scratch[name_width] = '\0';	    ap_rputs(&name_scratch[5], 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;	char *pad;	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 = "/";	    }	       /* 1234567890123456 */	    t2 = "Parent Directory";	    pad = name_scratch + 16;	    anchor = ap_escape_html(scratch, ap_os_escape_path(scratch, t, 0));	}	else {	    t = ar[x]->name;	    pad = name_scratch + strlen(t);	    t2 = ap_escape_html(scratch, 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);	    }	    ap_rvputs(r, " <A HREF=\"", anchor, "\">",		      widthify(t2, name_scratch, name_width, K_NOPAD),		      "</A>", NULL);	    /*	     * We know that widthify() prefilled the buffer with spaces	     * before doing its thing, so use them.	     */	    nwidth = strlen(t2);	    if (nwidth < (name_width - 1)) {		name_scratch[nwidth] = ' ';		ap_rputs(&name_scratch[nwidth], r);	    }	    /*	     * 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 {		    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), r);		}	    }	}	else {	    ap_rvputs(r, "<LI><A HREF=\"", anchor, "\"> ", t2,		      "</A>", pad, 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;    /*     * 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;    }    /*     * 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;    }    return strcmp(c1->name, c2->name);}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;    char *tmp;    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";    ap_send_http_header(r);    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';    }    if ((!(tmp = find_header(autoindex_conf, r)))	|| (!(insert_readme(name, tmp, title_name, NO_HRULE, FRONT_MATTER, r)))	) {	emit_preamble(r, title_name);	ap_rvputs(r, "<H1>Index of ", title_name, "</H1>\n", NULL);    }    /*     * Figure out what sort of indexing (if any) we're supposed to use.     */    if (autoindex_opts & SUPPRESS_COLSORT) {	keyid = K_NAME;	direction = D_ASCENDING;    }    else {	qstring = r->args;	/*	 * If no QUERY_STRING was specified, we use the default: ascending	 * by name.	 */	if ((qstring == NULL) || (*qstring == '\0')) {	    keyid = K_NAME;	    direction = D_ASCENDING;	}	else {	    keyid = *qstring;	    ap_getword(r->pool, &qstring, '=');	    if (qstring != '\0') {		direction = *qstring;	    }	    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 ((tmp = find_readme(autoindex_conf, r))) {	if (!insert_readme(name, tmp, "",			   ((autoindex_opts & FANCY_INDEXING) ? HRULE			                                      : NO_HRULE),			   END_MATTER, r)) {	    ap_rputs(ap_psignature("<HR>\n", r), r);	}    }    ap_rputs("</BODY></HTML>\n", r);    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 + -