/****************************************************************************** * * * Function: get_value_aggregate * * * * Purpose: retrieve data from Zabbix server (aggregate items) * * * * Parameters: item - item we are interested in * * * * Return value: SUCCEED - data successfully retrieved and stored in result * * and result_str (as string) * * NOTSUPPORTED - requested item is not supported * * * * Author: Alexei Vladishev * * * ******************************************************************************/ int get_value_aggregate(DC_ITEM *item, AGENT_RESULT *result) { const char *__function_name = "get_value_aggregate"; char tmp[8], params[MAX_STRING_LEN], groups[MAX_STRING_LEN], itemkey[MAX_STRING_LEN], funcp[32]; int grp_func, item_func, ret = SUCCEED; zabbix_log(LOG_LEVEL_DEBUG, "In %s() key:'%s'", __function_name, item->key_orig); if (ITEM_VALUE_TYPE_FLOAT != item->value_type && ITEM_VALUE_TYPE_UINT64 != item->value_type) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Value type must be Numeric for aggregate items")); return NOTSUPPORTED; } if (ZBX_COMMAND_WITH_PARAMS != parse_command(item->key, tmp, sizeof(tmp), params, sizeof(params))) return NOTSUPPORTED; if (0 == strcmp(tmp, "grpmin")) grp_func =ZBX_VALUE_FUNC_MIN; else if (0 == strcmp(tmp, "grpavg")) grp_func =ZBX_VALUE_FUNC_AVG; else if (0 == strcmp(tmp, "grpmax")) grp_func =ZBX_VALUE_FUNC_MAX; else if (0 == strcmp(tmp, "grpsum")) grp_func =ZBX_VALUE_FUNC_SUM; else return NOTSUPPORTED; if (4 != num_param(params)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters.")); return NOTSUPPORTED; } if (0 != get_param(params, 1, groups, sizeof(groups))) return NOTSUPPORTED; if (0 != get_param(params, 2, itemkey, sizeof(itemkey))) return NOTSUPPORTED; if (0 != get_param(params, 3, tmp, sizeof(tmp))) return NOTSUPPORTED; if (0 == strcmp(tmp, "min")) item_func = ZBX_VALUE_FUNC_MIN; else if (0 == strcmp(tmp, "avg")) item_func = ZBX_VALUE_FUNC_AVG; else if (0 == strcmp(tmp, "max")) item_func = ZBX_VALUE_FUNC_MAX; else if (0 == strcmp(tmp, "sum")) item_func = ZBX_VALUE_FUNC_SUM; else if (0 == strcmp(tmp, "count")) item_func = ZBX_VALUE_FUNC_COUNT; else if (0 == strcmp(tmp, "last")) item_func = ZBX_VALUE_FUNC_LAST; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); return NOTSUPPORTED; } if (0 != get_param(params, 4, funcp, sizeof(funcp))) return NOTSUPPORTED; if (SUCCEED != evaluate_aggregate(item, result, grp_func, groups, itemkey, item_func, funcp)) ret = NOTSUPPORTED; zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
int SYSTEM_HW_CPU(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { int ret = SYSINFO_RET_FAIL, filter, cpu, cur_cpu = -1, offset = 0; zbx_uint64_t maxfreq = FAIL, curfreq = FAIL; char line[MAX_STRING_LEN], name[MAX_STRING_LEN], tmp[MAX_STRING_LEN], buffer[MAX_BUFFER_LEN]; FILE *f; if (2 < num_param(param)) return ret; if (0 != get_param(param, 1, tmp, sizeof(tmp)) || '\0' == *tmp || 0 == strcmp(tmp, "all")) cpu = HW_CPU_ALL_CPUS; /* show all CPUs by default */ else if (FAIL == is_uint(tmp)) return ret; else cpu = atoi(tmp); if (0 != get_param(param, 2, tmp, sizeof(tmp)) || '\0' == *tmp || 0 == strcmp(tmp, "full")) filter = HW_CPU_SHOW_ALL; /* show full info by default */ else if (0 == strcmp(tmp, "maxfreq")) filter = HW_CPU_SHOW_MAXFREQ; else if (0 == strcmp(tmp, "vendor")) filter = HW_CPU_SHOW_VENDOR; else if (0 == strcmp(tmp, "model")) filter = HW_CPU_SHOW_MODEL; else if (0 == strcmp(tmp, "curfreq")) filter = HW_CPU_SHOW_CURFREQ; else return ret; if (NULL == (f = fopen(HW_CPU_INFO_FILE, "r"))) return ret; *buffer = '\0'; while (NULL != fgets(line, sizeof(line), f)) { if (2 != sscanf(line, "%[^:]: %[^\n]", name, tmp)) continue; if (0 == strncmp(name, "processor", 9)) { if (-1 != cur_cpu && (HW_CPU_ALL_CPUS == cpu || cpu == cur_cpu)) /* print info about the previous cpu */ offset += print_freq(buffer + offset, sizeof(buffer) - offset, filter, cpu, maxfreq, curfreq); curfreq = FAIL; cur_cpu = atoi(tmp); if (HW_CPU_ALL_CPUS != cpu && cpu != cur_cpu) continue; if (HW_CPU_ALL_CPUS == cpu || HW_CPU_SHOW_ALL == filter) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\nprocessor %d:", cur_cpu); if ((HW_CPU_SHOW_ALL == filter || HW_CPU_SHOW_MAXFREQ == filter) && FAIL != (maxfreq = get_cpu_max_freq(cur_cpu))) { ret = SYSINFO_RET_OK; } } if (HW_CPU_ALL_CPUS != cpu && cpu != cur_cpu) continue; if (0 == strncmp(name, "vendor_id", 9) && (HW_CPU_SHOW_ALL == filter || HW_CPU_SHOW_VENDOR == filter)) { ret = SYSINFO_RET_OK; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", tmp); } else if (0 == strncmp(name, "model name", 10) && (HW_CPU_SHOW_ALL == filter || HW_CPU_SHOW_MODEL == filter)) { ret = SYSINFO_RET_OK; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", tmp); } else if (0 == strncmp(name, "cpu MHz", 7) && (HW_CPU_SHOW_ALL == filter || HW_CPU_SHOW_CURFREQ == filter)) { ret = SYSINFO_RET_OK; ZBX_STR2UINT64(curfreq, tmp); } } zbx_fclose(f); if (SYSINFO_RET_OK == ret) { if (-1 != cur_cpu && (HW_CPU_ALL_CPUS == cpu || cpu == cur_cpu)) /* print info about the last cpu */ offset += print_freq(buffer + offset, sizeof(buffer) - offset, filter, cpu, maxfreq, curfreq); SET_TEXT_RESULT(result, zbx_strdup(NULL, buffer + 1)); /* buf has a leading space or '\n' */ } return ret; }
static int vfs_dev_rw(const char *param, AGENT_RESULT *result, int rw) { ZBX_SINGLE_DISKDEVICE_DATA *device; char devname[32], tmp[16]; int type, mode, nparam; zbx_uint64_t dstats[ZBX_DSTAT_MAX]; char *pd; /* pointer to device name without '/dev/' prefix, e.g. 'da0' */ if (3 < (nparam = num_param(param))) /* too many parameters? */ return SYSINFO_RET_FAIL; if (0 != get_param(param, 1, devname, sizeof(devname))) return SYSINFO_RET_FAIL; pd = devname; if ('\0' != *pd) { if (0 == strcmp(pd, "all")) *pd = '\0'; else { /* skip prefix ZBX_DEV_PFX, if present */ if (0 == strncmp(pd, ZBX_DEV_PFX, sizeof(ZBX_DEV_PFX) - 1)) pd += sizeof(ZBX_DEV_PFX) - 1; } } if (0 != get_param(param, 2, tmp, sizeof(tmp))) *tmp = '\0'; if ('\0' == *tmp || 0 == strcmp(tmp, "bps")) /* default parameter */ type = ZBX_DSTAT_TYPE_BPS; else if (0 == strcmp(tmp, "ops")) type = ZBX_DSTAT_TYPE_OPS; else if (0 == strcmp(tmp, "bytes")) type = ZBX_DSTAT_TYPE_BYTE; else if (0 == strcmp(tmp, "operations")) type = ZBX_DSTAT_TYPE_OPER; else return SYSINFO_RET_FAIL; if (type == ZBX_DSTAT_TYPE_BYTE || type == ZBX_DSTAT_TYPE_OPER) { if (nparam > 2) return SYSINFO_RET_FAIL; if (FAIL == get_diskstat(pd, dstats)) return SYSINFO_RET_FAIL; if (ZBX_DSTAT_TYPE_BYTE == type) SET_UI64_RESULT(result, dstats[(ZBX_DEV_READ == rw ? ZBX_DSTAT_R_BYTE : ZBX_DSTAT_W_BYTE)]); else /* ZBX_DSTAT_TYPE_OPER */ SET_UI64_RESULT(result, dstats[(ZBX_DEV_READ == rw ? ZBX_DSTAT_R_OPER : ZBX_DSTAT_W_OPER)]); return SYSINFO_RET_OK; } if (0 != get_param(param, 3, tmp, sizeof(tmp))) *tmp = '\0'; if ('\0' == *tmp || 0 == strcmp(tmp, "avg1")) /* default parameter */ mode = ZBX_AVG1; else if (0 == strcmp(tmp, "avg5")) mode = ZBX_AVG5; else if (0 == strcmp(tmp, "avg15")) mode = ZBX_AVG15; else return SYSINFO_RET_FAIL; if (NULL == collector) { /* CPU statistics collector and (optionally) disk statistics collector is started only when Zabbix */ /* agentd is running as a daemon. When Zabbix agent or agentd is started with "-p" or "-t" parameter */ /* the collectors are not available and keys "vfs.dev.read", "vfs.dev.write" with some parameters */ /* (e.g. sps, ops) are not supported. */ SET_MSG_RESULT(result, strdup("This parameter is available only in daemon mode when collectors are started.")); return SYSINFO_RET_FAIL; } if (NULL == (device = collector_diskdevice_get(pd))) { if (FAIL == get_diskstat(pd, dstats)) /* validate device name */ return SYSINFO_RET_FAIL; if (NULL == (device = collector_diskdevice_add(pd))) return SYSINFO_RET_FAIL; } if (ZBX_DSTAT_TYPE_BPS == type) /* default parameter */ SET_DBL_RESULT(result, (ZBX_DEV_READ == rw ? device->r_bps[mode] : device->w_bps[mode])); else if (ZBX_DSTAT_TYPE_OPS == type) SET_DBL_RESULT(result, (ZBX_DEV_READ == rw ? device->r_ops[mode] : device->w_ops[mode])); return SYSINFO_RET_OK; }
int VM_MEMORY_SIZE(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { PERFORMANCE_INFORMATION pfi; MEMORYSTATUSEX ms_ex; MEMORYSTATUS ms; char mode[16]; if (1 < num_param(param)) return SYSINFO_RET_FAIL; if (0 != get_param(param, 1, mode, sizeof(mode)) || '\0' == *mode) strscpy(mode, "total"); if (0 == strcmp(mode, "cached")) { if (NULL == zbx_GetPerformanceInfo) return SYSINFO_RET_FAIL; zbx_GetPerformanceInfo(&pfi, sizeof(PERFORMANCE_INFORMATION)); SET_UI64_RESULT(result, (zbx_uint64_t)pfi.SystemCache * pfi.PageSize); return SYSINFO_RET_OK; } if (NULL != zbx_GlobalMemoryStatusEx) { ms_ex.dwLength = sizeof(MEMORYSTATUSEX); zbx_GlobalMemoryStatusEx(&ms_ex); if (0 == strcmp(mode, "total")) SET_UI64_RESULT(result, ms_ex.ullTotalPhys); else if (0 == strcmp(mode, "free")) SET_UI64_RESULT(result, ms_ex.ullAvailPhys); else if (0 == strcmp(mode, "used")) SET_UI64_RESULT(result, ms_ex.ullTotalPhys - ms_ex.ullAvailPhys); else if (0 == strcmp(mode, "pused") && 0 != ms_ex.ullTotalPhys) SET_DBL_RESULT(result, (ms_ex.ullTotalPhys - ms_ex.ullAvailPhys) / (double)ms_ex.ullTotalPhys * 100); else if (0 == strcmp(mode, "available")) SET_UI64_RESULT(result, ms_ex.ullAvailPhys); else if (0 == strcmp(mode, "pavailable") && 0 != ms_ex.ullTotalPhys) SET_DBL_RESULT(result, ms_ex.ullAvailPhys / (double)ms_ex.ullTotalPhys * 100); else return SYSINFO_RET_FAIL; } else { GlobalMemoryStatus(&ms); if (0 == strcmp(mode, "total")) SET_UI64_RESULT(result, ms.dwTotalPhys); else if (0 == strcmp(mode, "free")) SET_UI64_RESULT(result, ms.dwAvailPhys); else if (0 == strcmp(mode, "used")) SET_UI64_RESULT(result, ms.dwTotalPhys - ms.dwAvailPhys); else if (0 == strcmp(mode, "pused") && 0 != ms.dwTotalPhys) SET_DBL_RESULT(result, (ms.dwTotalPhys - ms.dwAvailPhys) / (double)ms.dwTotalPhys * 100); else if (0 == strcmp(mode, "available")) SET_UI64_RESULT(result, ms.dwAvailPhys); else if (0 == strcmp(mode, "pavailable") && 0 != ms.dwTotalPhys) SET_DBL_RESULT(result, ms.dwAvailPhys / (double)ms.dwTotalPhys * 100); else return SYSINFO_RET_FAIL; } return SYSINFO_RET_OK; }
static void process_active_checks(char *server, unsigned short port) { register int i, s_count, p_count; char **pvalue; int now, send_err = SUCCEED, ret; unsigned long timestamp; char *source = NULL; char *value = NULL; unsigned short severity; long lastlogsize; char params[MAX_STRING_LEN]; char filename[MAX_STRING_LEN]; char pattern[MAX_STRING_LEN]; AGENT_RESULT result; zabbix_log( LOG_LEVEL_DEBUG, "In process_active_checks('%s',%u)",server, port); init_result(&result); now = (int)time(NULL); for(i=0; NULL != active_metrics[i].key && SUCCEED == send_err; i++) { if(active_metrics[i].nextcheck > now) continue; if(active_metrics[i].status != ITEM_STATUS_ACTIVE) continue; /* Special processing for log files */ if(strncmp(active_metrics[i].key,"log[",4) == 0) { do{ /* simple try realization */ if (parse_command(active_metrics[i].key, NULL, 0, params, MAX_STRING_LEN) != 2) break; if (num_param(params) > 2) break; if (get_param(params, 1, filename, sizeof(filename)) != 0) break; if (get_param(params, 2, pattern, sizeof(pattern)) != 0) *pattern = '\0'; s_count = 0; p_count = 0; lastlogsize = active_metrics[i].lastlogsize; while (SUCCEED == (ret = process_log(filename, &lastlogsize, &value))) { if (!value) /* EOF */ break; if (SUCCEED == regexp_match_ex(regexps, regexps_num, value, pattern, ZBX_CASE_SENSITIVE)) { send_err = process_value( server, port, CONFIG_HOSTNAME, active_metrics[i].key_orig, value, &lastlogsize, NULL, NULL, NULL ); s_count++; } p_count++; zbx_free(value); if (SUCCEED == send_err) active_metrics[i].lastlogsize = lastlogsize; else lastlogsize = active_metrics[i].lastlogsize; /* Do not flood ZABBIX server if file grows too fast */ if(s_count >= (MAX_LINES_PER_SECOND * active_metrics[i].refresh)) break; /* Do not flood local system if file grows too fast */ if(p_count >= (4 * MAX_LINES_PER_SECOND * active_metrics[i].refresh)) break; } if( FAIL == ret ) { active_metrics[i].status = ITEM_STATUS_NOTSUPPORTED; zabbix_log( LOG_LEVEL_WARNING, "Active check [%s] is not supported. Disabled.", active_metrics[i].key); send_err = process_value( server, port, CONFIG_HOSTNAME, active_metrics[i].key_orig, "ZBX_NOTSUPPORTED", &active_metrics[i].lastlogsize, NULL, NULL, NULL ); } }while(0); /* simple try realization */ } /* Special processing for eventlog */ else if(strncmp(active_metrics[i].key,"eventlog[",9) == 0) { do{ /* simple try realization */ if (parse_command(active_metrics[i].key, NULL, 0, params, MAX_STRING_LEN) != 2) break; if (num_param(params) > 2) break; if (get_param(params, 1, filename, sizeof(filename)) != 0) break; if (get_param(params, 2, pattern, sizeof(pattern)) != 0) *pattern = '\0'; s_count = 0; p_count = 0; lastlogsize = active_metrics[i].lastlogsize; while (SUCCEED == (ret = process_eventlog(filename, &lastlogsize, ×tamp, &source, &severity, &value))) { if (!value) /* EOF */ break; if (SUCCEED == regexp_match_ex(regexps, regexps_num, value, pattern, ZBX_CASE_SENSITIVE)) { send_err = process_value( server, port, CONFIG_HOSTNAME, active_metrics[i].key_orig, value, &lastlogsize, ×tamp, source, &severity ); s_count++; } p_count++; zbx_free(source); zbx_free(value); if (SUCCEED == send_err) active_metrics[i].lastlogsize = lastlogsize; else lastlogsize = active_metrics[i].lastlogsize; /* Do not flood ZABBIX server if file grows too fast */ if(s_count >= (MAX_LINES_PER_SECOND * active_metrics[i].refresh)) break; /* Do not flood local system if file grows too fast */ if(p_count >= (4 * MAX_LINES_PER_SECOND * active_metrics[i].refresh)) break; } if( FAIL == ret ) { active_metrics[i].status = ITEM_STATUS_NOTSUPPORTED; zabbix_log( LOG_LEVEL_WARNING, "Active check [%s] is not supported. Disabled.", active_metrics[i].key); send_err = process_value( server, port, CONFIG_HOSTNAME, active_metrics[i].key_orig, "ZBX_NOTSUPPORTED", &active_metrics[i].lastlogsize, NULL, NULL, NULL ); } }while(0); /* simple try realization NOTE: never loop */ } else { process(active_metrics[i].key, 0, &result); if( NULL == (pvalue = GET_TEXT_RESULT(&result)) ) pvalue = GET_MSG_RESULT(&result); if(pvalue) { zabbix_log( LOG_LEVEL_DEBUG, "For key [%s] received value [%s]", active_metrics[i].key, *pvalue); send_err = process_value( server, port, CONFIG_HOSTNAME, active_metrics[i].key_orig, *pvalue, NULL, NULL, NULL, NULL ); if( 0 == strcmp(*pvalue,"ZBX_NOTSUPPORTED") ) { active_metrics[i].status = ITEM_STATUS_NOTSUPPORTED; zabbix_log( LOG_LEVEL_WARNING, "Active check [%s] is not supported. Disabled.", active_metrics[i].key); } } free_result(&result); } active_metrics[i].nextcheck = (int)time(NULL)+active_metrics[i].refresh; } }
int PROC_MEMORY(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { #if defined(HAVE_PROC_1_STATUS) DIR *dir; struct dirent *entries; struct stat buf; char filename[MAX_STRING_LEN]; char line[MAX_STRING_LEN]; char name1[MAX_STRING_LEN]; char name2[MAX_STRING_LEN]; char procname[MAX_STRING_LEN]; char usrname[MAX_STRING_LEN]; char mode[MAX_STRING_LEN]; int proc_ok = 0; int usr_ok = 0; int do_task = DO_SUM; struct passwd *usrinfo = NULL; long long int llvalue = 0; FILE *f; double memsize = -1; int proccount = 0; assert(result); init_result(result); if(num_param(param) > 3) { return SYSINFO_RET_FAIL; } if(get_param(param, 1, procname, MAX_STRING_LEN) != 0) { return SYSINFO_RET_FAIL; } if(get_param(param, 2, usrname, MAX_STRING_LEN) != 0) { usrname[0] = 0; } else { if(usrname[0] != 0) { usrinfo = getpwnam(usrname); if(usrinfo == NULL) { /* incorrect user name */ return SYSINFO_RET_FAIL; } } } if(get_param(param, 3, mode, MAX_STRING_LEN) != 0) { mode[0] = '\0'; } if(mode[0] == '\0') { strscpy(mode, "sum"); } if(strcmp(mode,"avg") == 0) { do_task = DO_AVG; } else if(strcmp(mode,"max") == 0) { do_task = DO_MAX; } else if(strcmp(mode,"min") == 0) { do_task = DO_MIN; } else if(strcmp(mode,"sum") == 0) { do_task = DO_SUM; } else { return SYSINFO_RET_FAIL; } dir=opendir("/proc"); if(NULL == dir) { return SYSINFO_RET_FAIL; } while((entries=readdir(dir))!=NULL) { proc_ok = 0; usr_ok = 0; strscpy(filename,"/proc/"); zbx_strlcat(filename,entries->d_name,MAX_STRING_LEN); zbx_strlcat(filename,"/status",MAX_STRING_LEN); /* Self is a symbolic link. It leads to incorrect results for proc_cnt[zabbix_agentd] */ /* Better approach: check if /proc/x/ is symbolic link */ if(strncmp(entries->d_name,"self",MAX_STRING_LEN) == 0) { continue; } if(stat(filename,&buf)==0) { if(NULL == (f = fopen(filename,"r") )) { continue; } if(procname[0] != 0) { fgets(line,MAX_STRING_LEN,f); if(sscanf(line,"%s\t%s\n",name1,name2)==2) { if(strcmp(name1,"Name:") == 0) { if(strcmp(procname,name2)==0) { proc_ok = 1; } } } if(proc_ok == 0) { zbx_fclose(f); continue; } } else { proc_ok = 1; } if(usrinfo != NULL) { while(fgets(line, MAX_STRING_LEN, f) != NULL) { if(sscanf(line, "%s\t%lli\n", name1, &llvalue) != 2) { continue; } if(strcmp(name1,"Uid:") != 0) { continue; } if(usrinfo->pw_uid == (uid_t)(llvalue)) { usr_ok = 1; break; } } } else { usr_ok = 1; } if(proc_ok && usr_ok) { while(fgets(line, MAX_STRING_LEN, f) != NULL) { if(sscanf(line, "%s\t%lli %s\n", name1, &llvalue, name2) != 3) { continue; } if(strcmp(name1,"VmSize:") != 0) { continue; } proccount++; if(strcasecmp(name2, "kB") == 0) { llvalue <<= 10; } else if(strcasecmp(name2, "mB") == 0) { llvalue <<= 20; } else if(strcasecmp(name2, "GB") == 0) { llvalue <<= 30; } else if(strcasecmp(name2, "TB") == 0) { llvalue <<= 40; } if(memsize < 0) { memsize = (double) llvalue; } else { if(do_task == DO_MAX) { memsize = MAX(memsize, (double) llvalue); } else if(do_task == DO_MIN) { memsize = MIN(memsize, (double) llvalue); } else { memsize += (double) llvalue; } } break; } } zbx_fclose(f); } } closedir(dir); if(memsize < 0) { /* incorrect process name */ memsize = 0; } if(do_task == DO_AVG) { SET_DBL_RESULT(result, proccount == 0 ? 0 : ((double)memsize/(double)proccount)); } else { SET_UI64_RESULT(result, memsize); } return SYSINFO_RET_OK; #else return SYSINFO_RET_FAIL; #endif }
int SYSTEM_CPU_LOAD(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { char cpuname[10], mode[10]; if(num_param(param) > 2) { return SYSINFO_RET_FAIL; } if(get_param(param, 1, cpuname, sizeof(cpuname)) != 0) { cpuname[0] = '\0'; } if(cpuname[0] == '\0') { /* default parameter */ zbx_snprintf(cpuname, sizeof(cpuname), "all"); } if(get_param(param, 2, mode, sizeof(mode)) != 0) { mode[0] = '\0'; } if(mode[0] == '\0') { /* default parameter */ zbx_snprintf(mode, sizeof(mode), "avg1"); } if(strcmp(cpuname,"all") != 0) { return SYSINFO_RET_FAIL; } if ( !CPU_COLLECTOR_STARTED(collector) ) { SET_MSG_RESULT(result, strdup("Collector is not started!")); return SYSINFO_RET_OK; } if(strcmp(mode,"avg1") == 0) { SET_DBL_RESULT(result, collector->cpus.load1); } else if(strcmp(mode,"avg5") == 0) { SET_DBL_RESULT(result, collector->cpus.load5); } else if(strcmp(mode,"avg15") == 0) { SET_DBL_RESULT(result, collector->cpus.load15); } else { return SYSINFO_RET_FAIL; } return SYSINFO_RET_OK; }
int RUN_COMMAND(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { #define MAX_FLAG_LEN 10 char command[MAX_STRING_LEN]; char flag[MAX_FLAG_LEN]; #if defined (_WINDOWS) STARTUPINFO si; PROCESS_INFORMATION pi; char full_command[MAX_STRING_LEN]; #else /* not _WINDOWS */ pid_t pid; #endif assert(result); init_result(result); if (CONFIG_ENABLE_REMOTE_COMMANDS != 1) { SET_MSG_RESULT(result, strdup("ZBX_NOTSUPPORTED")); return SYSINFO_RET_FAIL; } if (num_param(param) > 2) return SYSINFO_RET_FAIL; if (0 != get_param(param, 1, command, sizeof(command))) return SYSINFO_RET_FAIL; if (*command == '\0') return SYSINFO_RET_FAIL; zabbix_log(LOG_LEVEL_DEBUG, "Run command '%s'", command); if (0 != get_param(param, 2, flag, sizeof(flag))) *flag = '\0'; if (*flag == '\0') zbx_snprintf(flag, sizeof(flag), "wait"); if (0 == strcmp(flag, "wait")) return EXECUTE_STR(cmd,command,flags,result); else if(0 != strcmp(flag,"nowait")) return SYSINFO_RET_FAIL; #if defined(_WINDOWS) zbx_snprintf(full_command, sizeof(full_command), "cmd /C \"%s\"", command); GetStartupInfo(&si); zabbix_log(LOG_LEVEL_DEBUG, "Execute command '%s'",full_command); if(!CreateProcess( NULL, /* No module name (use command line) */ full_command,/* Name of app to launch */ NULL, /* Default process security attributes */ NULL, /* Default thread security attributes */ FALSE, /* Don't inherit handles from the parent */ 0, /* Normal priority */ NULL, /* Use the same environment as the parent */ NULL, /* Launch in the current directory */ &si, /* Startup Information */ &pi)) /* Process information stored upon return */ { return SYSINFO_RET_FAIL; } #else /* not _WINDOWS */ pid = zbx_fork(); /* run new thread 1 */ switch(pid) { case -1: zabbix_log(LOG_LEVEL_WARNING, "fork failed for command '%s'",command); return SYSINFO_RET_FAIL; case 0: pid = zbx_fork(); /* run new tread 2 to replace by command */ switch(pid) { case -1: zabbix_log(LOG_LEVEL_WARNING, "fork2 failed for '%s'",command); return SYSINFO_RET_FAIL; case 0: /* * DON'T REMOVE SLEEP * sleep needed to return server result as "1" * then we can run "execl" * otherwise command print result into socket with STDOUT id */ sleep(3); /**/ /* replace thread 2 by the execution of command */ if(execl("/bin/sh", "sh", "-c", command, (char *)0)) { zabbix_log(LOG_LEVEL_WARNING, "execl failed for command '%s'",command); } /* In normal case the program will never reach this point */ exit(0); default: waitpid(pid, NULL, WNOHANG); /* NO WAIT can be used for thread 2 closing */ exit(0); /* close thread 1 and transmit thread 2 to system (solve zombie state) */ break; } default: waitpid(pid, NULL, 0); /* wait thread 1 closing */ break; } #endif /* _WINDOWS */ SET_UI64_RESULT(result, 1); return SYSINFO_RET_OK; }
int PROC_NUM(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { DIR *dir; int proc; struct dirent *entries; struct stat buf; struct passwd *usrinfo = NULL; struct prpsinfo psinfo; char filename[MAX_STRING_LEN]; char procname[MAX_STRING_LEN]; char usrname[MAX_STRING_LEN]; char procstat[MAX_STRING_LEN]; char proccomm[MAX_STRING_LEN]; int do_task = DO_SUM; int proccount = 0; pid_t curr_pid = getpid(); if(num_param(param) > 4) { return SYSINFO_RET_FAIL; } if(get_param(param, 1, procname, MAX_STRING_LEN) != 0) { return SYSINFO_RET_FAIL; } if(get_param(param, 2, usrname, MAX_STRING_LEN) != 0) { usrname[0] = 0; } else { if(usrname[0] != 0) { usrinfo = getpwnam(usrname); if(usrinfo == NULL) { /* incorrect user name */ return SYSINFO_RET_FAIL; } } } if(get_param(param, 3, procstat, MAX_STRING_LEN) != 0) { procstat[0] = '\0'; } if(procstat[0] == '\0') { strscpy(procstat, "all"); } if(strcmp(procstat,"run") == 0) { procstat[0] = PR_SRUN; procstat[1] = '\0'; } else if(strcmp(procstat,"sleep") == 0) { procstat[0] = PR_SSLEEP; procstat[1] = '\0'; } else if(strcmp(procstat,"zomb") == 0) { procstat[0] = PR_SZOMB; procstat[1] = '\0'; } else if(strcmp(procstat,"all") == 0) { procstat[0] = '\0'; } else { return SYSINFO_RET_FAIL; } if(get_param(param, 4, proccomm, MAX_STRING_LEN) != 0) { proccomm[0] = '\0'; } dir=opendir("/proc"); if(NULL == dir) { return SYSINFO_RET_FAIL; } while((entries=readdir(dir))!=NULL) { strscpy(filename,"/proc/"); zbx_strlcat(filename,entries->d_name,MAX_STRING_LEN); if(stat(filename,&buf)==0) { proc = open(filename,O_RDONLY); if(proc == -1) goto lbl_skip_procces; if(ioctl(proc,PIOCPSINFO,&psinfo) == -1) goto lbl_skip_procces; /* Self process information. It leads to incorrect results for proc_cnt[zabbix_agentd] */ if(psinfo.pr_pid == curr_pid) goto lbl_skip_procces; if(procname[0] != 0) if(strcmp(procname,psinfo.pr_fname) != 0) goto lbl_skip_procces; if(usrinfo != NULL) if(usrinfo->pw_uid != psinfo.pr_uid) goto lbl_skip_procces; if(procstat[0] != '\0') if(psinfo.pr_sname != procstat[0]) goto lbl_skip_procces; if(proccomm[0] != '\0') if(zbx_regexp_match(psinfo.pr_psargs,proccomm,NULL) == NULL) goto lbl_skip_procces; proccount++; lbl_skip_procces: if(proc) close(proc); } } closedir(dir); SET_UI64_RESULT(result, proccount); return SYSINFO_RET_OK; }
/****************************************************************************** * * * Function: get_value_external * * * * Purpose: retrieve data from script executed on Zabbix server * * * * Parameters: item - item we are interested in * * * * Return value: SUCCEED - data successfully retrieved and stored in result * * and result_str (as string) * * NOTSUPPORTED - requested item is not supported * * * * Author: Mike Nestor, rewritten by Alexander Vladishev * * * ******************************************************************************/ int get_value_external(DC_ITEM *item, AGENT_RESULT *result) { const char *__function_name = "get_value_external"; char key[MAX_STRING_LEN], params[MAX_STRING_LEN], error[ITEM_ERROR_LEN_MAX], *cmd = NULL, *buf = NULL; size_t cmd_alloc = ZBX_KIBIBYTE, cmd_offset = 0; int rc, ret = NOTSUPPORTED; zabbix_log(LOG_LEVEL_DEBUG, "In %s() key:'%s'", __function_name, item->key_orig); if (ZBX_COMMAND_ERROR == (rc = parse_command(item->key, key, sizeof(key), params, sizeof(params)))) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Key is badly formatted")); goto notsupported; } cmd = zbx_malloc(cmd, cmd_alloc); zbx_snprintf_alloc(&cmd, &cmd_alloc, &cmd_offset, "%s/%s", CONFIG_EXTERNALSCRIPTS, key); if (-1 == access(cmd, X_OK)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "%s: %s", cmd, zbx_strerror(errno))); goto notsupported; } if (ZBX_COMMAND_WITH_PARAMS == rc) { int i, n; char param[MAX_STRING_LEN], *param_esc; if (0 == (n = num_param(params))) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Key is badly formatted")); goto notsupported; } for (i = 1; i <= n; i++) { if (0 != get_param(params, i, param, sizeof(param))) { THIS_SHOULD_NEVER_HAPPEN; *param = '\0'; } param_esc = zbx_dyn_escape_string(param, "\"\\"); zbx_snprintf_alloc(&cmd, &cmd_alloc, &cmd_offset, " \"%s\"", param_esc); zbx_free(param_esc); } } if (SUCCEED == zbx_execute(cmd, &buf, error, sizeof(error), CONFIG_TIMEOUT)) { zbx_rtrim(buf, ZBX_WHITESPACE); if (SUCCEED == set_result_type(result, item->value_type, item->data_type, buf)) ret = SUCCEED; zbx_free(buf); } else SET_MSG_RESULT(result, zbx_strdup(NULL, error)); notsupported: zbx_free(cmd); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
int PERF_COUNTER(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { const char *__function_name = "PERF_COUNTER"; char counterpath[PDH_MAX_COUNTER_PATH], tmp[MAX_STRING_LEN]; int ret = SYSINFO_RET_FAIL, interval; double value; PERF_COUNTER_DATA *perfs = NULL; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (2 < num_param(param)) goto clean; if (0 != get_param(param, 1, counterpath, sizeof(counterpath)) || '\0' == *counterpath) goto clean; if (0 != get_param(param, 2, tmp, sizeof(tmp)) || '\0' == *tmp) interval = 1; else if (FAIL == is_uint(tmp)) goto clean; else interval = atoi(tmp); if (FAIL == check_counter_path(counterpath)) goto clean; if (1 < interval) { if (!PERF_COLLECTOR_STARTED(collector)) { zabbix_log(LOG_LEVEL_DEBUG, "Collector is not started!"); goto clean; } for (perfs = collector->perfs.pPerfCounterList; NULL != perfs; perfs = perfs->next) { if (0 == strcmp(perfs->counterpath, counterpath) && perfs->interval == interval) { if (PERF_COUNTER_ACTIVE != perfs->status) break; SET_DBL_RESULT(result, compute_average_value(__function_name, perfs, USE_DEFAULT_INTERVAL)); ret = SYSINFO_RET_OK; goto clean; } } if (NULL == perfs && NULL == (perfs = add_perf_counter(NULL, counterpath, interval))) goto clean; } if (ERROR_SUCCESS == calculate_counter_value(__function_name, counterpath, &value)) { if (NULL != perfs) perfs->status = PERF_COUNTER_INITIALIZED; SET_DBL_RESULT(result, value); ret = SYSINFO_RET_OK; } clean: zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return ret; }
/****************************************************************************** * * * Function: process_updated_records * * * * Purpose: * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ static void process_updated_records(int nodeid, char *data) { const char *__function_name = "process_updated_records"; char *r, *lf, *value_esc; int op, dnum; const ZBX_TABLE *table = NULL; const ZBX_FIELD *field = NULL; zbx_uint64_t recid; char *dsql = NULL, *isql = NULL, *ifld = NULL, *ival = NULL, *usql = NULL, *ufld = NULL; size_t dsql_alloc = 4 * ZBX_KIBIBYTE, dsql_offset = 0, dtmp_offset = 0, isql_alloc = 4 * ZBX_KIBIBYTE, isql_offset = 0, ifld_alloc = 4 * ZBX_KIBIBYTE, ifld_offset = 0, ival_alloc = 4 * ZBX_KIBIBYTE, ival_offset = 0, usql_alloc = 4 * ZBX_KIBIBYTE, usql_offset = 0, ufld_alloc = 4 * ZBX_KIBIBYTE, ufld_offset = 0; DB_RESULT result; DB_ROW row; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); dsql = zbx_malloc(dsql, dsql_alloc); isql = zbx_malloc(isql, isql_alloc); ifld = zbx_malloc(ifld, ifld_alloc); ival = zbx_malloc(ival, ival_alloc); usql = zbx_malloc(usql, usql_alloc); ufld = zbx_malloc(ufld, ufld_alloc); #ifdef HAVE_ORACLE DBbegin_multiple_update(&dsql, &dsql_alloc, &dsql_offset); DBbegin_multiple_update(&isql, &isql_alloc, &isql_offset); DBbegin_multiple_update(&usql, &usql_alloc, &usql_offset); #endif for (r = data; '\0' != *r;) { if (NULL != (lf = strchr(r, '\n'))) *lf = '\0'; /* table name */ zbx_get_next_field((const char **)&r, &buf, &buf_alloc, ZBX_DM_DELIMITER); if (NULL == table || 0 != strcmp(table->table, buf)) { if (NULL == (table = DBget_table(buf))) { zabbix_log(LOG_LEVEL_DEBUG, "%s(): cannot find table [%s]", __function_name, buf); goto next; } } /* record id */ zbx_get_next_field((const char **)&r, &buf, &buf_alloc, ZBX_DM_DELIMITER); ZBX_STR2UINT64(recid, buf); if (NULL == r) { zabbix_log(LOG_LEVEL_DEBUG, "%s(): invalid record", __function_name); goto next; } if ('0' == *r) /* NODE_CONFIGLOG_OP_UPDATE */ { result = DBselect("select 0 from %s where %s=" ZBX_FS_UI64, table->table, table->recid, recid); if (NULL == (row = DBfetch(result))) op = NODE_CONFIGLOG_OP_ADD; else op = NODE_CONFIGLOG_OP_UPDATE; DBfree_result(result); zbx_get_next_field((const char **)&r, &buf, &buf_alloc, ZBX_DM_DELIMITER); ifld_offset = 0; ival_offset = 0; ufld_offset = 0; dtmp_offset = dsql_offset; dnum = 0; if (op == NODE_CONFIGLOG_OP_ADD && NULL != table->uniq) { zbx_snprintf_alloc(&dsql, &dsql_alloc, &dsql_offset, "delete from %s where ", table->table); } while (NULL != r) { /* field name */ zbx_get_next_field((const char **)&r, &buf, &buf_alloc, ZBX_DM_DELIMITER); if (NULL == (field = DBget_field(table, buf))) { zabbix_log(LOG_LEVEL_DEBUG, "%s(): cannot find field [%s.%s]", __function_name, table->table, buf); goto next; } if (NODE_CONFIGLOG_OP_UPDATE == op) zbx_snprintf_alloc(&ufld, &ufld_alloc, &ufld_offset, "%s=", buf); else /* NODE_CONFIGLOG_OP_ADD */ zbx_snprintf_alloc(&ifld, &ifld_alloc, &ifld_offset, "%s,", buf); /* value type (ignored) */ zbx_get_next_field((const char **)&r, &buf, &buf_alloc, ZBX_DM_DELIMITER); zbx_get_next_field((const char **)&r, &buf, &buf_alloc, ZBX_DM_DELIMITER); if (0 == strcmp(buf, "NULL")) { if (NODE_CONFIGLOG_OP_UPDATE == op) zbx_strcpy_alloc(&ufld, &ufld_alloc, &ufld_offset, "NULL,"); else /* NODE_CONFIGLOG_OP_ADD */ zbx_strcpy_alloc(&ival, &ival_alloc, &ival_offset, "NULL,"); continue; } switch (field->type) { case ZBX_TYPE_ID: /* if the field relates the same table * for example: host.proxy_hostid relates with host.hostid */ if (NODE_CONFIGLOG_OP_ADD == op && NULL != field->fk_table && 0 == strcmp(table->table, field->fk_table)) { zbx_snprintf_alloc(&ufld, &ufld_alloc, &ufld_offset, "%s=%s,", field->name, buf); zbx_strcpy_alloc(&ival, &ival_alloc, &ival_offset, "NULL,"); break; } case ZBX_TYPE_INT: case ZBX_TYPE_UINT: case ZBX_TYPE_FLOAT: if (NODE_CONFIGLOG_OP_UPDATE == op) zbx_snprintf_alloc(&ufld, &ufld_alloc, &ufld_offset, "%s,", buf); else /* NODE_CONFIGLOG_OP_ADD */ { zbx_snprintf_alloc(&ival, &ival_alloc, &ival_offset, "%s,", buf); if (NULL != table->uniq && SUCCEED == str_in_list(table->uniq, field->name, ',')) { zbx_snprintf_alloc(&dsql, &dsql_alloc, &dsql_offset, "%s=%s and ", field->name, buf); dnum++; } } break; case ZBX_TYPE_BLOB: if ('\0' == *buf) { if (NODE_CONFIGLOG_OP_UPDATE == op) zbx_strcpy_alloc(&ufld, &ufld_alloc, &ufld_offset, "'',"); else /* NODE_CONFIGLOG_OP_ADD */ zbx_strcpy_alloc(&ival, &ival_alloc, &ival_offset, "'',"); } else { #if defined(HAVE_POSTGRESQL) size_t len; len = zbx_hex2binary(buf); DBbytea_escape((u_char *)buf, len, &tmp, &tmp_alloc); if (NODE_CONFIGLOG_OP_UPDATE == op) zbx_snprintf_alloc(&ufld, &ufld_alloc, &ufld_offset, "'%s',", tmp); else /* NODE_CONFIGLOG_OP_ADD */ zbx_snprintf_alloc(&ival, &ival_alloc, &ival_offset, "'%s',", tmp); #else if (NODE_CONFIGLOG_OP_UPDATE == op) zbx_snprintf_alloc(&ufld, &ufld_alloc, &ufld_offset, "0x%s,", buf); else /* NODE_CONFIGLOG_OP_ADD */ zbx_snprintf_alloc(&ival, &ival_alloc, &ival_offset, "0x%s,", buf); #endif } break; default: /* ZBX_TYPE_TEXT, ZBX_TYPE_CHAR */ zbx_hex2binary(buf); value_esc = DBdyn_escape_string(buf); if (NODE_CONFIGLOG_OP_UPDATE == op) zbx_snprintf_alloc(&ufld, &ufld_alloc, &ufld_offset, "'%s',", value_esc); else /* NODE_CONFIGLOG_OP_ADD */ { zbx_snprintf_alloc(&ival, &ival_alloc, &ival_offset, "'%s',", value_esc); if (NULL != table->uniq && SUCCEED == str_in_list(table->uniq, field->name, ',')) { zbx_snprintf_alloc(&dsql, &dsql_alloc, &dsql_offset, "%s='%s' and ", field->name, value_esc); dnum++; } } zbx_free(value_esc); } } if (dsql_offset != dtmp_offset) { if (dnum != num_param(table->uniq)) { zabbix_log(LOG_LEVEL_DEBUG, "%s(): missing required fields [%s][%s]", __function_name, table->table, table->uniq); dsql_offset = dtmp_offset; goto next; } dsql_offset -= 5; zbx_strcpy_alloc(&dsql, &dsql_alloc, &dsql_offset, ";\n"); } if (0 != ifld_offset) { ifld[--ifld_offset] = '\0'; ival[--ival_offset] = '\0'; zbx_snprintf_alloc(&isql, &isql_alloc, &isql_offset, "insert into %s (%s,%s) values (" ZBX_FS_UI64 ",%s);\n", table->table, table->recid, ifld, recid, ival); } if (0 != ufld_offset) { ufld[--ufld_offset] = '\0'; zbx_snprintf_alloc(&usql, &usql_alloc, &usql_offset, "update %s set %s where %s=" ZBX_FS_UI64 ";\n", table->table, ufld, table->recid, recid); } if (dsql_offset > ZBX_MAX_SQL_SIZE || isql_offset > ZBX_MAX_SQL_SIZE || usql_offset > ZBX_MAX_SQL_SIZE) { DBend_multiple_update(&dsql, &dsql_alloc, &dsql_offset); DBend_multiple_update(&isql, &isql_alloc, &isql_offset); DBend_multiple_update(&usql, &usql_alloc, &usql_offset); if (dsql_offset > 16) DBexecute("%s", dsql); if (isql_offset > 16) DBexecute("%s", isql); if (usql_offset > 16) DBexecute("%s", usql); dsql_offset = 0; isql_offset = 0; usql_offset = 0; #ifdef HAVE_ORACLE DBbegin_multiple_update(&dsql, &dsql_alloc, &dsql_offset); DBbegin_multiple_update(&isql, &isql_alloc, &isql_offset); DBbegin_multiple_update(&usql, &usql_alloc, &usql_offset); #endif } } next: if (lf != NULL) { *lf++ = '\n'; r = lf; } else break; } DBend_multiple_update(&dsql, &dsql_alloc, &dsql_offset); DBend_multiple_update(&isql, &isql_alloc, &isql_offset); DBend_multiple_update(&usql, &usql_alloc, &usql_offset); if (dsql_offset > 16) DBexecute("%s", dsql); if (isql_offset > 16) DBexecute("%s", isql); if (usql_offset > 16) DBexecute("%s", usql); zbx_free(ufld); zbx_free(usql); zbx_free(ival); zbx_free(ifld); zbx_free(isql); zbx_free(dsql); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
int SYSTEM_LOCALTIME(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { char type[16], buf[32]; struct tm *tm; size_t offset; int gmtoff, ms; unsigned short h, m; #ifdef _WINDOWS struct _timeb tv; #else struct timeval tv; struct timezone tz; #endif if (3 < num_param(param)) return SYSINFO_RET_FAIL; if (0 != get_param(param, 1, type, sizeof(type))) return SYSINFO_RET_FAIL; if ('\0' == *type || 0 == strcmp(type, "utc")) { SET_UI64_RESULT(result, time(NULL)); } else if (0 == strcmp(type, "local")) { #ifdef _WINDOWS _ftime(&tv); tm = localtime(&tv.time); ms = tv.millitm; #else gettimeofday(&tv, &tz); tm = localtime(&tv.tv_sec); ms = (int)(tv.tv_usec / 1000); #endif offset = zbx_snprintf(buf, sizeof(buf), "%04d-%02d-%02d,%02d:%02d:%02d.%03d,", 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, ms); /* timezone offset */ #if defined(HAVE_TM_TM_GMTOFF) gmtoff = tm->tm_gmtoff; #else gmtoff = -timezone; #endif #ifdef _WINDOWS if (0 < tm->tm_isdst) /* daylight saving time */ gmtoff += SEC_PER_HOUR; /* assume DST is one hour */ #endif h = (unsigned short)(abs(gmtoff) / SEC_PER_HOUR); m = (unsigned short)((abs(gmtoff) - h * SEC_PER_HOUR) / SEC_PER_MIN); if (0 <= gmtoff) offset += zbx_snprintf(buf + offset, sizeof(buf) - offset, "+"); else offset += zbx_snprintf(buf + offset, sizeof(buf) - offset, "-"); offset += zbx_snprintf(buf + offset, sizeof(buf) - offset, "%02d:%02d", (int)h, (int)m); SET_STR_RESULT(result, strdup(buf)); } else return SYSINFO_RET_FAIL; return SYSINFO_RET_OK; }
/****************************************************************************** * * * Function: aggregate_get_items * * * * Purpose: get array of items specified by key for selected groups * * * * Parameters: itemids - [OUT] list of item ids * * groups - [IN] list of comma-separated host groups * * itemkey - [IN] item key to aggregate * * * ******************************************************************************/ static void aggregate_get_items(zbx_vector_uint64_t *itemids, const char *groups, const char *itemkey) { const char *__function_name = "aggregate_get_items"; char *group, *esc; DB_RESULT result; DB_ROW row; zbx_uint64_t itemid; char *sql = NULL; size_t sql_alloc = ZBX_KIBIBYTE, sql_offset = 0; int num, n; zabbix_log(LOG_LEVEL_DEBUG, "In %s() groups:'%s' itemkey:'%s'", __function_name, groups, itemkey); sql = zbx_malloc(sql, sql_alloc); esc = DBdyn_escape_string(itemkey); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select distinct i.itemid" " from items i,hosts h,hosts_groups hg,groups g" " where i.hostid=h.hostid" " and h.hostid=hg.hostid" " and hg.groupid=g.groupid" " and i.key_='%s'" " and i.status=%d" " and i.state=%d" " and h.status=%d", esc, ITEM_STATUS_ACTIVE, ITEM_STATE_NORMAL, HOST_STATUS_MONITORED); zbx_free(esc); num = num_param(groups); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " and g.name in ("); for (n = 1; n <= num; n++) { if (NULL == (group = get_param_dyn(groups, n))) continue; esc = DBdyn_escape_string(group); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "'%s'", esc); if (n != num) zbx_chrcpy_alloc(&sql, &sql_alloc, &sql_offset, ','); zbx_free(esc); zbx_free(group); } zbx_chrcpy_alloc(&sql, &sql_alloc, &sql_offset, ')'); result = DBselect("%s", sql); zbx_free(sql); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(itemid, row[0]); zbx_vector_uint64_append(itemids, itemid); } DBfree_result(result); zbx_vector_uint64_sort(itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
int SYSTEM_STAT(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { char section[16], type[8]; int nparams; if (!VMSTAT_COLLECTOR_STARTED(collector)) { SET_MSG_RESULT(result, strdup("Collector is not started!")); return SYSINFO_RET_FAIL; } nparams = num_param(param); if (nparams > 2) return SYSINFO_RET_FAIL; if (0 != get_param(param, 1, section, sizeof(section))) return SYSINFO_RET_FAIL; if (0 != get_param(param, 2, type, sizeof(type))) *type = '\0'; if (0 == strcmp(section, "kthr")) { if (0 == strcmp(type, "r")) SET_DBL_RESULT(result, collector->vmstat.kthr_r); else if (0 == strcmp(type, "b")) SET_DBL_RESULT(result, collector->vmstat.kthr_b); else return SYSINFO_RET_FAIL; } else if (0 == strcmp(section, "page")) { if (0 == strcmp(type, "fi")) SET_DBL_RESULT(result, collector->vmstat.fi); else if (0 == strcmp(type, "fo")) SET_DBL_RESULT(result, collector->vmstat.fo); else if (0 == strcmp(type, "pi")) SET_DBL_RESULT(result, collector->vmstat.pi); else if (0 == strcmp(type, "po")) SET_DBL_RESULT(result, collector->vmstat.po); else if (0 == strcmp(type, "fr")) SET_DBL_RESULT(result, collector->vmstat.fr); else if (0 == strcmp(type, "sr")) SET_DBL_RESULT(result, collector->vmstat.sr); else return SYSINFO_RET_FAIL; } else if (0 == strcmp(section, "faults")) { if (0 == strcmp(type, "in")) SET_DBL_RESULT(result, collector->vmstat.in); else if (0 == strcmp(type, "sy")) SET_DBL_RESULT(result, collector->vmstat.sy); else if (0 == strcmp(type, "cs")) SET_DBL_RESULT(result, collector->vmstat.cs); else return SYSINFO_RET_FAIL; } else if (0 == strcmp(section, "cpu")) { if (0 == strcmp(type, "us")) SET_DBL_RESULT(result, collector->vmstat.cpu_us); else if (0 == strcmp(type, "sy")) SET_DBL_RESULT(result, collector->vmstat.cpu_sy); else if (0 == strcmp(type, "id")) SET_DBL_RESULT(result, collector->vmstat.cpu_id); else if (0 == strcmp(type, "wa")) SET_DBL_RESULT(result, collector->vmstat.cpu_wa); else if (0 == strcmp(type, "pc") && collector->vmstat.shared_enabled) SET_DBL_RESULT(result, collector->vmstat.cpu_pc); else if (0 == strcmp(type, "ec") && collector->vmstat.shared_enabled) SET_DBL_RESULT(result, collector->vmstat.cpu_ec); else if (0 == strcmp(type, "lbusy") && collector->vmstat.shared_enabled) SET_DBL_RESULT(result, collector->vmstat.cpu_lbusy); else if (0 == strcmp(type, "app") && collector->vmstat.shared_enabled && collector->vmstat.pool_util_authority) SET_DBL_RESULT(result, collector->vmstat.cpu_app); else return SYSINFO_RET_FAIL; } else if (0 == strcmp(section, "disk")) { if (0 == strcmp(type, "bps")) SET_UI64_RESULT(result, collector->vmstat.disk_bps); else if (0 == strcmp(type, "tps")) SET_DBL_RESULT(result, collector->vmstat.disk_tps); else return SYSINFO_RET_FAIL; } else if (0 == strcmp(section, "ent") && nparams == 1 && collector->vmstat.shared_enabled) SET_DBL_RESULT(result, collector->vmstat.ent); else if (0 == strcmp(section, "memory")) { if (0 == strcmp(type, "avm") && collector->vmstat.aix52stats) SET_UI64_RESULT(result, collector->vmstat.mem_avm); else if (0 == strcmp(type, "fre")) SET_UI64_RESULT(result, collector->vmstat.mem_fre); else return SYSINFO_RET_FAIL; } else return SYSINFO_RET_FAIL; return SYSINFO_RET_OK; }
int PROC_MEM(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { DIR *dir; int proc; struct dirent *entries; struct stat buf; struct passwd *usrinfo = NULL; struct prpsinfo psinfo; char filename[MAX_STRING_LEN]; char procname[MAX_STRING_LEN]; char usrname[MAX_STRING_LEN]; char mode[MAX_STRING_LEN]; char proccomm[MAX_STRING_LEN]; int do_task = DO_SUM; double memsize = -1; int pgsize = getpagesize(); int proccount = 0; pid_t curr_pid = getpid(); if(num_param(param) > 4) { return SYSINFO_RET_FAIL; } if(get_param(param, 1, procname, MAX_STRING_LEN) != 0) { return SYSINFO_RET_FAIL; } if(get_param(param, 2, usrname, MAX_STRING_LEN) != 0) { usrname[0] = 0; } else { if(usrname[0] != 0) { usrinfo = getpwnam(usrname); if(usrinfo == NULL) { /* incorrect user name */ return SYSINFO_RET_FAIL; } } } if(get_param(param, 3, mode, MAX_STRING_LEN) != 0) { mode[0] = '\0'; } if(mode[0] == '\0') { strscpy(mode, "sum"); } if(strcmp(mode,"avg") == 0) { do_task = DO_AVG; } else if(strcmp(mode,"max") == 0) { do_task = DO_MAX; } else if(strcmp(mode,"min") == 0) { do_task = DO_MIN; } else if(strcmp(mode,"sum") == 0) { do_task = DO_SUM; } else { return SYSINFO_RET_FAIL; } if(get_param(param, 4, proccomm, MAX_STRING_LEN) != 0) { proccomm[0] = '\0'; } dir=opendir("/proc"); if(NULL == dir) { return SYSINFO_RET_FAIL; } while((entries=readdir(dir))!=NULL) { strscpy(filename,"/proc/"); zbx_strlcat(filename,entries->d_name,MAX_STRING_LEN); if(stat(filename,&buf)==0) { proc = open(filename,O_RDONLY); if(proc == -1) goto lbl_skip_procces; if(ioctl(proc,PIOCPSINFO,&psinfo) == -1) goto lbl_skip_procces; /* Self process information. It leads to incorrect results for proc_cnt[zabbix_agentd] */ if(psinfo.pr_pid == curr_pid) goto lbl_skip_procces; if(procname[0] != 0) if(strcmp(procname,psinfo.pr_fname) != 0) goto lbl_skip_procces; if(usrinfo != NULL) if(usrinfo->pw_uid != psinfo.pr_uid) goto lbl_skip_procces; if(proccomm[0] != '\0') if(zbx_regexp_match(psinfo.pr_psargs,proccomm,NULL) == NULL) goto lbl_skip_procces; proccount++; if(memsize < 0) /* First inicialization */ { memsize = (double) (psinfo.pr_rssize * pgsize); } else { if(do_task == DO_MAX) { memsize = MAX(memsize, (double) (psinfo.pr_rssize * pgsize)); } else if(do_task == DO_MIN) { memsize = MIN(memsize, (double) (psinfo.pr_rssize * pgsize)); } else /* SUM */ { memsize += (double) (psinfo.pr_rssize * pgsize); } } lbl_skip_procces: if(proc) close(proc); } } closedir(dir); if(memsize < 0) { /* incorrect process name */ memsize = 0; } if(do_task == DO_AVG) { SET_DBL_RESULT(result, proccount == 0 ? 0 : ((double)memsize/(double)proccount)); } else { SET_UI64_RESULT(result, memsize); } return SYSINFO_RET_OK; }
int SYSTEM_SWAP_SIZE(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { /* * FreeBSD 7.0 i386 */ #ifdef XSWDEV_VERSION /* defined in <vm/vm_param.h> */ char swapdev[64], mode[64]; int mib[16], *mib_dev; size_t sz, mib_sz; struct xswdev xsw; zbx_uint64_t total = 0, used = 0; assert(result); init_result(result); if (num_param(param) > 2) return SYSINFO_RET_FAIL; if (0 != get_param(param, 1, swapdev, sizeof(swapdev))) return SYSINFO_RET_FAIL; if (0 != get_param(param, 2, mode, sizeof(mode))) *mode = '\0'; sz = sizeof(mib) / sizeof(mib[0]); if (-1 == sysctlnametomib("vm.swap_info", mib, &sz)) return FAIL; mib_sz = sz + 1; mib_dev = &(mib[sz]); *mib_dev = 0; sz = sizeof(xsw); while (-1 != sysctl(mib, mib_sz, &xsw, &sz, NULL, 0)) { if ('\0' == *swapdev || 0 == strcmp(swapdev, "all") /* default parameter */ || 0 == strcmp(swapdev, devname(xsw.xsw_dev, S_IFCHR))) { total += (zbx_uint64_t)xsw.xsw_nblks; used += (zbx_uint64_t)xsw.xsw_used; } (*mib_dev)++; } if ('\0' == *mode || 0 == strcmp(mode, "free")) /* default parameter */ SET_UI64_RESULT(result, (total - used) * getpagesize()); else if (0 == strcmp(mode, "total")) SET_UI64_RESULT(result, total * getpagesize()); else if (0 == strcmp(mode, "used")) SET_UI64_RESULT(result, used * getpagesize()); else if (0 == strcmp(mode, "pfree")) SET_DBL_RESULT(result, total ? ((double)(total - used) * 100.0 / (double)total) : 0.0); else if (0 == strcmp(mode, "pused")) SET_DBL_RESULT(result, total ? ((double)used * 100.0 / (double)total) : 0.0); else return SYSINFO_RET_FAIL; return SYSINFO_RET_OK; #else return SYSINFO_RET_FAIL; #endif }
int SYSTEM_CPU_LOAD(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { char tmp[16]; double value; int per_cpu = 1, cpu_num; #if defined(HAVE_GETLOADAVG) int mode; double load[ZBX_AVG_COUNT]; #elif defined(HAVE_KSTAT_H) char *key; int load; #endif if (2 < num_param(param)) return SYSINFO_RET_FAIL; if (0 != get_param(param, 1, tmp, sizeof(tmp)) || '\0' == *tmp || 0 == strcmp(tmp, "all")) per_cpu = 0; else if (0 != strcmp(tmp, "percpu")) return SYSINFO_RET_FAIL; #if defined(HAVE_GETLOADAVG) if (0 != get_param(param, 2, tmp, sizeof(tmp)) || '\0' == *tmp || 0 == strcmp(tmp, "avg1")) mode = ZBX_AVG1; else if (0 == strcmp(tmp, "avg5")) mode = ZBX_AVG5; else if (0 == strcmp(tmp, "avg15")) mode = ZBX_AVG15; else return SYSINFO_RET_FAIL; if (mode >= getloadavg(load, 3)) return SYSINFO_RET_FAIL; value = load[mode]; #elif defined(HAVE_KSTAT_H) if (0 != get_param(param, 2, tmp, sizeof(tmp)) || '\0' == *tmp || 0 == strcmp(tmp, "avg1")) key = "avenrun_1min"; else if (0 == strcmp(tmp, "avg5")) key = "avenrun_5min"; else if (0 == strcmp(tmp, "avg15")) key = "avenrun_15min"; else return SYSINFO_RET_FAIL; if (FAIL == get_kstat_system_misc(key, &load)) return SYSINFO_RET_FAIL; value = (double)load / FSCALE; #else return SYSINFO_RET_FAIL; #endif if (1 == per_cpu) { if (0 >= (cpu_num = sysconf(_SC_NPROCESSORS_ONLN))) return SYSINFO_RET_FAIL; value /= cpu_num; } SET_DBL_RESULT(result, value); return SYSINFO_RET_OK; }
int PROC_NUM(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { #if defined(HAVE_PROC_1_STATUS) DIR *dir; struct dirent *entries; struct stat buf; char filename[MAX_STRING_LEN]; char line[MAX_STRING_LEN]; char name1[MAX_STRING_LEN]; char name2[MAX_STRING_LEN]; char procname[MAX_STRING_LEN]; char usrname[MAX_STRING_LEN]; char procstat[MAX_STRING_LEN]; int proc_ok = 0; int usr_ok = 0; int stat_ok = 0; struct passwd *usrinfo = NULL; long int lvalue = 0; FILE *f; int proccount = 0; assert(result); init_result(result); if(num_param(param) > 3) { return SYSINFO_RET_FAIL; } if(get_param(param, 1, procname, MAX_STRING_LEN) != 0) { return SYSINFO_RET_FAIL; } if(get_param(param, 2, usrname, MAX_STRING_LEN) != 0) { usrname[0] = 0; } else { if(usrname[0] != 0) { usrinfo = getpwnam(usrname); if(usrinfo == NULL) { /* incorrect user name */ return SYSINFO_RET_FAIL; } } } if(get_param(param, 3, procstat, MAX_STRING_LEN) != 0) { procstat[0] = '\0'; } if(procstat[0] == '\0') { strscpy(procstat, "all"); } if(strcmp(procstat,"run") == 0) { strscpy(procstat,"R"); } else if(strcmp(procstat,"sleep") == 0) { strscpy(procstat,"S"); } else if(strcmp(procstat,"zomb") == 0) { strscpy(procstat,"Z"); } else if(strcmp(procstat,"all") == 0) { procstat[0] = 0; } else { return SYSINFO_RET_FAIL; } dir=opendir("/proc"); if(NULL == dir) { return SYSINFO_RET_FAIL; } while((entries=readdir(dir))!=NULL) { proc_ok = 0; stat_ok = 0; usr_ok = 0; /* Self is a symbolic link. It leads to incorrect results for proc_cnt[zabbix_agentd] */ /* Better approach: check if /proc/x/ is symbolic link */ if(strncmp(entries->d_name,"self",MAX_STRING_LEN) == 0) { continue; } strscpy(filename,"/proc/"); zbx_strlcat(filename,entries->d_name,MAX_STRING_LEN); zbx_strlcat(filename,"/status",MAX_STRING_LEN); if(stat(filename,&buf)==0) { if(NULL == (f = fopen(filename,"r") )) { continue; } if(procname[0] != 0) { fgets(line,MAX_STRING_LEN,f); if(sscanf(line,"%s\t%s\n",name1,name2)==2) { if(strcmp(name1,"Name:") == 0) { if(strcmp(procname,name2)==0) { proc_ok = 1; } } } if(proc_ok == 0) { zbx_fclose(f); continue; } } else { proc_ok = 1; } if(procstat[0] != 0) { while(fgets(line, MAX_STRING_LEN, f) != NULL) { if(sscanf(line, "%s\t%s\n", name1, name2) != 2) { continue; } if(strcmp(name1,"State:") != 0) { continue; } if(strcmp(name2, procstat)) { stat_ok = 1; break; } } } else { stat_ok = 1; } if(usrinfo != NULL) { while(fgets(line, MAX_STRING_LEN, f) != NULL) { if(sscanf(line, "%s\t%li\n", name1, &lvalue) != 2) { continue; } if(strcmp(name1,"Uid:") != 0) { continue; } if(usrinfo->pw_uid == (uid_t)(lvalue)) { usr_ok = 1; break; } } } else { usr_ok = 1; } if(proc_ok && stat_ok && usr_ok) { proccount++; } zbx_fclose(f); } } closedir(dir); SET_UI64_RESULT(result, proccount); return SYSINFO_RET_OK; #else return SYSINFO_RET_FAIL; #endif }
/****************************************************************************** * * * Function: process_trap_for_interface * * * * Purpose: add trap to all matching items for the specified interface * * * * Return value: SUCCEED - a matching item was found * * FAIL - no matching item was found (including fallback items) * * * * Author: Rudolfs Kreicbergs * * * ******************************************************************************/ static int process_trap_for_interface(zbx_uint64_t interfaceid, char *trap, zbx_timespec_t *ts) { DC_ITEM *items = NULL; char cmd[MAX_STRING_LEN], params[MAX_STRING_LEN], regex[MAX_STRING_LEN], error[ITEM_ERROR_LEN_MAX]; size_t num, i; int ret = FAIL, fb = -1, *lastclocks = NULL, *errcodes = NULL; zbx_uint64_t *itemids = NULL; unsigned char *states = NULL; AGENT_RESULT *results = NULL; zbx_vector_ptr_t regexps; zbx_vector_ptr_create(®exps); num = DCconfig_get_snmp_items_by_interfaceid(interfaceid, &items); itemids = zbx_malloc(itemids, sizeof(zbx_uint64_t) * num); states = zbx_malloc(states, sizeof(unsigned char) * num); lastclocks = zbx_malloc(lastclocks, sizeof(int) * num); errcodes = zbx_malloc(errcodes, sizeof(int) * num); results = zbx_malloc(results, sizeof(AGENT_RESULT) * num); for (i = 0; i < num; i++) { init_result(&results[i]); errcodes[i] = FAIL; items[i].key = zbx_strdup(items[i].key, items[i].key_orig); if (SUCCEED != substitute_key_macros(&items[i].key, NULL, &items[i], NULL, MACRO_TYPE_ITEM_KEY, error, sizeof(error))) { SET_MSG_RESULT(&results[i], zbx_strdup(NULL, error)); errcodes[i] = NOTSUPPORTED; continue; } if (0 == strcmp(items[i].key, "snmptrap.fallback")) { fb = i; continue; } if (ZBX_COMMAND_ERROR == parse_command(items[i].key, cmd, sizeof(cmd), params, sizeof(params))) continue; if (0 != strcmp(cmd, "snmptrap")) continue; if (1 < num_param(params)) continue; if (0 != get_param(params, 1, regex, sizeof(regex))) continue; if ('@' == *regex) DCget_expressions_by_name(®exps, regex + 1); if (SUCCEED != regexp_match_ex(®exps, trap, regex, ZBX_CASE_SENSITIVE)) continue; if (SUCCEED == set_result_type(&results[i], items[i].value_type, items[i].data_type, trap)) errcodes[i] = SUCCEED; else errcodes[i] = NOTSUPPORTED; ret = SUCCEED; } if (FAIL == ret && -1 != fb) { if (SUCCEED == set_result_type(&results[fb], items[fb].value_type, items[fb].data_type, trap)) errcodes[fb] = SUCCEED; else errcodes[fb] = NOTSUPPORTED; ret = SUCCEED; } for (i = 0; i < num; i++) { switch (errcodes[i]) { case SUCCEED: if (ITEM_VALUE_TYPE_LOG == items[i].value_type) { calc_timestamp(results[i].logs[0]->value, &results[i].logs[0]->timestamp, items[i].logtimefmt); } items[i].state = ITEM_STATE_NORMAL; dc_add_history(items[i].itemid, items[i].value_type, items[i].flags, &results[i], ts, items[i].state, NULL); itemids[i] = items[i].itemid; states[i] = items[i].state; lastclocks[i] = ts->sec; break; case NOTSUPPORTED: items[i].state = ITEM_STATE_NOTSUPPORTED; dc_add_history(items[i].itemid, items[i].value_type, items[i].flags, NULL, ts, items[i].state, results[i].msg); itemids[i] = items[i].itemid; states[i] = items[i].state; lastclocks[i] = ts->sec; break; } zbx_free(items[i].key); free_result(&results[i]); } zbx_free(results); DCrequeue_items(itemids, states, lastclocks, NULL, NULL, errcodes, num); zbx_free(errcodes); zbx_free(lastclocks); zbx_free(states); zbx_free(itemids); DCconfig_clean_items(items, NULL, num); zbx_free(items); zbx_regexp_clean_expressions(®exps); zbx_vector_ptr_destroy(®exps); dc_flush_history(); return ret; }
int SERVICES(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { int start_type, service_state, ret; char type[16], state[24], *buf = NULL, *utf8, exclude[MAX_STRING_LEN]; SC_HANDLE h_mgr; ENUM_SERVICE_STATUS_PROCESS *ssp = NULL; DWORD sz = 0, szn, i, services, resume_handle = 0; if (num_param(param) > 3) return SYSINFO_RET_FAIL; if (0 != get_param(param, 1, type, sizeof(type))) *type = '\0'; if ('\0' == *type || 0 == strcmp(type, "all")) /* default parameter */ start_type = ZBX_SRV_STARTTYPE_ALL; else if (0 == strcmp(type, "automatic")) start_type = ZBX_SRV_STARTTYPE_AUTOMATIC; else if (0 == strcmp(type, "manual")) start_type = ZBX_SRV_STARTTYPE_MANUAL; else if (0 == strcmp(type, "disabled")) start_type = ZBX_SRV_STARTTYPE_DISABLED; else return SYSINFO_RET_FAIL; if (0 != get_param(param, 2, state, sizeof(state))) *state = '\0'; if ('\0' == *state || 0 == strcmp(state, "all")) /* default parameter */ service_state = ZBX_SRV_STATE_ALL; else if (0 == strcmp(state, "stopped")) service_state = ZBX_SRV_STATE_STOPPED; else if (0 == strcmp(state, "started")) service_state = ZBX_SRV_STATE_STARTED; else if (0 == strcmp(state, "start_pending")) service_state = ZBX_SRV_STATE_START_PENDING; else if (0 == strcmp(state, "stop_pending")) service_state = ZBX_SRV_STATE_STOP_PENDING; else if (0 == strcmp(state, "running")) service_state = ZBX_SRV_STATE_RUNNING; else if (0 == strcmp(state, "continue_pending")) service_state = ZBX_SRV_STATE_CONTINUE_PENDING; else if (0 == strcmp(state, "pause_pending")) service_state = ZBX_SRV_STATE_PAUSE_PENDING; else if (0 == strcmp(state, "paused")) service_state = ZBX_SRV_STATE_PAUSED; else return SYSINFO_RET_FAIL; if (0 != get_param(param, 3, exclude, sizeof(exclude))) *exclude = '\0'; if (NULL == (h_mgr = OpenSCManager(NULL, NULL, GENERIC_READ))) return SYSINFO_RET_FAIL; while (0 != (ret = EnumServicesStatusEx(h_mgr, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, (LPBYTE)ssp, sz, &szn, &services, &resume_handle, NULL)) || ERROR_MORE_DATA == GetLastError()) { for (i = 0; i < services; i++) { SC_HANDLE h_srv; if (NULL == (h_srv = OpenService(h_mgr, ssp[i].lpServiceName, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG))) continue; if (SUCCEED == check_service_starttype(h_srv, start_type)) if (SUCCEED == check_service_state(h_srv, service_state)) { utf8 = zbx_unicode_to_utf8(ssp[i].lpServiceName); if (FAIL == str_in_list(exclude, utf8, ',')) buf = zbx_strdcatf(buf, "%s\n", utf8); zbx_free(utf8); } CloseServiceHandle(h_srv); } if (0 == szn) break; if (NULL == ssp) { sz = szn; ssp = (ENUM_SERVICE_STATUS_PROCESS *)zbx_malloc((void *)ssp, sz); } } zbx_free(ssp); CloseServiceHandle(h_mgr); if (NULL == buf) buf = strdup("0"); SET_STR_RESULT(result, buf); return SYSINFO_RET_OK; }
int check_service(const char *params, const char *default_addr, AGENT_RESULT *result, int perf) { unsigned short port = 0; char service[16], ip[64], str_port[8]; int value_int, ret = SYSINFO_RET_FAIL; double check_time; check_time = zbx_time(); if (3 < num_param(params)) return ret; if (0 != get_param(params, 1, service, sizeof(service))) return ret; if (0 != get_param(params, 2, ip, sizeof(ip)) || '\0' == *ip) strscpy(ip, default_addr); if (0 != get_param(params, 3, str_port, sizeof(str_port))) *str_port = '\0'; if ('\0' != *str_port && FAIL == is_ushort(str_port, &port)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Invalid \"port\" parameter")); return ret; } if (0 == strcmp(service, "ssh")) { if ('\0' == *str_port) port = ZBX_DEFAULT_SSH_PORT; ret = check_ssh(ip, port, CONFIG_TIMEOUT, &value_int); } else if (0 == strcmp(service, "ntp") || 0 == strcmp(service, "service.ntp" /* deprecated */)) { if ('\0' == *str_port) port = ZBX_DEFAULT_NTP_PORT; ret = check_ntp(ip, port, CONFIG_TIMEOUT, &value_int); } #ifdef HAVE_LDAP else if (0 == strcmp(service, "ldap")) { if ('\0' == *str_port) port = ZBX_DEFAULT_LDAP_PORT; ret = check_ldap(ip, port, CONFIG_TIMEOUT, &value_int); } #endif else if (0 == strcmp(service, "smtp")) { if ('\0' == *str_port) port = ZBX_DEFAULT_SMTP_PORT; ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, "220", "QUIT\r\n", &value_int); } else if (0 == strcmp(service, "ftp")) { if ('\0' == *str_port) port = ZBX_DEFAULT_FTP_PORT; ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, "220", "QUIT\n", &value_int); } else if (0 == strcmp(service, "http")) { if ('\0' == *str_port) port = ZBX_DEFAULT_HTTP_PORT; ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, NULL, NULL, &value_int); } else if (0 == strcmp(service, "pop")) { if ('\0' == *str_port) port = ZBX_DEFAULT_POP_PORT; ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, "+OK", "QUIT\n", &value_int); } else if (0 == strcmp(service, "nntp")) { if ('\0' == *str_port) port = ZBX_DEFAULT_NNTP_PORT; ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, "200", "QUIT\n", &value_int); } else if (0 == strcmp(service, "imap")) { if ('\0' == *str_port) port = ZBX_DEFAULT_IMAP_PORT; ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, "* OK", "a1 LOGOUT\n", &value_int); } else if (0 == strcmp(service, "tcp")) { if ('\0' == *str_port) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Required \"port\" parameter missing")); return ret; } ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, NULL, NULL, &value_int); } #ifdef HAVE_LIBCURL else if (0 == strcmp(service, "https")) { if ('\0' == *str_port) port = ZBX_DEFAULT_HTTPS_PORT; ret = check_https(ip, port, CONFIG_TIMEOUT, &value_int); } #endif else if (0 == strcmp(service, "telnet")) { if ('\0' == *str_port) port = ZBX_DEFAULT_TELNET_PORT; ret = check_telnet(ip, port, CONFIG_TIMEOUT, &value_int); } else return ret; if (SYSINFO_RET_OK == ret) { if (0 != perf) { if (0 != value_int) { check_time = zbx_time() - check_time; check_time = MAX(check_time, 0.0001); SET_DBL_RESULT(result, check_time); } else SET_DBL_RESULT(result, 0.0); } else SET_UI64_RESULT(result, value_int); } return ret; }
static int dns_query(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result, int short_answer) { #if defined(HAVE_RES_QUERY) || defined(_WINDOWS) size_t offset = 0; int res, type, retrans, retry, i, ret = SYSINFO_RET_FAIL; char ip[MAX_STRING_LEN], zone[MAX_STRING_LEN], tmp[MAX_STRING_LEN], buffer[MAX_STRING_LEN]; struct in_addr inaddr; #ifndef _WINDOWS int saved_nscount, saved_retrans, saved_retry; struct sockaddr_in saved_ns; #endif typedef struct { char *name; int type; } resolv_querytype_t; static const resolv_querytype_t qt[] = { {"ANY", T_ANY}, {"A", T_A}, {"NS", T_NS}, {"MD", T_MD}, {"MF", T_MF}, {"CNAME", T_CNAME}, {"SOA", T_SOA}, {"MB", T_MB}, {"MG", T_MG}, {"MR", T_MR}, {"NULL", T_NULL}, #ifndef _WINDOWS {"WKS", T_WKS}, #endif {"PTR", T_PTR}, {"HINFO", T_HINFO}, {"MINFO", T_MINFO}, {"MX", T_MX}, {"TXT", T_TXT}, {"SRV", T_SRV}, {NULL} }; #ifdef _WINDOWS PDNS_RECORD pQueryResults, pDnsRecord; LPTSTR wzone; char tmp2[MAX_STRING_LEN]; #else char *name; unsigned char *msg_end, *msg_ptr, *p; int num_answers, num_query, q_type, q_class, q_len, value, c, n; struct servent *s; HEADER *hp; struct protoent *pr; #if PACKETSZ > 1024 unsigned char buf[PACKETSZ]; #else unsigned char buf[1024]; #endif typedef union { HEADER h; #if defined(NS_PACKETSZ) unsigned char buffer[NS_PACKETSZ]; #elif defined(PACKETSZ) unsigned char buffer[PACKETSZ]; #else unsigned char buffer[512]; #endif } answer_t; answer_t answer; #endif /* _WINDOWS */ *buffer = '\0'; if (5 < num_param(param)) return SYSINFO_RET_FAIL; if (0 != get_param(param, 1, ip, sizeof(ip))) *ip = '\0'; if (0 != get_param(param, 2, zone, sizeof(zone)) || '\0' == *zone) strscpy(zone, "zabbix.com"); if (0 != get_param(param, 3, tmp, sizeof(tmp)) || '\0' == *tmp) type = T_SOA; else { for (i = 0; NULL != qt[i].name; i++) { #ifdef _WINDOWS if (0 == lstrcmpiA(qt[i].name, tmp)) #else if (0 == strcasecmp(qt[i].name, tmp)) #endif { type = qt[i].type; break; } } if (NULL == qt[i].name) return SYSINFO_RET_FAIL; } if (0 != get_param(param, 4, tmp, sizeof(tmp)) || '\0' == *tmp) retrans = 1; else retrans = atoi(tmp); if (0 != get_param(param, 5, tmp, sizeof(tmp)) || '\0' == *tmp) retry = 2; else retry = atoi(tmp); #ifdef _WINDOWS wzone = zbx_utf8_to_unicode(zone); res = DnsQuery(wzone, type, DNS_QUERY_STANDARD, NULL, &pQueryResults, NULL); zbx_free(wzone); if (1 == short_answer) { SET_UI64_RESULT(result, DNS_RCODE_NOERROR != res ? 0 : 1); ret = SYSINFO_RET_OK; goto clean; } if (DNS_RCODE_NOERROR != res) return SYSINFO_RET_FAIL; pDnsRecord = pQueryResults; while (NULL != pDnsRecord) { if (DnsSectionAnswer != pDnsRecord->Flags.S.Section) { pDnsRecord = pDnsRecord->pNext; continue; } if (NULL == pDnsRecord->pName) goto clean; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%-20s", zbx_unicode_to_utf8_static(pDnsRecord->pName, tmp, sizeof(tmp))); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %-8s", decode_type(pDnsRecord->wType)); switch (pDnsRecord->wType) { case T_A: inaddr.s_addr = pDnsRecord->Data.A.IpAddress; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntoa(inaddr)); break; case T_NS: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.NS.pNameHost, tmp, sizeof(tmp))); break; case T_MD: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MD.pNameHost, tmp, sizeof(tmp))); break; case T_MF: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MF.pNameHost, tmp, sizeof(tmp))); break; case T_CNAME: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.CNAME.pNameHost, tmp, sizeof(tmp))); break; case T_SOA: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s %s %lu %lu %lu %lu %lu", zbx_unicode_to_utf8_static(pDnsRecord->Data.SOA.pNamePrimaryServer, tmp, sizeof(tmp)), zbx_unicode_to_utf8_static(pDnsRecord->Data.SOA.pNameAdministrator, tmp2, sizeof(tmp2)), pDnsRecord->Data.SOA.dwSerialNo, pDnsRecord->Data.SOA.dwRefresh, pDnsRecord->Data.SOA.dwRetry, pDnsRecord->Data.SOA.dwExpire, pDnsRecord->Data.SOA.dwDefaultTtl); break; case T_MB: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MB.pNameHost, tmp, sizeof(tmp))); break; case T_MG: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MG.pNameHost, tmp, sizeof(tmp))); break; case T_MR: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MR.pNameHost, tmp, sizeof(tmp))); break; case T_NULL: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " len:%lu", pDnsRecord->Data.Null.dwByteCount); break; case T_PTR: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.PTR.pNameHost, tmp, sizeof(tmp))); break; case T_HINFO: for (i = 0; i < (int)(pDnsRecord->Data.HINFO.dwStringCount); i++) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%s\"", zbx_unicode_to_utf8_static(pDnsRecord->Data.HINFO.pStringArray[i], tmp, sizeof(tmp))); break; case T_MINFO: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MINFO.pNameMailbox, tmp, sizeof(tmp)), zbx_unicode_to_utf8_static(pDnsRecord->Data.MINFO.pNameErrorsMailbox, tmp2, sizeof(tmp2))); break; case T_MX: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %hu %s", pDnsRecord->Data.MX.wPreference, zbx_unicode_to_utf8_static(pDnsRecord->Data.MX.pNameExchange, tmp, sizeof(tmp))); break; case T_TXT: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \""); for (i = 0; i < (int)(pDnsRecord->Data.TXT.dwStringCount); i++) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%s ", zbx_unicode_to_utf8_static(pDnsRecord->Data.TXT.pStringArray[i], tmp, sizeof(tmp))); if (0 < i) offset -= 1; /* remove the trailing space */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\""); break; case T_SRV: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %hu %hu %hu %s", pDnsRecord->Data.SRV.wPriority, pDnsRecord->Data.SRV.wWeight, pDnsRecord->Data.SRV.wPort, zbx_unicode_to_utf8_static(pDnsRecord->Data.SRV.pNameTarget, tmp, sizeof(tmp))); break; default: break; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\n"); pDnsRecord = pDnsRecord->pNext; } #else /* not _WINDOWS */ if (-1 == res_init()) /* initialize always, settings might have changed */ return SYSINFO_RET_FAIL; if (-1 == (res = res_mkquery(QUERY, zone, C_IN, type, NULL, 0, NULL, buf, sizeof(buf)))) return SYSINFO_RET_FAIL; if ('\0' != *ip) { if (0 == inet_aton(ip, &inaddr)) return SYSINFO_RET_FAIL; memcpy(&saved_ns, &(_res.nsaddr_list[0]), sizeof(struct sockaddr_in)); saved_nscount = _res.nscount; _res.nsaddr_list[0].sin_addr = inaddr; _res.nsaddr_list[0].sin_family = AF_INET; _res.nsaddr_list[0].sin_port = htons(ZBX_DEFAULT_DNS_PORT); _res.nscount = 1; } saved_retrans = _res.retrans; saved_retry = _res.retry; _res.retrans = retrans; _res.retry = retry; res = res_send(buf, res, answer.buffer, sizeof(answer.buffer)); _res.retrans = saved_retrans; _res.retry = saved_retry; if ('\0' != *ip) { memcpy(&(_res.nsaddr_list[0]), &saved_ns, sizeof(struct sockaddr_in)); _res.nscount = saved_nscount; } hp = (HEADER *)answer.buffer; if (1 == short_answer) { SET_UI64_RESULT(result, NOERROR != hp->rcode || 0 == ntohs(hp->ancount) || -1 == res ? 0 : 1); return SYSINFO_RET_OK; } if (NOERROR != hp->rcode || 0 == ntohs(hp->ancount) || -1 == res) return SYSINFO_RET_FAIL; msg_end = answer.buffer + res; num_answers = ntohs(answer.h.ancount); num_query = ntohs(answer.h.qdcount); msg_ptr = answer.buffer + HFIXEDSZ; /* skipping query records */ for (; 0 < num_query && msg_ptr < msg_end; num_query--) msg_ptr += dn_skipname(msg_ptr, msg_end) + QFIXEDSZ; for (; 0 < num_answers && msg_ptr < msg_end; num_answers--) { if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%-20s", name); GETSHORT(q_type, msg_ptr); GETSHORT(q_class, msg_ptr); msg_ptr += INT32SZ; /* skipping TTL */ GETSHORT(q_len, msg_ptr); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %-8s", decode_type(q_type)); switch (q_type) { case T_A: switch (q_class) { case C_IN: case C_HS: memcpy(&inaddr, msg_ptr, INADDRSZ); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntoa(inaddr)); break; default: ; } msg_ptr += q_len; break; case T_NS: case T_CNAME: case T_MB: case T_MD: case T_MF: case T_MG: case T_MR: case T_PTR: if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; case T_MX: GETSHORT(value, msg_ptr); /* preference */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* exchange */ return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; case T_SOA: if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* source host */ return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* administrator */ return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); GETLONG(value, msg_ptr); /* serial number */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* refresh time */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* retry time */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* expire time */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* minimum TTL */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); break; case T_NULL: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " len:%d", q_len); msg_ptr += q_len; break; case T_WKS: if (INT32SZ + 1 > q_len) return SYSINFO_RET_FAIL; p = msg_ptr + q_len; memcpy(&inaddr, msg_ptr, INADDRSZ); msg_ptr += INT32SZ; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntoa(inaddr)); if (NULL != (pr = getprotobynumber(*msg_ptr))) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", pr->p_name); else offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", (int)*msg_ptr); msg_ptr++; n = 0; while (msg_ptr < p) { c = *msg_ptr++; do { if (0 != (c & 0200)) { s = getservbyport((int)htons(n), pr ? pr->p_name : NULL); if (NULL != s) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", s->s_name); else offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " #%d", n); } c <<= 1; } while (0 != (++n & 07)); } break; case T_HINFO: p = msg_ptr + q_len; c = *msg_ptr++; if (0 != c) { offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%.*s\"", c, msg_ptr); msg_ptr += c; } if (msg_ptr < p) { c = *msg_ptr++; if (0 != c) { offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%.*s\"", c, msg_ptr); msg_ptr += c; } } break; case T_MINFO: if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* mailbox responsible for mailing lists */ return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* mailbox for error messages */ return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; case T_TXT: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \""); p = msg_ptr + q_len; while (msg_ptr < p) { for (c = *msg_ptr++; 0 < c && msg_ptr < p; c--) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%c", *msg_ptr++); } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\""); break; case T_SRV: GETSHORT(value, msg_ptr); /* priority */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETSHORT(value, msg_ptr); /* weight */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETSHORT(value, msg_ptr); /* port */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* target */ return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; default: msg_ptr += q_len; break; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\n"); } #endif /* _WINDOWS */ if (0 != offset) buffer[--offset] = '\0'; SET_TEXT_RESULT(result, zbx_strdup(NULL, buffer)); ret = SYSINFO_RET_OK; #ifdef _WINDOWS clean: if (DNS_RCODE_NOERROR == res) DnsRecordListFree(pQueryResults, DnsFreeRecordList); #endif return ret; #else /* both HAVE_RES_QUERY and _WINDOWS not defined */ return SYSINFO_RET_FAIL; #endif /* defined(HAVE_RES_QUERY) || defined(_WINDOWS) */ }
int PROC_INFO(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { DWORD *procList, dwSize; HANDLE hProcess; char proc_name[MAX_PATH], attr[MAX_PATH], type[MAX_PATH], baseName[MAX_PATH]; const char *attrList[] = {"vmsize", "wkset", "pf", "ktime", "utime", "gdiobj", "userobj", "io_read_b", "io_read_op", "io_write_b", "io_write_op", "io_other_b", "io_other_op", NULL}, *typeList[] = {"min", "max", "avg", "sum", NULL}; double value; int i, proc_cnt, counter, attr_id, type_id, ret = SYSINFO_RET_OK; if (num_param(param) > 3) return SYSINFO_RET_FAIL; if (0 != get_param(param, 1, proc_name, sizeof(proc_name))) *proc_name = '\0'; if ('\0' == *proc_name) return SYSINFO_RET_FAIL; if (0 != get_param(param, 2, attr, sizeof(attr))) *attr = '\0'; if ('\0' == *attr) /* default parameter */ zbx_snprintf(attr, sizeof(attr), "%s", attrList[0]); if (0 != get_param(param, 3, type, sizeof(type))) *type = '\0'; if ('\0' == *type) /* default parameter */ zbx_snprintf(type, sizeof(type), "%s", typeList[2]); /* Get attribute code from string */ for (attr_id = 0; NULL != attrList[attr_id] && 0 != strcmp(attrList[attr_id], attr); attr_id++) ; if (NULL == attrList[attr_id]) /* Unsupported attribute */ return SYSINFO_RET_FAIL; /* Get type code from string */ for (type_id = 0; NULL != typeList[type_id] && 0 != strcmp(typeList[type_id], type); type_id++) ; if (NULL == typeList[type_id]) return SYSINFO_RET_FAIL; /* Unsupported type */ procList = (DWORD *)malloc(MAX_PROCESSES * sizeof(DWORD)); EnumProcesses(procList, sizeof(DWORD) * MAX_PROCESSES, &dwSize); proc_cnt = dwSize / sizeof(DWORD); counter = 0; value = 0; for (i = 0; i < proc_cnt; i++) { if (NULL != (hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE, procList[i]))) { if (SUCCEED == zbx_get_processname(hProcess, baseName)) if (0 == stricmp(baseName, proc_name)) if (SYSINFO_RET_OK != (ret = GetProcessAttribute(hProcess, attr_id, type_id, counter++, &value))) break; CloseHandle(hProcess); } } free(procList); if (SYSINFO_RET_OK == ret) SET_DBL_RESULT(result, value); return ret; }
/* check_service[ssh,127.0.0.1,ssh] */ int CHECK_SERVICE(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { unsigned short port=0; char service[MAX_STRING_LEN]; char ip[MAX_STRING_LEN]; char str_port[MAX_STRING_LEN]; int ret; int value_int = 0; assert(result); init_result(result); if(num_param(param) > 3) { return SYSINFO_RET_FAIL; } if(get_param(param, 1, service, MAX_STRING_LEN) != 0) { return SYSINFO_RET_FAIL; } if(get_param(param, 2, ip, MAX_STRING_LEN) != 0) { ip[0] = '\0'; } if(ip[0] == '\0') { strscpy(ip, "127.0.0.1"); } if(get_param(param, 3, str_port, MAX_STRING_LEN) != 0) { str_port[0] = '\0'; } if(str_port[0] != '\0') { port = atoi(str_port); } else { port = 0; } /* printf("IP:[%s]",ip); printf("Service:[%s]",service); printf("Port:[%d]",port);*/ if(strcmp(service,"ssh") == 0) { if(port == 0) port=22; ret=check_ssh(ip,port,&value_int); } else if(strcmp(service,"service.ntp") == 0) { if(port == 0) port=123; ret=check_ntp(ip,port,&value_int); } #ifdef HAVE_LDAP else if(strcmp(service,"ldap") == 0) { if(port == 0) port=389; ret=check_ldap(ip,port,&value_int); } #endif else if(strcmp(service,"smtp") == 0) { if(port == 0) port=25; ret=tcp_expect(ip,port,NULL,"220","QUIT\n",&value_int); } else if(strcmp(service,"ftp") == 0) { if(port == 0) port=21; ret=tcp_expect(ip,port,NULL,"220","",&value_int); } else if(strcmp(service,"http") == 0) { if(port == 0) port=80; ret=tcp_expect(ip,port,NULL,NULL,"",&value_int); } else if(strcmp(service,"pop") == 0) { if(port == 0) port=110; ret=tcp_expect(ip,port,NULL,"+OK","",&value_int); } else if(strcmp(service,"nntp") == 0) { if(port == 0) port=119; /* 220 is incorrect */ /* ret=tcp_expect(ip,port,"220","");*/ ret=tcp_expect(ip,port,NULL,"200","",&value_int); } else if(strcmp(service,"imap") == 0) { if(port == 0) port=143; ret=tcp_expect(ip,port,NULL,"* OK","a1 LOGOUT\n",&value_int); } else if(strcmp(service,"tcp") == 0) { if(port == 0) port=80; ret=tcp_expect(ip,port,NULL,NULL,"",&value_int); } else { return SYSINFO_RET_FAIL; } if(SYSINFO_RET_OK == ret) { SET_UI64_RESULT(result, value_int); } return ret; }
int PROC_NUM(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { HANDLE hProcess; DWORD procList[MAX_PROCESSES], dwSize; int i, proccount, max_proc_cnt, proc_ok = 0, user_ok = 0; char procName[MAX_PATH], userName[MAX_PATH], baseName[MAX_PATH], uname[MAX_NAME]; if (num_param(param) > 2) return SYSINFO_RET_FAIL; if (0 != get_param(param, 1, procName, sizeof(procName))) return SYSINFO_RET_FAIL; if (0 != get_param(param, 2, userName, sizeof(userName))) *userName = '******'; if (0 == EnumProcesses(procList, sizeof(DWORD) * MAX_PROCESSES, &dwSize)) return SYSINFO_RET_FAIL; max_proc_cnt = dwSize / sizeof(DWORD); proccount = 0; for (i = 0; i < max_proc_cnt; i++) { proc_ok = 0; user_ok = 0; if (NULL != (hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, procList[i]))) { if ('\0' != *procName) { if (SUCCEED == zbx_get_processname(hProcess, baseName)) if (0 == stricmp(baseName, procName)) proc_ok = 1; } else proc_ok = 1; if (0 != proc_ok && '\0' != *userName) { if (SUCCEED == zbx_get_process_username(hProcess, uname)) if (0 == stricmp(uname, userName)) user_ok = 1; } else user_ok = 1; if (0 != user_ok && 0 != proc_ok) proccount++; CloseHandle(hProcess); } } SET_UI64_RESULT(result, proccount); return SYSINFO_RET_OK; }
int SYSTEM_HW_MACADDR(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { size_t offset; int ret = SYSINFO_RET_FAIL, s, i, show_names; char *p, regex[MAX_STRING_LEN], address[MAX_STRING_LEN], buffer[MAX_STRING_LEN]; struct ifreq *ifr; struct ifconf ifc; zbx_vector_str_t addresses; if (2 < num_param(param)) return ret; if (0 != get_param(param, 1, regex, sizeof(regex)) || 0 == strcmp(regex, "all")) *regex = '\0'; if (0 != get_param(param, 2, buffer, sizeof(buffer)) || '\0' == *buffer || 0 == strcmp(buffer, "full")) show_names = 1; /* show interface names */ else if (0 == strcmp(buffer, "short")) show_names = 0; else return ret; if (-1 == (s = socket(AF_INET, SOCK_DGRAM, 0))) return ret; /* get the interface list */ ifc.ifc_len = sizeof(buffer); ifc.ifc_buf = buffer; if (-1 == ioctl(s, SIOCGIFCONF, &ifc)) goto close; ifr = ifc.ifc_req; ret = SYSINFO_RET_OK; zbx_vector_str_create(&addresses); zbx_vector_str_reserve(&addresses, 8); /* go through the list */ for (i = ifc.ifc_len / sizeof(struct ifreq); 0 < i--; ifr++) { if ('\0' != *regex && NULL == zbx_regexp_match(ifr->ifr_name, regex, NULL)) continue; if (-1 != ioctl(s, SIOCGIFFLAGS, ifr) && /* get the interface */ 0 == (ifr->ifr_flags & IFF_LOOPBACK) && /* skip loopback interface */ -1 != ioctl(s, SIOCGIFHWADDR, ifr)) /* get the MAC address */ { offset = 0; if (1 == show_names) offset += zbx_snprintf(address + offset, sizeof(address) - offset, "[%s ", ifr->ifr_name); zbx_snprintf(address + offset, sizeof(address) - offset, "%.2hx:%.2hx:%.2hx:%.2hx:%.2hx:%.2hx", (unsigned short int)(unsigned char)ifr->ifr_hwaddr.sa_data[0], (unsigned short int)(unsigned char)ifr->ifr_hwaddr.sa_data[1], (unsigned short int)(unsigned char)ifr->ifr_hwaddr.sa_data[2], (unsigned short int)(unsigned char)ifr->ifr_hwaddr.sa_data[3], (unsigned short int)(unsigned char)ifr->ifr_hwaddr.sa_data[4], (unsigned short int)(unsigned char)ifr->ifr_hwaddr.sa_data[5]); if (0 == show_names && FAIL != zbx_vector_str_search(&addresses, address, ZBX_DEFAULT_STR_COMPARE_FUNC)) continue; zbx_vector_str_append(&addresses, zbx_strdup(NULL, address)); } } offset = 0; if (0 != addresses.values_num) { zbx_vector_str_sort(&addresses, ZBX_DEFAULT_STR_COMPARE_FUNC); for (i = 0; i < addresses.values_num; i++) { if (1 == show_names && NULL != (p = strchr(addresses.values[i], ' '))) *p = ']'; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%s, ", addresses.values[i]); zbx_free(addresses.values[i]); } offset -= 2; } buffer[offset] = '\0'; if (SYSINFO_RET_OK == ret) SET_STR_RESULT(result, zbx_strdup(NULL, buffer)); zbx_vector_str_destroy(&addresses); close: close(s); return ret; }
int SYSTEM_SW_PACKAGES(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { size_t offset = 0; int ret = SYSINFO_RET_FAIL, show_pm, i, j; char buffer[MAX_BUFFER_LEN], regex[MAX_STRING_LEN], manager[MAX_STRING_LEN], tmp[MAX_STRING_LEN], *buf = NULL, *package; zbx_vector_str_t packages; ZBX_PACKAGE_MANAGER *mng; if (3 < num_param(param)) return ret; if (0 != get_param(param, 1, regex, sizeof(regex)) || 0 == strcmp(regex, "all")) *regex = '\0'; if (0 != get_param(param, 2, manager, sizeof(manager)) || 0 == strcmp(manager, "all")) *manager = '\0'; if (0 != get_param(param, 3, tmp, sizeof(tmp)) || '\0' == *tmp || 0 == strcmp(tmp, "full")) show_pm = 1; /* show package managers' names */ else if (0 == strcmp(tmp, "short")) show_pm = 0; else return ret; *buffer = '\0'; zbx_vector_str_create(&packages); for (i = 0; NULL != package_managers[i].name; i++) { mng = &package_managers[i]; if ('\0' != *manager && 0 != strcmp(manager, mng->name)) continue; if (SUCCEED == zbx_execute(mng->test_cmd, &buf, tmp, sizeof(tmp), CONFIG_TIMEOUT) && '\0' != *buf) /* consider PMS present, if test_cmd outputs anything to stdout */ { if (SUCCEED != zbx_execute(mng->list_cmd, &buf, tmp, sizeof(tmp), CONFIG_TIMEOUT)) continue; ret = SYSINFO_RET_OK; package = strtok(buf, "\n"); while (NULL != package) { if (NULL != mng->parser) /* check if the package name needs to be parsed */ { if (SUCCEED == mng->parser(package, tmp, sizeof(tmp))) package = tmp; else goto next; } if ('\0' != *regex && NULL == zbx_regexp_match(package, regex, NULL)) goto next; zbx_vector_str_append(&packages, zbx_strdup(NULL, package)); next: package = strtok(NULL, "\n"); } if (1 == show_pm) { offset += print_packages(buffer + offset, sizeof(buffer) - offset, &packages, mng->name); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\n"); /* deallocate memory used for string vector elements */ for (j = 0; j < packages.values_num; j++) zbx_free(packages.values[j]); packages.values_num = 0; } } } zbx_free(buf); if (0 == show_pm) { offset += print_packages(buffer + offset, sizeof(buffer) - offset, &packages, NULL); /* deallocate memory used for string vector elements */ for (j = 0; j < packages.values_num; j++) zbx_free(packages.values[j]); packages.values_num = 0; } else if (0 != offset) buffer[--offset] = '\0'; zbx_vector_str_destroy(&packages); if (SYSINFO_RET_OK == ret) SET_TEXT_RESULT(result, zbx_strdup(NULL, buffer)); return ret; }
int SYSTEM_CPU_UTIL(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { char cpuname[MAX_STRING_LEN]; char type[MAX_STRING_LEN]; char mode[MAX_STRING_LEN]; int cpu_num = 0; assert(result); init_result(result); if(num_param(param) > 3) { return SYSINFO_RET_FAIL; } if(get_param(param, 1, cpuname, sizeof(cpuname)) != 0) { cpuname[0] = '\0'; } if(cpuname[0] == '\0') { /* default parameter */ zbx_snprintf(cpuname, sizeof(cpuname), "all"); } if(get_param(param, 2, type, sizeof(type)) != 0) { type[0] = '\0'; } if(type[0] == '\0') { /* default parameter */ zbx_snprintf(type, sizeof(type), "user"); } if(get_param(param, 3, mode, sizeof(mode)) != 0) { mode[0] = '\0'; } if(mode[0] == '\0') { /* default parameter */ zbx_snprintf(mode, sizeof(mode), "avg1"); } if ( !CPU_COLLECTOR_STARTED(collector) ) { SET_MSG_RESULT(result, strdup("Collector is not started!")); return SYSINFO_RET_OK; } if(strcmp(cpuname,"all") == 0) { cpu_num = 0; } else { cpu_num = atoi(cpuname)+1; if ((cpu_num < 1) || (cpu_num > collector->cpus.count)) return SYSINFO_RET_FAIL; } if( 0 == strcmp(type,"idle")) { if( 0 == strcmp(mode,"avg1")) SET_DBL_RESULT(result, collector->cpus.cpu[cpu_num].idle1) else if( 0 == strcmp(mode,"avg5")) SET_DBL_RESULT(result, collector->cpus.cpu[cpu_num].idle5) else if( 0 == strcmp(mode,"avg15")) SET_DBL_RESULT(result, collector->cpus.cpu[cpu_num].idle15) else return SYSINFO_RET_FAIL; } else if( 0 == strcmp(type,"nice"))
static int parse_key_params(const char *key, const char *host_addr, icmpping_t *icmpping, char **addr, int *count, int *interval, int *size, int *timeout, icmppingsec_type_t *type, char *error, int max_error_len) { char cmd[16], params[MAX_STRING_LEN], buffer[MAX_STRING_LEN]; int num_params; if (0 == parse_command(key, cmd, sizeof(cmd), params, sizeof(params))) return NOTSUPPORTED; if (0 == strcmp(cmd, SERVER_ICMPPING_KEY)) { *icmpping = ICMPPING; } else if (0 == strcmp(cmd, SERVER_ICMPPINGLOSS_KEY)) { *icmpping = ICMPPINGLOSS; } else if (0 == strcmp(cmd, SERVER_ICMPPINGSEC_KEY)) { *icmpping = ICMPPINGSEC; } else { zbx_snprintf(error, max_error_len, "unsupported pinger key"); return NOTSUPPORTED; } num_params = num_param(params); if (6 < num_params || (ICMPPINGSEC != *icmpping && 5 < num_params)) { zbx_snprintf(error, max_error_len, "too many arguments"); return NOTSUPPORTED; } if (0 != get_param(params, 2, buffer, sizeof(buffer)) || '\0' == *buffer) { *count = 3; } else if (FAIL == is_uint(buffer) || MIN_COUNT > (*count = atoi(buffer)) || *count > MAX_COUNT) { zbx_snprintf(error, max_error_len, "number of packets [%s] is not between %d and %d", buffer, MIN_COUNT, MAX_COUNT); return NOTSUPPORTED; } if (0 != get_param(params, 3, buffer, sizeof(buffer)) || '\0' == *buffer) { *interval = 0; } else if (FAIL == is_uint(buffer) || MIN_INTERVAL > (*interval = atoi(buffer))) { zbx_snprintf(error, max_error_len, "interval [%s] should be at least %d", buffer, MIN_INTERVAL); return NOTSUPPORTED; } if (0 != get_param(params, 4, buffer, sizeof(buffer)) || '\0' == *buffer) { *size = 0; } else if (FAIL == is_uint(buffer) || MIN_SIZE > (*size = atoi(buffer)) || *size > MAX_SIZE) { zbx_snprintf(error, max_error_len, "packet size [%s] is not between %d and %d", buffer, MIN_SIZE, MAX_SIZE); return NOTSUPPORTED; } if (0 != get_param(params, 5, buffer, sizeof(buffer)) || '\0' == *buffer) *timeout = 0; else if (FAIL == is_uint(buffer) || MIN_TIMEOUT > (*timeout = atoi(buffer))) { zbx_snprintf(error, max_error_len, "timeout [%s] should be at least %d", buffer, MIN_TIMEOUT); return NOTSUPPORTED; } if (0 != get_param(params, 6, buffer, sizeof(buffer)) || '\0' == *buffer) *type = ICMPPINGSEC_AVG; else { if (0 == strcmp(buffer, "min")) { *type = ICMPPINGSEC_MIN; } else if (0 == strcmp(buffer, "avg")) { *type = ICMPPINGSEC_AVG; } else if (0 == strcmp(buffer, "max")) { *type = ICMPPINGSEC_MAX; } else { zbx_snprintf(error, max_error_len, "mode [%s] is not supported", buffer); return NOTSUPPORTED; } } if (0 != get_param(params, 1, buffer, sizeof(buffer)) || '\0' == *buffer) *addr = strdup(host_addr); else *addr = strdup(buffer); return SUCCEED; }