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