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 <string.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300   9) #include <errno.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  10) #include <error.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  11) #include <sys/stat.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  12) #include <sys/wait.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  13) #include <stdarg.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  14) #include <unistd.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  15) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  16) #include <defs.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  17) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  18) #include <strbuf.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  19) #include <system.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  20) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  21) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  22) #define SYSTEM_ERRMSG_SIZE 4096
bfc1508d (kx 2023-03-24 03:55:33 +0300  23) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  24) void system_error( const char *fmt, ... )
bfc1508d (kx 2023-03-24 03:55:33 +0300  25) {
bfc1508d (kx 2023-03-24 03:55:33 +0300  26)   va_list arg_ptr;
bfc1508d (kx 2023-03-24 03:55:33 +0300  27)   char  buf[SYSTEM_ERRMSG_SIZE];
bfc1508d (kx 2023-03-24 03:55:33 +0300  28)   char  msg[SYSTEM_ERRMSG_SIZE];
bfc1508d (kx 2023-03-24 03:55:33 +0300  29)   char *format = "%s: %s\n";
bfc1508d (kx 2023-03-24 03:55:33 +0300  30) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  31)   va_start( arg_ptr, fmt );
bfc1508d (kx 2023-03-24 03:55:33 +0300  32) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  33)   vsnprintf( msg, SYSTEM_ERRMSG_SIZE, (const void *)fmt, arg_ptr );
bfc1508d (kx 2023-03-24 03:55:33 +0300  34) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  35)   va_end( arg_ptr ); /* Reset variable arguments. */
bfc1508d (kx 2023-03-24 03:55:33 +0300  36) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  37)   snprintf( buf, SYSTEM_ERRMSG_SIZE, format, "system", msg );
bfc1508d (kx 2023-03-24 03:55:33 +0300  38) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  39)   (void)write( STDERR_FILENO, buf, strlen( buf ) );
bfc1508d (kx 2023-03-24 03:55:33 +0300  40) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  41)   exit( 1 );
bfc1508d (kx 2023-03-24 03:55:33 +0300  42) }
bfc1508d (kx 2023-03-24 03:55:33 +0300  43) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  44) system_errfunc system_fatal = system_error;
bfc1508d (kx 2023-03-24 03:55:33 +0300  45) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  46) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  47) static void xexec( const char *cmd )
bfc1508d (kx 2023-03-24 03:55:33 +0300  48) {
bfc1508d (kx 2023-03-24 03:55:33 +0300  49)   char *argv[4];
bfc1508d (kx 2023-03-24 03:55:33 +0300  50)   const char *shell = getenv ("SHELL");
bfc1508d (kx 2023-03-24 03:55:33 +0300  51) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  52)   if( !shell ) shell = "/bin/sh";
bfc1508d (kx 2023-03-24 03:55:33 +0300  53) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  54)   argv[0] = (char *) shell;
bfc1508d (kx 2023-03-24 03:55:33 +0300  55)   argv[1] = (char *) "-c";
bfc1508d (kx 2023-03-24 03:55:33 +0300  56)   argv[2] = (char *) cmd;
bfc1508d (kx 2023-03-24 03:55:33 +0300  57)   argv[3] = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300  58) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  59)   execv( shell, argv );
bfc1508d (kx 2023-03-24 03:55:33 +0300  60) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  61)   /******************************************
bfc1508d (kx 2023-03-24 03:55:33 +0300  62)     xexec() is called by child process, and
bfc1508d (kx 2023-03-24 03:55:33 +0300  63)     here child process faced to FATAL error:
bfc1508d (kx 2023-03-24 03:55:33 +0300  64)    */
bfc1508d (kx 2023-03-24 03:55:33 +0300  65)   system_fatal( "Cannot exec '%s'\n", cmd );
bfc1508d (kx 2023-03-24 03:55:33 +0300  66) }
bfc1508d (kx 2023-03-24 03:55:33 +0300  67) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  68) static pid_t xfork( void )
bfc1508d (kx 2023-03-24 03:55:33 +0300  69) {
bfc1508d (kx 2023-03-24 03:55:33 +0300  70)   pid_t p = fork();
bfc1508d (kx 2023-03-24 03:55:33 +0300  71) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  72)   if( p == (pid_t) -1 )
bfc1508d (kx 2023-03-24 03:55:33 +0300  73)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300  74)     system_fatal( "Cannot %s: %s\n", "fork()", strerror( errno ) );
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)   return p;
bfc1508d (kx 2023-03-24 03:55:33 +0300  78) }
bfc1508d (kx 2023-03-24 03:55:33 +0300  79) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  80) pid_t sys_exec_command( struct strbuf *sb, const char *cmd )
bfc1508d (kx 2023-03-24 03:55:33 +0300  81) {
bfc1508d (kx 2023-03-24 03:55:33 +0300  82)   int pipe_fh[2];
bfc1508d (kx 2023-03-24 03:55:33 +0300  83) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  84)   pid_t pid = -1;
bfc1508d (kx 2023-03-24 03:55:33 +0300  85) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  86)   if( sb )
bfc1508d (kx 2023-03-24 03:55:33 +0300  87)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300  88)     if( pipe(pipe_fh ) == -1 )
bfc1508d (kx 2023-03-24 03:55:33 +0300  89)     {
bfc1508d (kx 2023-03-24 03:55:33 +0300  90)       system_fatal( "Cannot create pipe: %s\n", strerror( errno ) );
bfc1508d (kx 2023-03-24 03:55:33 +0300  91)     }
bfc1508d (kx 2023-03-24 03:55:33 +0300  92)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300  93) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  94)   pid = xfork();
bfc1508d (kx 2023-03-24 03:55:33 +0300  95) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  96)   if( pid != 0 )
bfc1508d (kx 2023-03-24 03:55:33 +0300  97)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300  98)     if( sb )
bfc1508d (kx 2023-03-24 03:55:33 +0300  99)     {
bfc1508d (kx 2023-03-24 03:55:33 +0300 100)       ssize_t ret;
bfc1508d (kx 2023-03-24 03:55:33 +0300 101) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 102)       close(pipe_fh[1]);
bfc1508d (kx 2023-03-24 03:55:33 +0300 103)       ret = strbuf_read( sb, pipe_fh[0], 1024 );
bfc1508d (kx 2023-03-24 03:55:33 +0300 104)       if( ret < 0 )
bfc1508d (kx 2023-03-24 03:55:33 +0300 105)         system_fatal( "Cannot read pipe: %s\n", strerror( errno ) );
bfc1508d (kx 2023-03-24 03:55:33 +0300 106)       close(pipe_fh[0]);
bfc1508d (kx 2023-03-24 03:55:33 +0300 107)     }
bfc1508d (kx 2023-03-24 03:55:33 +0300 108) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 109)     return pid;
bfc1508d (kx 2023-03-24 03:55:33 +0300 110)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 111) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 112)   if( sb )
bfc1508d (kx 2023-03-24 03:55:33 +0300 113)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 114)     dup2(pipe_fh[1], STDOUT_FILENO);
bfc1508d (kx 2023-03-24 03:55:33 +0300 115)     close(pipe_fh[1]);
bfc1508d (kx 2023-03-24 03:55:33 +0300 116)     close(pipe_fh[0]);
bfc1508d (kx 2023-03-24 03:55:33 +0300 117)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 118) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 119)   xexec( cmd );
bfc1508d (kx 2023-03-24 03:55:33 +0300 120)   return pid; /* only to avoid compilaton warning */
bfc1508d (kx 2023-03-24 03:55:33 +0300 121) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 122) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 123) /*****************************************************************
bfc1508d (kx 2023-03-24 03:55:33 +0300 124)   sys_wait_command() - Wait for pid.
bfc1508d (kx 2023-03-24 03:55:33 +0300 125) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 126)   Return values:
bfc1508d (kx 2023-03-24 03:55:33 +0300 127)   -------------
bfc1508d (kx 2023-03-24 03:55:33 +0300 128)      0  - SUCCESS
bfc1508d (kx 2023-03-24 03:55:33 +0300 129)    >=1  - status returned by child process
bfc1508d (kx 2023-03-24 03:55:33 +0300 130)     -1  - Child terminated on signal
bfc1508d (kx 2023-03-24 03:55:33 +0300 131)     -2  - Child terminated on unknown reason
bfc1508d (kx 2023-03-24 03:55:33 +0300 132)     -3  - Cannot waitpid: waitpid() retusrs -1
bfc1508d (kx 2023-03-24 03:55:33 +0300 133) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 134)      Error message with SIZE length saved into *ERRMSG buffer.
bfc1508d (kx 2023-03-24 03:55:33 +0300 135)  *****************************************************************/
bfc1508d (kx 2023-03-24 03:55:33 +0300 136) int sys_wait_command( pid_t pid, struct strbuf *errmsg )
bfc1508d (kx 2023-03-24 03:55:33 +0300 137) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 138)   int status;
bfc1508d (kx 2023-03-24 03:55:33 +0300 139) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 140)   if( pid < 0 ) return (pid_t) -1;
bfc1508d (kx 2023-03-24 03:55:33 +0300 141) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 142)   while( waitpid( pid, &status, 0 ) == -1 )
bfc1508d (kx 2023-03-24 03:55:33 +0300 143)     if( errno != EINTR )
bfc1508d (kx 2023-03-24 03:55:33 +0300 144)     {
bfc1508d (kx 2023-03-24 03:55:33 +0300 145)       if( errmsg ) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 146)         strbuf_addf( errmsg, "PID %lu: Cannot %s", (unsigned long)pid, "waitpid" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 147)       }
bfc1508d (kx 2023-03-24 03:55:33 +0300 148)       return (int) -3;
bfc1508d (kx 2023-03-24 03:55:33 +0300 149)     }
bfc1508d (kx 2023-03-24 03:55:33 +0300 150) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 151)   if( WIFEXITED( status ) )
bfc1508d (kx 2023-03-24 03:55:33 +0300 152)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 153)     if( WEXITSTATUS (status) )
bfc1508d (kx 2023-03-24 03:55:33 +0300 154)     {
bfc1508d (kx 2023-03-24 03:55:33 +0300 155)       if( errmsg ) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 156)         strbuf_addf( errmsg, "PID %lu: Child returned status %d", (unsigned long)pid, WEXITSTATUS( status ) );
bfc1508d (kx 2023-03-24 03:55:33 +0300 157)       }
bfc1508d (kx 2023-03-24 03:55:33 +0300 158)       return (int) WEXITSTATUS( status );
bfc1508d (kx 2023-03-24 03:55:33 +0300 159)     }
bfc1508d (kx 2023-03-24 03:55:33 +0300 160)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 161)   else if( WIFSIGNALED( status ) )
bfc1508d (kx 2023-03-24 03:55:33 +0300 162)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 163)     if( errmsg ) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 164)       strbuf_addf( errmsg, "PID %lu: Child terminated on signal %d", (unsigned long)pid, WTERMSIG( status ) );
bfc1508d (kx 2023-03-24 03:55:33 +0300 165)     }
bfc1508d (kx 2023-03-24 03:55:33 +0300 166)     return (int) -1;
bfc1508d (kx 2023-03-24 03:55:33 +0300 167)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 168)   else
bfc1508d (kx 2023-03-24 03:55:33 +0300 169)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 170)     if( errmsg ) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 171)       strbuf_addf( errmsg, "PID %lu: Child terminated on unknown reason", (unsigned long)pid );
bfc1508d (kx 2023-03-24 03:55:33 +0300 172)     }
bfc1508d (kx 2023-03-24 03:55:33 +0300 173)     return (int) -2;
bfc1508d (kx 2023-03-24 03:55:33 +0300 174)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 175) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 176)   return 0;
bfc1508d (kx 2023-03-24 03:55:33 +0300 177) }