Commit | Line | Data |
---|---|---|
b4e2e355 KT |
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 | { "" }, | |
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 *strncmp(); | |
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/mem"; | |
110 | if(kflg) | |
111 | coref = "/usr/sys/core"; | |
112 | if ((mem = open(coref, 0)) < 0) { | |
113 | fprintf(stderr, "No mem\n"); | |
114 | exit(1); | |
115 | } | |
116 | swmem = open(coref, 0); | |
117 | /* | |
118 | * read mem to find swap dev. | |
119 | */ | |
120 | lseek(mem, (long)nl[1].n_value, 0); | |
121 | read(mem, (char *)&nl[1].n_value, sizeof(nl[1].n_value)); | |
122 | /* | |
123 | * Find base of swap | |
124 | */ | |
125 | lseek(mem, (long)nl[2].n_value, 0); | |
126 | read(mem, (char *)&swplo, sizeof(swplo)); | |
127 | /* | |
128 | * Locate proc table | |
129 | */ | |
130 | lseek(mem, (long)nl[0].n_value, 0); | |
131 | getdev(); | |
132 | uid = getuid(); | |
133 | if (lflg) | |
134 | printf(" F S UID PID PPID CPU PRI NICE ADDR SZ WCHAN TTY TIME CMD\n"); else | |
135 | if (chkpid==0) printf(" PID TTY TIME CMD\n"); | |
136 | for (i=0; i<NPROC; i++) { | |
137 | read(mem, (char *)&mproc, sizeof mproc); | |
138 | if (mproc.p_stat==0) | |
139 | continue; | |
140 | if (mproc.p_pgrp==0 && xflg==0 && mproc.p_uid==0) | |
141 | continue; | |
142 | puid = mproc.p_uid; | |
143 | if ((uid != puid && aflg==0) || | |
144 | (chkpid!=0 && chkpid!=mproc.p_pid)) | |
145 | continue; | |
146 | if(prcom(puid)) { | |
147 | printf("\n"); | |
148 | retcode=0; | |
149 | } | |
150 | } | |
151 | exit(retcode); | |
152 | } | |
153 | ||
154 | getdev() | |
155 | { | |
156 | #include <sys/stat.h> | |
157 | register FILE *df; | |
158 | struct stat sbuf; | |
159 | struct direct dbuf; | |
160 | ||
161 | if ((df = fopen("/dev", "r")) == NULL) { | |
162 | fprintf(stderr, "Can't open /dev\n"); | |
163 | exit(1); | |
164 | } | |
165 | ndev = 0; | |
166 | while (fread((char *)&dbuf, sizeof(dbuf), 1, df) == 1) { | |
167 | if(dbuf.d_ino == 0) | |
168 | continue; | |
169 | if(stat(dbuf.d_name, &sbuf) < 0) | |
170 | continue; | |
171 | if ((sbuf.st_mode&S_IFMT) != S_IFCHR) | |
172 | continue; | |
173 | strcpy(devl[ndev].dname, dbuf.d_name); | |
174 | devl[ndev].dev = sbuf.st_rdev; | |
175 | ndev++; | |
176 | } | |
177 | fclose(df); | |
178 | if ((swap = open("/dev/swap", 0)) < 0) { | |
179 | fprintf(stderr, "Can't open /dev/swap\n"); | |
180 | exit(1); | |
181 | } | |
182 | } | |
183 | ||
184 | long | |
185 | round(a, b) | |
186 | long a, b; | |
187 | { | |
188 | long w = ((a+b-1)/b)*b; | |
189 | ||
190 | return(w); | |
191 | } | |
192 | ||
193 | struct map { | |
194 | long b1, e1; long f1; | |
195 | long b2, e2; long f2; | |
196 | }; | |
197 | struct map datmap; | |
198 | int file; | |
199 | prcom(puid) | |
200 | { | |
201 | char abuf[512]; | |
202 | long addr; | |
203 | register int *ip; | |
204 | register char *cp, *cp1; | |
205 | long tm; | |
206 | int c, nbad; | |
207 | register char *tp; | |
208 | long txtsiz, datsiz, stksiz; | |
209 | int septxt; | |
210 | int lw=(lflg?35:80); | |
211 | char **ap; | |
212 | ||
213 | if (mproc.p_flag&SLOAD) { | |
214 | addr = ctob((long)mproc.p_addr); | |
215 | file = swmem; | |
216 | } else { | |
217 | addr = (mproc.p_addr+swplo)<<9; | |
218 | file = swap; | |
219 | } | |
220 | lseek(file, addr, 0); | |
221 | if (read(file, (char *)&u, sizeof(u)) != sizeof(u)) | |
222 | return(0); | |
223 | ||
224 | /* set up address maps for user pcs */ | |
225 | txtsiz = ctob(u.u_tsize); | |
226 | datsiz = ctob(u.u_dsize); | |
227 | stksiz = ctob(u.u_ssize); | |
228 | septxt = u.u_sep; | |
229 | datmap.b1 = (septxt ? 0 : round(txtsiz,TXTRNDSIZ)); | |
230 | datmap.e1 = datmap.b1+datsiz; | |
231 | datmap.f1 = ctob(USIZE)+addr; | |
232 | datmap.b2 = stackbas(stksiz); | |
233 | datmap.e2 = stacktop(stksiz); | |
234 | datmap.f2 = ctob(USIZE)+(datmap.e1-datmap.b1)+addr; | |
235 | ||
236 | tp = gettty(); | |
237 | if (tptr && strncmp(tptr, tp, 2)) | |
238 | return(0); | |
239 | if (lflg) { | |
240 | printf("%2o %c%4d", mproc.p_flag, | |
241 | "0SWRIZT"[mproc.p_stat], puid); | |
242 | } | |
243 | printf("%6u", mproc.p_pid); | |
244 | if (lflg) { | |
245 | printf("%6u%4d%4d%5d%6o%4d", mproc.p_ppid, mproc.p_cpu&0377, | |
246 | mproc.p_pri, | |
247 | mproc.p_nice, | |
248 | mproc.p_addr, (mproc.p_size+7)>>3); | |
249 | if (mproc.p_wchan) | |
250 | printf("%7o", mproc.p_wchan); | |
251 | else | |
252 | printf(" "); | |
253 | } | |
254 | printf(" %-2.2s", tp); | |
255 | if (mproc.p_stat==SZOMB) { | |
256 | printf(" <defunct>"); | |
257 | return(1); | |
258 | } | |
259 | tm = (u.u_utime + u.u_stime + 30)/60; | |
260 | printf(" %2ld:", tm/60); | |
261 | tm %= 60; | |
262 | printf(tm<10?"0%ld":"%ld", tm); | |
263 | if (vflg && lflg==0) { /* 0 == old tflg (print long times) */ | |
264 | tm = (u.u_cstime + 30)/60; | |
265 | printf(" %2ld:", tm/60); | |
266 | tm %= 60; | |
267 | printf(tm<10?"0%ld":"%ld", tm); | |
268 | tm = (u.u_cutime + 30)/60; | |
269 | printf(" %2ld:", tm/60); | |
270 | tm %= 60; | |
271 | printf(tm<10?"0%ld":"%ld", tm); | |
272 | } | |
273 | if (mproc.p_pid == 0) { | |
274 | printf(" swapper"); | |
275 | return(1); | |
276 | } | |
277 | addr += ctob((long)mproc.p_size) - 512; | |
278 | ||
279 | /* look for sh special */ | |
280 | lseek(file, addr+512-sizeof(char **), 0); | |
281 | if (read(file, (char *)&ap, sizeof(char *)) != sizeof(char *)) | |
282 | return(1); | |
283 | if (ap) { | |
284 | char b[82]; | |
285 | char *bp = b; | |
286 | while((cp=getptr(ap++)) && cp && (bp<b+lw) ) { | |
287 | nbad = 0; | |
288 | while((c=getbyte(cp++)) && (bp<b+lw)) { | |
289 | if (c<' ' || c>'~') { | |
290 | if (nbad++>3) | |
291 | break; | |
292 | continue; | |
293 | } | |
294 | *bp++ = c; | |
295 | } | |
296 | *bp++ = ' '; | |
297 | } | |
298 | *bp++ = 0; | |
299 | printf(lflg?" %.30s":" %.60s", b); | |
300 | return(1); | |
301 | } | |
302 | ||
303 | lseek(file, addr, 0); | |
304 | if (read(file, abuf, sizeof(abuf)) != sizeof(abuf)) | |
305 | return(1); | |
306 | for (ip = (int *)&abuf[512]-2; ip > (int *)abuf; ) { | |
307 | if (*--ip == -1 || *ip==0) { | |
308 | cp = (char *)(ip+1); | |
309 | if (*cp==0) | |
310 | cp++; | |
311 | nbad = 0; | |
312 | for (cp1 = cp; cp1 < &abuf[512]; cp1++) { | |
313 | c = *cp1&0177; | |
314 | if (c==0) | |
315 | *cp1 = ' '; | |
316 | else if (c < ' ' || c > 0176) { | |
317 | if (++nbad >= 5) { | |
318 | *cp1++ = ' '; | |
319 | break; | |
320 | } | |
321 | *cp1 = '?'; | |
322 | } else if (c=='=') { | |
323 | *cp1 = 0; | |
324 | while (cp1>cp && *--cp1!=' ') | |
325 | *cp1 = 0; | |
326 | break; | |
327 | } | |
328 | } | |
329 | while (*--cp1==' ') | |
330 | *cp1 = 0; | |
331 | printf(lflg?" %.30s":" %.60s", cp); | |
332 | return(1); | |
333 | } | |
334 | } | |
335 | return(1); | |
336 | } | |
337 | ||
338 | char * | |
339 | gettty() | |
340 | { | |
341 | register i; | |
342 | register char *p; | |
343 | ||
344 | if (u.u_ttyp==0) | |
345 | return("?"); | |
346 | for (i=0; i<ndev; i++) { | |
347 | if (devl[i].dev == u.u_ttyd) { | |
348 | p = devl[i].dname; | |
349 | if (p[0]=='t' && p[1]=='t' && p[2]=='y') | |
350 | p += 3; | |
351 | return(p); | |
352 | } | |
353 | } | |
354 | return("?"); | |
355 | } | |
356 | ||
357 | char * | |
358 | getptr(adr) | |
359 | char **adr; | |
360 | { | |
361 | char *ptr; | |
362 | register char *p, *pa; | |
363 | register i; | |
364 | ||
365 | ptr = 0; | |
366 | pa = (char *)adr; | |
367 | p = (char *)&ptr; | |
368 | for (i=0; i<sizeof(ptr); i++) | |
369 | *p++ = getbyte(pa++); | |
370 | return(ptr); | |
371 | } | |
372 | ||
373 | getbyte(adr) | |
374 | char *adr; | |
375 | { | |
376 | register struct map *amap = &datmap; | |
377 | char b; | |
378 | long saddr; | |
379 | ||
380 | if(!within(adr, amap->b1, amap->e1)) { | |
381 | if(within(adr, amap->b2, amap->e2)) { | |
382 | saddr = (unsigned)adr + amap->f2 - amap->b2; | |
383 | } else | |
384 | return(0); | |
385 | } else | |
386 | saddr = (unsigned)adr + amap->f1 - amap->b1; | |
387 | if(lseek(file, saddr, 0)==-1 | |
388 | || read(file, &b, 1)<1) { | |
389 | return(0); | |
390 | } | |
391 | return((unsigned)b); | |
392 | } | |
393 | ||
394 | ||
395 | within(adr,lbd,ubd) | |
396 | char *adr; | |
397 | long lbd, ubd; | |
398 | { | |
399 | return((unsigned)adr>=lbd && (unsigned)adr<ubd); | |
400 | } |