05d292b2 (kx 2023-03-24 03:51:10 +0300 1)
05d292b2 (kx 2023-03-24 03:51:10 +0300 2) #ifdef HAVE_CONFIG_H
05d292b2 (kx 2023-03-24 03:51:10 +0300 3) #include <config.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 4) #endif
05d292b2 (kx 2023-03-24 03:51:10 +0300 5)
05d292b2 (kx 2023-03-24 03:51:10 +0300 6) #include <stdlib.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 7) #include <stdio.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 8) #include <sys/sysinfo.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 9) #include <sys/types.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 10) #ifdef HAVE_INTTYPES_H
05d292b2 (kx 2023-03-24 03:51:10 +0300 11) #include <inttypes.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 12) #else
05d292b2 (kx 2023-03-24 03:51:10 +0300 13) #include <stdint.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 14) #endif
05d292b2 (kx 2023-03-24 03:51:10 +0300 15) #include <stddef.h> /* offsetof(3) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 16) #include <dirent.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 17) #include <sys/stat.h> /* chmod(2) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 18) #include <sys/file.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 19) #include <sys/mman.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 20) #include <fcntl.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 21) #include <limits.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 22) #include <string.h> /* strdup(3) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 23) #include <libgen.h> /* basename(3) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 24) #include <ctype.h> /* tolower(3) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 25) #include <errno.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 26) #include <time.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 27) #include <sys/time.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 28) #include <pwd.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 29) #include <grp.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 30) #include <stdarg.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 31) #include <locale.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 32) #include <unistd.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 33)
05d292b2 (kx 2023-03-24 03:51:10 +0300 34) #include <git2.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 35)
05d292b2 (kx 2023-03-24 03:51:10 +0300 36) #include <nls.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 37)
05d292b2 (kx 2023-03-24 03:51:10 +0300 38) #include <defs.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 39)
05d292b2 (kx 2023-03-24 03:51:10 +0300 40) #include <fatal.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 41) #include <http.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 42) #include <html.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 43)
05d292b2 (kx 2023-03-24 03:51:10 +0300 44) #include <cmpvers.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 45) #include <dlist.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 46) #include <strbuf.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 47) #include <repolist.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 48) #include <wrapper.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 49) #include <system.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 50) #include <date.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 51)
05d292b2 (kx 2023-03-24 03:51:10 +0300 52) #include <ctx.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 53) #include <git-shared.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 54) #include <ui-shared.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 55)
05d292b2 (kx 2023-03-24 03:51:10 +0300 56)
05d292b2 (kx 2023-03-24 03:51:10 +0300 57) /********************************
05d292b2 (kx 2023-03-24 03:51:10 +0300 58) Sorted dlist functions:
05d292b2 (kx 2023-03-24 03:51:10 +0300 59) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 60) struct tree_line {
05d292b2 (kx 2023-03-24 03:51:10 +0300 61) char *name;
05d292b2 (kx 2023-03-24 03:51:10 +0300 62) char *revision;
05d292b2 (kx 2023-03-24 03:51:10 +0300 63) git_filemode_t mode;
05d292b2 (kx 2023-03-24 03:51:10 +0300 64) git_time_t date;
05d292b2 (kx 2023-03-24 03:51:10 +0300 65) int offset;
05d292b2 (kx 2023-03-24 03:51:10 +0300 66) git_off_t size;
05d292b2 (kx 2023-03-24 03:51:10 +0300 67) };
05d292b2 (kx 2023-03-24 03:51:10 +0300 68)
05d292b2 (kx 2023-03-24 03:51:10 +0300 69) static struct dlist *directories = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 70) static struct dlist *files = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 71)
05d292b2 (kx 2023-03-24 03:51:10 +0300 72) static struct tree_line *tree_line_alloc( const char *name, const char *revision, git_filemode_t mode, git_time_t date, int offset, git_off_t size )
05d292b2 (kx 2023-03-24 03:51:10 +0300 73) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 74) struct tree_line *line = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 75) line = (struct tree_line *)xmalloc( sizeof(struct tree_line) );
05d292b2 (kx 2023-03-24 03:51:10 +0300 76)
05d292b2 (kx 2023-03-24 03:51:10 +0300 77) if( name ) { line->name = xstrdup( name ); }
05d292b2 (kx 2023-03-24 03:51:10 +0300 78) if( revision ) { line->revision = xstrdup( revision ); }
05d292b2 (kx 2023-03-24 03:51:10 +0300 79)
05d292b2 (kx 2023-03-24 03:51:10 +0300 80) if( mode ) line->mode = mode;
05d292b2 (kx 2023-03-24 03:51:10 +0300 81) else line->mode = GIT_FILEMODE_TREE;
05d292b2 (kx 2023-03-24 03:51:10 +0300 82)
05d292b2 (kx 2023-03-24 03:51:10 +0300 83) if( date ) line->date = date;
05d292b2 (kx 2023-03-24 03:51:10 +0300 84) else line->date = -1;
05d292b2 (kx 2023-03-24 03:51:10 +0300 85)
05d292b2 (kx 2023-03-24 03:51:10 +0300 86) if( size ) line->size = size;
05d292b2 (kx 2023-03-24 03:51:10 +0300 87) else line->size = 4096;
05d292b2 (kx 2023-03-24 03:51:10 +0300 88)
05d292b2 (kx 2023-03-24 03:51:10 +0300 89) return line;
05d292b2 (kx 2023-03-24 03:51:10 +0300 90) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 91)
05d292b2 (kx 2023-03-24 03:51:10 +0300 92) static void __line_free( void *data, void *user_data )
05d292b2 (kx 2023-03-24 03:51:10 +0300 93) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 94) struct tree_line *line = (struct tree_line *)data;
05d292b2 (kx 2023-03-24 03:51:10 +0300 95) if( line )
05d292b2 (kx 2023-03-24 03:51:10 +0300 96) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 97) if( line->name ) { free( line->name ); line->name = NULL; }
05d292b2 (kx 2023-03-24 03:51:10 +0300 98) if( line->revision ) { free( line->revision ); line->revision = NULL; }
05d292b2 (kx 2023-03-24 03:51:10 +0300 99)
05d292b2 (kx 2023-03-24 03:51:10 +0300 100) free( line );
05d292b2 (kx 2023-03-24 03:51:10 +0300 101) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 102) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 103)
05d292b2 (kx 2023-03-24 03:51:10 +0300 104) static struct dlist *tree_lines_free( struct dlist *lines )
05d292b2 (kx 2023-03-24 03:51:10 +0300 105) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 106) if( lines )
05d292b2 (kx 2023-03-24 03:51:10 +0300 107) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 108) dlist_free( lines, __line_free );
05d292b2 (kx 2023-03-24 03:51:10 +0300 109) lines = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 110) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 111) return lines;
05d292b2 (kx 2023-03-24 03:51:10 +0300 112) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 113)
05d292b2 (kx 2023-03-24 03:51:10 +0300 114) static int __cmp_tree_lines_byname( const void *a, const void *b )
05d292b2 (kx 2023-03-24 03:51:10 +0300 115) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 116) int ret = -1;
05d292b2 (kx 2023-03-24 03:51:10 +0300 117)
05d292b2 (kx 2023-03-24 03:51:10 +0300 118) struct tree_line *line1 = (struct tree_line *)a;
05d292b2 (kx 2023-03-24 03:51:10 +0300 119) struct tree_line *line2 = (struct tree_line *)b;
05d292b2 (kx 2023-03-24 03:51:10 +0300 120)
05d292b2 (kx 2023-03-24 03:51:10 +0300 121) if( line1->name && line2->name )
05d292b2 (kx 2023-03-24 03:51:10 +0300 122) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 123) ret = strcmp( line1->name, line2->name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 124) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 125) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 126) return ret;
05d292b2 (kx 2023-03-24 03:51:10 +0300 127)
05d292b2 (kx 2023-03-24 03:51:10 +0300 128) return ret;
05d292b2 (kx 2023-03-24 03:51:10 +0300 129) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 130)
05d292b2 (kx 2023-03-24 03:51:10 +0300 131) static int __cmp_tree_lines_bytag( const void *a, const void *b )
05d292b2 (kx 2023-03-24 03:51:10 +0300 132) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 133) char *v1 = NULL, *v2 = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 134) int ret = -1;
05d292b2 (kx 2023-03-24 03:51:10 +0300 135)
05d292b2 (kx 2023-03-24 03:51:10 +0300 136) struct tree_line *line1 = (struct tree_line *)a;
05d292b2 (kx 2023-03-24 03:51:10 +0300 137) struct tree_line *line2 = (struct tree_line *)b;
05d292b2 (kx 2023-03-24 03:51:10 +0300 138)
05d292b2 (kx 2023-03-24 03:51:10 +0300 139) if( line1->name && line2->name )
05d292b2 (kx 2023-03-24 03:51:10 +0300 140) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 141) v1 = line1->name;
05d292b2 (kx 2023-03-24 03:51:10 +0300 142) v2 = line2->name;
05d292b2 (kx 2023-03-24 03:51:10 +0300 143) while( *v1 && !isdigit( *v1 ) ) ++v1;
05d292b2 (kx 2023-03-24 03:51:10 +0300 144) while( *v2 && !isdigit( *v2 ) ) ++v2;
05d292b2 (kx 2023-03-24 03:51:10 +0300 145) ret = strcmp( line1->name, line2->name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 146) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 147) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 148) return ret;
05d292b2 (kx 2023-03-24 03:51:10 +0300 149)
05d292b2 (kx 2023-03-24 03:51:10 +0300 150) if( !*v1 || !*v2 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 151) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 152) return ret;
05d292b2 (kx 2023-03-24 03:51:10 +0300 153) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 154)
05d292b2 (kx 2023-03-24 03:51:10 +0300 155) /******************************************
05d292b2 (kx 2023-03-24 03:51:10 +0300 156) sort reversive to show newest tag first:
05d292b2 (kx 2023-03-24 03:51:10 +0300 157) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 158) return -cmp_version( (const char *)v1, (const char *)v2 );
05d292b2 (kx 2023-03-24 03:51:10 +0300 159) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 160)
05d292b2 (kx 2023-03-24 03:51:10 +0300 161) static struct dlist *tree_lines_sort_byname( struct dlist *lines )
05d292b2 (kx 2023-03-24 03:51:10 +0300 162) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 163) if( lines ) { lines = dlist_sort( lines, __cmp_tree_lines_byname ); }
05d292b2 (kx 2023-03-24 03:51:10 +0300 164) return lines;
05d292b2 (kx 2023-03-24 03:51:10 +0300 165) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 166)
05d292b2 (kx 2023-03-24 03:51:10 +0300 167) static struct dlist *tree_lines_sort_bytag( struct dlist *lines )
05d292b2 (kx 2023-03-24 03:51:10 +0300 168) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 169) if( lines ) { lines = dlist_sort( lines, __cmp_tree_lines_bytag ); }
05d292b2 (kx 2023-03-24 03:51:10 +0300 170) return lines;
05d292b2 (kx 2023-03-24 03:51:10 +0300 171) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 172) /*
05d292b2 (kx 2023-03-24 03:51:10 +0300 173) End of sorted dlist functions.
05d292b2 (kx 2023-03-24 03:51:10 +0300 174) ********************************/
05d292b2 (kx 2023-03-24 03:51:10 +0300 175)
05d292b2 (kx 2023-03-24 03:51:10 +0300 176) static void cgit_print_branches( struct strbuf *sb, const char *relative_path )
05d292b2 (kx 2023-03-24 03:51:10 +0300 177) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 178) git_repository *repo = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 179) git_reference_iterator *iter = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 180) const char *name = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 181) const char *refs = "refs/heads/*";
05d292b2 (kx 2023-03-24 03:51:10 +0300 182)
05d292b2 (kx 2023-03-24 03:51:10 +0300 183) const char *query_string = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 184)
05d292b2 (kx 2023-03-24 03:51:10 +0300 185) if( !sb || !relative_path || !*relative_path ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 186)
05d292b2 (kx 2023-03-24 03:51:10 +0300 187) query_string = ctx_remove_query_param( ctx.env.query_string, "rev" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 188) query_string = ctx_remove_query_param( query_string, "op" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 189)
05d292b2 (kx 2023-03-24 03:51:10 +0300 190) if( !(repo = cgit_open_repository()) ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 191)
05d292b2 (kx 2023-03-24 03:51:10 +0300 192) if( git_reference_iterator_glob_new( &iter, repo, refs ) < 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 193) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 194) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 195) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 196) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 197)
05d292b2 (kx 2023-03-24 03:51:10 +0300 198) strbuf_addstr( sb, "\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 199) strbuf_addf( sb, " <div class=\"repo-tree-header\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 200) strbuf_addf( sb, " <div class=\"row\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 201) strbuf_addf( sb, " <div class=\"col-path\">Path</div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 202) strbuf_addf( sb, " <div class=\"col-size\"><div class=\"tree-size trunc\">Size</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 203) strbuf_addf( sb, " <div class=\"col-rev\"><div class=\"tree-rev trunc\">Rev</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 204) strbuf_addf( sb, " <div class=\"col-date\"><div class=\"tree-date trunc\">Date</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 205) strbuf_addf( sb, " <div class=\"col-links\"><div class=\"tree-links trunc\">Links</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 206) strbuf_addf( sb, " </div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 207) strbuf_addf( sb, " </div>\n\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 208) strbuf_addf( sb, " <div class=\"tree\">\n\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 209)
05d292b2 (kx 2023-03-24 03:51:10 +0300 210) while( !git_reference_next_name( &name, iter ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 211) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 212) struct tree_line *line = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 213) git_commit *commit = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 214) const git_oid *oid;
05d292b2 (kx 2023-03-24 03:51:10 +0300 215) git_time_t date;
05d292b2 (kx 2023-03-24 03:51:10 +0300 216) int offset;
05d292b2 (kx 2023-03-24 03:51:10 +0300 217) char id[GIT_OID_HEXSZ+1] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 218)
05d292b2 (kx 2023-03-24 03:51:10 +0300 219) if( !(commit = get_commit_by_ref( repo, name )) ) continue;
05d292b2 (kx 2023-03-24 03:51:10 +0300 220)
05d292b2 (kx 2023-03-24 03:51:10 +0300 221) oid = git_commit_id( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 222) date = git_commit_time( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 223) offset = git_commit_time_offset( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 224)
05d292b2 (kx 2023-03-24 03:51:10 +0300 225) offset = (offset % 60) + ((offset / 60) * 100);
05d292b2 (kx 2023-03-24 03:51:10 +0300 226)
05d292b2 (kx 2023-03-24 03:51:10 +0300 227) if( git_oid_fmt( (char *)&id[0], oid ) < 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 228) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 229) git_commit_free( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 230) continue;
05d292b2 (kx 2023-03-24 03:51:10 +0300 231) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 232)
05d292b2 (kx 2023-03-24 03:51:10 +0300 233) line = tree_line_alloc( (const char *)&name[11], (const char *)&id[0], 0, date, offset, 0 );
05d292b2 (kx 2023-03-24 03:51:10 +0300 234) directories = dlist_append( directories, (void *)line );
05d292b2 (kx 2023-03-24 03:51:10 +0300 235)
05d292b2 (kx 2023-03-24 03:51:10 +0300 236) git_commit_free( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 237) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 238)
05d292b2 (kx 2023-03-24 03:51:10 +0300 239) git_reference_iterator_free( iter );
05d292b2 (kx 2023-03-24 03:51:10 +0300 240) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 241)
05d292b2 (kx 2023-03-24 03:51:10 +0300 242) /*************************
05d292b2 (kx 2023-03-24 03:51:10 +0300 243) Print directories list:
05d292b2 (kx 2023-03-24 03:51:10 +0300 244) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 245) if( directories )
05d292b2 (kx 2023-03-24 03:51:10 +0300 246) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 247) struct dlist *list = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 248)
05d292b2 (kx 2023-03-24 03:51:10 +0300 249) directories = tree_lines_sort_byname( directories );
05d292b2 (kx 2023-03-24 03:51:10 +0300 250)
05d292b2 (kx 2023-03-24 03:51:10 +0300 251) list = directories;
05d292b2 (kx 2023-03-24 03:51:10 +0300 252)
05d292b2 (kx 2023-03-24 03:51:10 +0300 253) while( list )
05d292b2 (kx 2023-03-24 03:51:10 +0300 254) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 255) struct tree_line *line = (struct tree_line *)list->data;
05d292b2 (kx 2023-03-24 03:51:10 +0300 256)
05d292b2 (kx 2023-03-24 03:51:10 +0300 257) if( strcmp( line->name, ctx.repo.trunk ) ) /* Do not print Trunk. */
05d292b2 (kx 2023-03-24 03:51:10 +0300 258) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 259) /*************************
05d292b2 (kx 2023-03-24 03:51:10 +0300 260) Print branch Reference:
05d292b2 (kx 2023-03-24 03:51:10 +0300 261) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 262) strbuf_addf( sb, " <div class=\"row\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 263) if( ctx.env.query_string && *ctx.env.query_string )
05d292b2 (kx 2023-03-24 03:51:10 +0300 264) strbuf_addf( sb, " <div class=\"col-path\"><a href=\"/%s/branches/%s/?%s\"><div class=\"tree-path dir\">%s/</div></a></div>\n", ctx.repo.name, line->name, ctx.env.query_string, line->name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 265) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 266) strbuf_addf( sb, " <div class=\"col-path\"><a href=\"/%s/branches/%s/\"><div class=\"tree-path dir\">%s/</div></a></div>\n", ctx.repo.name, line->name, line->name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 267) strbuf_addf( sb, " <div class=\"col-size\"><div onclick=\"trunc(this)\" class=\"tree-size trunc\">%ld</div></div>\n", line->size );
05d292b2 (kx 2023-03-24 03:51:10 +0300 268) strbuf_addf( sb, " <div class=\"col-rev\"><div onclick=\"trunc(this)\" class=\"tree-rev trunc\"><span class=\"rev-short\" title=\"%s\">%0.8s</span></div></div>\n", line->revision, line->revision );
05d292b2 (kx 2023-03-24 03:51:10 +0300 269) if( line->date != -1 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 270) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 271) strbuf_addf( sb, " <div class=\"col-date\"><div onclick=\"trunc(this)\" class=\"tree-date trunc\">" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 272) cgit_print_age( sb, (time_t)line->date, line->offset, 0 );
05d292b2 (kx 2023-03-24 03:51:10 +0300 273) strbuf_addf( sb, "</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 274) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 275) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 276) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 277) strbuf_addf( sb, " <div class=\"col-date\"><div onclick=\"trunc(this)\" class=\"tree-date trunc\">unknown</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 278) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 279) strbuf_addf( sb, " <div class=\"col-links\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 280) strbuf_addf( sb, " <div onclick=\"trunc(this)\" class=\"tree-links trunc\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 281) if( query_string && *query_string )
05d292b2 (kx 2023-03-24 03:51:10 +0300 282) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 283) strbuf_addf( sb, " <a title=\"Log from: %s\" href=\"/%s/branches/%s/?op=log&rev=%s&%s\">log</a> \n", line->revision, ctx.repo.name, line->name, line->revision, query_string );
05d292b2 (kx 2023-03-24 03:51:10 +0300 284) strbuf_addf( sb, " <a title=\"Compare with Previous\" href=\"/%s/branches/%s/?op=diff&rev=%s&%s\">diff</a>\n", ctx.repo.name, line->name, line->revision, query_string );
05d292b2 (kx 2023-03-24 03:51:10 +0300 285) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 286) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 287) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 288) strbuf_addf( sb, " <a title=\"Log from: %s\" href=\"/%s/branches/%s/?op=log&rev=%s\">log</a> \n", line->revision, ctx.repo.name, line->name, line->revision );
05d292b2 (kx 2023-03-24 03:51:10 +0300 289) strbuf_addf( sb, " <a title=\"Compare with Previous\" href=\"/%s/branches/%s/?op=diff&rev=%s\">diff</a>\n", ctx.repo.name, line->name, line->revision );
05d292b2 (kx 2023-03-24 03:51:10 +0300 290) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 291) strbuf_addf( sb, " </div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 292) strbuf_addf( sb, " </div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 293) strbuf_addf( sb, " </div>\n\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 294) /*
05d292b2 (kx 2023-03-24 03:51:10 +0300 295) End of printing.
05d292b2 (kx 2023-03-24 03:51:10 +0300 296) *************************/
05d292b2 (kx 2023-03-24 03:51:10 +0300 297) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 298)
05d292b2 (kx 2023-03-24 03:51:10 +0300 299) list = dlist_next( list );
05d292b2 (kx 2023-03-24 03:51:10 +0300 300) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 301) directories = tree_lines_free( directories );
05d292b2 (kx 2023-03-24 03:51:10 +0300 302) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 303)
05d292b2 (kx 2023-03-24 03:51:10 +0300 304) strbuf_addf( sb, " </div> <!-- End of Tree -->\n\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 305) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 306)
05d292b2 (kx 2023-03-24 03:51:10 +0300 307)
05d292b2 (kx 2023-03-24 03:51:10 +0300 308) static void cgit_print_tags( struct strbuf *sb, const char *relative_path )
05d292b2 (kx 2023-03-24 03:51:10 +0300 309) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 310) git_repository *repo = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 311) git_reference_iterator *iter = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 312) const char *name = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 313) const char *refs = "refs/tags/*";
05d292b2 (kx 2023-03-24 03:51:10 +0300 314)
05d292b2 (kx 2023-03-24 03:51:10 +0300 315) const char *query_string = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 316)
05d292b2 (kx 2023-03-24 03:51:10 +0300 317) if( !sb || !relative_path || !*relative_path ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 318)
05d292b2 (kx 2023-03-24 03:51:10 +0300 319) query_string = ctx_remove_query_param( ctx.env.query_string, "rev" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 320) query_string = ctx_remove_query_param( query_string, "op" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 321)
05d292b2 (kx 2023-03-24 03:51:10 +0300 322) if( !(repo = cgit_open_repository()) ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 323)
05d292b2 (kx 2023-03-24 03:51:10 +0300 324) if( git_reference_iterator_glob_new( &iter, repo, refs ) < 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 325) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 326) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 327) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 328) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 329)
05d292b2 (kx 2023-03-24 03:51:10 +0300 330) strbuf_addstr( sb, "\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 331) strbuf_addf( sb, " <div class=\"repo-tree-header\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 332) strbuf_addf( sb, " <div class=\"row\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 333) strbuf_addf( sb, " <div class=\"col-path\">Path</div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 334) strbuf_addf( sb, " <div class=\"col-size\"><div class=\"tree-size trunc\">Size</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 335) strbuf_addf( sb, " <div class=\"col-rev\"><div class=\"tree-rev trunc\">Rev</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 336) strbuf_addf( sb, " <div class=\"col-date\"><div class=\"tree-date trunc\">Date</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 337) strbuf_addf( sb, " <div class=\"col-links\"><div class=\"tree-links trunc\">Links</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 338) strbuf_addf( sb, " </div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 339) strbuf_addf( sb, " </div>\n\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 340) strbuf_addf( sb, " <div class=\"tree\">\n\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 341)
05d292b2 (kx 2023-03-24 03:51:10 +0300 342) while( !git_reference_next_name( &name, iter ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 343) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 344) struct tree_line *line = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 345) git_commit *commit = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 346) const git_oid *oid;
05d292b2 (kx 2023-03-24 03:51:10 +0300 347) git_time_t date;
05d292b2 (kx 2023-03-24 03:51:10 +0300 348) int offset;
05d292b2 (kx 2023-03-24 03:51:10 +0300 349) char id[GIT_OID_HEXSZ+1] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 350)
05d292b2 (kx 2023-03-24 03:51:10 +0300 351) if( !(commit = get_commit_by_ref( repo, name )) ) continue;
05d292b2 (kx 2023-03-24 03:51:10 +0300 352)
05d292b2 (kx 2023-03-24 03:51:10 +0300 353) oid = git_commit_id( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 354) date = git_commit_time( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 355) offset = git_commit_time_offset( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 356)
05d292b2 (kx 2023-03-24 03:51:10 +0300 357) offset = (offset % 60) + ((offset / 60) * 100);
05d292b2 (kx 2023-03-24 03:51:10 +0300 358)
05d292b2 (kx 2023-03-24 03:51:10 +0300 359) if( git_oid_fmt( (char *)&id[0], oid ) < 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 360) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 361) git_commit_free( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 362) continue;
05d292b2 (kx 2023-03-24 03:51:10 +0300 363) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 364)
05d292b2 (kx 2023-03-24 03:51:10 +0300 365) line = tree_line_alloc( (const char *)&name[10], (const char *)&id[0], 0, date, offset, 0 );
05d292b2 (kx 2023-03-24 03:51:10 +0300 366) directories = dlist_append( directories, (void *)line );
05d292b2 (kx 2023-03-24 03:51:10 +0300 367)
05d292b2 (kx 2023-03-24 03:51:10 +0300 368) git_commit_free( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 369) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 370)
05d292b2 (kx 2023-03-24 03:51:10 +0300 371) git_reference_iterator_free( iter );
05d292b2 (kx 2023-03-24 03:51:10 +0300 372) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 373)
05d292b2 (kx 2023-03-24 03:51:10 +0300 374) /*************************
05d292b2 (kx 2023-03-24 03:51:10 +0300 375) Print directories list:
05d292b2 (kx 2023-03-24 03:51:10 +0300 376) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 377) if( directories )
05d292b2 (kx 2023-03-24 03:51:10 +0300 378) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 379) struct dlist *list = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 380)
05d292b2 (kx 2023-03-24 03:51:10 +0300 381) directories = tree_lines_sort_bytag( directories );
05d292b2 (kx 2023-03-24 03:51:10 +0300 382)
05d292b2 (kx 2023-03-24 03:51:10 +0300 383) list = directories;
05d292b2 (kx 2023-03-24 03:51:10 +0300 384)
05d292b2 (kx 2023-03-24 03:51:10 +0300 385) while( list )
05d292b2 (kx 2023-03-24 03:51:10 +0300 386) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 387) struct tree_line *line = (struct tree_line *)list->data;
05d292b2 (kx 2023-03-24 03:51:10 +0300 388)
05d292b2 (kx 2023-03-24 03:51:10 +0300 389) /**********************
05d292b2 (kx 2023-03-24 03:51:10 +0300 390) Print tag Reference:
05d292b2 (kx 2023-03-24 03:51:10 +0300 391) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 392) strbuf_addf( sb, " <div class=\"row\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 393) if( ctx.env.query_string && *ctx.env.query_string )
05d292b2 (kx 2023-03-24 03:51:10 +0300 394) strbuf_addf( sb, " <div class=\"col-path\"><a href=\"/%s/tags/%s/?%s\"><div class=\"tree-path dir\">%s/</div></a></div>\n", ctx.repo.name, line->name, ctx.env.query_string, line->name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 395) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 396) strbuf_addf( sb, " <div class=\"col-path\"><a href=\"/%s/tags/%s/\"><div class=\"tree-path dir\">%s/</div></a></div>\n", ctx.repo.name, line->name, line->name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 397) strbuf_addf( sb, " <div class=\"col-size\"><div onclick=\"trunc(this)\" class=\"tree-size trunc\">%ld</div></div>\n", line->size );
05d292b2 (kx 2023-03-24 03:51:10 +0300 398) strbuf_addf( sb, " <div class=\"col-rev\"><div onclick=\"trunc(this)\" class=\"tree-rev trunc\"><span class=\"rev-short\" title=\"%s\">%0.8s</span></div></div>\n", line->revision, line->revision );
05d292b2 (kx 2023-03-24 03:51:10 +0300 399) if( line->date != -1 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 400) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 401) strbuf_addf( sb, " <div class=\"col-date\"><div onclick=\"trunc(this)\" class=\"tree-date trunc\">" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 402) cgit_print_age( sb, (time_t)line->date, line->offset, 0 );
05d292b2 (kx 2023-03-24 03:51:10 +0300 403) strbuf_addf( sb, "</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 404) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 405) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 406) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 407) strbuf_addf( sb, " <div class=\"col-date\"><div onclick=\"trunc(this)\" class=\"tree-date trunc\">unknown</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 408) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 409) strbuf_addf( sb, " <div class=\"col-links\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 410) strbuf_addf( sb, " <div onclick=\"trunc(this)\" class=\"tree-links trunc\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 411) if( query_string && *query_string )
05d292b2 (kx 2023-03-24 03:51:10 +0300 412) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 413) strbuf_addf( sb, " <a title=\"Log from: %s\" href=\"/%s/tags/%s/?op=log&rev=%s&%s\">log</a> \n", line->revision, ctx.repo.name, line->name, line->revision, query_string );
05d292b2 (kx 2023-03-24 03:51:10 +0300 414) strbuf_addf( sb, " <a title=\"Compare with Previous\" href=\"/%s/tags/%s/?op=diff&rev=%s&%s\">diff</a>\n", ctx.repo.name, line->name, line->revision, query_string );
05d292b2 (kx 2023-03-24 03:51:10 +0300 415) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 416) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 417) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 418) strbuf_addf( sb, " <a title=\"Log from: %s\" href=\"/%s/tags/%s/?op=log&rev=%s\">log</a> \n", line->revision, ctx.repo.name, line->name, line->revision );
05d292b2 (kx 2023-03-24 03:51:10 +0300 419) strbuf_addf( sb, " <a title=\"Compare with Previous\" href=\"/%s/tags/%s/?op=diff&rev=%s\">diff</a>\n", ctx.repo.name, line->name, line->revision );
05d292b2 (kx 2023-03-24 03:51:10 +0300 420) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 421) strbuf_addf( sb, " </div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 422) strbuf_addf( sb, " </div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 423) strbuf_addf( sb, " </div>\n\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 424) /*
05d292b2 (kx 2023-03-24 03:51:10 +0300 425) End of printing.
05d292b2 (kx 2023-03-24 03:51:10 +0300 426) **********************/
05d292b2 (kx 2023-03-24 03:51:10 +0300 427)
05d292b2 (kx 2023-03-24 03:51:10 +0300 428) list = dlist_next( list );
05d292b2 (kx 2023-03-24 03:51:10 +0300 429) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 430) directories = tree_lines_free( directories );
05d292b2 (kx 2023-03-24 03:51:10 +0300 431) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 432)
05d292b2 (kx 2023-03-24 03:51:10 +0300 433) strbuf_addf( sb, " </div> <!-- End of Tree -->\n\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 434) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 435)
05d292b2 (kx 2023-03-24 03:51:10 +0300 436)
05d292b2 (kx 2023-03-24 03:51:10 +0300 437) static void cgit_print_tree( struct strbuf *sb, const char *relative_path, const char *revision )
05d292b2 (kx 2023-03-24 03:51:10 +0300 438) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 439) struct cgit_info info = CGIT_INFO_INIT;
05d292b2 (kx 2023-03-24 03:51:10 +0300 440) const char *query_string = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 441)
05d292b2 (kx 2023-03-24 03:51:10 +0300 442) if( !sb || !relative_path || !*relative_path ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 443)
05d292b2 (kx 2023-03-24 03:51:10 +0300 444) if( !strcmp( relative_path, "tags" ) ) return cgit_print_tags( sb, relative_path );
05d292b2 (kx 2023-03-24 03:51:10 +0300 445) if( !strcmp( relative_path, "branches" ) ) return cgit_print_branches( sb, relative_path );
05d292b2 (kx 2023-03-24 03:51:10 +0300 446)
05d292b2 (kx 2023-03-24 03:51:10 +0300 447) if( revision && strcmp( revision, (const char *)&ctx.repo.relative_info.revision[0] ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 448) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 449) cgit_rpath_info( &info, relative_path, revision );
05d292b2 (kx 2023-03-24 03:51:10 +0300 450) if( info.kind != GIT_OBJECT_BLOB )
05d292b2 (kx 2023-03-24 03:51:10 +0300 451) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 452) strbuf_addf( sb, " <h1>Requested resource cannot be shown</h1>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 453) strbuf_addf( sb, " <p class='leading'>The Tree with specified revision '%s' cannot be shown.</p>\n", revision );
05d292b2 (kx 2023-03-24 03:51:10 +0300 454) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 455) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 456) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 457) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 458) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 459) memcpy( (void *)&info, (void *)&ctx.repo.relative_info, sizeof( struct cgit_info ) );
05d292b2 (kx 2023-03-24 03:51:10 +0300 460) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 461)
05d292b2 (kx 2023-03-24 03:51:10 +0300 462) query_string = ctx_remove_query_param( ctx.env.query_string, "rev" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 463) query_string = ctx_remove_query_param( query_string, "op" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 464)
05d292b2 (kx 2023-03-24 03:51:10 +0300 465) strbuf_addstr( sb, "\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 466) strbuf_addf( sb, " <div class=\"repo-tree-header\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 467) strbuf_addf( sb, " <div class=\"row\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 468) strbuf_addf( sb, " <div class=\"col-path\">Path</div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 469) strbuf_addf( sb, " <div class=\"col-size\"><div class=\"tree-size trunc\">Size</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 470) strbuf_addf( sb, " <div class=\"col-rev\"><div class=\"tree-rev trunc\">Rev</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 471) strbuf_addf( sb, " <div class=\"col-date\"><div class=\"tree-date trunc\">Date</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 472) strbuf_addf( sb, " <div class=\"col-links\"><div class=\"tree-links trunc\">Links</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 473) strbuf_addf( sb, " </div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 474) strbuf_addf( sb, " </div>\n\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 475) strbuf_addf( sb, " <div class=\"tree\">\n\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 476)
05d292b2 (kx 2023-03-24 03:51:10 +0300 477) if( info.kind == GIT_OBJECT_TREE )
05d292b2 (kx 2023-03-24 03:51:10 +0300 478) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 479) git_repository *repo = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 480) git_tree *tree = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 481) git_oid oid;
05d292b2 (kx 2023-03-24 03:51:10 +0300 482) size_t i, count;
05d292b2 (kx 2023-03-24 03:51:10 +0300 483) char rpath[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 484)
05d292b2 (kx 2023-03-24 03:51:10 +0300 485) if( git_oid_fromstr( &oid, (const char *)&info.oid[0] ) < 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 486) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 487) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 488) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 489)
05d292b2 (kx 2023-03-24 03:51:10 +0300 490) if( !(repo = cgit_open_repository()) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 491) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 492) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 493) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 494)
05d292b2 (kx 2023-03-24 03:51:10 +0300 495) if( git_tree_lookup( &tree, repo, &oid ) < 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 496) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 497) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 498) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 499) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 500)
05d292b2 (kx 2023-03-24 03:51:10 +0300 501) count = git_tree_entrycount( tree );
05d292b2 (kx 2023-03-24 03:51:10 +0300 502) for( i = 0; i < count; ++i )
05d292b2 (kx 2023-03-24 03:51:10 +0300 503) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 504) struct tree_line *line = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 505) struct cgit_info entry_info = CGIT_INFO_INIT;
05d292b2 (kx 2023-03-24 03:51:10 +0300 506) git_object *obj = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 507) git_off_t rawsize = 4096;
05d292b2 (kx 2023-03-24 03:51:10 +0300 508) const git_tree_entry *entry = git_tree_entry_byindex( (const git_tree *)tree, i );
05d292b2 (kx 2023-03-24 03:51:10 +0300 509) const char *name = git_tree_entry_name( entry ); /* filename */
05d292b2 (kx 2023-03-24 03:51:10 +0300 510)
05d292b2 (kx 2023-03-24 03:51:10 +0300 511) git_tree_entry_to_object( &obj, repo, entry );
05d292b2 (kx 2023-03-24 03:51:10 +0300 512) if( git_object_type( (const git_object *)obj ) == GIT_OBJECT_BLOB )
05d292b2 (kx 2023-03-24 03:51:10 +0300 513) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 514) rawsize = git_blob_rawsize( (git_blob *)obj );
05d292b2 (kx 2023-03-24 03:51:10 +0300 515) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 516) git_object_free( obj );
05d292b2 (kx 2023-03-24 03:51:10 +0300 517)
05d292b2 (kx 2023-03-24 03:51:10 +0300 518) sprintf( (char *)&rpath[0], "%s/%s", relative_path, name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 519) cgit_rpath_info( &entry_info, (char *)&rpath[0], info.revision );
05d292b2 (kx 2023-03-24 03:51:10 +0300 520)
05d292b2 (kx 2023-03-24 03:51:10 +0300 521) line = tree_line_alloc( name, (const char *)&entry_info.revision[0], entry_info.mode, entry_info.date, entry_info.offset, rawsize );
05d292b2 (kx 2023-03-24 03:51:10 +0300 522)
05d292b2 (kx 2023-03-24 03:51:10 +0300 523) if( entry_info.kind == GIT_OBJECT_TREE )
05d292b2 (kx 2023-03-24 03:51:10 +0300 524) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 525) directories = dlist_append( directories, (void *)line );
05d292b2 (kx 2023-03-24 03:51:10 +0300 526) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 527) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 528) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 529) files = dlist_append( files, (void *)line );
05d292b2 (kx 2023-03-24 03:51:10 +0300 530) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 531) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 532)
05d292b2 (kx 2023-03-24 03:51:10 +0300 533) git_tree_free( tree );
05d292b2 (kx 2023-03-24 03:51:10 +0300 534) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 535)
05d292b2 (kx 2023-03-24 03:51:10 +0300 536)
05d292b2 (kx 2023-03-24 03:51:10 +0300 537) /*************************
05d292b2 (kx 2023-03-24 03:51:10 +0300 538) Print directories list:
05d292b2 (kx 2023-03-24 03:51:10 +0300 539) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 540) if( directories )
05d292b2 (kx 2023-03-24 03:51:10 +0300 541) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 542) struct dlist *list = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 543)
05d292b2 (kx 2023-03-24 03:51:10 +0300 544) directories = tree_lines_sort_byname( directories );
05d292b2 (kx 2023-03-24 03:51:10 +0300 545)
05d292b2 (kx 2023-03-24 03:51:10 +0300 546) list = directories;
05d292b2 (kx 2023-03-24 03:51:10 +0300 547)
05d292b2 (kx 2023-03-24 03:51:10 +0300 548) while( list )
05d292b2 (kx 2023-03-24 03:51:10 +0300 549) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 550) const char *mode = "";
05d292b2 (kx 2023-03-24 03:51:10 +0300 551) struct tree_line *line = (struct tree_line *)list->data;
05d292b2 (kx 2023-03-24 03:51:10 +0300 552)
05d292b2 (kx 2023-03-24 03:51:10 +0300 553) if( line->mode == GIT_FILEMODE_LINK )
05d292b2 (kx 2023-03-24 03:51:10 +0300 554) mode = " link";
05d292b2 (kx 2023-03-24 03:51:10 +0300 555) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 556) mode = "";
05d292b2 (kx 2023-03-24 03:51:10 +0300 557)
05d292b2 (kx 2023-03-24 03:51:10 +0300 558) /*************************
05d292b2 (kx 2023-03-24 03:51:10 +0300 559) Print branch Reference:
05d292b2 (kx 2023-03-24 03:51:10 +0300 560) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 561) strbuf_addf( sb, " <div class=\"row\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 562) if( ctx.env.query_string && *ctx.env.query_string )
05d292b2 (kx 2023-03-24 03:51:10 +0300 563) strbuf_addf( sb, " <div class=\"col-path\"><a href=\"/%s/%s/%s/?%s\"><div class=\"tree-path dir%s\">%s/</div></a></div>\n", ctx.repo.name, relative_path, line->name, ctx.env.query_string, mode, line->name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 564) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 565) strbuf_addf( sb, " <div class=\"col-path\"><a href=\"/%s/%s/%s/\"><div class=\"tree-path dir%s\">%s/</div></a></div>\n", ctx.repo.name, relative_path, line->name, mode, line->name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 566) strbuf_addf( sb, " <div class=\"col-size\"><div onclick=\"trunc(this)\" class=\"tree-size trunc\">%ld</div></div>\n", line->size );
05d292b2 (kx 2023-03-24 03:51:10 +0300 567) strbuf_addf( sb, " <div class=\"col-rev\"><div onclick=\"trunc(this)\" class=\"tree-rev trunc\"><span class=\"rev-short\" title=\"%s\">%0.8s</span></div></div>\n", line->revision, line->revision );
05d292b2 (kx 2023-03-24 03:51:10 +0300 568) if( line->date != -1 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 569) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 570) strbuf_addf( sb, " <div class=\"col-date\"><div onclick=\"trunc(this)\" class=\"tree-date trunc\">" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 571) cgit_print_age( sb, (time_t)line->date, line->offset, 0 );
05d292b2 (kx 2023-03-24 03:51:10 +0300 572) strbuf_addf( sb, "</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 573) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 574) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 575) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 576) strbuf_addf( sb, " <div class=\"col-date\"><div onclick=\"trunc(this)\" class=\"tree-date trunc\">unknown</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 577) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 578) strbuf_addf( sb, " <div class=\"col-links\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 579) strbuf_addf( sb, " <div onclick=\"trunc(this)\" class=\"tree-links trunc\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 580) if( query_string && *query_string )
05d292b2 (kx 2023-03-24 03:51:10 +0300 581) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 582) strbuf_addf( sb, " <a title=\"Log from: %s\" href=\"/%s/%s/%s/?op=log&rev=%s&%s\">log</a> \n", line->revision, ctx.repo.name, relative_path, line->name, line->revision, query_string );
05d292b2 (kx 2023-03-24 03:51:10 +0300 583) strbuf_addf( sb, " <a title=\"Compare with Previous\" href=\"/%s/%s/%s/?op=diff&rev=%s&%s\">diff</a>\n", ctx.repo.name, relative_path, line->name, line->revision, query_string );
05d292b2 (kx 2023-03-24 03:51:10 +0300 584) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 585) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 586) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 587) strbuf_addf( sb, " <a title=\"Log from: %s\" href=\"/%s/%s/%s/?op=log&rev=%s\">log</a> \n", line->revision, ctx.repo.name, relative_path, line->name, line->revision );
05d292b2 (kx 2023-03-24 03:51:10 +0300 588) strbuf_addf( sb, " <a title=\"Compare with Previous\" href=\"/%s/%s/%s/?op=diff&rev=%s\">diff</a>\n", ctx.repo.name, relative_path, line->name, line->revision );
05d292b2 (kx 2023-03-24 03:51:10 +0300 589) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 590) strbuf_addf( sb, " </div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 591) strbuf_addf( sb, " </div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 592) strbuf_addf( sb, " </div>\n\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 593) /*
05d292b2 (kx 2023-03-24 03:51:10 +0300 594) End of printing.
05d292b2 (kx 2023-03-24 03:51:10 +0300 595) *************************/
05d292b2 (kx 2023-03-24 03:51:10 +0300 596)
05d292b2 (kx 2023-03-24 03:51:10 +0300 597) list = dlist_next( list );
05d292b2 (kx 2023-03-24 03:51:10 +0300 598) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 599) directories = tree_lines_free( directories );
05d292b2 (kx 2023-03-24 03:51:10 +0300 600) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 601)
05d292b2 (kx 2023-03-24 03:51:10 +0300 602) /********************
05d292b2 (kx 2023-03-24 03:51:10 +0300 603) Print filess list:
05d292b2 (kx 2023-03-24 03:51:10 +0300 604) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 605) if( files )
05d292b2 (kx 2023-03-24 03:51:10 +0300 606) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 607) struct dlist *list = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 608)
05d292b2 (kx 2023-03-24 03:51:10 +0300 609) files = tree_lines_sort_byname( files );
05d292b2 (kx 2023-03-24 03:51:10 +0300 610)
05d292b2 (kx 2023-03-24 03:51:10 +0300 611) list = files;
05d292b2 (kx 2023-03-24 03:51:10 +0300 612)
05d292b2 (kx 2023-03-24 03:51:10 +0300 613) while( list )
05d292b2 (kx 2023-03-24 03:51:10 +0300 614) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 615) const char *mode = "";
05d292b2 (kx 2023-03-24 03:51:10 +0300 616) const char *mode_prefix = "";
05d292b2 (kx 2023-03-24 03:51:10 +0300 617) struct tree_line *line = (struct tree_line *)list->data;
05d292b2 (kx 2023-03-24 03:51:10 +0300 618)
05d292b2 (kx 2023-03-24 03:51:10 +0300 619) if( line->mode == GIT_FILEMODE_LINK )
05d292b2 (kx 2023-03-24 03:51:10 +0300 620) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 621) mode = " link";
05d292b2 (kx 2023-03-24 03:51:10 +0300 622) mode_prefix = "@";
05d292b2 (kx 2023-03-24 03:51:10 +0300 623) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 624) else if( line->mode == GIT_FILEMODE_BLOB_EXECUTABLE )
05d292b2 (kx 2023-03-24 03:51:10 +0300 625) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 626) mode = " exec";
05d292b2 (kx 2023-03-24 03:51:10 +0300 627) mode_prefix = "";
05d292b2 (kx 2023-03-24 03:51:10 +0300 628) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 629) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 630) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 631) mode = "";
05d292b2 (kx 2023-03-24 03:51:10 +0300 632) mode_prefix = "";
05d292b2 (kx 2023-03-24 03:51:10 +0300 633) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 634)
05d292b2 (kx 2023-03-24 03:51:10 +0300 635) /*************************
05d292b2 (kx 2023-03-24 03:51:10 +0300 636) Print branch Reference:
05d292b2 (kx 2023-03-24 03:51:10 +0300 637) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 638) strbuf_addf( sb, " <div class=\"row\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 639) if( ctx.env.query_string && *ctx.env.query_string )
05d292b2 (kx 2023-03-24 03:51:10 +0300 640) strbuf_addf( sb, " <div class=\"col-path\"><a href=\"/%s/%s/%s/?%s\"><div class=\"tree-path file%s\">%s%s</div></a></div>\n", ctx.repo.name, relative_path, line->name, ctx.env.query_string, mode, mode_prefix, line->name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 641) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 642) strbuf_addf( sb, " <div class=\"col-path\"><a href=\"/%s/%s/%s/\"><div class=\"tree-path file%s\">%s%s</div></a></div>\n", ctx.repo.name, relative_path, line->name, mode, mode_prefix, line->name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 643) strbuf_addf( sb, " <div class=\"col-size\"><div onclick=\"trunc(this)\" class=\"tree-size trunc\">%ld</div></div>\n", line->size );
05d292b2 (kx 2023-03-24 03:51:10 +0300 644) strbuf_addf( sb, " <div class=\"col-rev\"><div onclick=\"trunc(this)\" class=\"tree-rev trunc\"><span class=\"rev-short\" title=\"%s\">%0.8s</span></div></div>\n", line->revision, line->revision );
05d292b2 (kx 2023-03-24 03:51:10 +0300 645) if( line->date != -1 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 646) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 647) strbuf_addf( sb, " <div class=\"col-date\"><div onclick=\"trunc(this)\" class=\"tree-date trunc\">" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 648) cgit_print_age( sb, (time_t)line->date, line->offset, 0 );
05d292b2 (kx 2023-03-24 03:51:10 +0300 649) strbuf_addf( sb, "</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 650) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 651) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 652) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 653) strbuf_addf( sb, " <div class=\"col-date\"><div onclick=\"trunc(this)\" class=\"tree-date trunc\">unknown</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 654) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 655) strbuf_addf( sb, " <div class=\"col-links\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 656) strbuf_addf( sb, " <div onclick=\"trunc(this)\" class=\"tree-links trunc\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 657) if( query_string && *query_string )
05d292b2 (kx 2023-03-24 03:51:10 +0300 658) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 659) strbuf_addf( sb, " <a title=\"Log from: %s\" href=\"/%s/%s/%s/?op=log&rev=%s&%s\">log</a> \n", line->revision, ctx.repo.name, relative_path, line->name, line->revision, query_string );
05d292b2 (kx 2023-03-24 03:51:10 +0300 660) strbuf_addf( sb, " <a title=\"Compare with Previous\" href=\"/%s/%s/%s/?op=diff&rev=%s&%s\">diff</a> \n", ctx.repo.name, relative_path, line->name, line->revision, query_string );
05d292b2 (kx 2023-03-24 03:51:10 +0300 661) strbuf_addf( sb, " <a href=\"/%s/%s/%s/?op=blame&rev=%s&%s\">blame</a>\n", ctx.repo.name, relative_path, line->name, line->revision, query_string );
05d292b2 (kx 2023-03-24 03:51:10 +0300 662) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 663) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 664) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 665) strbuf_addf( sb, " <a title=\"Log from: %s\" href=\"/%s/%s/%s/?op=log&rev=%s\">log</a> \n", line->revision, ctx.repo.name, relative_path, line->name, line->revision );
05d292b2 (kx 2023-03-24 03:51:10 +0300 666) strbuf_addf( sb, " <a title=\"Compare with Previous\" href=\"/%s/%s/%s/?op=diff&rev=%s\">diff</a> \n", ctx.repo.name, relative_path, line->name, line->revision );
05d292b2 (kx 2023-03-24 03:51:10 +0300 667) strbuf_addf( sb, " <a href=\"/%s/%s/%s/?op=blame&rev=%s\">blame</a>\n", ctx.repo.name, relative_path, line->name, line->revision );
05d292b2 (kx 2023-03-24 03:51:10 +0300 668) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 669) strbuf_addf( sb, " </div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 670) strbuf_addf( sb, " </div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 671) strbuf_addf( sb, " </div>\n\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 672) /*
05d292b2 (kx 2023-03-24 03:51:10 +0300 673) End of printing.
05d292b2 (kx 2023-03-24 03:51:10 +0300 674) *************************/
05d292b2 (kx 2023-03-24 03:51:10 +0300 675)
05d292b2 (kx 2023-03-24 03:51:10 +0300 676) list = dlist_next( list );
05d292b2 (kx 2023-03-24 03:51:10 +0300 677) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 678) files = tree_lines_free( files );
05d292b2 (kx 2023-03-24 03:51:10 +0300 679) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 680) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 681)
05d292b2 (kx 2023-03-24 03:51:10 +0300 682) strbuf_addf( sb, " </div> <!-- End of Tree -->\n\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 683)
05d292b2 (kx 2023-03-24 03:51:10 +0300 684) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 685) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 686)
05d292b2 (kx 2023-03-24 03:51:10 +0300 687) static void cgit_print_summary( struct strbuf *sb, const char *relative_path, const char *revision )
05d292b2 (kx 2023-03-24 03:51:10 +0300 688) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 689) struct cgit_info info;
05d292b2 (kx 2023-03-24 03:51:10 +0300 690) const char *query_string = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 691)
05d292b2 (kx 2023-03-24 03:51:10 +0300 692) if( !sb ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 693)
05d292b2 (kx 2023-03-24 03:51:10 +0300 694) if( relative_path && *relative_path )
05d292b2 (kx 2023-03-24 03:51:10 +0300 695) return cgit_print_tree( sb, relative_path, revision );
05d292b2 (kx 2023-03-24 03:51:10 +0300 696)
05d292b2 (kx 2023-03-24 03:51:10 +0300 697) query_string = ctx_remove_query_param( ctx.env.query_string, "rev" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 698) query_string = ctx_remove_query_param( query_string, "op" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 699)
05d292b2 (kx 2023-03-24 03:51:10 +0300 700) strbuf_addstr( sb, "\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 701) strbuf_addf( sb, " <div class=\"repo-tree-header\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 702) strbuf_addf( sb, " <div class=\"row\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 703) strbuf_addf( sb, " <div class=\"col-path\">Refs</div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 704) strbuf_addf( sb, " </div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 705) strbuf_addf( sb, " </div>\n\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 706) strbuf_addf( sb, " <div class=\"tree\">\n\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 707) strbuf_addf( sb, " <div class=\"row\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 708) strbuf_addf( sb, " <div class=\"col-path\"><div class=\"tree-path dir\"><a href=\"/%s/branches/\">branches/</a></div></div>\n", ctx.repo.name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 709) strbuf_addf( sb, " </div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 710) strbuf_addf( sb, " <div class=\"row\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 711) strbuf_addf( sb, " <div class=\"col-path\"><div class=\"tree-path dir\"><a href=\"/%s/tags/\">tags/</a></div></div>\n", ctx.repo.name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 712) strbuf_addf( sb, " </div>\n\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 713) strbuf_addf( sb, " </div> <!-- End of Tree -->\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 714)
05d292b2 (kx 2023-03-24 03:51:10 +0300 715) cgit_rpath_info( &info, "/", revision );
05d292b2 (kx 2023-03-24 03:51:10 +0300 716) if( info.kind != GIT_OBJECT_TREE && info.kind != GIT_OBJECT_BLOB )
05d292b2 (kx 2023-03-24 03:51:10 +0300 717) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 718) memcpy( (void *)&info, (const void *)&ctx.repo.relative_info, sizeof( struct cgit_info ) );
05d292b2 (kx 2023-03-24 03:51:10 +0300 719) ctx.query.revision = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 720) (void)ctx_grab_str_query_param( "rev" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 721) ctx.query.rev = "0";
05d292b2 (kx 2023-03-24 03:51:10 +0300 722) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 723)
05d292b2 (kx 2023-03-24 03:51:10 +0300 724) strbuf_addstr( sb, "\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 725) strbuf_addf( sb, " <div class=\"repo-tree-header\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 726) strbuf_addf( sb, " <div class=\"row\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 727) strbuf_addf( sb, " <div class=\"col-path\">Path</div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 728) strbuf_addf( sb, " <div class=\"col-size\"><div class=\"tree-size trunc\">Size</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 729) strbuf_addf( sb, " <div class=\"col-rev\"><div class=\"tree-rev trunc\">Rev</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 730) strbuf_addf( sb, " <div class=\"col-date\"><div class=\"tree-date trunc\">Date</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 731) strbuf_addf( sb, " <div class=\"col-links\"><div class=\"tree-links trunc\">Links</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 732) strbuf_addf( sb, " </div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 733) strbuf_addf( sb, " </div>\n\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 734) strbuf_addf( sb, " <div class=\"tree\">\n\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 735)
05d292b2 (kx 2023-03-24 03:51:10 +0300 736) /************************
05d292b2 (kx 2023-03-24 03:51:10 +0300 737) Print trunk Reference:
05d292b2 (kx 2023-03-24 03:51:10 +0300 738) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 739) strbuf_addf( sb, " <div class=\"row\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 740) strbuf_addf( sb, " <div class=\"col-path\"><a href=\"/%s/trunk/\"><div class=\"tree-path dir\">trunk/</div></a></div>\n", ctx.repo.name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 741) strbuf_addf( sb, " <div class=\"col-size\"><div onclick=\"trunc(this)\" class=\"tree-size trunc\">%ld</div></div>\n", (git_off_t)4096 );
05d292b2 (kx 2023-03-24 03:51:10 +0300 742) strbuf_addf( sb, " <div class=\"col-rev\"><div onclick=\"trunc(this)\" class=\"tree-rev trunc\"><span class=\"rev-short\" title=\"%s\">%0.8s</span></div></div>\n", info.revision, info.revision );
05d292b2 (kx 2023-03-24 03:51:10 +0300 743) if( info.date != -1 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 744) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 745) strbuf_addf( sb, " <div class=\"col-date\"><div onclick=\"trunc(this)\" class=\"tree-date trunc\">" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 746) cgit_print_age( sb, (time_t)info.date, info.offset, 0 );
05d292b2 (kx 2023-03-24 03:51:10 +0300 747) strbuf_addf( sb, "</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 748) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 749) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 750) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 751) strbuf_addf( sb, " <div class=\"col-date\"><div onclick=\"trunc(this)\" class=\"tree-date trunc\">unknown</div></div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 752) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 753) strbuf_addf( sb, " <div class=\"col-links\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 754) strbuf_addf( sb, " <div onclick=\"trunc(this)\" class=\"tree-links trunc\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 755) if( query_string && *query_string )
05d292b2 (kx 2023-03-24 03:51:10 +0300 756) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 757) strbuf_addf( sb, " <a title=\"Log from: %s\" href=\"/%s/trunk/?op=log&rev=%s&%s\">log</a> \n", info.revision, ctx.repo.name, info.revision, query_string );
05d292b2 (kx 2023-03-24 03:51:10 +0300 758) strbuf_addf( sb, " <a title=\"Compare with Previous\" href=\"/%s/trunk/?op=diff&rev=%s&%s\">diff</a>\n", ctx.repo.name, info.revision, query_string );
05d292b2 (kx 2023-03-24 03:51:10 +0300 759) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 760) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 761) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 762) strbuf_addf( sb, " <a title=\"Log from: %s\" href=\"/%s/trunk/?op=log&rev=%s\">log</a> \n", info.revision, ctx.repo.name, info.revision );
05d292b2 (kx 2023-03-24 03:51:10 +0300 763) strbuf_addf( sb, " <a title=\"Compare with Previous\" href=\"/%s/trunk/?op=diff&rev=%s\">diff</a>\n", ctx.repo.name, info.revision );
05d292b2 (kx 2023-03-24 03:51:10 +0300 764) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 765) strbuf_addf( sb, " </div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 766) strbuf_addf( sb, " </div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 767) strbuf_addf( sb, " </div>\n\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 768)
05d292b2 (kx 2023-03-24 03:51:10 +0300 769) strbuf_addf( sb, " </div> <!-- End of Tree -->\n\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 770) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 771)
05d292b2 (kx 2023-03-24 03:51:10 +0300 772)
05d292b2 (kx 2023-03-24 03:51:10 +0300 773) static void cgit_print_clone_urls( struct strbuf *sb, const char *relative_path )
05d292b2 (kx 2023-03-24 03:51:10 +0300 774) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 775) char ref[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 776) char rpath[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 777) char branch[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 778)
05d292b2 (kx 2023-03-24 03:51:10 +0300 779) if( !sb ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 780)
05d292b2 (kx 2023-03-24 03:51:10 +0300 781) parse_relative_path( (char *)&ref[0], (char *)&rpath[0], relative_path );
05d292b2 (kx 2023-03-24 03:51:10 +0300 782)
05d292b2 (kx 2023-03-24 03:51:10 +0300 783) if( ref[0] && strlen( (char *)&ref[0] ) > 11 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 784) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 785) const char *b = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 786) if( !strncmp( (char *)&ref[0], "refs/heads/", 11 ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 787) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 788) b = (const char *)&ref[11];
05d292b2 (kx 2023-03-24 03:51:10 +0300 789) sprintf( (char *)&branch[0], "--branch %s -- ", b );
05d292b2 (kx 2023-03-24 03:51:10 +0300 790) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 791)
05d292b2 (kx 2023-03-24 03:51:10 +0300 792) if( b && !strcmp( b, ctx.repo.trunk ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 793) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 794) branch[0] = '\0';
05d292b2 (kx 2023-03-24 03:51:10 +0300 795) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 796) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 797)
05d292b2 (kx 2023-03-24 03:51:10 +0300 798) strbuf_addf( sb, " <div class=\"clone-box\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 799) strbuf_addf( sb, " <div class=\"clone-header\">Clone</div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 800) strbuf_addf( sb, " <div class=\"clone-urls\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 801) strbuf_addf( sb, " <div class=\"clone-line\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 802) strbuf_addf( sb, " <div class=\"clone-perms\">ro:</div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 803)
05d292b2 (kx 2023-03-24 03:51:10 +0300 804) strbuf_addf( sb, " <div class=\"clone-url\">git clone %s%s/%s</div>\n", branch, ctx.repo.clone_ro_prefix, ctx.repo.name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 805)
05d292b2 (kx 2023-03-24 03:51:10 +0300 806) strbuf_addf( sb, " </div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 807) if( ctx.repo.clone_prefix && *ctx.repo.clone_prefix )
05d292b2 (kx 2023-03-24 03:51:10 +0300 808) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 809) strbuf_addf( sb, " <div class=\"clone-line\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 810) strbuf_addf( sb, " <div class=\"clone-perms\">rw:</div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 811)
05d292b2 (kx 2023-03-24 03:51:10 +0300 812) strbuf_addf( sb, " <div class=\"clone-url\">git clone %s%s/%s</div>\n", branch, ctx.repo.clone_prefix, ctx.repo.name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 813)
05d292b2 (kx 2023-03-24 03:51:10 +0300 814) strbuf_addf( sb, " </div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 815) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 816) strbuf_addf( sb, " </div>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 817) strbuf_addf( sb, " </div> <!-- End of Clone -->\n\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 818) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 819)
05d292b2 (kx 2023-03-24 03:51:10 +0300 820) void cgit_print_tree_page( void )
05d292b2 (kx 2023-03-24 03:51:10 +0300 821) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 822) FILE *fp;
05d292b2 (kx 2023-03-24 03:51:10 +0300 823) struct strbuf buf = STRBUF_INIT;
05d292b2 (kx 2023-03-24 03:51:10 +0300 824)
05d292b2 (kx 2023-03-24 03:51:10 +0300 825) fp = xfopen( ctx.page.header, "r" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 826) (void)strbuf_env_fread( &buf, fp );
05d292b2 (kx 2023-03-24 03:51:10 +0300 827) fclose( fp );
05d292b2 (kx 2023-03-24 03:51:10 +0300 828)
05d292b2 (kx 2023-03-24 03:51:10 +0300 829) strbuf_addf( &buf, " <div class=\"content segment\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 830) strbuf_addf( &buf, " <div class=\"container\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 831) strbuf_addf( &buf, " <div class=\"cgit-main-content\">\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 832)
05d292b2 (kx 2023-03-24 03:51:10 +0300 833) if( ctx.repo.relative_info.kind == GIT_OBJECT_TREE )
05d292b2 (kx 2023-03-24 03:51:10 +0300 834) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 835) if( ctx.repo.name )
05d292b2 (kx 2023-03-24 03:51:10 +0300 836) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 837) cgit_print_summary( &buf, ctx.repo.relative_path, (!strcmp( ctx.query.rev, "0" )) ? (const char *)&ctx.repo.relative_info.revision[0] : ctx.query.rev );
05d292b2 (kx 2023-03-24 03:51:10 +0300 838) cgit_print_clone_urls( &buf, ctx.repo.relative_path );
05d292b2 (kx 2023-03-24 03:51:10 +0300 839) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 840) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 841) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 842) strbuf_addf( &buf, " <h1>Requested resource cannot be shown</h1>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 843) strbuf_addf( &buf, " <p class='leading'>Repository '%s' not found.</p>\n", ctx.repo.name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 844) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 845) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 846) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 847) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 848) strbuf_addf( &buf, " <h1>Requested resource cannot be shown</h1>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 849) strbuf_addf( &buf, " <p class='leading'>This page assume the repository tree to be shown.</p>\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 850) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 851)
05d292b2 (kx 2023-03-24 03:51:10 +0300 852) strbuf_addf( &buf, " </div> <!-- End of cgit-main-content -->\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 853) strbuf_addf( &buf, " </div> <!-- End of container -->\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 854) strbuf_addf( &buf, " </div> <!-- End of content segment -->\n" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 855)
05d292b2 (kx 2023-03-24 03:51:10 +0300 856) fp = xfopen( ctx.page.footer, "r" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 857) (void)strbuf_env_fread( &buf, fp );
05d292b2 (kx 2023-03-24 03:51:10 +0300 858) fclose( fp );
05d292b2 (kx 2023-03-24 03:51:10 +0300 859)
05d292b2 (kx 2023-03-24 03:51:10 +0300 860) ctx.page.size = buf.len;
05d292b2 (kx 2023-03-24 03:51:10 +0300 861) cgit_print_http_headers();
05d292b2 (kx 2023-03-24 03:51:10 +0300 862) strbuf_write( &buf, STDOUT_FILENO );
05d292b2 (kx 2023-03-24 03:51:10 +0300 863) strbuf_release( &buf );
05d292b2 (kx 2023-03-24 03:51:10 +0300 864) }