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) #include <stdint.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  11) #include <dirent.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  12) #include <sys/stat.h> /* chmod(2)    */
bfc1508d (kx 2023-03-24 03:55:33 +0300  13) #include <sys/file.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  14) #include <sys/mman.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  15) #include <fcntl.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  16) #include <limits.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  17) #include <string.h>   /* strdup(3)   */
bfc1508d (kx 2023-03-24 03:55:33 +0300  18) #include <libgen.h>   /* basename(3) */
bfc1508d (kx 2023-03-24 03:55:33 +0300  19) #include <ctype.h>    /* tolower(3)  */
bfc1508d (kx 2023-03-24 03:55:33 +0300  20) #include <errno.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  21) #include <time.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  22) #include <sys/time.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  23) #include <pwd.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  24) #include <grp.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  25) #include <stdarg.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  26) #include <unistd.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  27) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  28) #include <defs.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  29) #include <cscm/bcf.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  30) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  31) #include <dlist.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  32) #include <strbuf.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  33) #include <repolist.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  34) #include <wrapper.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300  35) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  36) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  37) #define RLIST_ERRMSG_SIZE 4096
bfc1508d (kx 2023-03-24 03:55:33 +0300  38) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  39) void rlist_error( const char *fmt, ... )
bfc1508d (kx 2023-03-24 03:55:33 +0300  40) {
bfc1508d (kx 2023-03-24 03:55:33 +0300  41)   va_list arg_ptr;
bfc1508d (kx 2023-03-24 03:55:33 +0300  42)   char  buf[RLIST_ERRMSG_SIZE];
bfc1508d (kx 2023-03-24 03:55:33 +0300  43)   char  msg[RLIST_ERRMSG_SIZE];
bfc1508d (kx 2023-03-24 03:55:33 +0300  44)   char *format = "%s: %s\n";
bfc1508d (kx 2023-03-24 03:55:33 +0300  45) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  46)   va_start( arg_ptr, fmt );
bfc1508d (kx 2023-03-24 03:55:33 +0300  47) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  48)   vsnprintf( msg, RLIST_ERRMSG_SIZE, (const void *)fmt, arg_ptr );
bfc1508d (kx 2023-03-24 03:55:33 +0300  49) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  50)   va_end( arg_ptr ); /* Reset variable arguments. */
bfc1508d (kx 2023-03-24 03:55:33 +0300  51) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  52)   snprintf( buf, RLIST_ERRMSG_SIZE, format, "rlist", msg );
bfc1508d (kx 2023-03-24 03:55:33 +0300  53) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  54)   (void)write( STDERR_FILENO, buf, strlen( buf ) );
bfc1508d (kx 2023-03-24 03:55:33 +0300  55) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  56)   exit( 1 );
bfc1508d (kx 2023-03-24 03:55:33 +0300  57) }
bfc1508d (kx 2023-03-24 03:55:33 +0300  58) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  59) rlist_errfunc rlist_fatal = rlist_error;
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) struct dlist *config = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300  63) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  64) static void *bcf = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300  65) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  66) static size_t read_bcf( void )
bfc1508d (kx 2023-03-24 03:55:33 +0300  67) {
bfc1508d (kx 2023-03-24 03:55:33 +0300  68)   int fd;
bfc1508d (kx 2023-03-24 03:55:33 +0300  69)   struct stat st;
bfc1508d (kx 2023-03-24 03:55:33 +0300  70)   void *addr;
bfc1508d (kx 2023-03-24 03:55:33 +0300  71) 
bfc1508d (kx 2023-03-24 03:55:33 +0300  72)   fd = shm_open( CSVN_SHM_BCF, O_RDONLY, S_IRUSR | S_IWUSR );
bfc1508d (kx 2023-03-24 03:55:33 +0300  73)   if( fd == -1 )
bfc1508d (kx 2023-03-24 03:55:33 +0300  74)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300  75)     rlist_fatal( "Canot open SHM/%s data", "csvn.bcf" );
bfc1508d (kx 2023-03-24 03:55:33 +0300  76)     return 0;
bfc1508d (kx 2023-03-24 03:55:33 +0300  77)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300  78)   if( !fstat( fd, (struct stat *)&st ) )
bfc1508d (kx 2023-03-24 03:55:33 +0300  79)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300  80)     addr = mmap( NULL, (size_t)st.st_size, PROT_READ, MAP_SHARED, fd, 0 );
bfc1508d (kx 2023-03-24 03:55:33 +0300  81)     if( addr != MAP_FAILED )
bfc1508d (kx 2023-03-24 03:55:33 +0300  82)     {
bfc1508d (kx 2023-03-24 03:55:33 +0300  83)       bcf = malloc( (size_t)st.st_size );
bfc1508d (kx 2023-03-24 03:55:33 +0300  84)       if( !bcf )
bfc1508d (kx 2023-03-24 03:55:33 +0300  85)       {
bfc1508d (kx 2023-03-24 03:55:33 +0300  86)         (void)munmap( addr, (size_t)st.st_size );
bfc1508d (kx 2023-03-24 03:55:33 +0300  87)         rlist_fatal( "Canot allocate memory for SHM/%s data", "csvn.bcf" );
bfc1508d (kx 2023-03-24 03:55:33 +0300  88)         return 0;
bfc1508d (kx 2023-03-24 03:55:33 +0300  89)       }
bfc1508d (kx 2023-03-24 03:55:33 +0300  90)       memcpy( bcf, addr, (size_t)st.st_size );
bfc1508d (kx 2023-03-24 03:55:33 +0300  91)       (void)munmap( addr, (size_t)st.st_size );
bfc1508d (kx 2023-03-24 03:55:33 +0300  92)       return (size_t)st.st_size;
bfc1508d (kx 2023-03-24 03:55:33 +0300  93)     }
bfc1508d (kx 2023-03-24 03:55:33 +0300  94)     else
bfc1508d (kx 2023-03-24 03:55:33 +0300  95)     {
bfc1508d (kx 2023-03-24 03:55:33 +0300  96)       rlist_fatal( "Canot mmap SHM/%s data", "csvn.bcf" );
bfc1508d (kx 2023-03-24 03:55:33 +0300  97)       return 0;
bfc1508d (kx 2023-03-24 03:55:33 +0300  98)     }
bfc1508d (kx 2023-03-24 03:55:33 +0300  99)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 100)   else
bfc1508d (kx 2023-03-24 03:55:33 +0300 101)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 102)     rlist_fatal( "Canot stat SHM/%s data", "csvn.bcf" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 103)     return 0;
bfc1508d (kx 2023-03-24 03:55:33 +0300 104)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 105) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 106) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 107) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 108) static void check_bcf_ident( const void *bf, size_t size )
bfc1508d (kx 2023-03-24 03:55:33 +0300 109) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 110)   Bcf32_fhdr *fhdr = (Bcf32_fhdr *)bf;
bfc1508d (kx 2023-03-24 03:55:33 +0300 111) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 112)   if( !fhdr )
bfc1508d (kx 2023-03-24 03:55:33 +0300 113)     rlist_fatal( "Invalid address of SHM/%s data", "csvn.bcf" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 114) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 115)   if( (size_t)fhdr->b_fsize != size )
bfc1508d (kx 2023-03-24 03:55:33 +0300 116)     rlist_fatal( "Binary Config SHM/%s: invalid size", "csvn.bcf" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 117)   if( memcmp( fhdr->b_ident, BCFMAG, (size_t)SZBCFMAG ) )
bfc1508d (kx 2023-03-24 03:55:33 +0300 118)     rlist_fatal( "Binary Config SHM/%s: invalid MAGIC number", "csvn.bcf" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 119)   if( fhdr->b_ident[BI_CLASS] != BCF_CLASS_32 )
bfc1508d (kx 2023-03-24 03:55:33 +0300 120)     rlist_fatal( "Binary Config SHM/%s: invalid objects class", "csvn.bcf" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 121) #if __BYTE_ORDER == __LITTLE_ENDIAN
bfc1508d (kx 2023-03-24 03:55:33 +0300 122)   if( fhdr->b_ident[BI_DATA] != BCF_DATA_LSB )
bfc1508d (kx 2023-03-24 03:55:33 +0300 123)     rlist_fatal( "Binary Config SHM/%s: invalid byte-order", "csvn.bcf" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 124) #else
bfc1508d (kx 2023-03-24 03:55:33 +0300 125)   if( fhdr->b_ident[BI_DATA] != BCF_DATA_MSB )
bfc1508d (kx 2023-03-24 03:55:33 +0300 126)     rlist_fatal( "Binary Config SHM/%s: invalid byte-order", "csvn.bcf" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 127) #endif
bfc1508d (kx 2023-03-24 03:55:33 +0300 128)   if( fhdr->b_ident[BI_VERSION] != BV_CURRENT )
bfc1508d (kx 2023-03-24 03:55:33 +0300 129)     rlist_fatal( "Binary Config SHM/%s: invalid version", "csvn.bcf" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 130) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 131) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 132) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 133) /***************************************************************
bfc1508d (kx 2023-03-24 03:55:33 +0300 134)   Print config file functions:
bfc1508d (kx 2023-03-24 03:55:33 +0300 135)  */
bfc1508d (kx 2023-03-24 03:55:33 +0300 136) static void __print_global_variable( void *data, void *user_data )
bfc1508d (kx 2023-03-24 03:55:33 +0300 137) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 138)   struct variable *variable = (struct variable *)data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 139)   struct strbuf   *sb   = (struct strbuf *)user_data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 140) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 141)   if( !variable || !sb ) return;
bfc1508d (kx 2023-03-24 03:55:33 +0300 142) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 143)   switch( variable->type )
bfc1508d (kx 2023-03-24 03:55:33 +0300 144)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 145)     case DT_NUMERICAL:
bfc1508d (kx 2023-03-24 03:55:33 +0300 146)       strbuf_addf( sb, "  %s = %d;\n", variable->name, variable->_v.val );
bfc1508d (kx 2023-03-24 03:55:33 +0300 147)       break;
bfc1508d (kx 2023-03-24 03:55:33 +0300 148)     case DT_PATH:
bfc1508d (kx 2023-03-24 03:55:33 +0300 149)       strbuf_addf( sb, "  %s = '%s';\n", variable->name, variable->_v.vptr );
bfc1508d (kx 2023-03-24 03:55:33 +0300 150)       break;
bfc1508d (kx 2023-03-24 03:55:33 +0300 151)     case DT_STRING:
bfc1508d (kx 2023-03-24 03:55:33 +0300 152)       strbuf_addf( sb, "  %s = \"%s\";\n", variable->name, variable->_v.vptr );
bfc1508d (kx 2023-03-24 03:55:33 +0300 153)       break;
bfc1508d (kx 2023-03-24 03:55:33 +0300 154)     default:
bfc1508d (kx 2023-03-24 03:55:33 +0300 155)       break;
bfc1508d (kx 2023-03-24 03:55:33 +0300 156)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 157) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 158) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 159) static void print_global_variables( struct strbuf *sb, struct dlist *list )
bfc1508d (kx 2023-03-24 03:55:33 +0300 160) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 161)   if( list ) { dlist_foreach( list, __print_global_variable, (void *)sb ); }
bfc1508d (kx 2023-03-24 03:55:33 +0300 162) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 163) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 164) static void __print_repo_variable( void *data, void *user_data )
bfc1508d (kx 2023-03-24 03:55:33 +0300 165) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 166)   struct variable *variable = (struct variable *)data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 167)   struct strbuf   *sb   = (struct strbuf *)user_data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 168) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 169)   if( !variable || !sb ) return;
bfc1508d (kx 2023-03-24 03:55:33 +0300 170) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 171)   switch( variable->type )
bfc1508d (kx 2023-03-24 03:55:33 +0300 172)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 173)     case DT_NUMERICAL:
bfc1508d (kx 2023-03-24 03:55:33 +0300 174)       strbuf_addf( sb, "    %s = %d;\n", variable->name, variable->_v.val );
bfc1508d (kx 2023-03-24 03:55:33 +0300 175)       break;
bfc1508d (kx 2023-03-24 03:55:33 +0300 176)     case DT_PATH:
bfc1508d (kx 2023-03-24 03:55:33 +0300 177)       strbuf_addf( sb, "    %s = '%s';\n", variable->name, variable->_v.vptr );
bfc1508d (kx 2023-03-24 03:55:33 +0300 178)       break;
bfc1508d (kx 2023-03-24 03:55:33 +0300 179)     case DT_STRING:
bfc1508d (kx 2023-03-24 03:55:33 +0300 180)       strbuf_addf( sb, "    %s = \"%s\";\n", variable->name, variable->_v.vptr );
bfc1508d (kx 2023-03-24 03:55:33 +0300 181)       break;
bfc1508d (kx 2023-03-24 03:55:33 +0300 182)     default:
bfc1508d (kx 2023-03-24 03:55:33 +0300 183)       break;
bfc1508d (kx 2023-03-24 03:55:33 +0300 184)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 185) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 186) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 187) static void print_repo_variables( struct strbuf *sb, struct dlist *list )
bfc1508d (kx 2023-03-24 03:55:33 +0300 188) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 189)   if( list ) { dlist_foreach( list, __print_repo_variable, (void *)sb ); }
bfc1508d (kx 2023-03-24 03:55:33 +0300 190) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 191) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 192) static void __print_repo( void *data, void *user_data )
bfc1508d (kx 2023-03-24 03:55:33 +0300 193) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 194)   struct repo   *repo = (struct repo *)data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 195)   struct strbuf *sb   = (struct strbuf *)user_data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 196) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 197)   if( !repo || !sb ) return;
bfc1508d (kx 2023-03-24 03:55:33 +0300 198) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 199)   strbuf_addf( sb, "  repo '%s' {\n", repo->path );
bfc1508d (kx 2023-03-24 03:55:33 +0300 200)   if( repo->list )
bfc1508d (kx 2023-03-24 03:55:33 +0300 201)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 202)     print_repo_variables( sb, repo->list );
bfc1508d (kx 2023-03-24 03:55:33 +0300 203)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 204)   strbuf_addf( sb, "  }\n\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 205) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 206) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 207) static void print_repos( struct strbuf *sb, struct dlist *list )
bfc1508d (kx 2023-03-24 03:55:33 +0300 208) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 209)   if( list ) { dlist_foreach( list, __print_repo, (void *)sb ); }
bfc1508d (kx 2023-03-24 03:55:33 +0300 210) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 211) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 212) static void __print_section( void *data, void *user_data )
bfc1508d (kx 2023-03-24 03:55:33 +0300 213) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 214)   struct section *section = (struct section *)data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 215)   struct strbuf  *sb      = (struct strbuf *)user_data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 216) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 217)   if( !section || !sb ) return;
bfc1508d (kx 2023-03-24 03:55:33 +0300 218) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 219)   if( section->list )
bfc1508d (kx 2023-03-24 03:55:33 +0300 220)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 221)     if( section->type == ST_REPOS )
bfc1508d (kx 2023-03-24 03:55:33 +0300 222)     {
bfc1508d (kx 2023-03-24 03:55:33 +0300 223)       strbuf_addf( sb, "section \"%s\" {\n\n", section->name );
bfc1508d (kx 2023-03-24 03:55:33 +0300 224)       print_repos( sb, section->list );
bfc1508d (kx 2023-03-24 03:55:33 +0300 225)       strbuf_addf( sb, "}\n\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 226)     }
bfc1508d (kx 2023-03-24 03:55:33 +0300 227)     else if( section->type == ST_GLOBAL )
bfc1508d (kx 2023-03-24 03:55:33 +0300 228)     {
bfc1508d (kx 2023-03-24 03:55:33 +0300 229)       strbuf_addf( sb, "section \".global\" {\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 230)       print_global_variables( sb, section->list );
bfc1508d (kx 2023-03-24 03:55:33 +0300 231)       strbuf_addf( sb, "}\n\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 232)     }
bfc1508d (kx 2023-03-24 03:55:33 +0300 233)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 234) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 235) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 236) void print_config( struct strbuf *sb, struct dlist *list )
bfc1508d (kx 2023-03-24 03:55:33 +0300 237) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 238)   strbuf_addf( sb, "<pre><code class='language-C'>\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 239)   strbuf_addf( sb, "/*******************************************************\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 240)   strbuf_addf( sb, "  Global variables are propagate into repo sections but\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 241)   strbuf_addf( sb, "  their values overrides by correspond repo variables.\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 242)   strbuf_addf( sb, " */\n\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 243)   if( list ) { dlist_foreach( list, __print_section, (void *)sb ); }
bfc1508d (kx 2023-03-24 03:55:33 +0300 244)   strbuf_addf( sb, "</code></pre>\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 245) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 246) /*
bfc1508d (kx 2023-03-24 03:55:33 +0300 247)   End of print config file functions.
bfc1508d (kx 2023-03-24 03:55:33 +0300 248)  ***************************************************************/
bfc1508d (kx 2023-03-24 03:55:33 +0300 249) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 250) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 251) /**************************
bfc1508d (kx 2023-03-24 03:55:33 +0300 252)   lookup variable in repo:
bfc1508d (kx 2023-03-24 03:55:33 +0300 253)  */
bfc1508d (kx 2023-03-24 03:55:33 +0300 254) static int __compare_variables_by_name( const void *a, const void *b )
bfc1508d (kx 2023-03-24 03:55:33 +0300 255) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 256)   struct variable *va = (struct variable *)a;
bfc1508d (kx 2023-03-24 03:55:33 +0300 257)   struct variable *vb = (struct variable *)b;
bfc1508d (kx 2023-03-24 03:55:33 +0300 258) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 259)   if( !va || !vb ) return -1;
bfc1508d (kx 2023-03-24 03:55:33 +0300 260) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 261)   return strcmp( (const char *)va->name, (const char *)vb->name );
bfc1508d (kx 2023-03-24 03:55:33 +0300 262) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 263) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 264) struct variable *lookup( struct repo *repo, struct variable *variable )
bfc1508d (kx 2023-03-24 03:55:33 +0300 265) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 266)   struct dlist *found = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 267) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 268)   if( !repo || !repo->list ) return NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 269) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 270)   found = dlist_find_data( repo->list, __compare_variables_by_name, (const void *)variable );
bfc1508d (kx 2023-03-24 03:55:33 +0300 271)   if( found )
bfc1508d (kx 2023-03-24 03:55:33 +0300 272)     return (struct variable *)(found->data);
bfc1508d (kx 2023-03-24 03:55:33 +0300 273)   return NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 274) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 275) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 276) struct variable *lookup_global( struct section *section, struct variable *variable )
bfc1508d (kx 2023-03-24 03:55:33 +0300 277) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 278)   struct dlist *found = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 279) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 280)   if( !section || !section->list ) return NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 281) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 282)   found = dlist_find_data( section->list, __compare_variables_by_name, (const void *)variable );
bfc1508d (kx 2023-03-24 03:55:33 +0300 283)   if( found )
bfc1508d (kx 2023-03-24 03:55:33 +0300 284)     return (struct variable *)(found->data);
bfc1508d (kx 2023-03-24 03:55:33 +0300 285)   return NULL;
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) /**************
bfc1508d (kx 2023-03-24 03:55:33 +0300 289)   lookup repo:
bfc1508d (kx 2023-03-24 03:55:33 +0300 290)  */
bfc1508d (kx 2023-03-24 03:55:33 +0300 291) struct repo *lookup_repo( struct dlist *config, const char *path )
bfc1508d (kx 2023-03-24 03:55:33 +0300 292) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 293)   struct dlist *list = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 294) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 295)   if( !config || !path ) return NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 296) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 297)   list = config;
bfc1508d (kx 2023-03-24 03:55:33 +0300 298)   while( list )
bfc1508d (kx 2023-03-24 03:55:33 +0300 299)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 300)     struct section *section = (struct section *)list->data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 301) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 302)     if( section->type == ST_REPOS )
bfc1508d (kx 2023-03-24 03:55:33 +0300 303)     {
bfc1508d (kx 2023-03-24 03:55:33 +0300 304)       struct dlist *rlist = section->list;
bfc1508d (kx 2023-03-24 03:55:33 +0300 305)       while( rlist )
bfc1508d (kx 2023-03-24 03:55:33 +0300 306)       {
bfc1508d (kx 2023-03-24 03:55:33 +0300 307)         struct repo *repo = (struct repo *)rlist->data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 308)         if( !strcmp( (const char *)repo->path, path ) )
bfc1508d (kx 2023-03-24 03:55:33 +0300 309)           return repo;
bfc1508d (kx 2023-03-24 03:55:33 +0300 310)         rlist = dlist_next( rlist );
bfc1508d (kx 2023-03-24 03:55:33 +0300 311)       }
bfc1508d (kx 2023-03-24 03:55:33 +0300 312)     }
bfc1508d (kx 2023-03-24 03:55:33 +0300 313)     list = dlist_next( list );
bfc1508d (kx 2023-03-24 03:55:33 +0300 314)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 315) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 316)   return NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 317) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 318) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 319) /*****************
bfc1508d (kx 2023-03-24 03:55:33 +0300 320)   lookup section:
bfc1508d (kx 2023-03-24 03:55:33 +0300 321)  */
bfc1508d (kx 2023-03-24 03:55:33 +0300 322) struct section *lookup_section( struct dlist *config, const char *name )
bfc1508d (kx 2023-03-24 03:55:33 +0300 323) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 324)   struct dlist *list = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 325) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 326)   if( !config || !name ) return NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 327) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 328)   list = config;
bfc1508d (kx 2023-03-24 03:55:33 +0300 329)   while( list )
bfc1508d (kx 2023-03-24 03:55:33 +0300 330)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 331)     struct section *section = (struct section *)list->data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 332) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 333)     if( section && section->type == ST_REPOS && !strcmp( (const char *)section->name, name ) )
bfc1508d (kx 2023-03-24 03:55:33 +0300 334)         return section;
bfc1508d (kx 2023-03-24 03:55:33 +0300 335) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 336)     list = dlist_next( list );
bfc1508d (kx 2023-03-24 03:55:33 +0300 337)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 338) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 339)   return NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 340) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 341) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 342) /************************
bfc1508d (kx 2023-03-24 03:55:33 +0300 343)   lookup global section:
bfc1508d (kx 2023-03-24 03:55:33 +0300 344)  */
bfc1508d (kx 2023-03-24 03:55:33 +0300 345) struct section *lookup_global_section( struct dlist *config )
bfc1508d (kx 2023-03-24 03:55:33 +0300 346) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 347)   struct dlist *list = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 348) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 349)   if( !config ) return NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 350) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 351)   list = config;
bfc1508d (kx 2023-03-24 03:55:33 +0300 352)   while( list )
bfc1508d (kx 2023-03-24 03:55:33 +0300 353)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 354)     struct section *section = (struct section *)list->data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 355) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 356)     if( section && section->type == ST_GLOBAL )
bfc1508d (kx 2023-03-24 03:55:33 +0300 357)         return section;
bfc1508d (kx 2023-03-24 03:55:33 +0300 358) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 359)     list = dlist_next( list );
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)   return NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 363) }
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)   repolist length:
bfc1508d (kx 2023-03-24 03:55:33 +0300 367)  */
bfc1508d (kx 2023-03-24 03:55:33 +0300 368) int repolist_length( struct dlist *config )
bfc1508d (kx 2023-03-24 03:55:33 +0300 369) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 370)   struct dlist *list = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 371)   int length = 0;
bfc1508d (kx 2023-03-24 03:55:33 +0300 372) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 373)   if( !config ) return length;
bfc1508d (kx 2023-03-24 03:55:33 +0300 374) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 375)   list = config;
bfc1508d (kx 2023-03-24 03:55:33 +0300 376)   while( list )
bfc1508d (kx 2023-03-24 03:55:33 +0300 377)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 378)     struct section *section = (struct section *)list->data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 379) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 380)     if( section->type == ST_REPOS )
bfc1508d (kx 2023-03-24 03:55:33 +0300 381)     {
bfc1508d (kx 2023-03-24 03:55:33 +0300 382)       struct dlist *rlist = section->list;
bfc1508d (kx 2023-03-24 03:55:33 +0300 383)       while( rlist )
bfc1508d (kx 2023-03-24 03:55:33 +0300 384)       {
bfc1508d (kx 2023-03-24 03:55:33 +0300 385)         ++length;
bfc1508d (kx 2023-03-24 03:55:33 +0300 386)         rlist = dlist_next( rlist );
bfc1508d (kx 2023-03-24 03:55:33 +0300 387)       }
bfc1508d (kx 2023-03-24 03:55:33 +0300 388)     }
bfc1508d (kx 2023-03-24 03:55:33 +0300 389)     list = dlist_next( list );
bfc1508d (kx 2023-03-24 03:55:33 +0300 390)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 391) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 392)   return length;
bfc1508d (kx 2023-03-24 03:55:33 +0300 393) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 394) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 395) /***************
bfc1508d (kx 2023-03-24 03:55:33 +0300 396)   repolist nth:
bfc1508d (kx 2023-03-24 03:55:33 +0300 397)  */
bfc1508d (kx 2023-03-24 03:55:33 +0300 398) struct repo *repolist_nth( struct dlist *config, int n )
bfc1508d (kx 2023-03-24 03:55:33 +0300 399) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 400)   struct dlist *list = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 401)   int length = 0;
bfc1508d (kx 2023-03-24 03:55:33 +0300 402) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 403)   if( !config || n < 0 ) return NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 404) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 405)   list = config;
bfc1508d (kx 2023-03-24 03:55:33 +0300 406)   while( list )
bfc1508d (kx 2023-03-24 03:55:33 +0300 407)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 408)     struct section *section = (struct section *)list->data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 409) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 410)     if( section->type == ST_REPOS )
bfc1508d (kx 2023-03-24 03:55:33 +0300 411)     {
bfc1508d (kx 2023-03-24 03:55:33 +0300 412)       struct dlist *rlist = section->list;
bfc1508d (kx 2023-03-24 03:55:33 +0300 413)       while( rlist )
bfc1508d (kx 2023-03-24 03:55:33 +0300 414)       {
bfc1508d (kx 2023-03-24 03:55:33 +0300 415)         if( length == n )
bfc1508d (kx 2023-03-24 03:55:33 +0300 416)         {
bfc1508d (kx 2023-03-24 03:55:33 +0300 417)           struct repo *repo = (struct repo *)rlist->data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 418)           return repo;
bfc1508d (kx 2023-03-24 03:55:33 +0300 419)         }
bfc1508d (kx 2023-03-24 03:55:33 +0300 420)         ++length;
bfc1508d (kx 2023-03-24 03:55:33 +0300 421)         rlist = dlist_next( rlist );
bfc1508d (kx 2023-03-24 03:55:33 +0300 422)       }
bfc1508d (kx 2023-03-24 03:55:33 +0300 423)     }
bfc1508d (kx 2023-03-24 03:55:33 +0300 424)     list = dlist_next( list );
bfc1508d (kx 2023-03-24 03:55:33 +0300 425)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 426) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 427)   return NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 428) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 429) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 430) /**************************
bfc1508d (kx 2023-03-24 03:55:33 +0300 431)   repo position in config:
bfc1508d (kx 2023-03-24 03:55:33 +0300 432)  */
bfc1508d (kx 2023-03-24 03:55:33 +0300 433) int repo_position( struct dlist *config, struct repo *repo )
bfc1508d (kx 2023-03-24 03:55:33 +0300 434) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 435)   struct dlist *list = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 436)   int position = -1;
bfc1508d (kx 2023-03-24 03:55:33 +0300 437) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 438)   if( !config || !repo ) return position;
bfc1508d (kx 2023-03-24 03:55:33 +0300 439) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 440)   position = 0;
bfc1508d (kx 2023-03-24 03:55:33 +0300 441) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 442)   list = config;
bfc1508d (kx 2023-03-24 03:55:33 +0300 443)   while( list )
bfc1508d (kx 2023-03-24 03:55:33 +0300 444)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 445)     struct section *section = (struct section *)list->data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 446) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 447)     if( section->type == ST_REPOS )
bfc1508d (kx 2023-03-24 03:55:33 +0300 448)     {
bfc1508d (kx 2023-03-24 03:55:33 +0300 449)       struct dlist *rlist = section->list;
bfc1508d (kx 2023-03-24 03:55:33 +0300 450)       while( rlist )
bfc1508d (kx 2023-03-24 03:55:33 +0300 451)       {
bfc1508d (kx 2023-03-24 03:55:33 +0300 452)         if( (struct repo *)rlist->data == repo )
bfc1508d (kx 2023-03-24 03:55:33 +0300 453)         {
bfc1508d (kx 2023-03-24 03:55:33 +0300 454)           return position;
bfc1508d (kx 2023-03-24 03:55:33 +0300 455)         }
bfc1508d (kx 2023-03-24 03:55:33 +0300 456)         ++position;
bfc1508d (kx 2023-03-24 03:55:33 +0300 457)         rlist = dlist_next( rlist );
bfc1508d (kx 2023-03-24 03:55:33 +0300 458)       }
bfc1508d (kx 2023-03-24 03:55:33 +0300 459)     }
bfc1508d (kx 2023-03-24 03:55:33 +0300 460)     list = dlist_next( list );
bfc1508d (kx 2023-03-24 03:55:33 +0300 461)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 462) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 463)   return -1;
bfc1508d (kx 2023-03-24 03:55:33 +0300 464) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 465) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 466) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 467) /**************************************
bfc1508d (kx 2023-03-24 03:55:33 +0300 468)   parent section node of repolist nth:
bfc1508d (kx 2023-03-24 03:55:33 +0300 469)  */
bfc1508d (kx 2023-03-24 03:55:33 +0300 470) struct dlist *parent_section_node_repolist_nth( struct dlist *config, int n )
bfc1508d (kx 2023-03-24 03:55:33 +0300 471) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 472)   struct dlist *list = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 473)   int length = 0;
bfc1508d (kx 2023-03-24 03:55:33 +0300 474) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 475)   if( !config || n < 0 ) return NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 476) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 477)   list = config;
bfc1508d (kx 2023-03-24 03:55:33 +0300 478)   while( list )
bfc1508d (kx 2023-03-24 03:55:33 +0300 479)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 480)     struct section *section = (struct section *)list->data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 481) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 482)     if( section->type == ST_REPOS )
bfc1508d (kx 2023-03-24 03:55:33 +0300 483)     {
bfc1508d (kx 2023-03-24 03:55:33 +0300 484)       struct dlist *rlist = section->list;
bfc1508d (kx 2023-03-24 03:55:33 +0300 485)       while( rlist )
bfc1508d (kx 2023-03-24 03:55:33 +0300 486)       {
bfc1508d (kx 2023-03-24 03:55:33 +0300 487)         if( length == n )
bfc1508d (kx 2023-03-24 03:55:33 +0300 488)         {
bfc1508d (kx 2023-03-24 03:55:33 +0300 489)           return list;
bfc1508d (kx 2023-03-24 03:55:33 +0300 490)         }
bfc1508d (kx 2023-03-24 03:55:33 +0300 491)         ++length;
bfc1508d (kx 2023-03-24 03:55:33 +0300 492)         rlist = dlist_next( rlist );
bfc1508d (kx 2023-03-24 03:55:33 +0300 493)       }
bfc1508d (kx 2023-03-24 03:55:33 +0300 494)     }
bfc1508d (kx 2023-03-24 03:55:33 +0300 495)     list = dlist_next( list );
bfc1508d (kx 2023-03-24 03:55:33 +0300 496)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 497) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 498)   return NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 499) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 500) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 501) /************************************
bfc1508d (kx 2023-03-24 03:55:33 +0300 502)   parent rlist node of repolist nth:
bfc1508d (kx 2023-03-24 03:55:33 +0300 503)  */
bfc1508d (kx 2023-03-24 03:55:33 +0300 504) struct dlist *parent_rlist_node_repolist_nth( struct dlist *config, int n )
bfc1508d (kx 2023-03-24 03:55:33 +0300 505) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 506)   struct dlist *list = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 507)   int length = 0;
bfc1508d (kx 2023-03-24 03:55:33 +0300 508) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 509)   if( !config || n < 0 ) return NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 510) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 511)   list = config;
bfc1508d (kx 2023-03-24 03:55:33 +0300 512)   while( list )
bfc1508d (kx 2023-03-24 03:55:33 +0300 513)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 514)     struct section *section = (struct section *)list->data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 515) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 516)     if( section->type == ST_REPOS )
bfc1508d (kx 2023-03-24 03:55:33 +0300 517)     {
bfc1508d (kx 2023-03-24 03:55:33 +0300 518)       struct dlist *rlist = section->list;
bfc1508d (kx 2023-03-24 03:55:33 +0300 519)       while( rlist )
bfc1508d (kx 2023-03-24 03:55:33 +0300 520)       {
bfc1508d (kx 2023-03-24 03:55:33 +0300 521)         if( length == n )
bfc1508d (kx 2023-03-24 03:55:33 +0300 522)         {
bfc1508d (kx 2023-03-24 03:55:33 +0300 523)           return rlist;
bfc1508d (kx 2023-03-24 03:55:33 +0300 524)         }
bfc1508d (kx 2023-03-24 03:55:33 +0300 525)         ++length;
bfc1508d (kx 2023-03-24 03:55:33 +0300 526)         rlist = dlist_next( rlist );
bfc1508d (kx 2023-03-24 03:55:33 +0300 527)       }
bfc1508d (kx 2023-03-24 03:55:33 +0300 528)     }
bfc1508d (kx 2023-03-24 03:55:33 +0300 529)     list = dlist_next( list );
bfc1508d (kx 2023-03-24 03:55:33 +0300 530)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 531) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 532)   return NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 533) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 534) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 535) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 536) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 537) /**********************************************
bfc1508d (kx 2023-03-24 03:55:33 +0300 538)   Provide all global variables into each repo
bfc1508d (kx 2023-03-24 03:55:33 +0300 539)   if that variable is not present in the repo:
bfc1508d (kx 2023-03-24 03:55:33 +0300 540)  */
bfc1508d (kx 2023-03-24 03:55:33 +0300 541) static void __provide_foreach_data( void *data, void *user_data )
bfc1508d (kx 2023-03-24 03:55:33 +0300 542) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 543)   struct variable *variable = (struct variable *)data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 544)   struct repo     *repo     = (struct repo *)user_data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 545) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 546)   if( !repo || !variable ) return;
bfc1508d (kx 2023-03-24 03:55:33 +0300 547) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 548)   if( !lookup( repo, variable ) )
bfc1508d (kx 2023-03-24 03:55:33 +0300 549)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 550)     struct variable *var = (struct variable *)xmalloc( sizeof(struct variable) );
bfc1508d (kx 2023-03-24 03:55:33 +0300 551)     memcpy( (void *)var, (void *)variable, sizeof(struct variable) );
bfc1508d (kx 2023-03-24 03:55:33 +0300 552)     repo->list = dlist_append( repo->list, (void *)var );
bfc1508d (kx 2023-03-24 03:55:33 +0300 553)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 554) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 555) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 556) static void __provide_foreach_repos( void *data, void *user_data )
bfc1508d (kx 2023-03-24 03:55:33 +0300 557) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 558)   struct section *global = (struct section *)user_data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 559) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 560)   if( !global || !global->list ) return;
bfc1508d (kx 2023-03-24 03:55:33 +0300 561) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 562)   dlist_foreach( global->list, __provide_foreach_data, data );
bfc1508d (kx 2023-03-24 03:55:33 +0300 563) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 564) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 565) static void __provide_foreach_sections( void *data, void *user_data )
bfc1508d (kx 2023-03-24 03:55:33 +0300 566) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 567)   struct section *section = (struct section *)data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 568)   if( !section || section->type == ST_GLOBAL || !section->list ) return;
bfc1508d (kx 2023-03-24 03:55:33 +0300 569) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 570)   dlist_foreach( section->list, __provide_foreach_repos, user_data );
bfc1508d (kx 2023-03-24 03:55:33 +0300 571) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 572) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 573) static void provide_global_data( struct dlist *tree, struct section *global )
bfc1508d (kx 2023-03-24 03:55:33 +0300 574) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 575)   if( tree ) { dlist_foreach( tree, __provide_foreach_sections, (void *)global ); }
bfc1508d (kx 2023-03-24 03:55:33 +0300 576) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 577) /*
bfc1508d (kx 2023-03-24 03:55:33 +0300 578)  **********************************************/
bfc1508d (kx 2023-03-24 03:55:33 +0300 579) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 580) /**********************************************
bfc1508d (kx 2023-03-24 03:55:33 +0300 581)   Free REPO list functions:
bfc1508d (kx 2023-03-24 03:55:33 +0300 582)  */
bfc1508d (kx 2023-03-24 03:55:33 +0300 583) static void __free_variable( void *data, void *user_data )
bfc1508d (kx 2023-03-24 03:55:33 +0300 584) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 585)   struct variable *variable = (struct variable *)data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 586)   if( variable ) free( variable );
bfc1508d (kx 2023-03-24 03:55:33 +0300 587) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 588) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 589) static void free_variables( struct dlist *list )
bfc1508d (kx 2023-03-24 03:55:33 +0300 590) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 591)   if( list ) { dlist_free( list, __free_variable ); }
bfc1508d (kx 2023-03-24 03:55:33 +0300 592) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 593) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 594) static void __free_repo( void *data, void *user_data )
bfc1508d (kx 2023-03-24 03:55:33 +0300 595) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 596)   struct repo *repo = (struct repo *)data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 597)   if( !repo ) return;
bfc1508d (kx 2023-03-24 03:55:33 +0300 598)   if( repo->list ) { free_variables( repo->list ); }
bfc1508d (kx 2023-03-24 03:55:33 +0300 599)   free( repo );
bfc1508d (kx 2023-03-24 03:55:33 +0300 600) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 601) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 602) static void free_repos( struct dlist *list )
bfc1508d (kx 2023-03-24 03:55:33 +0300 603) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 604)   if( list ) { dlist_free( list, __free_repo ); }
bfc1508d (kx 2023-03-24 03:55:33 +0300 605) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 606) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 607) static void __free_section( void *data, void *user_data )
bfc1508d (kx 2023-03-24 03:55:33 +0300 608) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 609)   struct section *section = (struct section *)data;
bfc1508d (kx 2023-03-24 03:55:33 +0300 610)   if( !section ) return;
bfc1508d (kx 2023-03-24 03:55:33 +0300 611) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 612)   if( section->list )
bfc1508d (kx 2023-03-24 03:55:33 +0300 613)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 614)     if( section->type == ST_GLOBAL )
bfc1508d (kx 2023-03-24 03:55:33 +0300 615)       free_variables( section->list );
bfc1508d (kx 2023-03-24 03:55:33 +0300 616)     else if( section->type == ST_REPOS )
bfc1508d (kx 2023-03-24 03:55:33 +0300 617)       free_repos( section->list );
bfc1508d (kx 2023-03-24 03:55:33 +0300 618)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 619)   free( section );
bfc1508d (kx 2023-03-24 03:55:33 +0300 620) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 621) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 622) static void free_repolist( struct dlist *list )
bfc1508d (kx 2023-03-24 03:55:33 +0300 623) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 624)   if( list ) { dlist_free( list, __free_section ); }
bfc1508d (kx 2023-03-24 03:55:33 +0300 625) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 626) /*
bfc1508d (kx 2023-03-24 03:55:33 +0300 627)  **********************************************/
bfc1508d (kx 2023-03-24 03:55:33 +0300 628) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 629) void free_config( void )
bfc1508d (kx 2023-03-24 03:55:33 +0300 630) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 631)   free_repolist( config ); config = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 632)   if( bcf ) { free( bcf ); bcf = NULL; }
bfc1508d (kx 2023-03-24 03:55:33 +0300 633) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 634) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 635) static struct dlist *read_repolist( const void *bf )
bfc1508d (kx 2023-03-24 03:55:33 +0300 636) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 637)   struct dlist  *tree = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 638)   Bcf32_fhdr    *fhdr = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 639)   unsigned char *ftab, *stab;
bfc1508d (kx 2023-03-24 03:55:33 +0300 640) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 641)   ftab = (unsigned char *)bf;
bfc1508d (kx 2023-03-24 03:55:33 +0300 642)   fhdr = (Bcf32_fhdr *)ftab;
bfc1508d (kx 2023-03-24 03:55:33 +0300 643) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 644)   if( !fhdr )
bfc1508d (kx 2023-03-24 03:55:33 +0300 645)     return tree;
bfc1508d (kx 2023-03-24 03:55:33 +0300 646) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 647)   stab = (unsigned char *)(ftab + (int)fhdr->b_stoff);
bfc1508d (kx 2023-03-24 03:55:33 +0300 648) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 649) #if __DEBUG__ == 1
bfc1508d (kx 2023-03-24 03:55:33 +0300 650)   fprintf( stderr, "BCF: header's size in bytes: %d\n",  fhdr->b_hsize );
bfc1508d (kx 2023-03-24 03:55:33 +0300 651)   fprintf( stderr, "BCF: Whole BCF file size in bytes: %d\n",  fhdr->b_fsize );
bfc1508d (kx 2023-03-24 03:55:33 +0300 652)   fprintf( stderr, "BCF: section header table’s file offset in bytes: %d\n",  fhdr->b_shoff );
bfc1508d (kx 2023-03-24 03:55:33 +0300 653)   fprintf( stderr, "BCF: section header's size in bytes: %d\n",  fhdr->b_shentsize );
bfc1508d (kx 2023-03-24 03:55:33 +0300 654)   fprintf( stderr, "BCF: number of entries in section headers table: %d\n",  fhdr->b_shnum );
bfc1508d (kx 2023-03-24 03:55:33 +0300 655)   fprintf( stderr, "BCF: repository header table’s file offset in bytes: %d\n",  fhdr->b_rhoff );
bfc1508d (kx 2023-03-24 03:55:33 +0300 656)   fprintf( stderr, "BCF: repository header's size in bytes: %d\n",  fhdr->b_rhentsize );
bfc1508d (kx 2023-03-24 03:55:33 +0300 657)   fprintf( stderr, "BCF: number of entries in repository headers table: %d\n",  fhdr->b_rhnum );
bfc1508d (kx 2023-03-24 03:55:33 +0300 658)   fprintf( stderr, "BCF: data entries table’s file offset in bytes: %d\n",  fhdr->b_dtoff );
bfc1508d (kx 2023-03-24 03:55:33 +0300 659)   fprintf( stderr, "BCF: data entry's size in bytes: %d\n",  fhdr->b_dtentsize );
bfc1508d (kx 2023-03-24 03:55:33 +0300 660)   fprintf( stderr, "BCF: number of entries in data entries table: %d\n",  fhdr->b_dtnum );
bfc1508d (kx 2023-03-24 03:55:33 +0300 661)   fprintf( stderr, "BCF: string table’s file offset in bytes: %d\n\n",  fhdr->b_stoff );
bfc1508d (kx 2023-03-24 03:55:33 +0300 662) #endif
bfc1508d (kx 2023-03-24 03:55:33 +0300 663) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 664)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 665)     Bcf32_shdr *shdr = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 666)     int s = 0;
bfc1508d (kx 2023-03-24 03:55:33 +0300 667) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 668)     struct section *global = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 669) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 670)     shdr = (Bcf32_shdr *)((unsigned char *)bf + (int)fhdr->b_shoff);
bfc1508d (kx 2023-03-24 03:55:33 +0300 671) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 672)     while( s < fhdr->b_shnum )
bfc1508d (kx 2023-03-24 03:55:33 +0300 673)     {
bfc1508d (kx 2023-03-24 03:55:33 +0300 674) #if __DEBUG__ == 1
bfc1508d (kx 2023-03-24 03:55:33 +0300 675)       fprintf( stderr, "SECTION: s_name: %s\n",  shdr->s_name );
bfc1508d (kx 2023-03-24 03:55:33 +0300 676)       fprintf( stderr, "SECTION: s_type: %d\n",  shdr->s_type );
bfc1508d (kx 2023-03-24 03:55:33 +0300 677)       fprintf( stderr, "SECTION: s_shdr (offset in string table): %d\n",  shdr->s_shdr );
bfc1508d (kx 2023-03-24 03:55:33 +0300 678)       fprintf( stderr, "SECTION: s_sdata (file offset to data): %d\n",  shdr->s_sdata );
bfc1508d (kx 2023-03-24 03:55:33 +0300 679)       fprintf( stderr, "SECTION: s_dnum (number of data entries): %d\n",  shdr->s_dnum );
bfc1508d (kx 2023-03-24 03:55:33 +0300 680)       fprintf( stderr, "SECTION: name: \"%s\"\n\n",  stab + (int)shdr->s_shdr );
bfc1508d (kx 2023-03-24 03:55:33 +0300 681) #endif
bfc1508d (kx 2023-03-24 03:55:33 +0300 682) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 683)       if( shdr->s_type == ST_GLOBAL )
bfc1508d (kx 2023-03-24 03:55:33 +0300 684)       {
bfc1508d (kx 2023-03-24 03:55:33 +0300 685)         Bcf32_dntr *dntr = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 686)         int d = 0;
bfc1508d (kx 2023-03-24 03:55:33 +0300 687) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 688)         struct section *sec = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 689)         sec = (struct section *)xmalloc( sizeof(struct section) );
bfc1508d (kx 2023-03-24 03:55:33 +0300 690)         sec->type = ST_GLOBAL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 691)         sec->name = (unsigned char *)(stab + (int)shdr->s_shdr); /*do not allocate, all in bcf */
bfc1508d (kx 2023-03-24 03:55:33 +0300 692)         tree = dlist_append( tree, (void *)sec );
bfc1508d (kx 2023-03-24 03:55:33 +0300 693)         global = sec;
bfc1508d (kx 2023-03-24 03:55:33 +0300 694) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 695)         dntr = (Bcf32_dntr *)(ftab + (int)shdr->s_sdata);
bfc1508d (kx 2023-03-24 03:55:33 +0300 696) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 697)         while( d < shdr->s_dnum )
bfc1508d (kx 2023-03-24 03:55:33 +0300 698)         {
bfc1508d (kx 2023-03-24 03:55:33 +0300 699) #if __DEBUG__ == 1
bfc1508d (kx 2023-03-24 03:55:33 +0300 700)           fprintf( stderr, "DATA: d_name: %s\n",  stab + (int)dntr->d_name );
bfc1508d (kx 2023-03-24 03:55:33 +0300 701) #endif
bfc1508d (kx 2023-03-24 03:55:33 +0300 702) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 703)           switch( dntr->d_type )
bfc1508d (kx 2023-03-24 03:55:33 +0300 704)           {
bfc1508d (kx 2023-03-24 03:55:33 +0300 705)             case DT_NUMERICAL:
bfc1508d (kx 2023-03-24 03:55:33 +0300 706) #if __DEBUG__ == 1
bfc1508d (kx 2023-03-24 03:55:33 +0300 707)               fprintf( stderr, "DATA: _v.d_value: %d\n\n",  dntr->_v.d_value );
bfc1508d (kx 2023-03-24 03:55:33 +0300 708) #endif
bfc1508d (kx 2023-03-24 03:55:33 +0300 709)               {
bfc1508d (kx 2023-03-24 03:55:33 +0300 710)                 struct variable *var = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 711)                 var = (struct variable *)xmalloc( sizeof(struct variable) );
bfc1508d (kx 2023-03-24 03:55:33 +0300 712)                 var->type = DT_NUMERICAL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 713)                 var->name = (unsigned char *)(stab + (int)dntr->d_name); /*do not allocate, all in bcf */
bfc1508d (kx 2023-03-24 03:55:33 +0300 714)                 var->_v.val = (int)dntr->_v.d_value;
bfc1508d (kx 2023-03-24 03:55:33 +0300 715)                 sec->list = dlist_append( sec->list, (void *)var );
bfc1508d (kx 2023-03-24 03:55:33 +0300 716)               }
bfc1508d (kx 2023-03-24 03:55:33 +0300 717)               break;
bfc1508d (kx 2023-03-24 03:55:33 +0300 718)             case DT_PATH:
bfc1508d (kx 2023-03-24 03:55:33 +0300 719) #if __DEBUG__ == 1
bfc1508d (kx 2023-03-24 03:55:33 +0300 720)               fprintf( stderr, "DATA: _v.d_valptr (path): '%s';\n\n", stab + (int)dntr->_v.d_valptr );
bfc1508d (kx 2023-03-24 03:55:33 +0300 721) #endif
bfc1508d (kx 2023-03-24 03:55:33 +0300 722)               {
bfc1508d (kx 2023-03-24 03:55:33 +0300 723)                 struct variable *var = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 724)                 var = (struct variable *)xmalloc( sizeof(struct variable) );
bfc1508d (kx 2023-03-24 03:55:33 +0300 725)                 var->type = DT_PATH;
bfc1508d (kx 2023-03-24 03:55:33 +0300 726)                 var->name = (unsigned char *)(stab + (int)dntr->d_name); /*do not allocate, all in bcf */
bfc1508d (kx 2023-03-24 03:55:33 +0300 727)                 var->_v.vptr = (unsigned char *)(stab + (int)dntr->_v.d_valptr);
bfc1508d (kx 2023-03-24 03:55:33 +0300 728)                 sec->list = dlist_append( sec->list, (void *)var );
bfc1508d (kx 2023-03-24 03:55:33 +0300 729)               }
bfc1508d (kx 2023-03-24 03:55:33 +0300 730)               break;
bfc1508d (kx 2023-03-24 03:55:33 +0300 731)             case DT_STRING:
bfc1508d (kx 2023-03-24 03:55:33 +0300 732) #if __DEBUG__ == 1
bfc1508d (kx 2023-03-24 03:55:33 +0300 733)               fprintf( stderr, "DATA: _v.d_valptr (string): \"%s\";\n\n", stab + (int)dntr->_v.d_valptr );
bfc1508d (kx 2023-03-24 03:55:33 +0300 734) #endif
bfc1508d (kx 2023-03-24 03:55:33 +0300 735)               {
bfc1508d (kx 2023-03-24 03:55:33 +0300 736)                 struct variable *var = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 737)                 var = (struct variable *)xmalloc( sizeof(struct variable) );
bfc1508d (kx 2023-03-24 03:55:33 +0300 738)                 var->type = DT_STRING;
bfc1508d (kx 2023-03-24 03:55:33 +0300 739)                 var->name = (unsigned char *)(stab + (int)dntr->d_name); /*do not allocate, all in bcf */
bfc1508d (kx 2023-03-24 03:55:33 +0300 740)                 var->_v.vptr = (unsigned char *)(stab + (int)dntr->_v.d_valptr);
bfc1508d (kx 2023-03-24 03:55:33 +0300 741)                 sec->list = dlist_append( sec->list, (void *)var );
bfc1508d (kx 2023-03-24 03:55:33 +0300 742)               }
bfc1508d (kx 2023-03-24 03:55:33 +0300 743)               break;
bfc1508d (kx 2023-03-24 03:55:33 +0300 744)             default:
bfc1508d (kx 2023-03-24 03:55:33 +0300 745)               break;
bfc1508d (kx 2023-03-24 03:55:33 +0300 746)           }
bfc1508d (kx 2023-03-24 03:55:33 +0300 747) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 748)           ++d;
bfc1508d (kx 2023-03-24 03:55:33 +0300 749)           ++dntr;
bfc1508d (kx 2023-03-24 03:55:33 +0300 750) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 751)         } /* End of while( global data ) */
bfc1508d (kx 2023-03-24 03:55:33 +0300 752) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 753)       }
bfc1508d (kx 2023-03-24 03:55:33 +0300 754)       else if( shdr->s_type == ST_REPOS )
bfc1508d (kx 2023-03-24 03:55:33 +0300 755)       {
bfc1508d (kx 2023-03-24 03:55:33 +0300 756)         Bcf32_rhdr *rhdr = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 757)         int r = 0;
bfc1508d (kx 2023-03-24 03:55:33 +0300 758) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 759)         struct section *sec = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 760)         sec = (struct section *)xmalloc( sizeof(struct section) );
bfc1508d (kx 2023-03-24 03:55:33 +0300 761)         sec->type = ST_REPOS;
bfc1508d (kx 2023-03-24 03:55:33 +0300 762)         sec->name = (unsigned char *)(stab + (int)shdr->s_shdr); /*do not allocate, all in bcf */
bfc1508d (kx 2023-03-24 03:55:33 +0300 763)         tree = dlist_append( tree, (void *)sec );
bfc1508d (kx 2023-03-24 03:55:33 +0300 764) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 765)         rhdr = (Bcf32_rhdr *)(ftab + (int)shdr->s_sdata);
bfc1508d (kx 2023-03-24 03:55:33 +0300 766) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 767)         while( r < shdr->s_dnum )
bfc1508d (kx 2023-03-24 03:55:33 +0300 768)         {
bfc1508d (kx 2023-03-24 03:55:33 +0300 769)           int d = 0;
bfc1508d (kx 2023-03-24 03:55:33 +0300 770)           Bcf32_dntr *dntr = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 771) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 772)           struct repo *repo = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 773)           repo = (struct repo *)xmalloc( sizeof(struct repo) );
bfc1508d (kx 2023-03-24 03:55:33 +0300 774)           repo->path = (unsigned char *)(stab + (int)rhdr->r_rhdr); /*do not allocate, all in bcf */
bfc1508d (kx 2023-03-24 03:55:33 +0300 775)           sec->list = dlist_append( sec->list, (void *)repo );
bfc1508d (kx 2023-03-24 03:55:33 +0300 776) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 777) #if __DEBUG__ == 1
bfc1508d (kx 2023-03-24 03:55:33 +0300 778)           fprintf( stderr, "REPO: path: %s\n",  stab + (int)rhdr->r_rhdr );
bfc1508d (kx 2023-03-24 03:55:33 +0300 779) #endif
bfc1508d (kx 2023-03-24 03:55:33 +0300 780)           dntr = (Bcf32_dntr *)(ftab + (int)rhdr->r_rdata);
bfc1508d (kx 2023-03-24 03:55:33 +0300 781) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 782)           while( d < rhdr->r_dnum )
bfc1508d (kx 2023-03-24 03:55:33 +0300 783)           {
bfc1508d (kx 2023-03-24 03:55:33 +0300 784) #if __DEBUG__ == 1
bfc1508d (kx 2023-03-24 03:55:33 +0300 785)             fprintf( stderr, "REPO's DATA: d_name: %s\n",  stab + (int)dntr->d_name );
bfc1508d (kx 2023-03-24 03:55:33 +0300 786) #endif
bfc1508d (kx 2023-03-24 03:55:33 +0300 787)             switch( dntr->d_type )
bfc1508d (kx 2023-03-24 03:55:33 +0300 788)             {
bfc1508d (kx 2023-03-24 03:55:33 +0300 789)               case DT_NUMERICAL:
bfc1508d (kx 2023-03-24 03:55:33 +0300 790) #if __DEBUG__ == 1
bfc1508d (kx 2023-03-24 03:55:33 +0300 791)                 fprintf( stderr, "REPO's DATA: _v.d_value: %d\n\n",  dntr->_v.d_value );
bfc1508d (kx 2023-03-24 03:55:33 +0300 792) #endif
bfc1508d (kx 2023-03-24 03:55:33 +0300 793)                 {
bfc1508d (kx 2023-03-24 03:55:33 +0300 794)                   struct variable *var = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 795)                   var = (struct variable *)xmalloc( sizeof(struct variable) );
bfc1508d (kx 2023-03-24 03:55:33 +0300 796)                   var->type = DT_NUMERICAL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 797)                   var->name = (unsigned char *)(stab + (int)dntr->d_name); /*do not allocate, all in bcf */
bfc1508d (kx 2023-03-24 03:55:33 +0300 798)                   var->_v.val = (int)dntr->_v.d_value;
bfc1508d (kx 2023-03-24 03:55:33 +0300 799)                   repo->list = dlist_append( repo->list, (void *)var );
bfc1508d (kx 2023-03-24 03:55:33 +0300 800)                 }
bfc1508d (kx 2023-03-24 03:55:33 +0300 801)                 break;
bfc1508d (kx 2023-03-24 03:55:33 +0300 802)               case DT_PATH:
bfc1508d (kx 2023-03-24 03:55:33 +0300 803) #if __DEBUG__ == 1
bfc1508d (kx 2023-03-24 03:55:33 +0300 804)                 fprintf( stderr, "REPO's DATA: _v.d_valptr (path): '%s';\n\n", stab + (int)dntr->_v.d_valptr );
bfc1508d (kx 2023-03-24 03:55:33 +0300 805) #endif
bfc1508d (kx 2023-03-24 03:55:33 +0300 806)                 {
bfc1508d (kx 2023-03-24 03:55:33 +0300 807)                   struct variable *var = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 808)                   var = (struct variable *)xmalloc( sizeof(struct variable) );
bfc1508d (kx 2023-03-24 03:55:33 +0300 809)                   var->type = DT_PATH;
bfc1508d (kx 2023-03-24 03:55:33 +0300 810)                   var->name = (unsigned char *)(stab + (int)dntr->d_name); /*do not allocate, all in bcf */
bfc1508d (kx 2023-03-24 03:55:33 +0300 811)                   var->_v.vptr = (unsigned char *)(stab + (int)dntr->_v.d_valptr);
bfc1508d (kx 2023-03-24 03:55:33 +0300 812)                   repo->list = dlist_append( repo->list, (void *)var );
bfc1508d (kx 2023-03-24 03:55:33 +0300 813)                 }
bfc1508d (kx 2023-03-24 03:55:33 +0300 814)                 break;
bfc1508d (kx 2023-03-24 03:55:33 +0300 815)               case DT_STRING:
bfc1508d (kx 2023-03-24 03:55:33 +0300 816) #if __DEBUG__ == 1
bfc1508d (kx 2023-03-24 03:55:33 +0300 817)                 fprintf( stderr, "REPO's DATA: _v.d_valptr (string): \"%s\";\n\n", stab + (int)dntr->_v.d_valptr );
bfc1508d (kx 2023-03-24 03:55:33 +0300 818) #endif
bfc1508d (kx 2023-03-24 03:55:33 +0300 819)                 {
bfc1508d (kx 2023-03-24 03:55:33 +0300 820)                   struct variable *var = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 821)                   var = (struct variable *)xmalloc( sizeof(struct variable) );
bfc1508d (kx 2023-03-24 03:55:33 +0300 822)                   var->type = DT_STRING;
bfc1508d (kx 2023-03-24 03:55:33 +0300 823)                   var->name = (unsigned char *)(stab + (int)dntr->d_name); /*do not allocate, all in bcf */
bfc1508d (kx 2023-03-24 03:55:33 +0300 824)                   var->_v.vptr = (unsigned char *)(stab + (int)dntr->_v.d_valptr);
bfc1508d (kx 2023-03-24 03:55:33 +0300 825)                   repo->list = dlist_append( repo->list, (void *)var );
bfc1508d (kx 2023-03-24 03:55:33 +0300 826)                 }
bfc1508d (kx 2023-03-24 03:55:33 +0300 827)                 break;
bfc1508d (kx 2023-03-24 03:55:33 +0300 828)               default:
bfc1508d (kx 2023-03-24 03:55:33 +0300 829)                 break;
bfc1508d (kx 2023-03-24 03:55:33 +0300 830)             }
bfc1508d (kx 2023-03-24 03:55:33 +0300 831) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 832)             ++d;
bfc1508d (kx 2023-03-24 03:55:33 +0300 833)             ++dntr;
bfc1508d (kx 2023-03-24 03:55:33 +0300 834) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 835)           } /* End of while( repo data ) */
bfc1508d (kx 2023-03-24 03:55:33 +0300 836) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 837)           ++r;
bfc1508d (kx 2023-03-24 03:55:33 +0300 838)           ++rhdr;
bfc1508d (kx 2023-03-24 03:55:33 +0300 839) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 840)         } /* End of while( repos ) */
bfc1508d (kx 2023-03-24 03:55:33 +0300 841) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 842) #if __DEBUG__ == 1
bfc1508d (kx 2023-03-24 03:55:33 +0300 843)         fprintf( stderr, "\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 844) #endif
bfc1508d (kx 2023-03-24 03:55:33 +0300 845)       }
bfc1508d (kx 2023-03-24 03:55:33 +0300 846)       else
bfc1508d (kx 2023-03-24 03:55:33 +0300 847)       {
bfc1508d (kx 2023-03-24 03:55:33 +0300 848)         rlist_fatal( "Invalid section in the SHM/%s data", "csvn.bcf" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 849) #if __DEBUG__ == 1
bfc1508d (kx 2023-03-24 03:55:33 +0300 850)         fprintf( stderr, "SECTION: empty\n" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 851) #endif
bfc1508d (kx 2023-03-24 03:55:33 +0300 852)       }
bfc1508d (kx 2023-03-24 03:55:33 +0300 853) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 854)       ++s;
bfc1508d (kx 2023-03-24 03:55:33 +0300 855)       ++shdr;
bfc1508d (kx 2023-03-24 03:55:33 +0300 856) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 857)     } /* End of while( sections ) */
bfc1508d (kx 2023-03-24 03:55:33 +0300 858) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 859)     if( global )
bfc1508d (kx 2023-03-24 03:55:33 +0300 860)       provide_global_data( tree, global );
bfc1508d (kx 2023-03-24 03:55:33 +0300 861)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 862) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 863)   return tree;
bfc1508d (kx 2023-03-24 03:55:33 +0300 864) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 865) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 866) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 867) struct dlist *read_config( void )
bfc1508d (kx 2023-03-24 03:55:33 +0300 868) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 869)   size_t  bsize = 0;
bfc1508d (kx 2023-03-24 03:55:33 +0300 870) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 871)   if( (bsize = read_bcf()) )
bfc1508d (kx 2023-03-24 03:55:33 +0300 872)   {
bfc1508d (kx 2023-03-24 03:55:33 +0300 873)     check_bcf_ident( bcf, bsize ); /* fatal on error */
bfc1508d (kx 2023-03-24 03:55:33 +0300 874)     return read_repolist( bcf );
bfc1508d (kx 2023-03-24 03:55:33 +0300 875)   }
bfc1508d (kx 2023-03-24 03:55:33 +0300 876) 
bfc1508d (kx 2023-03-24 03:55:33 +0300 877)   return NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 878) }