|
|
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.