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

📄 mod_autoindex.c

📁 apache 安装教程 apache 安装教程
💻 C
📖 第 1 页 / 共 4 页
字号:
		    return "DescriptionWidth value must be greater than 12";		}		d_cfg->desc_width = width;		d_cfg->desc_adjust = K_NOADJUST;	    }	}        else {	    return "Invalid directory indexing option";	}	if (action == '\0') {	    opts |= option;	    opts_add = 0;	    opts_remove = 0;	}	else if (action == '+') {	    opts_add |= option;	    opts_remove &= ~option;	}	else {	    opts_remove |= option;	    opts_add &= ~option;	}    }    if ((opts & NO_OPTIONS) && (opts & ~NO_OPTIONS)) {	return "Cannot combine other IndexOptions keywords with 'None'";    }    d_cfg->incremented_opts = opts_add;    d_cfg->decremented_opts = opts_remove;    d_cfg->opts = opts;    return NULL;}static const char *set_default_order(cmd_parms *cmd, void *m, char *direction,				     char *key){    char temp[4];    autoindex_config_rec *d_cfg = (autoindex_config_rec *) m;    ap_cpystrn(temp, "k=d", sizeof(temp));    if (!strcasecmp(direction, "Ascending")) {	temp[2] = D_ASCENDING;    }    else if (!strcasecmp(direction, "Descending")) {	temp[2] = D_DESCENDING;    }    else {	return "First keyword must be 'Ascending' or 'Descending'";    }    if (!strcasecmp(key, "Name")) {	temp[0] = K_NAME;    }    else if (!strcasecmp(key, "Date")) {	temp[0] = K_LAST_MOD;    }    else if (!strcasecmp(key, "Size")) {	temp[0] = K_SIZE;    }    else if (!strcasecmp(key, "Description")) {	temp[0] = K_DESC;    }    else {	return "Second keyword must be 'Name', 'Date', 'Size', or "	    "'Description'";    }    if (d_cfg->default_order == NULL) {	d_cfg->default_order = ap_palloc(cmd->pool, 4);	d_cfg->default_order[3] = '\0';    }    ap_cpystrn(d_cfg->default_order, temp, sizeof(temp));    return NULL;}#define DIR_CMD_PERMS OR_INDEXESstatic const command_rec autoindex_cmds[] ={    {"AddIcon", add_icon, BY_PATH, DIR_CMD_PERMS, ITERATE2,     "an icon URL followed by one or more filenames"},    {"AddIconByType", add_icon, BY_TYPE, DIR_CMD_PERMS, ITERATE2,     "an icon URL followed by one or more MIME types"},    {"AddIconByEncoding", add_icon, BY_ENCODING, DIR_CMD_PERMS, ITERATE2,     "an icon URL followed by one or more content encodings"},    {"AddAlt", add_alt, BY_PATH, DIR_CMD_PERMS, ITERATE2,     "alternate descriptive text followed by one or more filenames"},    {"AddAltByType", add_alt, BY_TYPE, DIR_CMD_PERMS, ITERATE2,     "alternate descriptive text followed by one or more MIME types"},    {"AddAltByEncoding", add_alt, BY_ENCODING, DIR_CMD_PERMS, ITERATE2,     "alternate descriptive text followed by one or more content encodings"},    {"IndexOptions", add_opts, NULL, DIR_CMD_PERMS, RAW_ARGS,     "one or more index options"},    {"IndexOrderDefault", set_default_order, NULL, DIR_CMD_PERMS, TAKE2,     "{Ascending,Descending} {Name,Size,Description,Date}"},    {"IndexIgnore", add_ignore, NULL, DIR_CMD_PERMS, ITERATE,     "one or more file extensions"},    {"AddDescription", add_desc, BY_PATH, DIR_CMD_PERMS, ITERATE2,     "Descriptive text followed by one or more filenames"},    {"HeaderName", add_header, NULL, DIR_CMD_PERMS, TAKE1, "a filename"},    {"ReadmeName", add_readme, NULL, DIR_CMD_PERMS, TAKE1, "a filename"},    {"FancyIndexing", fancy_indexing, NULL, DIR_CMD_PERMS, FLAG,     "Limited to 'on' or 'off' (superseded by IndexOptions FancyIndexing)"},    {"DefaultIcon", ap_set_string_slot,     (void *) XtOffsetOf(autoindex_config_rec, default_icon),     DIR_CMD_PERMS, TAKE1, "an icon URL"},    {NULL}};static void *create_autoindex_config(pool *p, char *dummy){    autoindex_config_rec *new =    (autoindex_config_rec *) ap_pcalloc(p, sizeof(autoindex_config_rec));    new->icon_width = 0;    new->icon_height = 0;    new->name_width = DEFAULT_NAME_WIDTH;    new->name_adjust = K_UNSET;    new->desc_width = DEFAULT_DESC_WIDTH;    new->desc_adjust = K_UNSET;    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(ai_desc_t));    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;    new->default_order = NULL;    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;    }    /*     * Inherit the NameWidth settings if there aren't any specific to     * the new location; otherwise we'll end up using the defaults set in the     * config-rec creation routine.     */    if (add->name_adjust == K_UNSET) {	new->name_width = base->name_width;	new->name_adjust = base->name_adjust;    }    else {	new->name_width = add->name_width;	new->name_adjust = add->name_adjust;    }    /*     * Likewise for DescriptionWidth.     */    if (add->desc_adjust == K_UNSET) {	new->desc_width = base->desc_width;	new->desc_adjust = base->desc_adjust;    }    else {	new->desc_width = add->desc_width;	new->desc_adjust = add->desc_adjust;    }    new->default_order = (add->default_order != NULL)	? add->default_order : base->default_order;    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;    int isdir;    int checkdir;    int ignorecase;    char key;};static char *find_item(request_rec *r, array_header *list, int path_only){    const char *content_type = ap_field_noparam(r->pool, 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_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);}/* * Look through the list of pattern/description pairs and return the first one * if any) that matches the filename in the request.  If multiple patterns * match, only the first one is used; since the order in the array is the * same as the order in which directives were processed, earlier matching * directives will dominate. */#ifdef CASE_BLIND_FILESYSTEM#define MATCH_FLAGS FNM_CASE_BLIND#else#define MATCH_FLAGS 0#endifstatic char *find_desc(autoindex_config_rec *dcfg, request_rec *r){    int i;    ai_desc_t *list = (ai_desc_t *) dcfg->desc_list->elts;    const char *filename_full = r->filename;    const char *filename_only;    const char *filename;    /*     * If the filename includes a path, extract just the name itself     * for the simple matches.     */    if ((filename_only = strrchr(filename_full, '/')) == NULL) {	filename_only = filename_full;    }    else {	filename_only++;    }    for (i = 0; i < dcfg->desc_list->nelts; ++i) {	ai_desc_t *tuple = &list[i];	int found;	/*	 * Only use the full-path filename if the pattern contains '/'s.	 */	filename = (tuple->full_path) ? filename_full : filename_only;	/*	 * Make the comparison using the cheapest method; only do	 * wildcard checking if we must.	 */	if (tuple->wildcards) {	    found = (ap_fnmatch(tuple->pattern, filename, MATCH_FLAGS) == 0);	}	else {	    found = (strstr(filename, tuple->pattern) != NULL);	}	if (found) {	    return tuple->description;	}    }    return NULL;}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 *//* * Elements of the emitted document: *	Preamble *		Emitted unless SUPPRESS_PREAMBLE is set AND ap_run_sub_req *		succeeds for the (content_type == text/html) header file. *	Header file *		Emitted if found (and able). *	H1 tag line *		Emitted if a header file is NOT emitted. *	Directory stuff *		Always emitted. *	HR *		Emitted if FANCY_INDEXING is set. *	Readme file *		Emitted if found (and able). *	ServerSig *		Emitted if ServerSignature is not Off AND a readme file *		is NOT emitted. *	Postamble *		Emitted unless SUPPRESS_PREAMBLE is set AND ap_run_sub_req *		succeeds for the (content_type == text/html) readme file. *//* * emit a plain text file */static void do_emit_plain(request_rec *r, FILE *f){    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);	}

⌨️ 快捷键说明

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