~ubuntu-branches/ubuntu/lucid/zabbix/lucid

« back to all changes in this revision

Viewing changes to src/libs/zbxsysinfo/linux/proc.c

  • Committer: Bazaar Package Importer
  • Author(s): Emanuele Gentili
  • Date: 2008-08-10 18:37:11 UTC
  • mfrom: (1.1.7 upstream) (8.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080810183711-h4n52nkqqf3iuqhn
Tags: 1:1.4.6-1ubuntu1
* Merge from debian unstable, remaining changes:
 + fixing missing pid directory in /var/run
 + Added the same patch to debian/zabbix-server-{mysql,pgsql}.zabbix-server.init

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#define DO_MAX 1
26
26
#define DO_MIN 2
27
27
#define DO_AVG 3
28
 
                                    
29
 
int     PROC_MEMORY(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result)
30
 
{ /* usage: <function name>[ <process name>, <user name>, <mode>, <command> ] */
31
 
 
32
 
        DIR     *dir;
33
 
        struct  dirent *entries;
34
 
        struct  stat buf;
35
 
        char    filename[MAX_STRING_LEN];
36
 
        char    line[MAX_STRING_LEN];
37
 
 
38
 
        char    name1[MAX_STRING_LEN];
39
 
        char    name2[MAX_STRING_LEN];
40
 
 
41
 
        char    proccomm[MAX_STRING_LEN];
42
 
        char    procname[MAX_STRING_LEN];
43
 
        char    usrname[MAX_STRING_LEN];
44
 
        char    mode[MAX_STRING_LEN];
45
 
 
46
 
        int     comm_ok = 0;
47
 
        int     proc_ok = 0;
48
 
        int     usr_ok = 0;
49
 
        int     do_task = DO_SUM;
50
 
 
51
 
        int     i,n;
52
 
 
53
 
        struct  passwd  *usrinfo = NULL;
54
 
        zbx_uint64_t    llvalue = 0;
55
 
 
56
 
        FILE    *f = NULL, *f2 = NULL;
57
 
 
58
 
        zbx_uint64_t    memsize = 0;
59
 
        int             first=0;
60
 
        zbx_uint64_t    proccount = 0;
 
28
 
 
29
#define ZBX_PROC_STAT_ALL 0
 
30
#define ZBX_PROC_STAT_RUN 1
 
31
#define ZBX_PROC_STAT_SLEEP 2
 
32
#define ZBX_PROC_STAT_ZOMB 3
 
33
        
 
34
static FILE     *open_proc_file(const char *filename)
 
35
{
 
36
        struct stat     s;
 
37
 
 
38
        if (0 != stat(filename, &s))
 
39
                return NULL;
 
40
 
 
41
        return fopen(filename, "r");
 
42
}
 
43
 
 
44
static int      get_cmdline(FILE *f_cmd, char *line, size_t *n)
 
45
{
 
46
        rewind(f_cmd);
 
47
 
 
48
        if (0 != (*n = fread(line, 1, MAX_STRING_LEN, f_cmd)))
 
49
                return SUCCEED;
 
50
 
 
51
        return FAIL;
 
52
}
 
53
 
 
54
static int      get_procname(FILE *f_stat, char *line)
 
55
{
 
56
        char    tmp[MAX_STRING_LEN], *p;
 
57
 
 
58
        rewind(f_stat);
 
59
 
 
60
        while (NULL != fgets(tmp, sizeof(tmp), f_stat)) {
 
61
                if (NULL == (p = strchr(tmp, '\t')))
 
62
                        continue;
 
63
 
 
64
                *p++ = '\0';
 
65
 
 
66
                if (0 != strcmp(tmp, "Name:"))
 
67
                        continue;
 
68
 
 
69
                zbx_rtrim(p, "\n");
 
70
                zbx_strlcpy(line, p, MAX_STRING_LEN);
 
71
                return SUCCEED;
 
72
        }
 
73
 
 
74
        return FAIL;
 
75
}
 
76
 
 
77
static int      check_procname(FILE *f_cmd, FILE *f_stat, const char *procname)
 
78
{
 
79
        char    tmp[MAX_STRING_LEN], *p;
 
80
        size_t  l;
 
81
 
 
82
        if (*procname == '\0')
 
83
                return SUCCEED;
 
84
 
 
85
        if (SUCCEED == get_cmdline(f_cmd, tmp, &l)) {
 
86
                if (NULL == (p = strrchr(tmp, '/')))
 
87
                        p = tmp;
 
88
                else
 
89
                        p++;
 
90
 
 
91
                if (0 == strcmp(p, procname))
 
92
                        return SUCCEED;
 
93
        } else if (SUCCEED == get_procname(f_stat, tmp)) {
 
94
                if (0 == strcmp(tmp, procname))
 
95
                        return SUCCEED;
 
96
        }
 
97
 
 
98
        return FAIL;
 
99
}
 
100
 
 
101
static int      check_user(FILE *f_stat, struct passwd *usrinfo)
 
102
{
 
103
        char    tmp[MAX_STRING_LEN], *p, *p1;
 
104
        uid_t   uid;
 
105
 
 
106
        if (NULL == usrinfo)
 
107
                return SUCCEED;
 
108
 
 
109
        rewind(f_stat);
 
110
 
 
111
        while (NULL != fgets(tmp, sizeof(tmp), f_stat)) {
 
112
                if (NULL == (p = strchr(tmp, '\t')))
 
113
                        continue;
 
114
 
 
115
                *p++ = '\0';
 
116
 
 
117
                if (0 != strcmp(tmp, "Uid:"))
 
118
                        continue;
 
119
 
 
120
                if (NULL != (p1 = strchr(p, '\t')))
 
121
                        *p1 = '\0';
 
122
 
 
123
                uid = (uid_t)atoi(p);
 
124
                if (usrinfo->pw_uid == uid)
 
125
                        return SUCCEED;
 
126
                break;
 
127
        }
 
128
 
 
129
        return FAIL;
 
130
}
 
131
 
 
132
static int      check_proccomm(FILE *f_cmd, const char *proccomm)
 
133
{
 
134
        char    tmp[MAX_STRING_LEN];
 
135
        size_t  i, l;
 
136
 
 
137
        if (*proccomm == '\0')
 
138
                return SUCCEED;
 
139
 
 
140
        if (SUCCEED == get_cmdline(f_cmd, tmp, &l)) {
 
141
                for (i = 0; i < l - 1; i++)
 
142
                        if (tmp[i] == '\0')
 
143
                                tmp[i] = ' ';
 
144
 
 
145
                if (NULL != zbx_regexp_match(tmp, proccomm, NULL))
 
146
                        return SUCCEED;
 
147
        }
 
148
 
 
149
        return FAIL;
 
150
}
 
151
 
 
152
static int      check_procstate(FILE *f_stat, int zbx_proc_stat)
 
153
{
 
154
        char    tmp[MAX_STRING_LEN], *p;
 
155
 
 
156
        if (zbx_proc_stat == ZBX_PROC_STAT_ALL)
 
157
                return SUCCEED;
 
158
 
 
159
        rewind(f_stat);
 
160
 
 
161
        while (NULL != fgets(tmp, sizeof(tmp), f_stat)) {       
 
162
                if (NULL == (p = strchr(tmp, '\t')))
 
163
                        continue;
 
164
 
 
165
                *p++ = '\0';
 
166
 
 
167
                if (0 != strcmp(tmp, "State:"))
 
168
                        continue;
 
169
 
 
170
                switch (zbx_proc_stat) {
 
171
                        case ZBX_PROC_STAT_RUN:
 
172
                                return (*p == 'R') ? SUCCEED : FAIL;
 
173
                        case ZBX_PROC_STAT_SLEEP:
 
174
                                return (*p == 'S') ? SUCCEED : FAIL;
 
175
                        case ZBX_PROC_STAT_ZOMB:
 
176
                                return (*p == 'Z') ? SUCCEED : FAIL;
 
177
                        default:
 
178
                                return FAIL;
 
179
                }
 
180
        }
 
181
        return FAIL;
 
182
}
 
183
 
 
184
int     PROC_MEMORY(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result)
 
185
{
 
186
        char            tmp[MAX_STRING_LEN], *p, *p1,
 
187
                        procname[MAX_STRING_LEN],
 
188
                        buffer[MAX_STRING_LEN],
 
189
                        proccomm[MAX_STRING_LEN];
 
190
        DIR             *dir;
 
191
        struct dirent   *entries;
 
192
        struct passwd   *usrinfo;
 
193
        FILE            *f_cmd = NULL, *f_stat = NULL;
 
194
        zbx_uint64_t    value = 0;
 
195
        int             do_task;
 
196
        double          memsize = 0;
 
197
        int             proccount = 0;
61
198
 
62
199
        assert(result);
63
200
 
64
201
        init_result(result);
65
202
 
66
 
        if(num_param(param) > 4)
67
 
        {
68
 
                return SYSINFO_RET_FAIL;
69
 
        }
70
 
 
71
 
        if(get_param(param, 1, procname, MAX_STRING_LEN) != 0)
72
 
        {
73
 
                return SYSINFO_RET_FAIL;
74
 
        }
75
 
 
76
 
        if(get_param(param, 2, usrname, MAX_STRING_LEN) != 0)
77
 
        {
78
 
                usrname[0] = 0;
79
 
        }
80
 
        else
81
 
        {
82
 
                if(usrname[0] != 0)
83
 
                {
84
 
                        usrinfo = getpwnam(usrname);
85
 
                        if(usrinfo == NULL)
86
 
                        {
87
 
                                /* incorrect user name */
88
 
                                return SYSINFO_RET_FAIL;
89
 
                        }                               
90
 
                }
91
 
        }
92
 
 
93
 
        if(get_param(param, 3, mode, MAX_STRING_LEN) != 0)
94
 
        {
95
 
                mode[0] = '\0';
96
 
        }
97
 
 
98
 
        if(mode[0] == '\0')
99
 
        {
100
 
                strscpy(mode, "sum");
101
 
        }
102
 
 
103
 
        if(strcmp(mode,"avg") == 0)
104
 
        {
105
 
                do_task = DO_AVG;
106
 
        }
107
 
        else if(strcmp(mode,"max") == 0)
108
 
        {
109
 
                do_task = DO_MAX;
110
 
        }
111
 
        else if(strcmp(mode,"min") == 0)
112
 
        {
113
 
                do_task = DO_MIN;
114
 
        }
115
 
        else if(strcmp(mode,"sum") == 0)
116
 
        {
 
203
        if (num_param(param) > 4)
 
204
                return SYSINFO_RET_FAIL;
 
205
 
 
206
        if (0 != get_param(param, 1, procname, sizeof(procname)))
 
207
                *procname = '\0';
 
208
 
 
209
        if (0 != get_param(param, 2, buffer, sizeof(buffer)))
 
210
                *buffer = '\0';
 
211
 
 
212
        if (*buffer != '\0') {
 
213
                usrinfo = getpwnam(buffer);
 
214
                if (usrinfo == NULL)    /* incorrect user name */
 
215
                        return SYSINFO_RET_FAIL;
 
216
        } else
 
217
                usrinfo = NULL;
 
218
 
 
219
        if (0 != get_param(param, 3, buffer, sizeof(buffer)))
 
220
                *buffer = '\0';
 
221
 
 
222
        if (*buffer != '\0') {
 
223
                if (0 == strcmp(buffer, "avg"))
 
224
                        do_task = DO_AVG;
 
225
                else if (0 == strcmp(buffer, "max"))
 
226
                        do_task = DO_MAX;
 
227
                else if (0 == strcmp(buffer, "min"))
 
228
                        do_task = DO_MIN;
 
229
                else if (0 == strcmp(buffer, "sum"))
 
230
                        do_task = DO_SUM;
 
231
                else
 
232
                        return SYSINFO_RET_FAIL;
 
233
        } else
117
234
                do_task = DO_SUM;
118
 
        }
119
 
        else
120
 
        {
121
 
                return SYSINFO_RET_FAIL;
122
 
        }
123
 
        
124
 
        if(get_param(param, 4, proccomm, MAX_STRING_LEN) != 0)
125
 
        {
126
 
                proccomm[0] = '\0';
127
 
        }
128
 
        
129
 
 
130
 
        dir=opendir("/proc");
131
 
        if(NULL == dir)
132
 
        {
133
 
                return SYSINFO_RET_FAIL;
134
 
        }
135
 
 
136
 
        while((entries=readdir(dir))!=NULL)
137
 
        {
138
 
                zbx_fclose(f);
139
 
 
140
 
                proc_ok = 0;
141
 
                usr_ok = 0;
142
 
 
143
 
                strscpy(filename,"/proc/");     
144
 
                zbx_strlcat(filename,entries->d_name,MAX_STRING_LEN);
145
 
                zbx_strlcat(filename,"/status",MAX_STRING_LEN);
 
235
 
 
236
        if (0 != get_param(param, 4, proccomm, sizeof(proccomm)))
 
237
                *proccomm = '\0';
 
238
 
 
239
        if (NULL == (dir = opendir("/proc")))
 
240
                return SYSINFO_RET_FAIL;
 
241
 
 
242
        while (NULL != (entries = readdir(dir))) {
 
243
                zbx_fclose(f_cmd);
 
244
                zbx_fclose(f_stat);
146
245
 
147
246
                /* Self is a symbolic link. It leads to incorrect results for proc_cnt[zabbix_agentd] */
148
247
                /* Better approach: check if /proc/x/ is symbolic link */
149
 
                if(strncmp(entries->d_name,"self",MAX_STRING_LEN) == 0)
150
 
                {
151
 
                        continue;
152
 
                }
153
 
 
154
 
                if(stat(filename,&buf)==0)
155
 
                {
156
 
                        if(NULL == ( f = fopen(filename,"r") ))
157
 
                        {
158
 
                                continue;
159
 
                        }
160
 
 
161
 
                        if(procname[0] != 0)
162
 
                        {
163
 
                                if(NULL == fgets(line,MAX_STRING_LEN,f))
164
 
                                {
165
 
                                        continue;
166
 
                                }
167
 
                                if(sscanf(line,"%s\t%s\n",name1,name2)==2)
168
 
                                {
169
 
                                        if(strcmp(name1,"Name:") == 0)
170
 
                                        {
171
 
                                                if(strcmp(procname,name2)==0)
172
 
                                                {
173
 
                                                        proc_ok = 1;
174
 
                                                }
175
 
                                        }
176
 
                                }
177
 
                    
178
 
                                if(proc_ok == 0) 
179
 
                                {
180
 
                                        continue;
181
 
                                }
182
 
                        }
183
 
                        else
184
 
                        {
185
 
                                proc_ok = 1;
186
 
                        }
187
 
                    
188
 
                        if(usrinfo != NULL)
189
 
                        {
190
 
                                while(fgets(line, MAX_STRING_LEN, f) != NULL)
191
 
                                {       
192
 
 
193
 
                                        if(sscanf(line, "%s\t" ZBX_FS_UI64 "\n", name1, &llvalue) != 2)
194
 
                                        {
195
 
                                                continue;
196
 
                                        }
197
 
 
198
 
                                        if(strcmp(name1,"Uid:") != 0)
199
 
                                        {
200
 
                                                continue;
201
 
                                        }
202
 
 
203
 
                                        if(usrinfo->pw_uid == (uid_t)(llvalue))
204
 
                                        {
205
 
                                                usr_ok = 1;
206
 
                                                break;
207
 
                                        }
208
 
                                }
209
 
                        }
210
 
                        else
211
 
                        {
212
 
                                usr_ok = 1;
213
 
                        }
214
 
                    
215
 
                        comm_ok = 0;
216
 
                        if(proccomm[0] != '\0')
217
 
                        {
218
 
                                strscpy(filename,"/proc/");
219
 
                                zbx_strlcat(filename,entries->d_name,MAX_STRING_LEN);
220
 
                                zbx_strlcat(filename,"/cmdline",MAX_STRING_LEN);
221
 
 
222
 
                                if(stat(filename,&buf)!=0)      continue;
223
 
 
224
 
                                f2=fopen(filename,"r");
225
 
                                if(f2==NULL)                    continue;
226
 
 
227
 
                                memset(line,0,MAX_STRING_LEN);
228
 
                                if((n = fread(line, 1, MAX_STRING_LEN, f2)) != 0)
229
 
                                {
230
 
                                        /* Replace all zero delimiters with spaces */
231
 
                                        for(i=0;i<n-1;i++)
232
 
                                        {
233
 
                                                if(line[i]==0)  line[i]=' ';
234
 
                                        }
235
 
                                        if(zbx_regexp_match(line,proccomm,NULL) != NULL)
236
 
                                        comm_ok = 1;
237
 
                                }
238
 
 
239
 
                                fclose(f2);
240
 
                        } else {
241
 
                                comm_ok = 1;
242
 
                        }
243
 
                
244
 
                        if(proc_ok && usr_ok && comm_ok)
245
 
                        {
246
 
                                while(fgets(line, MAX_STRING_LEN, f) != NULL)
247
 
                                {       
248
 
 
249
 
                                        if(sscanf(line, "%s\t" ZBX_FS_UI64 " %s\n", name1, &llvalue, name2) != 3)
250
 
                                        {
251
 
                                                continue;
252
 
                                        }
253
 
 
254
 
                                        if(strcmp(name1,"VmSize:") != 0)
255
 
                                        {
256
 
                                                continue;
257
 
                                        }
258
 
 
259
 
                                        proccount++;
260
 
 
261
 
                                        if(strcasecmp(name2, "kB") == 0)
262
 
                                        {
263
 
                                                llvalue <<= 10;
264
 
                                        }
265
 
                                        else if(strcasecmp(name2, "mB") == 0)
266
 
                                        {
267
 
                                                llvalue <<= 20;
268
 
                                        }
269
 
                                        else if(strcasecmp(name2, "GB") == 0)
270
 
                                        {
271
 
                                                llvalue <<= 30;
272
 
                                        }
273
 
                                        else if(strcasecmp(name2, "TB") == 0)
274
 
                                        {
275
 
                                                llvalue <<= 40;
276
 
                                        }
277
 
 
278
 
                                        if(first == 0)
279
 
                                        {
280
 
                                                memsize = llvalue;
281
 
                                                first  = 1;
282
 
                                        }
283
 
                                        else
284
 
                                        {
285
 
                                                if(do_task == DO_MAX)
286
 
                                                {
287
 
                                                        memsize = MAX(memsize, llvalue);
288
 
                                                }
289
 
                                                else if(do_task == DO_MIN)
290
 
                                                {
291
 
                                                        memsize = MIN(memsize, llvalue);
292
 
                                                }
293
 
                                                else
294
 
                                                {
295
 
                                                        memsize +=  llvalue;
296
 
                                                }
297
 
                                        }
298
 
 
299
 
                                        break;
300
 
                                }
301
 
                        }
 
248
                if (0 == strncmp(entries->d_name, "self", MAX_STRING_LEN))
 
249
                        continue;
 
250
 
 
251
                zbx_snprintf(tmp, sizeof(tmp), "/proc/%s/cmdline", entries->d_name);
 
252
 
 
253
                if (NULL == (f_cmd = open_proc_file(tmp)))
 
254
                        continue;
 
255
 
 
256
                zbx_snprintf(tmp, sizeof(tmp), "/proc/%s/status", entries->d_name);
 
257
 
 
258
                if (NULL == (f_stat = open_proc_file(tmp)))
 
259
                        continue;
 
260
 
 
261
                if (FAIL == check_procname(f_cmd, f_stat, procname))
 
262
                        continue;
 
263
 
 
264
                if (FAIL == check_user(f_stat, usrinfo))
 
265
                        continue;
 
266
 
 
267
                if (FAIL == check_proccomm(f_cmd, proccomm))
 
268
                        continue;
 
269
 
 
270
                rewind(f_stat);
 
271
 
 
272
                while (NULL != fgets(tmp, sizeof(tmp), f_stat)) {       
 
273
                        if (NULL == (p = strchr(tmp, '\t')))
 
274
                                continue;
 
275
 
 
276
                        *p++ = '\0';
 
277
 
 
278
                        if (0 != strcmp(tmp, "VmSize:"))
 
279
                                continue;
 
280
 
 
281
                        if (NULL == (p1 = strrchr(p, ' ')))
 
282
                                continue;
 
283
 
 
284
                        *p1++ = '\0';
 
285
 
 
286
                        value = zbx_atoui64(p);
 
287
 
 
288
                        zbx_rtrim(p1, "\n");
 
289
 
 
290
                        if (0 == strcasecmp(p1, "kB"))
 
291
                                value <<= 10;
 
292
                        else if(0 == strcasecmp(p1, "mB"))
 
293
                                value <<= 20;
 
294
                        else if(0 == strcasecmp(p1, "GB"))
 
295
                                value <<= 30;
 
296
                        else if(0 == strcasecmp(p1, "TB"))
 
297
                                value <<= 40;
 
298
 
 
299
                        if (0 == proccount++)
 
300
                                memsize = value;
 
301
                        else {
 
302
                                if (do_task == DO_MAX)
 
303
                                        memsize = MAX(memsize, value);
 
304
                                else if(do_task == DO_MIN)
 
305
                                        memsize = MIN(memsize, value);
 
306
                                else
 
307
                                        memsize += value;
 
308
                        }
 
309
                        break;
302
310
                }
303
311
        }
304
 
        zbx_fclose(f);
 
312
        zbx_fclose(f_cmd);
 
313
        zbx_fclose(f_stat);
305
314
        closedir(dir);
306
315
 
307
 
        if(first == 0)
308
 
        {
309
 
                /* incorrect process name */
310
 
                memsize = 0;
311
 
        }
312
 
 
313
 
        if(do_task == DO_AVG)
314
 
        {
315
 
                SET_DBL_RESULT(result, proccount == 0 ? 0 : ((double)memsize/(double)proccount));
316
 
        }
317
 
        else
318
 
        {
 
316
        if (do_task == DO_AVG) {
 
317
                SET_DBL_RESULT(result, proccount == 0 ? 0 : memsize/proccount);
 
318
        } else {
319
319
                SET_UI64_RESULT(result, memsize);
320
320
        }
 
321
 
321
322
        return SYSINFO_RET_OK;
322
323
}
323
324
 
324
325
int         PROC_NUM(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result)
325
 
{ /* usage: <function name>[ <process name>, <user name>, <process state>, <command> ] */
326
 
        
327
 
        DIR     *dir;
328
 
        struct  dirent *entries;
329
 
        struct  stat buf;
330
 
        char    filename[MAX_STRING_LEN];
331
 
        char    line[MAX_STRING_LEN];
332
 
 
333
 
        char    name1[MAX_STRING_LEN];
334
 
        char    name2[MAX_STRING_LEN];
335
 
 
336
 
        char    proccomm[MAX_STRING_LEN];
337
 
        char    procname[MAX_STRING_LEN];
338
 
        char    usrname[MAX_STRING_LEN];
339
 
        char    procstat[MAX_STRING_LEN];
340
 
 
341
 
        int     proc_ok = 0;
342
 
        int     usr_ok = 0;
343
 
        int     stat_ok = 0;
344
 
        int     comm_ok = 0;
345
 
 
346
 
        int     i,n;
347
 
 
348
 
        struct  passwd *usrinfo = NULL;
349
 
        long int        lvalue = 0;
350
 
 
351
 
        FILE    *f;
 
326
{
 
327
        char            tmp[MAX_STRING_LEN],
 
328
                        procname[MAX_STRING_LEN],
 
329
                        buffer[MAX_STRING_LEN],
 
330
                        proccomm[MAX_STRING_LEN];
 
331
        DIR             *dir;
 
332
        struct dirent   *entries;
 
333
        struct passwd   *usrinfo;
 
334
        FILE            *f_cmd = NULL, *f_stat = NULL;
 
335
        int             zbx_proc_stat;
352
336
        zbx_uint64_t    proccount = 0;
353
337
 
354
 
        assert(result);
355
 
 
356
 
        init_result(result);
357
 
        
358
 
        if(num_param(param) > 4)
359
 
        {
360
 
                return SYSINFO_RET_FAIL;
361
 
        }
362
 
    
363
 
        if(get_param(param, 1, procname, MAX_STRING_LEN) != 0)
364
 
        {
365
 
                return SYSINFO_RET_FAIL;
366
 
        }
367
 
    
368
 
        usrinfo = NULL;
369
 
        if(get_param(param, 2, usrname, MAX_STRING_LEN) != 0)
370
 
        {
371
 
                usrname[0] = 0;
372
 
        }
373
 
        else
374
 
        {
375
 
            if(usrname[0] != 0)
376
 
            {
377
 
                usrinfo = getpwnam(usrname);
378
 
                if(usrinfo == NULL)
379
 
                {
380
 
                    /* incorrect user name */
381
 
                    return SYSINFO_RET_FAIL;
382
 
                }                               
383
 
            }
384
 
        }
385
 
    
386
 
        if(get_param(param, 3, procstat, MAX_STRING_LEN) != 0)
387
 
        {
388
 
                procstat[0] = '\0';
389
 
        }
390
 
 
391
 
        if(procstat[0] == '\0')
392
 
        {
393
 
                strscpy(procstat, "all");
394
 
        }
395
 
    
396
 
        if(strcmp(procstat,"run") == 0)
397
 
        {
398
 
            strscpy(procstat,"R");      
399
 
        }
400
 
        else if(strcmp(procstat,"sleep") == 0)
401
 
        {
402
 
            strscpy(procstat,"S");      
403
 
        }
404
 
        else if(strcmp(procstat,"zomb") == 0)
405
 
        {
406
 
            strscpy(procstat,"Z");      
407
 
        }
408
 
        else if(strcmp(procstat,"all") == 0)
409
 
        {
410
 
            procstat[0] = 0;
411
 
        }
412
 
        else
413
 
        {
414
 
            return SYSINFO_RET_FAIL;
415
 
        }
416
 
 
417
 
        if(get_param(param, 4, proccomm, MAX_STRING_LEN) != 0)
418
 
        {
419
 
                proccomm[0] = '\0';
420
 
        }
421
 
        
422
 
        dir=opendir("/proc");
423
 
        if(NULL == dir)
424
 
        {
425
 
            return SYSINFO_RET_FAIL;
426
 
        }
427
 
 
428
 
        while((entries=readdir(dir))!=NULL)
429
 
        {
430
 
 
431
 
/* Self is a symbolic link. It leads to incorrect results for proc_cnt[zabbix_agentd] */
432
 
/* Better approach: check if /proc/x/ is symbolic link */
433
 
                if(strncmp(entries->d_name,"self",MAX_STRING_LEN) == 0)
434
 
                {
435
 
                        continue;
436
 
                }
437
 
 
438
 
                strscpy(filename,"/proc/");     
439
 
                zbx_strlcat(filename,entries->d_name,MAX_STRING_LEN);
440
 
                zbx_strlcat(filename,"/status",MAX_STRING_LEN);
441
 
 
442
 
                if(stat(filename,&buf)!=0)
443
 
                {
444
 
                        continue;
445
 
                }
446
 
 
447
 
                if(NULL == (f = fopen(filename,"r") ))
448
 
                {
449
 
                        continue;
450
 
                }
451
 
    
452
 
                proc_ok = 0;
453
 
                if(procname[0] != 0)
454
 
                {
455
 
                    if(NULL == fgets(line,MAX_STRING_LEN,f))
456
 
                        {
457
 
                                continue;
458
 
                        }
459
 
                    if(sscanf(line,"%s\t%s\n",name1,name2)==2)
460
 
                    {
461
 
                        if(strcmp(name1,"Name:") == 0)
462
 
                        {
463
 
                            if(strcmp(procname,name2)==0)
464
 
                            {
465
 
                                proc_ok = 1;
466
 
                            }
467
 
                        }
468
 
                    }
469
 
                
470
 
                    if(proc_ok == 0) 
471
 
                    {
472
 
                        zbx_fclose(f);
473
 
                        continue;
474
 
                    }
475
 
                }
476
 
                else
477
 
                {
478
 
                    proc_ok = 1;
479
 
                }
480
 
 
481
 
                stat_ok = 0;
482
 
                if(procstat[0] != 0)
483
 
                {
484
 
                    while(fgets(line, MAX_STRING_LEN, f) != NULL)
485
 
                    {   
486
 
                    
487
 
                        if(sscanf(line, "%s\t%s\n", name1, name2) != 2)
488
 
                        {
489
 
                            continue;
490
 
                        }
491
 
                        
492
 
                        if(strcmp(name1,"State:") != 0)
493
 
                        {
494
 
                            continue;
495
 
                        }
496
 
                        
497
 
                        if(strcmp(name2, procstat) == 0)
498
 
                        {
499
 
                            stat_ok = 1;
500
 
                            break;
501
 
                        }
502
 
                    }
503
 
                }
504
 
                else
505
 
                {
506
 
                    stat_ok = 1;
507
 
                }
508
 
                
509
 
                usr_ok = 0;
510
 
                if(usrinfo != NULL)
511
 
                {
512
 
                    while(fgets(line, MAX_STRING_LEN, f) != NULL)
513
 
                    {   
514
 
                    
515
 
                        if(sscanf(line, "%s\t%li\n", name1, &lvalue) != 2)
516
 
                        {
517
 
                            continue;
518
 
                        }
519
 
                        
520
 
                        if(strcmp(name1,"Uid:") != 0)
521
 
                        {
522
 
                            continue;
523
 
                        }
524
 
                        
525
 
                        if(usrinfo->pw_uid == (uid_t)(lvalue))
526
 
                        {
527
 
                            usr_ok = 1;
528
 
                            break;
529
 
                        }
530
 
                    }
531
 
                }
532
 
                else
533
 
                {
534
 
                    usr_ok = 1;
535
 
                }
536
 
                zbx_fclose(f);
 
338
        assert(result);
 
339
 
 
340
        init_result(result);
 
341
        
 
342
 
 
343
        if (num_param(param) > 4)
 
344
                return SYSINFO_RET_FAIL;
 
345
 
 
346
        if (0 != get_param(param, 1, procname, sizeof(procname)))
 
347
                *procname = '\0';
 
348
 
 
349
        if (0 != get_param(param, 2, buffer, sizeof(buffer)))
 
350
                *buffer = '\0';
 
351
 
 
352
        if (*buffer != '\0') {
 
353
                usrinfo = getpwnam(buffer);
 
354
                if (usrinfo == NULL)    /* incorrect user name */
 
355
                        return SYSINFO_RET_FAIL;
 
356
        } else
 
357
                usrinfo = NULL;
 
358
    
 
359
        if (0 != get_param(param, 3, buffer, sizeof(buffer)))
 
360
                *buffer = '\0';
537
361
                
538
 
                comm_ok = 0;
539
 
                if(proccomm[0] != '\0')
540
 
                {
541
 
                        strscpy(filename,"/proc/");
542
 
                        zbx_strlcat(filename,entries->d_name,MAX_STRING_LEN);
543
 
                        zbx_strlcat(filename,"/cmdline",MAX_STRING_LEN);
544
 
 
545
 
                        if(stat(filename,&buf)!=0)      continue;
546
 
 
547
 
                        f=fopen(filename,"r");
548
 
                        if(f==NULL)                    continue;
549
 
                        
550
 
                        memset(line,0,MAX_STRING_LEN);
551
 
                        if((n = fread(line, 1, MAX_STRING_LEN, f)) != 0)
552
 
                        {
553
 
                                /* Replace all zero delimiters with spaces */
554
 
                                for(i=0;i<n-1;i++)
555
 
                                {
556
 
                                        if(line[i]==0)  line[i]=' ';
557
 
                                }
558
 
                                if(zbx_regexp_match(line,proccomm,NULL) != NULL)
559
 
                                comm_ok = 1;
560
 
                        }
561
 
                        fclose(f);
562
 
 
563
 
                } else {
564
 
                        comm_ok = 1;
565
 
                }
566
 
                
567
 
                if(proc_ok && stat_ok && usr_ok && comm_ok)
568
 
                {
569
 
                    proccount++;
570
 
                }
571
 
                
 
362
        if (*buffer != '\0') {
 
363
                if (0 == strcmp(buffer, "run"))
 
364
                        zbx_proc_stat = ZBX_PROC_STAT_RUN;
 
365
                else if (0 == strcmp(buffer, "sleep"))
 
366
                        zbx_proc_stat = ZBX_PROC_STAT_SLEEP;
 
367
                else if (0 == strcmp(buffer, "zomb"))
 
368
                        zbx_proc_stat = ZBX_PROC_STAT_ZOMB;
 
369
                else if (0 == strcmp(buffer, "all"))
 
370
                        zbx_proc_stat = ZBX_PROC_STAT_ALL;
 
371
                else
 
372
                        return SYSINFO_RET_FAIL;
 
373
        } else
 
374
                zbx_proc_stat = ZBX_PROC_STAT_ALL;
 
375
 
 
376
        if (0 != get_param(param, 4, proccomm, sizeof(proccomm)))
 
377
                *proccomm = '\0';
 
378
 
 
379
        if (NULL == (dir = opendir("/proc")))
 
380
                return SYSINFO_RET_FAIL;
 
381
 
 
382
        while (NULL != (entries = readdir(dir))) {
 
383
                zbx_fclose(f_cmd);
 
384
                zbx_fclose(f_stat);
 
385
 
 
386
                /* Self is a symbolic link. It leads to incorrect results for proc_cnt[zabbix_agentd] */
 
387
                /* Better approach: check if /proc/x/ is symbolic link */
 
388
                if (0 == strncmp(entries->d_name, "self", MAX_STRING_LEN))
 
389
                        continue;
 
390
 
 
391
                zbx_snprintf(tmp, sizeof(tmp), "/proc/%s/cmdline", entries->d_name);
 
392
 
 
393
                if (NULL == (f_cmd = open_proc_file(tmp)))
 
394
                        continue;
 
395
 
 
396
                zbx_snprintf(tmp, sizeof(tmp), "/proc/%s/status", entries->d_name);
 
397
 
 
398
                if (NULL == (f_stat = open_proc_file(tmp)))
 
399
                        continue;
 
400
 
 
401
                if (FAIL == check_procname(f_cmd, f_stat, procname))
 
402
                        continue;
 
403
 
 
404
                if (FAIL == check_user(f_stat, usrinfo))
 
405
                        continue;
 
406
 
 
407
                if (FAIL == check_proccomm(f_cmd, proccomm))
 
408
                        continue;
 
409
 
 
410
                if (FAIL == check_procstate(f_stat, zbx_proc_stat))
 
411
                        continue;
 
412
 
 
413
                proccount++;
572
414
        }
 
415
        zbx_fclose(f_cmd);
 
416
        zbx_fclose(f_stat);
573
417
        closedir(dir);
574
418
 
575
419
        SET_UI64_RESULT(result, proccount);
 
420
 
576
421
        return SYSINFO_RET_OK;
577
422
}
 
423