home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume23
/
sps2
/
part01
/
getcmd.c
next >
Wrap
C/C++ Source or Header
|
1991-01-08
|
7KB
|
269 lines
# ifndef lint
static char SccsId[] = "@(#)getcmd.c 1.7\t8/6/90" ;
# endif
# include "sps.h"
# include "flags.h"
# ifdef KVM
# include <kvm.h>
# include <ctype.h>
# else
# include <h/vm.h>
# ifdef BSD42
# include <machine/pte.h>
# else BSD42
# include <h/pte.h>
# endif BSD42
# endif KVM
/*
** GETCMD - Returns a character string read from a process' upage.
** This character string should represent the arguments to the current process.
*/
char *getcmd ( p )
register struct process *p ;
{
# ifdef KVM
char **ap ;
char *cp ;
char *sp ;
char **argv ;
char **env ;
extern kvm_t *Flkvm ;
# else
register int *ip ;
register char *cp ;
register char *cp0 ;
struct dblock db ;
struct pte ptetbl[ UPAGES + CLSIZE ] ;
extern int Flmem, Flswap ;
# endif
unsigned nbad ;
union
{
char a_argc[ CLSIZE * NBPG ] ;
int a_argi[ CLSIZE * NBPG / sizeof( int ) ] ;
} argbuf ;
extern struct flags Flg ;
extern union userstate User ;
char *strcat(), *strncpy(), *strsave() ;
p->pr_csaved = 0 ;
p->pr_upag = 0 ;
if ( p->pr_p.p_stat == SZOMB )
return ( "** Exit **" ) ;
if ( !(p->pr_p.p_flag & SLOAD) && Flg.flg_o )
return ( "** Swapped out **" ) ;
/* Find the process' upage */
# ifdef KVM
if ( !getupage( p ) )
# else
if ( !getupage( p, ptetbl ) )
# endif
return ( "** No upage **" ) ;
p->pr_upag = 1 ;
/* Is this a system process ? */
if ( p->pr_p.p_flag & SSYS )
switch ( p->pr_p.p_pid )
{
case 0 :
return ( "Unix Swapper" ) ;
case 2 :
return ( "Unix Pager" ) ;
# ifdef SUNOS40
case 3 :
case 4 :
return ( "Unix Idle" ) ;
# endif
default :
break ;
}
# ifdef DEC3100
/* Reading the command arguments doesn't work on the DEC 3100 so
we resort to this kludge until one day it does. */
if ( 1 )
# else DEC3100
if ( Flg.flg_c )
# endif DEC3100
{
p->pr_csaved = 1 ;
(void)strncpy( argbuf.a_argc, User.u_us.u_comm,
sizeof( User.u_us.u_comm ) ) ;
argbuf.a_argc[ sizeof ( User.u_us.u_comm ) ] = '\0' ;
return ( strsave( argbuf.a_argc ) ) ;
}
# ifdef KVM
if ( kvm_getcmd( Flkvm, &p->pr_p, &User.u_us, &argv,
Flg.flg_e ? &env : (char ***)NULL ) < 0 || argv == NULL )
goto getsysargs ;
p->pr_csaved = 1 ;
sp = argbuf.a_argc ;
nbad = 0 ;
ap = argv ;
do {
/* Copy one string from argv or env */
for ( cp = *ap++; *cp; )
if ( isprint( *cp ) )
*sp++ = *cp++ ;
else
{
/* Replace control characters with ?'s */
if ( ++nbad > 5 )
{
*sp++ = ' ' ;
break ;
}
*sp++ = '?' ;
cp++ ;
}
*sp++ = ' ' ;
/* Check if at end of argv and user wants to see env */
if ( *ap == 0 && Flg.flg_e && argv != 0 )
{
free( (char *) argv ) ;
argv = NULL ;
ap = env ;
if ( ap == NULL )
break ;
}
} while ( *ap ) ;
if ( Flg.flg_e )
free( (char*)env ) ;
while ( *--sp == ' ' )
*sp = '\0' ;
return ( strsave( argbuf.a_argc ) ) ;
# else
/* Fix by Alexander Dupuy <dupuy@amsterdam.columbia.edu> */
/* Check for lack of stack, jack! (Sun 3.0 biod's) */
if (User.u_us.u_ssize == 0)
goto getsysargs ;
/* Look at the top of the upage to locate the command arguments.
The page is loaded if the process itself is loaded and the pte
contains is marked as valid. */
if ( (p->pr_p.p_flag & SLOAD)
&& !ptetbl[0].pg_fod && ptetbl[0].pg_pfnum )
{ /* If the page is loaded, read the arguments from
physical memory. */
memseek( Flmem, (long)ctob( ptetbl[0].pg_pfnum ) ) ;
if ( read( Flmem, argbuf.a_argc, CLSIZE*NBPG ) != CLSIZE*NBPG )
return ( "** Memory read error **" ) ;
}
else
{ /* Otherwise the page is on the swap device */
vstodb( 0, ctod( CLSIZE ), &User.u_us.u_smap, &db, 1 ) ;
# ifdef BSD42
swseek( (long)dtob( db.db_base ) ) ;
# else
swseek( (long)ctob( db.db_base ) ) ;
# endif
if ( Flg.flg_o )
return ( "** Swapped page **" ) ;
if ( read( Flswap, argbuf.a_argc, CLSIZE*NBPG ) != CLSIZE*NBPG )
return ( "** Swap device read error **" ) ;
}
/* Look down until the end of command arguments is found. */
ip = &argbuf.a_argi[ CLSIZE*NBPG / sizeof( int ) ] ;
ip -= 2 ;
while ( *--ip )
if ( ip == &argbuf.a_argi[0] )
goto getsysargs ;
p->pr_csaved = 1 ;
/* Process the command arguments, looking for nulls and unprintable
characters. */
cp0 = (char*)(ip + 1) ;
if ( !*cp0 )
cp0++ ;
if ( *cp0 )
{
nbad = 0 ;
for ( cp = cp0 ; cp < &argbuf.a_argc[ CLSIZE*NBPG ] ; cp++ )
{
*cp &= 0177 ;
if ( !*cp )
{ /* Replace nulls with spaces */
*cp = ' ' ;
continue ;
}
if ( *cp < ' ' || *cp == 0177 )
{ /* Replace control characters with ?'s */
if ( ++nbad > 5 )
{
*cp++ = ' ' ;
break ;
}
*cp = '?' ;
continue ;
}
if ( !Flg.flg_e && *cp == '=' )
{ /* Break on an `=' if we are not interested
in the environment strings. */
*cp = '\0' ;
while ( cp > cp0 && *--cp != ' ' )
*cp = '\0' ;
break ;
}
}
while ( *--cp == ' ' )
*cp = '\0' ;
return ( strsave( cp0 ) ) ;
}
# endif KVM
getsysargs :
/* If the command arguments cannot be accessed from the user's memory
space, get the command name from the system's idea of what the
name should be. */
p->pr_csaved = 1 ;
argbuf.a_argc[0] = '(' ;
(void)strncpy( &argbuf.a_argc[1], User.u_us.u_comm,
sizeof( User.u_us.u_comm ) ) ;
argbuf.a_argc[ sizeof ( User.u_us.u_comm ) + 1 ] = '\0' ;
(void)strcat( &argbuf.a_argc[0], ")" ) ;
return ( strsave( argbuf.a_argc ) ) ;
}
# ifndef KVM
/*
** VSTODB - Given a base/size pair in virtual swap area,
** return a physical base/size pair which is the
** (largest) initial, physically contiguous block.
/* This code is stolen from the kernel file /sys/sys/vm_drum.c.
*/
vstodb ( vsbase, vssize, dmp, dbp, rev )
register int vsbase ;
register int vssize;
struct dmap *dmp ;
register struct dblock *dbp ;
int rev ;
{
register int blk ;
register swblk_t *ip ;
# ifdef BSD42
extern struct info Info ;
# endif
# ifdef BSD42
blk = Info.i_dmmin ;
# else
blk = DMMIN ;
# endif
ip = dmp->dm_map ;
while ( vsbase >= blk )
{
vsbase -= blk ;
# ifdef BSD42
if ( blk < Info.i_dmmax )
# else
if ( blk < DMMAX )
# endif
blk *= 2 ;
ip++ ;
}
dbp->db_size = vssize < blk - vsbase ? vssize : blk - vsbase ;
dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase);
}
# endif