pdp11v/usr/src/cmd/ps.c
/* @(#)ps.c 1.6 */
/*
* ps - process status
* examine and print certain things about processes
*/
#include <stdio.h>
#include <fcntl.h>
#include "sys/types.h"
#ifdef u3b
#include "sys/page.h"
#include "sys/istk.h"
#include "sys/ssr.h"
#include "sys/seg.h"
#endif
#include "a.out.h"
#include "pwd.h"
#include "sys/param.h"
#ifdef u3b
#include "sys/macro.h"
#else
#include "sys/sysmacros.h"
#endif
#include "sys/proc.h"
#include "sys/tty.h"
#include "sys/dir.h"
#include "sys/signal.h"
#include "sys/stat.h"
#include "sys/user.h"
#include "sys/var.h"
#include "core.h"
#define NTTYS 20
#define SIZ 30
#define TSIZE 100
#define ARGSIZ 30
#ifndef MAXLOGIN
#define MAXLOGIN 8
#endif
/* Structure for storing user info */
struct udata {
unsigned short uid; /* numeric user id */
char name[MAXLOGIN]; /* character user id, may not be null terminated */
};
/* udata granularity for structure allocation */
#define UDQ 50
/* Pointer to user data */
struct udata *ud;
int nud = 0; /* number of valid ud structures */
int maxud = 0; /* number of ud's allocated */
struct udata uid_tbl[SIZ]; /* table to store selected uid's */
int nut = 0; /* counter for uid_tbl */
struct nlist nl[] = {
#ifdef u3b
"proc", (long)0, (short)0, (unsigned short)0, (char)0, (char)0,
"swaplow", (long)0, (short)0, (unsigned short)0, (char)0, (char)0,
"v", (long)0, (short)0, (unsigned short)0, (char)0, (char)0,
"_sbrpte", (long)0, (short)0, (unsigned short)0, (char)0, (char)0,
0, (long)0, (short)0, (unsigned short)0, (char)0, (char)0
#else
{ "_proc" },
{ "_swplo" },
{ "_v" },
{ "_sbrpte" },
{ 0 },
#endif
};
#ifndef u3b
union {
struct proc mprc;
struct xproc zprc;
} prc;
#define mproc prc.mprc
#define zproc prc.zprc
#else /* u3b */
struct proc prc;
#define mproc prc
#define zproc prc
int procaddr;
#endif /* u3b */
struct var v;
#ifndef u3b
int sbrpte;
int upte[128];
int spte;
#endif
#if pdp11 || u3b
struct user u;
#endif
#ifdef vax
union { struct user yy;
int xx[128] [USIZE];
} zz;
#define u zz.yy
int mf;
#endif
#ifdef u3b
int file;
#endif
int retcode=1;
int c;
int lflg;
int eflg;
int uflg;
int aflg;
int dflg;
int pflg;
int fflg;
int gflg;
int nflg;
int tflg;
int sflg;
int errflg;
char *gettty();
char *ttyname();
int memfd;
int swmem;
int swap;
daddr_t swplo;
char argbuf[ARGSIZ];
char *parg;
char *p1;
char *coref;
char *memf;
char *system;
long lseek();
static char stdbuf[BUFSIZ];
#define NDEV 512
int ndev;
struct devl {
char dname[DIRSIZ];
dev_t dev;
} devl[NDEV];
char *tty[NTTYS]; /* for t option */
int ntty = 0;
int pid[SIZ]; /* for p option */
int npid = 0;
int grpid[SIZ]; /* for g option */
int ngrpid = 0;
main(argc, argv)
char **argv;
{
register char **ttyp = tty;
char *name;
char *p;
int puid, ppid, ppgrp;
int i, found;
extern char *optarg;
extern int optind;
char *getstr;
char *usage="ps [ -edalf ] [ -c corefile ] [ -s swapdev ] [ -n namelist ] [ -t tlist ]";
char *usage2=" [ -p plist ] [ -u ulist ] [ -g glist ]";
char *malloc();
unsigned size;
getstr = "lfeadn:s:c:t:p:g:u:";
system = "/unix";
#ifdef vax
coref = "/dev/kmem";
memf = "/dev/mem";
#else
coref = "/dev/mem";
memf = coref;
#endif
setbuf(stdout, stdbuf);
while ((c = getopt(argc,argv,getstr)) != EOF)
switch(c) {
case 'l': /* long listing */
lflg++;
break;
case 'f': /* full listing */
fflg++;
break;
case 'e': /* list for every process */
eflg++;
tflg = uflg = pflg = gflg = 0;
break;
case 'a': /* same as e except no proc grp leaders */
aflg++; /* and no non-terminal processes */
break;
case 'd': /* same as e except no proc grp leaders */
dflg++;
break;
case 'n': /* alternate namelist */
nflg++;
system = optarg;
break;
case 'c': /* core file given */
coref = optarg;
memf = coref;
break;
case 's': /* swap device given */
sflg++;
if ((swap = open(optarg, 0)) < 0 ) {
fprintf(stderr, "ps: cannot open %s\n",optarg);
done(1);
}
break;
case 't': /* terminals */
tflg++;
p1 = optarg;
do {
parg = argbuf;
if (ntty >= NTTYS)
break;
getarg();
if (strncmp(parg,"tty",3) == 0)
parg += 3;
size = strlen(parg);
if ((p = malloc(++size)) == NULL) {
fprintf(stderr,"ps: no memory\n");
done(1);
}
strcpy(p,parg);
*ttyp++ = p;
ntty++;
}
while (*p1);
break;
case 'p': /* proc ids */
pflg++;
p1 = optarg;
parg = argbuf;
do {
if (npid >= SIZ)
break;
getarg();
pid[npid++] = atoi(parg);
}
while (*p1);
break;
case 'g': /* proc group */
gflg++;
p1 = optarg;
parg = argbuf;
do {
if (ngrpid >= SIZ)
break;
getarg();
grpid[ngrpid++] = atoi(parg);
}
while (*p1);
break;
case 'u': /* user name or number */
uflg++;
p1 = optarg;
parg = argbuf;
do {
getarg();
if(nut < SIZ)
strncpy(uid_tbl[nut++].name,parg,MAXLOGIN);
}
while (*p1);
break;
case '?': /* error */
errflg++;
break;
}
if ( errflg || (optind < argc)) {
fprintf(stderr,"usage: %s\n%s\n",usage,usage2);
done(1);
}
if (tflg)
*ttyp = 0;
/* if specifying options not used, current terminal is default */
if ( !(aflg || eflg || dflg || uflg || tflg || pflg || gflg )) {
name = ttyname(2);
if (strncmp(name+5,"tty",3)==0)
*ttyp++ = name+8;
else
*ttyp++ = name+5;
*ttyp = 0;
ntty++;
tflg++;
}
if (eflg)
tflg = uflg = pflg = gflg = aflg = dflg = 0;
if (aflg || dflg)
tflg = 0;
/* get data from psfile */
if(!readata()) {
getdev();
getpass();
getnl();
if(!nflg)
wrdata();
}else {
if(nflg)
getnl();
}
uconv();
if(nl[0].n_value==0||nl[1].n_value==0||nl[2].n_value==0) {
fprintf(stderr, "ps: no namelist\n");
done(1);
}
#ifdef vax
nl[0].n_value = ((int)nl[0].n_value & 0x3fffffff);
nl[1].n_value = ((int)nl[1].n_value & 0x3fffffff);
nl[2].n_value = ((int)nl[2].n_value & 0x3fffffff);
nl[3].n_value = ((int)nl[3].n_value & 0x3fffffff);
#endif
if ((memfd = open(coref, 0)) < 0) {
fprintf(stderr, "ps: no mem\n");
done(1);
}
if ((swmem = open(memf,0)) < 0) {
fprintf(stderr, "ps: no mem\n");
done(1);
}
/*
* Find base of swap
*/
l_lseek(memfd, (long)nl[1].n_value, 0);
r_read(memfd, (char *)&swplo, sizeof(swplo));
/*
* read to find proc table size
*/
l_lseek(memfd, (long)nl[2].n_value, 0);
r_read(memfd, (char *)&v, sizeof(v));
#ifdef vax
/*
* read to find system page tables
*/
l_lseek(memfd, (long)nl[3].n_value, 0);
r_read(memfd, (char *)&sbrpte, sizeof(sbrpte));
sbrpte &= 0x3fffffff;
#endif
/*
* Locate proc table
*/
l_lseek(memfd, (long)nl[0].n_value, 0);
/* this opens swap */
if ( !sflg ) {
if ((swap = open("/dev/swap", 0)) < 0) {
fprintf(stderr, "ps: cannot open /dev/swap\n");
done(1);
}
}
if (fflg && lflg )
printf(" F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME COMD\n");
else if (fflg)
printf(" UID PID PPID C STIME TTY TIME COMMAND\n");
else if (lflg)
printf(" F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME COMD\n");
else
printf(" PID TTY TIME COMMAND\n");
/* determine which processes to print info about */
for (i=0; i<v.v_proc; i++) {
found = 0;
r_read(memfd, (char *)&mproc, sizeof(mproc));
if (mproc.p_stat == 0)
continue;
puid = mproc.p_uid;
ppid = mproc.p_pid;
ppgrp = mproc.p_pgrp;
if ((ppid == ppgrp) && (dflg || aflg))
continue;
if (eflg || dflg)
found++;
else if (pflg && search(pid, npid, ppid))
found++;
else if (uflg && ufind(puid))
found++;
else if (gflg && search(grpid, ngrpid, ppgrp))
found++;
if ( !found && !tflg && !aflg )
continue;
#ifdef u3b
procaddr = nl[0].n_value + (i * sizeof(mproc))
+ (int)mproc.p_stbl - (int)&mproc;
#endif
if (prcom(puid,found)) {
printf("\n");
retcode =0;
}
}
done(retcode);
}
/* readata reads in the open devices (terminals) and stores */
/* info in the devl structure. */
static char psfile[] = "/etc/ps_data";
int readata()
{
struct stat sbuf1, sbuf2;
int fd;
if (stat(psfile, &sbuf1) < 0
|| (stat("/dev", &sbuf2) < 0 || sbuf1.st_mtime <= sbuf2.st_mtime || sbuf1.st_mtime <= sbuf2.st_ctime)
|| (stat("/unix", &sbuf2) < 0 || sbuf1.st_mtime <= sbuf2.st_mtime || sbuf1.st_mtime <= sbuf2.st_ctime)
|| (stat("/etc/passwd", &sbuf2) < 0 || sbuf1.st_mtime <= sbuf2.st_mtime || sbuf1.st_mtime <= sbuf2.st_ctime)) {
return(0);
}
if(( fd = open(psfile, O_RDONLY)) < 0)
return(0);
/* read /dev data from psfile */
psread(fd, &ndev, sizeof(ndev));
psread(fd, devl, ndev * sizeof(*devl));
/* read /etc/passwd data from psfile */
psread(fd, &nud, sizeof(nud));
if((ud = (struct udata *)malloc(nud * sizeof(*ud))) == NULL) {
fprintf(stderr, "ps: not enough memory\n");
exit(1);
}
psread(fd, ud, nud * sizeof(*ud));
/* read /unix data from psfile */
if(!nflg)
psread(fd, nl, sizeof(nl));
close(fd);
return(1);
}
getdev()
{
register FILE *df;
struct direct dbuf;
struct stat sbuf1;
if ((df = fopen("/dev", "r")) == NULL) {
fprintf(stderr, "ps: cannot open /dev\n");
done(1);
}
if (chdir("/dev") < 0) {
fprintf(stderr, "ps: cannot change to /dev\n");
done(1);
}
ndev = 0;
while (fread((char *)&dbuf, sizeof(dbuf), 1, df) == 1) {
if(dbuf.d_ino == 0)
continue;
if(stat(dbuf.d_name, &sbuf1) < 0)
continue;
if ((sbuf1.st_mode&S_IFMT) != S_IFCHR)
continue;
strcpy(devl[ndev].dname, dbuf.d_name);
devl[ndev].dev = sbuf1.st_rdev;
ndev++;
}
fclose(df);
}
/* Get the passwd file data into the ud structure */
getpass()
{
struct passwd *pw, *getpwent();
char *malloc(), *realloc();
ud = NULL;
nud = 0;
maxud = 0;
while((pw=getpwent()) != NULL) {
while(nud >= maxud) {
maxud += UDQ;
ud = (struct udata *) ((ud == NULL) ?
malloc(sizeof(struct udata) * maxud) :
realloc(ud, sizeof(struct udata) * maxud));
if(ud == NULL) {
fprintf(stderr,"ps: not enough memory for %d users\n", maxud);
exit(1);
}
}
/* copy fields from pw file structure to udata */
ud[nud].uid = pw->pw_uid;
strncpy(ud[nud].name, pw->pw_name, MAXLOGIN);
nud++;
}
endpwent();
}
/* Get name list data into nl structure */
getnl()
{
nlist(system, nl);
}
wrdata()
{
int fd;
umask(02);
unlink(psfile);
if((fd = open(psfile, O_WRONLY | O_CREAT | O_EXCL, 0664)) > -1) {
/* write /dev data */
pswrite(fd, &ndev, sizeof(ndev));
pswrite(fd, devl, ndev * sizeof(*devl));
/* write /etc/passwd data */
pswrite(fd, &nud, sizeof(nud));
pswrite(fd, ud, nud * sizeof(*ud));
/* write /unix data */
pswrite(fd, nl, sizeof(nl));
close(fd);
}
}
/* getarg finds next argument in list and copies arg into argbuf */
/* p1 first pts to arg passed back from getopt routine. p1 is then */
/* bumped to next character that is not a comma or blank - p1 null */
/* indicates end of list */
getarg()
{
char *parga;
parga = argbuf;
while(*p1 && *p1 != ',' && *p1 != ' ')
*parga++ = *p1++;
*parga = '\0';
while( *p1 && ( *p1 == ',' || *p1 == ' ') )
p1++;
}
/* gettty returns the user's tty number or ? if none */
char *gettty()
{
register i;
register char *p;
if (u.u_ttyp==0)
return("?");
for (i=0; i<ndev; i++) {
if (devl[i].dev == u.u_ttyd) {
p = devl[i].dname;
if (strncmp(p,"tty",3) == 0)
p += 3;
return(p);
}
}
return("?");
}
#ifdef pdp11
long round(a,b)
long a, b;
{
long w = ((a+b-1)/b)*b;
return(w);
}
typedef unsigned pos;
struct map {
long b1, e1; long f1;
long b2, e2; long f2;
};
struct map datmap;
int file;
#endif
/* print info about the process */
prcom(puid,found)
int puid,found;
{
#ifdef u3b
char line[80];
int page;
#endif
register int *ip;
register char *cp, *cp1;
register char *tp;
long addr;
char *ctime();
time_t time();
time_t *clock, *tloc;
time_t tim;
char timbuf[26];
char *curtim = timbuf;
char *sttim, *s1;
long tm;
#if pdp11 || vax
int abuf[BSIZE*2/sizeof(int)];
int nbad, badflg;
#endif
#ifdef pdp11
long txtsiz, datsiz, stksiz;
int septxt;
int lw=(lflg?35:80);
#endif
int match, i;
int nbytes;
int uzero = 0;
register char **ttyp, *str;
#ifndef u3b
int ww;
int adrv0, cnt;
int *ip1;
#endif
/* if process is zombie, call print routine and return */
if (mproc.p_stat==SZOMB) {
if ( tflg && !found)
return(0);
else {
przom(puid);
return(1);
}
}
/* Determine if process is in memory or swap space */
/* and read in user block */
#ifdef u3b
if (mproc.p_flag & SLOAD) {
addr = mproc.p_uptbl[0] & PT_ADDR;
file = swmem;
} else {
addr = ( mproc.p_swaddr + swplo
+ (( mproc.p_size - USIZE ) * 4 )) <<9;
file = swap;
procaddr = mproc.p_swaddr;;
}
if (file >= 0) {
lseek(file, addr, 0);
if ((nbytes = read(file, &u, sizeof(u))) != sizeof(u))
if ((nbytes == 0) && sflg && (file == swap)) {
uzero++;
for ( i = 0, tp = (char *)&u; i < sizeof(u); i++)
*tp++ = '\0';
} else
return(0);
} else { /* swap device open failed */
for ( i = 0, tp = (char *)&u; i < sizeof(u); i++)
*tp++ = '\0';
for ( i = 0 , tp = "<NOSWAP>"; i < 8; i++)
u.u_comm[i] = *tp++;
uzero++;
}
#endif /* u3b */
#ifdef vax
if ((mproc.p_flag& (SLOAD | SSPART)) == 0) {
addr = (mproc.p_swaddr+swplo+mproc.p_swsize-USIZE)<<9;
mf = swap;
l_lseek(mf, addr, 0);
if ((nbytes = read(mf, (char *)&u, sizeof(u))) != sizeof(u)) {
if (( nbytes == 0) && sflg) {
uzero++;
for ( i = 0, tp = (char *) &u; i < sizeof(u); i++)
*tp++ = '\0';
}
else
return(0);
}
} else {
ww = (int)(mproc.p_spt + (mproc.p_nspt-1)*128);
ww = sbrpte + ((ww&0x3fffffff)>>9)*4;
l_lseek(swmem,(long)ww&0x3fffffff,0);
r_read(swmem,&spte, 4);
l_lseek(swmem,(spte<<9),0);
r_read(swmem, upte, sizeof upte);
for(c=0; c<USIZE; c++) {
l_lseek(swmem, upte[128-USIZE+c]<<9, 0);
if (read(swmem,(char *)(((int *)&u)+128*c),512) != 512) /* get u page */
return(0);
if(sizeof(struct user) - (c + 1) * 512 <= 0)
break;
}
}
#endif
#ifdef pdp11
if (mproc.p_flag&SLOAD) {
addr = ctob((long)mproc.p_addr);
file = swmem;
} else {
addr = (mproc.p_addr+swplo)<<9;
file = swap;
}
l_lseek(file, addr, 0);
if ((nbytes = read(file, (char *)&u, sizeof(u))) != sizeof(u))
if (( nbytes == 0) && sflg && (file == swap)) {
uzero++;
for ( i = 0, tp = (char *) &u; i < sizeof(u); i++)
*tp++ = '\0';
} else
return(0);
#endif
/* get current terminal - if none (?) and aflg is set */
/* then don't print info - if tflg is set, check if term */
/* is in list of desired terminals and print if so */
tp = gettty();
if ( aflg && (*tp == '?' ))
return(0);
if(tflg && !found) { /* the t option */
for (ttyp=tty, match=0; (str = *ttyp) !=0 && !match; ttyp++)
if (strcmp(tp,str) == 0)
match++;
if(!match)
return(0);
}
if (lflg)
printf("%3o %c", mproc.p_flag&0377, "OSWRIZTXX"[mproc.p_stat]); /* F S */
if (fflg) {
i = getunam(puid);
if (i >= 0)
printf("%7s", ud[i].name);
else
printf("%7u", puid);
}
else if (lflg)
printf("%6u", puid);
printf("%6u",mproc.p_pid); /* PID */
if (lflg || fflg)
printf("%6u%3d", mproc.p_ppid, mproc.p_cpu&0377); /* PPID CPU */
if (lflg) {
printf("%4d%3d",mproc.p_pri, mproc.p_nice); /* PRI NICE */
#if vax || u3b
printf("%7x%4d",
#ifdef vax
mproc.p_addr,
#else
procaddr,
#endif
mproc.p_size); /* ADDR SZ */
if (mproc.p_wchan)
printf("%9x",mproc.p_wchan); /* WCHAN */
else
printf(" ");
#endif
#ifdef pdp11
printf("%8o%3d", mproc.p_addr, (mproc.p_size+7)>>3);
if (mproc.p_wchan)
printf("%9o", mproc.p_wchan);
else
printf(" ");
#endif
}
if (uzero) /* u-block zeroed out so return */
return(1);
if (fflg) { /* STIME*/
clock = &u.u_start;
tim = time((time_t *) 0);
tloc = &tim;
s1 = ctime(tloc);
strcpy(curtim,s1);
sttim = ctime(clock);
prtim(curtim, sttim);
}
printf(" %4.4s", tp); /* TTY */
tm = (u.u_utime + u.u_stime + HZ/2)/HZ; /* TIME */
printf(" %2ld:%.2ld", tm/60, tm%60);
if (mproc.p_pid==0) {
printf(" swapper");
return(1);
}
/* if fflg not set, print command from u_block */
if (!fflg) { /* CMD */
printf(" %.8s", u.u_comm);
return(1);
}
/* set up address maps for user pcs */
#ifdef pdp11
txtsiz = ctob(u.u_tsize);
datsiz = ctob(u.u_dsize);
stksiz = ctob(u.u_ssize);
septxt = u.u_sep;
datmap.b1 = (septxt ? 0 : round(txtsiz,TXTRNDSIZ));
datmap.e1=datmap.b1+datsiz;
datmap.f1 = ctob(USIZE)+addr;
datmap.b2 = stackbas(stksiz);
datmap.e2 = stacktop(stksiz);
datmap.f2 = ctob(USIZE)+(datmap.e1-datmap.b1)+addr;
/* determine if process is a shell or not */
/* if last word is null then shell */
addr += ctob(mproc.p_size) - sizeof(abuf);
l_lseek(file, addr+sizeof(abuf)-sizeof(int), 0);
if (read(file, (char *)abuf, sizeof(int)) != sizeof(int))
return(1);
if (abuf[0]&0177400) {
char b[82];
char *bp = b;
char **ap = abuf[0];
char *cp;
*bp++ = ' ';
badflg = 0;
while((cp=(char *)getword(ap++)) != -1 && cp && (bp < b+lw)){
nbad = 0;
while((c = getbyte(cp++)) && (int)(cp) != 0177777 && (bp < b + lw)){
badflg++;
if (c < ' ' || c > '~') {
if (nbad++ > 3)
break;
continue;
}
*bp++ = c;
}
*bp++ = ' ';
}
*bp++ = '\0';
if ( badflg == 0 || nbad != 0 || *b == '\0' )
printf(" [ %.8s ]",u.u_comm);
else
printf("%.20s",b);
return(1);
}
l_lseek(file, addr, 0);
if (read(file, (char *)abuf, sizeof(abuf)) != sizeof(abuf))
return(1);
#endif
#ifdef vax
if ((mproc.p_flag & SLOAD) == 0) {
addr -= sizeof(abuf);
l_lseek(mf, addr, 0);
if (read(mf, (char *)abuf, sizeof(abuf)) != sizeof(abuf))
return(1);
} else {
l_lseek(swmem,ctob((upte[128-USIZE-2] & 0x1fffff)),0);
if (read(swmem,(char *)abuf,512) != 512)
return(1);
l_lseek(swmem,ctob((upte[128-USIZE-1] & 0x1fffff)),0);
if (read(swmem,(char *)&abuf[128],512) != 512)
return(1);
}
#endif
#ifndef u3b
badflg = 0;
for (ip = &abuf[BSIZE*2/sizeof(int)-sizeof(int)]; ip > abuf;) {
if (*--ip == -1 || *ip == 0) {
cp = (char *)(ip+1);
if (*cp==0)
cp++;
nbad = 0;
/* find argc */
cnt = 0;
adrv0 = (int)(ip+1) - (int)(abuf) + (int)(USRSTACK - sizeof(abuf));
for (ip1 = ip; ip1 > abuf;) {
if (*--ip1 == adrv0) {
cnt = *(ip1 - 3);
break;
}
}
for (cp1 = cp; cp1 < (char *)&abuf[BSIZE*2/sizeof(int)]; cp1++) {
badflg++;
c = *cp1&0177;
if (c==0) {
if (--cnt <= 0) {
*cp1++ = 0;
break;
}
else {
*cp1 = ' ';
}
}
else if (c < ' ' || c > '~') {
if (++nbad >= 3) {
*cp1++ = ' ';
break;
}
*cp1 = '?';
}
}
while (*--cp1==' ')
*cp1 = 0;
if ( cnt != 0 || badflg == 0 || nbad != 0 || *cp == '\0')
printf(" [ %.8s ]",u.u_comm);
else
printf(lflg?" %.35s":" %.80s", cp);
return(1);
}
}
printf(" [ %.8s ]",u.u_comm);
#endif
#ifdef u3b
if (file == swmem) {
lseek(file, segptbl(prc.p_stbl[NSEGP-STACKSEG]), 0);
read(file, &page, sizeof(page));
lseek(file, page & PT_ADDR, 0);
} else if (file >= 0)
lseek(file, addr - ptob(u.u_ssize), 0);
read(file, &page, sizeof(page)); /* argc */
read(file, line, sizeof (line));
if (page == 0) {
printf(" [ %.8s ]", u.u_comm);
} else {
for (i = 0; i < sizeof(line); i++)
if (line[i] == 0)
if (--page == 0)
break;
else if (line[i+1])
line[i] = ' ';
else
break;
printf(lflg?" %.35s":" %.80s", line);
}
#endif
return(1);
}
/* file handling and access routines */
#ifdef pdp11
getbyte(adr)
pos adr;
{
return((int)access(adr,1));
}
getword(adr)
pos adr;
{
return((int)access(adr,sizeof(int*)));
}
access(aadr,size)
pos aadr;
int size;
{
int *word = 0;
register struct map *amap = &datmap;
long adr = aadr;
if(!within(aadr,amap->b1,amap->e1)) {
if(within(aadr,amap->b2,amap->e2))
adr += (amap->f2)-(amap->b2);
else
return(0);
}
else {
adr += (amap->f1)-(amap->b1);
}
if(lseek(file,adr,0)==-1 || read(file,(char *)&word,size)<size) {
return(0);
}
return((int)word);
}
within(adr,lbd,ubd)
pos adr;
long lbd, ubd;
{
return(adr>=lbd && adr<ubd);
}
#endif
done(exitno)
{
exit(exitno);
}
/* search returns 1 if arg is found in array arr */
/* which has length num, and returns 0 if not found */
search(arr, num, arg)
int arr[];
int num;
int arg;
{
int i;
for (i = 0; i < num; i++)
if (arg == arr[i])
return(1);
return(0);
}
/* after the u option */
uconv()
{
int found;
int pwuid;
int i, j;
/* search thru name array for oarg */
for (i=0; i<nut; i++) {
found = -1;
for(j=0; j<nud; j++) {
if (strncmp(uid_tbl[i].name, ud[j].name, MAXLOGIN)==0) {
found = j;
break;
}
}
/* if not found and oarg is numeric */
/* then search through number array */
if (found < 0 && (uid_tbl[i].name[0] >= '0' && uid_tbl[i].name[0] <= '9')) {
pwuid = atoi(uid_tbl[i].name);
for (j=0; j<nud; j++) {
if (pwuid == ud[j].uid) {
found = j;
break;
}
}
}
/* if found then enter found index into tbl array */
if ( found != -1 ) {
uid_tbl[i].uid = ud[found].uid;
strncpy(uid_tbl[i].name,ud[found].name,MAXLOGIN);
}else {
for(j=i+1; j<nut; j++) {
strncpy(uid_tbl[j-1].name,uid_tbl[j].name,MAXLOGIN);
}
nut--;
i--;
}
}
return;
}
/* for full command (-f flag) print user name instead of number */
/* search thru existing table of userid numbers and if puid is found, */
/* return corresponding name. Else search thru /etc/passwd */
getunam(puid)
int puid;
{
int i;
for(i=0; i<nud; i++)
if(ud[i].uid == puid)
return(i);
return(-1);
}
/* ufind will return 1 if puid is in table ; if not return 0 */
ufind(puid)
int puid;
{
int i;
for(i=0; i<nut; i++)
if(uid_tbl[i].uid == puid)
return(1);
return(0);
}
/* lseek with error checking */
l_lseek(fd, offset, whence)
int fd, whence;
long offset;
{
if (lseek(fd, offset, whence) == -1) {
fprintf(stderr, "ps: error on lseek\n");
done(1);
}
}
/* read with error checking */
r_read (fd, buf, nbytes)
int fd, nbytes;
char *buf;
{
if (read(fd, buf, nbytes) != nbytes) {
fprintf(stderr, "ps: error on read\n");
done(1);
}
}
/* special read unlinks psfile on read error */
psread(fd, bp, bs)
int fd;
char *bp;
unsigned bs;
{
if(read(fd, bp, bs) != bs) {
fprintf(stderr, "ps: error on read\n");
unlink(psfile);
}
}
/* special write unlinks psfile on read error */
pswrite(fd, bp, bs)
int fd;
char *bp;
unsigned bs;
{
if(write(fd, bp, bs) != bs) {
fprintf(stderr, "ps: error on write\n");
unlink(psfile);
}
}
/* print starting time of process unless process started more */
/* than 24 hours ago in which case date is printed */
/* sttim is start time and it is compared to curtim (current time ) */
prtim(curtim, sttim)
char *curtim, *sttim;
{
char *p1, *p2;
char dayst[3], daycur[3];
if ( strncmp(curtim, sttim, 11) == 0) {
p1 = sttim + 11;
p2 = p1 + 8;
}
else {
p1 = sttim + 4;
p2 = p1 + 7;
/* if time is < 24 hours different, then print time */
if (strncmp(curtim+4, sttim+4, 3) == 0) {
strncpy(dayst,sttim+8, 2);
strcat(dayst,"");
strncpy(daycur,curtim+8,2);
strcat(daycur,"");
if ((atoi(dayst) +1 == atoi(daycur)) &&
(strncmp(curtim+11,sttim+11,8)<=0)) {
p1 = sttim + 11;
p2 = p1 + 8;
}
}
}
*p2 = '\0';
printf("%9s",p1);
}
#ifdef u3b
#define xp_flag p_flag
#define xp_stat p_stat
#define xp_pid p_pid
#define xp_ppid p_ppid
#define xp_cpu p_cpu
#define xp_pri p_pri
#define xp_nice p_nice
#define xp_utime p_utime
#define xp_stime p_stime
#endif
przom(puid)
/* print zombie process - zproc overlays mproc */
int puid;
{
int i;
long tm;
if (lflg)
printf("%3o %c", zproc.xp_flag&0377, "OSWRIZT"[zproc.xp_stat]); /* F S */
if (fflg) {
i = getunam(puid);
if (i >= 0)
printf("%7s", ud[i].name);
else
printf("%7u", puid);
}
else if (lflg)
printf("%6u", puid);
printf("%6u",zproc.xp_pid); /* PID */
if (lflg || fflg)
printf("%6u%3d", zproc.xp_ppid, zproc.xp_cpu&0377); /* PPID CPU */
if (lflg)
printf("%4d%3d",zproc.xp_pri, zproc.xp_nice); /* PRI NICE */
if (fflg) printf(" ");
if (lflg) printf(" ");
tm = (zproc.xp_utime + zproc.xp_stime + HZ/2)/HZ; /* TIME */
printf(" %2ld:%.2ld", tm/60, tm%60);
printf(" <defunct>");
return;
}