home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume22 / u386mon / part04 < prev    next >
Text File  |  1991-08-13  |  51KB  |  1,920 lines

  1. Newsgroups: comp.sources.misc
  2. From: Warren Tucker <wht@n4hgf.Mt-Park.GA.US>
  3. Subject:  v22i006:  u386mon - Sys V Rel 3.x Performance Monitor rev 2.40, Part04/07
  4. Message-ID: <1991Aug14.011641.15333@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: 827b813d80b01d0dbc7f2a9c6050384d
  6. Date: Wed, 14 Aug 1991 01:16:41 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: Warren Tucker <wht@n4hgf.Mt-Park.GA.US>
  10. Posting-number: Volume 22, Issue 6
  11. Archive-name: u386mon/part04
  12. Environment: SYSVR3
  13. Supersedes: u386mon-2.20: Volume 14, Issue 54-58
  14.  
  15. #!/bin/sh
  16. # This is part 04 of u386mon.3.40
  17. # ============= detail.c ==============
  18. if test -f 'detail.c' -a X"$1" != X"-c"; then
  19.     echo 'x - skipping detail.c (File already exists)'
  20. else
  21. echo 'x - extracting detail.c (Text)'
  22. sed 's/^X//' << 'SHAR_EOF' > 'detail.c' &&
  23. X/*+-------------------------------------------------------------------------
  24. X    detail.c - UNIX 386 system monitor detail window
  25. X
  26. X  Defined functions:
  27. X    detail_init()
  28. X    detail_panel_cmd(cmd)
  29. X    detail_panel_update()
  30. X    detpanel_destroy()
  31. X    detpanel_extra_init()
  32. X    detpanel_extra_update()
  33. X    detpanel_ps_init(full43)
  34. X    detpanel_ps_update()
  35. X    detpanel_sio_init()
  36. X    detpanel_sio_update()
  37. X    detpanel_streams_init()
  38. X    detpanel_streams_update()
  39. X    detpanel_table_init()
  40. X    detpanel_table_update()
  41. X
  42. X--------------------------------------------------------------------------*/
  43. X/*+:EDITS:*/
  44. X/*:08-01-1991-23:34-wht@n4hgf-release 3.40 source control point */
  45. X/*:05-15-1991-17:22-wht@n4hgf-2.3 patches for SVR31 from nba@sysware.dk */
  46. X/*:04-16-1991-16:51-martin@hppcmart-Fix display problems */
  47. X/*:04-16-1991-02:24-martin@hppcmart-additions for SCO 3.2.2 */
  48. X/*:08-10-1990-14:12-jmd@p1so/wht@n4hgf-2.20-add Tandem Integrity S2 */
  49. X/*:08-07-1990-14:24-wht@n4hgf-nba@sysware.dk SVR31 updates */
  50. X/*:08-02-1990-15:36-wht@n4hgf-2.12-old curses hacks+minor 3.2 formalizations */
  51. X/*:07-28-1990-18:06-wht@n4hgf-2.10 release */
  52. X/*:07-10-1990-14:53-root@n4hgf-clear msg line on detail cmd - fix 24-line bug */
  53. X/*:06-27-1990-01:57-wht@n4hgf-1.10-incorporate suggestions from alpha testers */
  54. X/*:06-25-1990-17:34-wht@n4hgf-add detail extra for 25 line tubes */
  55. X/*:06-25-1990-04:14-wht@n4hgf-1.02-better error handling */
  56. X/*:06-24-1990-20:53-wht@n4hgf-v1.01-add ISC support thanks to peter@radig.de */
  57. X/*:06-21-1990-14:26-r@n4hgf-version x0.12 seems bug free */
  58. X/*:06-15-1990-18:32-wht@n4hgf-creation */
  59. X
  60. X#include "config.h"
  61. X#define M_TERMINFO
  62. X#include <curses.h>
  63. X#undef timeout /* conflict in curses.h and bootinfo.h per trb@ima.ima.isc.com */
  64. X#undef reg     /* per nba@sysware.dk */
  65. X#ifdef NATIVE_PANELS
  66. X# include <panel.h>
  67. X#else
  68. X# include "libpanel.h"
  69. X#endif
  70. X#include <signal.h>
  71. X#include <string.h>
  72. X#include <fcntl.h>
  73. X#include <nlist.h>
  74. X#include <errno.h>
  75. X#include <time.h>
  76. X#include <pwd.h>
  77. X#include <sys/types.h>
  78. X#include <utmp.h>
  79. X#include <sys/utsname.h>
  80. X#include <sys/stat.h>
  81. X#undef NGROUPS_MAX
  82. X#undef NULL
  83. X#include <sys/param.h>
  84. X#include <sys/tuneable.h>
  85. X#include <sys/sysinfo.h>
  86. X#include <sys/sysmacros.h>
  87. X#include <sys/immu.h>
  88. X#include <sys/region.h>
  89. X#if defined(mips)
  90. X#include <sys/sbd.h>
  91. X#endif
  92. X#include <sys/proc.h>
  93. X#include <sys/var.h>
  94. X
  95. X#include "nlsym.h"
  96. X#include "libkmem.h"
  97. X#include "libnlsym.h"
  98. X#include "u386mon.h"
  99. X
  100. X#define DPT_NONE        0
  101. X#define DPT_PS            1
  102. X#define DPT_PS_LONG        2
  103. X#define DPT_EXTRA        3
  104. X#define DPT_SIO            4
  105. X#define DPT_STREAMS        5
  106. X#define DPT_TABLE        6
  107. X#define DPT_WD            7
  108. X
  109. XPANEL *mkpanel();
  110. X
  111. Xextern PANEL *pscr;
  112. Xextern WINDOW *wscr;
  113. X
  114. XPANEL *pdet;
  115. XWINDOW *wdet = (WINDOW *)0;
  116. Xu_char detpanel_type = DPT_NONE;
  117. Xint detpanel_length;
  118. Xint detpanel_cols;
  119. X
  120. X/*+-------------------------------------------------------------------------
  121. X    detpanel_ps_init(full43)
  122. X--------------------------------------------------------------------------*/
  123. Xvoid
  124. Xdetpanel_ps_init(full43)
  125. Xint full43;
  126. X{
  127. X/*
  128. X#define DETAIL_PS_COLS ((LINES >= 43) ? EXTRA4_TLX - 1 : PER_SEC4_TLX)
  129. Xdetpanel_cols = DETAIL_PS_COLS;
  130. X*/
  131. X
  132. X#define DETAIL_PS_TLY ((LINES >= 43) ? ((full43)?PER_SEC_TLY:PER_SEC_TLY+14)\
  133. X                                     : PER_SEC_TLY)
  134. X
  135. X#define DETAIL_PS_LENGTH        (MSG_TLY - DETAIL_PS_TLY)
  136. X
  137. X    detpanel_length = DETAIL_PS_LENGTH;
  138. X    detpanel_cols = COLS;
  139. X    if(!(pdet = mkpanel(detpanel_length,detpanel_cols,DETAIL_PS_TLY,0,"ps")))
  140. X    {
  141. X        leave_text("cannot make detail panel",1);
  142. X    }
  143. X    show_panel(pdet);
  144. X    top_panel(pdet);
  145. X    wdet = panel_window(pdet);
  146. X    display_proc_stats(wdet,1);
  147. X
  148. X}    /* end of detpanel_ps_init */
  149. X
  150. X/*+-------------------------------------------------------------------------
  151. X    detpanel_ps_update()
  152. X--------------------------------------------------------------------------*/
  153. Xvoid
  154. Xdetpanel_ps_update()
  155. X{
  156. X    display_proc_stats(wdet,0);
  157. X}    /* end of detpanel_ps_update */
  158. X
  159. X/*+-------------------------------------------------------------------------
  160. X    detpanel_extra_init()
  161. X--------------------------------------------------------------------------*/
  162. Xvoid
  163. Xdetpanel_extra_init()
  164. X{
  165. X#define DETAIL_EXTRA_TLY        PER_SEC_TLY
  166. X#define DETAIL_EXTRA_LENGTH        (CMD_TLY - DETAIL_EXTRA_TLY)
  167. X
  168. X    detpanel_length = DETAIL_EXTRA_LENGTH;
  169. X    detpanel_cols = COLS;
  170. X    if(!(pdet = mkpanel(detpanel_length,detpanel_cols,DETAIL_EXTRA_TLY,0,"ex")))
  171. X    {
  172. X        leave_text("cannot make detail panel",1);
  173. X    }
  174. X    show_panel(pdet);
  175. X    top_panel(pdet);
  176. X    wdet = panel_window(pdet);
  177. X    display_var(wdet,0,EXTRA1_TLX);
  178. X#if defined(HAS_BOOTINFO)
  179. X    display_bootinfo(wdet,0,EXTRA2_TLX);
  180. X#endif
  181. X    display_tune(wdet,0,EXTRA3_TLX);
  182. X    display_proc(wdet,0,EXTRA4_TLX);
  183. X
  184. X}    /* end of detpanel_extra_init */
  185. X
  186. X/*+-------------------------------------------------------------------------
  187. X    detpanel_extra_update()
  188. X--------------------------------------------------------------------------*/
  189. Xvoid
  190. Xdetpanel_extra_update()
  191. X{
  192. X    display_proc(wdet,0,EXTRA4_TLX);
  193. X}    /* end of detpanel_extra_update */
  194. X
  195. X/*+-------------------------------------------------------------------------
  196. X    detpanel_streams_init()
  197. X    SCO only streams stats
  198. X--------------------------------------------------------------------------*/
  199. X#if defined(M_UNIX) || defined(SVR31)
  200. Xvoid
  201. Xdetpanel_streams_init()
  202. X{
  203. X#define DETAIL_STREAMS_TLY ((LINES >= 43) ? (PER_SEC_TLY+14) : PER_SEC_TLY)
  204. X#define DETAIL_STREAMS_LENGTH        (CMD_TLY - DETAIL_STREAMS_TLY)
  205. X
  206. X    detpanel_length = DETAIL_STREAMS_LENGTH;
  207. X    detpanel_cols = COLS;
  208. X    if(!(pdet = mkpanel(detpanel_length,detpanel_cols,
  209. X        DETAIL_STREAMS_TLY,0,"str")))
  210. X    {
  211. X        leave_text("cannot make detail panel",1);
  212. X    }
  213. X    show_panel(pdet);
  214. X    top_panel(pdet);
  215. X    wdet = panel_window(pdet);
  216. X    draw_streamscale_literals(wdet, 0, 0);
  217. X    update_streamscale(wdet, 1, 21, 79-39);
  218. X}    /* end of detpanel_streams_init */
  219. X
  220. X/*+-------------------------------------------------------------------------
  221. X    detpanel_streams_update()
  222. X--------------------------------------------------------------------------*/
  223. X
  224. Xvoid
  225. Xdetpanel_streams_update()
  226. X{
  227. X    update_streamscale(wdet, 1, 21, 79-39);
  228. X}    /* end of detpanel_streams_update */
  229. X#endif
  230. X
  231. X/*+-------------------------------------------------------------------------
  232. X    detpanel_wd_init()
  233. X    SCO 3.2.2 only WD Disk stats
  234. X--------------------------------------------------------------------------*/
  235. X#if defined(M_UNIX) && defined(SCO322)
  236. Xvoid
  237. Xdetpanel_wd_init()
  238. X{
  239. X#define DETAIL_WD_TLY ((LINES >= 43) ? (PER_SEC_TLY + 14) : PER_SEC_TLY)
  240. X#define DETAIL_WD_LENGTH        (CMD_TLY - DETAIL_WD_TLY)
  241. X
  242. X    detpanel_length = DETAIL_WD_LENGTH;
  243. X    detpanel_cols = COLS;
  244. X    if(!(pdet = mkpanel(detpanel_length,detpanel_cols,DETAIL_WD_TLY,0,"str")))
  245. X    {
  246. X        leave_text("cannot make detail panel",1);
  247. X    }
  248. X    show_panel(pdet);
  249. X    top_panel(pdet);
  250. X    wdet = panel_window(pdet);
  251. X    draw_wd_literals(wdet, 0, 0);
  252. X    update_wd(wdet, 1, 9, 79-28);
  253. X}    /* end of detpanel_wd_init */
  254. X#endif
  255. X/*+-------------------------------------------------------------------------
  256. X    detpanel_wd_update()
  257. X--------------------------------------------------------------------------*/
  258. X#if defined(M_UNIX) && defined(SCO322)
  259. Xvoid
  260. Xdetpanel_wd_update()
  261. X{
  262. X    update_wd(wdet, 1, 9, 79-28);
  263. X}    /* end of detpanel_wd_update */
  264. X#endif
  265. X
  266. X/*+-------------------------------------------------------------------------
  267. X    detpanel_table_init()
  268. X    SCO only table stats
  269. X--------------------------------------------------------------------------*/
  270. X#if defined(M_UNIX) || defined(SVR31)
  271. Xvoid
  272. Xdetpanel_table_init()
  273. X{
  274. X#define DETAIL_TABLE_TLY ((LINES >= 43) ? (PER_SEC_TLY+14) : PER_SEC_TLY)
  275. X#define DETAIL_TABLE_LENGTH        (CMD_TLY - DETAIL_TABLE_TLY)
  276. X
  277. X    detpanel_length = DETAIL_TABLE_LENGTH;
  278. X    detpanel_cols = COLS;
  279. X    if(!(pdet = mkpanel(detpanel_length,detpanel_cols,DETAIL_TABLE_TLY,0,"tab")))
  280. X    {
  281. X        leave_text("cannot make detail panel",1);
  282. X    }
  283. X    show_panel(pdet);
  284. X    top_panel(pdet);
  285. X    wdet = panel_window(pdet);
  286. X    draw_table_literals(wdet, 0, 0);
  287. X    update_table(wdet, 1, 15, 79-32);
  288. X}    /* end of detpanel_table_init */
  289. X
  290. X/*+-------------------------------------------------------------------------
  291. X    detpanel_table_update()
  292. X--------------------------------------------------------------------------*/
  293. X
  294. Xvoid
  295. Xdetpanel_table_update()
  296. X{
  297. X    update_table(wdet, 1, 15, 79-32);
  298. X}    /* end of detpanel_table_update */
  299. X#endif
  300. X
  301. X
  302. X/*+-------------------------------------------------------------------------
  303. X    detpanel_sio_init() - SCO only serial I/O display
  304. X--------------------------------------------------------------------------*/
  305. X#if defined(M_UNIX)
  306. Xvoid
  307. Xdetpanel_sio_init()
  308. X{
  309. X#define DETAIL_SIO_TLY ((LINES >= 43) ? (PER_SEC_TLY+14) : PER_SEC_TLY)
  310. X#define DETAIL_SIO_LENGTH        (CMD_TLY - DETAIL_SIO_TLY)
  311. X
  312. X    detpanel_length = DETAIL_SIO_LENGTH;
  313. X    detpanel_cols = COLS;
  314. X    if(!(pdet = mkpanel(detpanel_length,detpanel_cols,DETAIL_SIO_TLY,0,"sio")))
  315. X    {
  316. X        leave_text("cannot make detail panel",1);
  317. X    }
  318. X    show_panel(pdet);
  319. X    top_panel(pdet);
  320. X    wdet = panel_window(pdet);
  321. X    display_sio_summary(wdet,1);
  322. X}    /* end of detpanel_sio_init */
  323. X#endif
  324. X
  325. X/*+-------------------------------------------------------------------------
  326. X    detpanel_sio_update()
  327. X--------------------------------------------------------------------------*/
  328. X#if defined(M_UNIX)
  329. Xvoid
  330. Xdetpanel_sio_update()
  331. X{
  332. X    display_sio_summary(wdet,0);
  333. X}    /* end of detpanel_sio_update */
  334. X#endif
  335. X
  336. X/*+-------------------------------------------------------------------------
  337. X    detpanel_destroy()
  338. X--------------------------------------------------------------------------*/
  339. Xvoid
  340. Xdetpanel_destroy()
  341. X{
  342. X    hide_panel(pdet);
  343. X    delwin(wdet);
  344. X    wdet = (WINDOW *)0;
  345. X    del_panel(pdet);
  346. X    top_panel(pscr);
  347. X    disp_msg(cpINFO,"");
  348. X    detpanel_type = DPT_NONE;
  349. X}    /* end of detpanel_destroy */
  350. X
  351. X/*+-------------------------------------------------------------------------
  352. X    detail_panel_cmd(cmd)
  353. X
  354. X  command: m main screen
  355. X           p proc status
  356. X--------------------------------------------------------------------------*/
  357. Xvoid
  358. Xdetail_panel_cmd(cmd)
  359. Xchtype cmd;
  360. X{
  361. X    disp_msg(cpINFO,"");
  362. X    switch(cmd)
  363. X    {
  364. X        case 'm':
  365. X            if(detpanel_type != DPT_NONE)
  366. X                detpanel_destroy();
  367. X            break;
  368. X
  369. X        case 'P':
  370. X            if(detpanel_type == DPT_PS_LONG)
  371. X                break;
  372. X            if(detpanel_type != DPT_NONE)
  373. X                detpanel_destroy();
  374. X            detpanel_ps_init(1);
  375. X            detpanel_type = DPT_PS_LONG;
  376. X            break;
  377. X
  378. X        case 'p':
  379. X            if(detpanel_type == DPT_PS)
  380. X                break;
  381. X            if(detpanel_type != DPT_NONE)
  382. X                detpanel_destroy();
  383. X            detpanel_ps_init(0);
  384. X            detpanel_type = DPT_PS;
  385. X            break;
  386. X
  387. X        case 'e':
  388. X            if(LINES >= 43)
  389. X                break;
  390. X            if(detpanel_type == DPT_EXTRA)
  391. X                break;
  392. X            if(detpanel_type != DPT_NONE)
  393. X                detpanel_destroy();
  394. X            detpanel_extra_init();
  395. X            detpanel_type = DPT_EXTRA;
  396. X            break;
  397. X
  398. X#if defined(M_UNIX) || defined(SVR31)
  399. X        case 'n':
  400. X            if(detpanel_type == DPT_STREAMS)
  401. X                break;
  402. X            if(detpanel_type != DPT_NONE)
  403. X                detpanel_destroy();
  404. X            detpanel_streams_init();
  405. X            detpanel_type = DPT_STREAMS;
  406. X            break;
  407. X        case 't':
  408. X            if(detpanel_type == DPT_TABLE)
  409. X                break;
  410. X            if(detpanel_type != DPT_NONE)
  411. X                detpanel_destroy();
  412. X            detpanel_table_init();
  413. X            detpanel_type = DPT_TABLE;
  414. X            break;
  415. X#endif
  416. X#if defined(M_UNIX)
  417. X        case 's':
  418. X            if(detpanel_type == DPT_SIO)
  419. X                break;
  420. X            if(detpanel_type != DPT_NONE)
  421. X                detpanel_destroy();
  422. X            detpanel_sio_init();
  423. X            detpanel_type = DPT_SIO;
  424. X            break;
  425. X#if defined(SCO322)
  426. X        case 'w':
  427. X            if(detpanel_type == DPT_WD)
  428. X                break;
  429. X            if(detpanel_type != DPT_NONE)
  430. X                detpanel_destroy();
  431. X            detpanel_wd_init();
  432. X            detpanel_type = DPT_WD;
  433. X            break;
  434. X#endif
  435. X#endif
  436. X
  437. X    }
  438. X}    /* end of detail_panel_cmd */
  439. X
  440. X/*+-------------------------------------------------------------------------
  441. X    detail_panel_update()
  442. X--------------------------------------------------------------------------*/
  443. Xvoid
  444. Xdetail_panel_update()
  445. X{
  446. X    switch(detpanel_type)
  447. X    {
  448. X        case DPT_PS:
  449. X        case DPT_PS_LONG:
  450. X            detpanel_ps_update();
  451. X            break;
  452. X        case DPT_EXTRA:
  453. X            detpanel_extra_update();
  454. X            break;
  455. X#if defined(M_UNIX)
  456. X        case DPT_SIO:
  457. X            detpanel_sio_update();
  458. X            break;
  459. X#endif
  460. X#if defined(M_UNIX) || defined (SYSVR31)
  461. X        case DPT_STREAMS:
  462. X            detpanel_streams_update();
  463. X            break;
  464. X        case DPT_TABLE:
  465. X            detpanel_table_update();
  466. X            break;
  467. X#if defined(SCO322)
  468. X        case DPT_WD:
  469. X            detpanel_wd_update();
  470. X            break;
  471. X#endif
  472. X#endif
  473. X    }
  474. X}    /* end of detail_panel_update */
  475. X
  476. X/*+-------------------------------------------------------------------------
  477. X    detail_init()
  478. X--------------------------------------------------------------------------*/
  479. Xvoid
  480. Xdetail_init()
  481. X{
  482. X    det_proc_init();    /* see det_proc.c */
  483. X#if defined(M_UNIX) || defined(SVR31)
  484. X    init_stream();
  485. X    init_table();
  486. X#ifdef SCO322
  487. X    init_wd();
  488. X#endif
  489. X#endif
  490. X}    /* end of detail_init */
  491. X
  492. X/* vi: set tabstop=4 shiftwidth=4: */
  493. X/* end of detail.c */
  494. SHAR_EOF
  495. chmod 0644 detail.c ||
  496. echo 'restore of detail.c failed'
  497. Wc_c="`wc -c < 'detail.c'`"
  498. test 12411 -eq "$Wc_c" ||
  499.     echo 'detail.c: original size 12411, current size' "$Wc_c"
  500. fi
  501. # ============= det_proc.c ==============
  502. if test -f 'det_proc.c' -a X"$1" != X"-c"; then
  503.     echo 'x - skipping det_proc.c (File already exists)'
  504. else
  505. echo 'x - extracting det_proc.c (Text)'
  506. sed 's/^X//' << 'SHAR_EOF' > 'det_proc.c' &&
  507. X/*+-------------------------------------------------------------------------
  508. X    det_proc.c - UNIX V/386 system monitor proc status detail
  509. X    ...!{gatech,emory}!n4hgf!wht
  510. X
  511. X  Defined functions:
  512. X    det_proc_init()
  513. X    display_proc_stat(win,iproc,initial)
  514. X    display_proc_stats(win,initial)
  515. X    find_utmp_for_pgrp(pgrp)
  516. X    get_cpu_time_str(ticks)
  517. X    get_user(tproc,tuser)
  518. X    getpwent_and_enter(uid)
  519. X    init_uid_name_hash()
  520. X    pgrp_to_ttyname(pgrp)
  521. X    ppproc_pid_compare(ppp1,ppp2)
  522. X    read_and_sort_procs(initial)
  523. X    read_utmp()
  524. X    uid_name_enter(uid,name)
  525. X    uid_to_name(uid)
  526. X
  527. X--------------------------------------------------------------------------*/
  528. X/*+:EDITS:*/
  529. X/*:08-01-1991-23:34-wht@n4hgf-release 3.40 source control point */
  530. X/*:02-14-1991-11:26-martin@hppcmart-Whittle procs with no cpu time*/
  531. X/*:08-10-1990-14:12-jmd@p1so/wht@n4hgf-2.20-add Tandem Integrity S2 */
  532. X/*:08-07-1990-14:24-wht@n4hgf-nba@sysware.dk SVR31 updates */
  533. X/*:08-02-1990-15:36-wht@n4hgf-2.12-old curses hacks+minor 3.2 formalizations */
  534. X/*:08-01-1990-12:26-wht@n4hgf-2.11-try to support ISC 1.x.x */
  535. X/*:07-28-1990-18:06-wht@n4hgf-2.10 release */
  536. X/*:07-11-1990-03:45-root@n4hgf-faster proc table manipulation */
  537. X/*:06-27-1990-01:57-wht@n4hgf-1.10-incorporate suggestions from alpha testers */
  538. X/*:06-25-1990-04:14-wht@n4hgf-1.02-better error handling */
  539. X/*:06-24-1990-20:53-wht@n4hgf-v1.01-add ISC support thanks to peter@radig.de */
  540. X/*:06-21-1990-14:26-r@n4hgf-version x0.12 seems bug free */
  541. X/*:01-05-1989-13:27-wht-creation */
  542. X
  543. X#include "config.h"
  544. X#define M_TERMINFO
  545. X#include <curses.h>
  546. X#undef timeout /* conflict in curses.h and bootinfo.h per trb@ima.ima.isc.com */
  547. X#undef reg     /* per nba@sysware.dk */
  548. X#ifdef NATIVE_PANELS
  549. X# include <panel.h>
  550. X#else
  551. X# include "libpanel.h"
  552. X#endif
  553. X#include <signal.h>
  554. X#include <string.h>
  555. X#include <fcntl.h>
  556. X#include <nlist.h>
  557. X#include <errno.h>
  558. X#include <time.h>
  559. X#include <pwd.h>
  560. X#include <sys/types.h>
  561. X#include <utmp.h>
  562. X#include <sys/stat.h>
  563. X#undef NGROUPS_MAX
  564. X#undef NULL
  565. X#include <sys/param.h>
  566. X#include <sys/tuneable.h>
  567. X#include <sys/sysinfo.h>
  568. X#include <sys/sysmacros.h>
  569. X#include <sys/immu.h>
  570. X#include <sys/region.h>
  571. X#if defined(mips)
  572. X#define pg_pres pg_sv /* alias: MIPS pg_sv==page valid */
  573. X#include <sys/sbd.h>
  574. X#include <sys/pcb.h>
  575. X#endif
  576. X#include <sys/proc.h>
  577. X#include <sys/fs/s5dir.h>
  578. X#include <sys/user.h>
  579. X#include <sys/var.h>
  580. X#if defined(M_UNIX) && (defined(i386) || defined(i486)) && SYSI86_RDUBLK_WANTED
  581. X/* maybe someday, but not now */
  582. X# include <sys/sysi86.h>
  583. X#endif
  584. X
  585. X#include "nlsym.h"
  586. X#include "libkmem.h"
  587. X#include "libmem.h"
  588. X#include "libswap.h"
  589. X#include "libnlsym.h"
  590. X#include "u386mon.h"
  591. X
  592. Xextern int errno;
  593. X
  594. Xextern int nprocs;
  595. Xextern struct var v;
  596. Xextern struct proc *procs;
  597. Xextern struct proc *oldprocs;
  598. Xextern struct proc **pprocs;
  599. Xextern struct proc **poldprocs;
  600. X
  601. Xint mypid;
  602. Xint noldprocs = 0;
  603. Xint nprocs = 0;
  604. Xint max_procs_to_display;
  605. X
  606. Xstruct user user;
  607. X
  608. X#define min(a,b) (((a) > (b)) ? (b) : (a))
  609. X
  610. X#define MAX_UTMP 64
  611. Xint nutmps = 0;
  612. Xstruct utmp utmps[MAX_UTMP];
  613. X
  614. X/*+-------------------------------------------------------------------------
  615. X    ppproc_pid_compare(ppp1,ppp2)
  616. X--------------------------------------------------------------------------*/
  617. Xppproc_pid_compare(ppp1,ppp2)
  618. Xregister struct proc **ppp1;
  619. Xregister struct proc **ppp2;
  620. X{
  621. X    return((*ppp1)->p_pid - (*ppp2)->p_pid);
  622. X}    /* end of ppproc_pid_compare */
  623. X
  624. X/*+-------------------------------------------------------------------------
  625. X    read_and_sort_procs(initial)
  626. X--------------------------------------------------------------------------*/
  627. Xvoid
  628. Xread_and_sort_procs(initial)
  629. Xint initial;
  630. X{
  631. Xint iproc;
  632. Xregister char *cptr;
  633. Xregister struct proc *tproc;
  634. Xint omitted_one;
  635. Xchar omitted[80];
  636. X
  637. X    omitted[0] = 0;
  638. X    disp_msg(cpINFO,"");
  639. X    if(!initial)
  640. X    {
  641. X        (void)memcpy((char *)oldprocs,(char *)procs,
  642. X            v.v_proc * sizeof(struct proc));
  643. X        noldprocs = nprocs;
  644. X        (void)memcpy((char *)poldprocs,(char *)pprocs,
  645. X            noldprocs * sizeof(struct proc *));
  646. X    }
  647. X
  648. X/* read current procs */
  649. X    grok_proc();
  650. X
  651. X/* if slot not in use, force to end when sorting */
  652. X    nprocs = 0;
  653. X    for(iproc = 0; iproc < v.v_proc; iproc++)
  654. X    {
  655. X        tproc = pprocs[iproc];
  656. X        if(    (tproc->p_stat == 0) ||        /* if slot not in use, ... */
  657. X            (tproc->p_pid == 1)  ||        /* ... or proc is init, ... */
  658. X            (tproc->p_flag & SSYS))        /* ... or proc is system process */
  659. X        {                            /* eliminate from consideration */
  660. X            tproc->p_pid = 32767;    /* force below selected procs in qsort */
  661. X            continue;
  662. X        }
  663. X        nprocs++;
  664. X    }
  665. X
  666. X/* if too many procs, whittle zombies */
  667. X    if(nprocs > max_procs_to_display)
  668. X    {
  669. X        nprocs = 0;
  670. X        omitted_one = 0;
  671. X        for(iproc = 0; iproc < v.v_proc; iproc++)
  672. X        {
  673. X            tproc = pprocs[iproc];
  674. X            if(tproc->p_pid == 32767)    /* previously eliminated? */
  675. X                continue;
  676. X            else if(tproc->p_stat == SZOMB)
  677. X            {
  678. X                tproc->p_pid = 32767;
  679. X                omitted_one = 1;
  680. X                continue;
  681. X            }
  682. X            nprocs++;
  683. X        }
  684. X        if(omitted_one)
  685. X        {
  686. X            if(omitted[0])
  687. X                strcat(omitted,"/");
  688. X            strcat(omitted,"zombie");
  689. X        }
  690. X    }
  691. X
  692. X/* if still too many procs, whittle shells and gettys */
  693. X    if(nprocs > max_procs_to_display)
  694. X    {
  695. X        nprocs = 0;
  696. X        omitted_one = 0;
  697. X        for(iproc = 0; iproc < v.v_proc; iproc++)
  698. X        {
  699. X            tproc = pprocs[iproc];
  700. X            if(tproc->p_pid == 32767)    /* previously eliminated? */
  701. X                continue;
  702. X            else if(get_user(tproc,&user))
  703. X            {
  704. X                if( !strcmp(cptr = user.u_comm,"csh") ||
  705. X                    !strcmp(cptr,"sh")        ||
  706. X                    !strcmp(cptr,"ksh")        ||
  707. X                    !strcmp(cptr,"bash")    ||
  708. X                    !strcmp(cptr,"cron")    ||
  709. X                    !strcmp(cptr,"errdemon")||
  710. X                    !strcmp(cptr,"lpsched") ||
  711. X                    !strcmp(cptr,"logger")    ||
  712. X                    !strcmp(cptr,"getty")    ||
  713. X                    !strcmp(cptr,"uugetty")        )
  714. X                {
  715. X                    tproc->p_pid = 32767;
  716. X                    omitted_one = 1;
  717. X                    continue;
  718. X                }
  719. X            }
  720. X            nprocs++;
  721. X        }
  722. X        if(omitted_one)
  723. X        {
  724. X            if(omitted[0])
  725. X                strcat(omitted,"/");
  726. X            strcat(omitted,"shell/getty");
  727. X        }
  728. X    }
  729. X
  730. X/* if still too many procs, whittle swapped */
  731. X    if(nprocs > max_procs_to_display)
  732. X    {
  733. X        nprocs = 0;
  734. X        omitted_one = 0;
  735. X        for(iproc = 0; iproc < v.v_proc; iproc++)
  736. X        {
  737. X            tproc = pprocs[iproc];
  738. X            if(tproc->p_pid == 32767)    /* previously eliminated? */
  739. X                continue;
  740. X            else if(!(tproc->p_flag & SLOAD) && (tproc->p_stat != SRUN))
  741. X            {
  742. X                tproc->p_pid = 32767;
  743. X                omitted_one = 1;
  744. X                continue;
  745. X            }
  746. X            nprocs++;
  747. X        }
  748. X        if(omitted_one)
  749. X        {
  750. X            if(omitted[0])
  751. X                strcat(omitted,"/");
  752. X            strcat(omitted,"swapped");
  753. X        }
  754. X    }
  755. X
  756. X/* If still too many procs, get rid of processes not using the CPU
  757. X   This hilites the processes that are actually doing something
  758. X   if you have a lot */
  759. X
  760. X    if(nprocs > max_procs_to_display)
  761. X    {
  762. X        nprocs = 0;
  763. X        omitted_one = 0;
  764. X        for(iproc = 0; iproc < v.v_proc; iproc++)
  765. X        {
  766. X            tproc = pprocs[iproc];
  767. X            if(tproc->p_pid == 32767)    /* previously eliminated? */
  768. X                continue;
  769. X            else if(!tproc->p_cpu)
  770. X            {
  771. X                tproc->p_pid = 32767;
  772. X                omitted_one = 1;
  773. X                continue;
  774. X            }
  775. X            nprocs++;
  776. X        }
  777. X        if(omitted_one)
  778. X        {
  779. X            if(omitted[0])
  780. X                strcat(omitted,"/");
  781. X            strcat(omitted,"no cpu");
  782. X        }
  783. X    }
  784. X
  785. X
  786. X/* if still too many procs, whittle hard */
  787. X    if(nprocs > max_procs_to_display)
  788. X    {
  789. X        nprocs = 0;
  790. X        omitted_one = 0;
  791. X        for(iproc = 0; iproc < v.v_proc; iproc++)
  792. X        {
  793. X            tproc = pprocs[iproc];
  794. X            if(tproc->p_pid == 32767)    /* previously eliminated? */
  795. X                continue;
  796. X            else if(tproc->p_stat == SSLEEP)
  797. X            {
  798. X                tproc->p_pid = 32767;
  799. X                omitted_one = 1;
  800. X                continue;
  801. X            }
  802. X            nprocs++;
  803. X        }
  804. X        if(omitted_one)
  805. X        {
  806. X            if(omitted[0])
  807. X                strcat(omitted,"/");
  808. X            strcat(omitted,"sleeping");
  809. X        }
  810. X    }
  811. X
  812. X/* if still too many procs, truncate */
  813. X    if(nprocs > max_procs_to_display)
  814. X    {
  815. X        nprocs = max_procs_to_display;
  816. X        disp_msg(cpMED,"display size too small for all processes");
  817. X        omitted[0] = 0;
  818. X    }
  819. X    if(omitted[0])
  820. X    {
  821. X        strcat(omitted," procs omitted");
  822. X        disp_msg(cpLIT,omitted);
  823. X    }
  824. X
  825. X/* sort new procs array */
  826. X    (void)qsort((char *)pprocs,(unsigned)v.v_proc,
  827. X        sizeof(struct proc *),ppproc_pid_compare);
  828. X
  829. X    if(initial)
  830. X    {
  831. X        (void)memcpy((char *)oldprocs,(char *)procs,
  832. X            v.v_proc * sizeof(struct proc));
  833. X        noldprocs = nprocs;
  834. X        (void)memcpy((char *)poldprocs,(char *)pprocs,
  835. X            noldprocs * sizeof(struct proc *));
  836. X    }
  837. X
  838. X}    /* end of read_and_sort_procs */
  839. X
  840. X/*+-------------------------------------------------------------------------
  841. X    read_utmp()
  842. X--------------------------------------------------------------------------*/
  843. Xvoid
  844. Xread_utmp()
  845. X{
  846. Xint utmpfd;
  847. Xregister struct utmp *tutmp = utmps;
  848. X
  849. X    nutmps = 0;
  850. X    if((utmpfd = open("/etc/utmp",O_RDONLY,755)) < 0)
  851. X        leave_text("/etc/utmp open error",255);
  852. X
  853. X    while(read(utmpfd,(char *)(tutmp++),sizeof(struct utmp)) > 0)
  854. X    {
  855. X        /* ensure null termination
  856. X         * (clobbers 1st byte of ut_line, but we don't use it)
  857. X         */
  858. X        tutmp->ut_id[sizeof(tutmp->ut_id)] = 0;
  859. X        if(++nutmps == MAX_UTMP)
  860. X            leave_text("too many utmp entries for me to handle",1);
  861. X    }
  862. X    (void)close(utmpfd);
  863. X}    /* end of read_utmp */
  864. X
  865. X/*+-------------------------------------------------------------------------
  866. X    find_utmp_for_pgrp(pgrp)
  867. X--------------------------------------------------------------------------*/
  868. Xstruct utmp *
  869. Xfind_utmp_for_pgrp(pgrp)
  870. Xint pgrp;
  871. X{
  872. Xstruct utmp *tutmp = utmps;
  873. Xregister int count = nutmps;
  874. X
  875. X    while(count--)
  876. X    {
  877. X        if(tutmp->ut_pid == pgrp)
  878. X            return(tutmp);
  879. X        tutmp++;
  880. X    }
  881. X    return((struct utmp *)0);
  882. X}    /* end of find_utmp_for_pgrp */
  883. X
  884. X/*+-------------------------------------------------------------------------
  885. X    pgrp_to_ttyname(pgrp)
  886. X--------------------------------------------------------------------------*/
  887. Xchar *
  888. Xpgrp_to_ttyname(pgrp)
  889. Xint pgrp;
  890. X{
  891. Xregister itmp;
  892. Xstruct utmp *tutmp;
  893. X
  894. X    if(!(tutmp = find_utmp_for_pgrp(pgrp)))
  895. X    {
  896. X        read_utmp();
  897. X        tutmp = find_utmp_for_pgrp(pgrp);
  898. X    }
  899. X    if(!tutmp)
  900. X        return("??");
  901. X    else
  902. X    {
  903. X        itmp = strlen(tutmp->ut_id);
  904. X        return(&tutmp->ut_id[(itmp >= 2) ? (itmp - 2) : 0]);
  905. X    }
  906. X}    /* end of pgrp_to_ttyname */
  907. X
  908. X/*+-------------------------------------------------------------------------
  909. X    get_user(tproc,tuser) - read user struct for pid
  910. Xreturn 1 if successful, else 0 if not available
  911. X--------------------------------------------------------------------------*/
  912. Xint
  913. Xget_user(tproc,tuser)
  914. Xstruct proc *tproc;
  915. Xstruct user *tuser;
  916. X{
  917. X#if defined(RDUBLK)    /* see sysi86.h #include above */
  918. X    /* this system call is not returning 0 on success ?!? */
  919. X    return(!!sysi86(RDUBLK,tproc->p_pid,(char *)tuser,sizeof(*tuser)));
  920. X#else /* RDUBLK */
  921. X    register caddr_t uptr = (caddr_t)tuser;
  922. X    register int ubrdcount = sizeof(struct user);
  923. X    int ipde;
  924. X    paddr_t mptr;
  925. X
  926. X#if !defined(ISC_1) && !defined(mips)
  927. X    if(tproc->p_flag & SULOAD)
  928. X    {
  929. X        for(ipde = 0;
  930. X#if defined(SVR31)
  931. X            ipde < USIZE;
  932. X#else
  933. X            ipde < tproc->p_usize;
  934. X#endif
  935. X            ipde++)
  936. X        {
  937. X            if(!tproc->p_ubptbl[ipde].pgm.pg_pres)    /* if not resident */
  938. X                return(0);
  939. X            mptr = tproc->p_ubptbl[ipde].pgm.pg_pfn * NBPP;
  940. X            mread(uptr,(daddr_t)mptr,min(ubrdcount,NBPP));
  941. X            uptr += NBPP;
  942. X            if((ubrdcount -= NBPP) <= 0)
  943. X                break;
  944. X        }
  945. X    }
  946. X    else
  947. X    {
  948. X#if defined(SVR31)
  949. X        mptr = tproc->p_ubdbd [0].dbd_blkno * NBPSCTR;
  950. X#else
  951. X        mptr = tproc->p_ubdbd.dbd_blkno * NBPSCTR;
  952. X#endif
  953. X        sread(uptr,mptr,ubrdcount);
  954. X    }
  955. X#else /* ISC_1: a compromise first-attempt */
  956. X    for(ipde = 0; ipde < USIZE; ipde++)
  957. X    {
  958. X        if(!tproc->p_ubptbl[ipde].pgm.pg_pres)    /* if not resident */
  959. X            return(0);
  960. X        mptr = tproc->p_ubptbl[ipde].pgm.pg_pfn * NBPP;
  961. X        mread(uptr,(daddr_t)mptr,min(ubrdcount,NBPP));
  962. X        uptr += NBPP;
  963. X        if((ubrdcount -= NBPP) <= 0)
  964. X            break;
  965. X    }
  966. X#endif /* ISC_1 */
  967. X
  968. X    /*
  969. X     * we can get crap from swap if things change after we get
  970. X     * an address to read from, so validate user as best we can
  971. X     */
  972. X    return( (tuser->u_ruid == tproc->p_uid) ||
  973. X            (tuser->u_ruid == tproc->p_suid));
  974. X
  975. X#endif /* RDUBLK */
  976. X}    /* end of get_user */
  977. X
  978. X/*+-------------------------------------------------------------------------
  979. Xuid to username conversion; thanks for the idea to William LeFebvre
  980. X--------------------------------------------------------------------------*/
  981. X#define UID_NAME_HASH_SIZE    127    /* prime */
  982. X#define HASH_EMPTY            32767
  983. X#define HASHIT(i)            ((i) % UID_NAME_HASH_SIZE)
  984. X
  985. Xstruct uid_name_hash_entry {
  986. X    ushort uid;
  987. X    char name[10];
  988. X};
  989. X
  990. Xstruct uid_name_hash_entry uid_name_table[UID_NAME_HASH_SIZE];
  991. Xint uid_count = 0;
  992. X
  993. X/*+-------------------------------------------------------------------------
  994. X    init_uid_name_hash()
  995. X--------------------------------------------------------------------------*/
  996. Xvoid
  997. Xinit_uid_name_hash()
  998. X{
  999. Xregister int ihash = 0;
  1000. Xregister struct uid_name_hash_entry *hashent = uid_name_table;
  1001. X
  1002. X    while(ihash++ < UID_NAME_HASH_SIZE)
  1003. X    {
  1004. X        hashent->uid = HASH_EMPTY;
  1005. X        hashent++;
  1006. X    }
  1007. X}    /* end of init_uid_name_hash */
  1008. X
  1009. X/*+-------------------------------------------------------------------------
  1010. X    uid_name_enter(uid,name)
  1011. X--------------------------------------------------------------------------*/
  1012. Xint
  1013. Xuid_name_enter(uid,name)
  1014. Xregister ushort uid;
  1015. Xregister char *name;
  1016. X{
  1017. Xregister ushort table_uid;
  1018. Xregister int hashval;
  1019. X
  1020. X    if(++uid_count >= UID_NAME_HASH_SIZE - 1)
  1021. X        leave_text("too many user names for me to handle",1);
  1022. X
  1023. X    hashval = HASHIT(uid);
  1024. X    while((table_uid = uid_name_table[hashval].uid) != HASH_EMPTY)
  1025. X    {
  1026. X        if(table_uid == uid)
  1027. X            return(hashval);
  1028. X        hashval = (hashval + 1) % UID_NAME_HASH_SIZE;
  1029. X    }
  1030. X
  1031. X    uid_name_table[hashval].uid = uid;
  1032. X    (void)strncpy(uid_name_table[hashval].name,name,
  1033. X        sizeof(uid_name_table[0].name));
  1034. X
  1035. X    return(hashval);
  1036. X
  1037. X}    /* end of uid_name_enter */
  1038. X
  1039. X/*+-------------------------------------------------------------------------
  1040. X    getpwent_and_enter(uid)
  1041. X--------------------------------------------------------------------------*/
  1042. Xgetpwent_and_enter(uid)
  1043. Xregister ushort uid;
  1044. X{
  1045. Xregister int hashval;
  1046. Xregister struct passwd *pwd;
  1047. Xchar errant[10];
  1048. Xstruct passwd *getpwuid();
  1049. X
  1050. X    pwd = getpwuid(uid);
  1051. X    endpwent();
  1052. X    if(pwd)
  1053. X    {
  1054. X        hashval = uid_name_enter(pwd->pw_uid,pwd->pw_name);
  1055. X        return(hashval);
  1056. X    }
  1057. X    (void)sprintf(errant,"%u",uid);
  1058. X    return(uid_name_enter(uid,errant));
  1059. X}    /* end of getpwent_and_enter */
  1060. X
  1061. X/*+-------------------------------------------------------------------------
  1062. X    uid_to_name(uid)
  1063. X--------------------------------------------------------------------------*/
  1064. Xchar *
  1065. Xuid_to_name(uid)
  1066. Xregister ushort uid;
  1067. X{
  1068. Xregister int uid_hash;
  1069. Xregister ushort table_uid;
  1070. X
  1071. X    uid_hash = HASHIT(uid);
  1072. X    while((table_uid = uid_name_table[uid_hash].uid) != uid)
  1073. X    {
  1074. X        if(table_uid == HASH_EMPTY)
  1075. X        {
  1076. X            /* not in hash table */
  1077. X            uid_hash = getpwent_and_enter(uid);
  1078. X            break;        /* out of while */
  1079. X        }
  1080. X        uid_hash = (uid_hash + 1) % UID_NAME_HASH_SIZE;
  1081. X    }
  1082. X    return(uid_name_table[uid_hash].name);
  1083. X}    /* end of uid_to_name */
  1084. X
  1085. X/*+-----------------------------------------------------------------------
  1086. X    char *get_cpu_time_str(ticks)
  1087. X  6-char static string address is returned
  1088. X------------------------------------------------------------------------*/
  1089. Xchar *
  1090. Xget_cpu_time_str(ticks)
  1091. Xtime_t ticks;
  1092. X{
  1093. Xstatic char timestr[10];
  1094. Xtime_t mm,ss;
  1095. Xextern int hz;
  1096. X
  1097. X    ticks /= hz;
  1098. X    mm = ticks / 60L;
  1099. X    ticks -= mm * 60L;
  1100. X    ss = ticks;
  1101. X
  1102. X    if(mm > 9999)
  1103. X        (void)strcpy(timestr,">9999m");
  1104. X    else if(mm > 999)
  1105. X        (void)sprintf(timestr,"%5ldm",mm);
  1106. X    else
  1107. X        (void)sprintf(timestr,"%3lu:%02lu",mm,ss);
  1108. X
  1109. X    return(timestr);
  1110. X
  1111. X}    /* end of get_cpu_time_str */
  1112. X
  1113. X#define PROC_Y        1
  1114. X#define PROC_X        0
  1115. X#define UID_X        2
  1116. X#define PID_X        12
  1117. X#define CPU_X        18
  1118. X#define PRI_X        22
  1119. X#define NICE_X        26
  1120. X#define UTIME_X        29
  1121. X#define STIME_X        36
  1122. X#define SIZE_X        43
  1123. X#define TTY_X        48
  1124. X#define CMD_X        52
  1125. X
  1126. X/*+-------------------------------------------------------------------------
  1127. X    display_proc_stat(win,iproc,initial)
  1128. X00000000001111111111222222222233333333334444444444555555555566666666667777777777
  1129. X01234567890123456789012345678901234567890123456789012345678901234567890123456789
  1130. XS     USER   PID  CPU PRI NI  UCPU   SCPU  SIZE TTY CMD
  1131. X#!########X ##### ### ### ## ###### ###### #### ### ########
  1132. X--------------------------------------------------------------------------*/
  1133. Xvoid
  1134. Xdisplay_proc_stat(win,iproc,initial)
  1135. XWINDOW *win;
  1136. Xregister int iproc;
  1137. Xregister int initial;
  1138. X{
  1139. Xregister int positioned = 0;
  1140. Xregister struct proc *tproc = pprocs[iproc];
  1141. Xstruct proc          *oproc = poldprocs[iproc];
  1142. Xint got_user;
  1143. Xstatic char *p_stat_str = " sRzdipx";    /* dependent on values of SSLEEP etc */
  1144. Xchar buf[20];
  1145. X
  1146. X    use_cp(win,cpINFO);
  1147. X    if((tproc->p_stat == SRUN) && !(tproc->p_flag & SLOAD))
  1148. X        use_cp(win,cpHIGH);
  1149. X    else if(tproc->p_stat == SRUN)
  1150. X        use_cp(win,cpMED);
  1151. X    if(tproc->p_pid != tproc->p_pid)
  1152. X        initial = 1;
  1153. X
  1154. X    wmove(win,PROC_Y + iproc,PROC_X);
  1155. X    waddch(win,(chtype)p_stat_str[tproc->p_stat]);
  1156. X    waddch(win,(tproc->p_flag & SLOAD) ? (chtype)' ' : (chtype)'S');
  1157. X    positioned = 1;
  1158. X
  1159. X    if(initial)
  1160. X    {
  1161. X        if(!positioned)
  1162. X            wmove(win,PROC_Y + iproc,PROC_X + UID_X);
  1163. X        (void)sprintf(buf,"%8s",uid_to_name(tproc->p_uid));
  1164. X        waddstr(win,buf);
  1165. X        waddch(win,(tproc->p_uid != tproc->p_suid) ? '#' : ' ');
  1166. X        waddch(win,' ');
  1167. X        positioned = 1;
  1168. X    }
  1169. X    else
  1170. X        positioned = 0;
  1171. X
  1172. X    if(initial)
  1173. X    {
  1174. X        if(!positioned)
  1175. X            wmove(win,PROC_Y + iproc,PROC_X + PID_X);
  1176. X        (void)sprintf(buf,"%5d ",tproc->p_pid);
  1177. X        waddstr(win,buf);
  1178. X        positioned = 1;
  1179. X    }
  1180. X    else
  1181. X        positioned = 0;
  1182. X
  1183. X    if(initial || (tproc->p_cpu != oproc->p_cpu))
  1184. X    {
  1185. X        if(!positioned)
  1186. X            wmove(win,PROC_Y + iproc,PROC_X + CPU_X);
  1187. X        (void)sprintf(buf,"%3u ",tproc->p_cpu);
  1188. X        waddstr(win,buf);
  1189. X        positioned = 1;
  1190. X    }
  1191. X    else
  1192. X        positioned = 0;
  1193. X
  1194. X    if(initial || (tproc->p_pri != oproc->p_pri))
  1195. X    {
  1196. X        if(!positioned)
  1197. X            wmove(win,PROC_Y + iproc,PROC_X + PRI_X);
  1198. X        (void)sprintf(buf,"%3u ",tproc->p_pri);
  1199. X        waddstr(win,buf);
  1200. X        positioned = 1;
  1201. X    }
  1202. X    else
  1203. X        positioned = 0;
  1204. X
  1205. X    if(initial || (tproc->p_nice != oproc->p_nice))
  1206. X    {
  1207. X        if(!positioned)
  1208. X            wmove(win,PROC_Y + iproc,PROC_X + NICE_X);
  1209. X        (void)sprintf(buf,"%2d ",tproc->p_nice);
  1210. X        waddstr(win,buf);
  1211. X        positioned = 1;
  1212. X    }
  1213. X    else
  1214. X        positioned = 0;
  1215. X
  1216. X/* since not saving user area, always update fields from it */
  1217. X    if(!positioned)
  1218. X        wmove(win,PROC_Y + iproc,PROC_X + UTIME_X);
  1219. X    if(got_user = get_user(tproc,&user))
  1220. X    {
  1221. X        waddstr(win,get_cpu_time_str(user.u_utime));
  1222. X        waddch(win,' ');
  1223. X        waddstr(win,get_cpu_time_str(user.u_stime));
  1224. X        waddch(win,' ');
  1225. X/*
  1226. X * process size:
  1227. X *
  1228. X * There are ways that seem right to a man, but the end of them is death.
  1229. X * u_tsize and friends are not clicks, but in bytes.
  1230. X * I thought this would have been:
  1231. X *        (ctob((u_long)user.u_tsize + user.u_dsize + user.u_ssize)) / 1024);
  1232. X * At least this makes numbers agree with /bin/ps, although I cannot
  1233. X * figure out why there is one extra page charged by ps (user is 2 pages).
  1234. X *
  1235. X *
  1236. X * This was evidentally wrong in SCO UNIX 3.2.0 and fixed in 3.2.1.
  1237. X * If you get lots of processes who size is reported as 4, define
  1238. X * USIZE_FIXED
  1239. X */
  1240. X        (void)sprintf(buf,"%4lu ",
  1241. X#if !defined(M_UNIX) /* !SCO */
  1242. X    /*
  1243. X    ** For ISC:
  1244. X    ** Reports exactly the same value as ps.  The values in the user
  1245. X    ** area seem totally bogus (u_tsize is always 0, from observation)
  1246. X    ** so this size, the program swap size, seems the best measure.
  1247. X    ** Without USIZE_FIXED, on ISC2.02/Dell UNIX 1.1 I get zeroes.
  1248. X    ** With USIZE_FIXED I get values, but they're way out (e.g. vpix
  1249. X    ** and cron shown as the same size....).
  1250. X    */
  1251. X            (u_long)tproc->p_size
  1252. X#else /* SCO */
  1253. X#if defined(USIZE_FIXED)    /* SCO UNIX 3.2.1 (and later?) */
  1254. X            (ctob((u_long)user.u_tsize + user.u_dsize + user.u_ssize)) / 1024
  1255. X#else                /* SCO UNIX 3.2.0 */
  1256. X            (((u_long)user.u_tsize + 511) / 1024) +
  1257. X            (((u_long)user.u_dsize + 511) / 1024) +
  1258. X            (((u_long)user.u_ssize + 511) / 1024) +
  1259. X            (((u_long)((user.u_tsize)?1:0) * NBPP) / 1024)
  1260. X#endif
  1261. X#endif /* SCO */
  1262. X        );
  1263. X        waddstr(win,buf);
  1264. X    }
  1265. X    else
  1266. X        waddstr(win,"------ ------ ---- ");
  1267. X
  1268. X/*
  1269. X    positioned = 1;
  1270. X    if(!positioned)
  1271. X        wmove(win,PROC_Y + iproc,PROC_X + TTY_X);
  1272. X*/
  1273. X    (void)sprintf(buf,"%3.3s ",pgrp_to_ttyname(tproc->p_pgrp));
  1274. X    waddstr(win,buf);
  1275. X    positioned = 1;
  1276. X
  1277. X/*
  1278. X    if(!positioned)
  1279. X        wmove(win,PROC_Y + iproc,PROC_X + CMD_X);
  1280. X*/
  1281. X    if(got_user)
  1282. X    {
  1283. X    register char *cptr = user.u_psargs;
  1284. X    int y,x,maxx = getmaxx(win);
  1285. X        getyx(win,y,x);
  1286. X        while(*cptr && (x < maxx))
  1287. X        {
  1288. X            *cptr &= 0x7F;
  1289. X            if(*cptr < 0x20)
  1290. X                *cptr = 0x20;
  1291. X            waddch(win,*cptr);
  1292. X            cptr++,x++;
  1293. X        }
  1294. X    }
  1295. X    else
  1296. X    {
  1297. X        switch(tproc->p_stat)
  1298. X        {
  1299. X            case SZOMB:
  1300. X                waddstr(win,"<zombie>");
  1301. X                break;
  1302. X            case SXBRK:
  1303. X                waddstr(win,"<xbreak>");
  1304. X                break;
  1305. X            case SIDL:
  1306. X                waddstr(win,"<in creation>");
  1307. X                break;
  1308. X            default:
  1309. X                waddstr(win,"<swapping>");
  1310. X        }
  1311. X    }
  1312. X
  1313. X    wclrtoeol(win);
  1314. X
  1315. X}    /* end of display_proc_stat */
  1316. X
  1317. X/*+-------------------------------------------------------------------------
  1318. X    display_proc_stats(win,initial)
  1319. X--------------------------------------------------------------------------*/
  1320. Xvoid
  1321. Xdisplay_proc_stats(win,initial)
  1322. XWINDOW *win;
  1323. Xint initial;
  1324. X{
  1325. Xregister int iproc;
  1326. Xint y,x;
  1327. X
  1328. X    touchwin (win);
  1329. X    if(initial)
  1330. X    {
  1331. X        use_cp(win,cpBANNER);
  1332. X        wmove(win,0,0);
  1333. X        waddstr(win,
  1334. X            "S     USER   PID  CPU PRI NI  UCPU   SCPU  SIZE TTY CMD");
  1335. X        getyx(win,y,x);
  1336. X        while(x < getmaxx(win))
  1337. X            waddch(win,(chtype)' '),x++;
  1338. X    }
  1339. X    mypid = getpid();
  1340. X    max_procs_to_display = getmaxy(win) - PROC_Y;
  1341. X    read_and_sort_procs(initial);
  1342. X    max_procs_to_display = min(nprocs,max_procs_to_display);
  1343. X    for(iproc = 0; iproc < max_procs_to_display; iproc++)
  1344. X        display_proc_stat(win,iproc,1);
  1345. X    wclrtobot(win);
  1346. X}    /* end of display_proc_stats */
  1347. X
  1348. X/*+-------------------------------------------------------------------------
  1349. X    det_proc_init()
  1350. X--------------------------------------------------------------------------*/
  1351. Xdet_proc_init()
  1352. X{
  1353. X    init_uid_name_hash();    /* see det_proc.c */
  1354. X}    /* end of det_proc_init */
  1355. X/* vi: set tabstop=4 shiftwidth=4: */
  1356. X/* end of det_proc.c */
  1357. SHAR_EOF
  1358. chmod 0644 det_proc.c ||
  1359. echo 'restore of det_proc.c failed'
  1360. Wc_c="`wc -c < 'det_proc.c'`"
  1361. test 21079 -eq "$Wc_c" ||
  1362.     echo 'det_proc.c: original size 21079, current size' "$Wc_c"
  1363. fi
  1364. # ============= det_sio.c ==============
  1365. if test -f 'det_sio.c' -a X"$1" != X"-c"; then
  1366.     echo 'x - skipping det_sio.c (File already exists)'
  1367. else
  1368. echo 'x - extracting det_sio.c (Text)'
  1369. sed 's/^X//' << 'SHAR_EOF' > 'det_sio.c' &&
  1370. X/*+-------------------------------------------------------------------------
  1371. X    det_sio.c - UNIX V/386 system monitor serial I/O detail
  1372. X    ...!{gatech,emory}!n4hgf!wht
  1373. X
  1374. X  Defined functions:
  1375. X    B_to_baud_rate(code)
  1376. X    cflag_to_baud_d_p_s(cflag)
  1377. X    grok_sio_tty()
  1378. X    display_siofull_init(win,tly,tlx,show_flag)
  1379. X    display_siofull_update(win,tly,tlx,tsio)
  1380. X    display_siosum_update(win,y,tsio)
  1381. X    tty_slot_compare(sio1,sio2)
  1382. X
  1383. X--------------------------------------------------------------------------*/
  1384. X/*+:EDITS:*/
  1385. X/*:08-01-1991-23:34-wht@n4hgf-release 3.40 source control point */
  1386. X/*:05-09-1991-03:35-wht@n4hgf-gcc gives good warning */
  1387. X/*:08-10-1990-14:12-jmd@p1so/wht@n4hgf-2.20-add Tandem Integrity S2 */
  1388. X/*:08-07-1990-14:24-wht@n4hgf-nba@sysware.dk SVR31 updates */
  1389. X/*:08-02-1990-15:36-wht@n4hgf-2.12-old curses hacks+minor 3.2 formalizations */
  1390. X/*:07-28-1990-18:06-wht@n4hgf-2.10 release */
  1391. X/*:06-27-1990-17:33-wht@n4hgf-fix bug during 24-line display */
  1392. X/*:06-27-1990-01:57-wht@n4hgf-1.10-incorporate suggestions from alpha testers */
  1393. X/*:06-26-1990-03:17-wht@n4hgf-creation */
  1394. X
  1395. X#include "config.h"
  1396. X#if defined(M_UNIX) /* SCO */
  1397. X#define M_TERMINFO
  1398. X#include <curses.h>
  1399. X#undef reg     /* per nba@sysware.dk */
  1400. X#ifdef NATIVE_PANELS
  1401. X# include <panel.h>
  1402. X#else
  1403. X# include "libpanel.h"
  1404. X#endif
  1405. X#include <string.h>
  1406. X#include <nlist.h>
  1407. X#include <sys/types.h>
  1408. X#include <sys/stat.h>
  1409. X#include <sys/ascii.h>
  1410. X#undef NGROUPS_MAX
  1411. X#undef NULL
  1412. X#include <sys/param.h>
  1413. X#include <sys/tty.h>
  1414. X
  1415. X#include "nlsym.h"
  1416. X#include "libkmem.h"
  1417. X#include "libmem.h"
  1418. X#include "libswap.h"
  1419. X#include "libnlsym.h"
  1420. X#include "u386mon.h"
  1421. X
  1422. Xextern int errno;
  1423. Xextern int sys_nerr;
  1424. Xextern char *sys_errlist[];
  1425. X
  1426. X#define SIO_NTTY 16    /* for now */
  1427. Xstruct tty sio[SIO_NTTY];
  1428. X
  1429. X#define t_slot    t_delct
  1430. X
  1431. Xint nsio;    /* number of sios open */
  1432. X
  1433. Xtypedef struct slabel
  1434. X{
  1435. X    int y,x;
  1436. X    char *label;
  1437. X} SLABEL;
  1438. X
  1439. XSLABEL tty_slabels[] =
  1440. X{
  1441. X    {  0,  0, "iflag:" },
  1442. X    {  2,  0, "oflag:" },
  1443. X    {  3,  0, "cflag:" },
  1444. X    {  4,  0, "lflag:" },
  1445. X    {  5,  7, "INTR QUIT ERASE KILL EOF/VMIN  EOL/VTIME EOL2 SWTCH" },
  1446. X    {  6,  0, "cc:" },
  1447. X    {  7,  0, "state:" },
  1448. X    {  -1,-1, (char *)0}
  1449. X};
  1450. X
  1451. Xtypedef struct bitfld
  1452. X{
  1453. X    int y,x;
  1454. X    char *label;
  1455. X    int flag_num;
  1456. X    int mask;
  1457. X} BITFLD;
  1458. X
  1459. X#define IFLAG 1
  1460. X#define OFLAG 2
  1461. X#define LFLAG 3
  1462. X#define CFLAG 4
  1463. X#define STATE 5
  1464. X
  1465. XBITFLD ttybitflds[] =
  1466. X{
  1467. X    {  0,  7, "IGNBRK", IFLAG, IGNBRK },
  1468. X    {  0, 15, "BRKINT", IFLAG, BRKINT },
  1469. X    {  0, 23, "IGNPAR", IFLAG, IGNPAR },
  1470. X    {  0, 31, "PARMRK", IFLAG, PARMRK },
  1471. X    {  0, 39, "INPCK",  IFLAG, INPCK },
  1472. X    {  0, 46, "ISTRIP", IFLAG, ISTRIP },
  1473. X    {  0, 53, "INLCR",  IFLAG, INLCR },
  1474. X    {  0, 60, "IGNCR",  IFLAG, IGNCR },
  1475. X    {  0, 68, "ICRNL",  IFLAG, ICRNL },
  1476. X    {  1,  7, "IUCLC",  IFLAG, IUCLC },
  1477. X    {  1, 15, "IXON",   IFLAG, IXON },
  1478. X    {  1, 23, "IXOFF",  IFLAG, IXOFF },
  1479. X    {  1, 31, "IXANY",  IFLAG, IXANY },
  1480. X    {  2,  7, "OPOST",  OFLAG, OPOST },
  1481. X    {  2, 15, "OLCUC",  OFLAG, OLCUC },
  1482. X    {  2, 23, "ONLCR",  OFLAG, ONLCR },
  1483. X    {  2, 31, "OCRNL",  OFLAG, OCRNL },
  1484. X    {  2, 39, "ONOCR",  OFLAG, ONOCR },
  1485. X    {  2, 46, "ONLRET", OFLAG, ONLRET },
  1486. X    {  2, 53, "OFDEL",  OFLAG, OFDEL },
  1487. X    {  3, 23, "CREAD",  CFLAG, CREAD },
  1488. X    {  3, 31, "HUPCL",  CFLAG, HUPCL },
  1489. X    {  3, 39, "CLOCAL", CFLAG, CLOCAL },
  1490. X#ifdef RTSFLOW
  1491. X    {  3, 46, "RTSFLO", CFLAG, RTSFLOW },
  1492. X#endif
  1493. X#ifdef CTSFLOW
  1494. X    {  3, 53, "CTSFLO", CFLAG, CTSFLOW },
  1495. X#endif
  1496. X    {  4,  7, "ISIG",   LFLAG, ISIG },
  1497. X    {  4, 15, "ICANON", LFLAG, ICANON },
  1498. X    {  4, 23, "XCASE",  LFLAG, XCASE },
  1499. X    {  4, 31, "ECHO",   LFLAG, ECHO },
  1500. X    {  4, 39, "ECHOE",  LFLAG, ECHOE },
  1501. X    {  4, 46, "ECHOK",  LFLAG, ECHOK },
  1502. X    {  4, 53, "ECHONL", LFLAG, ECHONL },
  1503. X    {  4, 60, "NOFLSH", LFLAG, NOFLSH },
  1504. X    {  4, 68, "XCLUDE", LFLAG, XCLUDE },
  1505. X    {  7,  7, "TO",     STATE, TIMEOUT },
  1506. X    {  7, 10, "WO",     STATE, WOPEN },
  1507. X    {  7, 13, "O",      STATE, ISOPEN },
  1508. X    {  7, 15, "TB",     STATE, TBLOCK },
  1509. X    {  7, 18, "CD",     STATE, CARR_ON },
  1510. X    {  7, 21, "BY",     STATE, BUSY },
  1511. X    {  7, 24, "OSLP",   STATE, OASLP },
  1512. X    {  7, 29, "ISLP",   STATE, IASLP },
  1513. X    {  7, 34, "STOP",   STATE, TTSTOP },
  1514. X    {  7, 39, "EXT",    STATE, EXTPROC },
  1515. X    {  7, 43, "TACT",   STATE, TACT },
  1516. X    {  7, 48, "ESC",    STATE, CLESC },
  1517. X    {  7, 52, "RTO",    STATE, RTO },
  1518. X    {  7, 56, "IOW",    STATE, TTIOW },
  1519. X    {  7, 60, "XON",    STATE, TTXON },
  1520. X    {  7, 64, "XOFF",   STATE, TTXOFF },
  1521. X    {  -1,-1, (char *)0,    -1,    -1 }
  1522. X};
  1523. X
  1524. Xtypedef struct valyx
  1525. X{
  1526. X    int y,x;
  1527. X} VALYX;
  1528. X
  1529. XVALYX ttyvalyx[] =
  1530. X{
  1531. X#define Fc_intr       0
  1532. X    {  6,  8 },
  1533. X#define Fcc_quit      1
  1534. X    {  6, 13 },
  1535. X#define Fcc_erase     2
  1536. X    {  6, 18 },
  1537. X#define Fcc_kill      3
  1538. X    {  6, 24 },
  1539. X#define Fcc_eof       4
  1540. X    {  6, 30 },
  1541. X#define Fcc_eol       5
  1542. X    {  6, 40 },
  1543. X#define Fcc_eol2      6
  1544. X    {  6, 49 },
  1545. X#define Fcc_swtch     7
  1546. X    {  6, 54 },
  1547. X#define Fbaud_b_p_s   8
  1548. X    {  3,  7 }
  1549. X};
  1550. X
  1551. Xtypedef struct b_to_br
  1552. X{
  1553. X    char *baud_rate;
  1554. X    int B_code;
  1555. X} B_TO_BR;
  1556. X
  1557. XB_TO_BR speeds[] =     /* ordered to put less common rates later in table */
  1558. X{                    /* and the vagaries of baud rates above 9600 "handled" */
  1559. X    " 2400",    B2400,
  1560. X    " 1200",    B1200,
  1561. X    " 9600",    B9600,
  1562. X#if defined(B19200)
  1563. X    "19200",    B19200,
  1564. X#endif
  1565. X#if defined(B38400)
  1566. X    "38400",    B38400,
  1567. X#endif
  1568. X    " 4800",    B4800,
  1569. X    "  300",    B300,
  1570. X    "  110",    B110,
  1571. X    "  600",    B600,
  1572. X    "   75",    B75,
  1573. X    "   50",    B50,
  1574. X    "  HUP",    B0,
  1575. X    " EXTA",    EXTA,
  1576. X    " EXTB",    EXTB,
  1577. X
  1578. X    (char *)0,0
  1579. X};
  1580. X
  1581. X/*+-------------------------------------------------------------------------
  1582. X    tty_slot_compare(sio1,sio2)
  1583. X--------------------------------------------------------------------------*/
  1584. Xint
  1585. Xtty_slot_compare(sio1,sio2)
  1586. Xstruct tty *sio1;
  1587. Xstruct tty *sio2;
  1588. X{
  1589. X    return(sio1->t_slot - sio2->t_slot);
  1590. X}    /* end of tty_slot_compare */
  1591. X
  1592. X/*+-------------------------------------------------------------------------
  1593. X    grok_sio_tty()
  1594. X--------------------------------------------------------------------------*/
  1595. Xvoid
  1596. Xgrok_sio_tty()
  1597. X{
  1598. Xregister isio;
  1599. Xregister struct tty *tsio;
  1600. X
  1601. X    nsio = 0;
  1602. X    kread((caddr_t)sio,sio_ttyaddr,sizeof(struct tty) * SIO_NTTY);
  1603. X    for(isio = 0; isio < SIO_NTTY; isio++)
  1604. X    {
  1605. X        tsio = &sio[isio];
  1606. X        if(tsio->t_state & (WOPEN | ISOPEN))
  1607. X        {
  1608. X            tsio->t_slot = (ushort)isio;
  1609. X            nsio++;
  1610. X            continue;
  1611. X        }
  1612. X        tsio->t_slot = 127;
  1613. X    }
  1614. X    (void)qsort((char *)sio,(unsigned)SIO_NTTY,
  1615. X        sizeof(struct tty),tty_slot_compare);
  1616. X
  1617. X}    /* end of grok_sio_tty */
  1618. X
  1619. X/*+-------------------------------------------------------------------------
  1620. X    B_to_baud_rate(code) - convert CBAUD B_ code to baud rate string
  1621. X--------------------------------------------------------------------------*/
  1622. Xchar *
  1623. XB_to_baud_rate(code)
  1624. X{
  1625. Xregister int n;
  1626. X
  1627. X    for(n=0; speeds[n].baud_rate; n++)
  1628. X        if(speeds[n].B_code == code)
  1629. X            return(speeds[n].baud_rate);
  1630. X    return("-----");
  1631. X}    /* end of B_to_baud_rate */
  1632. X
  1633. X/*+-------------------------------------------------------------------------
  1634. X    cflag_to_baud_d_p_s(cflag)
  1635. X--------------------------------------------------------------------------*/
  1636. Xchar *
  1637. Xcflag_to_baud_d_p_s(cflag)
  1638. Xint cflag;
  1639. X{
  1640. Xregister char *cptr;
  1641. Xstatic char rtnstr[16];
  1642. X
  1643. X    strcpy(rtnstr,B_to_baud_rate(cflag & CBAUD));
  1644. X    cptr = rtnstr + strlen(rtnstr);
  1645. X    *cptr++ = '-';
  1646. X    switch(cflag & CSIZE)
  1647. X    {
  1648. X        case CS5: *cptr++ = '5'; break;
  1649. X        case CS6: *cptr++ = '6'; break;
  1650. X        case CS7: *cptr++ = '7'; break;
  1651. X        case CS8: *cptr++ = '8'; break;
  1652. X    }
  1653. X    *cptr++ = '-';
  1654. X    *cptr++ = (cflag & PARENB) ? ((cflag & PARODD) ? 'O' : 'E') : 'N';
  1655. X    *cptr++ = '-';
  1656. X    *cptr++ = (cflag & CSTOPB) ? '2' : '1';
  1657. X    *cptr = 0;
  1658. X    return(rtnstr);
  1659. X
  1660. X}    /* end of cflag_to_baud_d_p_s */
  1661. X
  1662. X/*+-----------------------------------------------------------------------
  1663. X    display_siofull_update(win,tly,tlx,tsio)
  1664. X
  1665. X000000000011111111112222222222333333333344444444445555555555666666666677777
  1666. X012345678901234567890123456789012345678901234567890123456789012345678901234
  1667. Xiflag: IGNBRK  BRKINT  IGNPAR  PARMRK  INPCK  ISTRIP INLCR  IGNCR   ICRNL
  1668. X       IUCLC   IXON    IXOFF   IXANY
  1669. Xoflag: OPOST   OLCUC   ONLCR   OCRNL   ONOCR  ONLRET OFDEL
  1670. Xcflag: 09600-8-N-1     CREAD   HUPCL   CLOCAL
  1671. Xlflag: ISIG    ICANON  XCASE   ECHO    ECHOE  ECHOK  ECHONL NOFLSH  XCLUDE
  1672. X       INTR QUIT ERASE KILL EOF/VMIN  EOL/VTIME EOL2 SWTCH 
  1673. Xcc:     03   1c   08    15    01        00       00   00   
  1674. X
  1675. X------------------------------------------------------------------------*/
  1676. Xvoid
  1677. Xdisplay_siofull_update(win,tly,tlx,tsio)
  1678. XWINDOW *win;
  1679. Xint tly;
  1680. Xint tlx;
  1681. Xstruct tty *tsio;
  1682. X{
  1683. Xregister flag;
  1684. Xregister i_cc;
  1685. XBITFLD *bfptr = ttybitflds;
  1686. XVALYX *vptr = ttyvalyx;
  1687. X
  1688. X    use_cp(win,cpLOW);
  1689. X    while(bfptr->y >= 0)
  1690. X    {
  1691. X        switch(bfptr->flag_num)
  1692. X        {
  1693. X            case IFLAG: flag = tsio->t_iflag; break;
  1694. X            case OFLAG: flag = tsio->t_oflag; break;
  1695. X            case LFLAG: flag = tsio->t_lflag; break;
  1696. X            case CFLAG: flag = tsio->t_cflag; break;
  1697. X            case STATE: flag = tsio->t_state; break;
  1698. X        }
  1699. X        flag &= bfptr->mask;
  1700. X        wmove(win,bfptr->y + tly,bfptr->x + tlx);
  1701. X        if(flag)
  1702. X            use_cp(win,cpREVERSE);
  1703. X        waddstr(win,bfptr->label);
  1704. X        if(flag)
  1705. X            use_cp(win,cpLOW);
  1706. X        bfptr++;
  1707. X    }
  1708. X    for(i_cc = 0; i_cc < NCC; i_cc++)
  1709. X    {
  1710. X        wmove(win,vptr->y + tly,vptr->x + tlx);
  1711. X        wprintw(win,"%02x",tsio->t_cc[i_cc]);
  1712. X        vptr++;
  1713. X    }
  1714. X
  1715. X    vptr = &ttyvalyx[Fbaud_b_p_s];
  1716. X    clear_area(win,vptr->y + tly,vptr->x + tlx,12);
  1717. X    waddstr(win,cflag_to_baud_d_p_s(tsio->t_cflag));
  1718. X
  1719. X}    /* end of display_siofull_update */
  1720. X
  1721. X/*+-------------------------------------------------------------------------
  1722. X    display_siofull_init(win,tly,tlx,show_flag)
  1723. X--------------------------------------------------------------------------*/
  1724. Xvoid
  1725. Xdisplay_siofull_init(win,tly,tlx,show_flag)
  1726. XWINDOW *win;
  1727. Xint tly;
  1728. Xint tlx;
  1729. Xint show_flag;
  1730. X{
  1731. Xregister y;
  1732. XSLABEL *sptr = tty_slabels;
  1733. X
  1734. X    use_cp(win,cpLIT);
  1735. X    for(y = 0; y < 7; y++)
  1736. X        clear_area(win,y,0,getmaxy(win));
  1737. X    if(show_flag)
  1738. X    {
  1739. X        while(sptr->y >= 0)
  1740. X        {
  1741. X            wmove(win,sptr->y + tly,sptr->x + tlx);
  1742. X            waddstr(win,sptr->label);
  1743. X            sptr++;
  1744. X        }
  1745. X    }
  1746. X
  1747. X}    /* end of display_siofull_init */
  1748. X
  1749. X/*+-------------------------------------------------------------------------
  1750. X    display_siosum_update(win,y,tsio)
  1751. X--------------------------------------------------------------------------*/
  1752. Xvoid
  1753. Xdisplay_siosum_update(win,y,tsio)
  1754. Xregister WINDOW *win;
  1755. Xint y;
  1756. Xregister struct tty *tsio;
  1757. X{
  1758. Xregister unsigned int itmp;
  1759. Xregister opened = tsio->t_state & (ISOPEN | WOPEN);
  1760. Xchar s8[8];
  1761. X
  1762. X#define TX 1
  1763. X#define RX 6
  1764. X#define CX 11
  1765. X#define OX 16
  1766. X#define SX 23
  1767. X#define FX 30
  1768. X
  1769. X    wmove(win,y,TX);
  1770. X#ifdef M_UNIX
  1771. X    waddch(win,(tsio->t_slot < 8) ? '1' : '2');
  1772. X    waddch(win,(tsio->t_slot % 8) + 'a');
  1773. X#else
  1774. X    wprintw(win,"%02d",tsio->slot);
  1775. X#endif
  1776. X
  1777. X    if(!opened)
  1778. X    {
  1779. X        use_cp(win,cpINFO);
  1780. X        clear_area(win,y,TX,COLS - TX);
  1781. X        waddstr(win,"closed");
  1782. X        return;
  1783. X    }
  1784. X
  1785. X    wmove(win,y,RX);
  1786. X    if((itmp = (unsigned)tsio->t_rawq.c_cc) > 999)
  1787. X        itmp = 999;
  1788. X    if(itmp > 10)
  1789. X        use_cp(win,cpHIGH);
  1790. X    else if(itmp > 3)
  1791. X        use_cp(win,cpMED);
  1792. X    else
  1793. X        use_cp(win,cpLOW);
  1794. X    wprintw(win,"%3d",itmp);
  1795. X
  1796. X    if((itmp = (unsigned)tsio->t_canq.c_cc) > 999)
  1797. X        itmp = 999;
  1798. X    if(itmp > 20)
  1799. X        use_cp(win,cpHIGH);
  1800. X    else if(itmp > 10)
  1801. X        use_cp(win,cpMED);
  1802. X    else
  1803. X        use_cp(win,cpLOW);
  1804. X    wmove(win,y,CX);
  1805. X    wprintw(win,"%3d",itmp);
  1806. X
  1807. X    if((itmp = (unsigned)tsio->t_outq.c_cc + tsio->t_tbuf.c_count) > 99999)
  1808. X        itmp = 99999;
  1809. X    if(itmp > 75)
  1810. X        use_cp(win,cpHIGH);
  1811. X    else if(itmp > 20)
  1812. X        use_cp(win,cpMED);
  1813. X    else
  1814. X        use_cp(win,cpLOW);
  1815. X    wmove(win,y,OX);
  1816. X    wprintw(win,"%5d",itmp);
  1817. X
  1818. X    use_cp(win,cpINFO);
  1819. X    wmove(win,y,SX);
  1820. X    waddstr(win,B_to_baud_rate(tsio->t_cflag & CBAUD));
  1821. X
  1822. X    strcpy(s8,".....");
  1823. X    if(tsio->t_state & WOPEN)
  1824. X        s8[0] = 'W';
  1825. X    else if(tsio->t_state & ISOPEN)
  1826. X        s8[0] = 'O';
  1827. X    if(tsio->t_state & CARR_ON)
  1828. X        s8[1] = 'C';
  1829. X    if(tsio->t_state & BUSY)
  1830. X        s8[2] = 'B';
  1831. X    if(tsio->t_state & TTSTOP)
  1832. X        s8[3] = 'S';
  1833. X    if(tsio->t_state & TIMEOUT)
  1834. X        s8[4] = 'D';
  1835. X    wmove(win,y,FX);
  1836. X    waddstr(win,s8);
  1837. X
  1838. X    wprintw(win,"%7o",tsio->t_iflag);
  1839. X    wprintw(win,"%7o",tsio->t_oflag);
  1840. X    wprintw(win,"%7o",tsio->t_cflag);
  1841. X    wprintw(win,"%7o",tsio->t_lflag);
  1842. X    if(tsio->t_pgrp)
  1843. X        wprintw(win,"%6d",tsio->t_pgrp);
  1844. X    else
  1845. X        waddstr(win,"      ");
  1846. X
  1847. X}    /* end of display_siosum_update */
  1848. X
  1849. X/*+-------------------------------------------------------------------------
  1850. X    display_sio_summary(win,initial)
  1851. X--------------------------------------------------------------------------*/
  1852. Xdisplay_sio_summary(win,initial)
  1853. Xregister WINDOW *win;
  1854. Xint initial;
  1855. X{
  1856. Xregister int isio;
  1857. Xint max_displayable_sios = getmaxy(win) - 2;
  1858. Xstatic char *header  = 
  1859. X" tty  raw  can    out  speed  state  iflag  oflag  cflag  lflag  pgrp";
  1860. Xstatic char *legend =
  1861. X"W=wait for open  O=open C=carrier on  B=output busy  S=stopped  T=timeout";
  1862. Xstatic couldnt_display_all = 0;
  1863. X
  1864. X    if(initial)
  1865. X    {
  1866. X        use_cp(win,cpBANNER);
  1867. X        clear_area(win,0,0,getmaxx(win));
  1868. X        waddstr(win,header);
  1869. X        use_cp(win,cpLIT);
  1870. X        clear_area(win,getmaxy(win)-1,0,getmaxx(win));
  1871. X        waddstr(win,legend);
  1872. X        couldnt_display_all = 1;
  1873. X    }
  1874. X    grok_sio_tty();
  1875. X    for(isio = 0; (isio < nsio); isio++)
  1876. X    {
  1877. X        if(isio > max_displayable_sios)
  1878. X        {
  1879. X            wmove(win,getmaxy(win)-2);
  1880. X            use_cp(win,cpMED);
  1881. X            waddstr(win,"cannot display all active serial ports");
  1882. X            couldnt_display_all = 1;
  1883. X            return;
  1884. X        }
  1885. X        display_siosum_update(win,isio + 1,&sio[isio]);
  1886. X    }
  1887. X
  1888. X    for(; isio < getmaxy(win)-2; isio++);
  1889. X        clear_area(win,isio + 1,0,getmaxx(win));
  1890. X
  1891. X    if(couldnt_display_all)
  1892. X    {
  1893. X        use_cp(win,cpINFO);
  1894. X        clear_area(win,getmaxy(win)-2,0,getmaxx(win));
  1895. X        couldnt_display_all = 0;
  1896. X    }
  1897. X
  1898. X}    /* end of display_sio_summary */
  1899. X
  1900. X#endif /* M_UNIX / SCO */
  1901. X/* vi: set tabstop=4 shiftwidth=4: */
  1902. X/* end of det_sio.c */
  1903. SHAR_EOF
  1904. chmod 0644 det_sio.c ||
  1905. echo 'restore of det_sio.c failed'
  1906. Wc_c="`wc -c < 'det_sio.c'`"
  1907. test 13154 -eq "$Wc_c" ||
  1908.     echo 'det_sio.c: original size 13154, current size' "$Wc_c"
  1909. fi
  1910. true || echo 'restore of det_stream.c failed'
  1911. echo End of part 4, continue with part 5
  1912. exit 0
  1913.  
  1914. exit 0 # Just in case...
  1915. -- 
  1916. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1917. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1918. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1919. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1920.