|
|
1.1 root 1: /*
2: * ps; VAX 4BSD version
3: */
4:
5: #include <stdio.h>
6: #include <ctype.h>
7: #include <nlist.h>
8: #include <pwd.h>
9: #include <sys/param.h>
10: #include <sys/tty.h>
11: #include <sys/dir.h>
12: #include <sys/user.h>
13: #include <sys/proc.h>
14: #include <sys/pte.h>
15: #include <sys/vm.h>
16: #include <sys/text.h>
17: #include <sys/stat.h>
18: #include <math.h>
19: #include <sys/vlimit.h>
20: #include <sys/inode.h>
21: #include <sys/file.h>
22:
23: #define vprintf if (vflg) printf
24: #define WD -1
25: #define TEXT -2
26:
27: int pcbpf, nswap, kmem, mem, swap, uid, pid;
28: int uflg, fflg, inum, Mdev, mdev, special, vflg, nproc, pflg;
29: char *uname;
30:
31: struct nlist nl[] = {
32: { "_proc" },
33: #define X_PROC 0
34: { "_Usrptmap" },
35: #define X_USRPTMA 1
36: { "_usrpt" },
37: #define X_USRPT 2
38: { "_nswap" },
39: #define X_NSWAP 3
40: { "_nproc" },
41: #define X_NPROC 4
42: { 0 },
43: };
44:
45: struct proc proc[8], *mproc; /* 8 = a few, for less syscalls */
46: struct pte *Usrptma, *usrpt;
47:
48: int paduser1; /* avoid hardware mem clobbering botch */
49: union {
50: struct user user;
51: char upages[UPAGES][NBPG];
52: } user;
53: int paduser2; /* avoid hardware mem clobbering botch */
54: #define u user.user
55:
56: char *kmemf, *memf, *swapf, *nlistf;
57:
58: extern int errno;
59:
60: main(argc, argv)
61: char **argv;
62: {
63: register int i, j;
64: off_t procp;
65: dev_t dev;
66:
67: argv++;
68: while (--argc > 0) {
69: if (strcmp(*argv, "-v") == 0) {
70: vflg++;
71: argv++;
72: continue;
73: }
74: if (strcmp(*argv, "-u") == 0) {
75: if (uflg++)
76: usage();
77: if ((uid = getuname(*(++argv))) < 0) {
78: fprintf(stderr, "%s: unknown user\n", *argv);
79: exit(1);
80: }
81: --argc;
82: argv++;
83: continue;
84: }
85: if (strcmp(*argv, "-f") == 0) {
86: if (fflg++)
87: usage();
88: if ((dev = getfname(*(++argv))) < 0) {
89: perror(*argv);
90: exit(1);
91: }
92: --argc;
93: argv++;
94: continue;
95: }
96:
97: if (strcmp(*argv, "-p") == 0) {
98: if (pflg++ || ((pid = Atoi(*(++argv))) <= 0)) {
99: usage();
100: perror(*argv);
101: exit(1);
102: }
103: --argc;
104: argv++;
105: continue;
106: }
107:
108: /* admit missing -u, -f, -p */
109: /* it's an expert system! */
110: if ((pid = Atoi(*argv)) > 0) {
111: if (pflg++)
112: usage();
113: continue;
114: }
115: if (fflg && uflg)
116: usage();
117: if (uflg) {
118: /* it must be a file */
119: fflg++;
120: if ((dev = getfname(*argv)) < 0) {
121: perror(*argv);
122: exit(1);
123: }
124: argv++;
125: continue;
126: }
127: if (fflg) {
128: /* it must be a user */
129: uflg++;
130: if ((uid = getuname(*argv)) < 0) {
131: fprintf(stderr,
132: "%s: unknown user\n", *argv);
133: exit(1);
134: }
135: argv++;
136: continue;
137: }
138: /* !uflg && !fflg -- which is it? */
139: if ((dev = getfname(*argv)) >= 0)
140: fflg++; /* could be a file */
141: if ((uid = getuname(*argv)) >= 0)
142: uflg++; /* could be a user */
143: if ((!uflg ^ !fflg) == 0)
144: usage(); /* could be either/neither */
145: argv++;
146: continue;
147: }
148:
149: if (fflg) {
150: Mdev = major(dev);
151: mdev = minor(dev);
152: }
153:
154: if (chdir("/dev") < 0) {
155: perror("/dev");
156: exit(1);
157: }
158:
159: printf("user\t\t pid\t fd major minor\tinode\n");
160: openfiles();
161: getkvars();
162: procp = getw((off_t) nl[X_PROC].n_value);
163: nproc = getw((off_t) nl[X_NPROC].n_value);
164: for (i=0; i<nproc; i += 8) {
165: lseek(kmem, (long) procp, 0);
166: j = nproc - i;
167: if (j > 8)
168: j = 8;
169: j *= sizeof (struct proc);
170: if (read(kmem, (char *) proc, j) != j)
171: cantread("proc table", kmemf);
172: procp += j;
173: for (j = j / sizeof (struct proc) - 1; j >= 0; j--) {
174: mproc = &proc[j];
175: if (mproc->p_stat == 0)
176: continue;
177: doproc();
178: }
179: }
180: exit(0);
181: }
182:
183: long
184: getw(loc)
185: off_t loc;
186: {
187: long word;
188:
189: lseek(kmem, (long) loc, 0);
190: if (read(kmem, (char *) &word, sizeof (word)) != sizeof (word))
191: vprintf("error reading kmem at %x\n", loc);
192: return (word);
193: }
194:
195: openfiles()
196: {
197:
198: kmemf = "kmem";
199: kmem = open(kmemf, 0);
200: if (kmem < 0) {
201: perror(kmemf);
202: exit(1);
203: }
204: memf = "mem";
205: mem = open(memf, 0);
206: if (mem < 0) {
207: perror(memf);
208: exit(1);
209: }
210: swapf = "drum";
211: swap = open(swapf, 0);
212: if (swap < 0) {
213: perror(swapf);
214: exit(1);
215: }
216: }
217:
218: getkvars()
219: {
220: nlistf = "/unix";
221: nlist(nlistf, nl);
222: if (nl[0].n_type == 0) {
223: fprintf(stderr, "%s: No namelist\n", nlistf);
224: exit(1);
225: }
226: Usrptma = (struct pte *) nl[X_USRPTMA].n_value;
227: usrpt = (struct pte *) nl[X_USRPT].n_value;
228: lseek(kmem, (long) nl[X_NSWAP].n_value, 0);
229: if (read(kmem, (char *) &nswap, sizeof (nswap)) != sizeof (nswap)) {
230: cantread("nswap", kmemf);
231: exit(1);
232: }
233: }
234:
235: cantread(what, fromwhat)
236: char *what, *fromwhat;
237: {
238:
239: vprintf("fstat: error reading %s from %s", what, fromwhat);
240: }
241:
242: doproc()
243: {
244: struct passwd *getpwuid();
245:
246: if (uflg && mproc->p_uid != uid)
247: return;
248: if (pflg && mproc->p_pid != pid)
249: return;
250: if (mproc->p_stat != SZOMB && getu() == 0)
251: return;
252: uname = getpwuid(u.u_uid)->pw_name;
253: dotext();
254: getf();
255: }
256:
257: getu()
258: {
259: struct pte *pteaddr, apte;
260: int pad1; /* avoid hardware botch */
261: struct pte arguutl[UPAGES+CLSIZE];
262: int pad2; /* avoid hardware botch */
263: register int i;
264: int ncl, size, argaddr;
265:
266: size = sizeof (struct user);
267: if ((mproc->p_flag & SLOAD) == 0) {
268: lseek(swap, (long) ctob(mproc->p_swaddr), 0);
269: if (read(swap, (char *) &user.user, size) != size) {
270: vprintf("fstat: cant read u for pid %d from %s\n",
271: mproc->p_pid, swapf);
272: return (0);
273: }
274: pcbpf = 0;
275: argaddr = 0;
276: return (1);
277: }
278: pteaddr = &Usrptma[btokmx(mproc->p_p0br) + mproc->p_szpt - 1];
279: lseek(kmem, (long) pteaddr, 0);
280: if (read(kmem, (char *) &apte, sizeof(apte)) != sizeof(apte)) {
281: vprintf("fstat: can't read indir pte to get u for pid %d from %s\n",
282: mproc->p_pid, swapf);
283: return (0);
284: }
285: lseek(mem,
286: (long) ctob(apte.pg_pfnum+1) - (UPAGES+CLSIZE) * sizeof (struct pte), 0);
287: if (read(mem, (char *) arguutl, sizeof(arguutl)) != sizeof(arguutl)) {
288: vprintf("fstat: can't read page table for u of pid %d from %s\n",
289: mproc->p_pid, swapf);
290: return (0);
291: }
292: if (arguutl[0].pg_fod == 0 && arguutl[0].pg_pfnum)
293: argaddr = ctob(arguutl[0].pg_pfnum);
294: else
295: argaddr = 0;
296: pcbpf = arguutl[CLSIZE].pg_pfnum;
297: ncl = (size + NBPG*CLSIZE - 1) / (NBPG*CLSIZE);
298: while (--ncl >= 0) {
299: i = ncl * CLSIZE;
300: lseek(mem, (long) ctob(arguutl[CLSIZE+i].pg_pfnum), 0);
301: if (read(mem, user.upages[i], CLSIZE*NBPG) != CLSIZE*NBPG) {
302: vprintf("fstat: can't read page %d of u of pid %d from %s\n",
303: arguutl[CLSIZE+i].pg_pfnum, mproc->p_pid, memf);
304: return(0);
305: }
306: }
307: return (1);
308: }
309:
310: #define NMAX 8
311: #define NUID 2048
312:
313: dotext()
314: {
315: struct text text;
316:
317: lseek(kmem, (long) mproc->p_textp, 0);
318: if (read(kmem, (char *) &text, sizeof(text)) != sizeof(text)) {
319: cantread("text table", kmemf);
320: return;
321: }
322: if (text.x_flag == 0)
323: return;
324: itrans(text.x_iptr, TEXT);
325: }
326:
327: itrans(i, fno)
328: struct inode *i;
329: {
330: struct inode inode;
331: dev_t idev;
332:
333: lseek(kmem, (long) i, 0);
334: if (read(kmem, (char *) &inode, sizeof(inode))
335: != sizeof(inode)) {
336: vprintf("error %d reading inode at %x from kmem\n", errno, i);
337: return;
338: }
339: if (special)
340: idev = inode.i_dev;
341: else
342: idev = inode.i_dev;
343: if (fflg && major(idev) != Mdev)
344: return;
345: if (fflg && minor(idev) != mdev)
346: return;
347: if (inum && inode.i_number != inum)
348: return;
349: printf("%-16s%5d\t", uname, mproc->p_pid);
350: if (fno == WD)
351: printf(" wd");
352: else if (fno == TEXT)
353: printf("text");
354: else
355: printf("%4d", fno);
356: printf("\t%2d\t%2d\t%5d\n", major(inode.i_dev), minor(inode.i_dev),
357: inode.i_number);
358: }
359:
360: getf()
361: {
362: int i;
363: struct file file;
364:
365: itrans(u.u_cdir, WD);
366: for (i = 0; i < NOFILE; i++) {
367: if (u.u_ofile[i] == 0)
368: continue;
369: lseek(kmem, (long) u.u_ofile[i], 0);
370: if (read(kmem, (char *) &file, sizeof(file)) != sizeof(file)) {
371: cantread("file", kmemf);
372: continue;
373: }
374: itrans(file.f_inode, i);
375: }
376: }
377:
378: usage()
379: {
380: fputs("usage: fstat [-u user] [-f filename] [-p pid]\n", stderr);
381: exit(1);
382: }
383:
384: getuname(uname)
385: char *uname;
386: {
387: struct passwd *passwd, *getpwnam();
388:
389: if ((passwd = getpwnam(uname)) == NULL)
390: return(-1);
391: return(passwd->pw_uid);
392: }
393:
394: getfname(filename)
395: char *filename;
396: {
397: struct stat statbuf;
398:
399: if (stat(filename, &statbuf) != 0)
400: return(-1);
401:
402: /*
403: * if file is block special, look for open files on it
404: */
405: if ((statbuf.st_mode & S_IFMT) != S_IFBLK) {
406: inum = statbuf.st_ino;
407: return(statbuf.st_dev);
408: } else {
409: special++;
410: inum = 0;
411: return(statbuf.st_rdev);
412: }
413: }
414:
415: Atoi(p)
416: register char *p;
417: {
418: register int n = 0;
419:
420: while(*p >= '0' && *p <= '9')
421: n = n*10 + *p++ - '0';
422: return(*p ? -n : n);
423: }
424: /* @(#)getpwent.c 4.1 (Berkeley) 12/21/80 */
425:
426: static char PASSWD[] = "/etc/passwd";
427: static char EMPTY[] = "";
428: static FILE *pwf = NULL;
429: static char line[BUFSIZ+1];
430: static struct passwd passwd;
431:
432: setpwent()
433: {
434: if( pwf == NULL )
435: pwf = fopen( PASSWD, "r" );
436: else
437: rewind( pwf );
438: }
439:
440: endpwent()
441: {
442: if( pwf != NULL ){
443: fclose( pwf );
444: pwf = NULL;
445: }
446: }
447:
448: static char *
449: pwskip(p)
450: register char *p;
451: {
452: while( *p && *p != ':' )
453: ++p;
454: if( *p ) *p++ = 0;
455: return(p);
456: }
457:
458: struct passwd *
459: getpwent()
460: {
461: register char *p;
462:
463: if (pwf == NULL) {
464: if( (pwf = fopen( PASSWD, "r" )) == NULL )
465: return(0);
466: }
467: p = fgets(line, BUFSIZ, pwf);
468: if (p==NULL)
469: return(0);
470: passwd.pw_name = p;
471: p = pwskip(p);
472: passwd.pw_passwd = p;
473: p = pwskip(p);
474: passwd.pw_uid = atoi(p);
475: p = pwskip(p);
476: passwd.pw_gid = atoi(p);
477: passwd.pw_quota = 0;
478: passwd.pw_comment = EMPTY;
479: p = pwskip(p);
480: passwd.pw_gecos = p;
481: p = pwskip(p);
482: passwd.pw_dir = p;
483: p = pwskip(p);
484: passwd.pw_shell = p;
485: while(*p && *p != '\n') p++;
486: *p = '\0';
487: return(&passwd);
488: }
489: /* @(#)getpwuid.c 4.1 (Berkeley) 12/21/80 */
490:
491: struct passwd *
492: getpwuid(uid)
493: register uid;
494: {
495: register struct passwd *p;
496: struct passwd *getpwent();
497:
498: setpwent();
499: while( (p = getpwent()) && p->pw_uid != uid );
500: endpwent();
501: return(p);
502: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.