summaryrefslogtreecommitdiffstats
path: root/plugins-root/pst3.c
diff options
context:
space:
mode:
authorM. Sean Finney <seanius@users.sourceforge.net>2005-09-22 09:43:12 (GMT)
committerM. Sean Finney <seanius@users.sourceforge.net>2005-09-22 09:43:12 (GMT)
commit5163656fe8b96a98def934c2fb4a8529fe3a7489 (patch)
tree16e919f6ae083783ae27b14ac80c2821e86ad3c0 /plugins-root/pst3.c
parent07881972576a9a517100f7394d5538200d6986fd (diff)
downloadmonitoring-plugins-5163656fe8b96a98def934c2fb4a8529fe3a7489.tar.gz
first version of bob ingraham's pst3 to allow checking for longer
cmdline names than otherwise possible, by querying solaris kmem directly (ps forcibly truncates). added requisite configure.in voodoo and updated THANKS.in. git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@1238 f882894a-f735-0410-b71e-b25c423dba1c
Diffstat (limited to 'plugins-root/pst3.c')
-rw-r--r--plugins-root/pst3.c252
1 files changed, 252 insertions, 0 deletions
diff --git a/plugins-root/pst3.c b/plugins-root/pst3.c
new file mode 100644
index 0000000..ace3113
--- /dev/null
+++ b/plugins-root/pst3.c
@@ -0,0 +1,252 @@
1/* pst3.c
2 *
3 * Third version to get process arg info; this time by using
4 * a combination of reading the /proc/<pid>/psinfo structures
5 * and reading the complete arg vector from kernel memory structures.
6 *
7 * Developed and tested under Solaris 5.8 (both 32 and 64 bit modes).
8 *
9 * NOTE: This program must be setuid-root (or run by root) to work!
10 *
11 * Written: 2005-04-28 R.W.Ingraham
12 */
13
14
15#define _KMEMUSER 1
16
17#include <kvm.h>
18#include <sys/param.h>
19#include <sys/user.h>
20#include <sys/time.h>
21#include <sys/proc.h>
22#include <sys/types.h>
23#include <sys/stat.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <unistd.h>
27#include <string.h>
28#include <procfs.h>
29#include <fcntl.h>
30#include <dirent.h>
31#include <errno.h>
32
33
34/*
35 * Constants
36 */
37
38#define PROC_DIR "/proc"
39#define MAX_PATH 1024
40
41
42/*
43 * Structures
44 */
45
46
47/*
48 * Globals
49 */
50
51static char * szProg;
52static kvm_t * kd;
53static struct proc * pProc;
54static struct user * pUser;
55static char ** myArgv;
56
57
58/*
59 * Prototypes
60 */
61
62static int HandleFile (struct dirent *pDent);
63static int HandlePsInfo (char *szPath, psinfo_t *pPsInfo);
64static int GetArgVectors (pid_t pid);
65static void ShowArgVectors (void);
66static void ReleaseArgVectors();
67
68
69/*----------------------------------------------------------------------------*/
70
71int main (int argc, char **argv)
72{
73 DIR *pDir;
74 struct dirent *pDent;
75 int retcode = 0;
76
77
78 /* Set our program name global */
79 if ((szProg = strrchr(argv[0], '/')) != NULL)
80 szProg++;
81 else
82 szProg = argv[0];
83
84 /* Make sure that our euid is root */
85 if (geteuid() != 0)
86 {
87 fprintf(stderr, "%s: This program can only be run by the root user!\n", szProg);
88 exit(1);
89 }
90
91 /* Get a handle to the running kernel image */
92 if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, argv[0])) == NULL)
93 {
94 fprintf(stderr, "%s: Failed to open kernel memory: %s\n", szProg, strerror(errno));
95 exit(2);
96 }
97
98 /* Open the /proc directory */
99 if ((pDir = opendir(PROC_DIR)) != NULL)
100 {
101 /* Display column headings */
102 printf("S UID PPID VSZ RSS %%CPU COMMAND ARGS\n");
103
104 /* Zip through all of the process entries */
105 while ((pDent = readdir(pDir)) != NULL)
106 {
107 /* Handle each pid sub-directory */
108 HandleFile(pDent);
109 }
110
111 /* Close the directory */
112 closedir(pDir);
113 }
114 else /* ERROR: Failure to open PROC_DIR */
115 {
116 fprintf(stderr, "%s: Failed to open \"%s\": %s\n", szProg, PROC_DIR, strerror(errno));
117 retcode = 3;
118 }
119
120 /* Close the handle to the running kernel image */
121 kvm_close(kd);
122
123 return retcode;
124}
125
126/*----------------------------------------------------------------------------*/
127
128static int HandleFile (struct dirent *pDent)
129{
130 char szPath[MAX_PATH];
131 psinfo_t sPsInfo;
132 int fd, len;
133 int rc = 0;
134
135 /* Skip files beginning with a "." */
136 if (pDent->d_name[0] == '.')
137 return 0;
138
139 /* Cosntruct the path to the psinfo file */
140 len = sprintf(szPath, "%s/%s/psinfo", PROC_DIR, pDent->d_name);
141
142 /* Open the psinfo file for this pid and print out its arg vectors */
143 if ((fd = open(szPath, O_RDONLY)) >= 0)
144 {
145 /* Read the psinfo struct */
146 if ((len = read(fd, &sPsInfo, sizeof(sPsInfo))) != sizeof(sPsInfo))
147 {
148 rc = errno;
149 fprintf(stderr, "%s: Read error of psinfo structure (%d)\n", szPath, len);
150 return rc;
151 }
152
153 /* Close the psinfo file */
154 close(fd);
155
156 /* Pass psinfo struct to reporting function */
157 HandlePsInfo(szPath, &sPsInfo);
158 }
159 else if (errno != ENOENT)
160 {
161 rc = errno;
162 fprintf(stderr, "%s: %s\n", szPath, strerror(errno));
163 }
164
165 return 0;
166}
167
168/*----------------------------------------------------------------------------*/
169
170static int HandlePsInfo (char *szPath, psinfo_t *pPsInfo)
171{
172 int retcode;
173 char *thisProg;
174
175 /* Make sure that the process is still there */
176 if ((retcode = GetArgVectors(pPsInfo->pr_pid)) == 0)
177 {
178 /* We use the program name from the kvm argv[0] instead
179 * of pr_fname from the psinfo struct because pr_fname
180 * may be truncated.
181 *
182 * Also, strip-off leading path information.
183 */
184 if ((thisProg = strrchr(myArgv[0], '/')) != NULL)
185 thisProg++;
186 else
187 thisProg = myArgv[0];
188
189 /* Display the ps columns (except for argv) */
190 printf("%c %5d %5d %6lu %6lu %4.1f %s ",
191 pPsInfo->pr_lwp.pr_sname,
192 (int)(pPsInfo->pr_euid),
193 (int)(pPsInfo->pr_ppid),
194 (unsigned long)(pPsInfo->pr_size),
195 (unsigned long)(pPsInfo->pr_rssize),
196 ((float)(pPsInfo->pr_pctcpu) / 0x8000 * 100.0),
197 thisProg);
198
199 /* Display the arg vectors associated with this pid */
200 ShowArgVectors();
201
202 /* Release the arg vector buffer memory */
203 ReleaseArgVectors();
204 }
205
206 return retcode;
207}
208
209/*----------------------------------------------------------------------------*/
210
211static int GetArgVectors (pid_t pid)
212{
213 int retcode = 1;
214
215 /* Get the proc structure for the specified PID */
216 if ((pProc = kvm_getproc(kd, pid)) != NULL)
217 {
218 /* Save a copy of the process' u-area */
219 if ((pUser = kvm_getu(kd, pProc)) != NULL)
220 {
221 /* Reconstruct the process' argv vector array */
222 if (kvm_getcmd(kd, pProc, pUser, &myArgv, NULL) == 0)
223 {
224 retcode = 0;
225 }
226 }
227 }
228
229 return retcode;
230}
231
232/*----------------------------------------------------------------------------*/
233
234static void ShowArgVectors (void)
235{
236 int i;
237
238 for (i=0; myArgv[i]; i++)
239 {
240 printf(" %s", myArgv[i]);
241 }
242 printf("\n");
243}
244
245/*----------------------------------------------------------------------------*/
246
247static void ReleaseArgVectors()
248{
249 /* NOOP */
250}
251
252/*----------------------------------------------------------------------------*/