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

📄 mod_autoindex.c

📁 apache简化版
💻 C
📖 第 1 页 / 共 3 页
字号:
    new->icon_list = ap_make_array(p, 4, sizeof(struct item));    new->alt_list = ap_make_array(p, 4, sizeof(struct item));    new->desc_list = ap_make_array(p, 4, sizeof(struct item));    new->ign_list = ap_make_array(p, 4, sizeof(struct item));    new->hdr_list = ap_make_array(p, 4, sizeof(struct item));    new->rdme_list = ap_make_array(p, 4, sizeof(struct item));    new->opts = 0;    new->incremented_opts = 0;    new->decremented_opts = 0;    return (void *) new;}static void *merge_autoindex_configs(pool *p, void *basev, void *addv){    autoindex_config_rec *new;    autoindex_config_rec *base = (autoindex_config_rec *) basev;    autoindex_config_rec *add = (autoindex_config_rec *) addv;    new = (autoindex_config_rec *) ap_pcalloc(p, sizeof(autoindex_config_rec));    new->default_icon = add->default_icon ? add->default_icon                                          : base->default_icon;    new->icon_height = add->icon_height ? add->icon_height : base->icon_height;    new->icon_width = add->icon_width ? add->icon_width : base->icon_width;    new->alt_list = ap_append_arrays(p, add->alt_list, base->alt_list);    new->ign_list = ap_append_arrays(p, add->ign_list, base->ign_list);    new->hdr_list = ap_append_arrays(p, add->hdr_list, base->hdr_list);    new->desc_list = ap_append_arrays(p, add->desc_list, base->desc_list);    new->icon_list = ap_append_arrays(p, add->icon_list, base->icon_list);    new->rdme_list = ap_append_arrays(p, add->rdme_list, base->rdme_list);    if (add->opts & NO_OPTIONS) {	/*	 * If the current directory says 'no options' then we also	 * clear any incremental mods from being inheritable further down.	 */	new->opts = NO_OPTIONS;	new->incremented_opts = 0;	new->decremented_opts = 0;    }    else {	/*	 * If there were any non-incremental options selected for	 * this directory, they dominate and we don't inherit *anything.*	 * Contrariwise, we *do* inherit if the only settings here are	 * incremental ones.	 */	if (add->opts == 0) {	    new->incremented_opts = (base->incremented_opts 				     | add->incremented_opts)		                    & ~add->decremented_opts;	    new->decremented_opts = (base->decremented_opts				     | add->decremented_opts);	    /*	     * We may have incremental settings, so make sure we don't	     * inadvertently inherit an IndexOptions None from above.	     */	    new->opts = (base->opts & ~NO_OPTIONS);	}	else {	    /*	     * There are local non-incremental settings, which clear	     * all inheritance from above.  They *are* the new base settings.	     */	    new->opts = add->opts;;	}	/*	 * We're guaranteed that there'll be no overlap between	 * the add-options and the remove-options.	 */	new->opts |= new->incremented_opts;	new->opts &= ~new->decremented_opts;    }    new->name_width = add->name_width;    new->name_adjust = add->name_adjust;    return new;}/**************************************************************** * * Looking things up in config entries... *//* Structure used to hold entries when we're actually building an index */struct ent {    char *name;    char *icon;    char *alt;    char *desc;    off_t size;    time_t lm;    struct ent *next;    int ascending;    char key;};static char *find_item(request_rec *r, array_header *list, int path_only){    const char *content_type = r->content_type;    const char *content_encoding = r->content_encoding;    char *path = r->filename;    struct item *items = (struct item *) list->elts;    int i;    for (i = 0; i < list->nelts; ++i) {	struct item *p = &items[i];	/* Special cased for ^^DIRECTORY^^ and ^^BLANKICON^^ */	if ((path[0] == '^') || (!ap_strcmp_match(path, p->apply_path))) {	    if (!*(p->apply_to)) {		return p->data;	    }	    else if (p->type == BY_PATH || path[0] == '^') {	        if (!ap_strcmp_match(path, p->apply_to)) {		    return p->data;		}	    }	    else if (!path_only) {		if (!content_encoding) {		    if (p->type == BY_TYPE) {			if (content_type			    && !ap_strcasecmp_match(content_type,						    p->apply_to)) {			    return p->data;			}		    }		}		else {		    if (p->type == BY_ENCODING) {			if (!ap_strcasecmp_match(content_encoding,						 p->apply_to)) {			    return p->data;			}		    }		}	    }	}    }    return NULL;}#define find_icon(d,p,t) find_item(p,d->icon_list,t)#define find_alt(d,p,t) find_item(p,d->alt_list,t)#define find_desc(d,p) find_item(p,d->desc_list,0)#define find_header(d,p) find_item(p,d->hdr_list,0)#define find_readme(d,p) find_item(p,d->rdme_list,0)static char *find_default_icon(autoindex_config_rec *d, char *bogus_name){    request_rec r;    /* Bleah.  I tried to clean up find_item, and it lead to this bit     * of ugliness.   Note that the fields initialized are precisely     * those that find_item looks at...     */    r.filename = bogus_name;    r.content_type = r.content_encoding = NULL;    return find_item(&r, d->icon_list, 1);}static int ignore_entry(autoindex_config_rec *d, char *path){    array_header *list = d->ign_list;    struct item *items = (struct item *) list->elts;    char *tt;    int i;    if ((tt = strrchr(path, '/')) == NULL) {	tt = path;    }    else {	tt++;    }    for (i = 0; i < list->nelts; ++i) {	struct item *p = &items[i];	char *ap;	if ((ap = strrchr(p->apply_to, '/')) == NULL) {	    ap = p->apply_to;	}	else {	    ap++;	}#ifndef CASE_BLIND_FILESYSTEM	if (!ap_strcmp_match(path, p->apply_path)	    && !ap_strcmp_match(tt, ap)) {	    return 1;	}#else  /* !CASE_BLIND_FILESYSTEM */	/*	 * On some platforms, the match must be case-blind.  This is really	 * a factor of the filesystem involved, but we can't detect that	 * reliably - so we have to granularise at the OS level.	 */	if (!ap_strcasecmp_match(path, p->apply_path)	    && !ap_strcasecmp_match(tt, ap)) {	    return 1;	}#endif /* !CASE_BLIND_FILESYSTEM */    }    return 0;}/***************************************************************** * * Actually generating output *//* * Look for the specified file, and pump it into the response stream if we * find it. */static int insert_readme(char *name, char *readme_fname, char *title,			 int hrule, int whichend, request_rec *r){    char *fn;    FILE *f;    struct stat finfo;    int plaintext = 0;    request_rec *rr;    autoindex_config_rec *cfg;    int autoindex_opts;    cfg = (autoindex_config_rec *) ap_get_module_config(r->per_dir_config,							&autoindex_module);    autoindex_opts = cfg->opts;    /* XXX: this is a load of crap, it needs to do a full sub_req_lookup_uri */    fn = ap_make_full_path(r->pool, name, readme_fname);    fn = ap_pstrcat(r->pool, fn, ".html", NULL);    if (stat(fn, &finfo) == -1) {	/* A brief fake multiviews search for README.html */	fn[strlen(fn) - 5] = '\0';	if (stat(fn, &finfo) == -1) {	    return 0;	}	plaintext = 1;	if (hrule) {	    ap_rputs("<HR>\n", r);	}    }    else if (hrule) {	ap_rputs("<HR>\n", r);    }    /* XXX: when the above is rewritten properly, this necessary security     * check will be redundant. -djg */    rr = ap_sub_req_lookup_file(fn, r);    if (rr->status != HTTP_OK) {	ap_destroy_sub_req(rr);	return 0;    }    ap_destroy_sub_req(rr);    if (!(f = ap_pfopen(r->pool, fn, "r"))) {        return 0;    }    if ((whichend == FRONT_MATTER)	&& (!(autoindex_opts & SUPPRESS_PREAMBLE))) {	emit_preamble(r, title);    }    if (!plaintext) {	ap_send_fd(f, r);    }    else {	char buf[IOBUFSIZE + 1];	int i, n, c, ch;	ap_rputs("<PRE>\n", r);	while (!feof(f)) {	    do {		n = fread(buf, sizeof(char), IOBUFSIZE, f);	    }	    while (n == -1 && ferror(f) && errno == EINTR);	    if (n == -1 || n == 0) {		break;	    }	    buf[n] = '\0';	    c = 0;	    while (c < n) {	        for (i = c; i < n; i++) {		    if (buf[i] == '<' || buf[i] == '>' || buf[i] == '&') {			break;		    }		}		ch = buf[i];		buf[i] = '\0';		ap_rputs(&buf[c], r);		if (ch == '<') {		    ap_rputs("&lt;", r);		}		else if (ch == '>') {		    ap_rputs("&gt;", r);		}		else if (ch == '&') {		    ap_rputs("&amp;", r);		}		c = i + 1;	    }	}    }    ap_pfclose(r->pool, f);    if (plaintext) {	ap_rputs("</PRE>\n", r);    }    return 1;}static char *find_title(request_rec *r){    char titlebuf[MAX_STRING_LEN], *find = "<TITLE>";    FILE *thefile = NULL;    int x, y, n, p;    if (r->status != HTTP_OK) {	return NULL;    }    if (r->content_type	&& (!strcmp(r->content_type, "text/html")	    || !strcmp(r->content_type, INCLUDES_MAGIC_TYPE))	&& !r->content_encoding) {        if (!(thefile = ap_pfopen(r->pool, r->filename, "r"))) {	    return NULL;	}	n = fread(titlebuf, sizeof(char), MAX_STRING_LEN - 1, thefile);	if (n <= 0) {	    ap_pfclose(r->pool, thefile);	    return NULL;	}	titlebuf[n] = '\0';	for (x = 0, p = 0; titlebuf[x]; x++) {	    if (ap_toupper(titlebuf[x]) == find[p]) {		if (!find[++p]) {		    if ((p = ap_ind(&titlebuf[++x], '<')) != -1) {			titlebuf[x + p] = '\0';		    }		    /* Scan for line breaks for Tanmoy's secretary */		    for (y = x; titlebuf[y]; y++) {			if ((titlebuf[y] == CR) || (titlebuf[y] == LF)) {			    if (y == x) {				x++;			    }			    else {				titlebuf[y] = ' ';			    }			}		    }		    ap_pfclose(r->pool, thefile);		    return ap_pstrdup(r->pool, &titlebuf[x]);		}	    }	    else {		p = 0;	    }	}	ap_pfclose(r->pool, thefile);    }    return NULL;}static struct ent *make_autoindex_entry(char *name, int autoindex_opts,					autoindex_config_rec *d,					request_rec *r, char keyid,					char direction){    struct ent *p;    if ((name[0] == '.') && (!name[1])) {	return (NULL);    }    if (ignore_entry(d, ap_make_full_path(r->pool, r->filename, name))) {        return (NULL);    }    p = (struct ent *) ap_pcalloc(r->pool, sizeof(struct ent));    p->name = ap_pstrdup(r->pool, name);    p->size = -1;    p->icon = NULL;    p->alt = NULL;    p->desc = NULL;    p->lm = -1;    p->key = ap_toupper(keyid);    p->ascending = (ap_toupper(direction) == D_ASCENDING);    if (autoindex_opts & FANCY_INDEXING) {	request_rec *rr = ap_sub_req_lookup_file(name, r);	if (rr->finfo.st_mode != 0) {	    p->lm = rr->finfo.st_mtime;	    if (S_ISDIR(rr->finfo.st_mode)) {	        if (!(p->icon = find_icon(d, rr, 1))) {		    p->icon = find_default_icon(d, "^^DIRECTORY^^");		}		if (!(p->alt = find_alt(d, rr, 1))) {		    p->alt = "DIR";		}		p->size = -1;		p->name = ap_pstrcat(r->pool, name, "/", NULL);	    }	    else {		p->icon = find_icon(d, rr, 0);		p->alt = find_alt(d, rr, 0);		p->size = rr->finfo.st_size;	    }	}	p->desc = find_desc(d, rr);	if ((!p->desc) && (autoindex_opts & SCAN_HTML_TITLES)) {	    p->desc = ap_pstrdup(r->pool, find_title(rr));	}	ap_destroy_sub_req(rr);    }    /*     * We don't need to take any special action for the file size key.  If     * we did, it would go here.     */    if (keyid == K_LAST_MOD) {        if (p->lm < 0) {	    p->lm = 0;	}    }    return (p);}static char *terminate_description(autoindex_config_rec *d, char *desc,				   int autoindex_opts){    int maxsize = 23;    register int x;    if (autoindex_opts & SUPPRESS_LAST_MOD) {	maxsize += 19;    }    if (autoindex_opts & SUPPRESS_SIZE) {	maxsize += 7;    }    for (x = 0; desc[x] && (maxsize > 0 || desc[x]=='<'); x++) {	if (desc[x] == '<') {	    while (desc[x] != '>') {		if (!desc[x]) {		    maxsize = 0;		    break;		}		++x;	    }	} 	else if (desc[x] == '&') { 	    /* entities like &auml; count as one character */ 	    --maxsize; 	    for ( ; desc[x] != ';'; ++x) { 		if (desc[x] == '\0') {                     maxsize = 0;                     break;		}	    }        }	else {	    --maxsize;	}    }    if (!maxsize && desc[x] != '\0') {	desc[x - 1] = '>';	/* Grump. */	desc[x] = '\0';		/* Double Grump! */    }    return desc;}/* * Emit the anchor for the specified field.  If a field is the key for the * current request, the link changes its meaning to reverse the order when * selected again.  Non-active fields always start in ascending order. */

⌨️ 快捷键说明

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