bool read_config(FILE *file, bool is_active) { struct sway_config *temp_config = malloc(sizeof(struct sway_config)); config_defaults(temp_config); if (is_active) { sway_log(L_DEBUG, "Performing configuration file reload"); temp_config->reloading = true; temp_config->active = true; } bool success = true; int temp_depth = 0; // Temporary: skip all config sections with depth while (!feof(file)) { int _; char *line = read_line(file); line = strip_whitespace(line, &_); line = strip_comments(line); if (!line[0]) { goto _continue; } if (temp_depth && line[0] == '}') { temp_depth--; goto _continue; } // Any command which would require wlc to be initialized // should be queued for later execution list_t *args = split_string(line, " "); if (!is_active && ( strcmp("exec", args->items[0]) == 0 || strcmp("exec_always", args->items[0]) == 0 )) { sway_log(L_DEBUG, "Deferring command %s", line); char *cmd = malloc(strlen(line) + 1); strcpy(cmd, line); list_add(temp_config->cmd_queue, cmd); } else if (!temp_depth && !handle_command(temp_config, line)) { sway_log(L_DEBUG, "Config load failed for line %s", line); success = false; temp_config->failed = true; } list_free(args); _continue: if (line && line[strlen(line) - 1] == '{') { temp_depth++; } free(line); } if (is_active) { temp_config->reloading = false; container_map(&root_container, reset_gaps, NULL); arrange_windows(&root_container, -1, -1); } config = temp_config; return success; }
//load configuration file int config_load() { int fd; //set defaults config_defaults(); //try to open config file if((fd = file_open(path_config,"rt")) == -1) { log_warning("cannot open config file '%s'\n",path_config); return(1); } while(file_eof(fd) == 0) { char line[512],*p,*oldp; char name[256],data[256]; int i; file_gets(fd,line,512); // log_message("read line: '%s'\n",line); //eat whitespace from beginning of var name for(p = line;*p == ' ' || *p == '\t';p++); //comments if(*p == ';' || *p == '#' || *p == 0) continue; if((oldp = p = strchr(p,'=')) == 0) { log_warning("malformed configuration line, skipping\n"); continue; } //eat whitespace end of var name for(*p--=0;*p == ' ' || *p == '\t';) *p-- = 0; //eat whitespace from var data for(oldp++;*oldp == ' ' || *oldp == '\t';oldp++); strcpy(name,line); strcpy(data,oldp); for(i=0;configvars[i].type != 0;i++) { //variable match if(strcmp(name,configvars[i].name) == 0) { if(configvars[i].type == CFG_U32) *((u32*)configvars[i].data) = atoi(data); else strcpy(((char*)configvars[i].data),data); // log_message("config var '%s' set to '%s'\n",name,data); } } } file_close(fd); #ifndef PS2 log_message("creating directories\n"); mkdir(config.path_state); mkdir(config.path_cheat); mkdir(config.path_shots); #endif return(0); }
void config_load() { memset(&AQCONFIG,0,sizeof(AQCONFIG)); config_read(); if ((AQCONFIG.magic!=MAGIC) || (AQCONFIG.version!=VERSION)) { config_defaults(); config_save(); } }
bool load_main_config(const char *file, bool is_active) { input_init(); char *path; if (file != NULL) { path = strdup(file); } else { path = get_config_path(); } struct sway_config *old_config = config; config = calloc(1, sizeof(struct sway_config)); config_defaults(config); if (is_active) { sway_log(L_DEBUG, "Performing configuration file reload"); config->reloading = true; config->active = true; } config->current_config = path; list_add(config->config_chain, path); config->reading = true; bool success = load_config(path, config); if (is_active) { config->reloading = false; } if (old_config) { free_config(old_config); } config->reading = false; if (success) { update_active_bar_modifiers(); } return success; }
static int config_init( struct idmap_config *config) { int status; /* load default values */ status = config_defaults(config); if (status) { eprintf("config_defaults() failed with %d\n", status); goto out; } /* load configuration from file */ status = config_load(config, CONFIG_FILENAME); if (status) { eprintf("config_load('%s') failed with %d\n", CONFIG_FILENAME, status); goto out; } out: return status; }
int read_config(const char* file, struct hub_config* config, int allow_missing) { int ret; memset(config, 0, sizeof(struct hub_config)); config_defaults(config); ret = file_read_lines(file, config, &config_parse_line); if (ret < 0) { if (allow_missing && ret == -2) { LOG_DUMP("Using default configuration."); } else { return -1; } } return 0; }
struct sway_config *read_config(FILE *file) { struct sway_config *config = malloc(sizeof(struct sway_config)); config_defaults(config); bool success = true; int temp_depth = 0; // Temporary: skip all config sections with depth while (!feof(file)) { int _; char *line = read_line(file); line = strip_whitespace(line, &_); line = strip_comments(line); if (!line[0]) { goto _continue; } if (temp_depth && line[0] == '}') { temp_depth--; goto _continue; } if (!temp_depth && handle_command(config, line) != 0) { success = false; } _continue: if (line && line[strlen(line) - 1] == '{') { temp_depth++; } free(line); } if (!success) { exit(1); } return config; }
bool load_main_config(const char *file, bool is_active) { input_init(); char *path; if (file != NULL) { path = strdup(file); } else { path = get_config_path(); } struct sway_config *old_config = config; config = calloc(1, sizeof(struct sway_config)); if (!config) { sway_abort("Unable to allocate config"); } config_defaults(config); if (is_active) { sway_log(L_DEBUG, "Performing configuration file reload"); config->reloading = true; config->active = true; } config->current_config = path; list_add(config->config_chain, path); config->reading = true; // Read security configs bool success = true; DIR *dir = opendir(SYSCONFDIR "/sway/security.d"); if (!dir) { sway_log(L_ERROR, "%s does not exist, sway will have no security configuration" " and will probably be broken", SYSCONFDIR "/sway/security.d"); } else { list_t *secconfigs = create_list(); char *base = SYSCONFDIR "/sway/security.d/"; struct dirent *ent = readdir(dir); struct stat s; while (ent != NULL) { char *_path = malloc(strlen(ent->d_name) + strlen(base) + 1); strcpy(_path, base); strcat(_path, ent->d_name); lstat(_path, &s); if (S_ISREG(s.st_mode)) { list_add(secconfigs, _path); } ent = readdir(dir); } closedir(dir); list_qsort(secconfigs, qstrcmp); for (int i = 0; i < secconfigs->length; ++i) { char *_path = secconfigs->items[i]; if (stat(_path, &s) || s.st_uid != 0 || s.st_gid != 0 || (((s.st_mode & 0777) != 0644) && (s.st_mode & 0777) != 0444)) { sway_log(L_ERROR, "Refusing to load %s - it must be owned by root and mode 644 or 444", _path); success = false; } else { success = success && load_config(_path, config); } } free_flat_list(secconfigs); } success = success && load_config(path, config); if (is_active) { config->reloading = false; } if (old_config) { free_config(old_config); } config->reading = false; if (success) { update_active_bar_modifiers(); } return success; }
bool read_config(FILE *file, bool is_active) { struct sway_config *old_config = config; config = calloc(1, sizeof(struct sway_config)); config_defaults(config); config->reading = true; if (is_active) { sway_log(L_DEBUG, "Performing configuration file reload"); config->reloading = true; config->active = true; } bool success = true; enum cmd_status block = CMD_BLOCK_END; int line_number = 0; char *line; while (!feof(file)) { line = read_line(file); line_number++; line = strip_whitespace(line); if (line[0] == '#') { continue; } struct cmd_results *res = config_command(line, block); switch(res->status) { case CMD_FAILURE: case CMD_INVALID: sway_log(L_ERROR, "Error on line %i '%s': %s", line_number, line, res->error); success = false; break; case CMD_DEFER: sway_log(L_DEBUG, "Defferring command `%s'", line); list_add(config->cmd_queue, strdup(line)); break; case CMD_BLOCK_MODE: if (block == CMD_BLOCK_END) { block = CMD_BLOCK_MODE; } else { sway_log(L_ERROR, "Invalid block '%s'", line); } break; case CMD_BLOCK_END: switch(block) { case CMD_BLOCK_MODE: sway_log(L_DEBUG, "End of mode block"); config->current_mode = config->modes->items[0]; break; case CMD_BLOCK_END: sway_log(L_ERROR, "Unmatched }"); break; default:; } default:; } free(line); free(res); } if (is_active) { config->reloading = false; arrange_windows(&root_container, -1, -1); } if (old_config) { free_config(old_config); } config->reading = false; return success; }
/* Main rated */ int main(int argc, char *argv[]) { crew_t crew; pthread_t sig_thread; sigset_t signal_set; struct timeval begin_time, end_time; unsigned long sleep_time; unsigned long poll_time; unsigned long long polls; unsigned long long last_poll; double rate; char *conf_file = NULL; char *table; char errstr[BUFSIZE]; int ch, i, freed; struct timespec ts; dfp = stderr; /* Check argument count */ if (argc < 3) usage(argv[0]); /* Set default environment */ config_defaults(set); /* Parse the command-line. */ while ((ch = getopt(argc, argv, "c:p:dhmDt:vz")) != EOF) switch ((char) ch) { case 'c': conf_file = optarg; break; case 'd': set->dbon = FALSE; break; case 'D': set->daemon = FALSE; break; case 'h': usage(argv[0]); break; case 'm': set->multiple++; break; case 'p': pid_file = optarg; break; case 't': target_file = optarg; break; case 'v': set->verbose++; break; case 'z': set->withzeros = TRUE; break; } debug(LOW, "rated version %s starting.\n", VERSION); if (set->daemon) { if (daemon_init() < 0) fatal("Could not fork daemon!\n"); debug(LOW, "Daemon detached\n"); } pthread_mutex_init(&stats.mutex, NULL); /* Initialize signal handler */ sigemptyset(&signal_set); sigaddset(&signal_set, SIGHUP); sigaddset(&signal_set, SIGUSR1); sigaddset(&signal_set, SIGUSR2); sigaddset(&signal_set, SIGTERM); sigaddset(&signal_set, SIGINT); sigaddset(&signal_set, SIGQUIT); if (!set->multiple) checkPID(pid_file, set); if (pthread_sigmask(SIG_BLOCK, &signal_set, NULL) != 0) fatal("pthread_sigmask error\n"); /* start a thread to catch signals */ if (pthread_create(&sig_thread, NULL, sig_handler, (void *) &(signal_set)) != 0) fatal("pthread_create error\n"); /* Read configuration file to establish local environment */ if (conf_file) { if ((read_rated_config(conf_file, set)) < 0) fatal("Could not read config file: %s\n", conf_file); } else { conf_file = malloc(BUFSIZE); if (!conf_file) fatal("Fatal malloc error!\n"); for(i=0;i<CONFIG_PATHS;i++) { snprintf(conf_file, BUFSIZE, "%s%s", config_paths[i], DEFAULT_CONF_FILE); if (read_rated_config(conf_file, set) >= 0) break; if (i == CONFIG_PATHS-1) { snprintf(conf_file, BUFSIZE, "%s%s", config_paths[0], DEFAULT_CONF_FILE); if ((write_rated_config(conf_file, set)) < 0) fatal("Couldn't write config file.\n"); } } } /* these probably aren't thread safe*/ init_snmp("rated"); /* TODO only do this if we're debugging or not daemonised? */ snmp_enable_stderrlog(); /* output oids numerically - this is equivalent to -On in the snmp tools */ netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, NETSNMP_OID_OUTPUT_NUMERIC); if (set->dbon) { /* load the database driver */ /* we need a db connection before we parse the targets file so we can check and create tables */ if (!(db_init(set) && db_connect(set))) fatal("** Database error - check configuration.\n"); /* create our own internal tables */ table = db_check_and_create_data_table(RATED); if (table == NULL) fatal("** Database error - couldn't create rated table.\n"); else free(table); if (!db_check_and_create_oids_table(OIDS)) fatal("** Database error - couldn't create oids table.\n"); } /* build list of hosts to be polled */ head = hash_target_file(target_file); if (head == NULL) fatal("Error updating target list."); if (hosts < set->threads) { debug(LOW, "Number of hosts is less than configured number of threads, defaulting to %i.\n", hosts); set->threads = hosts; } debug(LOW, "Initializing threads (%d).\n", set->threads); pthread_mutex_init(&(crew.mutex), NULL); pthread_cond_init(&(crew.done), NULL); pthread_cond_init(&(crew.go), NULL); crew.current = NULL; debug(HIGH, "Starting threads..."); crew.running = set->threads; for (i = 0; i < set->threads; i++) { crew.member[i].index = i; crew.member[i].crew = &crew; if (pthread_create(&(crew.member[i].thread), NULL, poller, (void *) &(crew.member[i])) != 0) fatal("pthread_create error\n"); debug(HIGH, " %i", i); } debug(HIGH, " done\n"); /* spin waiting for all threads to start up */ debug(HIGH, "Waiting for thread startup.\n"); ts.tv_sec = 0; ts.tv_nsec = 10000000; /* 10 ms */ gettimeofday(&begin_time, NULL); while (crew.running > 0 ) { nanosleep(&ts, NULL); } gettimeofday(&end_time, NULL); debug(HIGH, "Waited %lu milliseconds for thread startup.\n", timediff(end_time, begin_time)); debug(LOW, "rated ready.\n"); /* Loop Forever Polling Target List */ while (1) { /* check if we've been signalled */ if (quitting) { debug(LOW, "Quitting: received signal %i.\n", quit_signal); if (set->dbon) db_disconnect(); /* one final stat output */ print_stats(stats, set); unlink(pid_file); exit(1); } else if (waiting) { debug(HIGH, "Processing pending SIGHUP.\n"); /* this just rebuilds the target list * so all of the targets will reset to a first poll */ /* none of the threads should be running at this point so we shouldn't need a lock */ freed = free_host_list(head); debug(HIGH, "Freed %i hosts\n", freed); head = hash_target_file(target_file); waiting = FALSE; } last_poll = stats.polls; gettimeofday(&begin_time, NULL); PT_MUTEX_LOCK(&(crew.mutex)); crew.current = head; debug(LOW, "Queue ready, broadcasting thread go condition.\n"); PT_COND_BROAD(&(crew.go)); PT_MUTEX_UNLOCK(&(crew.mutex)); /* * wait for signals from threads finishing * we have to use a do loop because when this starts up the running count will be zero * so wait at least once until we get a signal that some thread is done before checking for zero */ PT_MUTEX_LOCK(&(crew.mutex)); do { PT_COND_WAIT(&(crew.done), &(crew.mutex)); } while (crew.running > 0); PT_MUTEX_UNLOCK(&(crew.mutex)); if (quitting_now) continue; gettimeofday(&end_time, NULL); poll_time = timediff(end_time, begin_time); polls = stats.polls - last_poll; rate = ((double) polls / poll_time) * 1000; /* don't underflow */ if (poll_time < set->interval) { sleep_time = set->interval - poll_time; } else { sleep_time = 0; stats.slow++; } /* have to call this before we increment the round counter */ calc_stats(&stats, poll_time); stats.round++; debug(LOW, "Poll round %d completed %llu getnexts in %lu ms (%.0f/s).\n", stats.round, polls, poll_time, rate); /* insert the internal poll data for this round into the rated table */ if (set->dbon) db_insert(RATED, 0, end_time, stats.polls - last_poll, rate); if (set->verbose >= LOW) { print_stats(stats, set); } if (sleep_time > 0) { sleepy(sleep_time, set); } else { debug(LOW, "Slow poll, not sleeping\n"); } } /* while(1) */ exit(0); }
int main(int argc, char *argv[]) { struct timeval now; char *conf_file = NULL; double begin_time, end_time; int num_rows; int device_counter = 0; int last_active_threads = 0; long int THREAD_SLEEP = 100000; time_t nowbin; const struct tm *nowstruct; pthread_t* threads = NULL; pthread_attr_t attr; pthread_mutexattr_t mutexattr; int* ids = NULL; MYSQL mysql; MYSQL_RES *result = NULL; MYSQL_ROW mysql_row; int canexit = 0; int host_id; int i; int mutex_status = 0; int thread_status = 0; char result_string[BUFSIZE] = ""; char logmessage[LOGSIZE]; /* set start time for cacti */ gettimeofday(&now, NULL); begin_time = (double) now.tv_usec / 1000000 + now.tv_sec; /* get time for poller_output table */ if (time(&nowbin) == (time_t) - 1) printf("ERROR: Could not get time of day from time()\n"); nowstruct = localtime(&nowbin); if (strftime(start_datetime, sizeof(start_datetime), "%Y-%m-%d %H:%M:%S", nowstruct) == (size_t) 0) printf("ERROR: Could not get string from strftime()\n"); set.verbose = POLLER_VERBOSITY_HIGH; /* get static defaults for system */ config_defaults(&set); /* scan arguments for errors */ if ((argc != 1) && (argc != 3)) { printf("ERROR: Cactid requires either 0 or 2 input parameters\n"); printf("USAGE: <cactidpath>/cactid [start_id end_id]\n"); exit(-1); } /* return error if the first arg is greater than the second */ if (argc == 3) { if (atol(argv[1]) > atol(argv[2])) { printf("ERROR: Invalid row specifications. First row must be less than the second row\n"); exit(-2); } } /* read configuration file to establish local environment */ if (conf_file) { if ((read_cactid_config(conf_file, &set)) < 0) { printf("ERROR: Could not read config file: %s\n", conf_file); exit(-3); } }else{ conf_file = malloc(BUFSIZE); if (!conf_file) { printf("ERROR: Fatal malloc error!\n"); exit(-1); } for(i=0;i<CONFIG_PATHS;i++) { snprintf(conf_file, BUFSIZE, "%s%s", config_paths[i], DEFAULT_CONF_FILE); if (read_cactid_config(conf_file, &set) >= 0) { break; } if (i == CONFIG_PATHS-1) { snprintf(conf_file, BUFSIZE, "%s%s", config_paths[0], DEFAULT_CONF_FILE); } } } /* read settings table from the database to further establish environment */ read_config_options(&set); /* set the poller ID, stub for next version */ set.poller_id = 0; if (set.verbose == POLLER_VERBOSITY_DEBUG) { snprintf(logmessage, LOGSIZE, "CACTID: Version %s starting\n", VERSION); cacti_log(logmessage); } else { printf("CACTID: Version %s starting\n", VERSION); } /* connect to database */ db_connect(set.dbdb, &mysql); /* initialize SNMP */ init_snmp("cactid"); /* initialize PHP */ php_init(); /* get the id's to poll */ switch (argc) { case 1: result = db_query(&mysql, "SELECT id FROM host WHERE disabled='' ORDER BY id"); break; case 3: snprintf(result_string, sizeof(result_string), "SELECT id FROM host WHERE (disabled='' and (id >= %s and id <= %s)) ORDER BY id\0", argv[1], argv[2]); result = db_query(&mysql, result_string); break; default: break; } num_rows = mysql_num_rows(result); threads = (pthread_t *)malloc(num_rows * sizeof(pthread_t)); ids = (int *)malloc(num_rows * sizeof(int)); /* initialize threads and mutexes */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); init_mutexes(); if (set.verbose == POLLER_VERBOSITY_DEBUG) { snprintf(logmessage, LOGSIZE, "DEBUG: Initial Value of Active Threads is %i\n", active_threads); cacti_log(logmessage); } /* loop through devices until done */ while (device_counter < num_rows) { mutex_status = thread_mutex_trylock(LOCK_THREAD); switch (mutex_status) { case 0: if (last_active_threads != active_threads) { last_active_threads = active_threads; } while ((active_threads < set.threads) && (device_counter < num_rows)) { mysql_row = mysql_fetch_row(result); host_id = atoi(mysql_row[0]); ids[device_counter] = host_id; /* create child process */ thread_status = pthread_create(&threads[device_counter], &attr, child, &ids[device_counter]); switch (thread_status) { case 0: if (set.verbose == POLLER_VERBOSITY_DEBUG) { snprintf(logmessage, LOGSIZE, "DEBUG: Valid Thread to be Created\n"); cacti_log(logmessage); } device_counter++; active_threads++; if (set.verbose == POLLER_VERBOSITY_DEBUG) { snprintf(logmessage, LOGSIZE, "DEBUG: The Value of Active Threads is %i\n", active_threads); cacti_log(logmessage); } break; case EAGAIN: snprintf(logmessage, LOGSIZE, "ERROR: The System Lacked the Resources to Create a Thread\n"); cacti_log(logmessage); break; case EFAULT: snprintf(logmessage, LOGSIZE, "ERROR: The Thread or Attribute Was Invalid\n"); cacti_log(logmessage); break; case EINVAL: snprintf(logmessage, LOGSIZE, "ERROR: The Thread Attribute is Not Initialized\n"); cacti_log(logmessage); break; default: snprintf(logmessage, LOGSIZE, "ERROR: Unknown Thread Creation Error\n"); cacti_log(logmessage); break; } usleep(THREAD_SLEEP); } thread_mutex_unlock(LOCK_THREAD); break; case EBUSY: snprintf(logmessage, LOGSIZE, "ERROR: Deadlock Occured\n"); cacti_log(logmessage); break; case EINVAL: snprintf(logmessage, LOGSIZE, "ERROR: Attempt to Unlock an Uninitialized Mutex\n"); cacti_log(logmessage); break; case EFAULT: snprintf(logmessage, LOGSIZE, "ERROR: Attempt to Unlock an Invalid Mutex\n"); cacti_log(logmessage); break; default: snprintf(logmessage, LOGSIZE, "ERROR: Unknown Mutex Lock Error Code Returned\n"); cacti_log(logmessage); break; } usleep(THREAD_SLEEP); } /* wait for all threads to complete */ while (canexit == 0) { if (thread_mutex_trylock(LOCK_THREAD) != EBUSY) { if (last_active_threads != active_threads) { last_active_threads = active_threads; } if (active_threads == 0) { canexit = 1; } thread_mutex_unlock(LOCK_THREAD); } usleep(THREAD_SLEEP); } /* print out stats */ gettimeofday(&now, NULL); /* update the db for |data_time| on graphs */ db_insert(&mysql, "replace into settings (name,value) values ('date',NOW())"); db_insert(&mysql, "insert into poller_time (poller_id, start_time, end_time) values (0, NOW(), NOW())"); /* cleanup and exit program */ pthread_attr_destroy(&attr); pthread_mutexattr_destroy(&mutexattr); if (set.verbose == POLLER_VERBOSITY_DEBUG) { cacti_log("DEBUG: Thread Cleanup Complete\n"); } /* close the php script server */ php_close(); if (set.verbose == POLLER_VERBOSITY_DEBUG) { cacti_log("DEBUG: PHP Script Server Pipes Closed\n"); } /* free malloc'd variables */ free(threads); free(ids); free(conf_file); if (set.verbose == POLLER_VERBOSITY_DEBUG) { cacti_log("DEBUG: Allocated Variable Memory Freed\n"); } /* close mysql */ mysql_free_result(result); mysql_close(&mysql); if (set.verbose == POLLER_VERBOSITY_DEBUG) { cacti_log("DEBUG: MYSQL Free & Close Completed\n"); } /* finally add some statistics to the log and exit */ end_time = (double) now.tv_usec / 1000000 + now.tv_sec; if ((set.verbose >= POLLER_VERBOSITY_MEDIUM) && (argc != 1)) { snprintf(logmessage, LOGSIZE, "Time: %.4f s, Threads: %i, Hosts: %i\n", (end_time - begin_time), set.threads, num_rows); cacti_log(logmessage); } else { printf("CACTID: Execution Time: %.4f s, Threads: %i, Hosts: %i\n", (end_time - begin_time), set.threads, num_rows); } exit(0); }
static char *get_config_path() { char *home = getenv("HOME"); if (home) { home = strdup(getenv("HOME")); } char *config = getenv("XDG_CONFIG_HOME"); if (config) { config = strdup(getenv("XDG_CONFIG_HOME")); } else if (home) { const char *def = "/.config"; config = malloc(strlen(home) + strlen(def) + 1); strcpy(config, home); strcat(config, def); } else { home = strdup(""); config = strdup(""); } // Set up a temporary config for holding set variables struct sway_config *temp_config = malloc(sizeof(struct sway_config)); config_defaults(temp_config); const char *set_home = "set $home "; char *_home = malloc(strlen(home) + strlen(set_home) + 1); strcpy(_home, set_home); strcat(_home, home); handle_command(temp_config, _home); free(_home); const char *set_config = "set $config "; char *_config = malloc(strlen(config) + strlen(set_config) + 1); strcpy(_config, set_config); strcat(_config, config); handle_command(temp_config, _config); free(_config); char *test = NULL; int i; for (i = 0; i < (int)(sizeof(search_paths) / sizeof(char *)); ++i) { test = strdup(search_paths[i]); test = do_var_replacement(temp_config, test); sway_log(L_DEBUG, "Checking for config at %s", test); if (exists(test)) { goto _continue; } free(test); test = NULL; } sway_log(L_DEBUG, "Trying to find config in XDG_CONFIG_DIRS"); char *xdg_config_dirs = getenv("XDG_CONFIG_DIRS"); if (xdg_config_dirs != NULL) { list_t *paths = split_string(xdg_config_dirs, ":"); char *name = "/sway/config"; int i; for (i = 0; i < paths->length; i++ ) { test = malloc(strlen(paths->items[i]) + strlen(name) + 1); strcpy(test, paths->items[i]); strcat(test, name); if (exists(test)) { free_flat_list(paths); return test; } free(test); test = NULL; } free_flat_list(paths); } _continue: free_config(temp_config); free(home); free(config); return test; }
config_t* config_parse(TCHAR* path) { FILE* file = fopen(path, "r"); TCHAR buffer[TEXTLEN], param[CONFIG_STR_MAXSIZE]; size_t len, count; mask_t* msk; config_t* conf = malloc(sizeof(config_t)); config_defaults(conf); if (file) { while (fgets(buffer, TEXTLEN, file)) { len = sizeof(CONFIG_STR_COMMENTS) - 1; strncpy(param, buffer, len); param[len] = '\0'; if (!stricmp(CONFIG_STR_COMMENTS, param)) { strtok(buffer, " =-\n"); conf->comments = atoi(strtok(NULL, " =-\n")); continue; } len = sizeof(CONFIG_STR_LABELS) - 1; strncpy(param, buffer, len); param[len] = '\0'; if (!stricmp(CONFIG_STR_LABELS, param)) { strtok(buffer, " =-\n"); conf->labels = atoi(strtok(NULL, " =-\n")); continue; } len = sizeof(CONFIG_STR_COLLISIONS) - 1; strncpy(param, buffer, len); param[len] = '\0'; if (!stricmp(CONFIG_STR_COLLISIONS, param)) { strtok(buffer, " =-\n"); conf->collisionchecks = atoi(strtok(NULL, " =-\n")); continue; } len = sizeof(CONFIG_STR_APPLYTO) - 1; strncpy(param, buffer, len); param[len] = '\0'; if (!stricmp(CONFIG_STR_APPLYTO, param)) { strtok(buffer, " =-\n"); conf->applytodebuggee = atoi(strtok(NULL, " =-\n")); continue; } len = sizeof(CONFIG_STR_AUTOIMPORT) - 1; strncpy(param, buffer, len); param[len] = '\0'; if (!stricmp(CONFIG_STR_AUTOIMPORT, param)) { strtok(buffer, " =-\n"); conf->aimport = atoi(strtok(NULL, " =-\n")); continue; } len = sizeof(CONFIG_STR_DEMANGLE) - 1; strncpy(param, buffer, len); param[len] = '\0'; if (!stricmp(CONFIG_STR_DEMANGLE, param)) { strtok(buffer, " =-\n"); conf->demangle = atoi(strtok(NULL, " =-\n")); continue; } len = sizeof(CONFIG_STR_USEMASKS) - 1; strncpy(param, buffer, len); param[len] = '\0'; if (!stricmp(CONFIG_STR_USEMASKS, param)) { strtok(buffer, " =-\n"); conf->usemasks = atoi(strtok(NULL, " =-\n")); continue; } len = sizeof(CONFIG_STR_MASKS) - 1; strncpy(param, buffer, len); param[len] = '\0'; if (!stricmp(CONFIG_STR_MASKS, param)) { strtok(buffer, " =-\n"); conf->masks = list_create(); count = atoi(strtok(NULL, " =-\n")); while (conf->masks->count < count && fgets(buffer, TEXTLEN, file)) { msk = list_addmask(conf->masks, strtok(buffer, "\n")); if (msk->errcode) { free(msk); } } } } fclose(file); } return conf; }
/* Main rtgpoll */ int main(int argc, char *argv[]) { crew_t crew; pthread_t sig_thread; sigset_t signal_set; struct timeval now; double begin_time, end_time, sleep_time; char *conf_file = NULL; char errstr[BUFSIZE]; int ch, i; dfp = stderr; /* Check argument count */ if (argc < 3) usage(argv[0]); /* Set default environment */ config_defaults(set); /* Parse the command-line. */ while ((ch = getopt(argc, argv, "c:p:dhmDt:vz")) != EOF) switch ((char) ch) { case 'c': conf_file = optarg; break; case 'd': set->dboff = TRUE; break; case 'D': set->daemon = FALSE; break; case 'h': usage(argv[0]); break; case 'm': set->multiple++; break; case 'p': pid_file = optarg; break; case 't': target_file = optarg; break; case 'v': set->verbose++; break; case 'z': set->withzeros = TRUE; break; } debug(LOW, "RTG version %s starting.\n", VERSION); if (set->daemon) { if (daemon_init() < 0) fatal("Could not fork daemon!\n"); debug(LOW, "Daemon detached\n"); } /* Initialize signal handler */ sigemptyset(&signal_set); sigaddset(&signal_set, SIGHUP); sigaddset(&signal_set, SIGUSR1); sigaddset(&signal_set, SIGUSR2); sigaddset(&signal_set, SIGTERM); sigaddset(&signal_set, SIGINT); sigaddset(&signal_set, SIGQUIT); if (!set->multiple) checkPID(pid_file, set); if (pthread_sigmask(SIG_BLOCK, &signal_set, NULL) != 0) printf("pthread_sigmask error\n"); /* Read configuration file to establish local environment */ if (conf_file) { if ((read_rtg_config(conf_file, set)) < 0) fatal("Could not read config file: %s\n", conf_file); } else { conf_file = malloc(BUFSIZE); if (!conf_file) fatal("Fatal malloc error!\n"); for(i=0;i<CONFIG_PATHS;i++) { snprintf(conf_file, BUFSIZE, "%s%s", config_paths[i], DEFAULT_CONF_FILE); if (read_rtg_config(conf_file, set) >= 0) break; if (i == CONFIG_PATHS-1) { snprintf(conf_file, BUFSIZE, "%s%s", config_paths[0], DEFAULT_CONF_FILE); if ((write_rtg_config(conf_file, set)) < 0) fatal("Couldn't write config file.\n"); } } } /* hash list of targets to be polled */ init_hash(); entries = hash_target_file(target_file); if (entries <= 0) fatal("Error updating target list."); debug(LOW, "Initializing threads (%d).\n", set->threads); pthread_mutex_init(&(crew.mutex), NULL); pthread_cond_init(&(crew.done), NULL); pthread_cond_init(&(crew.go), NULL); crew.work_count = 0; /* Initialize the SNMP session */ debug(LOW, "Initializing SNMP (port %d).\n", set->snmp_port); init_snmp("RTG"); /* Attempt to connect to the MySQL Database */ #ifndef FEATURES #if HAVE_MYSQL if (!(set->dboff)) { if (mysql_dbconnect(set->dbdb, &mysql) < 0) fatal("** Database error - check configuration.\n"); if (!mysql_ping(&mysql)) debug(LOW, "connected.\n"); else fatal("server not responding.\n"); } #endif #else #if HAVE_MYSQL my_init(); #endif #endif debug(HIGH, "\nStarting threads.\n"); for (i = 0; i < set->threads; i++) { crew.member[i].index = i; crew.member[i].crew = &crew; if (pthread_create(&(crew.member[i].thread), NULL, poller, (void *) &(crew.member[i])) != 0) printf("pthread_create error\n"); } if (pthread_create(&sig_thread, NULL, sig_handler, (void *) &(signal_set)) != 0) printf("pthread_create error\n"); /* give threads time to start up */ sleep(1); debug(LOW, "RTG Ready.\n"); /* Loop Forever Polling Target List */ while (1) { lock = TRUE; gettimeofday(&now, NULL); begin_time = (double) now.tv_usec / 1000000 + now.tv_sec; PT_MUTEX_LOCK(&(crew.mutex)); init_hash_walk(); current = getNext(); crew.work_count = entries; PT_MUTEX_UNLOCK(&(crew.mutex)); if (set->verbose >= LOW) { if (set->daemon) sysloginfo("Queue ready, broadcasting thread go condition."); else timestamp("Queue ready, broadcasting thread go condition."); } PT_COND_BROAD(&(crew.go)); PT_MUTEX_LOCK(&(crew.mutex)); while (crew.work_count > 0) { PT_COND_WAIT(&(crew.done), &(crew.mutex)); } PT_MUTEX_UNLOCK(&(crew.mutex)); gettimeofday(&now, NULL); lock = FALSE; end_time = (double) now.tv_usec / 1000000 + now.tv_sec; stats.poll_time = end_time - begin_time; stats.round++; sleep_time = set->interval - stats.poll_time; if (waiting) { debug(HIGH, "Processing pending SIGHUP.\n"); entries = hash_target_file(target_file); waiting = FALSE; } if (set->verbose >= LOW) { snprintf(errstr, sizeof(errstr), "Poll round %d complete.", stats.round); if (set->daemon) sysloginfo(errstr); else timestamp(errstr); print_stats(stats, set); } if (sleep_time <= 0) stats.slow++; else sleepy(sleep_time, set); } /* while */ #ifndef FEATURES #if HAVE_MYSQL /* Disconnect from the MySQL Database, exit. */ if (!(set->dboff)) mysql_dbdisconnect(&mysql); #endif #endif exit(0); }
/*! \fn main(int argc, char *argv[]) * \brief The Cactid program entry point * \param argc The number of arguments passed to the function plus one (+1) * \param argv An array of the command line arguments * * The Cactid entry point. This function performs the following tasks. * 1) Processes command line input parameters * 2) Processes the Cactid configuration file to obtain database access information * 3) Process runtime parameters from the settings table * 4) Initialize the runtime threads and mutexes for the threaded environment * 5) Initialize Net-SNMP, MySQL, and the PHP Script Server (if required) * 6) Spawns X threads in order to process hosts * 7) Loop until either all hosts have been processed or until the poller runtime * has been exceeded * 8) Close database and free variables * 9) Log poller process statistics if required * 10) Exit * * Note: Command line runtime parameters override any database settings. * * \return 0 if SUCCESS, or -1 if FAILED * */ int main(int argc, char *argv[]) { struct timeval now; char *conf_file = NULL; double begin_time, end_time, current_time; int poller_interval; int num_rows; int device_counter = 0; int poller_counter = 0; int last_active_threads = 0; long int EXTERNAL_THREAD_SLEEP = 100000; long int internal_thread_sleep; time_t nowbin; struct tm now_time; struct tm *now_ptr; pthread_t* threads = NULL; pthread_attr_t attr; int* ids = NULL; MYSQL mysql; MYSQL_RES *result = NULL; MYSQL_ROW mysql_row; int canexit = 0; int host_id; int i; int mutex_status = 0; int thread_status = 0; UNUSED_PARAMETER(argc); /* we operate strictly with argv */ /* establish php processes and initialize space */ php_processes = (php_t*) calloc(MAX_PHP_SERVERS, sizeof(php_t)); for (i = 0; i < MAX_PHP_SERVERS; i++) { php_processes[i].php_state = PHP_BUSY; } /* set start time for cacti */ begin_time = get_time_as_double(); /* get time for poller_output table */ if (time(&nowbin) == (time_t) - 1) { die("ERROR: Could not get time of day from time()\n"); } localtime_r(&nowbin,&now_time); now_ptr = &now_time; if (strftime(start_datetime, sizeof(start_datetime), "%Y-%m-%d %H:%M:%S", now_ptr) == (size_t) 0) { die("ERROR: Could not get string from strftime()\n"); } /* set default verbosity */ set.log_level = POLLER_VERBOSITY_LOW; /* get static defaults for system */ config_defaults(); /*! ---------------------------------------------------------------- * PROCESS COMMAND LINE * * Run through the list of ARGV words looking for parameters we * know about. Most have two flavors (-C + --conf), and many * themselves take a parameter. * * These parameters can be structured in two ways: * * --conf=FILE both parts in one argv[] string * --conf FILE two separate argv[] strings * * We set "arg" to point to "--conf", and "opt" to point to FILE. * The helper routine * * In each loop we set "arg" to next argv[] string, then look * to see if it has an equal sign. If so, we split it in half * and point to the option separately. * * NOTE: most direction to the program is given with dash-type * parameters, but we also allow standalone numeric device IDs * in "first last" format: this is how poller.php calls this * program. */ /* initialize some global variables */ set.start_host_id = -1; set.end_host_id = -1; set.php_initialized = FALSE; set.logfile_processed = FALSE; set.parent_fork = CACTID_PARENT; for (argv++; *argv; argv++) { char *arg = *argv; char *opt = strchr(arg, '='); /* pick off the =VALUE part */ if (opt) *opt++ = '\0'; if (STRIMATCH(arg, "-f") || STRIMATCH(arg, "--first")) { if (HOSTID_DEFINED(set.start_host_id)) { die("ERROR: %s can only be used once", arg); } set.start_host_id = atoi(opt = getarg(opt, &argv)); if (!HOSTID_DEFINED(set.start_host_id)) { die("ERROR: '%s=%s' is invalid first-host ID", arg, opt); } } else if (STRIMATCH(arg, "-l") || STRIMATCH(arg, "--last")) { if (HOSTID_DEFINED(set.end_host_id)) { die("ERROR: %s can only be used once", arg); } set.end_host_id = atoi(opt = getarg(opt, &argv)); if (!HOSTID_DEFINED(set.end_host_id)) { die("ERROR: '%s=%s' is invalid last-host ID", arg, opt); } } else if (STRIMATCH(arg, "-p") || STRIMATCH(arg, "--poller")) { set.poller_id = atoi(getarg(opt, &argv)); } else if (STRIMATCH(arg, "-h") || STRIMATCH(arg, "-v") || STRIMATCH(arg, "--help") || STRIMATCH(arg, "--version")) { display_help(); exit(EXIT_SUCCESS); } else if (STRIMATCH(arg, "-O") || STRIMATCH(arg, "--option")) { char *setting = getarg(opt, &argv); char *value = strchr(setting, ':'); if (*value) { *value++ = '\0'; }else{ die("ERROR: -O requires setting:value"); } set_option(setting, value); } else if (STRIMATCH(arg, "-R") || STRIMATCH(arg, "--readonly") || STRIMATCH(arg, "--read-only")) { set.SQL_readonly = TRUE; } else if (STRIMATCH(arg, "-C") || STRIMATCH(arg, "--conf")) { conf_file = strdup(getarg(opt, &argv)); } else if (STRIMATCH(arg, "-S") || STRIMATCH(arg, "--stdout")) { set_option("log_destination", "STDOUT"); } else if (STRIMATCH(arg, "-L") || STRIMATCH(arg, "--log")) { set_option("log_destination", getarg(opt, &argv)); } else if (STRIMATCH(arg, "-V") || STRIMATCH(arg, "--verbosity")) { set_option("log_verbosity", getarg(opt, &argv)); } else if (STRIMATCH(arg, "--snmponly") || STRIMATCH(arg, "--snmp-only")) { set.snmponly = TRUE; } else if (!HOSTID_DEFINED(set.start_host_id) && all_digits(arg)) { set.start_host_id = atoi(arg); } else if (!HOSTID_DEFINED(set.end_host_id) && all_digits(arg)) { set.end_host_id = atoi(arg); } else { die("ERROR: %s is an unknown command-line parameter", arg); } } /* we require either both the first and last hosts, or niether host */ if (HOSTID_DEFINED(set.start_host_id) != HOSTID_DEFINED(set.end_host_id)) { die("ERROR: must provide both -f/-l, or neither"); } if (set.start_host_id > set.end_host_id) { die("ERROR: Invalid row spec; first host_id must be less than the second"); } /* read configuration file to establish local environment */ if (conf_file) { if ((read_cactid_config(conf_file)) < 0) { die("ERROR: Could not read config file: %s\n", conf_file); } }else{ if (!(conf_file = calloc(1, BUFSIZE))) { die("ERROR: Fatal malloc error: cactid.c conf_file!\n"); } for (i=0; i<CONFIG_PATHS; i++) { snprintf(conf_file, BUFSIZE-1, "%s%s", config_paths[i], DEFAULT_CONF_FILE); if (read_cactid_config(conf_file) >= 0) { break; } if (i == CONFIG_PATHS-1) { snprintf(conf_file, BUFSIZE-1, "%s%s", config_paths[0], DEFAULT_CONF_FILE); } } } /* read settings table from the database to further establish environment */ read_config_options(); /* set the poller interval for those who use less than 5 minute intervals */ if (set.poller_interval == 0) { poller_interval = 300; }else { poller_interval = set.poller_interval; } /* calculate the external_tread_sleep value */ internal_thread_sleep = EXTERNAL_THREAD_SLEEP * set.num_parent_processes / 2; if (set.log_level == POLLER_VERBOSITY_DEBUG) { CACTID_LOG_DEBUG(("CACTID: Version %s starting\n", VERSION)); }else{ printf("CACTID: Version %s starting\n", VERSION); } /* connect to database */ db_connect(set.dbdb, &mysql); /* initialize SNMP */ CACTID_LOG_DEBUG(("CACTID: Initializing Net-SNMP API\n")); snmp_cactid_init(); /* initialize PHP if required */ CACTID_LOG_DEBUG(("CACTID: Initializing PHP Script Server\n")); /* tell cactid that it is parent, and set the poller id */ set.parent_fork = CACTID_PARENT; set.poller_id = 0; /* initialize the script server */ if (set.php_required) { php_init(PHP_INIT); set.php_initialized = TRUE; set.php_current_server = 0; } /* obtain the list of hosts to poll */ { char querybuf[256], *qp = querybuf; qp += sprintf(qp, "SELECT id FROM host"); qp += sprintf(qp, " WHERE disabled=''"); qp += append_hostrange(qp, "id"); /* AND id BETWEEN a AND b */ qp += sprintf(qp, " ORDER BY id"); result = db_query(&mysql, querybuf); } num_rows = mysql_num_rows(result) + 1; /* add 1 for host = 0 */ if (!(threads = (pthread_t *)malloc(num_rows * sizeof(pthread_t)))) { die("ERROR: Fatal malloc error: cactid.c threads!\n"); } if (!(ids = (int *)malloc(num_rows * sizeof(int)))) { die("ERROR: Fatal malloc error: cactid.c host id's!\n"); } /* initialize threads and mutexes */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); init_mutexes(); CACTID_LOG_DEBUG(("DEBUG: Initial Value of Active Threads is %i\n", active_threads)); /* tell fork processes that they are now active */ set.parent_fork = CACTID_FORK; /* loop through devices until done */ while ((device_counter < num_rows) && (canexit == 0)) { mutex_status = thread_mutex_trylock(LOCK_THREAD); switch (mutex_status) { case 0: if (last_active_threads != active_threads) { last_active_threads = active_threads; } while ((active_threads < set.threads) && (device_counter < num_rows)) { if (device_counter > 0) { mysql_row = mysql_fetch_row(result); host_id = atoi(mysql_row[0]); ids[device_counter] = host_id; }else{ ids[device_counter] = 0; } /* create child process */ thread_status = pthread_create(&threads[device_counter], &attr, child, &ids[device_counter]); switch (thread_status) { case 0: CACTID_LOG_DEBUG(("DEBUG: Valid Thread to be Created\n")); device_counter++; active_threads++; CACTID_LOG_DEBUG(("DEBUG: The Value of Active Threads is %i\n", active_threads)); break; case EAGAIN: CACTID_LOG(("ERROR: The System Lacked the Resources to Create a Thread\n")); break; case EFAULT: CACTID_LOG(("ERROR: The Thread or Attribute Was Invalid\n")); break; case EINVAL: CACTID_LOG(("ERROR: The Thread Attribute is Not Initialized\n")); break; default: CACTID_LOG(("ERROR: Unknown Thread Creation Error\n")); break; } usleep(internal_thread_sleep); /* get current time and exit program if time limit exceeded */ if (poller_counter >= 20) { current_time = get_time_as_double(); if ((current_time - begin_time + 6) > poller_interval) { CACTID_LOG(("ERROR: Cactid Timed Out While Processing Hosts Internal\n")); canexit = 1; break; } poller_counter = 0; }else{ poller_counter++; } } thread_mutex_unlock(LOCK_THREAD); break; case EDEADLK: CACTID_LOG(("ERROR: Deadlock Occured\n")); break; case EBUSY: break; case EINVAL: CACTID_LOG(("ERROR: Attempt to Unlock an Uninitialized Mutex\n")); break; case EFAULT: CACTID_LOG(("ERROR: Attempt to Unlock an Invalid Mutex\n")); break; default: CACTID_LOG(("ERROR: Unknown Mutex Lock Error Code Returned\n")); break; } usleep(internal_thread_sleep); /* get current time and exit program if time limit exceeded */ if (poller_counter >= 20) { current_time = get_time_as_double(); if ((current_time - begin_time + 6) > poller_interval) { CACTID_LOG(("ERROR: Cactid Timed Out While Processing Hosts Internal\n")); canexit = 1; break; } poller_counter = 0; }else{ poller_counter++; } } /* wait for all threads to complete */ while (canexit == 0) { if (thread_mutex_trylock(LOCK_THREAD) == 0) { if (last_active_threads != active_threads) { last_active_threads = active_threads; } if (active_threads == 0) { canexit = 1; } thread_mutex_unlock(LOCK_THREAD); } usleep(EXTERNAL_THREAD_SLEEP); /* get current time and exit program if time limit exceeded */ if (poller_counter >= 20) { current_time = get_time_as_double(); if ((current_time - begin_time + 6) > poller_interval) { CACTID_LOG(("ERROR: Cactid Timed Out While Processing Hosts Internal\n")); canexit = 1; break; } poller_counter = 0; }else{ poller_counter++; } } /* tell Cactid that it is now parent */ set.parent_fork = CACTID_PARENT; /* print out stats */ gettimeofday(&now, NULL); /* update the db for |data_time| on graphs */ db_insert(&mysql, "replace into settings (name,value) values ('date',NOW())"); db_insert(&mysql, "insert into poller_time (poller_id, start_time, end_time) values (0, NOW(), NOW())"); /* cleanup and exit program */ pthread_attr_destroy(&attr); CACTID_LOG_DEBUG(("DEBUG: Thread Cleanup Complete\n")); /* close the php script server */ if (set.php_required) { php_close(PHP_INIT); } CACTID_LOG_DEBUG(("DEBUG: PHP Script Server Pipes Closed\n")); /* free malloc'd variables */ free(threads); free(ids); free(conf_file); CACTID_LOG_DEBUG(("DEBUG: Allocated Variable Memory Freed\n")); /* shutdown SNMP */ snmp_cactid_close(); CACTID_LOG_DEBUG(("CACTID: Net-SNMP API Shutdown Completed\n")); /* close mysql */ mysql_free_result(result); mysql_close(&mysql); CACTID_LOG_DEBUG(("DEBUG: MYSQL Free & Close Completed\n")); /* finally add some statistics to the log and exit */ end_time = TIMEVAL_TO_DOUBLE(now); CACTID_LOG_MEDIUM(("Time: %.4f s, Threads: %i, Hosts: %i\n", (end_time - begin_time), set.threads, num_rows)); exit(EXIT_SUCCESS); }