#ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #ifdef HAVE_INTTYPES_H #include #else #include #endif #include /* offsetof(3) */ #include #include /* chmod(2) */ #include #include #include #include #include /* strdup(3) */ #include /* basename(3) */ #include /* tolower(3) */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static void cgit_print_blame( struct strbuf *sb, const char *relative_path, const char *revision ) { const char *name = NULL, *git_root = NULL, *repo_root = NULL; if( !sb || !relative_path ) return; name = ctx.repo.name; git_root = ctx.repo.git_root; repo_root = ctx.repo.repo_root; strbuf_addf( sb, "
" ); strbuf_addf( sb, "
" );

  if( name && git_root )
  {
    char ref[PATH_MAX] = { 0 };
    char rpath[PATH_MAX] = { 0 };

    char path[PATH_MAX] = { 0 };
    char cmd[PATH_MAX];
    struct strbuf buf = STRBUF_INIT;
    char *raw = NULL;
    pid_t p = (pid_t) -1;
    int   rc;

    sprintf( (char *)&path[0], "%s/", git_root );
    if( repo_root && *repo_root )
    {
      strcat( (char *)&path[0], repo_root );
      strcat( (char *)&path[0], "/" );
    }
    strcat( (char *)&path[0], name );

    if( !is_bare( (char *)&path[0] ) )
    {
      strcat( (char *)&path[0], "/.git" );
    }

    parse_relative_path( (char *)&ref[0], (char *)&rpath[0], relative_path );

    if( revision && *revision )
      snprintf( (char *)&cmd[0], 1024, "git --git-dir=%s blame %s -- %s 2>/dev/null", (char *)&path[0], revision, (char *)&rpath[0] );
    else
      snprintf( (char *)&cmd[0], 1024, "git --git-dir=%s blame -- %s 2>/dev/null", (char *)&path[0], (char *)&rpath[0] );
    p = sys_exec_command( &buf, cmd );
    rc = sys_wait_command( p, NULL );
    if( rc != 0 )
    {
      strbuf_release( &buf );
      return;
    }

    if( buf.buf[0] )
    {
      raw = strbuf_detach( &buf, NULL );
      strbuf_addstr_xml_quoted( &buf, (const char *)raw );
      free( raw );

      strbuf_addbuf( sb, (const struct strbuf *)&buf );
    }
    strbuf_release( &buf );
  }

  strbuf_addstr( sb, "\n  
\n" ); strbuf_addstr( sb, "
\n" ); return; } void cgit_print_blame_page( void ) { FILE *fp; struct strbuf buf = STRBUF_INIT; fp = xfopen( ctx.page.header, "r" ); (void)strbuf_env_fread( &buf, fp ); fclose( fp ); strbuf_addf( &buf, "
\n" ); strbuf_addf( &buf, "
\n" ); strbuf_addf( &buf, "
\n" ); if( ctx.repo.name ) { cgit_print_blame( &buf, ctx.repo.relative_path, (!strcmp( ctx.query.rev, "0" )) ? (const char *)&ctx.repo.relative_info.revision[0] : ctx.query.rev ); } else { strbuf_addf( &buf, "

Requested resource cannot be shown

\n" ); strbuf_addf( &buf, "

Repository '%s' not found.

\n", ctx.repo.name ); } strbuf_addf( &buf, "
\n" ); strbuf_addf( &buf, "
\n" ); strbuf_addf( &buf, "
\n" ); fp = xfopen( ctx.page.footer, "r" ); (void)strbuf_env_fread( &buf, fp ); fclose( fp ); ctx.page.size = buf.len; cgit_print_http_headers(); strbuf_write( &buf, STDOUT_FILENO ); strbuf_release( &buf ); }