Add support for environment variable expansion
This patch teaches cgit to expand environment variables in certain cgitrc option values (cache_root, scan-path, include) plus when finding the location of cgitrc itself. One use case for this feature is virtual hosting - e.g. by setting $CGIT_CONFIG='/etc/cgitrc/$HTTP_HOST' in httpd.conf, all virtual hosts automatically gets their own cgitrc. Signed-off-by: Lars Hjemli <hjemli@gmail.com>
此提交包含在:
		
							
								
								
									
										10
									
								
								cgit.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								cgit.c
									
									
									
									
									
								
							| @@ -148,7 +148,7 @@ void config_cb(const char *name, const char *value) | ||||
| 	else if (!strcmp(name, "cache-size")) | ||||
| 		ctx.cfg.cache_size = atoi(value); | ||||
| 	else if (!strcmp(name, "cache-root")) | ||||
| 		ctx.cfg.cache_root = xstrdup(value); | ||||
| 		ctx.cfg.cache_root = xstrdup(expand_macros(value)); | ||||
| 	else if (!strcmp(name, "cache-root-ttl")) | ||||
| 		ctx.cfg.cache_root_ttl = atoi(value); | ||||
| 	else if (!strcmp(name, "cache-repo-ttl")) | ||||
| @@ -177,9 +177,9 @@ void config_cb(const char *name, const char *value) | ||||
| 		ctx.cfg.max_commit_count = atoi(value); | ||||
| 	else if (!strcmp(name, "scan-path")) | ||||
| 		if (!ctx.cfg.nocache && ctx.cfg.cache_size) | ||||
| 			process_cached_repolist(value); | ||||
| 			process_cached_repolist(expand_macros(value)); | ||||
| 		else | ||||
| 			scan_tree(value, repo_config); | ||||
| 			scan_tree(expand_macros(value), repo_config); | ||||
| 	else if (!strcmp(name, "source-filter")) | ||||
| 		ctx.cfg.source_filter = new_filter(value, 1); | ||||
| 	else if (!strcmp(name, "summary-log")) | ||||
| @@ -203,7 +203,7 @@ void config_cb(const char *name, const char *value) | ||||
| 	else if (!prefixcmp(name, "mimetype.")) | ||||
| 		add_mimetype(name + 9, value); | ||||
| 	else if (!strcmp(name, "include")) | ||||
| 		parse_configfile(value, config_cb); | ||||
| 		parse_configfile(expand_macros(value), config_cb); | ||||
| } | ||||
|  | ||||
| static void querystring_cb(const char *name, const char *value) | ||||
| @@ -688,7 +688,7 @@ int main(int argc, const char **argv) | ||||
| 	cgit_repolist.repos = NULL; | ||||
|  | ||||
| 	cgit_parse_args(argc, argv); | ||||
| 	parse_configfile(ctx.env.cgit_config, config_cb); | ||||
| 	parse_configfile(expand_macros(ctx.env.cgit_config), config_cb); | ||||
| 	ctx.repo = NULL; | ||||
| 	http_parse_querystring(ctx.qry.raw, querystring_cb); | ||||
|  | ||||
|   | ||||
							
								
								
									
										2
									
								
								cgit.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								cgit.h
									
									
									
									
									
								
							| @@ -296,4 +296,6 @@ extern int cgit_close_filter(struct cgit_filter *filter); | ||||
|  | ||||
| extern int readfile(const char *path, char **buf, size_t *size); | ||||
|  | ||||
| extern char *expand_macros(const char *txt); | ||||
|  | ||||
| #endif /* CGIT_H */ | ||||
|   | ||||
							
								
								
									
										71
									
								
								shared.c
									
									
									
									
									
								
							
							
						
						
									
										71
									
								
								shared.c
									
									
									
									
									
								
							| @@ -423,3 +423,74 @@ int readfile(const char *path, char **buf, size_t *size) | ||||
| 	close(fd); | ||||
| 	return (*size == st.st_size ? 0 : e); | ||||
| } | ||||
|  | ||||
| int is_token_char(char c) | ||||
| { | ||||
| 	return isalnum(c) || c == '_'; | ||||
| } | ||||
|  | ||||
| /* Replace name with getenv(name), return pointer to zero-terminating char | ||||
|  */ | ||||
| char *expand_macro(char *name, int maxlength) | ||||
| { | ||||
| 	char *value; | ||||
| 	int len; | ||||
|  | ||||
| 	len = 0; | ||||
| 	value = getenv(name); | ||||
| 	if (value) { | ||||
| 		len = strlen(value); | ||||
| 		if (len > maxlength) | ||||
| 			len = maxlength; | ||||
| 		strncpy(name, value, len); | ||||
| 	} | ||||
| 	return name + len; | ||||
| } | ||||
|  | ||||
| #define EXPBUFSIZE (1024 * 8) | ||||
|  | ||||
| /* Replace all tokens prefixed by '$' in the specified text with the | ||||
|  * value of the named environment variable. | ||||
|  * NB: the return value is a static buffer, i.e. it must be strdup'd | ||||
|  * by the caller. | ||||
|  */ | ||||
| char *expand_macros(const char *txt) | ||||
| { | ||||
| 	static char result[EXPBUFSIZE]; | ||||
| 	char *p, *start; | ||||
| 	int len; | ||||
|  | ||||
| 	p = result; | ||||
| 	start = NULL; | ||||
| 	while (p < result + EXPBUFSIZE - 1 && txt && *txt) { | ||||
| 		*p = *txt; | ||||
| 		if (start) { | ||||
| 			if (!is_token_char(*txt)) { | ||||
| 				if (p - start > 0) { | ||||
| 					*p = '\0'; | ||||
| 					len = result + EXPBUFSIZE - start - 1; | ||||
| 					p = expand_macro(start, len) - 1; | ||||
| 				} | ||||
| 				start = NULL; | ||||
| 				txt--; | ||||
| 			} | ||||
| 			p++; | ||||
| 			txt++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (*txt == '$') { | ||||
| 			start = p; | ||||
| 			txt++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		p++; | ||||
| 		txt++; | ||||
| 	} | ||||
| 	*p = '\0'; | ||||
| 	if (start && p - start > 0) { | ||||
| 		len = result + EXPBUFSIZE - start - 1; | ||||
| 		p = expand_macro(start, len); | ||||
| 		*p = '\0'; | ||||
| 	} | ||||
| 	return result; | ||||
| } | ||||
|   | ||||
		新增問題並參考
	
	封鎖使用者
	 Lars Hjemli
					Lars Hjemli