/**************************************************************/
/* Copyright (c) 1999, Magic Software Development, Inc. */
/* Author: Sean Ray Eskins. <sean@gilasoft.com> */
/* This file is free software; it can be modified and/or */
/* redistributed under the same terms as Perl itself. */
/**************************************************************/
#include "bsdi.h"
extern void bless_into_proc(char* format, char** fields, ...);
char* OS_initialize() {
return(NULL);
}
void OS_get_table() {
kvm_t *kd;
char errbuf[_POSIX2_LINE_MAX];
struct kinfo_proc *procs; /* array of processes */
int count; /* returns number of processes */
int i, j;
int seconds, minutes, secleft; /* for time[20] */
int milsec, shortmsec; /* for miliseconds of time[20] */
int ttynum;
long start;
char *ttydev;
static time_t now; /* for started[20] */
struct tm *tp; /* for month/day/hour/min/AM/PM fields of started[20] */
int SECSPERHOUR = 3600;
int SECSPERDAY = 24 * 3600;
pid_t sesid;
int length;
char cmndline[MAXARGLN+1];
char ** argv;
/* for bless_into_proc */
static char format[F_LASTFIELD + 2];
/* variables to hold some values for bless_into_proc */
char state[20];
char cputime[20];
char started[20];
char session[20];
char shortsess[20];
/* Open the kvm interface, get a descriptor */
if ((kd = kvm_open(NULL, NULL, NULL, 0, errbuf)) == NULL) {
/* fprintf(stderr, "kvm_open: %s\n", errbuf); */
ppt_croak("kvm_open: ", errbuf);
}
/* Get the list of processes. */
if ((procs = kvm_getprocs(kd, KERN_PROC_ALL, 0, &count)) == NULL) {
kvm_close(kd);
/* fprintf(stderr, "kvm_getprocs: %s\n", kvm_geterr(kd)); */
ppt_croak("kvm_getprocs: ", kvm_geterr(kd));
}
/* Iterate through the processes in kinfo_proc, sending proc info */
/* to bless_into_proc for each proc */
for (i=0; i < count; i++) {
static struct pstats ps;
static struct session seslead;
strcpy(format, Defaultformat);
/* get ttydev */
ttynum=procs[i].kp_eproc.e_tdev;
ttydev=devname(ttynum, S_IFCHR);
if (ttydev == NULL) ttydev = "??";
/* get the state of processes */
switch (procs[i].kp_proc.p_stat)
{
case SIDL:
strcpy(state, IDLE);
break;
case SRUN:
strcpy(state, RUN);
break;
case SSLEEP:
strcpy(state, SLEEP);
break;
case SSTOP:
strcpy(state, STOP);
break;
case SZOMB:
strcpy(state, ZOMBIE);
break;
default:
strcpy(state, UNKNOWN);
break;
}
/* get the cpu time of processes */
seconds=procs[i].kp_proc.p_rtime.tv_sec;
milsec=procs[i].kp_proc.p_rtime.tv_usec;
shortmsec=roundit(milsec);
if (seconds < 60) {
if (seconds < 10)
sprintf(cputime, "0:0%d.%d", seconds, shortmsec);
else
sprintf(cputime, "0:%d.%d", seconds, shortmsec);
}
else {
minutes=seconds/60;
secleft=seconds-(minutes * 60);
if (secleft < 10)
sprintf(cputime, "%d:0%d.%d", minutes, secleft, shortmsec);
else
sprintf(cputime, "%d:%d.%d", minutes, secleft, shortmsec);
}
/* get the start time of process (when started) */
/* fill the pstats struct using kvm_read */
if (kvm_read(kd, (u_long)procs[i].kp_proc.p_stats, (char *)&ps, sizeof(ps)) == sizeof(ps)) {
start=ps.p_start.tv_sec;
tp=localtime(&start);
if (!now)
(void)time(&now);
if (now - ps.p_start.tv_sec < 24 * SECSPERHOUR) {
static char fmt[] = __CONCAT("%l:%", "M%p");
(void)strftime(started, sizeof(started) - 1, fmt, tp);
}
else if (now - ps.p_start.tv_sec < 7 * SECSPERDAY) {
static char fmt[] = __CONCAT("%a%", "I%p");
(void)strftime(started, sizeof(started) - 1, fmt, tp);
}
else
(void)strftime(started, sizeof(started) - 1, "%e%b%y", tp);
}
/* get the session ID (ie: session pointer ID) */
sprintf(session, "%x", (u_long)procs[i].kp_eproc.e_sess);
length=strlen(session);
for (j=0; j < length; j++) {
if (session[1] == '1')
shortsess[j]=session[j+1];
else
shortsess[j]=session[j+2];
}
/* fill the session leader and proc struct using kvm_read */
if (kvm_read(kd, (u_long)procs[i].kp_eproc.e_sess, (char *)&seslead, sizeof(seslead)) == sizeof(seslead)) {
static struct proc leader;
if (kvm_read(kd, (u_long)seslead.s_leader, (char *)&leader, sizeof(leader)) == sizeof(leader)) {
sesid=leader.p_pid;
}
}
/* retrieve the arguments */
cmndline[0] = '\0';
argv = kvm_getargv(kd, (const struct kinfo_proc *) &(procs[i]) , 0);
if (argv) {
int j = 0;
while (argv[j] && strlen(cmndline)+strlen(argv[j])+1 <= MAXARGLN) {
strcat(cmndline, argv[j]);
if (argv[j+1]) {
strcat(cmndline, " ");
}
j++;
}
}
/* access everything else directly from the kernel, send it */
/* into bless_into_proc */
bless_into_proc( format,
Fields,
procs[i].kp_eproc.e_pcred.p_ruid,
procs[i].kp_eproc.e_pcred.p_rgid,
procs[i].kp_proc.p_pid,
procs[i].kp_eproc.e_ppid,
procs[i].kp_eproc.e_pgid,
procs[i].kp_proc.p_priority - PZERO,
shortsess,
sesid,
cputime,
procs[i].kp_eproc.e_wmesg,
procs[i].kp_proc.p_comm,
state,
started,
ttydev,
ttynum,
cmndline
);
}
if (kd) {
kvm_close(kd);
}
}