cSvn-UI for SVN Repositories

cGit-UI – is a web interface for Subversion (SVN) Repositories. cSvn CGI script is writen in C and therefore it's fast enough

6 Commits   0 Branches   2 Tags
bfc1508d (kx 2023-03-24 03:55:33 +0300   1) 
bfc1508d (kx 2023-03-24 03:55:33 +0300   2) #ifdef HAVE_CONFIG_H
bfc1508d (kx 2023-03-24 03:55:33 +0300   3) #include <config.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300   4) #endif
bfc1508d (kx 2023-03-24 03:55:33 +0300   5) 
bfc1508d (kx 2023-03-24 03:55:33 +0300   6) #include <stdlib.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300   7) #include <stdio.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300   8) #include <sys/sysinfo.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300   9) #include <sys/types.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  10) #ifdef HAVE_INTTYPES_H
bfc1508d (kx 2023-03-24 03:55:33 +0300  11) #include <inttypes.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  12) #else
bfc1508d (kx 2023-03-24 03:55:33 +0300  13) #include <stdint.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  14) #endif
bfc1508d (kx 2023-03-24 03:55:33 +0300  15) #include <stddef.h>   /* offsetof(3) */
bfc1508d (kx 2023-03-24 03:55:33 +0300  16) #include <dirent.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  17) #include <sys/stat.h> /* chmod(2)    */
bfc1508d (kx 2023-03-24 03:55:33 +0300  18) #include <sys/file.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  19) #include <sys/mman.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  20) #include <fcntl.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  21) #include <limits.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  22) #include <string.h>   /* strdup(3)   */
bfc1508d (kx 2023-03-24 03:55:33 +0300  23) #include <libgen.h>   /* basename(3) */
bfc1508d (kx 2023-03-24 03:55:33 +0300  24) #include <ctype.h>    /* tolower(3)  */
bfc1508d (kx 2023-03-24 03:55:33 +0300  25) #include <errno.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  26) #include <time.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  27) #include <sys/time.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  28) #include <pwd.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  29) #include <grp.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  30) #include <stdarg.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  31) #include <locale.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  32) #include <unistd.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  33) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  34) #include <libxml/parser.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  35) #include <libxml/tree.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  36) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  37) #include <nls.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  38) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  39) #include <defs.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  40) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  41) #include <fatal.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  42) #include <http.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  43) #include <html.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  44) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  45) #include <dlist.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  46) #include <strbuf.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  47) #include <repolist.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  48) #include <wrapper.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  49) #include <system.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  50) #include <date.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  51) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  52) #include <ctx.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  53) #include <ui-shared.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  54) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  55) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  56) static void xml_csvn_log( struct strbuf *sb, const struct strbuf *buf, const char *relative_path )
bfc1508d (kx 2023-03-24 03:55:33 +0300  57) {
bfc1508d (kx 2023-03-24 03:55:33 +0300  58)   xmlDocPtr doc = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300  59)   xmlNode *root = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300  60)   char    *path = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300  61) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  62)   int count = 0, printed = 0, reminder = 0, page_size = 200;
bfc1508d (kx 2023-03-24 03:55:33 +0300  63) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  64)   if( !sb || !sb->len || !buf || !buf->buf ) return;
bfc1508d (kx 2023-03-24 03:55:33 +0300  65)   if( relative_path && *relative_path )
bfc1508d (kx 2023-03-24 03:55:33 +0300  66)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300  67)     path = (char *)xmalloc( strlen( relative_path ) + 2 );
bfc1508d (kx 2023-03-24 03:55:33 +0300  68)     path[0] = '/';
bfc1508d (kx 2023-03-24 03:55:33 +0300  69)     sprintf( (char *)&path[1], relative_path );
bfc1508d (kx 2023-03-24 03:55:33 +0300  70)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300  71)   else
bfc1508d (kx 2023-03-24 03:55:33 +0300  72)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300  73)     path = (char *)xmalloc( 1 );
bfc1508d (kx 2023-03-24 03:55:33 +0300  74)     path[0] = '\0';
bfc1508d (kx 2023-03-24 03:55:33 +0300  75)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300  76) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  77)   page_size = atoi( ctx.vars.page_size );
bfc1508d (kx 2023-03-24 03:55:33 +0300  78) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  79)   LIBXML_TEST_VERSION
bfc1508d (kx 2023-03-24 03:55:33 +0300  80) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  81)   doc = xmlReadMemory( buf->buf, buf->len, "log.xml", NULL, 0 );
bfc1508d (kx 2023-03-24 03:55:33 +0300  82)   if( !doc )
bfc1508d (kx 2023-03-24 03:55:33 +0300  83)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300  84)     html_fatal( "cannot parse svn log.xml" );
bfc1508d (kx 2023-03-24 03:55:33 +0300  85)     return;
bfc1508d (kx 2023-03-24 03:55:33 +0300  86)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300  87) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  88)   root = xmlDocGetRootElement( doc );
bfc1508d (kx 2023-03-24 03:55:33 +0300  89)   if( !root )
bfc1508d (kx 2023-03-24 03:55:33 +0300  90)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300  91)     free( path );
bfc1508d (kx 2023-03-24 03:55:33 +0300  92)     xmlFreeDoc( doc );
bfc1508d (kx 2023-03-24 03:55:33 +0300  93)     xmlCleanupParser();
bfc1508d (kx 2023-03-24 03:55:33 +0300  94)     return;
bfc1508d (kx 2023-03-24 03:55:33 +0300  95)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300  96) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  97)   if( !strcmp( "log", (char *)root->name ) )
bfc1508d (kx 2023-03-24 03:55:33 +0300  98)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300  99)     xmlNode *node = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 100) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 101)     strbuf_addstr( sb, "\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 102)     strbuf_addf( sb, "              <div class=\"repo-log-header\">\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 103)     strbuf_addf( sb, "                <div class=\"row\">\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 104)     strbuf_addf( sb, "                  <div class=\"col-date\"><div class=\"log-date\">Date</div></div>\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 105)     strbuf_addf( sb, "                  <div class=\"col-cmsg\"><div class=\"log-cmsg trunc\">Commit Message</div></div>\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 106)     strbuf_addf( sb, "                  <div class=\"col-rev\"><div class=\"log-rev trunc\">Rev</div></div>\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 107)     strbuf_addf( sb, "                  <div class=\"col-author\"><div class=\"log-author trunc\">Author</div></div>\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 108)     strbuf_addf( sb, "                </div>\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 109)     strbuf_addf( sb, "              </div>\n\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 110) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 111)     strbuf_addf( sb, "              <div class=\"log\">\n\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 112) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 113)     /**************************
bfc1508d (kx 2023-03-24 03:55:33 +0300 114)       Print directories first:
bfc1508d (kx 2023-03-24 03:55:33 +0300 115)      */
bfc1508d (kx 2023-03-24 03:55:33 +0300 116)     for( node = root->children; node; node = node->next )
bfc1508d (kx 2023-03-24 03:55:33 +0300 117)     {
bfc1508d (kx 2023-03-24 03:55:33 +0300 118)       if( node->type == XML_ELEMENT_NODE && !strcmp( "logentry", (char *)node->name ) )
bfc1508d (kx 2023-03-24 03:55:33 +0300 119)       {
bfc1508d (kx 2023-03-24 03:55:33 +0300 120)         xmlNode *param = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 121)         xmlChar *date = NULL, *cmsg = NULL, *revision = NULL, *author = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 122) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 123)         revision = xmlGetProp( node, (const unsigned char *)"revision" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 124) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 125)         for( param = node->children; param; param= param->next )
bfc1508d (kx 2023-03-24 03:55:33 +0300 126)         {
bfc1508d (kx 2023-03-24 03:55:33 +0300 127)           if( param->type == XML_ELEMENT_NODE && !strcmp( "date", (char *)param->name ) )
bfc1508d (kx 2023-03-24 03:55:33 +0300 128)           {
bfc1508d (kx 2023-03-24 03:55:33 +0300 129)             date = xmlNodeGetContent( param );
bfc1508d (kx 2023-03-24 03:55:33 +0300 130)           }
bfc1508d (kx 2023-03-24 03:55:33 +0300 131)           if( param->type == XML_ELEMENT_NODE && !strcmp( "msg", (char *)param->name ) )
bfc1508d (kx 2023-03-24 03:55:33 +0300 132)           {
bfc1508d (kx 2023-03-24 03:55:33 +0300 133)             cmsg = xmlNodeGetContent( param );
bfc1508d (kx 2023-03-24 03:55:33 +0300 134)           }
bfc1508d (kx 2023-03-24 03:55:33 +0300 135)           if( param->type == XML_ELEMENT_NODE && !strcmp( "author", (char *)param->name ) )
bfc1508d (kx 2023-03-24 03:55:33 +0300 136)           {
bfc1508d (kx 2023-03-24 03:55:33 +0300 137)             author = xmlNodeGetContent( param );
bfc1508d (kx 2023-03-24 03:55:33 +0300 138)           }
bfc1508d (kx 2023-03-24 03:55:33 +0300 139) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 140)         } /* End for entry parameters */
bfc1508d (kx 2023-03-24 03:55:33 +0300 141) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 142)         if( date && cmsg && revision && author )
bfc1508d (kx 2023-03-24 03:55:33 +0300 143)         {
bfc1508d (kx 2023-03-24 03:55:33 +0300 144)           struct tm   tm;
bfc1508d (kx 2023-03-24 03:55:33 +0300 145)           time_t      time = -1;
bfc1508d (kx 2023-03-24 03:55:33 +0300 146)           const char *query_string = ctx_remove_query_param( ctx.env.query_string, "rev" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 147) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 148)           query_string = ctx_remove_query_param( query_string, "op" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 149) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 150)           time = parse_date( &tm, (const char *)date );
bfc1508d (kx 2023-03-24 03:55:33 +0300 151) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 152)           ++count;
bfc1508d (kx 2023-03-24 03:55:33 +0300 153)           if( count > ctx.query.ofs && printed < page_size )
bfc1508d (kx 2023-03-24 03:55:33 +0300 154)           {
bfc1508d (kx 2023-03-24 03:55:33 +0300 155) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 156)             strbuf_addf( sb, "                <div class=\"row\">\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 157)             if( time != -1 )
bfc1508d (kx 2023-03-24 03:55:33 +0300 158)             {
bfc1508d (kx 2023-03-24 03:55:33 +0300 159)               strbuf_addf( sb, "                  <div class=\"col-date\"><div onclick=\"trunc(this)\" class=\"log-date trunc\">" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 160)               csvn_print_age( sb, time, 0, 0 );
bfc1508d (kx 2023-03-24 03:55:33 +0300 161)               strbuf_addf( sb, "</div></div>\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 162)             }
bfc1508d (kx 2023-03-24 03:55:33 +0300 163)             else
bfc1508d (kx 2023-03-24 03:55:33 +0300 164)             {
bfc1508d (kx 2023-03-24 03:55:33 +0300 165)               strbuf_addf( sb, "                  <div class=\"col-date\"><div onclick=\"trunc(this)\" class=\"log-date trunc\">unknown</div></div>\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 166)             }
bfc1508d (kx 2023-03-24 03:55:33 +0300 167)             strbuf_addf( sb, "                  <div class=\"col-cmsg\"><div onclick=\"trunc(this)\" class=\"log-cmsg trunc\">%s</div></div>\n", (char *)cmsg );
bfc1508d (kx 2023-03-24 03:55:33 +0300 168)             if( query_string && *query_string )
bfc1508d (kx 2023-03-24 03:55:33 +0300 169)             {
c7693c71 (kx 2023-04-12 19:21:06 +0300 170)               if( ctx.repo.repo_root && *ctx.repo.repo_root )
c7693c71 (kx 2023-04-12 19:21:06 +0300 171)               {
c7693c71 (kx 2023-04-12 19:21:06 +0300 172)                 strbuf_addf( sb, "                  <div class=\"col-rev\"><div onclick=\"trunc(this)\" class=\"log-rev trunc\"><a title=\"Compare with Previous\" href=\"/%s/%s%s/?op=diff&rev=%s&%s\">%s</a></div></div>\n", ctx.repo.repo_root, ctx.repo.name, path, (char *)revision, query_string, (char *)revision );
c7693c71 (kx 2023-04-12 19:21:06 +0300 173)               }
c7693c71 (kx 2023-04-12 19:21:06 +0300 174)               else
c7693c71 (kx 2023-04-12 19:21:06 +0300 175)               {
c7693c71 (kx 2023-04-12 19:21:06 +0300 176)                 strbuf_addf( sb, "                  <div class=\"col-rev\"><div onclick=\"trunc(this)\" class=\"log-rev trunc\"><a title=\"Compare with Previous\" href=\"/%s%s/?op=diff&rev=%s&%s\">%s</a></div></div>\n", ctx.repo.name, path, (char *)revision, query_string, (char *)revision );
c7693c71 (kx 2023-04-12 19:21:06 +0300 177)               }
bfc1508d (kx 2023-03-24 03:55:33 +0300 178)             }
bfc1508d (kx 2023-03-24 03:55:33 +0300 179)             else
bfc1508d (kx 2023-03-24 03:55:33 +0300 180)             {
c7693c71 (kx 2023-04-12 19:21:06 +0300 181)               if( ctx.repo.repo_root && *ctx.repo.repo_root )
c7693c71 (kx 2023-04-12 19:21:06 +0300 182)               {
c7693c71 (kx 2023-04-12 19:21:06 +0300 183)                 strbuf_addf( sb, "                  <div class=\"col-rev\"><div onclick=\"trunc(this)\" class=\"log-rev trunc\"><a title=\"Compare with Previous\" href=\"/%s/%s%s/?op=diff&rev=%s\">%s</a></div></div>\n", ctx.repo.repo_root, path, ctx.repo.name, path, (char *)revision, (char *)revision );
c7693c71 (kx 2023-04-12 19:21:06 +0300 184)               }
c7693c71 (kx 2023-04-12 19:21:06 +0300 185)               else
c7693c71 (kx 2023-04-12 19:21:06 +0300 186)               {
c7693c71 (kx 2023-04-12 19:21:06 +0300 187)                 strbuf_addf( sb, "                  <div class=\"col-rev\"><div onclick=\"trunc(this)\" class=\"log-rev trunc\"><a title=\"Compare with Previous\" href=\"/%s%s/?op=diff&rev=%s\">%s</a></div></div>\n", ctx.repo.name, path, (char *)revision, (char *)revision );
c7693c71 (kx 2023-04-12 19:21:06 +0300 188)               }
bfc1508d (kx 2023-03-24 03:55:33 +0300 189)             }
bfc1508d (kx 2023-03-24 03:55:33 +0300 190)             strbuf_addf( sb, "                  <div class=\"col-author\"><div onclick=\"trunc(this)\" class=\"log-author trunc\">%s</div></div>\n", (char *)author );
bfc1508d (kx 2023-03-24 03:55:33 +0300 191)             strbuf_addf( sb, "                </div>\n\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 192) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 193)             ++printed;
bfc1508d (kx 2023-03-24 03:55:33 +0300 194)           }
bfc1508d (kx 2023-03-24 03:55:33 +0300 195) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 196)           xmlFree( date );
bfc1508d (kx 2023-03-24 03:55:33 +0300 197)           xmlFree( cmsg );
bfc1508d (kx 2023-03-24 03:55:33 +0300 198)           xmlFree( revision );
bfc1508d (kx 2023-03-24 03:55:33 +0300 199)           xmlFree( author );
bfc1508d (kx 2023-03-24 03:55:33 +0300 200)         }
bfc1508d (kx 2023-03-24 03:55:33 +0300 201)         else
bfc1508d (kx 2023-03-24 03:55:33 +0300 202)         {
bfc1508d (kx 2023-03-24 03:55:33 +0300 203)           if( date )     xmlFree( date );
bfc1508d (kx 2023-03-24 03:55:33 +0300 204)           if( cmsg )     xmlFree( cmsg );
bfc1508d (kx 2023-03-24 03:55:33 +0300 205)           if( revision ) xmlFree( revision );
bfc1508d (kx 2023-03-24 03:55:33 +0300 206)           if( author )   xmlFree( author );
bfc1508d (kx 2023-03-24 03:55:33 +0300 207)         }
bfc1508d (kx 2023-03-24 03:55:33 +0300 208)       }
bfc1508d (kx 2023-03-24 03:55:33 +0300 209)     }
bfc1508d (kx 2023-03-24 03:55:33 +0300 210) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 211)     strbuf_addf( sb, "              </div> <!-- End of Log -->\n\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 212) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 213)     /********************************
bfc1508d (kx 2023-03-24 03:55:33 +0300 214)       Print log direction:
bfc1508d (kx 2023-03-24 03:55:33 +0300 215)      */
bfc1508d (kx 2023-03-24 03:55:33 +0300 216)     reminder = count - ctx.query.ofs - printed;
bfc1508d (kx 2023-03-24 03:55:33 +0300 217)     if( page_size < count )
bfc1508d (kx 2023-03-24 03:55:33 +0300 218)     {
bfc1508d (kx 2023-03-24 03:55:33 +0300 219)       int prev, next;
bfc1508d (kx 2023-03-24 03:55:33 +0300 220) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 221)       strbuf_addf( sb, "              <div class=\"log-direction\">\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 222)       strbuf_addf( sb, "                <div class=\"row\">\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 223)       strbuf_addf( sb, "                  <div class=\"left col-prev\">\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 224)       strbuf_addf( sb, "                    <div class=\"prev-log-direction\">\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 225) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 226)       if( ctx.query.ofs )
bfc1508d (kx 2023-03-24 03:55:33 +0300 227)       {
bfc1508d (kx 2023-03-24 03:55:33 +0300 228)         prev = ctx.query.ofs - page_size;
bfc1508d (kx 2023-03-24 03:55:33 +0300 229)         if( prev < 0 ) prev = 0;
bfc1508d (kx 2023-03-24 03:55:33 +0300 230) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 231)         if( ctx.env.query_string && *ctx.env.query_string )
c7693c71 (kx 2023-04-12 19:21:06 +0300 232)         {
c7693c71 (kx 2023-04-12 19:21:06 +0300 233)           if( ctx.repo.repo_root && *ctx.repo.repo_root )
c7693c71 (kx 2023-04-12 19:21:06 +0300 234)           {
c7693c71 (kx 2023-04-12 19:21:06 +0300 235)             strbuf_addf( sb, "                      <a href=\"/%s/%s%s/?ofs=%d&%s\">&#x226a;&nbsp; Prev</a>\n", ctx.repo.repo_root, ctx.repo.name, path, prev, ctx.env.query_string );
c7693c71 (kx 2023-04-12 19:21:06 +0300 236)           }
c7693c71 (kx 2023-04-12 19:21:06 +0300 237)           else
c7693c71 (kx 2023-04-12 19:21:06 +0300 238)           {
c7693c71 (kx 2023-04-12 19:21:06 +0300 239)             strbuf_addf( sb, "                      <a href=\"/%s%s/?ofs=%d&%s\">&#x226a;&nbsp; Prev</a>\n", ctx.repo.name, path, prev, ctx.env.query_string );
c7693c71 (kx 2023-04-12 19:21:06 +0300 240)           }
c7693c71 (kx 2023-04-12 19:21:06 +0300 241)         }
bfc1508d (kx 2023-03-24 03:55:33 +0300 242)         else
c7693c71 (kx 2023-04-12 19:21:06 +0300 243)         {
c7693c71 (kx 2023-04-12 19:21:06 +0300 244)           if( ctx.repo.repo_root && *ctx.repo.repo_root )
c7693c71 (kx 2023-04-12 19:21:06 +0300 245)           {
c7693c71 (kx 2023-04-12 19:21:06 +0300 246)             strbuf_addf( sb, "                      <a href=\"/%s/%s%s/?ofs=%d\">&#x226a;&nbsp; Prev</a>\n", ctx.repo.repo_root, ctx.repo.name, path, prev );
c7693c71 (kx 2023-04-12 19:21:06 +0300 247)           }
c7693c71 (kx 2023-04-12 19:21:06 +0300 248)           else
c7693c71 (kx 2023-04-12 19:21:06 +0300 249)           {
c7693c71 (kx 2023-04-12 19:21:06 +0300 250)             strbuf_addf( sb, "                      <a href=\"/%s%s/?ofs=%d\">&#x226a;&nbsp; Prev</a>\n", ctx.repo.name, path, prev );
c7693c71 (kx 2023-04-12 19:21:06 +0300 251)           }
c7693c71 (kx 2023-04-12 19:21:06 +0300 252)         }
bfc1508d (kx 2023-03-24 03:55:33 +0300 253)       }
bfc1508d (kx 2023-03-24 03:55:33 +0300 254) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 255)       strbuf_addf( sb, "                    </div>\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 256)       strbuf_addf( sb, "                  </div>\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 257)       strbuf_addf( sb, "                  <div class=\"right col-next\">\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 258)       strbuf_addf( sb, "                    <div class=\"next-log-direction\">\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 259) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 260)       if( reminder )
bfc1508d (kx 2023-03-24 03:55:33 +0300 261)       {
bfc1508d (kx 2023-03-24 03:55:33 +0300 262)         next = ctx.query.ofs + page_size;
bfc1508d (kx 2023-03-24 03:55:33 +0300 263) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 264)         if( ctx.env.query_string && *ctx.env.query_string )
c7693c71 (kx 2023-04-12 19:21:06 +0300 265)         {
c7693c71 (kx 2023-04-12 19:21:06 +0300 266)           if( ctx.repo.repo_root && *ctx.repo.repo_root )
c7693c71 (kx 2023-04-12 19:21:06 +0300 267)           {
c7693c71 (kx 2023-04-12 19:21:06 +0300 268)             strbuf_addf( sb, "                      <a href=\"/%s/%s%s/?ofs=%d&%s\">Next &nbsp;&#x226b;</a>\n", ctx.repo.repo_root, ctx.repo.name, path, next, ctx.env.query_string );
c7693c71 (kx 2023-04-12 19:21:06 +0300 269)           }
c7693c71 (kx 2023-04-12 19:21:06 +0300 270)           else
c7693c71 (kx 2023-04-12 19:21:06 +0300 271)           {
c7693c71 (kx 2023-04-12 19:21:06 +0300 272)             strbuf_addf( sb, "                      <a href=\"/%s%s/?ofs=%d&%s\">Next &nbsp;&#x226b;</a>\n", ctx.repo.name, path, next, ctx.env.query_string );
c7693c71 (kx 2023-04-12 19:21:06 +0300 273)           }
c7693c71 (kx 2023-04-12 19:21:06 +0300 274)         }
bfc1508d (kx 2023-03-24 03:55:33 +0300 275)         else
c7693c71 (kx 2023-04-12 19:21:06 +0300 276)         {
c7693c71 (kx 2023-04-12 19:21:06 +0300 277)           if( ctx.repo.repo_root && *ctx.repo.repo_root )
c7693c71 (kx 2023-04-12 19:21:06 +0300 278)           {
c7693c71 (kx 2023-04-12 19:21:06 +0300 279)             strbuf_addf( sb, "                      <a href=\"/%s/%s%s/?ofs=%d\">Next &nbsp;&#x226b;</a>\n", ctx.repo.repo_root, ctx.repo.name, path, next );
c7693c71 (kx 2023-04-12 19:21:06 +0300 280)           }
c7693c71 (kx 2023-04-12 19:21:06 +0300 281)           else
c7693c71 (kx 2023-04-12 19:21:06 +0300 282)           {
c7693c71 (kx 2023-04-12 19:21:06 +0300 283)             strbuf_addf( sb, "                      <a href=\"/%s%s/?ofs=%d\">Next &nbsp;&#x226b;</a>\n", ctx.repo.name, path, next );
c7693c71 (kx 2023-04-12 19:21:06 +0300 284)           }
c7693c71 (kx 2023-04-12 19:21:06 +0300 285)         }
bfc1508d (kx 2023-03-24 03:55:33 +0300 286)       }
bfc1508d (kx 2023-03-24 03:55:33 +0300 287) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 288)       strbuf_addf( sb, "                    </div>\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 289)       strbuf_addf( sb, "                  </div>\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 290)       strbuf_addf( sb, "                </div>\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 291)       strbuf_addf( sb, "              </div>\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 292)     }
bfc1508d (kx 2023-03-24 03:55:33 +0300 293)     /*
bfc1508d (kx 2023-03-24 03:55:33 +0300 294)       End of printing log direction.
bfc1508d (kx 2023-03-24 03:55:33 +0300 295)      ********************************/
bfc1508d (kx 2023-03-24 03:55:33 +0300 296) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 297)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 298) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 299)   free( path );
bfc1508d (kx 2023-03-24 03:55:33 +0300 300)   xmlFreeDoc(doc);
bfc1508d (kx 2023-03-24 03:55:33 +0300 301)   xmlCleanupParser();
bfc1508d (kx 2023-03-24 03:55:33 +0300 302) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 303) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 304) static void csvn_print_log( struct strbuf *sb, const char *relative_path, int revision )
bfc1508d (kx 2023-03-24 03:55:33 +0300 305) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 306)   const char *co_prefix = ctx.repo.checkout_ro_prefix;
c7693c71 (kx 2023-04-12 19:21:06 +0300 307)   const char *name      = ctx.repo.name;
c7693c71 (kx 2023-04-12 19:21:06 +0300 308)   const char *repo_root = ctx.repo.repo_root;
bfc1508d (kx 2023-03-24 03:55:33 +0300 309)   char *path = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 310) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 311)   if( !sb ) return;
bfc1508d (kx 2023-03-24 03:55:33 +0300 312) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 313)   if( relative_path && *relative_path )
bfc1508d (kx 2023-03-24 03:55:33 +0300 314)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 315)     path = (char *)xmalloc( strlen( relative_path ) + 2 );
bfc1508d (kx 2023-03-24 03:55:33 +0300 316)     path[0] = '/';
bfc1508d (kx 2023-03-24 03:55:33 +0300 317)     sprintf( (char *)&path[1], relative_path );
bfc1508d (kx 2023-03-24 03:55:33 +0300 318)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 319)   else
bfc1508d (kx 2023-03-24 03:55:33 +0300 320)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 321)     path = (char *)xmalloc( 1 );
bfc1508d (kx 2023-03-24 03:55:33 +0300 322)     path[0] = '\0';
bfc1508d (kx 2023-03-24 03:55:33 +0300 323)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 324) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 325)   if( co_prefix )
bfc1508d (kx 2023-03-24 03:55:33 +0300 326)   {
c7693c71 (kx 2023-04-12 19:21:06 +0300 327)     char repo_path[PATH_MAX] = { 0 };
c7693c71 (kx 2023-04-12 19:21:06 +0300 328)     char cmd[PATH_MAX];
bfc1508d (kx 2023-03-24 03:55:33 +0300 329)     struct strbuf buf = STRBUF_INIT;
bfc1508d (kx 2023-03-24 03:55:33 +0300 330)     pid_t p = (pid_t) -1;
bfc1508d (kx 2023-03-24 03:55:33 +0300 331)     int   rc;
bfc1508d (kx 2023-03-24 03:55:33 +0300 332) 
c7693c71 (kx 2023-04-12 19:21:06 +0300 333)     if( repo_root && *repo_root )
c7693c71 (kx 2023-04-12 19:21:06 +0300 334)     {
c7693c71 (kx 2023-04-12 19:21:06 +0300 335)       strcat( (char *)&repo_path[0], repo_root );
c7693c71 (kx 2023-04-12 19:21:06 +0300 336)       strcat( (char *)&repo_path[0], "/" );
c7693c71 (kx 2023-04-12 19:21:06 +0300 337)     }
c7693c71 (kx 2023-04-12 19:21:06 +0300 338)     strcat( (char *)&repo_path[0], name );
c7693c71 (kx 2023-04-12 19:21:06 +0300 339) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 340)     if( revision )
bfc1508d (kx 2023-03-24 03:55:33 +0300 341)       snprintf( (char *)&cmd[0], 1024,
bfc1508d (kx 2023-03-24 03:55:33 +0300 342)                 "svn log --revision %d:0 --xml %s/%s%s 2>/dev/null",
c7693c71 (kx 2023-04-12 19:21:06 +0300 343)                 revision, co_prefix, (char *)&repo_path[0], path );
bfc1508d (kx 2023-03-24 03:55:33 +0300 344)     else
bfc1508d (kx 2023-03-24 03:55:33 +0300 345)       snprintf( (char *)&cmd[0], 1024,
bfc1508d (kx 2023-03-24 03:55:33 +0300 346)                 "svn log --xml %s/%s%s 2>/dev/null",
c7693c71 (kx 2023-04-12 19:21:06 +0300 347)                 co_prefix, (char *)&repo_path[0], path );
bfc1508d (kx 2023-03-24 03:55:33 +0300 348)     p = sys_exec_command( &buf, cmd );
bfc1508d (kx 2023-03-24 03:55:33 +0300 349)     rc = sys_wait_command( p, NULL );
bfc1508d (kx 2023-03-24 03:55:33 +0300 350)     if( rc != 0 )
bfc1508d (kx 2023-03-24 03:55:33 +0300 351)     {
bfc1508d (kx 2023-03-24 03:55:33 +0300 352)       strbuf_release( &buf );
bfc1508d (kx 2023-03-24 03:55:33 +0300 353)       free( path );
bfc1508d (kx 2023-03-24 03:55:33 +0300 354)       return;
bfc1508d (kx 2023-03-24 03:55:33 +0300 355)     }
bfc1508d (kx 2023-03-24 03:55:33 +0300 356) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 357)     xml_csvn_log( sb, (const struct strbuf *)&buf, relative_path );
bfc1508d (kx 2023-03-24 03:55:33 +0300 358) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 359)     strbuf_release( &buf );
bfc1508d (kx 2023-03-24 03:55:33 +0300 360)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 361) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 362)   free( path );
bfc1508d (kx 2023-03-24 03:55:33 +0300 363)   return;
bfc1508d (kx 2023-03-24 03:55:33 +0300 364) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 365) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 366) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 367) void csvn_print_log_page( void )
bfc1508d (kx 2023-03-24 03:55:33 +0300 368) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 369)   FILE  *fp;
bfc1508d (kx 2023-03-24 03:55:33 +0300 370)   struct strbuf buf = STRBUF_INIT;
bfc1508d (kx 2023-03-24 03:55:33 +0300 371) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 372)   fp = xfopen( ctx.page.header, "r" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 373)   (void)strbuf_env_fread( &buf, fp );
bfc1508d (kx 2023-03-24 03:55:33 +0300 374)   fclose( fp );
bfc1508d (kx 2023-03-24 03:55:33 +0300 375) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 376)   strbuf_addf( &buf, "        <div class=\"content segment\">\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 377)   strbuf_addf( &buf, "          <div class=\"container\">\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 378)   strbuf_addf( &buf, "            <div class=\"csvn-main-content\">\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 379) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 380)   if( ctx.repo.name )
bfc1508d (kx 2023-03-24 03:55:33 +0300 381)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 382)     csvn_print_log( &buf, ctx.repo.relative_path, ctx.query.rev );
bfc1508d (kx 2023-03-24 03:55:33 +0300 383)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 384)   else
bfc1508d (kx 2023-03-24 03:55:33 +0300 385)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 386)     strbuf_addf( &buf, "              <h1>Requested resource cannot be shown</h1>\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 387)     strbuf_addf( &buf, "              <p class='leading'>Repository '%s' not found.</p>\n", ctx.repo.name );
bfc1508d (kx 2023-03-24 03:55:33 +0300 388)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 389) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 390)   strbuf_addf( &buf, "            </div> <!-- End of csvn-main-content -->\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 391)   strbuf_addf( &buf, "          </div> <!-- End of container -->\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 392)   strbuf_addf( &buf, "        </div> <!-- End of content segment -->\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 393) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 394)   fp = xfopen( ctx.page.footer, "r" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 395)   (void)strbuf_env_fread( &buf, fp );
bfc1508d (kx 2023-03-24 03:55:33 +0300 396)   fclose( fp );
bfc1508d (kx 2023-03-24 03:55:33 +0300 397) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 398)   ctx.page.size = buf.len;
bfc1508d (kx 2023-03-24 03:55:33 +0300 399)   csvn_print_http_headers();
bfc1508d (kx 2023-03-24 03:55:33 +0300 400)   strbuf_write( &buf, STDOUT_FILENO );
bfc1508d (kx 2023-03-24 03:55:33 +0300 401)   strbuf_release( &buf );
bfc1508d (kx 2023-03-24 03:55:33 +0300 402) }