diff options
| author | Lars Hjemli <hjemli@gmail.com> | 2007-05-20 22:09:55 +0200 | 
|---|---|---|
| committer | Lars Hjemli <hjemli@gmail.com> | 2007-05-20 22:09:55 +0200 | 
| commit | dc3ac3f76077c5d612d42e8beb4878e43acfc58a (patch) | |
| tree | dfb996c0ce9833841578e1f0accbb5a387c01237 | |
| parent | Merge branch 'index-header' (diff) | |
| parent | Don't be fooled by trailing '/' in url-parameter (diff) | |
| download | cgit-dc3ac3f76077c5d612d42e8beb4878e43acfc58a.tar.gz cgit-dc3ac3f76077c5d612d42e8beb4878e43acfc58a.tar.bz2 cgit-dc3ac3f76077c5d612d42e8beb4878e43acfc58a.zip | |
Merge branch 'virtual-url'
* virtual-url:
  Don't be fooled by trailing '/' in url-parameter
  cache_safe_filename() needs more buffers
  Enable url=value querystring parameter
  Add lookup-function for valid repo commands
  Move cgit_get_repoinfo into shared.c
| -rw-r--r-- | cache.c | 22 | ||||
| -rw-r--r-- | cgit.c | 74 | ||||
| -rw-r--r-- | cgit.h | 15 | ||||
| -rw-r--r-- | parsing.c | 44 | ||||
| -rw-r--r-- | shared.c | 30 | ||||
| -rw-r--r-- | ui-shared.c | 5 | 
6 files changed, 139 insertions, 51 deletions
| @@ -12,18 +12,23 @@ const int NOLOCK = -1;  char *cache_safe_filename(const char *unsafe)  { -	static char buf[PATH_MAX]; -	char *s = buf; +	static char buf[4][PATH_MAX]; +	static int bufidx; +	char *s;  	char c; +	bufidx++; +	bufidx &= 3; +	s = buf[bufidx]; +  	while(unsafe && (c = *unsafe++) != 0) { -		if (c == '/' || c == ' ' || c == '&' || c == '|' ||  +		if (c == '/' || c == ' ' || c == '&' || c == '|' ||  		    c == '>' || c == '<' || c == '.')  			c = '_';  		*s++ = c;  	}  	*s = '\0'; -	return buf; +	return buf[bufidx];  }  int cache_exist(struct cacheitem *item) @@ -43,15 +48,18 @@ int cache_create_dirs()  	if (mkdir(path, S_IRWXU) && errno!=EEXIST)  		return 0; -	if (!cgit_query_repo) +	if (!cgit_repo)  		return 0; -	path = fmt("%s/%s", cgit_cache_root, cgit_query_repo); +	path = fmt("%s/%s", cgit_cache_root, +		   cache_safe_filename(cgit_repo->url)); +  	if (mkdir(path, S_IRWXU) && errno!=EEXIST)  		return 0;  	if (cgit_query_page) { -		path = fmt("%s/%s/%s", cgit_cache_root, cgit_query_repo,  +		path = fmt("%s/%s/%s", cgit_cache_root, +			   cache_safe_filename(cgit_repo->url),  			   cgit_query_page);  		if (mkdir(path, S_IRWXU) && errno!=EEXIST)  			return 0; @@ -11,29 +11,9 @@  const char cgit_version[] = CGIT_VERSION; -static struct repoinfo *cgit_get_repoinfo(char *url) -{ -	int i; -	struct repoinfo *repo; - -	for (i=0; i<cgit_repolist.count; i++) { -		repo = &cgit_repolist.repos[i]; -		if (!strcmp(repo->url, url)) -			return repo; -	} -	return NULL; -} - -  static int cgit_prepare_cache(struct cacheitem *item)  { -	if (!cgit_query_repo) { -		item->name = xstrdup(fmt("%s/index.html", cgit_cache_root)); -		item->ttl = cgit_cache_root_ttl; -		return 1; -	} -	cgit_repo = cgit_get_repoinfo(cgit_query_repo); -	if (!cgit_repo) { +	if (!cgit_repo && cgit_query_repo) {  		char *title = fmt("%s - %s", cgit_root_title, "Bad request");  		cgit_print_docstart(title, item);  		cgit_print_pageheader(title, 0); @@ -42,13 +22,19 @@ static int cgit_prepare_cache(struct cacheitem *item)  		return 0;  	} -	if (!cgit_query_page) { +	if (!cgit_repo) { +		item->name = xstrdup(fmt("%s/index.html", cgit_cache_root)); +		item->ttl = cgit_cache_root_ttl; +		return 1; +	} + +	if (!cgit_cmd) {  		item->name = xstrdup(fmt("%s/%s/index.html", cgit_cache_root, -			   cgit_repo->url)); +			   cache_safe_filename(cgit_repo->url)));  		item->ttl = cgit_cache_repo_ttl;  	} else {  		item->name = xstrdup(fmt("%s/%s/%s/%s.html", cgit_cache_root, -			   cgit_repo->url, cgit_query_page, +			   cache_safe_filename(cgit_repo->url), cgit_query_page,  			   cache_safe_filename(cgit_querystring)));  		if (cgit_query_has_symref)  			item->ttl = cgit_cache_dynamic_ttl; @@ -82,25 +68,20 @@ static void cgit_print_repo_page(struct cacheitem *item)  	show_search = 0;  	setenv("GIT_DIR", cgit_repo->path, 1); -	if (cgit_query_page) { -	    if (cgit_repo->snapshots && !strcmp(cgit_query_page, "snapshot")) { +	if ((cgit_cmd == CMD_SNAPSHOT) && cgit_repo->snapshots) {  		cgit_print_snapshot(item, cgit_query_sha1, "zip",  				    cgit_repo->url, cgit_query_name);  		return; -	    } -	    if (!strcmp(cgit_query_page, "blob")) { -		    cgit_print_blob(item, cgit_query_sha1, cgit_query_path); -		    return; -	    }  	} -	if (cgit_query_page && !strcmp(cgit_query_page, "log")) -		show_search = 1; +	if (cgit_cmd == CMD_BLOB) { +		cgit_print_blob(item, cgit_query_sha1, cgit_query_path); +		return; +	} +	show_search = (cgit_cmd == CMD_LOG);  	cgit_print_docstart(title, item); - - -	if (!cgit_query_page) { +	if (!cgit_cmd) {  		cgit_print_pageheader("summary", show_search);  		cgit_print_summary();  		cgit_print_docend(); @@ -109,20 +90,26 @@ static void cgit_print_repo_page(struct cacheitem *item)  	cgit_print_pageheader(cgit_query_page, show_search); -	if (!strcmp(cgit_query_page, "log")) { +	switch(cgit_cmd) { +	case CMD_LOG:  		cgit_print_log(cgit_query_head, cgit_query_ofs,  			       cgit_max_commit_count, cgit_query_search,  			       cgit_query_path); -	} else if (!strcmp(cgit_query_page, "tree")) { +		break; +	case CMD_TREE:  		cgit_print_tree(cgit_query_head, cgit_query_sha1, cgit_query_path); -	} else if (!strcmp(cgit_query_page, "commit")) { +		break; +	case CMD_COMMIT:  		cgit_print_commit(cgit_query_head); -	} else if (!strcmp(cgit_query_page, "view")) { +		break; +	case CMD_VIEW:  		cgit_print_view(cgit_query_sha1, cgit_query_path); -	} else if (!strcmp(cgit_query_page, "diff")) { +		break; +	case CMD_DIFF:  		cgit_print_diff(cgit_query_head, cgit_query_sha1, cgit_query_sha2,  				cgit_query_path); -	} else { +		break; +	default:  		cgit_print_error("Invalid request");  	}  	cgit_print_docend(); @@ -143,7 +130,7 @@ static void cgit_fill_cache(struct cacheitem *item, int use_cache)  		chk_positive(dup2(item->fd, STDOUT_FILENO), "Dup2(cachefile)");  	} -	if (cgit_query_repo) +	if (cgit_repo)  		cgit_print_repo_page(item);  	else  		cgit_print_repolist(item); @@ -248,6 +235,7 @@ int main(int argc, const char **argv)  	cgit_repolist.repos = NULL;  	cgit_read_config(CGIT_CONFIG, cgit_global_config_cb); +	cgit_repo = NULL;  	if (getenv("SCRIPT_NAME"))  		cgit_script_name = xstrdup(getenv("SCRIPT_NAME"));  	if (getenv("QUERY_STRING")) @@ -18,6 +18,17 @@  #include <xdiff/xdiff.h> +/* + * The valid cgit repo-commands + */ +#define CMD_LOG      1 +#define CMD_COMMIT   2 +#define CMD_DIFF     3 +#define CMD_TREE     4 +#define CMD_VIEW     5 +#define CMD_BLOB     6 +#define CMD_SNAPSHOT 7 +  typedef void (*configfn)(const char *name, const char *value);  typedef void (*filepair_fn)(struct diff_filepair *pair);  typedef void (*linediff_fn)(char *line, int len); @@ -71,6 +82,7 @@ extern const char cgit_version[];  extern struct repolist cgit_repolist;  extern struct repoinfo *cgit_repo; +extern int cgit_cmd;  extern char *cgit_root_title;  extern char *cgit_css; @@ -113,6 +125,8 @@ extern int   cgit_query_ofs;  extern int htmlfd; +extern int cgit_get_cmd_index(const char *cmd); +extern struct repoinfo *cgit_get_repoinfo(const char *url);  extern void cgit_global_config_cb(const char *name, const char *value);  extern void cgit_repo_config_cb(const char *name, const char *value);  extern void cgit_querystring_cb(const char *name, const char *value); @@ -151,6 +165,7 @@ extern int cgit_read_config(const char *filename, configfn fn);  extern int cgit_parse_query(char *txt, configfn fn);  extern struct commitinfo *cgit_parse_commit(struct commit *commit);  extern struct taginfo *cgit_parse_tag(struct tag *tag); +extern void cgit_parse_url(const char *url);  extern char *cache_safe_filename(const char *unsafe);  extern int cache_lock(struct cacheitem *item); @@ -132,6 +132,50 @@ int cgit_parse_query(char *txt, configfn fn)  	return 0;  } +/* + * url syntax: [repo ['/' cmd [ '/' path]]] + *   repo: any valid repo url, may contain '/' + *   cmd:  log | commit | diff | tree | view | blob | snapshot + *   path: any valid path, may contain '/' + * + */ +void cgit_parse_url(const char *url) +{ +	char *cmd, *p; + +	cgit_repo = NULL; +	if (!url || url[0] == '\0') +		return; + +	cgit_repo = cgit_get_repoinfo(url); +	if (cgit_repo) { +		cgit_query_repo = cgit_repo->url; +		return; +	} + +	cmd = strchr(url, '/'); +	while (!cgit_repo && cmd) { +		cmd[0] = '\0'; +		cgit_repo = cgit_get_repoinfo(url); +		if (cgit_repo == NULL) { +			cmd[0] = '/'; +			cmd = strchr(cmd + 1, '/'); +			continue; +		} + +		cgit_query_repo = cgit_repo->url; +		p = strchr(cmd + 1, '/'); +		if (p) { +			p[0] = '\0'; +			if (p[1]) +				cgit_query_path = xstrdup(p + 1); +		} +		cgit_cmd = cgit_get_cmd_index(cmd + 1); +		cgit_query_page = xstrdup(cmd + 1); +		return; +	} +} +  char *substr(const char *head, const char *tail)  {  	char *buf; @@ -10,6 +10,7 @@  struct repolist cgit_repolist;  struct repoinfo *cgit_repo; +int cgit_cmd;  char *cgit_root_title   = "Git repository browser";  char *cgit_css          = "/cgit.css"; @@ -52,6 +53,18 @@ int   cgit_query_ofs    = 0;  int htmlfd = 0; + +int cgit_get_cmd_index(const char *cmd) +{ +	static char *cmds[] = {"log", "commit", "diff", "tree", "view", "blob", "snapshot", NULL}; +	int i; + +	for(i = 0; cmds[i]; i++) +		if (!strcmp(cmd, cmds[i])) +			return i + 1; +	return 0; +} +  int chk_zero(int result, char *msg)  {  	if (result != 0) @@ -94,6 +107,19 @@ struct repoinfo *add_repo(const char *url)  	return ret;  } +struct repoinfo *cgit_get_repoinfo(const char *url) +{ +	int i; +	struct repoinfo *repo; + +	for (i=0; i<cgit_repolist.count; i++) { +		repo = &cgit_repolist.repos[i]; +		if (!strcmp(repo->url, url)) +			return repo; +	} +	return NULL; +} +  void cgit_global_config_cb(const char *name, const char *value)  {  	if (!strcmp(name, "root-title")) @@ -162,8 +188,12 @@ void cgit_querystring_cb(const char *name, const char *value)  {  	if (!strcmp(name,"r")) {  		cgit_query_repo = xstrdup(value); +		cgit_repo = cgit_get_repoinfo(value);  	} else if (!strcmp(name, "p")) {  		cgit_query_page = xstrdup(value); +		cgit_cmd = cgit_get_cmd_index(value); +	} else if (!strcmp(name, "url")) { +		cgit_parse_url(value);  	} else if (!strcmp(name, "q")) {  		cgit_query_search = xstrdup(value);  	} else if (!strcmp(name, "h")) { diff --git a/ui-shared.c b/ui-shared.c index 6211056..c7fbc5e 100644 --- a/ui-shared.c +++ b/ui-shared.c @@ -68,7 +68,10 @@ char *cgit_pageurl(const char *reponame, const char *pagename,  			return fmt("%s/%s/%s/", cgit_virtual_root, reponame,  				   pagename);  	} else { -		return fmt("?r=%s&p=%s&%s", reponame, pagename, query); +		if (query) +			return fmt("?r=%s&p=%s&%s", reponame, pagename, query); +		else +			return fmt("?r=%s&p=%s", reponame, pagename);  	}  } | 
