Commit | Line | Data |
---|---|---|
b5fdd46b TL |
1 | /* |
2 | * ps - process status | |
3 | * examine and print certain things about processes | |
4 | */ | |
5 | ||
6 | #include <stdio.h> | |
7 | #include <a.out.h> | |
8 | #include <core.h> | |
9 | #include <sys/param.h> | |
10 | #include <sys/proc.h> | |
11 | #include <sys/tty.h> | |
12 | #include <sys/dir.h> | |
13 | #include <sys/user.h> | |
14 | ||
15 | struct nlist nl[] = { | |
16 | { "_proc" }, | |
17 | { "_swapdev" }, | |
18 | { "_swplo" }, | |
19 | { 0 }, | |
20 | }; | |
21 | ||
22 | struct proc mproc; | |
23 | ||
24 | struct user u; | |
25 | int chkpid; | |
26 | int retcode=1; | |
27 | int lflg; | |
28 | int vflg; | |
29 | int kflg; | |
30 | int xflg; | |
31 | char *tptr; | |
32 | long lseek(); | |
33 | char *gettty(); | |
34 | char *getptr(); | |
35 | char *strcmpn(); | |
36 | int aflg; | |
37 | int mem; | |
38 | int swmem; | |
39 | int swap; | |
40 | daddr_t swplo; | |
41 | ||
42 | int ndev; | |
43 | struct devl { | |
44 | char dname[DIRSIZ]; | |
45 | dev_t dev; | |
46 | } devl[256]; | |
47 | ||
48 | char *coref; | |
49 | ||
50 | main(argc, argv) | |
51 | char **argv; | |
52 | { | |
53 | int i; | |
54 | char *ap; | |
55 | int uid, puid; | |
56 | ||
57 | if (argc>1) { | |
58 | ap = argv[1]; | |
59 | while (*ap) switch (*ap++) { | |
60 | ||
61 | case 'v': | |
62 | vflg++; | |
63 | break; | |
64 | ||
65 | case 'a': | |
66 | aflg++; | |
67 | break; | |
68 | ||
69 | case 't': | |
70 | if(*ap) | |
71 | tptr = ap; | |
72 | aflg++; | |
73 | if (*tptr == '?') | |
74 | xflg++; | |
75 | goto bbreak; | |
76 | ||
77 | case 'x': | |
78 | xflg++; | |
79 | break; | |
80 | ||
81 | case '-': | |
82 | break; | |
83 | ||
84 | case 'l': | |
85 | lflg++; | |
86 | break; | |
87 | ||
88 | case 'k': | |
89 | kflg++; | |
90 | break; | |
91 | ||
92 | default: | |
93 | chkpid = atoi(ap-1); | |
94 | goto bbreak; | |
95 | break; | |
96 | } | |
97 | } | |
98 | ||
99 | bbreak: | |
100 | if(chdir("/dev") < 0) { | |
101 | fprintf(stderr, "Can't change to /dev\n"); | |
102 | exit(1); | |
103 | } | |
104 | nlist(argc>2? argv[2]:"/unix", nl); | |
105 | if (nl[0].n_type==0) { | |
106 | fprintf(stderr, "No namelist\n"); | |
107 | exit(1); | |
108 | } | |
109 | coref = "/dev/kmem"; | |
110 | if(kflg) | |
111 | coref = "/usr/sys/core"; | |
112 | if ((mem = open(coref, 0)) < 0) { | |
113 | fprintf(stderr, "No kmem\n"); | |
114 | exit(1); | |
115 | } | |
116 | if ((swmem = open("/dev/mem", 0)) < 0) { | |
117 | fprintf(stderr, "No mem\n"); | |
118 | exit(1); | |
119 | } | |
120 | /* | |
121 | * read mem to find swap dev. | |
122 | */ | |
123 | lseek(mem, (long)nl[1].n_value, 0); | |
124 | read(mem, (char *)&nl[1].n_value, sizeof(nl[1].n_value)); | |
125 | /* | |
126 | * Find base of swap | |
127 | */ | |
128 | lseek(mem, (long)nl[2].n_value, 0); | |
129 | read(mem, (char *)&swplo, sizeof(swplo)); | |
130 | /* | |
131 | * Locate proc table | |
132 | */ | |
133 | lseek(mem, (long)nl[0].n_value, 0); | |
134 | getdev(); | |
135 | uid = getuid(); | |
136 | if (lflg) | |
137 | printf(" F S UID PID PPID CPU PRI NICE ADDR SZ WCHAN TTY TIME CMD\n"); else | |
138 | if (chkpid==0) printf(" PID TTY TIME CMD\n"); | |
139 | for (i=0; i<NPROC; i++) { | |
140 | read(mem, (char *)&mproc, sizeof mproc); | |
141 | if (mproc.p_stat==0) | |
142 | continue; | |
143 | if (mproc.p_pgrp==0 && xflg==0 && mproc.p_uid==0) | |
144 | continue; | |
145 | puid = mproc.p_uid; | |
146 | if ((uid != puid && aflg==0) || | |
147 | (chkpid!=0 && chkpid!=mproc.p_pid)) | |
148 | continue; | |
149 | if(prcom(puid)) { | |
150 | printf("\n"); | |
151 | retcode=0; | |
152 | } | |
153 | } | |
154 | exit(retcode); | |
155 | } | |
156 | ||
157 | getdev() | |
158 | { | |
159 | #include <sys/stat.h> | |
160 | register FILE *df; | |
161 | struct stat sbuf; | |
162 | struct direct dbuf; | |
163 | ||
164 | if ((df = fopen("/dev", "r")) == NULL) { | |
165 | fprintf(stderr, "Can't open /dev\n"); | |
166 | exit(1); | |
167 | } | |
168 | ndev = 0; | |
169 | while (fread((char *)&dbuf, sizeof(dbuf), 1, df) == 1) { | |
170 | if(dbuf.d_ino == 0) | |
171 | continue; | |
172 | if(stat(dbuf.d_name, &sbuf) < 0) | |
173 | continue; | |
174 | if ((sbuf.st_mode&S_IFMT) != S_IFCHR) | |
175 | continue; | |
176 | strcpy(devl[ndev].dname, dbuf.d_name); | |
177 | devl[ndev].dev = sbuf.st_rdev; | |
178 | ndev++; | |
179 | } | |
180 | fclose(df); | |
181 | if ((swap = open("/dev/swap", 0)) < 0) { | |
182 | fprintf(stderr, "Can't open /dev/swap\n"); | |
183 | exit(1); | |
184 | } | |
185 | } | |
186 | ||
187 | long | |
188 | round(a, b) | |
189 | long a, b; | |
190 | { | |
191 | long w = ((a+b-1)/b)*b; | |
192 | ||
193 | return(w); | |
194 | } | |
195 | ||
196 | struct map { | |
197 | long b1, e1; long f1; | |
198 | long b2, e2; long f2; | |
199 | }; | |
200 | struct map datmap; | |
201 | int file; | |
202 | prcom(puid) | |
203 | { | |
204 | char abuf[512]; | |
205 | long addr; | |
206 | register int *ip; | |
207 | register char *cp, *cp1; | |
208 | long tm; | |
209 | int c, nbad; | |
210 | register char *tp; | |
211 | long txtsiz, datsiz, stksiz; | |
212 | int lw=(lflg?35:80); | |
213 | char **ap; | |
214 | ||
215 | if (mproc.p_flag&SLOAD) { | |
216 | addr = ctob((long)mproc.p_addr); | |
217 | file = swmem; | |
218 | } else { | |
219 | addr = (mproc.p_addr+swplo)<<9; | |
220 | file = swap; | |
221 | } | |
222 | lseek(file, addr, 0); | |
223 | if (read(file, (char *)&u, sizeof(u)) != sizeof(u)) | |
224 | return(0); | |
225 | ||
226 | /* set up address maps for user pcs */ | |
227 | txtsiz = ctob(u.u_tsize); | |
228 | datsiz = ctob(u.u_dsize); | |
229 | stksiz = ctob(u.u_ssize); | |
230 | datmap.b1 = round(txtsiz,TXTRNDSIZ); | |
231 | datmap.e1 = datmap.b1+datsiz; | |
232 | datmap.f1 = ctob(USIZE)+addr; | |
233 | datmap.b2 = stackbas(stksiz); | |
234 | datmap.e2 = stacktop(stksiz); | |
235 | datmap.f2 = ctob(USIZE)+(datmap.e1-datmap.b1)+addr; | |
236 | ||
237 | tp = gettty(); | |
238 | if (tptr && strcmpn(tptr, tp, 2)) | |
239 | return(0); | |
240 | if (lflg) { | |
241 | printf("%2o %c%4d", mproc.p_flag, | |
242 | "0SWRIZT"[mproc.p_stat], puid); | |
243 | } | |
244 | printf("%6u", mproc.p_pid); | |
245 | if (lflg) { | |
246 | printf("%6u%4d%4d%5d%6x%4d", mproc.p_ppid, mproc.p_cpu&0377, | |
247 | mproc.p_pri, | |
248 | mproc.p_nice, | |
249 | mproc.p_addr, mproc.p_size); | |
250 | if (mproc.p_wchan) | |
251 | printf("%9x", mproc.p_wchan); | |
252 | else | |
253 | printf(" "); | |
254 | } | |
255 | printf(" %-2.2s", tp); | |
256 | if (mproc.p_stat==SZOMB) { | |
257 | printf(" <defunct>"); | |
258 | return(1); | |
259 | } | |
260 | tm = (u.u_utime + u.u_stime + 30)/60; | |
261 | printf(" %2ld:", tm/60); | |
262 | tm %= 60; | |
263 | printf(tm<10?"0%ld":"%ld", tm); | |
264 | if (vflg && lflg==0) { /* 0 == old tflg (print long times) */ | |
265 | tm = (u.u_cstime + 30)/60; | |
266 | printf(" %2ld:", tm/60); | |
267 | tm %= 60; | |
268 | printf(tm<10?"0%ld":"%ld", tm); | |
269 | tm = (u.u_cutime + 30)/60; | |
270 | printf(" %2ld:", tm/60); | |
271 | tm %= 60; | |
272 | printf(tm<10?"0%ld":"%ld", tm); | |
273 | } | |
274 | if (mproc.p_pid == 0) { | |
275 | printf(" swapper"); | |
276 | return(1); | |
277 | } | |
278 | addr += ctob((long)mproc.p_size) - 512; | |
279 | ||
280 | /* look for sh special */ | |
281 | lseek(file, addr+512-sizeof(char **), 0); | |
282 | if (read(file, (char *)&ap, sizeof(char *)) != sizeof(char *)) | |
283 | return(1); | |
284 | if (ap) { | |
285 | char b[82]; | |
286 | char *bp = b; | |
287 | while((cp=getptr(ap++)) && cp && (bp<b+lw) ) { | |
288 | nbad = 0; | |
289 | while((c=getbyte(cp++)) && (bp<b+lw)) { | |
290 | if (c<' ' || c>'~') { | |
291 | if (nbad++>3) | |
292 | break; | |
293 | continue; | |
294 | } | |
295 | *bp++ = c; | |
296 | } | |
297 | *bp++ = ' '; | |
298 | } | |
299 | *bp++ = 0; | |
300 | printf(lflg?" %.30s":" %.60s", b); | |
301 | return(1); | |
302 | } | |
303 | ||
304 | lseek(file, addr, 0); | |
305 | if (read(file, abuf, sizeof(abuf)) != sizeof(abuf)) | |
306 | return(1); | |
307 | for (ip = (int *)&abuf[512]-2; ip > (int *)abuf; ) { | |
308 | if (*--ip == -1 || *ip==0) { | |
309 | cp = (char *)(ip+1); | |
310 | if (*cp==0) | |
311 | cp++; | |
312 | nbad = 0; | |
313 | for (cp1 = cp; cp1 < &abuf[512]; cp1++) { | |
314 | c = *cp1&0177; | |
315 | if (c==0) | |
316 | *cp1 = ' '; | |
317 | else if (c < ' ' || c > 0176) { | |
318 | if (++nbad >= 5) { | |
319 | *cp1++ = ' '; | |
320 | break; | |
321 | } | |
322 | *cp1 = '?'; | |
323 | } else if (c=='=') { | |
324 | *cp1 = 0; | |
325 | while (cp1>cp && *--cp1!=' ') | |
326 | *cp1 = 0; | |
327 | break; | |
328 | } | |
329 | } | |
330 | while (*--cp1==' ') | |
331 | *cp1 = 0; | |
332 | printf(lflg?" %.30s":" %.60s", cp); | |
333 | return(1); | |
334 | } | |
335 | } | |
336 | return(1); | |
337 | } | |
338 | ||
339 | char * | |
340 | gettty() | |
341 | { | |
342 | register i; | |
343 | register char *p; | |
344 | ||
345 | if (u.u_ttyp==0) | |
346 | return("?"); | |
347 | for (i=0; i<ndev; i++) { | |
348 | if (devl[i].dev == u.u_ttyd) { | |
349 | p = devl[i].dname; | |
350 | if (p[0]=='t' && p[1]=='t' && p[2]=='y') | |
351 | p += 3; | |
352 | return(p); | |
353 | } | |
354 | } | |
355 | return("?"); | |
356 | } | |
357 | ||
358 | char * | |
359 | getptr(adr) | |
360 | char **adr; | |
361 | { | |
362 | char *ptr; | |
363 | register char *p, *pa; | |
364 | register i; | |
365 | ||
366 | ptr = 0; | |
367 | pa = (char *)adr; | |
368 | p = (char *)&ptr; | |
369 | for (i=0; i<sizeof(ptr); i++) | |
370 | *p++ = getbyte(pa++); | |
371 | return(ptr); | |
372 | } | |
373 | ||
374 | getbyte(adr) | |
375 | char *adr; | |
376 | { | |
377 | register struct map *amap = &datmap; | |
378 | char b; | |
379 | long saddr; | |
380 | ||
381 | if(!within(adr, amap->b1, amap->e1)) { | |
382 | if(within(adr, amap->b2, amap->e2)) { | |
383 | saddr = (unsigned)adr + amap->f2 - amap->b2; | |
384 | } else | |
385 | return(0); | |
386 | } else | |
387 | saddr = (unsigned)adr + amap->f1 - amap->b1; | |
388 | if(lseek(file, saddr, 0)==-1 | |
389 | || read(file, &b, 1)<1) { | |
390 | return(0); | |
391 | } | |
392 | return((unsigned)b); | |
393 | } | |
394 | ||
395 | ||
396 | within(adr,lbd,ubd) | |
397 | char *adr; | |
398 | long lbd, ubd; | |
399 | { | |
400 | return((unsigned)adr>=lbd && (unsigned)adr<ubd); | |
401 | } |