home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / finger / part05 / ustruct.c < prev   
Encoding:
C/C++ Source or Header  |  1992-04-03  |  9.1 KB  |  358 lines

  1. /*
  2.  * ustruct.c -- read user structure for finger
  3.  *
  4.  * Copyright (C) 1986, 1990  Philip L. Budne
  5.  *
  6.  * This file is part of "Phil's Finger Program".
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 1, or (at your option)
  11.  * any later version.
  12.  *
  13.  */
  14.  
  15. /* WISH: Perhaps split into one file per O/S?
  16.  * The copyright overhead would horrific!!
  17.  */
  18.  
  19. # ifndef lint
  20. static char *rcsid = "$Id: ustruct.c,v 3.0 90/07/06 13:12:12 budd Rel $";
  21. # endif /* lint not defined */
  22.  
  23. # include "finger.h"
  24.  
  25. # ifndef Umax
  26. # include <stdio.h>
  27.  
  28. # include "ustruct.h"
  29.  
  30. # include "kmem.h"
  31. # include "info.h"            /* after finger.h */
  32.  
  33. /*# define DEBUG_USTRUCT /**/
  34.  
  35. # ifdef DEBUG_USTRUCT
  36. # define DEB(x) x
  37. # else  /* DEBUG_USTRUCT not defined */
  38. # define DEB(x)
  39. # endif /* DEBUG_USTRUCT not defined */
  40.  
  41. LOCAL initialized = FALSE;
  42. extern struct info I;            /* namelist values from names.c */
  43.  
  44. extern FTYPE kmem;            /* fd for /dev/kmem */
  45. # if SunOS < 400
  46. extern FTYPE mem;            /* fd for /dev/mem */
  47. extern FTYPE drum;            /* fd for /dev/drum */
  48.                     /* from kmem.c */
  49.  
  50. # if !defined(NBPG) && defined(NBPP)
  51. # define NBPG NBPP
  52. # endif /* !defined(NBPG) && defined(NBPP) */
  53.  
  54. # ifndef UPAGES
  55. # ifdef USIZE
  56. # define UPAGES USIZE            /* SVR3 */
  57. # else  /* USIZE not defined */
  58. # define UPAGES ((sizeof(struct user)+NBPG-1)/NBPG) /* ?? */
  59. # endif /* USIZE not defined */
  60. # endif /* UPAGES not defined */
  61.  
  62. # ifndef ibm032                /* not IBM RT */
  63. LOCAL union {
  64.     struct user U;
  65. # ifdef NBPG
  66.     char upages[UPAGES][NBPG];
  67. # endif /* NBPG defined */
  68. } _u;
  69.  
  70. # define u _u.U
  71. # else  /* ibm032 defined */
  72.  
  73. LOCAL union {
  74.     struct {
  75.     char padding[ UPAGES*NBPG - sizeof( struct user ) ];
  76.     struct user U;
  77.     } _U;
  78.     char upages[UPAGES][NBPG];
  79. } _u;
  80. # define u _u._U.U
  81. # endif /* ibm032 defined */
  82.  
  83. # if !defined(accel) && !defined(USG)
  84. # define NEED_UPAGEMAP            /* most BSD systems */
  85. # ifndef NEED_USRPT
  86. LOCAL struct pte upagemap[ UPAGES ];    /* pte's for ustruct */
  87. # else  /* NEED_USRPT defined */
  88. LOCAL struct pte upagemap[ NPTEPG ];    /* one page of pte's for ustruct */
  89. LOCAL struct pte *Usrptmap;        /* map for usrpt */
  90. LOCAL struct pte *usrpt;        /* user page map */
  91. # endif /* NEED_USRPT defined */
  92. # endif /* !defined(accel) && !defined(USG) */
  93.  
  94. /****************************************************************/
  95.  
  96. LOCAL void u_init() {
  97. # ifdef NEED_USRPT
  98.     /* assumes readnames() called */
  99.     Usrptmap = (struct pte *) I.info_Usrptmap;
  100.     usrpt = (struct pte *) I.info_usrpt;
  101. # endif /* NEED_USRPT defined */
  102.     initialized = TRUE;
  103. } /* u_init */
  104. # endif /* SunOS < 400 */
  105.  
  106. /****************************************************************/
  107.  
  108. GLOBAL void u_cleanup() {
  109. } /* u_cleanup */
  110.  
  111. /****************************************************************/
  112.  
  113. # undef HAVE_USTRUCT            /* sure wish #elif was ubiquitous!! */
  114.  
  115. # if SunOS >= 400
  116. # define HAVE_USTRUCT
  117. LOCAL struct user *ustruct2( mpp )    /* find & read in the user structure */
  118. struct proc *mpp;
  119. {
  120.     return( kvm_getu( kmem, mpp ) );
  121. }
  122. # endif /* SunOS >= 400 */
  123.  
  124. /****************/
  125.  
  126. # ifdef sgi
  127. # define HAVE_USTRUCT
  128. LOCAL struct user *ustruct2( mpp )    /* find & read in the user structure */
  129. struct proc *mpp;
  130. {
  131.     if( syssgi( SGI_RDUBLK, mpp->p_pid, &u, sizeof( _u ) ) < 0 )
  132.     return( NULL );
  133.     return( &u );
  134. }
  135. # endif /* sgi defined */
  136.  
  137. # ifdef SYSI86                /* Interactive 386/ix  */
  138. # define HAVE_USTRUCT
  139. LOCAL struct user *ustruct2( mpp )    /* find & read in the user structure */
  140. struct proc *mpp;
  141. {
  142.     if( sysi86( RDUBLK, mpp->p_pid, &u, sizeof( _u ) ) < 0 )
  143.     return( NULL );
  144.     return( &u );
  145. }
  146. # endif /* SYSI86 defined */
  147.  
  148. # ifdef UmaxV
  149. # define HAVE_USTRUCT
  150.  
  151. # ifdef ns32302                /* on DPC (32032) BPP is a lie */
  152. # define NPPP 4                /* Each "page" is 4 physical pages */
  153. # else  /* ns32302 not defined */
  154. # define NPPP 1                /* APC: pages per physical page */
  155. # endif /* ns32302 not defined */
  156.  
  157. LOCAL struct user *ustruct2( mpp )    /* find & read in the user structure */
  158. struct proc *mpp;
  159. {
  160.     int i;
  161.     for( i = 0; i < USIZE; i++ ) {
  162.     int k;
  163.     for( k = 0; k < NPPP; k++ ) {
  164.         /* upages never swapped? */
  165.         if( !mpp->p_ubptbl[i].pgm[k].pg_v ||
  166.            !kread( mem,
  167.               mpp->p_ubptbl[i].pgm[k].pg_pfn << PNUMSHFT,
  168.               ((char *)_u.upages[i]) + k * NBPP/NPPP,
  169.               NBPP/NPPP ) )
  170.            return( NULL );
  171.     } /* for k */
  172.     } /* for i */
  173.     return( &u );
  174. }
  175. # endif /* UmaxV defined */
  176.  
  177. /****************/
  178.  
  179. # ifdef AIX_RT
  180. # define HAVE_USTRUCT
  181. LOCAL struct user *ustruct2( mpp )    /* find & read in the user structure */
  182. struct proc *mpp;
  183. {
  184.     int i, cc;
  185.  
  186.     /* seems that segids[n] always == n, but make sure!! */
  187.     for( i = 0; i < mpp->p_segs.count; i++ )
  188.     if( mpp->p_segs.p_segids[i].seg_reg == STACKSEG )
  189.         break;
  190.  
  191.     if( i == mpp->p_segs.count || lseek( mem, I.info_u, 0 ) < 0 )
  192.     return( NULL );
  193.  
  194.     i = mpp->p_segs.p_segids[i].seg_id;    /* get VRM segment ID */
  195.     cc = readx( mem, &_u, sizeof( _u ), i ); /* funky 4 arg read!! */
  196.     if( cc < sizeof( _u ) )
  197.     return( NULL );
  198.     return( &u );
  199. }
  200. # endif /* AIX_RT defined */
  201.  
  202. # ifdef AIX3
  203. # define HAVE_USTRUCT
  204. /* calls getuser directly in readpr() */
  205. # endif /* AIX3 defined */
  206.  
  207. /****************/
  208.  
  209. # ifdef AIX_PS2                /* yet another OS named AIX! */
  210. # define HAVE_USTRUCT
  211. LOCAL struct user *ustruct2( mpp )    /* find & read in the user structure */
  212. struct proc *mpp;
  213. {
  214.     int i;
  215.  
  216.     if( (mpp->p_flag & SLOAD) == 0 ) {    /* process is swapped */
  217.     for( i = 0; i < UPAGES; i++ ) {
  218.         printf("p_uswaddr[%d].dbd_type = %d\n",
  219.         i, mpp->p_uswaddr[i].dbd_type );
  220.     }
  221.     }
  222.  
  223.     for( i = 0; i < UPAGES; i++ ) {
  224.     long upage;
  225.  
  226.     upage = ctob( PFN( mpp->p_uaddr[i] ) );
  227.     DEB( printf("  upage %d/%d at %#x\n", i+1, UPAGES, upage ) );
  228.     if( ! kread(mem, upage, _u.upages[i], NBPG) )
  229.         return( NULL );
  230.     }
  231. }
  232. # endif /* AIX_PS2 defined */
  233.  
  234. /****************
  235.  * BSD systems
  236.  */
  237.  
  238. # if !defined(USG) && !defined(HAVE_USTRUCT)
  239. # define HAVE_USTRUCT
  240. LOCAL struct user *ustruct2( mpp )    /* find & read in the user structure */
  241. struct proc *mpp;
  242. {
  243.     int i;                /* loop index */
  244. # ifdef NEED_USRPT
  245.     struct pte indirpte, *pte, *pumap;
  246. # endif /* NEED_USRPT defined */
  247.  
  248.     if( !initialized )
  249.     u_init();            /* initialize ustruct reader */
  250.  
  251.     if( (mpp->p_flag & SLOAD) == 0 ) {    /* process is swapped */
  252.     long addr;            /* disk address of ustruct */
  253.  
  254.     addr = dtob(mpp->p_swaddr);    /* disk to bytes */
  255.     DEB( printf(" ustruct from drum %#x\n", addr ) );
  256.     if( ! kread(drum, addr, &u, sizeof(_u)) ) /* read from drum */
  257.         return( NULL );
  258.     return( &u );
  259.     } /* is swapped */
  260.  
  261.  
  262.     /****************************************************************
  263.      * process loaded in core:
  264.      */
  265.  
  266. # ifdef accel
  267.     /*
  268.      * amazingly easy... p_addr is kernel address!!
  269.      */
  270.     if( ! KMEMREAD( mpp->p_addr, &u, sizeof(u)) ) /* read from kmem */
  271.     return( NULL );
  272.  
  273. # else  /* accel not defined */
  274.  
  275. # ifndef NEED_USRPT
  276. # ifdef sequent
  277. # define p_addr p_pttop
  278. # endif /* sequent defined */
  279.     DEB( printf(" p_addr: %#x\n", mpp->p_addr ) );
  280.     if( ! KMEMREAD( mpp->p_addr, upagemap, sizeof(upagemap)) )
  281.     return( NULL );
  282. # else  /* NEED_USRPT defined */
  283.     /*
  284.      * p_addr does not work on IBM RT ACIS/4.3;
  285.      * read page table entry for uarea page map page from user pagemap
  286.      */
  287.  
  288.     pte = &Usrptmap[ btokmx(mpp->p_p0br) + mpp->p_szpt - 1 ];
  289.     DEB( printf(" indirpte pte at %#x\n", pte ) );
  290.     if( ! KMEMREAD( (long)pte, &indirpte, sizeof(indirpte)) )
  291.     return( NULL );
  292.  
  293.     /****************************************************************
  294.      * read one page of ptes for user area page table
  295.      */
  296. # ifndef ibm032
  297.     /* for vax, sun: */
  298.     pumap = (struct pte *) ctob( indirpte.pg_pfnum );
  299. # else  /* ibm032 defined */
  300. # define REDPAGES 2            /* this is sick */
  301.     pumap = ((struct pte *) ctob( indirpte.pg_pfnum + 1))  - (UPAGES+REDPAGES);
  302. # endif /* ibm032 defined */
  303.  
  304.     DEB( printf(" upagemap at %#x\n", pumap ) );
  305.     if( ! kread(mem, pumap, upagemap, sizeof(upagemap)) )
  306.     return( NULL );
  307. # endif /* NEED_USRPT defined */
  308.  
  309.     /* read actual user structure pages */
  310.     for( i = 0; i < UPAGES; i++ ) {    /* get u area pages */
  311.     long upage;            /* address of upage pagemap */
  312.  
  313. # ifndef NEED_USRPT
  314.     upage = ctob( upagemap[i].pg_pfnum );
  315. # else  /* NEED_USRPT defined */
  316. # ifdef ibm032
  317.     upage = ctob( upagemap[i+REDPAGES].pg_pfnum );
  318. # else  /* ibm032 not defined */
  319.     upage = ctob( upagemap[i+NPTEPG-UPAGES].pg_pfnum ); /* vax, sun */
  320. # endif /* ibm032 not defined */
  321. # endif /* NEED_USRPT defined */
  322.     DEB( printf("  upage %d/%d at %#x\n", i+1, UPAGES, upage ) );
  323.     if( ! kread(mem, upage, _u.upages[i], NBPG) )
  324.         return( NULL );
  325.     } /* for i */
  326. # endif /* accel not defined */
  327.     return( &u );
  328. } /* ustruct2 */
  329. # endif /* !defined(USG) && !defined(HAVE_USTRUCT) */
  330.  
  331. /****************/
  332.  
  333. # ifndef HAVE_USTRUCT
  334. LOCAL struct user *ustruct2( mpp )    /* find & read in the user structure */
  335. struct proc *mpp;
  336. {
  337.     return( NULL );            /* no generic USG solution */
  338. } /* ustruct2 */
  339. # endif /* HAVE_USTRUCT not defined */
  340.  
  341. /****************/
  342.  
  343. GLOBAL struct user *ustruct( mpp )
  344. struct proc *mpp;
  345. {
  346.     struct user *upp;
  347.     upp = ustruct2( mpp );
  348.     DEB( if( upp != NULL ) printf(" u_ttyd: %#x\n", upp->u_ttyd ) );
  349.     return( upp );
  350. } /* ustruct */
  351. # endif /* Umax not defined */
  352.  
  353. /*
  354.  * Local variables:
  355.  * comment-column: 40
  356.  * End:
  357.  */
  358.