From c7693c71799633467d154afe65f9b4810cec42f5 Mon Sep 17 00:00:00 2001 From: kx Date: Wed, 12 Apr 2023 19:21:06 +0300 Subject: Added repo-root variable for repositories which placed in subdirectory relative svnserve root --- csvncgi/csvn-cgi.c | 1 + csvncgi/csvn-ui.rc.5 | 10 +++ csvncgi/ctx.c | 126 +++++++++++++++++++++++++++--------- csvncgi/ui-blame.c | 17 +++-- csvncgi/ui-diff.c | 15 ++++- csvncgi/ui-file.c | 96 +++++++++++++++++++++------ csvncgi/ui-log.c | 79 +++++++++++++++++++--- csvncgi/ui-repolist.c | 16 +++-- csvncgi/ui-shared.c | 51 +++++++++++---- csvncgi/ui-tree.c | 176 ++++++++++++++++++++++++++++++++++++++++++-------- 10 files changed, 476 insertions(+), 111 deletions(-) diff --git a/csvncgi/csvn-cgi.c b/csvncgi/csvn-cgi.c index 3a2688b..5996342 100644 --- a/csvncgi/csvn-cgi.c +++ b/csvncgi/csvn-cgi.c @@ -188,6 +188,7 @@ int main( int argc, char *argv[] ) strbuf_addf( &buf, "ctx.query.search = '%s';\n", ctx.query.search ); strbuf_addf( &buf, "\n" ); strbuf_addf( &buf, "ctx.repo.name = %s\n", ctx.repo.name ); + strbuf_addf( &buf, "ctx.repo.repo_root = %s\n", ctx.repo.repo_root ); strbuf_addf( &buf, "ctx.repo.info = {\n" ); switch( ctx.repo.info.kind ) { diff --git a/csvncgi/csvn-ui.rc.5 b/csvncgi/csvn-ui.rc.5 index c6e5f41..7931383 100644 --- a/csvncgi/csvn-ui.rc.5 +++ b/csvncgi/csvn-ui.rc.5 @@ -81,6 +81,16 @@ The integer or string value of UTC offset on the SVN server where repositories a .EE .in +.TP 4 +\fBrepo-root\fR +The name of directory where some repository is placed related to \fBsvn repositories root\fR directory. For example: +.PP +.in +6n +.EX +\fIrepo-root = 'tools';\fR +.EE +.in + .TP 4 \fBcheckout-prefix-readonly\fR The checkout prefix for readonly access to the repository. The value of this variable should has \fBpath\fR type 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, "%s/", ctx.repo.name, ctx.repo.name ); + if( ctx.repo.repo_root && *ctx.repo.repo_root ) + strbuf_addf( &buf, "%s/%s/", ctx.repo.repo_root, ctx.repo.name, ctx.repo.repo_root, ctx.repo.name ); + else + strbuf_addf( &buf, "%s/", 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 ); diff --git a/csvncgi/ui-blame.c b/csvncgi/ui-blame.c index 15fff42..ddd37cb 100644 --- a/csvncgi/ui-blame.c +++ b/csvncgi/ui-blame.c @@ -53,7 +53,8 @@ static void csvn_print_blame( struct strbuf *sb, const char *relative_path, int revision ) { const char *co_prefix = ctx.repo.checkout_ro_prefix; - const char *repo_path = ctx.repo.name; + const char *name = ctx.repo.name; + const char *repo_root = ctx.repo.repo_root; if( !sb || !relative_path ) return; @@ -62,20 +63,28 @@ static void csvn_print_blame( struct strbuf *sb, const char *relative_path, int if( co_prefix ) { - char cmd[1024]; + char repo_path[PATH_MAX] = { 0 }; + char cmd[PATH_MAX]; struct strbuf buf = STRBUF_INIT; char *raw = NULL; pid_t p = (pid_t) -1; int rc; + if( repo_root && *repo_root ) + { + strcat( (char *)&repo_path[0], repo_root ); + strcat( (char *)&repo_path[0], "/" ); + } + strcat( (char *)&repo_path[0], name ); + if( revision ) snprintf( (char *)&cmd[0], 1024, "svn blame --revision %d %s/%s/%s 2>/dev/null", - revision, co_prefix, repo_path, relative_path ); + revision, co_prefix, (char *)&repo_path[0], relative_path ); else snprintf( (char *)&cmd[0], 1024, "svn blame %s/%s/%s 2>/dev/null", - co_prefix, repo_path, relative_path ); + co_prefix, (char *)&repo_path[0], relative_path ); p = sys_exec_command( &buf, cmd ); rc = sys_wait_command( p, NULL ); if( rc != 0 ) diff --git a/csvncgi/ui-diff.c b/csvncgi/ui-diff.c index 7851f00..e74de6c 100644 --- a/csvncgi/ui-diff.c +++ b/csvncgi/ui-diff.c @@ -53,7 +53,8 @@ static void csvn_print_diff( struct strbuf *sb, const char *relative_path, int revision ) { const char *co_prefix = ctx.repo.checkout_ro_prefix; - const char *repo_path = ctx.repo.name; + const char *name = ctx.repo.name; + const char *repo_root = ctx.repo.repo_root; if( !sb || !relative_path || !revision ) return; @@ -61,15 +62,23 @@ static void csvn_print_diff( struct strbuf *sb, const char *relative_path, int r if( co_prefix ) { - char cmd[1024]; + char repo_path[PATH_MAX] = { 0 }; + char cmd[PATH_MAX]; struct strbuf buf = STRBUF_INIT; char *raw = NULL; pid_t p = (pid_t) -1; int rc; + if( repo_root && *repo_root ) + { + strcat( (char *)&repo_path[0], repo_root ); + strcat( (char *)&repo_path[0], "/" ); + } + strcat( (char *)&repo_path[0], name ); + snprintf( (char *)&cmd[0], 1024, "svn diff --revision %d:%d %s/%s/%s 2>/dev/null", - revision-1, revision, co_prefix, repo_path, relative_path ); + revision-1, revision, co_prefix, (char *)&repo_path[0], relative_path ); p = sys_exec_command( &buf, cmd ); rc = sys_wait_command( p, NULL ); if( rc != 0 ) diff --git a/csvncgi/ui-file.c b/csvncgi/ui-file.c index b20d86e..d7fe731 100644 --- a/csvncgi/ui-file.c +++ b/csvncgi/ui-file.c @@ -56,21 +56,30 @@ static int csvn_file_last_changed_revision( const char *relative_path ) { const char *co_prefix = ctx.repo.checkout_ro_prefix; - const char *repo_path = ctx.repo.name; + const char *name = ctx.repo.name; + const char *repo_root = ctx.repo.repo_root; int ret = 0; if( !relative_path ) return ret; if( co_prefix ) { - char cmd[1024]; + char repo_path[PATH_MAX] = { 0 }; + char cmd[PATH_MAX]; struct strbuf buf = STRBUF_INIT; pid_t p = (pid_t) -1; int rc; + if( repo_root && *repo_root ) + { + strcat( (char *)&repo_path[0], repo_root ); + strcat( (char *)&repo_path[0], "/" ); + } + strcat( (char *)&repo_path[0], name ); + snprintf( (char *)&cmd[0], 1024, "svn info --show-item last-changed-revision --no-newline %s/%s/%s 2>/dev/null", - co_prefix, repo_path, relative_path ); + co_prefix, (char *)&repo_path[0], relative_path ); p = sys_exec_command( &buf, cmd ); rc = sys_wait_command( p, NULL ); if( rc != 0 ) @@ -109,15 +118,33 @@ static void csvn_print_file_links( struct strbuf *sb, const char *relative_path, if( query_string && *query_string ) { - strbuf_addf( sb, "
log
\n", ctx.repo.name, relative_path, (char *)&rev[0], query_string ); - strbuf_addf( sb, "
diff
\n", ctx.repo.name, relative_path, (char *)&rev[0], query_string ); - strbuf_addf( sb, "
blame
\n", ctx.repo.name, relative_path, (char *)&rev[0], query_string ); + if( ctx.repo.repo_root && *ctx.repo.repo_root ) + { + strbuf_addf( sb, "
log
\n", ctx.repo.repo_root, ctx.repo.name, relative_path, (char *)&rev[0], query_string ); + strbuf_addf( sb, "
diff
\n", ctx.repo.repo_root, ctx.repo.name, relative_path, (char *)&rev[0], query_string ); + strbuf_addf( sb, "
blame
\n", ctx.repo.repo_root, ctx.repo.name, relative_path, (char *)&rev[0], query_string ); + } + else + { + strbuf_addf( sb, "
log
\n", ctx.repo.name, relative_path, (char *)&rev[0], query_string ); + strbuf_addf( sb, "
diff
\n", ctx.repo.name, relative_path, (char *)&rev[0], query_string ); + strbuf_addf( sb, "
blame
\n", ctx.repo.name, relative_path, (char *)&rev[0], query_string ); + } } else { - strbuf_addf( sb, "
log
\n", ctx.repo.name, relative_path, (char *)&rev[0] ); - strbuf_addf( sb, "
diff
\n", ctx.repo.name, relative_path, (char *)&rev[0] ); - strbuf_addf( sb, "
blame
\n", ctx.repo.name, relative_path, (char *)&rev[0] ); + if( ctx.repo.repo_root && *ctx.repo.repo_root ) + { + strbuf_addf( sb, "
log
\n", ctx.repo.repo_root, ctx.repo.name, relative_path, (char *)&rev[0] ); + strbuf_addf( sb, "
diff
\n", ctx.repo.repo_root, ctx.repo.name, relative_path, (char *)&rev[0] ); + strbuf_addf( sb, "
blame
\n", ctx.repo.repo_root, ctx.repo.name, relative_path, (char *)&rev[0] ); + } + else + { + strbuf_addf( sb, "
log
\n", ctx.repo.name, relative_path, (char *)&rev[0] ); + strbuf_addf( sb, "
diff
\n", ctx.repo.name, relative_path, (char *)&rev[0] ); + strbuf_addf( sb, "
blame
\n", ctx.repo.name, relative_path, (char *)&rev[0] ); + } } strbuf_addf( sb, " \n" ); @@ -144,7 +171,8 @@ static int csvn_write_markdown_content( struct strbuf *sb, const struct strbuf * static void csvn_print_markdown_file( struct strbuf *sb, const char *relative_path, int revision ) { const char *co_prefix = ctx.repo.checkout_ro_prefix; - const char *repo_path = ctx.repo.name; + const char *name = ctx.repo.name; + const char *repo_root = ctx.repo.repo_root; if( !sb || !relative_path ) return; @@ -154,19 +182,27 @@ static void csvn_print_markdown_file( struct strbuf *sb, const char *relative_pa if( co_prefix ) { - char cmd[1024]; + char repo_path[PATH_MAX] = { 0 }; + char cmd[PATH_MAX]; struct strbuf buf = STRBUF_INIT; pid_t p = (pid_t) -1; int rc; + if( repo_root && *repo_root ) + { + strcat( (char *)&repo_path[0], repo_root ); + strcat( (char *)&repo_path[0], "/" ); + } + strcat( (char *)&repo_path[0], name ); + if( revision ) snprintf( (char *)&cmd[0], 1024, "svn cat --revision %d %s/%s/%s 2>/dev/null", - revision, co_prefix, repo_path, relative_path ); + revision, co_prefix, (char *)&repo_path[0], relative_path ); else snprintf( (char *)&cmd[0], 1024, "svn cat %s/%s/%s 2>/dev/null", - co_prefix, repo_path, relative_path ); + co_prefix, (char *)&repo_path[0], relative_path ); p = sys_exec_command( &buf, cmd ); rc = sys_wait_command( p, NULL ); if( rc != 0 ) @@ -191,7 +227,8 @@ static void csvn_print_markdown_file( struct strbuf *sb, const char *relative_pa static void csvn_print_file( struct strbuf *sb, const char *relative_path, int revision, const char *lang ) { const char *co_prefix = ctx.repo.checkout_ro_prefix; - const char *repo_path = ctx.repo.name; + const char *name = ctx.repo.name; + const char *repo_root = ctx.repo.repo_root; if( !sb || !relative_path ) return; @@ -204,20 +241,28 @@ static void csvn_print_file( struct strbuf *sb, const char *relative_path, int r if( co_prefix ) { - char cmd[1024]; + char repo_path[PATH_MAX] = { 0 }; + char cmd[PATH_MAX]; struct strbuf buf = STRBUF_INIT; char *raw = NULL; pid_t p = (pid_t) -1; int rc; + if( repo_root && *repo_root ) + { + strcat( (char *)&repo_path[0], repo_root ); + strcat( (char *)&repo_path[0], "/" ); + } + strcat( (char *)&repo_path[0], name ); + if( revision ) snprintf( (char *)&cmd[0], 1024, "svn cat --revision %d %s/%s/%s 2>/dev/null", - revision, co_prefix, repo_path, relative_path ); + revision, co_prefix, (char *)&repo_path[0], relative_path ); else snprintf( (char *)&cmd[0], 1024, "svn cat %s/%s/%s 2>/dev/null", - co_prefix, repo_path, relative_path ); + co_prefix, (char *)&repo_path[0], relative_path ); p = sys_exec_command( &buf, cmd ); rc = sys_wait_command( p, NULL ); if( rc != 0 ) @@ -244,25 +289,34 @@ static void csvn_print_file( struct strbuf *sb, const char *relative_path, int r static void csvn_print_image_file( struct strbuf *sb, const char *relative_path, int revision ) { const char *co_prefix = ctx.repo.checkout_ro_prefix; - const char *repo_path = ctx.repo.name; + const char *name = ctx.repo.name; + const char *repo_root = ctx.repo.repo_root; if( !sb || !relative_path ) return; if( co_prefix ) { - char cmd[1024]; + char repo_path[PATH_MAX] = { 0 }; + char cmd[PATH_MAX]; struct strbuf buf = STRBUF_INIT; pid_t p = (pid_t) -1; int rc; + if( repo_root && *repo_root ) + { + strcat( (char *)&repo_path[0], repo_root ); + strcat( (char *)&repo_path[0], "/" ); + } + strcat( (char *)&repo_path[0], name ); + if( revision ) snprintf( (char *)&cmd[0], 1024, "svn cat --revision %d %s/%s/%s 2>/dev/null", - revision, co_prefix, repo_path, relative_path ); + revision, co_prefix, (char *)&repo_path[0], relative_path ); else snprintf( (char *)&cmd[0], 1024, "svn cat %s/%s/%s 2>/dev/null", - co_prefix, repo_path, relative_path ); + co_prefix, (char *)&repo_path[0], relative_path ); p = sys_exec_command( &buf, cmd ); rc = sys_wait_command( p, NULL ); if( rc != 0 ) diff --git a/csvncgi/ui-log.c b/csvncgi/ui-log.c index d0c17b6..a97dd06 100644 --- a/csvncgi/ui-log.c +++ b/csvncgi/ui-log.c @@ -167,11 +167,25 @@ static void xml_csvn_log( struct strbuf *sb, const struct strbuf *buf, const cha strbuf_addf( sb, "
%s
\n", (char *)cmsg ); if( query_string && *query_string ) { - strbuf_addf( sb, "
\n", ctx.repo.name, path, (char *)revision, query_string, (char *)revision ); + if( ctx.repo.repo_root && *ctx.repo.repo_root ) + { + strbuf_addf( sb, "
\n", ctx.repo.repo_root, ctx.repo.name, path, (char *)revision, query_string, (char *)revision ); + } + else + { + strbuf_addf( sb, "
\n", ctx.repo.name, path, (char *)revision, query_string, (char *)revision ); + } } else { - strbuf_addf( sb, "
\n", ctx.repo.name, path, (char *)revision, (char *)revision ); + if( ctx.repo.repo_root && *ctx.repo.repo_root ) + { + strbuf_addf( sb, "
\n", ctx.repo.repo_root, path, ctx.repo.name, path, (char *)revision, (char *)revision ); + } + else + { + strbuf_addf( sb, "
\n", ctx.repo.name, path, (char *)revision, (char *)revision ); + } } strbuf_addf( sb, "
%s
\n", (char *)author ); strbuf_addf( sb, " \n\n" ); @@ -215,9 +229,27 @@ static void xml_csvn_log( struct strbuf *sb, const struct strbuf *buf, const cha if( prev < 0 ) prev = 0; if( ctx.env.query_string && *ctx.env.query_string ) - strbuf_addf( sb, " ≪  Prev\n", ctx.repo.name, path, prev, ctx.env.query_string ); + { + if( ctx.repo.repo_root && *ctx.repo.repo_root ) + { + strbuf_addf( sb, " ≪  Prev\n", ctx.repo.repo_root, ctx.repo.name, path, prev, ctx.env.query_string ); + } + else + { + strbuf_addf( sb, " ≪  Prev\n", ctx.repo.name, path, prev, ctx.env.query_string ); + } + } else - strbuf_addf( sb, " ≪  Prev\n", ctx.repo.name, path, prev ); + { + if( ctx.repo.repo_root && *ctx.repo.repo_root ) + { + strbuf_addf( sb, " ≪  Prev\n", ctx.repo.repo_root, ctx.repo.name, path, prev ); + } + else + { + strbuf_addf( sb, " ≪  Prev\n", ctx.repo.name, path, prev ); + } + } } strbuf_addf( sb, " \n" ); @@ -230,9 +262,27 @@ static void xml_csvn_log( struct strbuf *sb, const struct strbuf *buf, const cha next = ctx.query.ofs + page_size; if( ctx.env.query_string && *ctx.env.query_string ) - strbuf_addf( sb, " Next  ≫\n", ctx.repo.name, path, next, ctx.env.query_string ); + { + if( ctx.repo.repo_root && *ctx.repo.repo_root ) + { + strbuf_addf( sb, " Next  ≫\n", ctx.repo.repo_root, ctx.repo.name, path, next, ctx.env.query_string ); + } + else + { + strbuf_addf( sb, " Next  ≫\n", ctx.repo.name, path, next, ctx.env.query_string ); + } + } else - strbuf_addf( sb, " Next  ≫\n", ctx.repo.name, path, next ); + { + if( ctx.repo.repo_root && *ctx.repo.repo_root ) + { + strbuf_addf( sb, " Next  ≫\n", ctx.repo.repo_root, ctx.repo.name, path, next ); + } + else + { + strbuf_addf( sb, " Next  ≫\n", ctx.repo.name, path, next ); + } + } } strbuf_addf( sb, " \n" ); @@ -254,7 +304,8 @@ static void xml_csvn_log( struct strbuf *sb, const struct strbuf *buf, const cha static void csvn_print_log( struct strbuf *sb, const char *relative_path, int revision ) { const char *co_prefix = ctx.repo.checkout_ro_prefix; - const char *repo_path = ctx.repo.name; + const char *name = ctx.repo.name; + const char *repo_root = ctx.repo.repo_root; char *path = NULL; if( !sb ) return; @@ -273,19 +324,27 @@ static void csvn_print_log( struct strbuf *sb, const char *relative_path, int re if( co_prefix ) { - char cmd[1024]; + char repo_path[PATH_MAX] = { 0 }; + char cmd[PATH_MAX]; struct strbuf buf = STRBUF_INIT; pid_t p = (pid_t) -1; int rc; + if( repo_root && *repo_root ) + { + strcat( (char *)&repo_path[0], repo_root ); + strcat( (char *)&repo_path[0], "/" ); + } + strcat( (char *)&repo_path[0], name ); + if( revision ) snprintf( (char *)&cmd[0], 1024, "svn log --revision %d:0 --xml %s/%s%s 2>/dev/null", - revision, co_prefix, repo_path, path ); + revision, co_prefix, (char *)&repo_path[0], path ); else snprintf( (char *)&cmd[0], 1024, "svn log --xml %s/%s%s 2>/dev/null", - co_prefix, repo_path, path ); + co_prefix, (char *)&repo_path[0], path ); p = sys_exec_command( &buf, cmd ); rc = sys_wait_command( p, NULL ); if( rc != 0 ) diff --git a/csvncgi/ui-repolist.c b/csvncgi/ui-repolist.c index 44795c2..728f658 100644 --- a/csvncgi/ui-repolist.c +++ b/csvncgi/ui-repolist.c @@ -132,8 +132,10 @@ void csvn_print_section_stop( struct strbuf *sb ) void csvn_print_repo( struct strbuf *sb, struct repo *repo ) { - struct variable owner = { (unsigned char *)"owner", { 0 }, DT_STRING }, + struct variable repo_root = { (unsigned char *)"repo-root", { 0 }, DT_PATH }, + owner = { (unsigned char *)"owner", { 0 }, DT_STRING }, description = { (unsigned char *)"description", { 0 }, DT_STRING }; + struct variable *rroot = NULL; struct variable *auth = NULL; struct variable *desc = NULL; @@ -144,12 +146,16 @@ void csvn_print_repo( struct strbuf *sb, struct repo *repo ) if( !sb || !repo || !repo->path ) return; - auth = lookup( repo, &owner ); - desc = lookup( repo, &description ); - time = csvn_repo_last_changed_time( repo ); + rroot = lookup( repo, &repo_root ); + auth = lookup( repo, &owner ); + desc = lookup( repo, &description ); + time = csvn_repo_last_changed_time( repo ); strbuf_addf( sb, "
\n" ); - strbuf_addf( sb, " \n", repo->path, repo->path ); + if( rroot ) + strbuf_addf( sb, " \n", (const char *)rroot->_v.vptr, repo->path, repo->path ); + else + strbuf_addf( sb, " \n", repo->path, repo->path ); if( desc ) strbuf_addf( sb, "
%s
\n", (const char *)desc->_v.vptr ); diff --git a/csvncgi/ui-shared.c b/csvncgi/ui-shared.c index e34141e..1079486 100644 --- a/csvncgi/ui-shared.c +++ b/csvncgi/ui-shared.c @@ -406,23 +406,32 @@ static void xml_csvn_info( struct strbuf *sb, struct csvn_info *info ) void csvn_repo_info( struct csvn_info *info, int revision ) { const char *co_prefix = ctx.repo.checkout_ro_prefix; - const char *repo_path = ctx.repo.name; + const char *name = ctx.repo.name; + const char *repo_root = ctx.repo.repo_root; if( co_prefix ) { - char cmd[1024]; + char repo_path[PATH_MAX] = { 0 }; + char cmd[PATH_MAX]; struct strbuf buf = STRBUF_INIT; pid_t p = (pid_t) -1; int rc; + if( repo_root && *repo_root ) + { + strcat( (char *)&repo_path[0], repo_root ); + strcat( (char *)&repo_path[0], "/" ); + } + strcat( (char *)&repo_path[0], name ); + if( revision ) snprintf( (char *)&cmd[0], 1024, "svn info --revision %d --xml %s/%s/ 2>/dev/null", - revision, co_prefix, repo_path ); + revision, co_prefix, (char *)&repo_path[0] ); else snprintf( (char *)&cmd[0], 1024, "svn info --xml %s/%s/ 2>/dev/null", - co_prefix, repo_path ); + co_prefix, (char *)&repo_path[0] ); p = sys_exec_command( &buf, cmd ); rc = sys_wait_command( p, NULL ); if( rc != 0 ) @@ -650,25 +659,34 @@ static const char *mime_info( struct csvn_info *info, const char *buffer, size_t void csvn_rpath_mime_info( struct csvn_info *info, const char *relative_path, int revision ) { const char *co_prefix = ctx.repo.checkout_ro_prefix; - const char *repo_path = ctx.repo.name; + const char *name = ctx.repo.name; + const char *repo_root = ctx.repo.repo_root; if( !info || !relative_path ) return; if( co_prefix ) { - char cmd[1024]; + char repo_path[PATH_MAX] = { 0 }; + char cmd[PATH_MAX]; struct strbuf buf = STRBUF_INIT; pid_t p = (pid_t) -1; int rc; + if( repo_root && *repo_root ) + { + strcat( (char *)&repo_path[0], repo_root ); + strcat( (char *)&repo_path[0], "/" ); + } + strcat( (char *)&repo_path[0], name ); + if( revision ) snprintf( (char *)&cmd[0], 1024, "svn cat --revision %d %s/%s/%s 2>/dev/null | tr -d '\\0' | head -c 1024", - revision, co_prefix, repo_path, relative_path ); + revision, co_prefix, (char *)&repo_path[0], relative_path ); else snprintf( (char *)&cmd[0], 1024, "svn cat %s/%s/%s 2>/dev/null | tr -d '\\0' | head -c 1024", - co_prefix, repo_path, relative_path ); + co_prefix, (char *)&repo_path[0], relative_path ); p = sys_exec_command( &buf, cmd ); rc = sys_wait_command( p, NULL ); if( rc != 0 ) @@ -689,25 +707,34 @@ void csvn_rpath_mime_info( struct csvn_info *info, const char *relative_path, in void csvn_rpath_info( struct csvn_info *info, const char *relative_path, int revision ) { const char *co_prefix = ctx.repo.checkout_ro_prefix; - const char *repo_path = ctx.repo.name; + const char *name = ctx.repo.name; + const char *repo_root = ctx.repo.repo_root; if( !info || !relative_path ) return; if( co_prefix ) { - char cmd[1024]; + char repo_path[PATH_MAX] = { 0 }; + char cmd[PATH_MAX]; struct strbuf buf = STRBUF_INIT; pid_t p = (pid_t) -1; int rc; + if( repo_root && *repo_root ) + { + strcat( (char *)&repo_path[0], repo_root ); + strcat( (char *)&repo_path[0], "/" ); + } + strcat( (char *)&repo_path[0], name ); + if( revision ) snprintf( (char *)&cmd[0], 1024, "svn info --revision %d --xml %s/%s/%s 2>/dev/null", - revision, co_prefix, repo_path, relative_path ); + revision, co_prefix, (char *)&repo_path[0], relative_path ); else snprintf( (char *)&cmd[0], 1024, "svn info --xml %s/%s/%s 2>/dev/null", - co_prefix, repo_path, relative_path ); + co_prefix, (char *)&repo_path[0], relative_path ); p = sys_exec_command( &buf, cmd ); rc = sys_wait_command( p, NULL ); if( rc != 0 ) diff --git a/csvncgi/ui-tree.c b/csvncgi/ui-tree.c index bc46535..007abc2 100644 --- a/csvncgi/ui-tree.c +++ b/csvncgi/ui-tree.c @@ -147,7 +147,8 @@ static struct dlist *tree_lines_sort_bytag( struct dlist *lines ) static const char *is_file_executable( const char *relative_path, const char *name, int revision ) { const char *co_prefix = ctx.repo.checkout_ro_prefix; - const char *repo_path = ctx.repo.name; + const char *repo_name = ctx.repo.name; + const char *repo_root = ctx.repo.repo_root; const char *ret = ""; char *path = NULL; @@ -167,19 +168,27 @@ static const char *is_file_executable( const char *relative_path, const char *na if( co_prefix ) { - char cmd[1024]; + char repo_path[PATH_MAX] = { 0 }; + char cmd[PATH_MAX]; struct strbuf buf = STRBUF_INIT; pid_t p = (pid_t) -1; int rc; + if( repo_root && *repo_root ) + { + strcat( (char *)&repo_path[0], repo_root ); + strcat( (char *)&repo_path[0], "/" ); + } + strcat( (char *)&repo_path[0], repo_name ); + if( revision ) snprintf( (char *)&cmd[0], 1024, "svn propget svn:executable --revision %d %s/%s%s/%s 2>/dev/null", - revision, co_prefix, repo_path, path, name ); + revision, co_prefix, (char *)&repo_path[0], path, name ); else snprintf( (char *)&cmd[0], 1024, "svn propget svn:executable %s/%s%s/%s 2>/dev/null", - co_prefix, repo_path, path, name ); + co_prefix, (char *)&repo_path[0], path, name ); p = sys_exec_command( &buf, cmd ); rc = sys_wait_command( p, NULL ); if( rc != 0 ) @@ -432,9 +441,27 @@ static void dlist_csvn_tree( struct strbuf *sb, const char *relative_path, int r strbuf_addf( sb, "
\n" ); if( ctx.env.query_string && *ctx.env.query_string ) - strbuf_addf( sb, " \n", ctx.repo.name, path, line->name, ctx.env.query_string, line->name ); + { + if( ctx.repo.repo_root && *ctx.repo.repo_root ) + { + strbuf_addf( sb, " \n", ctx.repo.repo_root, ctx.repo.name, path, line->name, ctx.env.query_string, line->name ); + } + else + { + strbuf_addf( sb, " \n", ctx.repo.name, path, line->name, ctx.env.query_string, line->name ); + } + } else - strbuf_addf( sb, " \n", ctx.repo.name, path, line->name, line->name ); + { + if( ctx.repo.repo_root && *ctx.repo.repo_root ) + { + strbuf_addf( sb, " \n", ctx.repo.repo_root, ctx.repo.name, path, line->name, line->name ); + } + else + { + strbuf_addf( sb, " \n", ctx.repo.name, path, line->name, line->name ); + } + } strbuf_addf( sb, "
4096
\n" ); strbuf_addf( sb, "
%s
\n", line->revision ); if( time != -1 ) @@ -451,13 +478,29 @@ static void dlist_csvn_tree( struct strbuf *sb, const char *relative_path, int r strbuf_addf( sb, " \n" ); strbuf_addf( sb, "
\n" ); @@ -492,9 +535,27 @@ static void dlist_csvn_tree( struct strbuf *sb, const char *relative_path, int r strbuf_addf( sb, "
\n" ); if( ctx.env.query_string && *ctx.env.query_string ) - strbuf_addf( sb, " \n", ctx.repo.name, path, line->name, ctx.env.query_string, exec, line->name ); + { + if( ctx.repo.repo_root && *ctx.repo.repo_root ) + { + strbuf_addf( sb, " \n", ctx.repo.repo_root, ctx.repo.name, path, line->name, ctx.env.query_string, exec, line->name ); + } + else + { + strbuf_addf( sb, " \n", ctx.repo.name, path, line->name, ctx.env.query_string, exec, line->name ); + } + } else - strbuf_addf( sb, " \n", ctx.repo.name, path, line->name, exec, line->name ); + { + if( ctx.repo.repo_root && *ctx.repo.repo_root ) + { + strbuf_addf( sb, " \n", ctx.repo.repo_root, ctx.repo.name, path, line->name, exec, line->name ); + } + else + { + strbuf_addf( sb, " \n", ctx.repo.name, path, line->name, exec, line->name ); + } + } strbuf_addf( sb, "
%s
\n", line->size ); strbuf_addf( sb, "
%s
\n", line->revision ); if( time != -1 ) @@ -511,15 +572,33 @@ static void dlist_csvn_tree( struct strbuf *sb, const char *relative_path, int r strbuf_addf( sb, " \n" ); strbuf_addf( sb, "
\n" ); @@ -539,7 +618,8 @@ static void dlist_csvn_tree( struct strbuf *sb, const char *relative_path, int r static void csvn_print_tree( struct strbuf *sb, const char *relative_path, int revision ) { const char *co_prefix = ctx.repo.checkout_ro_prefix; - const char *repo_path = ctx.repo.name; + const char *name = ctx.repo.name; + const char *repo_root = ctx.repo.repo_root; char *path = NULL; if( !sb ) return; @@ -558,19 +638,27 @@ static void csvn_print_tree( struct strbuf *sb, const char *relative_path, int r if( co_prefix ) { - char cmd[1024]; + char repo_path[PATH_MAX] = { 0 }; + char cmd[PATH_MAX]; struct strbuf buf = STRBUF_INIT; pid_t p = (pid_t) -1; int rc; + if( repo_root && *repo_root ) + { + strcat( (char *)&repo_path[0], repo_root ); + strcat( (char *)&repo_path[0], "/" ); + } + strcat( (char *)&repo_path[0], name ); + if( revision ) snprintf( (char *)&cmd[0], 1024, "svn list --revision %d --xml %s/%s%s 2>/dev/null", - revision, co_prefix, repo_path, path ); + revision, co_prefix, (char *)&repo_path[0], path ); else snprintf( (char *)&cmd[0], 1024, "svn list --xml %s/%s%s 2>/dev/null", - co_prefix, repo_path, path ); + co_prefix, (char *)&repo_path[0], path ); p = sys_exec_command( &buf, cmd ); rc = sys_wait_command( p, NULL ); if( rc != 0 ) @@ -615,9 +703,27 @@ static void csvn_print_checkout_urls( struct strbuf *sb, const char *relative_pa strbuf_addf( sb, "
ro:
\n" ); if( revision ) - strbuf_addf( sb, "
svn checkout --revision %d %s/%s%s
\n", revision, ctx.repo.checkout_ro_prefix, ctx.repo.name, path ); + { + if( ctx.repo.repo_root && *ctx.repo.repo_root ) + { + strbuf_addf( sb, "
svn checkout --revision %d %s/%s/%s%s
\n", revision, ctx.repo.checkout_ro_prefix, ctx.repo.repo_root, ctx.repo.name, path ); + } + else + { + strbuf_addf( sb, "
svn checkout --revision %d %s/%s%s
\n", revision, ctx.repo.checkout_ro_prefix, ctx.repo.name, path ); + } + } else - strbuf_addf( sb, "
svn checkout %s/%s%s
\n", ctx.repo.checkout_ro_prefix, ctx.repo.name, path ); + { + if( ctx.repo.repo_root && *ctx.repo.repo_root ) + { + strbuf_addf( sb, "
svn checkout %s/%s/%s%s
\n", ctx.repo.checkout_ro_prefix, ctx.repo.repo_root, ctx.repo.name, path ); + } + else + { + strbuf_addf( sb, "
svn checkout %s/%s%s
\n", ctx.repo.checkout_ro_prefix, ctx.repo.name, path ); + } + } strbuf_addf( sb, "
\n" ); if( ctx.repo.checkout_prefix && *ctx.repo.checkout_prefix ) @@ -626,9 +732,27 @@ static void csvn_print_checkout_urls( struct strbuf *sb, const char *relative_pa strbuf_addf( sb, "
rw:
\n" ); if( revision ) - strbuf_addf( sb, "
svn checkout --revision %d %s/%s%s
\n", revision, ctx.repo.checkout_prefix, ctx.repo.name, path ); + { + if( ctx.repo.repo_root && *ctx.repo.repo_root ) + { + strbuf_addf( sb, "
svn checkout --revision %d %s/%s/%s%s
\n", revision, ctx.repo.checkout_prefix, ctx.repo.repo_root, ctx.repo.name, path ); + } + else + { + strbuf_addf( sb, "
svn checkout --revision %d %s/%s%s
\n", revision, ctx.repo.checkout_prefix, ctx.repo.name, path ); + } + } else - strbuf_addf( sb, "
svn checkout %s/%s%s
\n", ctx.repo.checkout_prefix, ctx.repo.name, path ); + { + if( ctx.repo.repo_root && *ctx.repo.repo_root ) + { + strbuf_addf( sb, "
svn checkout %s/%s/%s%s
\n", ctx.repo.checkout_prefix, ctx.repo.repo_root, ctx.repo.name, path ); + } + else + { + strbuf_addf( sb, "
svn checkout %s/%s%s
\n", ctx.repo.checkout_prefix, ctx.repo.name, path ); + } + } strbuf_addf( sb, " \n" ); } -- cgit v1.2.3