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: }