int add_user_parameter(const char *itemkey, char *command, char *error, size_t max_error_len) { int i; char key[MAX_STRING_LEN], parameters[MAX_STRING_LEN]; unsigned flag = CF_USERPARAMETER; ZBX_METRIC metric; if (ZBX_COMMAND_ERROR == (i = parse_command(itemkey, key, sizeof(key), parameters, sizeof(parameters)))) { zbx_strlcpy(error, "syntax error", max_error_len); return FAIL; } else if (ZBX_COMMAND_WITH_PARAMS == i) { if (0 != strcmp(parameters, "*")) /* must be '*' parameters */ { zbx_strlcpy(error, "syntax error", max_error_len); return FAIL; } flag |= CF_HAVEPARAMS; } metric.key = key; metric.flags = flag; metric.function = &EXECUTE_USER_PARAMETER; metric.test_param = command; return add_metric(&metric, error, max_error_len); }
/****************************************************************************** * * * Function: setproctitle_set_status * * * * Purpose: set a process command line displayed by "ps" command. * * * * Comments: call this function when a process starts some interesting task. * * Program name argv[0] will be displayed "as-is" followed by ": " * * and a status message. * * * ******************************************************************************/ void setproctitle_set_status(const char *status) { #if defined(PS_OVERWRITE_ARGV) static int initialized = 0; if (1 == initialized) { size_t msg_size; msg_size = zbx_strlcpy(ps_buf, status, ps_buf_size); if (prev_msg_size > msg_size) memset(ps_buf + msg_size + 1, '\0', ps_buf_size - msg_size - 1); prev_msg_size = msg_size; } else if (NULL != ps_buf) { size_t start_pos; /* Initialization has not been moved to setproctitle_save_env() because setproctitle_save_env() */ /* is called from the main process and we do not change its command line. */ /* argv[] changing takes place only in child processes. */ #if defined(PS_CONCAT_ARGV) start_pos = strlen(argv_int[0]); #else start_pos = strlen(ps_buf); #endif if (start_pos + 2 < ps_buf_size) /* is there space for ": " ? */ { zbx_strlcpy(ps_buf + start_pos, ": ", (size_t)3); ps_buf += start_pos + 2; ps_buf_size -= start_pos + 2; /* space after "argv[copy_first]: " for status message */ memset(ps_buf, '\0', ps_buf_size); prev_msg_size = zbx_strlcpy(ps_buf, status, ps_buf_size); initialized = 1; } } #elif defined(PS_PSTAT_ARGV) if (NULL != p_msg) { union pstun pst; zbx_strlcpy(p_msg, status, ps_buf_size_msg); pst.pst_command = ps_buf; pstat(PSTAT_SETCMD, pst, strlen(ps_buf), 0, 0); } #endif }
void alias_expand(const char *orig, char *expanded, int exp_buf_len) { ALIAS *alias; for(alias = aliasList; alias!=NULL; alias = alias->next) { if (!strcmp(alias->name,orig)) { zbx_strlcpy(expanded, alias->value, exp_buf_len); return; } } zbx_strlcpy(expanded, orig, exp_buf_len); }
int set_ipmi_control_value(DC_ITEM *item, int value, char *error, size_t max_error_len) { zbx_ipmi_host_t *h; zbx_ipmi_control_t *c; zabbix_log(LOG_LEVEL_DEBUG, "In set_ipmi_control_value(control:%s, value:%d)", item->ipmi_sensor, value); if (NULL == os_hnd) { zbx_strlcpy(error, "IPMI handler is not initialised", max_error_len); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); return NOTSUPPORTED; } h = init_ipmi_host(item->interface.addr, item->interface.port, item->host.ipmi_authtype, item->host.ipmi_privilege, item->host.ipmi_username, item->host.ipmi_password); if (0 == h->domain_up) { if (NULL != h->err) { zbx_strlcpy(error, h->err, max_error_len); zabbix_log(LOG_LEVEL_DEBUG, "%s", h->err); } return h->ret; } c = get_ipmi_control_by_name(h, item->ipmi_sensor); if (NULL == c) { zbx_snprintf(error, max_error_len, "control %s@[%s]:%d does not exist", item->ipmi_sensor, h->ip, h->port); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); return NOTSUPPORTED; } set_ipmi_control(h, c, value); if (h->ret != SUCCEED) { if (NULL != h->err) { zbx_strlcpy(error, h->err, max_error_len); zabbix_log(LOG_LEVEL_DEBUG, "%s", h->err); } } return h->ret; }
int add_alias(const char *name, const char *value) { ALIAS *alias = NULL; assert(name); assert(value); for(alias = aliasList; ; alias=alias->next) { /* Add new parameters */ if ( NULL == alias ) { alias = (ALIAS *)zbx_malloc(alias, sizeof(ALIAS)); memset(alias,0,sizeof(ALIAS)); zbx_strlcpy(alias->name, name, MAX_ALIAS_NAME-1); alias->value = strdup(value); alias->next=aliasList; aliasList=alias; zabbix_log( LOG_LEVEL_DEBUG, "Alias added. [%s] -> [%s]", name, value); return SUCCEED; } /* Replace existing parameters */ if (strcmp(alias->name, name) == 0) { zbx_free(alias->value); memset(alias, 0, sizeof(ALIAS)); zbx_strlcpy(alias->name, name, MAX_ALIAS_NAME-1); alias->value = strdup(value); alias->next = aliasList; aliasList = alias; zabbix_log( LOG_LEVEL_DEBUG, "Alias replaced. [%s] -> [%s]", name, value); return SUCCEED; } } zabbix_log( LOG_LEVEL_WARNING, "Alias FAILED. [%s] -> [%s]", name, value); return FAIL; }
static int check_script_permissions(zbx_uint64_t groupid, zbx_uint64_t hostid, char *error, size_t max_error_len) { const char *__function_name = "check_script_permissions"; DB_RESULT result; int ret = SUCCEED; zabbix_log(LOG_LEVEL_DEBUG, "In %s() groupid:" ZBX_FS_UI64 " hostid:" ZBX_FS_UI64, __function_name, groupid, hostid); if (0 == groupid) goto exit; result = DBselect( "select hostid" " from hosts_groups" " where hostid=" ZBX_FS_UI64 " and groupid=" ZBX_FS_UI64, hostid, groupid); if (NULL == DBfetch(result)) { zbx_strlcpy(error, "Insufficient permissions. Host is not in an allowed host group.", max_error_len); ret = FAIL; } DBfree_result(result); exit: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
static int zbx_execute_script_on_agent(DC_HOST *host, const char *command, char **result, char *error, size_t max_error_len) { const char *__function_name = "zbx_execute_script_on_agent"; int ret; AGENT_RESULT agent_result; char *param, *port = NULL; DC_ITEM item; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); *error = '\0'; memset(&item, 0, sizeof(item)); memcpy(&item.host, host, sizeof(item.host)); if (SUCCEED != (ret = DCconfig_get_interface_by_type(&item.interface, host->hostid, INTERFACE_TYPE_AGENT))) { zbx_snprintf(error, max_error_len, "Whatap agent interface is not defined for host [%s]", host->host); goto fail; } port = zbx_strdup(port, item.interface.port_orig); substitute_simple_macros(NULL, NULL, NULL, NULL, &host->hostid, NULL, NULL, &port, MACRO_TYPE_COMMON, NULL, 0); if (SUCCEED != (ret = is_ushort(port, &item.interface.port))) { zbx_snprintf(error, max_error_len, "Invalid port number [%s]", item.interface.port_orig); goto fail; } param = zbx_dyn_escape_string(command, "\""); item.key = zbx_dsprintf(item.key, "system.run[\"%s\",\"%s\"]", param, NULL == result ? "nowait" : "wait"); item.value_type = ITEM_VALUE_TYPE_TEXT; zbx_free(param); init_result(&agent_result); alarm(CONFIG_TIMEOUT); if (SUCCEED != (ret = get_value_agent(&item, &agent_result))) { if (ISSET_MSG(&agent_result)) zbx_strlcpy(error, agent_result.msg, max_error_len); ret = FAIL; } else if (NULL != result && ISSET_TEXT(&agent_result)) *result = zbx_strdup(*result, agent_result.text); alarm(0); free_result(&agent_result); zbx_free(item.key); fail: zbx_free(port); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
int zbx_variant_set_numeric(zbx_variant_t *value, const char *text) { zbx_uint64_t value_ui64; char buffer[MAX_STRING_LEN]; zbx_strlcpy(buffer, text, sizeof(buffer)); zbx_rtrim(buffer, "\n\r"); /* trim newline for historical reasons / backwards compatibility */ zbx_trim_integer(buffer); del_zeros(buffer); if ('+' == buffer[0]) { /* zbx_trim_integer() stripped one '+' sign, so there's more than one '+' sign in the 'text' argument */ return FAIL; } if (SUCCEED == is_uint64(buffer, &value_ui64)) { zbx_variant_set_ui64(value, value_ui64); return SUCCEED; } if (SUCCEED == is_double(buffer)) { zbx_variant_set_dbl(value, atof(buffer)); return SUCCEED; } return FAIL; }
/****************************************************************************** * * * Comments: Translate device name to the one used internally by kernel. The * * translation is done based on minor and major device numbers * * listed in INFO_FILE_NAME . If the names differ it is usually an * * LVM device which is listed in kernel device mapper. * * * ******************************************************************************/ static int get_kernel_devname(const char *devname, char *kernel_devname, size_t max_kernel_devname_len) { FILE *f; char tmp[MAX_STRING_LEN], name[MAX_STRING_LEN], dev_path[MAX_STRING_LEN]; int ret = FAIL; zbx_uint64_t ds[ZBX_DSTAT_MAX], rdev_major, rdev_minor; zbx_stat_t dev_st; if ('\0' == *devname) return ret; *dev_path = '\0'; if (0 != strncmp(devname, ZBX_DEV_PFX, ZBX_CONST_STRLEN(ZBX_DEV_PFX))) strscpy(dev_path, ZBX_DEV_PFX); strscat(dev_path, devname); if (zbx_stat(dev_path, &dev_st) < 0 || NULL == (f = fopen(INFO_FILE_NAME, "r"))) return ret; while (NULL != fgets(tmp, sizeof(tmp), f)) { PARSE(tmp); if (major(dev_st.st_rdev) != rdev_major || minor(dev_st.st_rdev) != rdev_minor) continue; zbx_strlcpy(kernel_devname, name, max_kernel_devname_len); ret = SUCCEED; break; } zbx_fclose(f); return ret; }
static int variant_to_dbl(zbx_variant_t *value) { char buffer[MAX_STRING_LEN]; double value_dbl; switch (value->type) { case ZBX_VARIANT_DBL: return SUCCEED; case ZBX_VARIANT_UI64: zbx_variant_set_dbl(value, (double)value->data.ui64); return SUCCEED; case ZBX_VARIANT_STR: zbx_strlcpy(buffer, value->data.str, sizeof(buffer)); break; default: return FAIL; } zbx_rtrim(buffer, "\n\r"); /* trim newline for historical reasons / backwards compatibility */ zbx_trim_float(buffer); if (SUCCEED != is_double(buffer)) return FAIL; value_dbl = atof(buffer); zbx_variant_clear(value); zbx_variant_set_dbl(value, value_dbl); return SUCCEED; }
void add_alias(const char *name, const char *value) { ALIAS *alias = NULL; assert(name); assert(value); for (alias = aliasList; ; alias = alias->next) { /* add new Alias */ if (NULL == alias) { alias = (ALIAS *)zbx_malloc(alias, sizeof(ALIAS)); memset(alias, 0, sizeof(ALIAS)); zbx_strlcpy(alias->name, name, MAX_ALIAS_NAME - 1); alias->value = strdup(value); alias->next = aliasList; aliasList = alias; zabbix_log(LOG_LEVEL_DEBUG, "Alias added: \"%s\" -> \"%s\"", name, value); break; } /* treat duplicate Alias as error */ if (0 == strcmp(alias->name, name)) { zabbix_log(LOG_LEVEL_CRIT, "failed to add Alias \"%s\": duplicate name", name); exit(EXIT_FAILURE); } } }
ZBX_SINGLE_DISKDEVICE_DATA *collector_diskdevice_add(const char *devname) { const char *__function_name = "collector_diskdevice_add"; ZBX_SINGLE_DISKDEVICE_DATA *device; assert(devname); zabbix_log(LOG_LEVEL_DEBUG, "In %s() devname:'%s'", __function_name, devname); /* collector is full */ if (collector->diskdevices.count == MAX_DISKDEVICES) { zabbix_log(LOG_LEVEL_DEBUG, "End of %s():NULL collector is full", __function_name); return NULL; } device = &collector->diskdevices.device[collector->diskdevices.count]; zbx_strlcpy(device->name, devname, sizeof(device->name)); device->index = -1; collector->diskdevices.count++; process_diskstat(device); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%p", __function_name, device); return device; }
/****************************************************************************** * * * Purpose: get DATA from <tag>DATA</tag> * * * ******************************************************************************/ int xml_get_data_dyn(const char *xml, const char *tag, char **data) { size_t len, sz; char *start, *end; sz = sizeof(data_static); len = zbx_snprintf(data_static, sz, "<%s>", tag); if (NULL == (start = strstr(xml, data_static))) return FAIL; zbx_snprintf(data_static, sz, "</%s>", tag); if (NULL == (end = strstr(xml, data_static))) return FAIL; if (end < start) return FAIL; start += len; len = end - start; if (len > sz - 1) *data = zbx_malloc(*data, len + 1); else *data = data_static; zbx_strlcpy(*data, start, len + 1); return SUCCEED; }
static char *get_commandline(struct kinfo_proc *proc) { int mib[4], i; size_t sz; static char *args = NULL; static int args_alloc = 128; if (NULL == args) args = zbx_malloc(args, args_alloc); mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_ARGS; mib[3] = proc->ZBX_PROC_PID; retry: sz = (size_t)args_alloc; if (-1 == sysctl(mib, 4, args, &sz, NULL, 0)) { if (errno == ENOMEM) { args_alloc *= 2; args = zbx_realloc(args, args_alloc); goto retry; } return NULL; } for (i = 0; i < (int)(sz - 1); i++) if (args[i] == '\0') args[i] = ' '; if (sz == 0) zbx_strlcpy(args, proc->ZBX_PROC_COMM, args_alloc); return args; }
static int variant_to_ui64(zbx_variant_t *value) { zbx_uint64_t value_ui64; char buffer[MAX_STRING_LEN]; switch (value->type) { case ZBX_VARIANT_UI64: return SUCCEED; case ZBX_VARIANT_DBL: if (0 > value->data.dbl) return FAIL; zbx_variant_set_ui64(value, value->data.dbl); return SUCCEED; case ZBX_VARIANT_STR: zbx_strlcpy(buffer, value->data.str, sizeof(buffer)); break; default: return FAIL; } zbx_rtrim(buffer, "\n\r"); /* trim newline for historical reasons / backwards compatibility */ zbx_trim_integer(buffer); del_zeros(buffer); if (SUCCEED != is_uint64(buffer, &value_ui64)) return FAIL; zbx_variant_clear(value); zbx_variant_set_ui64(value, value_ui64); return SUCCEED; }
/* * hidden */ static DISK_DATA *get_disk_data_record(const char *device) { static DISK_DATA *disks; DISK_DATA *p; for(p = disks; (p) && (strncmp(p->name, device, MAX_STRING_LEN) != 0); p = p->next) if (p == (DISK_DATA *) NULL) { p = (DISK_DATA *) calloc(1, sizeof(DISK_DATA)); if (p) { zbx_strlcpy(p->name, device, MAX_STRING_LEN); if (p->name) { p->next = disks; disks = p; } else { free(p); p = NULL; } } } return p; }
static char *sensor_id_to_str(char *str, size_t str_sz, const char *id, enum ipmi_str_type_e id_type, int id_sz) { /* minimum size of 'str' buffer, str_sz, is 35 bytes to avoid truncation */ int i; char *p = str; size_t id_len; if (0 == id_sz) /* id is meaningful only if length > 0 (see SDR record format in IPMI v2 spec) */ { *str = '\0'; return str; } if (IPMI_SENSOR_ID_SZ < id_sz) { zbx_strlcpy(str, "ILLEGAL-SENSOR-ID-SIZE", str_sz); THIS_SHOULD_NEVER_HAPPEN; return str; } switch (id_type) { case IPMI_ASCII_STR: case IPMI_UNICODE_STR: id_len = str_sz > (size_t)id_sz ? (size_t)id_sz : str_sz - 1; memcpy(str, id, id_len); *(str + id_len) = '\0'; break; case IPMI_BINARY_STR: /* "BCD Plus" or "6-bit ASCII packed" encoding - print it as a hex string. */ *p++ = '0'; /* prefix to distinguish from ASCII/Unicode strings */ *p++ = 'x'; for (i = 0; i < id_sz; i++, p += 2) { zbx_snprintf(p, str_sz - (size_t)(2 + i + i), "%02x", (unsigned int)(unsigned char)*(id + i)); } *p = '\0'; break; default: zbx_strlcpy(str, "ILLEGAL-SENSOR-ID-TYPE", str_sz); THIS_SHOULD_NEVER_HAPPEN; } return str; }
/****************************************************************************** * * * Function: discovery_update_service_status * * * * Purpose: process and update the new service status * * * * Author: Alexander Vladishev * * * ******************************************************************************/ static void discovery_update_service_status(DB_DSERVICE *dservice, int status, const char *value, int now) { zbx_timespec_t ts; ts.sec = now; ts.ns = 0; if (DOBJECT_STATUS_UP == status) { if (DOBJECT_STATUS_DOWN == dservice->status || 0 == dservice->lastup) { dservice->status = status; dservice->lastdown = 0; dservice->lastup = now; zbx_strlcpy(dservice->value, value, sizeof(dservice->value)); discovery_update_dservice(dservice); add_event(0, EVENT_SOURCE_DISCOVERY, EVENT_OBJECT_DSERVICE, dservice->dserviceid, &ts, DOBJECT_STATUS_DISCOVER, NULL, NULL, 0, 0); } else if (0 != strcmp(dservice->value, value)) { zbx_strlcpy(dservice->value, value, sizeof(dservice->value)); discovery_update_dservice_value(dservice); } } else /* DOBJECT_STATUS_DOWN */ { if (DOBJECT_STATUS_UP == dservice->status || 0 == dservice->lastdown) { dservice->status = status; dservice->lastdown = now; dservice->lastup = 0; discovery_update_dservice(dservice); add_event(0, EVENT_SOURCE_DISCOVERY, EVENT_OBJECT_DSERVICE, dservice->dserviceid, &ts, DOBJECT_STATUS_LOST, NULL, NULL, 0, 0); } } add_event(0, EVENT_SOURCE_DISCOVERY, EVENT_OBJECT_DSERVICE, dservice->dserviceid, &ts, status, NULL, NULL, 0, 0); process_events(); }
int WEB_PAGE_REGEXP(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { char hostname[MAX_STRING_LEN]; char path[MAX_STRING_LEN]; char port_str[8]; char regexp[MAX_STRING_LEN]; char len_str[16]; char back[MAX_BUFFER_LEN]; char *buffer = NULL, *found; int len, found_len; if (num_param(param) > 5) return SYSINFO_RET_FAIL; if (0 != get_param(param, 1, hostname, sizeof(hostname))) return SYSINFO_RET_FAIL; if (0 != get_param(param, 2, path, sizeof(path))) *path = '\0'; if (0 != get_param(param, 3, port_str, sizeof(port_str)) || '\0' == *port_str) zbx_snprintf(port_str, sizeof(port_str), "%d", ZBX_DEFAULT_HTTP_PORT); else if (FAIL == is_uint(port_str)) return SYSINFO_RET_FAIL; if (0 != get_param(param, 4, regexp, sizeof(regexp))) return SYSINFO_RET_FAIL; if (0 != get_param(param, 5, len_str, sizeof(len_str)) || '\0' == *len_str) zbx_snprintf(len_str, sizeof(len_str), "%d", MAX_BUFFER_LEN - 1); else if (FAIL == is_uint(len_str)) return SYSINFO_RET_FAIL; buffer = zbx_malloc(buffer, ZBX_MAX_WEBPAGE_SIZE); if (SYSINFO_RET_OK == get_http_page(hostname, path, (unsigned short)atoi(port_str), buffer, ZBX_MAX_WEBPAGE_SIZE)) { if (NULL != (found = zbx_regexp_match(buffer, regexp, &found_len))) { len = atoi(len_str) + 1; len = MIN(len, found_len + 1); len = MIN(len, sizeof(back)); zbx_strlcpy(back, found, len); SET_STR_RESULT(result, strdup(back)); } else SET_STR_RESULT(result, strdup("EOF")); } else SET_STR_RESULT(result, strdup("EOF")); zbx_free(buffer); return SYSINFO_RET_OK; }
/* * Function: pg_connect * * Parses a Zabbix agent request and returns a PostgreSQL connection. * * See: http://www.postgresql.org/docs/9.4/static/libpq-connect.html#LIBPQ-PQCONNECTDB * * Parameter [request]: Zabbix agent request structure. * The following parameters may be set: * * 0: connection string (default: DEFAULT_CONN_STRING) * 1: connection database (default: DEFAULT_CONN_DBNAME) * * Returns: Valid PostgreSQL connection or NULL on error */ PGconn *pg_connect(AGENT_REQUEST *request) { const char *__function_name = "pg_connect"; PGconn *conn = NULL; char *param_connstring = NULL, *param_dbname = NULL; char connstring[MAX_STRING_LEN], *c = NULL; int param_connstring_len = 0, param_dbname_len = 0, connstring_len = 0;; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); // get connection string from first parameter param_connstring = get_rparam(request, PARAM_CONN_STRING); param_connstring = (NULL == param_connstring) ? DEFAULT_CONN_STRING : param_connstring; param_connstring_len = strlen(param_connstring); // get database name from second parameter param_dbname = get_rparam(request, PARAM_DBNAME); param_dbname = (NULL == param_dbname) ? DEFAULT_CONN_DBNAME : param_dbname; param_dbname_len = strisnull(param_dbname) ? 0 : strlen(param_dbname); // create buffer to concat connection string and database name zbx_strlcpy(connstring, param_connstring, sizeof(connstring)); c = connstring; // append dbname= key if (!strisnull(param_dbname)) { if (!strisnull(connstring)) c = strcat2(c, " "); c = strcat(c, "dbname="); c = strcat(c, param_dbname); } /* * Breaks in ~ v8.4 // append application name if (!strisnull(connstring)) c = strcat2(c, " "); c = strcat(c, "application_name='" STRVER "'"); */ // connect zabbix_log(LOG_LEVEL_DEBUG, "Connecting to PostgreSQL with: %s", connstring); conn = PQconnectdb(connstring); if(CONNECTION_OK != PQstatus(conn)) { zabbix_log(LOG_LEVEL_ERR, "Failed to connect to PostgreSQL in %s():\n%s", __function_name, PQerrorMessage(conn)); PQfinish(conn); conn = NULL; } zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return conn; }
/****************************************************************************** * * * Function: split_string * * * * Purpose: separates given string to two parts by given delimiter in string * * * * Parameters: str - the string to split * * del - pointer to a character in the string * * part1 - pointer to buffer for the first part with delimiter * * part2 - pointer to buffer for the second part * * * * Return value: SUCCEED - on splitting without errors * * FAIL - on splitting with errors * * * * Author: Dmitry Borovikov, Aleksandrs Saveljevs * * * * Comments: Memory for "part1" and "part2" is allocated only on SUCCEED. * * * ******************************************************************************/ static int split_string(const char *str, const char *del, char **part1, char **part2) { int str_length = 0; int part1_length = 0; int part2_length = 0; assert(str); assert(*str);/* why to split an empty string */ assert(del); assert(*del);/* why to split if "part2" is empty */ assert(part1); assert(NULL == *part1);/* target 1 must be empty */ assert(part2); assert(NULL == *part2);/* target 2 must be empty */ zabbix_log(LOG_LEVEL_DEBUG, "In split_string(): str [%s] del [%s]", str, del); str_length = strlen(str); /* since the purpose of this function is to be used in split_filename(), we allow part1 to be */ /* just *del (e.g., "/" - file system root), but we do not allow part2 (filename) to be empty */ if (del < str || del >= (str + str_length - 1)) { zabbix_log(LOG_LEVEL_DEBUG, "Delimiter is out of range. Cannot proceed."); return FAIL; } part1_length = del - str + 1; part2_length = str_length - part1_length; *part1 = zbx_malloc(*part1, part1_length + 1); zbx_strlcpy(*part1, str, part1_length + 1); *part2 = zbx_malloc(*part2, part2_length + 1); zbx_strlcpy(*part2, str + part1_length, part2_length + 1); zabbix_log(LOG_LEVEL_DEBUG, "End split_string(): part1 [%s] part2 [%s]", *part1, *part2); return SUCCEED; }
/* function 'parse_ipmi_command' requires 'c_name' with size 'ITEM_IPMI_SENSOR_LEN_MAX' */ int parse_ipmi_command(const char *command, char *c_name, int *val, char *error, size_t max_error_len) { const char *__function_name = "parse_ipmi_command"; const char *p; size_t sz_c_name; int ret = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s() command:'%s'", __function_name, command); while ('\0' != *command && NULL != strchr(" \t", *command)) command++; for (p = command; '\0' != *p && NULL == strchr(" \t", *p); p++) ; if (0 == (sz_c_name = p - command)) { zbx_strlcpy(error, "IPMI command is empty", max_error_len); goto fail; } if (ITEM_IPMI_SENSOR_LEN_MAX <= sz_c_name) { zbx_snprintf(error, max_error_len, "IPMI command is too long [%.*s]", sz_c_name, command); goto fail; } memcpy(c_name, command, sz_c_name); c_name[sz_c_name] = '\0'; while ('\0' != *p && NULL != strchr(" \t", *p)) p++; if ('\0' == *p || 0 == strcasecmp(p, "on")) *val = 1; else if (0 == strcasecmp(p, "off")) *val = 0; else if (SUCCEED == is_uint(p)) *val = atoi(p); else { zbx_snprintf(error, max_error_len, "IPMI command value is not supported [%s]", p); goto fail; } ret = SUCCEED; fail: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Purpose: evaluate a suffixed number or a parenthesized expression * * * ******************************************************************************/ static double evaluate_term9(int *unknown_idx) { double result; while (' ' == *ptr || '\r' == *ptr || '\n' == *ptr || '\t' == *ptr) ptr++; if ('\0' == *ptr) { zbx_strlcpy(buffer, "Cannot evaluate expression: unexpected end of expression.", max_buffer_len); return ZBX_INFINITY; } if ('(' == *ptr) { ptr++; if (ZBX_INFINITY == (result = evaluate_term1(unknown_idx))) return ZBX_INFINITY; /* if evaluate_term1() returns ZBX_UNKNOWN then continue as with regular number */ if (')' != *ptr) { zbx_snprintf(buffer, max_buffer_len, "Cannot evaluate expression:" " expected closing parenthesis at \"%s\".", ptr); return ZBX_INFINITY; } ptr++; } else { if (ZBX_INFINITY == (result = evaluate_number(unknown_idx))) { zbx_snprintf(buffer, max_buffer_len, "Cannot evaluate expression:" " expected numeric token at \"%s\".", ptr); return ZBX_INFINITY; } } while ('\0' != *ptr && (' ' == *ptr || '\r' == *ptr || '\n' == *ptr || '\t' == *ptr)) ptr++; return result; }
/****************************************************************************** * * * Function: get_event_info * * * * Purpose: get event and trigger info to event structure * * * * Parameters: eventid - [IN] requested event id * * event - [OUT] event data * * * * Return value: SUCCEED if processed successfully, FAIL - otherwise * * * * Author: Alexander Vladishev * * * * Comments: use 'free_event_info' function to clear allocated memory * * * ******************************************************************************/ static int get_event_info(zbx_uint64_t eventid, DB_EVENT *event) { DB_RESULT result; DB_ROW row; int res = FAIL; memset(event, 0, sizeof(DB_EVENT)); result = DBselect("select eventid,source,object,objectid,clock,value,acknowledged" " from events where eventid=" ZBX_FS_UI64, eventid); if (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(event->eventid, row[0]); event->source = atoi(row[1]); event->object = atoi(row[2]); ZBX_STR2UINT64(event->objectid, row[3]); event->clock = atoi(row[4]); event->value = atoi(row[5]); event->acknowledged = atoi(row[6]); res = SUCCEED; } DBfree_result(result); if (res == SUCCEED && event->object == EVENT_OBJECT_TRIGGER) { result = DBselect("select description,priority,comments,url,type" " from triggers where triggerid=" ZBX_FS_UI64, event->objectid); if (NULL != (row = DBfetch(result))) { zbx_strlcpy(event->trigger_description, row[0], sizeof(event->trigger_description)); event->trigger_priority = atoi(row[1]); event->trigger_comments = strdup(row[2]); event->trigger_url = strdup(row[3]); event->trigger_type = atoi(row[4]); } DBfree_result(result); } return res; }
/* function 'GetProcessUsername' require 'userName' with size 'MAX_NAME' */ static int GetProcessUsername(HANDLE hProcess, char *userName) { HANDLE tok; TOKEN_USER *ptu = NULL; DWORD sz = 0, nlen, dlen; char name[MAX_NAME], dom[MAX_NAME]; int iUse, res = 0; assert(userName); //clean result; *userName = '******'; //open the processes token if (0 == OpenProcessToken(hProcess, TOKEN_QUERY, &tok)) return res; // Get required buffer size and allocate the TOKEN_USER buffer if (0 == GetTokenInformation(tok, (TOKEN_INFORMATION_CLASS)1, (LPVOID)ptu, 0, &sz)) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto lbl_err; ptu = (PTOKEN_USER)zbx_malloc(ptu, sz); } // Get the token user information from the access token. if (0 == GetTokenInformation(tok, (TOKEN_INFORMATION_CLASS)1, (LPVOID)ptu, sz, &sz)) goto lbl_err; //get the account/domain name of the SID nlen = sizeof(name); dlen = sizeof(dom); if (0 == LookupAccountSid(NULL, ptu->User.Sid, name, &nlen, dom, &dlen, (PSID_NAME_USE)&iUse)) goto lbl_err; zbx_strlcpy(userName, name, MAX_NAME); res = 1; lbl_err: zbx_free(ptu); CloseHandle(tok); return res; }
/* * Custom key pg.index.discovery * * Parameters: * 0: connection string * 1: connection database * 2: search mode: deep (default) | shallow * 3: filter by schema name * 4: filter by table name * * Returns all known indexes in a PostgreSQL database * * Returns: * { * "data":[ * { * "{#OID}":"12345", * "{#INDEX}":"MyIndex", * "{#DATABASE}":"MyDatabase", * "{#SCHEMA}":"public", * "{#TABLE}":"MyTable", * "{#OWNER}":"postgres", * "{#ACCESS}":"btree|hash"}]} */ int PG_INDEX_DISCOVERY(AGENT_REQUEST *request, AGENT_RESULT *result) { int ret = SYSINFO_RET_FAIL; // Request result code const char *__function_name = "PG_DB_DISCOVERY"; // Function name for log file char query[MAX_STRING_LEN], buffer[MAX_STRING_LEN]; char *c = NULL; char *param_mode = NULL, *param_table = NULL, *param_schema = NULL; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); // build the query zbx_strlcpy(query, PGSQL_DISCOVER_INDEXES, sizeof(query)); c = query; // filter by schema name param_schema = get_rparam(request, PARAM_FIRST + 1); if(!strisnull(param_schema)) { zbx_snprintf(buffer, sizeof(buffer), " AND n.nspname = '%s'", param_schema); c = strcat2(c, buffer); } // filter by table name param_table = get_rparam(request, PARAM_FIRST + 2); if(!strisnull(param_table)) { zbx_snprintf(buffer, sizeof(buffer), " AND t.relname = '%s'", param_table); c = strcat2(c, buffer); } // build results param_mode = get_rparam(request, PARAM_FIRST); if (strisnull(param_mode) || 0 == strcmp(param_mode, "deep")) { ret = pg_get_discovery_wide(request, result, query, NULL); } else if (0 == strcmp(param_mode, "shallow")) { ret = pg_get_discovery(request, result, query, NULL); } else { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Invalid search mode parameter: %s", param_mode)); } zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return ret; }
/****************************************************************************** * * * Function: zbx_module_docker_up * * * * Purpose: check if container is running * * * * Return value: 1 - is running, 0 - is not running * * * ******************************************************************************/ int zbx_module_docker_up(AGENT_REQUEST *request, AGENT_RESULT *result) { zabbix_log(LOG_LEVEL_DEBUG, "In zbx_module_docker_up()"); char *container, *metric; int ret = SYSINFO_RET_FAIL; if (1 != request->nparam) { zabbix_log(LOG_LEVEL_ERR, "Invalid number of parameters: %d", request->nparam); SET_MSG_RESULT(result, strdup("Invalid number of parameters.")); return SYSINFO_RET_FAIL; } if (stat_dir == NULL) { zabbix_log(LOG_LEVEL_DEBUG, "docker.up check is not available at the moment - no stat directory."); SET_MSG_RESULT(result, zbx_strdup(NULL, "docker.up check is not available at the moment - no stat directory.")); return SYSINFO_RET_OK; } container = get_rparam(request, 0); char *stat_file = "/cpuacct.stat"; char *cgroup = "cpuacct/"; size_t filename_size = strlen(base_dir) + strlen(cgroup) + strlen(container) + strlen(stat_dir) + strlen(stat_file) + 2; char *filename = malloc(filename_size); zbx_strlcpy(filename, base_dir, filename_size); zbx_strlcat(filename, cgroup, filename_size); zbx_strlcat(filename, stat_dir, filename_size); zbx_strlcat(filename, container, filename_size); zbx_strlcat(filename, stat_file, filename_size); zabbix_log(LOG_LEVEL_DEBUG, "Metric source file: %s", filename); FILE *file; if (NULL == (file = fopen(filename, "r"))) { zabbix_log(LOG_LEVEL_DEBUG, "Can't open docker container metric file: '%s', container doesn't run", filename); SET_DBL_RESULT(result, 0); return SYSINFO_RET_OK; } zbx_fclose(file); zabbix_log(LOG_LEVEL_DEBUG, "Can open docker container metric file: '%s', container is running", filename); SET_DBL_RESULT(result, 1); return SYSINFO_RET_OK; }
/******************************************************************************************************** * * * Function : This function will construct a complete zabbix key including parameters from a request * * Returns : 0 (success), 1 (failure) * * * ********************************************************************************************************/ int zbx_key_gen(AGENT_REQUEST *request, char *zbx_key) { // Declare Variables int count = 0; // Initialise string zbx_strlcpy(zbx_key,"",sizeof(zbx_key)); // Append keyname strcat(zbx_key,request->key); // Ammend params if present if(request->nparam) { // Open the parameters strcat(zbx_key,"["); // For every parameter for(count=0;count<request->nparam;count++) { // If there are more parameters then append a comma if(count) { strcat(zbx_key,","); } // Append the parameter strcat(zbx_key,request->params[count]); } // Close the parameters strcat(zbx_key,"]"); } // Return success return 0; }
ZBX_SINGLE_DISKDEVICE_DATA *collector_diskdevice_add(const char *devname) { ZBX_SINGLE_DISKDEVICE_DATA *device; assert(devname); zabbix_log(LOG_LEVEL_DEBUG, "In collector_diskdevice_add(\"%s\")", devname); /* collector is full */ if (collector->diskdevices.count == MAX_DISKDEVICES) return NULL; device = &collector->diskdevices.device[collector->diskdevices.count]; zbx_strlcpy(device->name, devname, sizeof(device->name)); device->index = -1; collector->diskdevices.count++; process_diskstat(device); return device; }
void zbx_gethost_by_ip(const char *ip, char *host, size_t hostlen) { struct in_addr addr; struct hostent *hst; assert(ip); if (0 == inet_aton(ip, &addr)) { host[0] = '\0'; return; } if (NULL == (hst = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET))) { host[0] = '\0'; return; } zbx_strlcpy(host, hst->h_name, hostlen); }