home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / comp / sources / misc / 4118 < prev    next >
Encoding:
Text File  |  1992-11-21  |  50.7 KB  |  1,975 lines

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