#ident "$Header: uarea.c 1.7 89/04/04 $"

/*
 * $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred.
 */

#ifndef lint
static char rcsid[] = "$Header: uarea.c 1.7 89/04/04 $";
#endif

#include "crash.h"

#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/dir.h> 
#include <sys/resource.h>
#include <signal.h>
#include <sys/user.h>
#include <sys/timer.h>
#include <sys/proc.h>
#include <sys/file.h>
#include <sys/vm.h>
#include <sys/pte.h>
#include <sys/plocal.h>
#include <sys/sysmacros.h>

Uarea()
{
	char *arg;
	struct proc *p;

	while((arg = token()) != NULL) {
		if( p = getproc(arg) )
			pruarea(p);
	}
}

pruarea(pp)
	struct proc *pp;	/* virtual address of proc entry */
{
	register  int  i;
	char *u;
	register struct user *USR;

	if ((u = getuarea(pp)) == BADREAD) {
		printf("bad read of uarea\n");
		return(-1);
	}
	if (u == SWAPPED) {
		printf("process is swapped\n");
		return(-1);
	}

	USR = UBTOUSER(u);
	printf("PER PROCESS USER AREA:\n");
	printf("USER ID's:\t");
	printf("uid: %u, gid: %u, real uid: %u, real gid: %u\n",
		USR->u_uid, USR->u_gid, USR->u_ruid, USR->u_rgid);
	printf("GROUPS:\t");
	for (i = 0; USR->u_groups[i] != INVAL_GID; i++)
		printf(" %d", USR->u_groups[i]);
	printf("\n");
	printf("CRED ref count = %d\n", USR->u_cred->cr_ref);
#ifdef WANT
	printf("PROCESS TIMES:\t");
	printf("user: %ld, sys: %ld, child user: %ld, child sys: %ld\n",
		USR->u_utime, USR->u_stime, USR->u_cutime, USR->u_cstime);
#endif
	printf("PROCESS MISC:\t");
	printf("proc slot: %d", USR->u_procp - proc );
	printf(", u_sp: %#06x\n", USR->u_sp);
#ifdef	WANT
	printf("IPC:\t\t");
#endif

#ifdef	WANT
	printf("locks:%s%s%s%s",
		((USR->u_lock & UNLOCK) == UNLOCK) ? " unlocked" : "",
		((USR->u_lock & PROCLOCK) == PROCLOCK) ? " proc" : "",
		((USR->u_lock & TXTLOCK) == TXTLOCK) ? " text" : "",
		((USR->u_lock & DATLOCK) == DATLOCK) ? " data" : "");
#endif
	printf("FILE I/O:\tfile offset: %ld, bytes: %u\n", USR->u_offset, USR->u_count);
#ifdef	WANT
	printf("\t\tsegment: %s,", USR->u_segflg == 0 ? "data" :
		(USR->u_segflg == 1 ? "sys" : "text"));
	printf(" umask: %#03o, ulimit: %ld\n", USR->u_cmask, USR->u_limit);
	printf("ACCOUNTING:\t");
	printf("command: %.14s, memory: %ld, type: %s%s%s%s\n\t\tstart: %s",
		procslot ? USR->u_comm : "swapper",
		USR->u_mem, USR->u_acflag & AFORK ? "fork" : "exec",
		USR->u_acflag & ASU ? " su-user" : "",
		USR->u_exdata.ux_mag == VAXWRMAGIC ? " lpd" : "",
		USR->u_exdata.ux_mag == VAXROMAGIC ? " rd/only-txt" : "",

		ctime(&USR->u_start.tv_sec));
	printf("OPEN FILES:\t");
	printf("file desc: ");
	for(i = 0; i < NOFILE; i++)
		if(USR->u_ofile[i] != 0)
			printf(" %3d", i);
	printf("\n\t\tfile slot: ");
	for(i = 0; i < NOFILE; i++)
		if(USR->u_ofile[i] != 0)
			printf(" %3d", ((unsigned)USR->u_ofile[i] -
				File->n_value) / sizeof (struct file));
#endif
	printf("\n");
}

char *
getuarea(pp)
	struct proc *pp;	/* virtual address of proc slot */
{
	struct proc p;
	register struct user *up;
	static char pagealign[(UPAGES*NBPG)+(CLBYTES-1)];
	char *u = (char *)(((int)pagealign + (CLBYTES-1)) &~ (CLBYTES-1));
	static struct ucred cred;

	if( readv(pp, &p, sizeof (struct proc)) != sizeof (struct proc) ) 
		return BADREAD;
	if (p.p_stat == NULL)
		return NULL;
	if (p.p_flag & SLOAD) {
		if( readv(USERTOUB(p.p_uarea), u, UPAGES*NBPG) != UPAGES*NBPG)
			return BADREAD;
	} else if (live && swapfd) {
			lseek(swapfd, (long)dtob(p.p_swaddr), 0);
			if (read(swapfd, (char *)u, UPAGES*NBPG) != UPAGES*NBPG)
				return BADREAD;
	} else
		return SWAPPED;

	/*
	 * Got the uarea, see about getting the cred structure.
	 */
	up = UBTOUSER(u);
	if (readv(up->u_cred, &cred, sizeof(cred)) != sizeof(cred))
		return BADREAD;
	up->u_cred = &cred;
	return u;
}
