1 /**************************************************************/
2 /* Copyright (c) 1999, Magic Software Development, Inc. */
3 /* Author: Sean Ray Eskins. <sean@gilasoft.com> */
4 /* This file is free software; it can be modified and/or */
5 /* redistributed under the same terms as Perl itself. */
6 /**************************************************************/
7
8 #include "bsdi.h"
9
10 extern void bless_into_proc(char* format, char** fields, ...);
11
OS_initialize()12 char* OS_initialize() {
13 return(NULL);
14 }
15
OS_get_table()16 void OS_get_table() {
17 kvm_t *kd;
18 char errbuf[_POSIX2_LINE_MAX];
19 struct kinfo_proc *procs; /* array of processes */
20 int count; /* returns number of processes */
21 int i, j;
22 int seconds, minutes, secleft; /* for time[20] */
23 int milsec, shortmsec; /* for miliseconds of time[20] */
24 int ttynum;
25 long start;
26 char *ttydev;
27 static time_t now; /* for started[20] */
28 struct tm *tp; /* for month/day/hour/min/AM/PM fields of started[20] */
29 int SECSPERHOUR = 3600;
30 int SECSPERDAY = 24 * 3600;
31 pid_t sesid;
32 int length;
33 char cmndline[MAXARGLN+1];
34 char ** argv;
35
36 /* for bless_into_proc */
37 static char format[F_LASTFIELD + 2];
38
39 /* variables to hold some values for bless_into_proc */
40 char state[20];
41 char cputime[20];
42 char started[20];
43 char session[20];
44 char shortsess[20];
45
46 /* Open the kvm interface, get a descriptor */
47 if ((kd = kvm_open(NULL, NULL, NULL, 0, errbuf)) == NULL) {
48 /* fprintf(stderr, "kvm_open: %s\n", errbuf); */
49 ppt_croak("kvm_open: ", errbuf);
50 }
51
52 /* Get the list of processes. */
53 if ((procs = kvm_getprocs(kd, KERN_PROC_ALL, 0, &count)) == NULL) {
54 kvm_close(kd);
55 /* fprintf(stderr, "kvm_getprocs: %s\n", kvm_geterr(kd)); */
56 ppt_croak("kvm_getprocs: ", kvm_geterr(kd));
57 }
58
59 /* Iterate through the processes in kinfo_proc, sending proc info */
60 /* to bless_into_proc for each proc */
61 for (i=0; i < count; i++) {
62 static struct pstats ps;
63 static struct session seslead;
64 strcpy(format, Defaultformat);
65
66 /* get ttydev */
67 ttynum=procs[i].kp_eproc.e_tdev;
68 ttydev=devname(ttynum, S_IFCHR);
69 if (ttydev == NULL) ttydev = "??";
70
71 /* get the state of processes */
72 switch (procs[i].kp_proc.p_stat)
73 {
74 case SIDL:
75 strcpy(state, IDLE);
76 break;
77 case SRUN:
78 strcpy(state, RUN);
79 break;
80 case SSLEEP:
81 strcpy(state, SLEEP);
82 break;
83 case SSTOP:
84 strcpy(state, STOP);
85 break;
86 case SZOMB:
87 strcpy(state, ZOMBIE);
88 break;
89 default:
90 strcpy(state, UNKNOWN);
91 break;
92 }
93
94 /* get the cpu time of processes */
95 seconds=procs[i].kp_proc.p_rtime.tv_sec;
96 milsec=procs[i].kp_proc.p_rtime.tv_usec;
97 shortmsec=roundit(milsec);
98
99 if (seconds < 60) {
100 if (seconds < 10)
101 sprintf(cputime, "0:0%d.%d", seconds, shortmsec);
102 else
103 sprintf(cputime, "0:%d.%d", seconds, shortmsec);
104 }
105 else {
106 minutes=seconds/60;
107 secleft=seconds-(minutes * 60);
108 if (secleft < 10)
109 sprintf(cputime, "%d:0%d.%d", minutes, secleft, shortmsec);
110 else
111 sprintf(cputime, "%d:%d.%d", minutes, secleft, shortmsec);
112 }
113
114 /* get the start time of process (when started) */
115 /* fill the pstats struct using kvm_read */
116 if (kvm_read(kd, (u_long)procs[i].kp_proc.p_stats, (char *)&ps, sizeof(ps)) == sizeof(ps)) {
117 start=ps.p_start.tv_sec;
118 tp=localtime(&start);
119 if (!now)
120 (void)time(&now);
121 if (now - ps.p_start.tv_sec < 24 * SECSPERHOUR) {
122 static char fmt[] = __CONCAT("%l:%", "M%p");
123 (void)strftime(started, sizeof(started) - 1, fmt, tp);
124 }
125 else if (now - ps.p_start.tv_sec < 7 * SECSPERDAY) {
126 static char fmt[] = __CONCAT("%a%", "I%p");
127 (void)strftime(started, sizeof(started) - 1, fmt, tp);
128 }
129 else
130 (void)strftime(started, sizeof(started) - 1, "%e%b%y", tp);
131 }
132
133 /* get the session ID (ie: session pointer ID) */
134 sprintf(session, "%x", (u_long)procs[i].kp_eproc.e_sess);
135 length=strlen(session);
136 for (j=0; j < length; j++) {
137 if (session[1] == '1')
138 shortsess[j]=session[j+1];
139 else
140 shortsess[j]=session[j+2];
141 }
142
143 /* fill the session leader and proc struct using kvm_read */
144 if (kvm_read(kd, (u_long)procs[i].kp_eproc.e_sess, (char *)&seslead, sizeof(seslead)) == sizeof(seslead)) {
145 static struct proc leader;
146 if (kvm_read(kd, (u_long)seslead.s_leader, (char *)&leader, sizeof(leader)) == sizeof(leader)) {
147 sesid=leader.p_pid;
148 }
149 }
150
151 /* retrieve the arguments */
152 cmndline[0] = '\0';
153 argv = kvm_getargv(kd, (const struct kinfo_proc *) &(procs[i]) , 0);
154 if (argv) {
155 int j = 0;
156 while (argv[j] && strlen(cmndline)+strlen(argv[j])+1 <= MAXARGLN) {
157 strcat(cmndline, argv[j]);
158 if (argv[j+1]) {
159 strcat(cmndline, " ");
160 }
161 j++;
162 }
163 }
164
165 /* access everything else directly from the kernel, send it */
166 /* into bless_into_proc */
167 bless_into_proc( format,
168 Fields,
169 procs[i].kp_eproc.e_pcred.p_ruid,
170 procs[i].kp_eproc.e_pcred.p_rgid,
171 procs[i].kp_proc.p_pid,
172 procs[i].kp_eproc.e_ppid,
173 procs[i].kp_eproc.e_pgid,
174 procs[i].kp_proc.p_priority - PZERO,
175 shortsess,
176 sesid,
177 cputime,
178 procs[i].kp_eproc.e_wmesg,
179 procs[i].kp_proc.p_comm,
180 state,
181 started,
182 ttydev,
183 ttynum,
184 cmndline
185 );
186 }
187 if (kd) {
188 kvm_close(kd);
189 }
190 }
191
192
193
194
195
196