diff options
| -rw-r--r-- | cache.c | 9 | ||||
| -rw-r--r-- | cgit.c | 60 | ||||
| -rw-r--r-- | cgit.h | 16 | ||||
| -rw-r--r-- | parsing.c | 43 | ||||
| -rw-r--r-- | shared.c | 5 | ||||
| -rw-r--r-- | ui-shared.c | 5 | 
6 files changed, 98 insertions, 40 deletions
| @@ -43,15 +43,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; @@ -13,13 +13,7 @@ const char cgit_version[] = CGIT_VERSION;  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); @@ -28,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; @@ -68,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(); @@ -95,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(); @@ -129,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); @@ -234,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")) @@ -21,13 +21,13 @@  /*   * The valid cgit repo-commands   */ -#define CMD_LOG      = 1; -#define CMD_COMMIT   = 1; -#define CMD_DIFF     = 1; -#define CMD_TREE     = 1; -#define CMD_VIEW     = 1; -#define CMD_BLOB     = 1; -#define CMD_SNAPSHOT = 1; +#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); @@ -82,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; @@ -162,6 +163,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,49 @@ 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'; +			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"; @@ -184,8 +185,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);  	}  } | 
