Return "-1" on an error.
[unix-history] / usr / src / usr.bin / w / w.c
CommitLineData
f42904bc
DF
1/*
2 * Copyright (c) 1980 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
7#ifndef lint
8char copyright[] =
9"@(#) Copyright (c) 1980 Regents of the University of California.\n\
10 All rights reserved.\n";
11#endif not lint
12
68d13ee3 13#ifndef lint
f04cce90 14static char sccsid[] = "@(#)w.c 5.5 (Berkeley) %G%";
f42904bc
DF
15#endif not lint
16
76238d88
BJ
17/*
18 * w - print system status (who and what)
19 *
20 * This program is similar to the systat command on Tenex/Tops 10/20
21 * It needs read permission on /dev/mem, /dev/kmem, and /dev/drum.
22 */
23#include <sys/param.h>
24#include <nlist.h>
25#include <stdio.h>
26#include <ctype.h>
27#include <utmp.h>
76238d88
BJ
28#include <sys/stat.h>
29#include <sys/dir.h>
30#include <sys/user.h>
31#include <sys/proc.h>
3b8dff21 32#include <sys/ioctl.h>
57ee57ff 33#include <machine/pte.h>
76238d88
BJ
34#include <sys/vm.h>
35
36#define NMAX sizeof(utmp.ut_name)
37#define LMAX sizeof(utmp.ut_line)
3b8dff21 38#define HMAX sizeof(utmp.ut_host)
76238d88
BJ
39
40#define ARGWIDTH 33 /* # chars left on 80 col crt for args */
41
bdb1f95f 42struct pr {
76238d88
BJ
43 short w_pid; /* proc.p_pid */
44 char w_flag; /* proc.p_flag */
45 short w_size; /* proc.p_size */
46 long w_seekaddr; /* where to find args */
47 long w_lastpg; /* disk address of stack */
48 int w_igintr; /* INTR+3*QUIT, 0=die, 1=ign, 2=catch */
49 time_t w_time; /* CPU time used by this process */
50 time_t w_ctime; /* CPU time used by children */
51 dev_t w_tty; /* tty device of process */
af9a91c9 52 int w_uid; /* uid of process */
76238d88
BJ
53 char w_comm[15]; /* user.u_comm, null terminated */
54 char w_args[ARGWIDTH+1]; /* args if interesting process */
bdb1f95f
BJ
55} *pr;
56int nproc;
76238d88
BJ
57
58struct nlist nl[] = {
59 { "_proc" },
60#define X_PROC 0
61 { "_swapdev" },
62#define X_SWAPDEV 1
63 { "_Usrptmap" },
64#define X_USRPTMA 2
65 { "_usrpt" },
66#define X_USRPT 3
67 { "_nswap" },
68#define X_NSWAP 4
69 { "_avenrun" },
70#define X_AVENRUN 5
a43be079
SL
71 { "_boottime" },
72#define X_BOOTTIME 6
bdb1f95f
BJ
73 { "_nproc" },
74#define X_NPROC 7
68d13ee3
SL
75 { "_dmmin" },
76#define X_DMMIN 8
77 { "_dmmax" },
78#define X_DMMAX 9
20932249 79 { "" },
76238d88
BJ
80};
81
82FILE *ps;
83FILE *ut;
84FILE *bootfd;
85int kmem;
86int mem;
87int swap; /* /dev/kmem, mem, and swap */
88int nswap;
68d13ee3 89int dmmin, dmmax;
76238d88 90dev_t tty;
af9a91c9 91int uid;
76238d88
BJ
92char doing[520]; /* process attached to terminal */
93time_t proctime; /* cpu time of process in doing */
94double avenrun[3];
bdb1f95f 95struct proc *aproc;
76238d88 96
68d13ee3 97#define DIV60(t) ((t+30)/60) /* x/60 rounded */
af9a91c9 98#define TTYEQ (tty == pr[i].w_tty && uid == pr[i].w_uid)
76238d88
BJ
99#define IGINT (1+3*1) /* ignoring both SIGINT & SIGQUIT */
100
101char *getargs();
102char *fread();
103char *ctime();
104char *rindex();
105FILE *popen();
106struct tm *localtime();
80b96391 107time_t findidle();
76238d88
BJ
108
109int debug; /* true if -d flag: debugging output */
3b8dff21 110int ttywidth = 80; /* width of tty */
76238d88
BJ
111int header = 1; /* true if -h flag: don't print heading */
112int lflag = 1; /* true if -l flag: long style output */
3b8dff21 113int prfrom = 1; /* true if not -f flag: print host from */
76238d88 114int login; /* true if invoked as login shell */
80b96391 115time_t idle; /* number of minutes user is idle */
76238d88
BJ
116int nusers; /* number of users logged in now */
117char * sel_user; /* login of particular user selected */
118char firstchar; /* first char of name of prog invoked as */
119time_t jobtime; /* total cpu time visible */
120time_t now; /* the current time of day */
a43be079
SL
121struct timeval boottime;
122time_t uptime; /* time of last reboot & elapsed time since */
76238d88
BJ
123int np; /* number of processes currently active */
124struct utmp utmp;
125struct proc mproc;
20932249
SL
126union {
127 struct user U_up;
128 char pad[NBPG][UPAGES];
129} Up;
130#define up Up.U_up
76238d88
BJ
131
132main(argc, argv)
133 char **argv;
134{
135 int days, hrs, mins;
136 register int i, j;
137 char *cp;
138 register int curpid, empty;
3b8dff21 139 struct winsize win;
76238d88 140
76238d88
BJ
141 login = (argv[0][0] == '-');
142 cp = rindex(argv[0], '/');
143 firstchar = login ? argv[0][1] : (cp==0) ? argv[0][0] : cp[1];
144 cp = argv[0]; /* for Usage */
145
146 while (argc > 1) {
147 if (argv[1][0] == '-') {
148 for (i=1; argv[1][i]; i++) {
149 switch(argv[1][i]) {
150
151 case 'd':
152 debug++;
153 break;
154
3b8dff21
MK
155 case 'f':
156 prfrom = !prfrom;
157 break;
158
76238d88
BJ
159 case 'h':
160 header = 0;
161 break;
162
163 case 'l':
164 lflag++;
165 break;
166
167 case 's':
168 lflag = 0;
169 break;
170
171 case 'u':
172 case 'w':
635aa49f 173 firstchar = argv[1][i];
76238d88
BJ
174 break;
175
176 default:
177 printf("Bad flag %s\n", argv[1]);
178 exit(1);
179 }
180 }
181 } else {
182 if (!isalnum(argv[1][0]) || argc > 2) {
3b8dff21 183 printf("Usage: %s [ -hlsfuw ] [ user ]\n", cp);
76238d88
BJ
184 exit(1);
185 } else
186 sel_user = argv[1];
187 }
188 argc--; argv++;
189 }
190
f04cce90 191 if (ioctl(1, TIOCGWINSZ, &win) != -1 && win.ws_col > 70)
3b8dff21 192 ttywidth = win.ws_col;
76238d88
BJ
193 if ((kmem = open("/dev/kmem", 0)) < 0) {
194 fprintf(stderr, "No kmem\n");
195 exit(1);
196 }
197 nlist("/vmunix", nl);
198 if (nl[0].n_type==0) {
199 fprintf(stderr, "No namelist\n");
200 exit(1);
201 }
202
203 if (firstchar != 'u')
204 readpr();
205
206 ut = fopen("/etc/utmp","r");
80b96391 207 time(&now);
76238d88
BJ
208 if (header) {
209 /* Print time of day */
80b96391 210 prtat(&now);
76238d88
BJ
211
212 /*
213 * Print how long system has been up.
a43be079 214 * (Found by looking for "boottime" in kernel)
76238d88 215 */
a43be079
SL
216 lseek(kmem, (long)nl[X_BOOTTIME].n_value, 0);
217 read(kmem, &boottime, sizeof (boottime));
76238d88 218
a43be079 219 uptime = now - boottime.tv_sec;
baaa0078 220 uptime += 30;
76238d88
BJ
221 days = uptime / (60*60*24);
222 uptime %= (60*60*24);
223 hrs = uptime / (60*60);
224 uptime %= (60*60);
baaa0078 225 mins = uptime / 60;
76238d88
BJ
226
227 printf(" up");
228 if (days > 0)
229 printf(" %d day%s,", days, days>1?"s":"");
230 if (hrs > 0 && mins > 0) {
231 printf(" %2d:%02d,", hrs, mins);
232 } else {
233 if (hrs > 0)
234 printf(" %d hr%s,", hrs, hrs>1?"s":"");
235 if (mins > 0)
236 printf(" %d min%s,", mins, mins>1?"s":"");
237 }
238
239 /* Print number of users logged in to system */
240 while (fread(&utmp, sizeof(utmp), 1, ut)) {
241 if (utmp.ut_name[0] != '\0')
242 nusers++;
243 }
244 rewind(ut);
fddf7972 245 printf(" %d user%s", nusers, nusers>1?"s":"");
76238d88
BJ
246
247 /*
248 * Print 1, 5, and 15 minute load averages.
249 * (Found by looking in kernel for avenrun).
250 */
251 printf(", load average:");
252 lseek(kmem, (long)nl[X_AVENRUN].n_value, 0);
253 read(kmem, avenrun, sizeof(avenrun));
254 for (i = 0; i < (sizeof(avenrun)/sizeof(avenrun[0])); i++) {
255 if (i > 0)
256 printf(",");
257 printf(" %.2f", avenrun[i]);
258 }
259 printf("\n");
260 if (firstchar == 'u')
261 exit(0);
262
263 /* Headers for rest of output */
3b8dff21
MK
264 if (lflag && prfrom)
265 printf("User tty from login@ idle JCPU PCPU what\n");
266 else if (lflag)
76238d88 267 printf("User tty login@ idle JCPU PCPU what\n");
3b8dff21
MK
268 else if (prfrom)
269 printf("User tty from idle what\n");
76238d88
BJ
270 else
271 printf("User tty idle what\n");
272 fflush(stdout);
273 }
274
275
276 for (;;) { /* for each entry in utmp */
277 if (fread(&utmp, sizeof(utmp), 1, ut) == NULL) {
278 fclose(ut);
279 exit(0);
280 }
281 if (utmp.ut_name[0] == '\0')
282 continue; /* that tty is free */
283 if (sel_user && strcmpn(utmp.ut_name, sel_user, NMAX) != 0)
284 continue; /* we wanted only somebody else */
285
286 gettty();
287 jobtime = 0;
288 proctime = 0;
289 strcpy(doing, "-"); /* default act: normally never prints */
290 empty = 1;
291 curpid = -1;
292 idle = findidle();
293 for (i=0; i<np; i++) { /* for each process on this tty */
294 if (!(TTYEQ))
295 continue;
296 jobtime += pr[i].w_time + pr[i].w_ctime;
297 proctime += pr[i].w_time;
f8217b43
JL
298 /*
299 * Meaning of debug fields following proc name is:
300 * & by itself: ignoring both SIGINT and QUIT.
301 * (==> this proc is not a candidate.)
302 * & <i> <q>: i is SIGINT status, q is quit.
303 * 0 == DFL, 1 == IGN, 2 == caught.
304 * *: proc pgrp == tty pgrp.
305 */
306 if (debug) {
76238d88
BJ
307 printf("\t\t%d\t%s", pr[i].w_pid, pr[i].w_args);
308 if ((j=pr[i].w_igintr) > 0)
309 if (j==IGINT)
310 printf(" &");
311 else
312 printf(" & %d %d", j%3, j/3);
313 printf("\n");
314 }
315 if (empty && pr[i].w_igintr!=IGINT) {
316 empty = 0;
317 curpid = -1;
318 }
319 if(pr[i].w_pid>curpid && (pr[i].w_igintr!=IGINT || empty)){
320 curpid = pr[i].w_pid;
321 strcpy(doing, lflag ? pr[i].w_args : pr[i].w_comm);
322#ifdef notdef
323 if (doing[0]==0 || doing[0]=='-' && doing[1]<=' ' || doing[0] == '?') {
324 strcat(doing, " (");
325 strcat(doing, pr[i].w_comm);
326 strcat(doing, ")");
327 }
328#endif
329 }
330 }
331 putline();
332 }
333}
334
335/* figure out the major/minor device # pair for this tty */
336gettty()
337{
338 char ttybuf[20];
339 struct stat statbuf;
340
341 ttybuf[0] = 0;
342 strcpy(ttybuf, "/dev/");
343 strcat(ttybuf, utmp.ut_line);
344 stat(ttybuf, &statbuf);
345 tty = statbuf.st_rdev;
af9a91c9 346 uid = statbuf.st_uid;
76238d88
BJ
347}
348
349/*
350 * putline: print out the accumulated line of info about one user.
351 */
352putline()
353{
354 register int tm;
3b8dff21 355 int width = ttywidth - 1;
76238d88
BJ
356
357 /* print login name of the user */
358 printf("%-*.*s ", NMAX, NMAX, utmp.ut_name);
3b8dff21 359 width -= NMAX + 1;
76238d88
BJ
360
361 /* print tty user is on */
3b8dff21 362 if (lflag && !prfrom) {
76238d88
BJ
363 /* long form: all (up to) LMAX chars */
364 printf("%-*.*s", LMAX, LMAX, utmp.ut_line);
3b8dff21
MK
365 width -= LMAX;
366 } else {
76238d88
BJ
367 /* short form: 2 chars, skipping 'tty' if there */
368 if (utmp.ut_line[0]=='t' && utmp.ut_line[1]=='t' && utmp.ut_line[2]=='y')
369 printf("%-2.2s", &utmp.ut_line[3]);
370 else
371 printf("%-2.2s", utmp.ut_line);
3b8dff21
MK
372 width -= 2;
373 }
374
375 if (prfrom) {
376 printf(" %-14.14s", utmp.ut_host);
377 width -= 15;
76238d88
BJ
378 }
379
3b8dff21 380 if (lflag) {
76238d88 381 /* print when the user logged in */
80b96391 382 prtat(&utmp.ut_time);
3b8dff21
MK
383 width -= 8;
384 }
76238d88
BJ
385
386 /* print idle time */
80b96391
MK
387 if (idle >= 36 * 60)
388 printf("%2ddays ", (idle + 12 * 60) / (24 * 60));
389 else
390 prttime(idle," ");
3b8dff21 391 width -= 7;
76238d88
BJ
392
393 if (lflag) {
394 /* print CPU time for all processes & children */
a591da4b 395 prttime(jobtime," ");
3b8dff21 396 width -= 7;
76238d88 397 /* print cpu time for interesting process */
a591da4b 398 prttime(proctime," ");
3b8dff21 399 width -= 7;
76238d88
BJ
400 }
401
402 /* what user is doing, either command tail or args */
3b8dff21 403 printf(" %-.*s\n", width-1, doing);
76238d88
BJ
404 fflush(stdout);
405}
406
407/* find & return number of minutes current tty has been idle */
408findidle()
409{
410 struct stat stbuf;
411 long lastaction, diff;
412 char ttyname[20];
413
414 strcpy(ttyname, "/dev/");
415 strcatn(ttyname, utmp.ut_line, LMAX);
416 stat(ttyname, &stbuf);
417 time(&now);
418 lastaction = stbuf.st_atime;
419 diff = now - lastaction;
420 diff = DIV60(diff);
421 if (diff < 0) diff = 0;
422 return(diff);
423}
424
80b96391
MK
425#define HR (60 * 60)
426#define DAY (24 * HR)
427#define MON (30 * DAY)
428
76238d88 429/*
80b96391 430 * prttime prints a time in hours and minutes or minutes and seconds.
76238d88
BJ
431 * The character string tail is printed at the end, obvious
432 * strings to pass are "", " ", or "am".
433 */
434prttime(tim, tail)
435 time_t tim;
436 char *tail;
437{
76238d88
BJ
438
439 if (tim >= 60) {
440 printf("%3d:", tim/60);
80b96391
MK
441 tim %= 60;
442 printf("%02d", tim);
443 } else if (tim > 0)
444 printf(" %2d", tim);
445 else
446 printf(" ");
76238d88
BJ
447 printf("%s", tail);
448}
449
80b96391
MK
450char *weekday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
451char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
452 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
453
76238d88 454/* prtat prints a 12 hour time given a pointer to a time of day */
80b96391
MK
455prtat(time)
456 long *time;
76238d88 457{
80b96391
MK
458 struct tm *p;
459 register int hr, pm;
460
461 p = localtime(time);
462 hr = p->tm_hour;
463 pm = (hr > 11);
464 if (hr > 11)
465 hr -= 12;
466 if (hr == 0)
467 hr = 12;
468 if (now - *time <= 18 * HR)
469 prttime(hr * 60 + p->tm_min, pm ? "pm" : "am");
470 else if (now - *time <= 7 * DAY)
471 printf(" %s%2d%s", weekday[p->tm_wday], hr, pm ? "pm" : "am");
472 else
473 printf(" %2d%s%2d", p->tm_mday, month[p->tm_mon], p->tm_year);
76238d88
BJ
474}
475
476/*
477 * readpr finds and reads in the array pr, containing the interesting
478 * parts of the proc and user tables for each live process.
479 */
480readpr()
481{
482 int pn, mf, addr, c;
483 int szpt, pfnum, i;
484 struct pte *Usrptma, *usrpt, *pte, apte;
485 struct dblock db;
486
487 Usrptma = (struct pte *) nl[X_USRPTMA].n_value;
488 usrpt = (struct pte *) nl[X_USRPT].n_value;
489 if((mem = open("/dev/mem", 0)) < 0) {
490 fprintf(stderr, "No mem\n");
491 exit(1);
492 }
493 if ((swap = open("/dev/drum", 0)) < 0) {
494 fprintf(stderr, "No drum\n");
495 exit(1);
496 }
497 /*
498 * read mem to find swap dev.
499 */
500 lseek(kmem, (long)nl[X_SWAPDEV].n_value, 0);
501 read(kmem, &nl[X_SWAPDEV].n_value, sizeof(nl[X_SWAPDEV].n_value));
502 /*
68d13ee3 503 * Find base of and parameters of swap
76238d88
BJ
504 */
505 lseek(kmem, (long)nl[X_NSWAP].n_value, 0);
506 read(kmem, &nswap, sizeof(nswap));
68d13ee3
SL
507 lseek(kmem, (long)nl[X_DMMIN].n_value, 0);
508 read(kmem, &dmmin, sizeof(dmmin));
509 lseek(kmem, (long)nl[X_DMMAX].n_value, 0);
510 read(kmem, &dmmax, sizeof(dmmax));
76238d88
BJ
511 /*
512 * Locate proc table
513 */
bdb1f95f
BJ
514 lseek(kmem, (long)nl[X_NPROC].n_value, 0);
515 read(kmem, &nproc, sizeof(nproc));
516 pr = (struct pr *)calloc(nproc, sizeof (struct pr));
76238d88 517 np = 0;
bdb1f95f
BJ
518 lseek(kmem, (long)nl[X_PROC].n_value, 0);
519 read(kmem, &aproc, sizeof(aproc));
520 for (pn=0; pn<nproc; pn++) {
521 lseek(kmem, (int)(aproc + pn), 0);
76238d88
BJ
522 read(kmem, &mproc, sizeof mproc);
523 /* decide if it's an interesting process */
f8217b43 524 if (mproc.p_stat==0 || mproc.p_stat==SZOMB || mproc.p_pgrp==0)
76238d88 525 continue;
76238d88
BJ
526 /* find & read in the user structure */
527 if ((mproc.p_flag & SLOAD) == 0) {
528 /* not in memory - get from swap device */
20932249 529 addr = dtob(mproc.p_swaddr);
76238d88
BJ
530 lseek(swap, (long)addr, 0);
531 if (read(swap, &up, sizeof(up)) != sizeof(up)) {
532 continue;
533 }
534 } else {
535 int p0br, cc;
536#define INTPPG (NBPG / sizeof (int))
537 struct pte pagetbl[NBPG / sizeof (struct pte)];
538 /* loaded, get each page from memory separately */
539 szpt = mproc.p_szpt;
540 p0br = (int)mproc.p_p0br;
541 pte = &Usrptma[btokmx(mproc.p_p0br) + szpt-1];
542 lseek(kmem, (long)pte, 0);
543 if (read(kmem, &apte, sizeof(apte)) != sizeof(apte))
544 continue;
545 lseek(mem, ctob(apte.pg_pfnum), 0);
546 if (read(mem,pagetbl,sizeof(pagetbl)) != sizeof(pagetbl))
547cont:
548 continue;
549 for(cc=0; cc<UPAGES; cc++) { /* get u area */
550 int upage = pagetbl[NPTEPG-UPAGES+cc].pg_pfnum;
551 lseek(mem,ctob(upage),0);
552 if (read(mem,((int *)&up)+INTPPG*cc,NBPG) != NBPG)
553 goto cont;
554 }
555 szpt = up.u_pcb.pcb_szpt;
556 pr[np].w_seekaddr = ctob(apte.pg_pfnum);
557 }
e941b445 558 vstodb(0, CLSIZE, &up.u_smap, &db, 1);
20932249 559 pr[np].w_lastpg = dtob(db.db_base);
76238d88
BJ
560 if (up.u_ttyp == NULL)
561 continue;
562
563 /* save the interesting parts */
564 pr[np].w_pid = mproc.p_pid;
565 pr[np].w_flag = mproc.p_flag;
566 pr[np].w_size = mproc.p_dsize + mproc.p_ssize;
20932249
SL
567 pr[np].w_igintr = (((int)up.u_signal[2]==1) +
568 2*((int)up.u_signal[2]>1) + 3*((int)up.u_signal[3]==1)) +
569 6*((int)up.u_signal[3]>1);
a43be079
SL
570 pr[np].w_time =
571 up.u_ru.ru_utime.tv_sec + up.u_ru.ru_stime.tv_sec;
572 pr[np].w_ctime =
573 up.u_cru.ru_utime.tv_sec + up.u_cru.ru_stime.tv_sec;
76238d88 574 pr[np].w_tty = up.u_ttyd;
af9a91c9 575 pr[np].w_uid = mproc.p_uid;
76238d88
BJ
576 up.u_comm[14] = 0; /* Bug: This bombs next field. */
577 strcpy(pr[np].w_comm, up.u_comm);
578 /*
579 * Get args if there's a chance we'll print it.
580 * Cant just save pointer: getargs returns static place.
581 * Cant use strcpyn: that crock blank pads.
582 */
583 pr[np].w_args[0] = 0;
584 strcatn(pr[np].w_args,getargs(&pr[np]),ARGWIDTH);
585 if (pr[np].w_args[0]==0 || pr[np].w_args[0]=='-' && pr[np].w_args[1]<=' ' || pr[np].w_args[0] == '?') {
586 strcat(pr[np].w_args, " (");
587 strcat(pr[np].w_args, pr[np].w_comm);
588 strcat(pr[np].w_args, ")");
589 }
590 np++;
591 }
592}
593
594/*
595 * getargs: given a pointer to a proc structure, this looks at the swap area
596 * and tries to reconstruct the arguments. This is straight out of ps.
597 */
598char *
599getargs(p)
bdb1f95f 600 struct pr *p;
76238d88
BJ
601{
602 int c, addr, nbad;
e941b445 603 static int abuf[CLSIZE*NBPG/sizeof(int)];
76238d88
BJ
604 struct pte pagetbl[NPTEPG];
605 register int *ip;
606 register char *cp, *cp1;
607
608 if ((p->w_flag & SLOAD) == 0) {
609 lseek(swap, p->w_lastpg, 0);
610 if (read(swap, abuf, sizeof(abuf)) != sizeof(abuf))
611 return(p->w_comm);
612 } else {
613 c = p->w_seekaddr;
614 lseek(mem,c,0);
615 if (read(mem,pagetbl,NBPG) != NBPG)
616 return(p->w_comm);
e941b445
BJ
617 if (pagetbl[NPTEPG-CLSIZE-UPAGES].pg_fod==0 && pagetbl[NPTEPG-CLSIZE-UPAGES].pg_pfnum) {
618 lseek(mem,ctob(pagetbl[NPTEPG-CLSIZE-UPAGES].pg_pfnum),0);
76238d88
BJ
619 if (read(mem,abuf,sizeof(abuf)) != sizeof(abuf))
620 return(p->w_comm);
621 } else {
622 lseek(swap, p->w_lastpg, 0);
623 if (read(swap, abuf, sizeof(abuf)) != sizeof(abuf))
624 return(p->w_comm);
625 }
626 }
e941b445
BJ
627 abuf[sizeof(abuf)/sizeof(abuf[0])-1] = 0;
628 for (ip = &abuf[sizeof(abuf)/sizeof(abuf[0])-2]; ip > abuf;) {
76238d88
BJ
629 /* Look from top for -1 or 0 as terminator flag. */
630 if (*--ip == -1 || *ip == 0) {
631 cp = (char *)(ip+1);
632 if (*cp==0)
633 cp++;
634 nbad = 0; /* up to 5 funny chars as ?'s */
e941b445 635 for (cp1 = cp; cp1 < (char *)&abuf[sizeof(abuf)/sizeof(abuf[0])]; cp1++) {
76238d88
BJ
636 c = *cp1&0177;
637 if (c==0) /* nulls between args => spaces */
638 *cp1 = ' ';
639 else if (c < ' ' || c > 0176) {
640 if (++nbad >= 5) {
641 *cp1++ = ' ';
642 break;
643 }
644 *cp1 = '?';
645 } else if (c=='=') { /* Oops - found an
646 * environment var, back
647 * over & erase it. */
648 *cp1 = 0;
649 while (cp1>cp && *--cp1!=' ')
650 *cp1 = 0;
651 break;
652 }
653 }
654 while (*--cp1==' ') /* strip trailing spaces */
655 *cp1 = 0;
656 return(cp);
657 }
658 }
659 return (p->w_comm);
660}
661
662/*
663 * Given a base/size pair in virtual swap area,
664 * return a physical base/size pair which is the
665 * (largest) initial, physically contiguous block.
666 */
667vstodb(vsbase, vssize, dmp, dbp, rev)
668 register int vsbase;
669 int vssize;
670 struct dmap *dmp;
671 register struct dblock *dbp;
672{
68d13ee3 673 register int blk = dmmin;
76238d88
BJ
674 register swblk_t *ip = dmp->dm_map;
675
20932249
SL
676 vsbase = ctod(vsbase);
677 vssize = ctod(vssize);
76238d88
BJ
678 if (vsbase < 0 || vsbase + vssize > dmp->dm_size)
679 panic("vstodb");
680 while (vsbase >= blk) {
681 vsbase -= blk;
68d13ee3 682 if (blk < dmmax)
76238d88
BJ
683 blk *= 2;
684 ip++;
685 }
686 if (*ip <= 0 || *ip + blk > nswap)
687 panic("vstodb *ip");
688 dbp->db_size = min(vssize, blk - vsbase);
689 dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase);
690}
691
692panic(cp)
693 char *cp;
694{
695
696 /* printf("%s\n", cp); */
697}
698
699min(a, b)
700{
701
702 return (a < b ? a : b);
703}