12c7b1c5 (kx 2023-03-24 02:53:04 +0300 1)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 2) #ifdef HAVE_CONFIG_H
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 3) #include <config.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 4) #endif
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 5)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 6) #include <stdlib.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 7) #include <stdio.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 8) #include <sys/sysinfo.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 9) #include <sys/types.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 10) #include <stdint.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 11) #include <dirent.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 12) #include <sys/stat.h> /* chmod(2) */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 13) #include <fcntl.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 14) #include <limits.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 15) #include <string.h> /* strdup(3) */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 16) #include <libgen.h> /* basename(3) */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 17) #include <ctype.h> /* tolower(3) */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 18) #include <errno.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 19) #include <time.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 20) #include <sys/time.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 21) #include <pwd.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 22) #include <grp.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 23) #include <stdarg.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 24) #include <unistd.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 25)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 26) #include <sys/inotify.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 27)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 28) #include <locale.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 29) #include <wchar.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 30) #include <wctype.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 31)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 32) #include <sys/wait.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 33)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 34) #include <sys/resource.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 35)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 36) #include <signal.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 37) #if !defined SIGCHLD && defined SIGCLD
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 38) # define SIGCHLD SIGCLD
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 39) #endif
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 40)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 41) #define _GNU_SOURCE
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 42) #include <getopt.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 43)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 44)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 45) #include <daemon.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 46) #include <msglog.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 47) #include <error.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 48) #include <utf8ing.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 49) #include <symtab.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 50) #include <parse.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 51) #include <lex.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 52) #include <bconf.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 53)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 54) #include <defs.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 55)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 56)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 57) /*********************
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 58) Default File Names:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 59) */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 60) const char *CONFIG_FILE = CSVN_CONFIG;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 61) const char *BCF_FILE = CSVN_HOME_DIR "/" CSVN_PROGRAM ".bcf";
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 62) const char *LOG_FILE = CSCM_LOG_DIR "/" CSVN_PROGRAM "d.log";
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 63) const char *PID_FILE = CSCM_PID_DIR "/" CSVN_PROGRAM "d.pid";
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 64) const char *SHM_BCF = CSVN_SHM_BCF;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 65)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 66)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 67) char *program = PROGRAM_DAEMON;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 68) int exit_status = EXIT_SUCCESS; /* errors counter */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 69)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 70) FILE *config = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 71) char *config_fname = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 72)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 73) char *log_fname = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 74) char *pid_fname = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 75)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 76) static sigset_t blockmask;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 77)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 78) static int run_as_daemon = 0;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 79) static int test_config_file = 0;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 80) static int config_inotify = 0;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 81)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 82)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 83) static void free_resources( void );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 84)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 85)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 86) /***********************
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 87) Inotify declarations:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 88) */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 89) #define IN_BUFFER_SIZE (7 * (sizeof(struct inotify_event) + NAME_MAX + 1))
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 90)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 91) static int inotify_fd = 0, wd = 0;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 92) static struct inotify_event *event = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 93) static char buf[IN_BUFFER_SIZE] __attribute__ ((aligned(8)));
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 94)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 95) static int check_event( struct inotify_event *e )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 96) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 97) if( e->mask & IN_CLOSE_WRITE ) return 1;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 98) return 0;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 99) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 100)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 101) static void init_config_inotify( void )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 102) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 103) inotify_fd = inotify_init(); /* Create inotify instance */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 104) if( inotify_fd == -1 )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 105) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 106) ERROR( "Cannot initialize inotify for file: %s", config_fname );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 107) LOG( "Stop cScm Configuration Daemon." );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 108) free_resources();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 109) exit( 1 );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 110) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 111)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 112) wd = inotify_add_watch( inotify_fd, config_fname, IN_CLOSE_WRITE );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 113) if( wd == -1 )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 114) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 115) ERROR( "Cannot add inotify watch for file: %s", config_fname );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 116) LOG( "Stop cScm Configuration Daemon." );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 117) free_resources();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 118) exit( 1 );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 119) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 120) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 121)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 122) static void fini_config_inotify( void )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 123) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 124) if( wd > 0 ) { (void)inotify_rm_watch( inotify_fd, wd ); wd = 0; }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 125) if( inotify_fd > 0 ) { (void)close( inotify_fd ); inotify_fd = 0; }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 126) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 127)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 128)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 129) static void free_resources( void )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 130) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 131) fini_config_inotify();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 132)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 133) if( log_fname )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 134) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 135) if( errlog ) { fclose( errlog ); errlog = NULL; }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 136) free( log_fname ); log_fname = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 137) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 138) if( config_fname )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 139) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 140) if( config ) { fclose( config ); config = NULL; }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 141) free( config_fname ); config_fname = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 142) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 143) bcf_shm_free();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 144) if( bcf_fname )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 145) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 146) if( bcf ) { fclose( bcf ); bcf = NULL; }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 147) (void)unlink( (const char *)bcf_fname );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 148) free( bcf_fname ); bcf_fname = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 149) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 150) if( pid_fname )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 151) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 152) (void)unlink( (const char *)pid_fname );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 153) free( pid_fname ); pid_fname = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 154) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 155) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 156)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 157)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 158) void usage()
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 159) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 160) free_resources();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 161)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 162) fprintf( stdout, "\n" );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 163) fprintf( stdout, "Usage: %s [options]\n", program );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 164) fprintf( stdout, "\n" );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 165) fprintf( stdout, "Start cScm Configuration Daemon to read config file.\n" );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 166) fprintf( stdout, "\n" );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 167) fprintf( stdout, "Options:\n" );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 168) fprintf( stdout, " -h,--help Display this information.\n" );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 169) fprintf( stdout, " -v,--version Display the version of %s utility.\n", program );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 170) fprintf( stdout, " -d,--daemonize Run in background as a daemon.\n" );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 171) fprintf( stdout, " -i,--inotify Notify about configuration changes.\n" );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 172) fprintf( stdout, " -b,--bcf=<BCF_FILE> Binary config file. Default: %s.\n", BCF_FILE );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 173) fprintf( stdout, " -c,--config=<CONFIG_FILE> Config file. Default: %s.\n", CONFIG_FILE );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 174) fprintf( stdout, " -l,--log=<LOG_FILE> Log file. Default: %s.\n", LOG_FILE );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 175) fprintf( stdout, " -p,--pid=<PID_FILE> PID file. Default: %s.\n", PID_FILE );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 176) fprintf( stdout, " -s,--scm=<SCM> SCM 'svn' or 'git'. Default: 'svn'.\n" );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 177) fprintf( stdout, " -t,--test Test config file and exit.\n" );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 178) fprintf( stdout, "\n" );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 179)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 180) exit( EXIT_FAILURE );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 181) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 182)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 183) void to_lowercase( char *s )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 184) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 185) char *p = s;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 186) while( p && *p ) { int c = *p; *p = tolower( c ); ++p; }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 187) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 188)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 189) void to_uppercase( char *s )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 190) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 191) char *p = s;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 192) while( p && *p ) { int c = *p; *p = toupper( c ); ++p; }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 193) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 194)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 195) void version()
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 196) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 197) char *upper = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 198)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 199) upper = (char *)alloca( strlen( program ) + 1 );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 200)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 201) strcpy( (char *)upper, (const char *)program );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 202) to_uppercase( upper );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 203)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 204) fprintf( stdout, "%s (%s) %s\n", program, upper, PROGRAM_VERSION );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 205)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 206) fprintf( stdout, "Copyright (C) 2022 Andrey V.Kosteltsev.\n" );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 207) fprintf( stdout, "This is free software. There is NO warranty; not even\n" );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 208) fprintf( stdout, "for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 209) fprintf( stdout, "\n" );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 210)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 211) free_resources();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 212) exit( EXIT_SUCCESS );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 213) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 214)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 215) void get_args( int argc, char *argv[] )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 216) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 217) const char* short_options = "hvdic:l:p:s:t";
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 218)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 219) const struct option long_options[] =
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 220) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 221) { "help", no_argument, NULL, 'h' },
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 222) { "version", no_argument, NULL, 'v' },
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 223) { "daemonize", no_argument, NULL, 'd' },
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 224) { "inotify", no_argument, NULL, 'i' },
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 225) { "bcf", required_argument, NULL, 'b' },
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 226) { "config", required_argument, NULL, 'c' },
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 227) { "log", required_argument, NULL, 'l' },
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 228) { "pid", required_argument, NULL, 'p' },
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 229) { "scm", required_argument, NULL, 's' },
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 230) { "test", no_argument, NULL, 't' },
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 231) { NULL, 0, NULL, 0 }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 232) };
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 233)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 234) int ret;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 235) int option_index = 0;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 236)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 237) while( (ret = getopt_long( argc, argv, short_options, long_options, &option_index )) != -1 )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 238) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 239) switch( ret )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 240) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 241) case 'h':
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 242) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 243) usage();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 244) break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 245) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 246) case 'v':
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 247) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 248) version();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 249) break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 250) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 251) case 'd':
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 252) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 253) run_as_daemon = 1;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 254) break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 255) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 256) case 'i':
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 257) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 258) config_inotify = 1;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 259) break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 260) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 261) case 't':
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 262) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 263) test_config_file = 1;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 264) break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 265) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 266)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 267) case 'b':
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 268) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 269) if( optarg != NULL )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 270) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 271) bcf_fname = strdup( optarg );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 272) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 273) else
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 274) /* option is present but without value */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 275) usage();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 276) break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 277) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 278)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 279) case 'c':
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 280) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 281) if( optarg != NULL )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 282) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 283) config_fname = strdup( optarg );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 284) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 285) else
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 286) /* option is present but without value */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 287) usage();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 288) break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 289) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 290)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 291) case 'l':
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 292) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 293) if( optarg != NULL )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 294) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 295) log_fname = strdup( optarg );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 296) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 297) else
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 298) /* option is present but without value */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 299) usage();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 300) break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 301) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 302)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 303) case 'p':
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 304) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 305) if( optarg != NULL )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 306) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 307) pid_fname = strdup( optarg );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 308) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 309) else
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 310) /* option is present but without value */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 311) usage();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 312) break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 313) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 314)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 315) case 's':
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 316) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 317) if( optarg != NULL )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 318) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 319) if( *optarg && !strncmp( optarg, "git", 3 ) )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 320) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 321) CONFIG_FILE = CGIT_CONFIG;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 322) BCF_FILE = CGIT_HOME_DIR "/" CGIT_PROGRAM ".bcf";
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 323) LOG_FILE = CSCM_LOG_DIR "/" CGIT_PROGRAM "d.log";
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 324) PID_FILE = CSCM_PID_DIR "/" CGIT_PROGRAM "d.pid";
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 325) SHM_BCF = CGIT_SHM_BCF;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 326) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 327) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 328) else
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 329) /* option is present but without value */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 330) usage();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 331) break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 332) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 333)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 334) case '?': default:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 335) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 336) usage();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 337) break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 338) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 339) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 340) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 341) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 342)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 343)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 344) static int is_directory( const char *path )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 345) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 346) struct stat st;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 347) return ( !stat( path, &st ) && S_ISDIR(st.st_mode) );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 348) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 349)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 350) static void logpid( void )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 351) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 352) FILE *fp;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 353)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 354) if( !pid_fname )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 355) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 356) /* allocate memory for PID file name */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 357) pid_fname = (char *)malloc( strlen( PID_FILE ) + 1 );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 358) if( !pid_fname ) { FATAL_ERROR( "Cannot allocate memory for PID file name: %s", PID_FILE ); }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 359) (void)strcpy( pid_fname, PID_FILE );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 360) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 361)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 362) /* Create CSCM_PID_DIR if not exists: */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 363) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 364) char *pid_dir = NULL, *dir = strdup( pid_fname );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 365)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 366) pid_dir = dirname( dir );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 367)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 368) if( !is_directory( (const char *)pid_dir ) )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 369) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 370) /* Create if not exists */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 371) if( 0 != mkdir( (const char *)pid_dir, 0755 ) )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 372) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 373) FATAL_ERROR( "Cannot create directory for PID file: %s", PID_FILE );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 374) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 375) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 376) free( dir );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 377) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 378)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 379) if( (fp = fopen( pid_fname, "w" )) != NULL )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 380) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 381) fprintf( fp, "%u\n", getpid() );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 382) (void)fclose( fp );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 383) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 384) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 385)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 386) void init_logs( void )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 387) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 388) /* print to stderr until the errlog file is open */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 389) errlog = stderr;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 390)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 391) if( !log_fname )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 392) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 393) /* allocate memory for LOG file name */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 394) log_fname = (char *)malloc( strlen( LOG_FILE ) + 1 );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 395) if( !log_fname ) { FATAL_ERROR( "Cannot open log file: %s", LOG_FILE ); }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 396) (void)strcpy( log_fname, LOG_FILE );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 397) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 398)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 399) /* Create CSCM_LOG_DIR if not exists: */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 400) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 401) char *log_dir = NULL, *dir = strdup( log_fname );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 402)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 403) log_dir = dirname( dir );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 404)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 405) if( !is_directory( (const char *)log_dir ) )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 406) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 407) /* Create if not exists */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 408) if( 0 != mkdir( (const char *)log_dir, 0755 ) )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 409) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 410) FATAL_ERROR( "Cannot create directory for log file: %s", LOG_FILE );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 411) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 412) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 413) free( dir );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 414) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 415)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 416) /* open LOG file */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 417) errlog = fopen( (const char *)log_fname, "a" );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 418) if( !errlog ) { errlog = stderr; FATAL_ERROR( "Cannot open log file: %s", log_fname ); }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 419) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 420)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 421) void open_config_file( void )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 422) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 423) if( !config_fname )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 424) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 425) /* allocate memory for CONFIG file name */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 426) config_fname = (char *)malloc( strlen( CONFIG_FILE ) + 1 );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 427) if( !config_fname )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 428) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 429) FATAL_ERROR( "Cannot open config file: %s", CONFIG_FILE );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 430) if( log_fname ) { fclose( errlog ); free( log_fname ); }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 431) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 432) (void)strcpy( config_fname, CONFIG_FILE );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 433) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 434)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 435) /* open CONFIG file */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 436) config = fopen( (const char *)config_fname, "r" );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 437) if( !config )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 438) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 439) FATAL_ERROR( "Cannot open config file: %s", config_fname );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 440) if( log_fname ) { fclose( errlog ); free( log_fname ); }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 441) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 442)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 443) if( !bcf_fname )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 444) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 445) /* allocate memory for BCF file name */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 446) bcf_fname = (char *)malloc( strlen( BCF_FILE ) + 1 );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 447) if( !bcf_fname )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 448) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 449) FATAL_ERROR( "Cannot allocate memory gor BCF file name: %s", BCF_FILE );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 450) if( log_fname ) { fclose( errlog ); free( log_fname ); }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 451) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 452) (void)strcpy( bcf_fname, BCF_FILE );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 453) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 454) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 455)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 456) void close_config_file( void )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 457) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 458) if( config ) { fclose( config ); config = NULL; }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 459) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 460)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 461)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 462)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 463) void parse_config_file( void )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 464) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 465) int ret;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 466)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 467) /***********************************
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 468) Blick signals until parser works:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 469) */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 470) (void)sigprocmask( SIG_BLOCK, (const sigset_t *)&blockmask, (sigset_t *)NULL );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 471)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 472) open_config_file();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 473) init_symtab();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 474) init_lex();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 475)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 476) if( !(ret = yyparse()) )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 477) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 478) reverse_symlist( (SYMBOL **)&symlist );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 479) remove_consts( (SYMBOL **)&symlist );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 480) (void)write_binary_config();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 481) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 482) else
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 483) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 484) bcf_shm_free();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 485) if( bcf_fname )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 486) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 487) if( bcf ) { fclose( bcf ); bcf = NULL; }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 488) (void)unlink( (const char *)bcf_fname );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 489) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 490) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 491)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 492) fini_lex();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 493) fini_symtab();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 494) close_config_file();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 495)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 496) (void)sigprocmask( SIG_UNBLOCK, (const sigset_t *)&blockmask, (sigset_t *)NULL );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 497)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 498) if( test_config_file )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 499) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 500) if( ret )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 501) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 502) fprintf( stdout, "%s: %s: Config file is not correct. See: %s\n", program, config_fname, log_fname );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 503) LOG( "Stop cScm Configuration Daemon." );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 504) free_resources();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 505) exit( 1 );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 506) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 507) else
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 508) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 509) fprintf( stdout, "%s: %s: Config file is correct.\n", program, config_fname );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 510) LOG( "Stop cScm Configuration Daemon." );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 511) free_resources();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 512) exit( 0 );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 513) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 514) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 515) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 516)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 517)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 518)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 519) void fatal_error_actions( void )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 520) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 521) free_resources();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 522) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 523)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 524) void sigint( int signum )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 525) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 526) (void)signum;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 527)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 528) LOG( "received SIGINT: free resources at exit" );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 529) LOG( "Stop cScm Configuration Daemon." );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 530)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 531) free_resources();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 532) exit( 0 );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 533) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 534)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 535) void sigusr( int signum )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 536) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 537) if( signum == SIGUSR1 )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 538) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 539) LOG( "signal USR1 has been received" );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 540) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 541) else if( signum == SIGUSR2 )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 542) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 543) LOG( "signal USR2 has been received" );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 544) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 545) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 546)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 547) void sighup( int signum )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 548) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 549) (void)signum;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 550)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 551) LOG( "received SIGHUP: parse config file: %s", config_fname );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 552)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 553) parse_config_file();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 554) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 555)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 556) static void set_signal_handlers()
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 557) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 558) struct sigaction sa;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 559) sigset_t set;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 560)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 561) memset( &sa, 0, sizeof( sa ) );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 562) sa.sa_handler = sighup; /* HUP: read config file */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 563) sa.sa_flags = SA_RESTART;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 564) sigemptyset( &set );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 565) sigaddset( &set, SIGHUP );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 566) sa.sa_mask = set;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 567) sigaction( SIGHUP, &sa, NULL );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 568)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 569) memset( &sa, 0, sizeof( sa ) );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 570) sa.sa_handler = sigusr; /* USR1, USR2 */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 571) sa.sa_flags = SA_RESTART;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 572) sigemptyset( &set );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 573) sigaddset( &set, SIGUSR1 );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 574) sigaddset( &set, SIGUSR2 );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 575) sa.sa_mask = set;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 576) sigaction( SIGUSR1, &sa, NULL );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 577) sigaction( SIGUSR2, &sa, NULL );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 578)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 579) memset( &sa, 0, sizeof( sa ) );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 580) sa.sa_handler = sigint; /* TERM, INT */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 581) sa.sa_flags = SA_RESTART;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 582) sigemptyset( &set );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 583) sigaddset( &set, SIGTERM );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 584) sigaddset( &set, SIGINT );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 585) sa.sa_mask = set;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 586) sigaction( SIGTERM, &sa, NULL );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 587) sigaction( SIGINT, &sa, NULL );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 588)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 589) memset( &sa, 0, sizeof( sa ) ); /* ignore SIGPIPE */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 590) sa.sa_handler = SIG_IGN;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 591) sa.sa_flags = 0;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 592) sigaction( SIGPIPE, &sa, NULL );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 593)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 594) /* на случай блокировки сигналов с помощью sigprocmask(): */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 595) sigemptyset( &blockmask );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 596) sigaddset( &blockmask, SIGHUP );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 597) sigaddset( &blockmask, SIGUSR1 );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 598) sigaddset( &blockmask, SIGUSR2 );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 599) sigaddset( &blockmask, SIGTERM );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 600) sigaddset( &blockmask, SIGINT );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 601)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 602) /* System V fork+wait does not work if SIGCHLD is ignored */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 603) signal( SIGCHLD, SIG_DFL );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 604) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 605)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 606)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 607)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 608) int main( int argc, char *argv[] )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 609) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 610) gid_t gid;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 611)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 612) set_signal_handlers();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 613)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 614) gid = getgid();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 615) setgroups( 1, &gid );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 616)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 617) fatal_error_hook = fatal_error_actions;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 618)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 619) program = basename( argv[0] );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 620) get_args( argc, argv );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 621)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 622) if( getppid() != 1 )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 623) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 624) if( run_as_daemon ) daemon( 1, 0 );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 625) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 626)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 627) init_logs();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 628) logpid();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 629)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 630) LOG( "Start cScm Configuration Daemon..." );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 631)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 632) parse_config_file();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 633)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 634) if( config_inotify ) init_config_inotify();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 635)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 636) for( ;; )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 637) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 638) int max_sd;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 639) struct timeval timeout;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 640) fd_set listen_set;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 641)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 642) /*************************************
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 643) Waiting for events from inotify_fd:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 644) */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 645) max_sd = inotify_fd + 1;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 646) FD_ZERO( &listen_set );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 647) FD_SET( inotify_fd, &listen_set );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 648)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 649) do
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 650) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 651) int rc;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 652)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 653) /*********************************************
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 654) Initialize the timeval struct to 5 seconds:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 655) */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 656) timeout.tv_sec = 5;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 657) timeout.tv_usec = 0;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 658)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 659) rc = select( max_sd, &listen_set, NULL, NULL, &timeout );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 660)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 661) /*****************************************
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 662) Check to see if the select call failed:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 663) */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 664) if( rc < 0 && errno != EINTR )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 665) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 666) WARNING( "%s: inotify select() failed", config_fname );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 667) break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 668) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 669)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 670) /************************************************
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 671) Check to see if the 5 second time out expired:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 672) */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 673) if( rc == 0 )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 674) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 675) /* Here we can output some log info. */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 676) break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 677) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 678)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 679) if( FD_ISSET( inotify_fd, &listen_set ) )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 680) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 681) ssize_t n;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 682) char *p;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 683)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 684) n = read( inotify_fd, buf, IN_BUFFER_SIZE );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 685) if( n == 0 )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 686) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 687) ERROR( "%s: read() from inotify file descriptor returned '0'", config_fname );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 688) LOG( "Stop cScm Configuration Daemon." );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 689) free_resources();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 690) exit( 1 );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 691) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 692) if( n == -1 )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 693) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 694) ERROR( "%s: read() from inotify file descriptor returned '-1'", config_fname );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 695) LOG( "Stop cScm Configuration Daemon." );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 696) free_resources();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 697) exit( 1 );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 698) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 699)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 700) for( p = buf; p < buf + n; )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 701) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 702) event = (struct inotify_event *)p;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 703) /************************************************************
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 704) в принципе, нам хватает одного события и, если мы получили
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 705) нужное событие и перечитали config file, то здесь мы можем
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 706) выйти из цикла чтения событий с помощью break
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 707) */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 708) if( check_event( event ) )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 709) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 710) LOG( "Config file '%s' has been changed. Read new config content...", config_fname );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 711) parse_config_file();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 712) break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 713) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 714) p += sizeof(struct inotify_event) + event->len;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 715) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 716)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 717) } /* End if( FD_ISSET() ) */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 718)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 719) } while( 1 );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 720)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 721) /*
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 722) Здесь мы можем выполнить действия, которые необходимы
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 723) в том случае, если в течение 5-и секунд мы не получили
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 724) ни одного сигнала об изменении дескриптора inotify_fd.
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 725) */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 726) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 727) sleep( 5 );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 728) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 729)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 730) } /* End of waiting for( ;; ) */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 731)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 732)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 733) LOG( "Stop cScm Configuration Daemon." );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 734) free_resources();
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 735)
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 736) return 0;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 737) }