home *** CD-ROM | disk | FTP | other *** search
- /*
- * ustruct.c -- read user structure for finger
- *
- * Copyright (C) 1986, 1990 Philip L. Budne
- *
- * This file is part of "Phil's Finger Program".
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
- *
- */
-
- /* WISH: Perhaps split into one file per O/S?
- * The copyright overhead would horrific!!
- */
-
- # ifndef lint
- static char *rcsid = "$Id: ustruct.c,v 3.0 90/07/06 13:12:12 budd Rel $";
- # endif /* lint not defined */
-
- # include "finger.h"
-
- # ifndef Umax
- # include <stdio.h>
-
- # include "ustruct.h"
-
- # include "kmem.h"
- # include "info.h" /* after finger.h */
-
- /*# define DEBUG_USTRUCT /**/
-
- # ifdef DEBUG_USTRUCT
- # define DEB(x) x
- # else /* DEBUG_USTRUCT not defined */
- # define DEB(x)
- # endif /* DEBUG_USTRUCT not defined */
-
- LOCAL initialized = FALSE;
- extern struct info I; /* namelist values from names.c */
-
- extern FTYPE kmem; /* fd for /dev/kmem */
- # if SunOS < 400
- extern FTYPE mem; /* fd for /dev/mem */
- extern FTYPE drum; /* fd for /dev/drum */
- /* from kmem.c */
-
- # if !defined(NBPG) && defined(NBPP)
- # define NBPG NBPP
- # endif /* !defined(NBPG) && defined(NBPP) */
-
- # ifndef UPAGES
- # ifdef USIZE
- # define UPAGES USIZE /* SVR3 */
- # else /* USIZE not defined */
- # define UPAGES ((sizeof(struct user)+NBPG-1)/NBPG) /* ?? */
- # endif /* USIZE not defined */
- # endif /* UPAGES not defined */
-
- # ifndef ibm032 /* not IBM RT */
- LOCAL union {
- struct user U;
- # ifdef NBPG
- char upages[UPAGES][NBPG];
- # endif /* NBPG defined */
- } _u;
-
- # define u _u.U
- # else /* ibm032 defined */
-
- LOCAL union {
- struct {
- char padding[ UPAGES*NBPG - sizeof( struct user ) ];
- struct user U;
- } _U;
- char upages[UPAGES][NBPG];
- } _u;
- # define u _u._U.U
- # endif /* ibm032 defined */
-
- # if !defined(accel) && !defined(USG)
- # define NEED_UPAGEMAP /* most BSD systems */
- # ifndef NEED_USRPT
- LOCAL struct pte upagemap[ UPAGES ]; /* pte's for ustruct */
- # else /* NEED_USRPT defined */
- LOCAL struct pte upagemap[ NPTEPG ]; /* one page of pte's for ustruct */
- LOCAL struct pte *Usrptmap; /* map for usrpt */
- LOCAL struct pte *usrpt; /* user page map */
- # endif /* NEED_USRPT defined */
- # endif /* !defined(accel) && !defined(USG) */
-
- /****************************************************************/
-
- LOCAL void u_init() {
- # ifdef NEED_USRPT
- /* assumes readnames() called */
- Usrptmap = (struct pte *) I.info_Usrptmap;
- usrpt = (struct pte *) I.info_usrpt;
- # endif /* NEED_USRPT defined */
- initialized = TRUE;
- } /* u_init */
- # endif /* SunOS < 400 */
-
- /****************************************************************/
-
- GLOBAL void u_cleanup() {
- } /* u_cleanup */
-
- /****************************************************************/
-
- # undef HAVE_USTRUCT /* sure wish #elif was ubiquitous!! */
-
- # if SunOS >= 400
- # define HAVE_USTRUCT
- LOCAL struct user *ustruct2( mpp ) /* find & read in the user structure */
- struct proc *mpp;
- {
- return( kvm_getu( kmem, mpp ) );
- }
- # endif /* SunOS >= 400 */
-
- /****************/
-
- # ifdef sgi
- # define HAVE_USTRUCT
- LOCAL struct user *ustruct2( mpp ) /* find & read in the user structure */
- struct proc *mpp;
- {
- if( syssgi( SGI_RDUBLK, mpp->p_pid, &u, sizeof( _u ) ) < 0 )
- return( NULL );
- return( &u );
- }
- # endif /* sgi defined */
-
- # ifdef SYSI86 /* Interactive 386/ix */
- # define HAVE_USTRUCT
- LOCAL struct user *ustruct2( mpp ) /* find & read in the user structure */
- struct proc *mpp;
- {
- if( sysi86( RDUBLK, mpp->p_pid, &u, sizeof( _u ) ) < 0 )
- return( NULL );
- return( &u );
- }
- # endif /* SYSI86 defined */
-
- # ifdef UmaxV
- # define HAVE_USTRUCT
-
- # ifdef ns32302 /* on DPC (32032) BPP is a lie */
- # define NPPP 4 /* Each "page" is 4 physical pages */
- # else /* ns32302 not defined */
- # define NPPP 1 /* APC: pages per physical page */
- # endif /* ns32302 not defined */
-
- LOCAL struct user *ustruct2( mpp ) /* find & read in the user structure */
- struct proc *mpp;
- {
- int i;
- for( i = 0; i < USIZE; i++ ) {
- int k;
- for( k = 0; k < NPPP; k++ ) {
- /* upages never swapped? */
- if( !mpp->p_ubptbl[i].pgm[k].pg_v ||
- !kread( mem,
- mpp->p_ubptbl[i].pgm[k].pg_pfn << PNUMSHFT,
- ((char *)_u.upages[i]) + k * NBPP/NPPP,
- NBPP/NPPP ) )
- return( NULL );
- } /* for k */
- } /* for i */
- return( &u );
- }
- # endif /* UmaxV defined */
-
- /****************/
-
- # ifdef AIX_RT
- # define HAVE_USTRUCT
- LOCAL struct user *ustruct2( mpp ) /* find & read in the user structure */
- struct proc *mpp;
- {
- int i, cc;
-
- /* seems that segids[n] always == n, but make sure!! */
- for( i = 0; i < mpp->p_segs.count; i++ )
- if( mpp->p_segs.p_segids[i].seg_reg == STACKSEG )
- break;
-
- if( i == mpp->p_segs.count || lseek( mem, I.info_u, 0 ) < 0 )
- return( NULL );
-
- i = mpp->p_segs.p_segids[i].seg_id; /* get VRM segment ID */
- cc = readx( mem, &_u, sizeof( _u ), i ); /* funky 4 arg read!! */
- if( cc < sizeof( _u ) )
- return( NULL );
- return( &u );
- }
- # endif /* AIX_RT defined */
-
- # ifdef AIX3
- # define HAVE_USTRUCT
- /* calls getuser directly in readpr() */
- # endif /* AIX3 defined */
-
- /****************/
-
- # ifdef AIX_PS2 /* yet another OS named AIX! */
- # define HAVE_USTRUCT
- LOCAL struct user *ustruct2( mpp ) /* find & read in the user structure */
- struct proc *mpp;
- {
- int i;
-
- if( (mpp->p_flag & SLOAD) == 0 ) { /* process is swapped */
- for( i = 0; i < UPAGES; i++ ) {
- printf("p_uswaddr[%d].dbd_type = %d\n",
- i, mpp->p_uswaddr[i].dbd_type );
- }
- }
-
- for( i = 0; i < UPAGES; i++ ) {
- long upage;
-
- upage = ctob( PFN( mpp->p_uaddr[i] ) );
- DEB( printf(" upage %d/%d at %#x\n", i+1, UPAGES, upage ) );
- if( ! kread(mem, upage, _u.upages[i], NBPG) )
- return( NULL );
- }
- }
- # endif /* AIX_PS2 defined */
-
- /****************
- * BSD systems
- */
-
- # if !defined(USG) && !defined(HAVE_USTRUCT)
- # define HAVE_USTRUCT
- LOCAL struct user *ustruct2( mpp ) /* find & read in the user structure */
- struct proc *mpp;
- {
- int i; /* loop index */
- # ifdef NEED_USRPT
- struct pte indirpte, *pte, *pumap;
- # endif /* NEED_USRPT defined */
-
- if( !initialized )
- u_init(); /* initialize ustruct reader */
-
- if( (mpp->p_flag & SLOAD) == 0 ) { /* process is swapped */
- long addr; /* disk address of ustruct */
-
- addr = dtob(mpp->p_swaddr); /* disk to bytes */
- DEB( printf(" ustruct from drum %#x\n", addr ) );
- if( ! kread(drum, addr, &u, sizeof(_u)) ) /* read from drum */
- return( NULL );
- return( &u );
- } /* is swapped */
-
-
- /****************************************************************
- * process loaded in core:
- */
-
- # ifdef accel
- /*
- * amazingly easy... p_addr is kernel address!!
- */
- if( ! KMEMREAD( mpp->p_addr, &u, sizeof(u)) ) /* read from kmem */
- return( NULL );
-
- # else /* accel not defined */
-
- # ifndef NEED_USRPT
- # ifdef sequent
- # define p_addr p_pttop
- # endif /* sequent defined */
- DEB( printf(" p_addr: %#x\n", mpp->p_addr ) );
- if( ! KMEMREAD( mpp->p_addr, upagemap, sizeof(upagemap)) )
- return( NULL );
- # else /* NEED_USRPT defined */
- /*
- * p_addr does not work on IBM RT ACIS/4.3;
- * read page table entry for uarea page map page from user pagemap
- */
-
- pte = &Usrptmap[ btokmx(mpp->p_p0br) + mpp->p_szpt - 1 ];
- DEB( printf(" indirpte pte at %#x\n", pte ) );
- if( ! KMEMREAD( (long)pte, &indirpte, sizeof(indirpte)) )
- return( NULL );
-
- /****************************************************************
- * read one page of ptes for user area page table
- */
- # ifndef ibm032
- /* for vax, sun: */
- pumap = (struct pte *) ctob( indirpte.pg_pfnum );
- # else /* ibm032 defined */
- # define REDPAGES 2 /* this is sick */
- pumap = ((struct pte *) ctob( indirpte.pg_pfnum + 1)) - (UPAGES+REDPAGES);
- # endif /* ibm032 defined */
-
- DEB( printf(" upagemap at %#x\n", pumap ) );
- if( ! kread(mem, pumap, upagemap, sizeof(upagemap)) )
- return( NULL );
- # endif /* NEED_USRPT defined */
-
- /* read actual user structure pages */
- for( i = 0; i < UPAGES; i++ ) { /* get u area pages */
- long upage; /* address of upage pagemap */
-
- # ifndef NEED_USRPT
- upage = ctob( upagemap[i].pg_pfnum );
- # else /* NEED_USRPT defined */
- # ifdef ibm032
- upage = ctob( upagemap[i+REDPAGES].pg_pfnum );
- # else /* ibm032 not defined */
- upage = ctob( upagemap[i+NPTEPG-UPAGES].pg_pfnum ); /* vax, sun */
- # endif /* ibm032 not defined */
- # endif /* NEED_USRPT defined */
- DEB( printf(" upage %d/%d at %#x\n", i+1, UPAGES, upage ) );
- if( ! kread(mem, upage, _u.upages[i], NBPG) )
- return( NULL );
- } /* for i */
- # endif /* accel not defined */
- return( &u );
- } /* ustruct2 */
- # endif /* !defined(USG) && !defined(HAVE_USTRUCT) */
-
- /****************/
-
- # ifndef HAVE_USTRUCT
- LOCAL struct user *ustruct2( mpp ) /* find & read in the user structure */
- struct proc *mpp;
- {
- return( NULL ); /* no generic USG solution */
- } /* ustruct2 */
- # endif /* HAVE_USTRUCT not defined */
-
- /****************/
-
- GLOBAL struct user *ustruct( mpp )
- struct proc *mpp;
- {
- struct user *upp;
- upp = ustruct2( mpp );
- DEB( if( upp != NULL ) printf(" u_ttyd: %#x\n", upp->u_ttyd ) );
- return( upp );
- } /* ustruct */
- # endif /* Umax not defined */
-
- /*
- * Local variables:
- * comment-column: 40
- * End:
- */
-