int PROC_NUM(AGENT_REQUEST *request, AGENT_RESULT *result) { char tmp[MAX_STRING_LEN], *procname, *proccomm, *param; DIR *dir; struct dirent *entries; zbx_stat_t buf; struct passwd *usrinfo; psinfo_t psinfo; /* In the correct procfs.h, the structure name is psinfo_t */ int fd = -1; int zbx_proc_stat; zbx_uint64_t proccount = 0; if (4 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } procname = get_rparam(request, 0); param = get_rparam(request, 1); if (NULL != param && '\0' != *param) { errno = 0; if (NULL == (usrinfo = getpwnam(param))) { if (0 == errno) SET_MSG_RESULT(result, zbx_strdup(NULL, "Specified user does not exist.")); else SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain user information: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } } else usrinfo = NULL; param = get_rparam(request, 2); if (NULL == param || '\0' == *param || 0 == strcmp(param, "all")) zbx_proc_stat = ZBX_PROC_STAT_ALL; else if (0 == strcmp(param, "run")) zbx_proc_stat = ZBX_PROC_STAT_RUN; else if (0 == strcmp(param, "sleep")) zbx_proc_stat = ZBX_PROC_STAT_SLEEP; else if (0 == strcmp(param, "zomb")) zbx_proc_stat = ZBX_PROC_STAT_ZOMB; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); return SYSINFO_RET_FAIL; } proccomm = get_rparam(request, 3); if (NULL == (dir = opendir("/proc"))) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot open /proc: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } while (NULL != (entries = readdir(dir))) { if (-1 != fd) { close(fd); fd = -1; } zbx_snprintf(tmp, sizeof(tmp), "/proc/%s/psinfo", entries->d_name); if (0 != zbx_stat(tmp, &buf)) continue; if (-1 == (fd = open(tmp, O_RDONLY))) continue; if (-1 == read(fd, &psinfo, sizeof(psinfo))) continue; if (NULL != procname && '\0' != *procname && 0 != strcmp(procname, psinfo.pr_fname)) continue; if (NULL != usrinfo && usrinfo->pw_uid != psinfo.pr_uid) continue; if (FAIL == check_procstate(&psinfo, zbx_proc_stat)) continue; if (NULL != proccomm && '\0' != *proccomm && NULL == zbx_regexp_match(psinfo.pr_psargs, proccomm, NULL)) continue; proccount++; } closedir(dir); if (-1 != fd) close(fd); SET_UI64_RESULT(result, proccount); return SYSINFO_RET_OK; }
int PROC_NUM(AGENT_REQUEST *request, AGENT_RESULT *result) { char *param, *procname, *proccomm; struct passwd *usrinfo; struct procentry64 procentry; pid_t pid = 0; int proccount = 0, invalid_user = 0, zbx_proc_stat; if (4 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } procname = get_rparam(request, 0); param = get_rparam(request, 1); if (NULL != param && '\0' != *param) { if (NULL == (usrinfo = getpwnam(param))) invalid_user = 1; } else usrinfo = NULL; param = get_rparam(request, 2); if (NULL == param || '\0' == *param || 0 == strcmp(param, "all")) zbx_proc_stat = ZBX_PROC_STAT_ALL; else if (0 == strcmp(param, "run")) zbx_proc_stat = ZBX_PROC_STAT_RUN; else if (0 == strcmp(param, "sleep")) zbx_proc_stat = ZBX_PROC_STAT_SLEEP; else if (0 == strcmp(param, "zomb")) zbx_proc_stat = ZBX_PROC_STAT_ZOMB; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); return SYSINFO_RET_FAIL; } proccomm = get_rparam(request, 3); if (1 == invalid_user) /* handle 0 for non-existent user after all parameters have been parsed and validated */ goto out; while (0 < getprocs64(&procentry, (int)sizeof(struct procentry64), NULL, 0, &pid, 1)) { if (NULL != procname && '\0' != *procname && 0 != strcmp(procname, procentry.pi_comm)) continue; if (NULL != usrinfo && usrinfo->pw_uid != procentry.pi_uid) continue; if (SUCCEED != check_procstate(&procentry, zbx_proc_stat)) continue; if (NULL != proccomm && '\0' != *proccomm && SUCCEED != check_procargs(&procentry, proccomm)) continue; proccount++; } out: SET_UI64_RESULT(result, proccount); return SYSINFO_RET_OK; }
int PROC_NUM(AGENT_REQUEST *request, AGENT_RESULT *result) { #define ZBX_BURST ((size_t)10) char *procname, *proccomm, *param; struct passwd *usrinfo; int proccount = 0, invalid_user = 0, zbx_proc_stat, i, count, idx = 0; struct pst_status pst[ZBX_BURST]; if (4 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } procname = get_rparam(request, 0); if (NULL != procname && '\0' == *procname) procname = NULL; param = get_rparam(request, 1); if (NULL != param && '\0' != *param) { errno = 0; if (NULL == (usrinfo = getpwnam(param))) { if (0 != errno) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain user information: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } invalid_user = 1; } } else usrinfo = NULL; param = get_rparam(request, 2); if (NULL == param || '\0' == *param || 0 == strcmp(param, "all")) zbx_proc_stat = ZBX_PROC_STAT_ALL; else if (0 == strcmp(param, "run")) zbx_proc_stat = ZBX_PROC_STAT_RUN; else if (0 == strcmp(param, "sleep")) zbx_proc_stat = ZBX_PROC_STAT_SLEEP; else if (0 == strcmp(param, "zomb")) zbx_proc_stat = ZBX_PROC_STAT_ZOMB; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); return SYSINFO_RET_FAIL; } proccomm = get_rparam(request, 3); if (NULL != proccomm && '\0' == *proccomm) proccomm = NULL; if (1 == invalid_user) /* handle 0 for non-existent user after all parameters have been parsed and validated */ goto out; memset(pst, 0, sizeof(pst)); while (0 < (count = pstat_getproc(pst, sizeof(*pst), ZBX_BURST, idx))) { for (i = 0; i < count; i++) { if (NULL != procname && 0 != strcmp(pst[i].pst_ucomm, procname)) continue; if (NULL != usrinfo && usrinfo->pw_uid != pst[i].pst_uid) continue; if (NULL != proccomm && NULL == zbx_regexp_match(pst[i].pst_cmd, proccomm, NULL)) continue; if (FAIL == check_procstate(pst[i], zbx_proc_stat)) continue; proccount++; } idx = pst[count - 1].pst_idx + 1; memset(pst, 0, sizeof(pst)); } if (-1 == count) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain process information.")); return SYSINFO_RET_FAIL; } out: SET_UI64_RESULT(result, proccount); return SYSINFO_RET_OK; }
int PROC_NUM(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { char tmp[MAX_STRING_LEN], procname[MAX_STRING_LEN], proccomm[MAX_STRING_LEN]; DIR *dir; struct dirent *entries; struct passwd *usrinfo; FILE *f_cmd = NULL, *f_stat = NULL; int zbx_proc_stat; zbx_uint64_t proccount = 0; if (num_param(param) > 4) return SYSINFO_RET_FAIL; if (0 != get_param(param, 1, procname, sizeof(procname))) *procname = '\0'; if (0 != get_param(param, 2, tmp, sizeof(tmp))) *tmp = '\0'; if (*tmp != '\0') { usrinfo = getpwnam(tmp); if (usrinfo == NULL) /* incorrect user name */ return SYSINFO_RET_FAIL; } else usrinfo = NULL; if (0 != get_param(param, 3, tmp, sizeof(tmp))) *tmp = '\0'; if (*tmp != '\0') { if (0 == strcmp(tmp, "run")) zbx_proc_stat = ZBX_PROC_STAT_RUN; else if (0 == strcmp(tmp, "sleep")) zbx_proc_stat = ZBX_PROC_STAT_SLEEP; else if (0 == strcmp(tmp, "zomb")) zbx_proc_stat = ZBX_PROC_STAT_ZOMB; else if (0 == strcmp(tmp, "all")) zbx_proc_stat = ZBX_PROC_STAT_ALL; else return SYSINFO_RET_FAIL; } else zbx_proc_stat = ZBX_PROC_STAT_ALL; if (0 != get_param(param, 4, proccomm, sizeof(proccomm))) *proccomm = '\0'; if (NULL == (dir = opendir("/proc"))) return SYSINFO_RET_FAIL; while (NULL != (entries = readdir(dir))) { zbx_fclose(f_cmd); zbx_fclose(f_stat); /* 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 (0 == strncmp(entries->d_name, "self", MAX_STRING_LEN)) continue; zbx_snprintf(tmp, sizeof(tmp), "/proc/%s/cmdline", entries->d_name); if (NULL == (f_cmd = open_proc_file(tmp))) continue; zbx_snprintf(tmp, sizeof(tmp), "/proc/%s/status", entries->d_name); if (NULL == (f_stat = open_proc_file(tmp))) continue; if (FAIL == check_procname(f_cmd, f_stat, procname)) continue; if (FAIL == check_user(f_stat, usrinfo)) continue; if (FAIL == check_proccomm(f_cmd, proccomm)) continue; if (FAIL == check_procstate(f_stat, zbx_proc_stat)) continue; proccount++; } zbx_fclose(f_cmd); zbx_fclose(f_stat); closedir(dir); SET_UI64_RESULT(result, proccount); return SYSINFO_RET_OK; }
int PROC_NUM(AGENT_REQUEST *request, AGENT_RESULT *result) { char tmp[MAX_STRING_LEN], *procname, *proccomm, *param; DIR *dir; struct dirent *entries; struct passwd *usrinfo; FILE *f_cmd = NULL, *f_stat = NULL; int proccount = 0, invalid_user = 0, zbx_proc_stat; if (4 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } procname = get_rparam(request, 0); param = get_rparam(request, 1); if (NULL != param && '\0' != *param) { errno = 0; if (NULL == (usrinfo = getpwnam(param))) { if (0 != errno) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain user information: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } invalid_user = 1; } } else usrinfo = NULL; param = get_rparam(request, 2); if (NULL == param || '\0' == *param || 0 == strcmp(param, "all")) zbx_proc_stat = ZBX_PROC_STAT_ALL; else if (0 == strcmp(param, "run")) zbx_proc_stat = ZBX_PROC_STAT_RUN; else if (0 == strcmp(param, "sleep")) zbx_proc_stat = ZBX_PROC_STAT_SLEEP; else if (0 == strcmp(param, "zomb")) zbx_proc_stat = ZBX_PROC_STAT_ZOMB; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); return SYSINFO_RET_FAIL; } proccomm = get_rparam(request, 3); if (1 == invalid_user) /* handle 0 for non-existent user after all parameters have been parsed and validated */ goto out; if (NULL == (dir = opendir("/proc"))) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot open /proc: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } while (NULL != (entries = readdir(dir))) { zbx_fclose(f_cmd); zbx_fclose(f_stat); if (0 == strcmp(entries->d_name, "self")) continue; zbx_snprintf(tmp, sizeof(tmp), "/proc/%s/cmdline", entries->d_name); if (NULL == (f_cmd = fopen(tmp, "r"))) continue; zbx_snprintf(tmp, sizeof(tmp), "/proc/%s/status", entries->d_name); if (NULL == (f_stat = fopen(tmp, "r"))) continue; if (FAIL == check_procname(f_cmd, f_stat, procname)) continue; if (FAIL == check_user(f_stat, usrinfo)) continue; if (FAIL == check_proccomm(f_cmd, proccomm)) continue; if (FAIL == check_procstate(f_stat, zbx_proc_stat)) continue; proccount++; } zbx_fclose(f_cmd); zbx_fclose(f_stat); closedir(dir); out: SET_UI64_RESULT(result, proccount); return SYSINFO_RET_OK; }