home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / sps3 / part03 / getcmd.c next >
Encoding:
C/C++ Source or Header  |  1992-05-08  |  7.5 KB  |  308 lines

  1. # ifndef lint
  2. static char SccsId[] =  "@(#)getcmd.c    1.8\t6/26/91" ;
  3. # endif
  4.  
  5. # include       "sps.h"
  6. # include       "flags.h"
  7. # ifdef KVM
  8. #  include      <kvm.h>
  9. #  include      <ctype.h>
  10. # else
  11. #  include      <h/vm.h>
  12. #  ifdef BSD42
  13. #   include    <machine/pte.h>
  14. #  else BSD42
  15. #   include      <h/pte.h>
  16. #  endif BSD42
  17. # endif KVM
  18.  
  19. /*
  20. ** GETCMD - Returns a character string read from a process' upage.
  21. ** This character string should represent the arguments to the current process.
  22. */
  23. char    *getcmd ( p )
  24.  
  25. register struct process         *p ;
  26.  
  27. {
  28. # ifdef KVM
  29.     char                    **ap ;
  30.     char                    *cp ;
  31.     char                    *sp ;
  32.     int            spsize ;
  33.     char                    **argv ;
  34.     char                    **env ;
  35.     extern kvm_t            *Flkvm ;
  36. # else
  37.     register int            *ip ;
  38.     register char           *cp ;
  39.     register char           *cp0 ;
  40.     struct dblock           db ;
  41.     struct pte              ptetbl[ UPAGES + CLSIZE ] ;
  42.     extern int              Flmem, Flswap ;
  43. # endif
  44.     unsigned                nbad ;
  45.     union
  46.     {
  47.         char            a_argc[ CLSIZE * NBPG ] ;
  48.         int             a_argi[ CLSIZE * NBPG / sizeof( int ) ] ;
  49.     } argbuf ;
  50.     extern struct flags     Flg ;
  51.     extern union userstate  User ;
  52.     char                    *strcat(), *strncpy(), *strsave() ;
  53.  
  54.     p->pr_csaved = 0 ;
  55.     p->pr_upag = 0 ;
  56.     if ( p->pr_p.p_stat == SZOMB )
  57.         return ( "** Exit **" ) ;
  58. # ifdef ULTRIX40
  59.     if ( !(p->pr_p.p_sched & SLOAD) && Flg.flg_o )
  60. # else
  61.     if ( !(p->pr_p.p_flag & SLOAD) && Flg.flg_o )
  62. # endif
  63.         return ( "** Swapped out **" ) ;
  64.     /* Find the process' upage */
  65. # ifdef KVM
  66.     if ( !getupage( p ) )           
  67. # else
  68.     if ( !getupage( p, ptetbl ) )           
  69. # endif
  70.         return ( "** No upage **" ) ;
  71.     p->pr_upag = 1 ;
  72.     /* Is this a system process ? */
  73. # ifdef ULTRIX40
  74.     if ( p->pr_p.p_type & SSYS )            
  75. # else
  76.     if ( p->pr_p.p_flag & SSYS )            
  77. # endif
  78.         switch ( p->pr_p.p_pid )
  79.         {
  80.             case 0 :
  81.                 return ( "Unix Swapper" ) ;
  82.             case 2 :
  83.                 return ( "Unix Pager" ) ;
  84. # ifdef SUNOS40
  85.             case 3 :
  86.             case 4 :
  87.                 return ( "Unix Idle" ) ;
  88. # endif
  89.             default :
  90.                 break ;
  91.         }
  92. # ifdef ULTRIX40
  93.     /* Reading the command arguments doesn't work on the DEC 3100 so
  94.        we resort to this kludge until one day it does. */
  95.     if ( 1 )
  96. # else ULTRIX40
  97.     if ( Flg.flg_c )
  98. # endif ULTRIX40
  99.     {
  100.         p->pr_csaved = 1 ;
  101.         (void)strncpy( argbuf.a_argc, User.u_us.u_comm,
  102.             sizeof( User.u_us.u_comm ) ) ;
  103.         argbuf.a_argc[ sizeof ( User.u_us.u_comm ) ] = '\0' ;
  104.         return ( strsave( argbuf.a_argc ) ) ;
  105.     }
  106.     
  107.  
  108. # ifdef KVM
  109.     spsize = sizeof( argbuf ) - 2 ;
  110.     if ( kvm_getcmd( Flkvm, &p->pr_p, &User.u_us, &argv,
  111.         Flg.flg_e ? &env : (char ***)NULL ) < 0 || argv == NULL )
  112.             goto getsysargs ;
  113.     p->pr_csaved = 1 ;
  114.     sp = argbuf.a_argc ;
  115.     nbad = 0 ;
  116.     ap = argv ;
  117.     while ( ap && *ap )
  118.     {
  119.         /* Copy one string from argv or env */
  120.         cp = *ap++ ;
  121.         while ( cp && *cp )
  122.             if ( isprint( *cp ) )
  123.                 /* Be careful not to overrun allocated array.
  124.                    Fix provided by Matti E Aarnio
  125.                    <mea@nic.funet.fi> */
  126.                 if ( --spsize > 0 )
  127.                     *sp++ = *cp++ ;
  128.                 else
  129.                     ++cp ;
  130.             else
  131.             {
  132.                 /* Replace control characters with ?'s */
  133.                 if ( ++nbad > 5 )
  134.                 {
  135.                     if ( --spsize > 0 )
  136.                           *sp++ = ' ' ;
  137.                       break ;
  138.                   }
  139.                 if ( --spsize > 0 )
  140.                     *sp++ = '?' ;
  141.                 cp++ ;
  142.             }
  143.         if (--spsize > 0)
  144.             *sp++ = ' ' ;
  145.         /* Check if at end of argv and user wants to see env */
  146.         if ( ap && *ap == 0 && Flg.flg_e && argv != 0 )
  147.         {
  148.             free( (char *) argv ) ;
  149.             argv = NULL ;
  150.             ap = env ;
  151.             if ( ap == NULL )
  152.                 break ;
  153.         }
  154.     }
  155.      if ( Flg.flg_e )
  156.                 free( (char*)env ) ;
  157.     while ( *--sp == ' ' )
  158.         *sp = '\0' ;
  159.     return ( strsave( argbuf.a_argc ) ) ;
  160. # else
  161.     /* Fix by Alexander Dupuy <dupuy@amsterdam.columbia.edu> */
  162.     /* Check for lack of stack, jack! (Sun 3.0 biod's) */
  163.     if (User.u_us.u_ssize == 0)
  164.         goto getsysargs ;
  165.     /* Look at the top of the upage to locate the command arguments.
  166.        The page is loaded if the process itself is loaded and the pte
  167.        contains is marked as valid. */
  168. # ifdef ULTRIX40
  169.     if ( (p->pr_p.p_sched & SLOAD)
  170. # else
  171.     if ( (p->pr_p.p_flag & SLOAD)
  172. # endif
  173.     && !ptetbl[0].pg_fod && ptetbl[0].pg_pfnum )
  174.     {       /* If the page is loaded, read the arguments from
  175.            physical memory. */
  176.         memseek( Flmem, (long)ctob( ptetbl[0].pg_pfnum ) ) ;
  177.         if ( read( Flmem, argbuf.a_argc, CLSIZE*NBPG ) != CLSIZE*NBPG )
  178.             return ( "** Memory read error **" ) ;
  179.     }
  180.     else                            
  181.     {       /* Otherwise the page is on the swap device */
  182. # ifdef ULTRIX40
  183.         vstodb( 0, ctod( CLSIZE ),&p->pr_p.p_smap, &db, 1 ) ;
  184. # else
  185.         vstodb( 0, ctod( CLSIZE ), &User.u_us.u_smap, &db, 1 ) ;
  186. # endif
  187. #  ifdef BSD42
  188.         swseek( (long)dtob( db.db_base ) ) ;
  189. #  else
  190.         swseek( (long)ctob( db.db_base ) ) ;
  191. #  endif
  192.         if ( Flg.flg_o )
  193.             return ( "** Swapped page **" ) ;
  194.         if ( read( Flswap, (char *)argbuf.a_argc, CLSIZE*NBPG )
  195.         != CLSIZE*NBPG )
  196.             return ( "** Swap device read error **" ) ;
  197.     }
  198.     /* Look down until the end of command arguments is found. */
  199.     ip = &argbuf.a_argi[ CLSIZE*NBPG / sizeof( int ) ] ;
  200.     ip -= 2 ;
  201.     while ( *--ip )
  202.         if ( ip == &argbuf.a_argi[0] )
  203.             goto getsysargs ;
  204.     p->pr_csaved = 1 ;
  205.     /* Process the command arguments, looking for nulls and unprintable
  206.        characters. */
  207.     cp0 = (char*)(ip + 1) ;
  208.     if ( !*cp0 )                    
  209.         cp0++ ;                 
  210.     if ( *cp0 )
  211.     {
  212.         nbad = 0 ;                      
  213.         for ( cp = cp0 ; cp < &argbuf.a_argc[ CLSIZE*NBPG ] ; cp++ )
  214.         {
  215.             *cp &= 0177 ;
  216.             if ( !*cp )             
  217.             {       /* Replace nulls with spaces */
  218.                 *cp = ' ' ;
  219.                 continue ;
  220.             }
  221.             if ( *cp < ' ' || *cp == 0177 )
  222.             {       /* Replace control characters with ?'s */
  223.                 if ( ++nbad > 5 )
  224.                 {
  225.                     *cp++ = ' ' ;
  226.                     break ;
  227.                 }
  228.                 *cp = '?' ;
  229.                 continue ;
  230.             }
  231.             if ( !Flg.flg_e && *cp == '=' )
  232.             {       /* Break on an `=' if we are not interested
  233.                    in the environment strings. */
  234.                 *cp = '\0' ;
  235.                 while ( cp > cp0 && *--cp != ' ' )
  236.                     *cp = '\0' ;
  237.                 break ;
  238.             }
  239.         }
  240.         while ( *--cp == ' ' )
  241.             *cp = '\0' ;
  242.         return ( strsave( cp0 ) ) ;
  243.     }
  244. # endif KVM
  245. getsysargs :
  246.     /* If the command arguments cannot be accessed from the user's memory
  247.        space, get the command name from the system's idea of what the
  248.        name should be. */
  249.     p->pr_csaved = 1 ;
  250.     argbuf.a_argc[0] = '(' ;
  251.     (void)strncpy( &argbuf.a_argc[1], User.u_us.u_comm,
  252.         sizeof( User.u_us.u_comm ) ) ;
  253.     argbuf.a_argc[ sizeof ( User.u_us.u_comm ) + 1 ] = '\0' ;
  254.     (void)strcat( &argbuf.a_argc[0], ")" ) ;
  255.     return ( strsave( argbuf.a_argc ) ) ;
  256. }
  257.  
  258. # ifndef KVM
  259. /*
  260. ** VSTODB - Given a base/size pair in virtual swap area,
  261. ** return a physical base/size pair which is the
  262. ** (largest) initial, physically contiguous block.
  263. /* This code is stolen from the kernel file /sys/sys/vm_drum.c.
  264. */
  265. vstodb ( vsbase, vssize, dmp, dbp, rev )
  266.  
  267. register int                    vsbase ;
  268. register int                    vssize;
  269. struct dmap                     *dmp ;
  270. register struct dblock          *dbp ;
  271. int                             rev ;
  272.  
  273. {
  274.     register int            blk ;
  275.     register swblk_t        *ip ;
  276. # ifdef BSD42
  277.     extern struct info      Info ;
  278. # endif
  279. # ifndef ULTRIX40
  280. # ifdef BSD42
  281.     blk = Info.i_dmmin ;
  282. # else
  283.     blk = DMMIN ;
  284. # endif
  285.     ip = dmp->dm_map ;
  286.     while ( vsbase >= blk )
  287.     {
  288.         vsbase -= blk ;
  289. # ifdef BSD42
  290.         if ( blk < Info.i_dmmax )
  291. # else
  292.         if ( blk < DMMAX )
  293. # endif
  294.             blk *= 2 ;
  295.         ip++ ;
  296.     }
  297. # else ULTRIX40
  298.     blk = Info.i_swapfrag ;
  299.     ip =  dmp->dm_map ;
  300.     ip += (vsbase/blk) ;
  301.         vsbase %= blk;
  302. # endif ULTRIX40
  303.  
  304.     dbp->db_size = vssize < blk - vsbase ? vssize : blk - vsbase ;
  305.     dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase);
  306. }
  307. # endif
  308.