| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- /*****************************************************************************
- *
- * pst3
- *
- * License: GPL
- * Copyright (c) 2008 Nagios Plugin Development Team
- *
- * Description:
- *
- * This file contains the pst3 executable. This is a replacement ps command
- * for Solaris to get output which provides a long argument listing, which
- * is not possible with the standard ps command (due to truncation). /usr/ucb/ps
- * also has issues where some fields run into each other.
- *
- * This executable works by reading the kernel memory structures, so needs
- * to be executed as root
- *
- * Originally written by R.W.Ingraham
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- *****************************************************************************/
- #define _KMEMUSER 1
- #include <kvm.h>
- #include <sys/param.h>
- #include <sys/user.h>
- #include <sys/time.h>
- #include <sys/proc.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include <procfs.h>
- #include <fcntl.h>
- #include <dirent.h>
- #include <errno.h>
- /*
- * Constants
- */
- #define PROC_DIR "/proc"
- #define MAX_PATH 1024
- #define OK 0
- #define FAIL NULL
- /*
- * Structures
- */
- /*
- * Globals
- */
- static char * szProg;
- static kvm_t * kd;
- static struct proc * pProc;
- static struct user * pUser;
- static char ** myArgv;
- /*
- * Prototypes
- */
- static int output_info(struct proc *proc_kvm, psinfo_t procinfo,char **proc_argv);
- static psinfo_t get_procinfo(struct proc *proc);
- static int HandleProc(struct proc *proc);
- /*----------------------------------------------------------------------------*/
- int main (int argc, char **argv)
- {
- DIR *pDir;
- struct dirent *pDent;
- int retcode = 0;
- struct proc *proc;
- struct pid pid;
- /* Set our program name global */
- if ((szProg = strrchr(argv[0], '/')) != NULL)
- szProg++;
- else
- szProg = argv[0];
- /* Make sure that our euid is root */
- if (geteuid() != 0)
- {
- fprintf(stderr, "%s: This program can only be run by the root user!\n", szProg);
- exit(1);
- }
- /* Get a handle to the running kernel image */
- if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, argv[0])) == NULL)
- {
- fprintf(stderr, "%s: Failed to open kernel memory: %s\n", szProg, strerror(errno));
- exit(2);
- }
- /* reset to first proc in list */
- if(kvm_setproc(kd) == -1) {
- perror("kvm_setproc");
- exit(2);
- }
- /* Display column headings */
- printf("%c %5s %5s %5s %6s %6s %4s %s %s\n",
- 'S',
- "UID",
- "PID",
- "PPID",
- "VSZ",
- "RSS",
- "%CPU",
- "COMMAND",
- "ARGS"
- );
- /* Zip through all of the process entries */
- while((proc = kvm_nextproc(kd)) != 0) {
- HandleProc(proc);
- }
- /* Close the handle to the running kernel image */
- kvm_close(kd);
- return retcode;
- }
- /*----------------------------------------------------------------------------*/
- static int HandleProc(struct proc *proc)
- {
- struct pid pid;
- struct user *user;
- psinfo_t procinfo;
- char **proc_argv = 0;
- if(kvm_kread(kd, (unsigned long) proc->p_pidp, (char *) &pid, sizeof pid) == -1) {
- perror("kvm_read error");
- exit(2);
- }
- proc->p_pidp = &pid;
- user = kvm_getu(kd, proc);
- if(kvm_getcmd(kd, proc, user, &proc_argv, NULL) == -1) {
- return FAIL;
- }
- procinfo = get_procinfo(proc);
- return output_info(proc, procinfo, proc_argv);
- }
- static psinfo_t get_procinfo(struct proc *proc)
- {
- char procpath[MAX_PATH];
- psinfo_t procinfo;
- int fd, len;
- sprintf(procpath, "/proc/%d/psinfo", proc->p_pidp->pid_id);
- if ((fd = open(procpath, O_RDONLY)) >= 0)
- {
- if ((len = read(fd, &procinfo, sizeof(procinfo))) != sizeof(procinfo))
- {
- fprintf(stderr,"%s: Read error of psingo structure (%d)\n", procpath, len);
- exit(2);
- }
- close(fd);
- }
- return procinfo;
- }
- static int output_info(struct proc *proc_kvm, psinfo_t procinfo, char **proc_argv)
- {
- char *procname;
- int i;
- if((procname = strrchr(proc_argv[0], '/')) != NULL)
- procname++;
- else
- procname = proc_argv[0];
- printf("%c %5d %5d %5d %6lu %6lu %4.1f %s ",
- procinfo.pr_lwp.pr_sname,
- (int)(procinfo.pr_euid),
- (int)proc_kvm->p_pidp->pid_id,
- (int)proc_kvm->p_ppid,
- (unsigned long)(procinfo.pr_size),
- (unsigned long)(procinfo.pr_rssize),
- ((float)(procinfo.pr_pctcpu) / 0x8000 * 100.0),
- procname
- );
- for(i=0;proc_argv[i];i++) {
- printf(" %s", proc_argv[i]);
- }
- printf("\n");
- return OK;
- }
|