Example #1
0
MYSQL_RES *db_query(MYSQL *mysql, char *query) {
    MYSQL_RES *mysql_res;
    int return_code;
    int retries;
    int error;

    thread_mutex_lock(LOCK_MYSQL);
    retries = 0;
    error = FALSE;
    while (retries < 3) {
        return_code = mysql_query(mysql, query);
        if (return_code) {
            cacti_log("MYSQL: ERROR encountered while attempting to retrieve records from query\n");
            error = TRUE;
        } else {
            mysql_res = mysql_store_result(mysql);
            error = FALSE;
            break;
        }
        usleep(1000);
        retries++;
    }
    thread_mutex_unlock(LOCK_MYSQL);

    if (error) {
        cacti_log("MYSQL: ERROR could not obtain results from database, exiting\n");
        exit_cactid();
    }

    return mysql_res;
}
Example #2
0
void *child(void * arg) {
    extern int active_threads;
    int host_id = *(int *) arg;
    char logmessage[LOGSIZE];

    if (set.verbose == POLLER_VERBOSITY_DEBUG) {
        snprintf(logmessage, LOGSIZE, "DEBUG: In Poller, About to Start Polling of Host\n");
        cacti_log(logmessage);
    }

    if (active_threads == 1) {
        if (set.verbose == POLLER_VERBOSITY_DEBUG) {
            snprintf(logmessage, LOGSIZE, "DEBUG: This is where popen DEADLOCKs errors occur\n");
        }
    }

    poll_host(host_id);

    thread_mutex_lock(LOCK_THREAD);
    active_threads = active_threads - 1;
    thread_mutex_unlock(LOCK_THREAD);

    if (set.verbose == POLLER_VERBOSITY_DEBUG) {
        snprintf(logmessage, LOGSIZE, "DEBUG: The Value of Active Threads is %i\n" ,active_threads);
        cacti_log(logmessage);
    }

    pthread_exit(0);
}
Example #3
0
int db_connect(char *database, MYSQL *mysql) {
	char logmessage[LOGSIZE];
	int tries;
	int result;
	char *hostname;
	char *socket;

	if ((hostname = strdup(set.dbhost)) == NULL) {
		snprintf(logmessage, LOGSIZE-1, "ERROR: malloc(): strdup() failed\n");
		cacti_log(logmessage);
		return (FALSE);
	}
	if ((socket = strstr(hostname,":"))) *socket++ = 0x0;

	/* initialalize my variables */
	tries = 10;
	result = 0;

	if (set.verbose == POLLER_VERBOSITY_DEBUG) {
		snprintf(logmessage, LOGSIZE-1, "MYSQL: Connecting to MySQL database '%s' on '%s'...\n", database, set.dbhost);
		cacti_log(logmessage);
	}

	thread_mutex_lock(LOCK_MYSQL);
	mysql_init(mysql);
	
	while (tries > 0){
		tries--;
		if (!mysql_real_connect(mysql, hostname, set.dbuser, set.dbpass, database, set.dbport, socket, 0)) {
			if (set.verbose == POLLER_VERBOSITY_DEBUG) {
				snprintf(logmessage, LOGSIZE-1, "MYSQL: Connection Failed: %s\n", mysql_error(mysql));
				cacti_log(logmessage);
			}
			result = 1;
		}else{
			tries = 0;
			result = 0;
			if (set.verbose == POLLER_VERBOSITY_DEBUG) {
				snprintf(logmessage, LOGSIZE-1, "MYSQL: Connected to MySQL database '%s' on '%s'...\n", database, set.dbhost);
				cacti_log(logmessage);
			}
		}
	}

	free(hostname);

	if (result == 1){
		snprintf(logmessage, LOGSIZE-1, "MYSQL: Connection Failed: %s\n", mysql_error(mysql));
		cacti_log(logmessage);
		thread_mutex_unlock(LOCK_MYSQL);
		exit_cactid();
	}else{
		thread_mutex_unlock(LOCK_MYSQL);
		return (0);
	}
}
Example #4
0
int db_insert(MYSQL *mysql, char *query) {
	char logmessage[LOGSIZE];

	if (set.verbose == POLLER_VERBOSITY_DEBUG) {
		snprintf(logmessage, LOGSIZE-1, "DEBUG: SQLCMD: %s\n", query);
		cacti_log(logmessage);
	}

	thread_mutex_lock(LOCK_MYSQL);
	if (mysql_query(mysql, query)) {
		snprintf(logmessage, LOGSIZE-1, "ERROR: Problem with MySQL: %s\n", mysql_error(mysql));
		cacti_log(logmessage);
		thread_mutex_unlock(LOCK_MYSQL);
		return (FALSE);
	}else{
		thread_mutex_unlock(LOCK_MYSQL);
		return (TRUE);
	}
}
Example #5
0
MYSQL_RES *db_query(MYSQL *mysql, char *query) {
	MYSQL_RES *mysql_res;
	int return_code;
	
	thread_mutex_lock(LOCK_MYSQL);
 	return_code = mysql_query(mysql, query);
	if (return_code) {
		cacti_log("MYSQL: ERROR encountered while attempting to retrieve records from query\n");
		thread_mutex_unlock(LOCK_MYSQL);
		exit_cactid();
	}else{
		mysql_res = mysql_store_result(mysql);
		thread_mutex_unlock(LOCK_MYSQL);
	}

	return mysql_res;
}
Example #6
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);
}
Example #7
0
void poll_host(int host_id) {
    char query1[BUFSIZE];
    char query2[BUFSIZE];
    char *query3;
    char query4[BUFSIZE];
    char errstr[512];
    int num_rows;
    int host_status;
    int assert_fail = 0;
    char *poll_result = NULL;
    char logmessage[LOGSIZE];
    char update_sql[BUFSIZE];

    reindex_t *reindex;
    target_t *entry;
    host_t *host;
    ping_t *ping;

    MYSQL mysql;
    MYSQL_RES *result;
    MYSQL_ROW row;

    /* allocate host and ping structures with appropriate values */
    host = (host_t *) malloc(sizeof(host_t));
    ping = (ping_t *) malloc(sizeof(ping_t));

#ifndef OLD_MYSQL
    mysql_thread_init();
#endif

    snprintf(query1, sizeof(query1), "select action,hostname,snmp_community,snmp_version,snmp_username,snmp_password,rrd_name,rrd_path,arg1,arg2,arg3,local_data_id,rrd_num,snmp_port,snmp_timeout from poller_item where host_id=%i order by rrd_path,rrd_name", host_id);
    snprintf(query2, sizeof(query2), "select id, hostname,snmp_community,snmp_version,snmp_port,snmp_timeout,status,status_event_count,status_fail_date,status_rec_date,status_last_error,min_time,max_time,cur_time,avg_time,total_polls,failed_polls,availability from host where id=%i", host_id);
    snprintf(query4, sizeof(query4), "select data_query_id,action,op,assert_value,arg1 from poller_reindex where host_id=%i", host_id);

    db_connect(set.dbdb, &mysql);

    /* get data about this host */
    result = db_query(&mysql, query2);
    num_rows = (int)mysql_num_rows(result);

    if (num_rows != 1) {
        snprintf(logmessage, LOGSIZE, "Host[%i] ERROR: Unknown Host ID", host_id);
        cacti_log(logmessage);
        return;
    }

    row = mysql_fetch_row(result);

    /* populate host structure */
    host->id = atoi(row[0]);
    if (row[1] != NULL) snprintf(host->hostname, sizeof(host->hostname), "%s", row[1]);
    if (row[2] != NULL) snprintf(host->snmp_community, sizeof(host->snmp_community), "%s", row[2]);
    host->snmp_version = atoi(row[3]);
    host->snmp_port = atoi(row[4]);
    host->snmp_timeout = atoi(row[5]);
    if (row[6] != NULL) host->status = atoi(row[6]);
    host->status_event_count = atoi(row[7]);
    snprintf(host->status_fail_date, sizeof(host->status_fail_date), "%s", row[8]);
    snprintf(host->status_rec_date, sizeof(host->status_rec_date), "%s", row[9]);
    snprintf(host->status_last_error, sizeof(host->status_last_error), "%s", row[10]);
    host->min_time = atof(row[11]);
    host->max_time = atof(row[12]);
    host->cur_time = atof(row[13]);
    host->avg_time = atof(row[14]);
    host->total_polls = atoi(row[15]);
    host->failed_polls = atoi(row[16]);
    host->availability = atof(row[17]);

    host->ignore_host = 0;

    /* initialize SNMP */
    snmp_host_init(host);

    /* perform a check to see if the host is alive by polling it's SysDesc
     * if the host down from an snmp perspective, don't poll it.
     * function sets the ignore_host bit */
    if ((set.availability_method == AVAIL_SNMP) && (host->snmp_community == "")) {
        update_host_status(HOST_UP, host, ping, set.availability_method);

        if (set.verbose >= POLLER_VERBOSITY_MEDIUM) {
            snprintf(logmessage, LOGSIZE, "Host[%s] No host availability check possible for '%s'\n", host->id, host->hostname);
            cacti_log(logmessage);
        }
    } else {
        if (ping_host(host, ping) == HOST_UP) {
            update_host_status(HOST_UP, host, ping, set.availability_method);
        } else {
            host->ignore_host = 1;
            update_host_status(HOST_DOWN, host, ping, set.availability_method);
        }
    }

    /* update host table */
    snprintf(update_sql, sizeof(update_sql), "update host set status='%i',status_event_count='%i', status_fail_date='%s',status_rec_date='%s',status_last_error='%s',min_time='%f',max_time='%f',cur_time='%f',avg_time='%f',total_polls='%i',failed_polls='%i',availability='%.4f' where id='%i'\n",
             host->status,
             host->status_event_count,
             host->status_fail_date,
             host->status_rec_date,
             host->status_last_error,
             host->min_time,
             host->max_time,
             host->cur_time,
             host->avg_time,
             host->total_polls,
             host->failed_polls,
             host->availability,
             host->id);

    db_insert(&mysql, update_sql);

    /* do the reindex check for this host */
    if (!host->ignore_host) {
        reindex = (reindex_t *) malloc(sizeof(reindex_t));

        result = db_query(&mysql, query4);
        num_rows = (int)mysql_num_rows(result);

        if (num_rows > 0) {
            if (set.verbose == POLLER_VERBOSITY_DEBUG) {
                snprintf(logmessage, LOGSIZE, "Host[%i] RECACHE: Processing %i items in the auto reindex cache for '%s'\n", host->id, num_rows, host->hostname);
                cacti_log(logmessage);
            }

            while ((row = mysql_fetch_row(result))) {
                assert_fail = 0;

                reindex->data_query_id = atoi(row[0]);
                reindex->action = atoi(row[1]);
                if (row[2] != NULL) snprintf(reindex->op, sizeof(reindex->op), "%s", row[2]);
                if (row[3] != NULL) snprintf(reindex->assert_value, sizeof(reindex->assert_value), "%s", row[3]);
                if (row[4] != NULL) snprintf(reindex->arg1, sizeof(reindex->arg1), "%s", row[4]);

                switch(reindex->action) {
                case POLLER_ACTION_SNMP: /* snmp */
                    poll_result = snmp_get(host, reindex->arg1);
                    break;
                case POLLER_ACTION_SCRIPT: /* script (popen) */
                    poll_result = exec_poll(host, reindex->arg1);
                    break;
                }

                /* assume ok if host is up and result wasn't obtained */
                if (!strcmp(poll_result,"U")) {
                    assert_fail = 0;
                } else if ((!strcmp(reindex->op, "=")) && (strcmp(reindex->assert_value,poll_result) != 0)) {
                    snprintf(logmessage, LOGSIZE, "ASSERT: '%s=%s' failed. Recaching host '%s', data query #%i\n", reindex->assert_value, poll_result, host->hostname, reindex->data_query_id);
                    cacti_log(logmessage);

                    query3 = (char *)malloc(128);
                    snprintf(query3, 128, "insert into poller_command (poller_id,time,action,command) values (0,NOW(),%i,'%i:%i')", POLLER_COMMAND_REINDEX, host_id, reindex->data_query_id);
                    db_insert(&mysql, query3);
                    free(query3);

                    assert_fail = 1;
                } else if ((!strcmp(reindex->op, ">")) && (strtoll(reindex->assert_value, (char **)NULL, 10) <= strtoll(poll_result, (char **)NULL, 10))) {
                    snprintf(logmessage, LOGSIZE, "ASSERT: '%s>%s' failed. Recaching host '%s', data query #%i\n", reindex->assert_value, poll_result, host->hostname, reindex->data_query_id);
                    cacti_log(logmessage);

                    query3 = (char *)malloc(128);
                    snprintf(query3, 128, "insert into poller_command (poller_id,time,action,command) values (0,NOW(),%i,'%i:%i')", POLLER_COMMAND_REINDEX, host_id, reindex->data_query_id);
                    db_insert(&mysql, query3);
                    free(query3);

                    assert_fail = 1;
                } else if ((!strcmp(reindex->op, "<")) && (strtoll(reindex->assert_value, (char **)NULL, 10) >= strtoll(poll_result, (char **)NULL, 10))) {
                    snprintf(logmessage, LOGSIZE, "ASSERT: '%s<%s' failed. Recaching host '%s', data query #%i\n", reindex->assert_value, poll_result, host->hostname, reindex->data_query_id);
                    cacti_log(logmessage);

                    query3 = (char *)malloc(128);
                    snprintf(query3, 128, "insert into poller_command (poller_id,time,action,command) values (0,NOW(),%i,'%i:%i')", POLLER_COMMAND_REINDEX, host_id, reindex->data_query_id);
                    db_insert(&mysql, query3);
                    free(query3);

                    assert_fail = 1;
                }

                /* update 'poller_reindex' with the correct information if:
                 * 1) the assert fails
                 * 2) the OP code is > or < meaning the current value could have changed without causing
                 *     the assert to fail */
                if ((assert_fail == 1) || (!strcmp(reindex->op, ">")) || (!strcmp(reindex->op, ">"))) {
                    query3 = (char *)malloc(255);
                    snprintf(query3, 255, "update poller_reindex set assert_value='%s' where host_id='%i' and data_query_id='%i' and arg1='%s'", poll_result, host_id, reindex->data_query_id, reindex->arg1);
                    db_insert(&mysql, query3);
                    free(query3);
                }

                free(poll_result);
            }
        }
    }

    /* retreive each hosts polling items from poller cache */
    entry = (target_t *) malloc(sizeof(target_t));

    result = db_query(&mysql, query1);
    num_rows = (int)mysql_num_rows(result);

    while ((row = mysql_fetch_row(result)) && (!host->ignore_host)) {
        /* initialize monitored object */
        entry->target_id = 0;
        entry->action = atoi(row[0]);
        if (row[1] != NULL) snprintf(entry->hostname, sizeof(entry->hostname), "%s", row[1]);
        if (row[2] != NULL) {
            snprintf(entry->snmp_community, sizeof(entry->snmp_community), "%s", row[2]);
        } else {
            snprintf(entry->snmp_community, sizeof(entry->snmp_community), "%s", "");
        }
        entry->snmp_version = atoi(row[3]);
        if (row[4] != NULL) snprintf(entry->snmp_username, sizeof(entry->snmp_username), "%s", row[4]);
        if (row[5] != NULL) snprintf(entry->snmp_password, sizeof(entry->snmp_password), "%s", row[5]);
        if (row[6] != NULL) snprintf(entry->rrd_name, sizeof(entry->rrd_name), "%s", row[6]);
        if (row[7] != NULL) snprintf(entry->rrd_path, sizeof(entry->rrd_path), "%s", row[7]);
        if (row[8] != NULL) snprintf(entry->arg1, sizeof(entry->arg1), "%s", row[8]);
        if (row[9] != NULL) snprintf(entry->arg2, sizeof(entry->arg2), "%s", row[9]);
        if (row[10] != NULL) snprintf(entry->arg3, sizeof(entry->arg3), "%s", row[10]);
        entry->local_data_id = atoi(row[11]);
        entry->rrd_num = atoi(row[12]);
        entry->snmp_port = atoi(row[13]);
        entry->snmp_timeout = atoi(row[14]);
        snprintf(entry->result, sizeof(entry->result), "%s", "U");

        if (!host->ignore_host) {
            switch(entry->action) {
            case POLLER_ACTION_SNMP: /* raw SNMP poll */
                poll_result = snmp_get(host, entry->arg1);
                snprintf(entry->result, sizeof(entry->result), "%s", poll_result);
                free(poll_result);

                if (host->ignore_host) {
                    snprintf(logmessage, LOGSIZE, "Host[%i] ERROR: SNMP timeout detected [%i milliseconds], ignoring host '%s'\n", host_id, host->snmp_timeout, host->hostname);
                    cacti_log(logmessage);
                    snprintf(entry->result, sizeof(entry->result), "%s", "U");
                } else {
                    /* remove double or single quotes from string */
                    strncpy(entry->result, strip_quotes(entry->result), sizeof(entry->result));

                    /* detect erroneous non-numeric result */
                    if (!is_numeric(entry->result)) {
                        strncpy(errstr, entry->result,sizeof(errstr));
                        snprintf(logmessage, LOGSIZE, "Host[%i] WARNING: Result from SNMP not valid. Partial Result: %.20s...\n", host_id, errstr);
                        cacti_log(logmessage);
                        strncpy(entry->result, "U", sizeof(entry->result));
                    }
                }

                if (set.verbose >= POLLER_VERBOSITY_MEDIUM) {
                    snprintf(logmessage, LOGSIZE, "Host[%i] SNMP: v%i: %s, dsname: %s, oid: %s, value: %s\n", host_id, host->snmp_version, host->hostname, entry->rrd_name, entry->arg1, entry->result);
                    cacti_log(logmessage);
                }

                break;
            case POLLER_ACTION_SCRIPT: /* execute script file */
                poll_result = exec_poll(host, entry->arg1);
                snprintf(entry->result, sizeof(entry->result), "%s", poll_result);
                free(poll_result);

                /* remove double or single quotes from string */
                strncpy(entry->result, strip_quotes(entry->result), sizeof(entry->result));

                /* detect erroneous result. can be non-numeric */
                if (!validate_result(entry->result)) {
                    strncpy(errstr, (char *) strip_string_crlf(entry->result),sizeof(errstr));
                    snprintf(logmessage, LOGSIZE, "Host[%i] WARNING: Result from SCRIPT not valid. Partial Result: %.20s...\n", host_id, errstr);
                    cacti_log(logmessage);
                    strncpy(entry->result, "U", sizeof(entry->result));
                }

                if (set.verbose >= POLLER_VERBOSITY_MEDIUM) {
                    snprintf(logmessage, LOGSIZE, "Host[%i] SCRIPT: %s, output: %s\n", host_id, entry->arg1, entry->result);
                    cacti_log(logmessage);
                }

                break;
            case POLLER_ACTION_PHP_SCRIPT_SERVER: /* execute script server */
                poll_result = php_cmd(entry->arg1);
                snprintf(entry->result, sizeof(entry->result), "%s", poll_result);
                free(poll_result);

                /* remove double or single quotes from string */
                strncpy(entry->result, strip_quotes(entry->result), sizeof(entry->result));

                /* detect erroneous result. can be non-numeric */
                if (!validate_result(entry->result)) {
                    strncpy(errstr, entry->result, sizeof(errstr));
                    snprintf(logmessage, LOGSIZE, "Host[%i] WARNING: Result from SERVER not valid.  Partial Result: %.20s...\n", host_id, errstr);
                    cacti_log(logmessage);
                    strncpy(entry->result, "U", sizeof(entry->result));
                }

                if (set.verbose >= POLLER_VERBOSITY_MEDIUM) {
                    snprintf(logmessage, LOGSIZE, "Host[%i] SERVER: %s, output: %s\n", host_id, entry->arg1, entry->result);
                    cacti_log(logmessage);
                }

                break;
            default: /* unknown action, generate error */
                snprintf(logmessage, LOGSIZE, "Host[%i] ERROR: Unknown Poller Action: %s\n", host_id, entry->arg1);
                cacti_log(logmessage);

                break;
            }
        }

        if (entry->result != NULL) {
            /* format database insert string */
            query3 = (char *)malloc(sizeof(entry->result) + sizeof(entry->local_data_id) + 128);
            snprintf(query3, (sizeof(entry->result) + sizeof(entry->local_data_id) + 128), "insert into poller_output (local_data_id,rrd_name,time,output) values (%i,'%s','%s','%s')", entry->local_data_id, entry->rrd_name, start_datetime, entry->result);
            db_insert(&mysql, query3);
            free(query3);
        }
    }

    /* cleanup memory and prepare for function exit */
    snmp_host_cleanup(host);

    free(entry);
    free(host);
    free(ping);

    mysql_free_result(result);

#ifndef OLD_MYSQL
    mysql_thread_end();
#endif

    mysql_close(&mysql);

    if (set.verbose == POLLER_VERBOSITY_DEBUG) {
        snprintf(logmessage, LOGSIZE, "Host[%i] DEBUG: HOST COMPLETE: About to Exit Host Polling Thread Function\n", host_id);
        cacti_log(logmessage);
    }
}
Example #8
0
char *exec_poll(host_t *current_host, char *command) {
    extern int errno;
    FILE *cmd_stdout;
    int cmd_fd;
    int return_value;
    int bytes_read;
    char logmessage[LOGSIZE];

    fd_set fds;
    int rescode, numfds;
    struct timeval timeout;

    char *result_string = (char *) malloc(BUFSIZE);

    /* establish timeout of 5 seconds for pipe response */
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;

    cmd_fd = nft_popen((char *)clean_string(command), "r");

    if (set.verbose == POLLER_VERBOSITY_DEBUG) {
        snprintf(logmessage, LOGSIZE, "Host[%i] DEBUG: The POPEN returned the following File Descriptor %i\n", current_host->id, cmd_fd);
        cacti_log(logmessage);
    }

    if (cmd_fd >= 0) {
        /* Initialize File Descriptors to Review for Input/Output */
        FD_ZERO(&fds);
        FD_SET(cmd_fd,&fds);

        numfds = cmd_fd + 1;

        /* wait 5 seonds for pipe response */
        switch (select(numfds, &fds, NULL, NULL, &timeout)) {
        case -1:
            switch (errno) {
            case EBADF:
                snprintf(logmessage, LOGSIZE, "Host[%i] ERROR: One or more of the file descriptor sets specified a file descriptor that is not a valid open file descriptor.\n", current_host->id);
                cacti_log(logmessage);
                snprintf(result_string, 2, "%s", "U");
                break;
            case EINTR:
                snprintf(logmessage, LOGSIZE, "Host[%i] ERROR: The function was interrupted before any of the selected events occurred and before the timeout interval expired.\n", current_host->id);
                cacti_log(logmessage);
                snprintf(result_string, 2, "%s", "U");
                break;
            case EINVAL:
                snprintf(logmessage, LOGSIZE, "Host[%i] ERROR: Possible invalid timeout specified in select() statement.\n", current_host->id);
                cacti_log(logmessage);
                snprintf(result_string, 2, "%s", "U");
                break;
            default:
                snprintf(logmessage, LOGSIZE, "Host[%i] ERROR: The script/command select() failed\n", current_host->id);
                cacti_log(logmessage);
                snprintf(result_string, 2, "%s", "U");
                break;
            }
        case 0:
            snprintf(logmessage, LOGSIZE, "Host[%i] ERROR: The POPEN timed out\n", current_host->id);
            cacti_log(logmessage);
            snprintf(result_string, 2, "%s", "U");
            break;
        default:
            /* get only one line of output, we will ignore the rest */
            bytes_read = read(cmd_fd, result_string, BUFSIZE-1);
            if (bytes_read > 0) {
                result_string[bytes_read] = '\0';
                strip_string_crlf(result_string);
            } else {
                snprintf(logmessage, LOGSIZE, "Host[%i] ERROR: Empty result [%s]: '%s'\n", current_host->id, current_host->hostname, command);
                cacti_log(logmessage);
                snprintf(result_string, BUFSIZE, "%s", "U");
            }
        }

        /* close pipe */
        nft_pclose(cmd_fd);
    } else {
        snprintf(logmessage, LOGSIZE, "Host[%i] ERROR: Problem executing POPEN [%s]: '%s'\n", current_host->id, current_host->hostname, command);
        cacti_log(logmessage);
        snprintf(result_string, BUFSIZE, "%s", "U");
    }

    return result_string;
}