diff options
Diffstat (limited to 'csvncgi/ctx.c')
-rw-r--r-- | csvncgi/ctx.c | 126 |
1 files changed, 96 insertions, 30 deletions
diff --git a/csvncgi/ctx.c b/csvncgi/ctx.c index e3405c4..e7e4e2a 100644 --- a/csvncgi/ctx.c +++ b/csvncgi/ctx.c @@ -181,6 +181,7 @@ void csvn_prepare_context( void ) ctx.repo.name = NULL; ctx.repo.info = CSVN_INFO_INIT; + ctx.repo.repo_root = NULL; ctx.repo.relative_path = NULL; ctx.repo.relative_info = CSVN_INFO_INIT; ctx.repo.relative_html = NULL; @@ -408,13 +409,19 @@ static void ctx_page_size_from_repo( struct repo *repo ) static void ctx_repo_dirs_from_global( void ) { - struct variable trunk = { (unsigned char *)"trunk", { 0 }, DT_PATH }; - struct variable branches = { (unsigned char *)"branches", { 0 }, DT_PATH }; - struct variable tags = { (unsigned char *)"tags", { 0 }, DT_PATH }; + struct variable repo_root = { (unsigned char *)"repo-root", { 0 }, DT_PATH }; + struct variable trunk = { (unsigned char *)"trunk", { 0 }, DT_PATH }; + struct variable branches = { (unsigned char *)"branches", { 0 }, DT_PATH }; + struct variable tags = { (unsigned char *)"tags", { 0 }, DT_PATH }; struct variable ro_prefix = { (unsigned char *)"checkout-prefix-readonly", { 0 }, DT_PATH }; struct variable rw_prefix = { (unsigned char *)"checkout-prefix", { 0 }, DT_PATH }; struct variable *var = NULL; + var = lookup_global( lookup_global_section( config ), &repo_root ); + if( var ) + { + ctx.repo.repo_root = (const char *)var->_v.vptr; + } var = lookup_global( lookup_global_section( config ), &trunk ); if( var ) { @@ -671,15 +678,21 @@ static void ctx_promo_vars_from_global( void ) static void ctx_repo_dirs_from_repo( struct repo *repo ) { - struct variable trunk = { (unsigned char *)"trunk", { 0 }, DT_PATH }; - struct variable branches = { (unsigned char *)"branches", { 0 }, DT_PATH }; - struct variable tags = { (unsigned char *)"tags", { 0 }, DT_PATH }; + struct variable repo_root = { (unsigned char *)"repo-root", { 0 }, DT_PATH }; + struct variable trunk = { (unsigned char *)"trunk", { 0 }, DT_PATH }; + struct variable branches = { (unsigned char *)"branches", { 0 }, DT_PATH }; + struct variable tags = { (unsigned char *)"tags", { 0 }, DT_PATH }; struct variable ro_prefix = { (unsigned char *)"checkout-prefix-readonly", { 0 }, DT_PATH }; struct variable rw_prefix = { (unsigned char *)"checkout-prefix", { 0 }, DT_PATH }; struct variable *var = NULL; if( !repo ) return; + var = lookup( repo, &repo_root ); + if( var ) + { + ctx.repo.repo_root = (const char *)var->_v.vptr; + } var = lookup( repo, &trunk ); if( var ) { @@ -1165,45 +1178,92 @@ static void ctx_footer_from_repo( struct repo *repo ) } -static void ctx_repo_name( void ) +static char name[PATH_MAX] = { 0 }; +static char repo_root[PATH_MAX] = { 0 }; +static char relative_path[PATH_MAX] = { 0 }; + +static char try[PATH_MAX] = { 0 }; + +static struct repo *ctx_repo_name( void ) { - char *p, *path, *rpath, *name, *rname, *path_info; + struct repo *repo = NULL; + char *s, *p = NULL, *n, *path, *path_info; int len = 0; if( strcmp( "/", ctx.env.path_info ) ) { path_info = xstrdup( ctx.env.path_info ); - name = path_info; + s = path_info; - while( *name && is_dir_sep( *name ) ) - ++name; - p = name; - while( *p && !is_dir_sep( *p ) ) - ++p; + while( *s ) + { + while( *s && is_dir_sep( *s ) ) + ++s; + n = p = s; - if( *p ) { *p = '\0'; path = ++p; } - else - path = p; + while( *p && !is_dir_sep( *p ) ) + ++p; + if( *p ) + { + *p = '\0'; s = ++p; - len = (int)strlen( name ) + 1; - rname = (char *)__sbrk( len ); - memcpy( (void *)rname, (const void *)name, len ); - ctx.repo.name = (const char *)rname; + /**************************************************************** + The repo name can be given as a relative path in the git-root: + */ + if( repo_root[0] ) + { + sprintf( try, "%s", repo_root ); + strcat( try, "/" ); + strcat( try, n ); + } + else + { + sprintf( try, "%s", n ); + } + + if( (repo = lookup_repo( config, try )) ) + { + sprintf( name, "%s", try ); + { + char *rr = strstr( repo_root, try ); + if( rr ) + *rr = '\0'; + else + repo_root[0] = '\0'; + } + break; + } + else + { + if( repo_root[0] ) + strcat( repo_root, "/" ); + strcat( repo_root, n ); + } + } + else + s = p; + } + + ctx.repo.name = (const char *)&name[0]; + ctx.repo.repo_root = (const char *)&repo_root[0]; + + path = p; if( *path ) { len = (int)strlen( path ); - if( is_dir_sep( path[len-1] ) ) { path[len-1] = '\0'; --len; } + if( path[len-1] =='/' ) { path[len-1] = '\0'; --len; } len += 1; - rpath = (char *)__sbrk( len ); - memcpy( (void *)rpath, (const void *)path, len ); - ctx.repo.relative_path = (const char *)rpath; + sprintf( relative_path, "%s", path ); + ctx.repo.relative_path = (const char *)&relative_path[0]; } free( path_info ); } + + return repo; } @@ -1342,9 +1402,12 @@ static void ctx_relative_html( void ) } else if( !strcmp( ctx.vars.page_type, ptype_repo ) ) { - if( ctx.repo.name && *ctx.repo.name && ctx.repo.info.kind != KIND_UNKNOWN ) + if( ctx.repo.name && *ctx.repo.name && ctx.repo.info.kind != KIND_UNKNOWN ) { - strbuf_addf( &buf, "<a class='base' href='/%s/'>%s</a>/", ctx.repo.name, ctx.repo.name ); + if( ctx.repo.repo_root && *ctx.repo.repo_root ) + strbuf_addf( &buf, "<a class='base' href='/%s/%s/'>%s/%s</a>/", ctx.repo.repo_root, ctx.repo.name, ctx.repo.repo_root, ctx.repo.name ); + else + strbuf_addf( &buf, "<a class='base' href='/%s/'>%s</a>/", ctx.repo.name, ctx.repo.name ); } if( ctx.repo.relative_path && *ctx.repo.relative_path && ctx.repo.relative_info.kind != KIND_UNKNOWN ) { @@ -1524,8 +1587,7 @@ void csvn_parse_query( void ) { struct repo *repo = NULL; - ctx_repo_name(); - repo = lookup_repo( config, ctx.repo.name ); + repo = ctx_repo_name(); if( repo ) { ctx_page_size_from_repo( repo ); @@ -1562,7 +1624,11 @@ void csvn_parse_query( void ) struct strbuf buf = STRBUF_INIT; char *stmsg = NULL; - strbuf_addf( &buf, "Subversion Repository '%s' not found.", ctx.repo.name ); + /************************************************************************** + We slipped to the end of PATH_INFO when we were looking for a repository + and now we printout the repo-root: + */ + strbuf_addf( &buf, "Subversion Repository '%s' not found.", ctx.repo.repo_root ); stmsg = (char *)__sbrk( (int)buf.len + 1 ); memcpy( (void *)stmsg, (const void *)buf.buf, buf.len + 1 ); strbuf_release( &buf ); |