home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume11 / statline / part01 next >
Encoding:
Text File  |  1990-03-25  |  32.9 KB  |  1,541 lines

  1. Newsgroups: comp.sources.misc
  2. subject: v11i086: statline - BSD sysline clone for System V/Xenix
  3. From: staceyc@sco.UUCP
  4. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5.  
  6. Posting-number: Volume 11, Issue 86
  7. Submitted-by: staceyc@sco.UUCP
  8. Archive-name: statline/part01
  9.  
  10. This is a System V/Xenix clone of a BSD PD program called sysline.
  11. Statline displays system and user information on the hardware
  12. status line of a terminal.
  13.  
  14. It has been compiled and runs under Xenix 2.3 on a 386 box,
  15. System 5.3.2 on a AT&T 3b2, and SCO Unix 5.3.2.  It should be
  16. readily portable to any System 5.3 based operating system.
  17.  
  18. Statline has the following flags;
  19.  
  20.     -d     date [default]
  21.     -l     machine load [default]
  22.     -c     user count [default]
  23.     -u     current logins
  24.     -g     logins/logouts [default]
  25.     -t     machine uptime [default]
  26.     -b     mail arrival
  27.  
  28. #!/bin/sh
  29. # Created by mshar - shell archiver
  30. #
  31. # This archive contains:
  32. #    README
  33. #    statline.1
  34. #    Makefile
  35. #    biff.c
  36. #    date.c
  37. #    statline.c
  38. #    users.c
  39. #    kmem.sysv.c
  40. #    kmem.xenix.c
  41. #    editwarn.c
  42. #    funcs.h
  43. #    types.h
  44. #
  45. PATH=/bin:$PATH
  46. echo 'mshar: extracting README (size: 2736)'
  47. sed 's/^X//' << 'GURK' > README &&
  48. X                      Statline 1.0
  49. X                      ------------
  50. X
  51. XThis is a System V/Xenix clone of a BSD PD program called sysline.
  52. XStatline displays system and user information on the hardware
  53. Xstatus line of a terminal.
  54. X
  55. XIt has been compiled and runs under Xenix 2.3 on a 386 box,
  56. XSystem 5.3.2 on a AT&T 3b2, and SCO Unix 5.3.2.  It should be
  57. Xreadily portable to any System 5.3 based operating system.
  58. X
  59. XStatline has the following flags;
  60. X
  61. X    -d     date [default]
  62. X    -l     machine load [default]
  63. X    -c     user count [default]
  64. X    -u     current logins
  65. X    -g     logins/logouts [default]
  66. X    -t     machine uptime [default]
  67. X    -b     mail arrival
  68. X
  69. XSpecifying an upper case flag switches that option off.
  70. X
  71. XStatline takes one parameter which is the number of seconds to
  72. Xsleep between updates.
  73. X
  74. XThe machine load and uptime are calculated from values in
  75. X/dev/kmem.  This means statline expects to read /unix (or
  76. X/xenix) using nlist(2) (xlist(3)) to obtain the offset of
  77. Xcertain symbols in the kernel.
  78. X
  79. XOn systems where security is not an issue this is as simple
  80. Xas making /unix and /dev/kmem readable by all.  The alternative
  81. Xis to make use of /etc/group and either establish or use an
  82. Xexisting group privilege to access the files.
  83. X
  84. XFor example under Xenix 2.3 /xenix and /dev/kmem typically
  85. Xallow access to group 'sysinfo'.  To enable statline to read these
  86. Xfiles do the following;
  87. X
  88. X$ su root
  89. X# chgrp sysinfo /usr/local/bin/statline
  90. X# chmod g+s /usr/local/bin/statline
  91. X# chmod g+r /dev/kmem /xenix
  92. X
  93. XUser information is read from /etc/utmp.  This is usually
  94. Xreadable by all, so privileges should not be an issue.
  95. X
  96. XThe cpu load information is slightly different between Unix
  97. Xand Xenix; there is a corresponding difference in the display.
  98. XThe mail notification routine is fairly simple minded and
  99. Xmay need tweaking.
  100. X
  101. XStatline will attempt to show as much information as possible,
  102. Xso if it cannot read /dev/kmem it will still show other
  103. Xnon-kernel displays.
  104. X
  105. XStatline uses the following terminal capablities;
  106. X
  107. X    hs  - termial has status line
  108. X    tsl - to status line
  109. X    fsl - from status line
  110. X    wsl - width of status line
  111. X
  112. XThese capabilities are extracted from terminfo(4) files under
  113. XUnix 5.3, or terminfo(4) or termcap(M) under Xenix 2.3.  Thanks
  114. Xto Jon Luini for adding termcap support for SCO Unix/Xenix.
  115. X
  116. XStatline forks a process that runs in the background.  The process
  117. Xshould be killed with SIGTERM (15) or SIGHUP (1).
  118. X
  119. XEdit the Makefile to reflect your compiling and running environment.
  120. X
  121. XGood luck!
  122. X
  123. XStacey Campbell                                             _--_|\
  124. X{uunet,ucscc,decwrl,att,microsoft,wyse}!sco!staceyc        /      \
  125. Xstaceyc@sco.com                                            \_.--._/
  126. X                                                                 v
  127. GURK
  128. chmod 0644 README || echo 'restore of README fails'
  129. echo 'mshar: extracting statline.1 (size: 847)'
  130. sed 's/^X//' << 'GURK' > statline.1 &&
  131. X.TH Statline 1l
  132. X.SH NAME
  133. Xstatline \- display user/system information on terminal status line
  134. X.SH SYNOPSIS
  135. X.B statline
  136. X.B [\-dlcugtb] [N]
  137. X.SH DESCRIPTION
  138. X.I Statline
  139. Xdisplays information about the system and the system's users on
  140. Xthe hardware status line of a terminal.  N is the number
  141. Xof seconds to sleep between display updates.
  142. XOptions are:
  143. X.TP
  144. X.B  \-d
  145. Xdisplay the current time
  146. X.TP
  147. X.B  \-l
  148. Xmachine load
  149. X.TP
  150. X.B  \-c
  151. Xuser count
  152. X.TP
  153. X.B  \-u
  154. Xcurrent logins
  155. X.TP
  156. X.B  \-g
  157. Xdisplay users logging on or off the system
  158. X.TP
  159. X.B  \-t
  160. Xmachine uptime
  161. X.TP
  162. X.B  \-b
  163. Xmail arrival
  164. X.TP
  165. X.B  \-h
  166. X.I statline
  167. Xoptions and the defaults
  168. X.PP
  169. XUsing an upper case flag disables the given option.
  170. X.SH BUGS
  171. XUnknown, but please send bug problems to {uunet,ucscc,decwrl,sun}!sco!staceyc
  172. Xor staceyc@sco.com.
  173. X.SH AUTHOR
  174. XStacey Campbell \- Santa Cruz, California, USA \- March 1990
  175. GURK
  176. chmod 0640 statline.1 || echo 'restore of statline.1 fails'
  177. echo 'mshar: extracting Makefile (size: 983)'
  178. sed 's/^X//' << 'GURK' > Makefile &&
  179. X# statline makefile
  180. X
  181. XOBJS= statline.o biff.o date.o kmem.o users.o
  182. XSRC= biff.c date.c statline.c users.c kmem.sysv.c kmem.xenix.c editwarn.c
  183. XINCLUDES= funcs.h types.h
  184. XDOC= README $(EXE).1
  185. XARCFILES= $(DOC) Makefile $(SRC) $(INCLUDES)
  186. X
  187. X# Xenix - terminfo
  188. X#PFLAGS= -DM_TERMINFO
  189. X#LDLIBS= -ltinfo
  190. X
  191. X# Xenix - termcap
  192. X#PFLAGS= -DM_TERMCAP
  193. X#LDLIBS= -ltermlib
  194. X
  195. X# System V
  196. XPFLAGS=
  197. XLDLIBS= -lcurses
  198. X
  199. XCFLAGS= -O $(PFLAGS)
  200. XEXE= statline
  201. X
  202. X$(EXE): $(OBJS)
  203. X    cc $(CFLAGS) $(OBJS) -o $(EXE) $(LDLIBS)
  204. X
  205. Xclean:
  206. X    rm -f core $(OBJS) $(EXE) kmem.c
  207. X
  208. Xtar:
  209. X    tar cvf $(EXE).tar $(ARCFILES)
  210. X
  211. Xshar:
  212. X    mshar $(ARCFILES) > $(EXE).shar
  213. X
  214. Xkmem.o: kmem.c
  215. X
  216. Xkmem.c: kmem.sysv.c kmem.xenix.c
  217. X    @if test -f /unix ; then \
  218. X        echo "Using System V kmem routines." ; \
  219. X        cat editwarn.c kmem.sysv.c > kmem.c ; \
  220. X    else \
  221. X        if test -f /xenix ; then \
  222. X            echo "Using Xenix kmem routines." ; \
  223. X            cat editwarn.c kmem.xenix.c > kmem.c ; \
  224. X        else \
  225. X        echo "Where is /unix??  Warm up the editor." ; \
  226. X        fi \
  227. X    fi
  228. GURK
  229. chmod 0644 Makefile || echo 'restore of Makefile fails'
  230. echo 'mshar: extracting biff.c (size: 3252)'
  231. sed 's/^X//' << 'GURK' > biff.c &&
  232. X#include <stdio.h>
  233. X#include <string.h>
  234. X#include <time.h>
  235. X#include <sys/types.h>
  236. X#include "types.h"
  237. X#include "funcs.h"
  238. X
  239. X#define MESSAGE "mail has arrived from "
  240. X
  241. Xextern char *getenv();
  242. Xextern char *malloc();
  243. Xextern void free();
  244. X
  245. Xstatic void DoWarning();
  246. X
  247. Xextern char *TermBell;
  248. Xextern time_t Now;
  249. X
  250. Xstatic char *MonthCmp[] = {
  251. X    "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
  252. X    "Nov", "Dec"};
  253. X
  254. Xstatic char *MailFile;
  255. Xstatic struct tm StartTm;
  256. Xstatic long StartDaySecond;
  257. Xstatic long Check;
  258. X
  259. Xstatic int MonthVal(str)
  260. X
  261. Xchar *str;
  262. X
  263. X    {
  264. X    int i;
  265. X
  266. X    for (i = 0; i < sizeof(MonthCmp) / sizeof(MonthCmp[0]); ++i)
  267. X        if (strcmp(MonthCmp[i], str) == 0)
  268. X            return i;
  269. X    return -1;
  270. X    }
  271. X
  272. Xint BiffFnInit(display)
  273. X
  274. Xdisplay_t *display;
  275. X
  276. X    {
  277. X    char *home;
  278. X    long start;
  279. X    char *check_str;
  280. X    static char spool[256];
  281. X
  282. X    if (! (MailFile = getenv("MAIL")))
  283. X        if ((home = getenv("HOME")) && (home = strrchr(home, '/')))
  284. X            {
  285. X            sprintf(spool, "/usr/spool/mail%s", home);
  286. X            MailFile = spool;
  287. X            }
  288. X        else
  289. X            {
  290. X            DisplayAdd(display, "unknown mail spool file ");
  291. X            return 0;
  292. X            }
  293. X    else
  294. X        {
  295. X        strcpy(spool, MailFile);
  296. X        MailFile = spool;
  297. X        }
  298. X    if (! (check_str = getenv("MAILCHECK")))
  299. X        Check = 30;
  300. X    else
  301. X        {
  302. X        Check = atol(check_str);
  303. X        if (Check <= 0)
  304. X            Check = 30;
  305. X        }
  306. X    start = Now;
  307. X    StartTm = *localtime(&start);
  308. X    StartDaySecond = StartTm.tm_hour * 60 * 60 + StartTm.tm_min * 60 +
  309. X        StartTm.tm_sec;
  310. X    StartDaySecond = StartTm.tm_mday * 24 * 60 * 60 + StartTm.tm_hour
  311. X        * 60 * 60 + StartTm.tm_min * 60 + StartTm.tm_sec;
  312. X
  313. X    return 1;
  314. X    }
  315. X
  316. Xint BiffFn(display)
  317. X
  318. Xdisplay_t *display;
  319. X
  320. X    {
  321. X    long start, current;
  322. X    FILE *fp;
  323. X    char buf[256];
  324. X    int count;
  325. X    char from[6], user[129], wday[6], month[6];
  326. X    int day, hour, minute, second, year, monthval;
  327. X    int warn = 0;
  328. X    long day_second;
  329. X    static long last_check = 0;
  330. X
  331. X    current = Now;
  332. X    if (last_check + Check > current)
  333. X        return 1;
  334. X
  335. X    last_check = current;
  336. X
  337. X    if ((fp = fopen(MailFile, "r")) == NULL)
  338. X        {
  339. X        DisplayAdd(display, "biff: cannot read spool file ");
  340. X        return 0;
  341. X        }
  342. X
  343. X    while (fgets(buf, sizeof(buf), fp) != NULL)
  344. X        {
  345. X        if (buf[0] != 'F')
  346. X            continue;
  347. X        count = sscanf(buf,
  348. X            "%5s %128s %4s %4s %d %d:%d:%d %d",
  349. X            from, user, wday, month, &day, &hour,
  350. X            &minute, &second, &year);
  351. X        if (count == 9 && strcmp(from, "From") == 0 &&
  352. X            ((monthval = MonthVal(month)) != -1))
  353. X            {
  354. X            year -= 1900;
  355. X            day_second = day * 24 * 60 * 60 + hour
  356. X                * 60 * 60 + minute * 60 + second;
  357. X            if ((year > StartTm.tm_year)
  358. X                ||
  359. X                (year == StartTm.tm_year &&
  360. X                monthval > StartTm.tm_mon)
  361. X                ||
  362. X                (year == StartTm.tm_year &&
  363. X                monthval == StartTm.tm_mon &&
  364. X                day_second >= StartDaySecond))
  365. X                {
  366. X                DoWarning(display, user);
  367. X                warn = 1;
  368. X                }
  369. X            }
  370. X        }
  371. X
  372. X    if (warn)
  373. X        {
  374. X        start = time((time_t *)0);
  375. X        StartTm = *localtime(&start);
  376. X        StartDaySecond = StartTm.tm_mday * 24 * 60
  377. X            * 60 + StartTm.tm_hour * 60 * 60 +
  378. X            StartTm.tm_min * 60 + StartTm.tm_sec;
  379. X        }
  380. X
  381. X    (void)fclose(fp);
  382. X
  383. X    return 1;
  384. X    }
  385. X
  386. Xstatic void DoWarning(display, user)
  387. X
  388. Xdisplay_t *display;
  389. Xchar *user;
  390. X
  391. X    {
  392. X    char *buffer;
  393. X
  394. X    buffer = malloc(strlen(user) + sizeof(MESSAGE) + 5);
  395. X    sprintf(buffer, "%s%s ", MESSAGE, user);
  396. X    DisplayAdd(display, buffer);
  397. X    free(buffer);
  398. X    (void)write(fileno(stdout), TermBell, strlen(TermBell));
  399. X    }
  400. GURK
  401. chmod 0644 biff.c || echo 'restore of biff.c fails'
  402. echo 'mshar: extracting date.c (size: 467)'
  403. sed 's/^X//' << 'GURK' > date.c &&
  404. X#include <time.h>
  405. X#include <sys/types.h>
  406. X#include <string.h>
  407. X#include "types.h"
  408. X#include "funcs.h"
  409. X
  410. Xextern char *malloc();
  411. Xextern void free();
  412. X
  413. Xextern time_t Now;
  414. X
  415. Xint DateFnInit(display)
  416. X
  417. Xdisplay_t *display;
  418. X
  419. X    {
  420. X    return 1;
  421. X    }
  422. X
  423. Xint DateFn(display)
  424. X
  425. Xdisplay_t *display;
  426. X
  427. X    {
  428. X    long clock;
  429. X    struct tm tm;
  430. X    char buf[32];
  431. X
  432. X    clock = Now;
  433. X    tm = *localtime(&clock);
  434. X    sprintf(buf, "%.2d:%.2d:%.2d ", tm.tm_hour, tm.tm_min, tm.tm_sec);
  435. X    DisplayAdd(display, buf);
  436. X
  437. X    return 1;
  438. X    }
  439. GURK
  440. chmod 0644 date.c || echo 'restore of date.c fails'
  441. echo 'mshar: extracting statline.c (size: 9371)'
  442. sed 's/^X//' << 'GURK' > statline.c &&
  443. X#include <signal.h>
  444. X#include <time.h>
  445. X#include <string.h>
  446. X#include <sys/types.h>
  447. X
  448. X#if (defined(M_XENIX) && defined(M_TERMINFO)) || ! defined(M_XENIX)
  449. X#define USE_TERMINFO
  450. X#endif
  451. X
  452. X#ifdef USE_TERMINFO
  453. X#include <curses.h>
  454. X#include <term.h>
  455. X#define TERMMODE "terminfo"
  456. X#define GETFLAG(flag) tigetflag(flag)
  457. X#define GETNUM(flag) tigetnum(flag)
  458. X#define GETPARM(flag) tparm(flag, 0)
  459. X#else
  460. X#include <stdio.h>
  461. X#include <sgtty.h>
  462. X#define TERMMODE "termcap"
  463. X#define reset_shell_mode() ;
  464. X#define GETFLAG(flag) tgetflag(flag, &area)
  465. X#define GETNUM(flag) tgetnum(flag, &area)
  466. X#define GETPARM(flag) tgetstr(flag, &area)
  467. X#endif
  468. X
  469. X#include <ctype.h>
  470. X#include "types.h"
  471. X#include "funcs.h"
  472. X
  473. X#define SLEEP_DEFAULT 10
  474. X#define DIS_BUF_BLOCK 128
  475. X#define CONT "..."
  476. X
  477. Xextern char *malloc(), *realloc();
  478. Xextern void free();
  479. X#ifndef USE_TERMINFO
  480. Xextern char *getenv();
  481. Xextern char *tgetstr();
  482. X#endif
  483. X
  484. Xchar *TermBell;
  485. Xtime_t Now;
  486. X
  487. Xstatic char *DefaultBell = "\007";
  488. Xstatic display_t *CleanDisplay;
  489. X
  490. Xstatic int InitStatusLine();
  491. Xstatic void ProcessOptions();
  492. Xstatic void Usage();
  493. Xstatic void ShowDisplay();
  494. Xstatic void PutStatLine();
  495. Xstatic int FormChunk();
  496. Xstatic void CleanUp();
  497. Xstatic void TermInit();
  498. X
  499. Xint main(argc, argv)
  500. X
  501. Xint argc;
  502. Xchar **argv;
  503. X
  504. X    {
  505. X    int errret, i;
  506. X    long sleeptime;
  507. X    int fn_list_size;
  508. X    static display_t display;
  509. X    static fn_list_t fn_list[] = {
  510. X        {DateFn,       DateFnInit,       1, 'd', "date"},
  511. X        {LoadFn,       LoadFnInit,       1, 'l', "machine load"},
  512. X        {UsersCountFn, UsersCountFnInit, 1, 'c', "user count"},
  513. X        {UsersFn,      UsersFnInit,      0, 'u', "current logins"},
  514. X        {UsersDelta,   UsersDeltaInit,   1, 'g', "logins/logouts"},
  515. X        {UptimeFn,     UptimeFnInit,     1, 't', "machine uptime"},
  516. X        {BiffFn,       BiffFnInit,       0, 'b', "mail arrival"}};
  517. X
  518. X    fn_list_size = sizeof(fn_list) / sizeof(fn_list[0]);
  519. X    ProcessOptions(argc, argv, fn_list, fn_list_size, &sleeptime);
  520. X    TermInit(argv[0]);
  521. X    if (InitStatusLine(argv[0], &display.stat_line_info))
  522. X        {
  523. X        reset_shell_mode();
  524. X        exit(1);
  525. X        }
  526. X    errret = fork();
  527. X    if (errret == -1)
  528. X        {
  529. X        reset_shell_mode();
  530. X        perror(argv[0]);
  531. X        exit(1);
  532. X        }
  533. X    if (errret)
  534. X        {
  535. X        reset_shell_mode();
  536. X        exit(0);
  537. X        }
  538. X    CleanDisplay = &display;
  539. X    (void)signal(SIGTERM, CleanUp);
  540. X    (void)signal(SIGHUP, CleanUp);
  541. X    (void)signal(SIGINT, SIG_IGN);
  542. X    (void)signal(SIGQUIT, SIG_IGN);
  543. X    Now = time((time_t *)0);
  544. X    for (i = 0; i < fn_list_size; ++i)
  545. X        if (fn_list[i].call)
  546. X            fn_list[i].call = (*fn_list[i].init_fn_name)(&display);
  547. X    ShowDisplay(&display, sleeptime);
  548. X    for (;;)
  549. X        {
  550. X        Now = time((time_t *)0);
  551. X        for (i = 0; i < fn_list_size; ++i)
  552. X            if (fn_list[i].call)
  553. X                fn_list[i].call =
  554. X                    (*fn_list[i].fn_name)(&display);
  555. X        ShowDisplay(&display, sleeptime);
  556. X        }
  557. X    }
  558. X
  559. Xstatic void ShowDisplay(display, sleeptime)
  560. X
  561. Xdisplay_t *display;
  562. Xlong sleeptime;
  563. X
  564. X    {
  565. X    int index;
  566. X    long sub_sleep;
  567. X    stat_line_info_t *info;
  568. X    static char *buf = 0;
  569. X    static int sub_width;
  570. X
  571. X    info = &display->stat_line_info;
  572. X    if (! display->display_len)
  573. X        {
  574. X        DisplayAdd(display, " ");
  575. X        ShowDisplay(display, sleeptime);
  576. X        return;
  577. X        }
  578. X    if (! buf)
  579. X        {
  580. X        buf = malloc(info->width + 2);
  581. X        sub_width = info->width - sizeof(CONT) - 1;
  582. X        }
  583. X    sub_sleep = sleeptime / (display->display_len / sub_width + 1);
  584. X    if (sub_sleep < 2)
  585. X        sub_sleep = 2;
  586. X    index = 0;
  587. X    while (index + sub_width < display->display_len)
  588. X        {
  589. X        index += FormChunk(buf, &display->buffer[index], sub_width);
  590. X        PutStatLine(buf, CONT, &display->stat_line_info, sub_sleep);
  591. X        }
  592. X    PutStatLine(&display->buffer[index], "", &display->stat_line_info,
  593. X        sub_sleep);
  594. X    display->buffer[0] = '\0';
  595. X    display->display_len = 0;
  596. X    }
  597. X
  598. Xstatic int FormChunk(buf, str, max_width)
  599. X
  600. Xchar *buf;
  601. Xchar *str;
  602. Xint max_width;
  603. X
  604. X    {
  605. X    int i;
  606. X
  607. X    i = max_width - 1;
  608. X    while (i >= 0 && str[i] != ' ')
  609. X        --i;
  610. X    if (i > 0)
  611. X        {
  612. X        memcpy(buf, str, i);
  613. X        buf[i] = '\0';
  614. X        return i;
  615. X        }
  616. X    memcpy(buf, str, max_width);
  617. X    buf[max_width] = '\0';
  618. X
  619. X    return max_width;
  620. X    }
  621. X
  622. Xstatic void PutStatLine(str, sup, info, sleeptime)
  623. X
  624. Xchar *str;
  625. Xchar *sup;
  626. Xstat_line_info_t *info;
  627. Xlong sleeptime;
  628. X
  629. X    {
  630. X    int  total;
  631. X    static char *out_buf = 0;
  632. X    static char *buf = 0;
  633. X
  634. X    if (! buf)
  635. X        {
  636. X        buf = malloc(info->width + info->tsl_len + info->fsl_len + 2);
  637. X        out_buf = malloc(info->width + 2);
  638. X        }
  639. X    (void)sprintf(out_buf, "%s%s", str, sup);
  640. X    total = strlen(out_buf);
  641. X    while (total < info->width)
  642. X        {
  643. X        out_buf[total] = ' ';
  644. X        ++total;
  645. X        }
  646. X    out_buf[total] = '\0';
  647. X    sprintf(buf, "%s%s%s", info->tsl, out_buf, info->fsl);
  648. X    total = strlen(buf);
  649. X    (void)write(fileno(stdout), buf, total);
  650. X    (void)sleep(sleeptime);
  651. X    }
  652. X
  653. Xstatic void ProcessOptions(argc, argv, fn_list, fn_list_size, sleeptime)
  654. X
  655. Xint argc;
  656. Xchar **argv;
  657. Xfn_list_t *fn_list;
  658. Xint fn_list_size;
  659. Xlong *sleeptime;
  660. X
  661. X    {
  662. X    int i, opt, index;
  663. X    char *optstring;
  664. X    fn_list_t *init_list;
  665. X    extern int optind;
  666. X
  667. X    optstring = malloc(fn_list_size * 2 + 1);
  668. X    init_list = (fn_list_t *)malloc(sizeof(fn_list_t) * fn_list_size);
  669. X    for (i = 0; i < fn_list_size; ++i)
  670. X        {
  671. X        index = i * 2;
  672. X        optstring[index] = fn_list[i].flag;
  673. X        optstring[index + 1] = toupper(fn_list[i].flag);
  674. X        init_list[i] = fn_list[i];
  675. X        }
  676. X    optstring[fn_list_size * 2] = '\0';
  677. X    while ((opt = getopt(argc, argv, optstring)) != EOF)
  678. X        {
  679. X        i = 0;
  680. X        while (i < fn_list_size && opt != fn_list[i].flag &&
  681. X            opt != toupper(fn_list[i].flag))
  682. X            ++i;
  683. X        if (i < fn_list_size)
  684. X            fn_list[i].call = fn_list[i].flag == opt;
  685. X        else
  686. X            Usage(argv[0], init_list, fn_list_size);
  687. X        }
  688. X    if (optind == argc)
  689. X        *sleeptime = SLEEP_DEFAULT;
  690. X    else
  691. X        if (optind + 1 == argc)
  692. X            {
  693. X            *sleeptime = atol(argv[optind]);
  694. X            if (sleeptime <= 0)
  695. X                Usage(argv[0], init_list, fn_list_size);
  696. X            }
  697. X        else
  698. X            Usage(argv[0], init_list, fn_list_size);
  699. X    free(optstring);
  700. X    free(init_list);
  701. X    }
  702. X
  703. Xstatic void Usage(prog, fn_list, fn_list_size)
  704. X
  705. Xchar *prog;
  706. Xfn_list_t *fn_list;
  707. Xint fn_list_size;
  708. X
  709. X    {
  710. X    int i;
  711. X
  712. X    fprintf(stderr, "usage: %s [-", prog);
  713. X    for (i = 0; i < fn_list_size; ++i)
  714. X        fprintf(stderr, "%c", fn_list[i].flag);
  715. X    fprintf(stderr, "] [N]\n\n");
  716. X    fprintf(stderr, "Descriptions:\n");
  717. X    for (i = 0; i < fn_list_size; ++i)
  718. X        {
  719. X        fprintf(stderr, "\t-%c\t %s", fn_list[i].flag, fn_list[i].desc);
  720. X        if (fn_list[i].call)
  721. X            fprintf(stderr, " [default]");
  722. X        fprintf(stderr, "\n");
  723. X        }
  724. X    fprintf(stderr, "\tN = seconds to sleep between iterations ");
  725. X    fprintf(stderr, "[default %d]\n", SLEEP_DEFAULT);
  726. X    fprintf(stderr, "Upper case flag switches display off.\n");
  727. X    exit(1);
  728. X    }
  729. X
  730. Xstatic int InitStatusLine(prog, stat_line_info)
  731. X
  732. Xchar *prog;
  733. Xstat_line_info_t *stat_line_info;
  734. X
  735. X    {
  736. X    int errret;
  737. X    char *buf;
  738. X    int len;
  739. X    int width;
  740. X    char *tsl, *fsl;
  741. X#ifndef USE_TERMINFO
  742. X    static char buffer[200], *area = buffer;
  743. X#endif
  744. X
  745. X    if ((errret = GETFLAG("hs")) <= 0)
  746. X        {
  747. X        fprintf(stderr, "%s: ", prog);
  748. X        if (errret == 0)
  749. X            {
  750. X            fprintf(stderr, "status line not supported ");
  751. X            fprintf(stderr, "by terminal\n");
  752. X            }
  753. X        else
  754. X            fprintf(stderr, "bogus 'hs' %s entry\n", TERMMODE);
  755. X        return 1;
  756. X        }
  757. X    width = GETNUM("wsl");
  758. X    if (width == -2)
  759. X        {
  760. X        fprintf(stderr, "%s: bogus 'wsl' %s entry\n", prog, TERMMODE);
  761. X        return 1;
  762. X        }
  763. X    if (width <= 0)
  764. X        {
  765. X        width = GETNUM("cols");
  766. X        if (width <= 0)
  767. X            width = 40;               /* hope this is reasonable */
  768. X        }
  769. X    stat_line_info->width = width - 1;
  770. X#ifdef USE_TERMINFO
  771. X    tsl = GETPARM(to_status_line);
  772. X#else
  773. X    tsl = GETPARM("ts");
  774. X#endif
  775. X    if (!tsl)
  776. X        {
  777. X        fprintf(stderr, "%s: no to status line %s entry\n", prog, 
  778. X            TERMMODE);
  779. X        return 1;
  780. X        }
  781. X    len = strlen(tsl);
  782. X    buf = malloc(len + 1);
  783. X    strcpy(buf, tsl);
  784. X    stat_line_info->tsl = buf;
  785. X    stat_line_info->tsl_len = len;
  786. X#ifdef USE_TERMINFO
  787. X    fsl = GETPARM(from_status_line);
  788. X#else
  789. X    fsl = GETPARM("fs");
  790. X#endif
  791. X    
  792. X    if (!fsl)
  793. X        {
  794. X        fprintf(stderr, "%s: no from status line %s entry\n", prog, 
  795. X            TERMMODE);
  796. X        return 1;
  797. X        }
  798. X    len = strlen(fsl);
  799. X    buf = malloc(len + 1);
  800. X    strcpy(buf, fsl);
  801. X    stat_line_info->fsl = buf;
  802. X    stat_line_info->fsl_len = len;
  803. X#ifdef USE_TERMINFO
  804. X    if (TermBell = GETPARM(bell))
  805. X#else
  806. X    if (TermBell = GETPARM("vb"))
  807. X#endif
  808. X        {
  809. X        buf = malloc(strlen(TermBell) + 1);
  810. X        strcpy(buf, TermBell);
  811. X        TermBell = buf;
  812. X        }
  813. X    else
  814. X        TermBell = DefaultBell;
  815. X
  816. X    return 0;
  817. X    }
  818. X
  819. Xvoid DisplayAdd(display, str)
  820. X
  821. Xdisplay_t *display;
  822. Xchar *str;
  823. X
  824. X    {
  825. X    int len, new_dis_len;
  826. X
  827. X    len = strlen(str);
  828. X    new_dis_len = display->display_len + len;
  829. X    while (new_dis_len + 1 >= display->buf_len)
  830. X        {
  831. X        if (display->buffer)
  832. X            display->buffer = realloc(display->buffer,
  833. X                display->buf_len += DIS_BUF_BLOCK);
  834. X        else
  835. X            display->buffer = malloc(
  836. X                display->buf_len = DIS_BUF_BLOCK);
  837. X        new_dis_len = display->display_len + len;
  838. X        }
  839. X    strcpy(&display->buffer[display->display_len], str);
  840. X    display->display_len = new_dis_len;
  841. X    }
  842. X
  843. Xstatic void CleanUp(sig_no)
  844. X
  845. Xint sig_no;
  846. X
  847. X    {
  848. X    (void)signal(SIGHUP, SIG_IGN);
  849. X    (void)signal(SIGTERM, SIG_IGN);
  850. X    CleanDisplay->display_len = 0;
  851. X    ShowDisplay(CleanDisplay, 1);
  852. X    reset_shell_mode();
  853. X
  854. X    exit(0);
  855. X    }
  856. X
  857. X#ifdef USE_TERMINFO
  858. X
  859. Xstatic void TermInit(prog)
  860. X
  861. Xchar *prog;
  862. X
  863. X    {
  864. X    int errret;
  865. X
  866. X    if (setupterm((char *)0, 1, &errret) == ERR)
  867. X        {
  868. X        fprintf(stderr, "%s: setupterm failed - %d\n", prog, errret);
  869. X        exit(1);
  870. X        }
  871. X    }
  872. X
  873. X#else
  874. X
  875. Xstatic void TermInit(prog)
  876. X
  877. Xchar *prog;
  878. X
  879. X    {
  880. X    static char bp[1024];
  881. X    char *term;
  882. X
  883. X    term = getenv("TERM");
  884. X    if (! term)
  885. X        {
  886. X        fprintf(stderr, "%s: bad TERM variable\n", prog);
  887. X        exit(1);
  888. X        }
  889. X    switch (tgetent(bp, term)) 
  890. X        {
  891. X        case -1 :
  892. X        fprintf(stderr, "%s: can't open termcap file.\n", prog);
  893. X        exit(1);
  894. X        break;
  895. X        case 0:
  896. X        fprintf(stderr, "%s: no termcap entry for %s.\n", term);
  897. X        exit(1);
  898. X        }
  899. X    }
  900. X
  901. X#endif
  902. GURK
  903. chmod 0644 statline.c || echo 'restore of statline.c fails'
  904. echo 'mshar: extracting users.c (size: 3938)'
  905. sed 's/^X//' << 'GURK' > users.c &&
  906. X#include <stdio.h>
  907. X#include <sys/types.h>
  908. X#include <utmp.h>
  909. X#include <string.h>
  910. X#include "types.h"
  911. X#include "funcs.h"
  912. X
  913. X#define USER_SIZE (sizeof(sizeutmp.ut_user) / sizeof(sizeutmp.ut_user[0]))
  914. X
  915. Xextern char *malloc(), *realloc();
  916. Xextern void qsort();
  917. X
  918. Xextern time_t Now;
  919. X
  920. Xstatic int Users();
  921. Xstatic int AddUser();
  922. Xstatic int UserCmp();
  923. Xstatic int InUserList();
  924. X
  925. Xstatic char **UserList = 0;
  926. Xstatic int UserListSize = 0;
  927. Xstatic struct utmp sizeutmp;
  928. X
  929. Xint UsersCountFnInit(display)
  930. X
  931. Xdisplay_t *display;
  932. X
  933. X    {
  934. X    return 1;
  935. X    }
  936. X
  937. Xint UsersCountFn(display)
  938. X
  939. Xdisplay_t *display;
  940. X
  941. X    {
  942. X    int user_count;
  943. X    char buf[128];
  944. X
  945. X    user_count = Users();
  946. X    if (user_count < 0)
  947. X        {
  948. X        DisplayAdd(display, "cannot read /etc/utmp ");
  949. X        return 0;
  950. X        }
  951. X    sprintf(buf, "uc: %d ", user_count);
  952. X    DisplayAdd(display, buf);
  953. X
  954. X    return 1;
  955. X    }
  956. X
  957. Xint UsersFnInit(display)
  958. X
  959. Xdisplay_t *display;
  960. X
  961. X    {
  962. X    return 1;
  963. X    }
  964. X
  965. Xint UsersFn(display)
  966. X
  967. Xdisplay_t *display;
  968. X
  969. X    {
  970. X    int i;
  971. X    int user_count;
  972. X
  973. X    user_count = Users();
  974. X    if (user_count < 0)
  975. X        {
  976. X        DisplayAdd(display, "cannot read /etc/utmp");
  977. X        return 0;
  978. X        }
  979. X    if (user_count == 0)
  980. X        {
  981. X        DisplayAdd(display, "no users ");
  982. X        return 1;
  983. X        }
  984. X    DisplayAdd(display, "users: ");
  985. X    for (i = 0; i < user_count; ++i)
  986. X        {
  987. X        DisplayAdd(display, UserList[i]);
  988. X        DisplayAdd(display, " ");
  989. X        }
  990. X
  991. X    return 1;
  992. X    }
  993. X
  994. Xint UsersDeltaInit(display)
  995. X
  996. Xdisplay_t *display;
  997. X
  998. X    {
  999. X    return 1;
  1000. X    }
  1001. X
  1002. Xint UsersDelta(display)
  1003. X
  1004. Xdisplay_t *display;
  1005. X
  1006. X    {
  1007. X    int i;
  1008. X    int user_count;
  1009. X    static char **old_list = 0;
  1010. X    static int old_list_count = 0;
  1011. X    static int old_list_size = 0;
  1012. X
  1013. X    user_count = Users();
  1014. X    if (user_count < 0)
  1015. X        {
  1016. X        DisplayAdd(display, "delta cannot read /etc/utmp");
  1017. X        return 0;
  1018. X        }
  1019. X    for (i = 0; i < old_list_count; ++i)
  1020. X        if (! InUserList(old_list[i], UserList, user_count))
  1021. X            {
  1022. X            DisplayAdd(display, old_list[i]);
  1023. X            DisplayAdd(display, "(off) ");
  1024. X            }
  1025. X    for (i = 0; i < user_count; ++i)
  1026. X        if (! InUserList(UserList[i], old_list, old_list_count))
  1027. X            {
  1028. X            DisplayAdd(display, UserList[i]);
  1029. X            DisplayAdd(display, "(on) ");
  1030. X            }
  1031. X    if (user_count == 0 && old_list_count == 0)
  1032. X        return 1;
  1033. X    if (user_count > old_list_size)
  1034. X        {
  1035. X        if (! old_list)
  1036. X            old_list = (char **)malloc(sizeof(char **) *
  1037. X                user_count);
  1038. X        else
  1039. X            old_list = (char **)realloc(old_list,
  1040. X                sizeof(char **) * user_count);
  1041. X        for (i = old_list_size; i < user_count; ++i)
  1042. X            old_list[i] = malloc(USER_SIZE + 1);
  1043. X        old_list_size = user_count;
  1044. X        }
  1045. X    for (i = 0; i < user_count; ++i)
  1046. X        strcpy(old_list[i], UserList[i]);
  1047. X    old_list_count = user_count;
  1048. X
  1049. X    return 1;
  1050. X    }
  1051. X
  1052. Xstatic int InUserList(name, list, list_count)
  1053. X
  1054. Xchar *name;
  1055. Xchar **list;
  1056. Xint list_count;
  1057. X
  1058. X    {
  1059. X    int i;
  1060. X
  1061. X    i = 0;
  1062. X    while (i < list_count && strcmp(name, list[i]))
  1063. X        ++i;
  1064. X
  1065. X    return i < list_count;
  1066. X    }
  1067. X
  1068. Xstatic int Users()
  1069. X
  1070. X    {
  1071. X    FILE *fp;
  1072. X    struct utmp utmp;
  1073. X    static time_t last_check = 0;
  1074. X    static int user_count = 0;
  1075. X
  1076. X    if (last_check == Now)       /* go easy on file system */
  1077. X        return user_count;
  1078. X    if ((fp = fopen("/etc/utmp", "r")) == NULL)
  1079. X        return -1;
  1080. X    user_count = 0;
  1081. X    while (fread((char *)&utmp, sizeof(utmp), 1, fp) == 1)
  1082. X        if (utmp.ut_user[0] != '\0' && utmp.ut_type == USER_PROCESS)
  1083. X            if (AddUser(&utmp, user_count))
  1084. X                ++user_count;
  1085. X    (void)fclose(fp);
  1086. X
  1087. X    if (user_count)
  1088. X        qsort((char *)UserList, user_count, sizeof(char *), UserCmp);
  1089. X
  1090. X    last_check = Now;
  1091. X
  1092. X    return user_count;
  1093. X    }
  1094. X
  1095. Xstatic int UserCmp(s1, s2)
  1096. X
  1097. Xchar **s1;
  1098. Xchar **s2;
  1099. X
  1100. X    {
  1101. X    return strcmp(*s1, *s2);
  1102. X    }
  1103. X
  1104. Xstatic int AddUser(utmp, count)
  1105. X
  1106. Xstruct utmp *utmp;
  1107. Xint count;
  1108. X
  1109. X    {
  1110. X    char new_user[USER_SIZE + 1];
  1111. X    int i;
  1112. X
  1113. X    memcpy(new_user, utmp->ut_user, USER_SIZE);
  1114. X    new_user[USER_SIZE] = '\0';
  1115. X    i = 0;
  1116. X    while (i < count && strcmp(UserList[i], new_user) != 0)
  1117. X        ++i;
  1118. X    if (i < count)
  1119. X        return 0;
  1120. X    if (count >= UserListSize)
  1121. X        {
  1122. X        UserListSize = count + 1;
  1123. X        if (! UserList)
  1124. X            UserList = (char **)malloc(sizeof(char *));
  1125. X        else
  1126. X            UserList = (char **)realloc(UserList,
  1127. X                sizeof(char *) * UserListSize);
  1128. X        UserList[count] = malloc(USER_SIZE + 1);
  1129. X        }
  1130. X    strcpy(UserList[count], new_user);
  1131. X
  1132. X    return 1;
  1133. X    }
  1134. GURK
  1135. chmod 0644 users.c || echo 'restore of users.c fails'
  1136. echo 'mshar: extracting kmem.sysv.c (size: 4390)'
  1137. sed 's/^X//' << 'GURK' > kmem.sysv.c &&
  1138. X
  1139. X/* kmem.sysv.c - kmem routines for System V.3.2 */
  1140. X
  1141. X#include <fcntl.h>
  1142. X#include <stdio.h>
  1143. X#include <a.out.h>
  1144. X#include <sys/types.h>
  1145. X#include <sys/sysinfo.h>
  1146. X#include <errno.h>
  1147. X#include "types.h"
  1148. X#include "funcs.h"
  1149. X
  1150. X#define NL_SYSINFO 0
  1151. X#define NL_LBOLT 1
  1152. X#define CPU_INFO_SZ (sizeof(sysinfo.cpu) / sizeof(sysinfo.cpu[0]))
  1153. X#define DEFAULT_HZ "60"
  1154. X
  1155. Xextern long lseek();
  1156. Xextern char *getenv();
  1157. X
  1158. Xextern char *TermBell;
  1159. Xextern time_t Now;
  1160. X
  1161. Xstruct sysinfo sysinfo;  /* need to declare these to deal with sys/sysinfo.h */
  1162. Xtime_t lbolt;            /* extern declarations */
  1163. Xstatic struct nlist NlistInfo[] = {
  1164. X    {"sysinfo"},
  1165. X    {"lbolt"},
  1166. X    {0}};
  1167. X
  1168. Xstatic int NlistLoaded = 0;
  1169. Xstatic int KmemFd;
  1170. Xstatic time_t SavedCpu[CPU_INFO_SZ];
  1171. Xstatic time_t BootTime;
  1172. Xstatic int Hertz;
  1173. X
  1174. Xint LoadFnInit(display)
  1175. X
  1176. Xdisplay_t *display;
  1177. X
  1178. X    {
  1179. X    int i;
  1180. X    char *hz_str;
  1181. X    struct sysinfo sysinfo;
  1182. X    static int kmem_status = 0;
  1183. X
  1184. X    if (! NlistLoaded)
  1185. X        {
  1186. X        NlistLoaded = 1;
  1187. X        if (nlist("/unix", NlistInfo) < 0)
  1188. X            {
  1189. X            DisplayAdd(display, "nlist error ");
  1190. X            return 0;
  1191. X            }
  1192. X        if (NlistInfo[NL_SYSINFO].n_value == 0)
  1193. X            {
  1194. X            DisplayAdd(display, "bad sysinfo offset ");
  1195. X            write(fileno(stdout), TermBell, strlen(TermBell));
  1196. X            return 0;
  1197. X            }
  1198. X        if (NlistInfo[NL_LBOLT].n_value == 0)
  1199. X            {
  1200. X            DisplayAdd(display, "bad lbolt offset ");
  1201. X            write(fileno(stdout), TermBell, strlen(TermBell));
  1202. X            return 0;
  1203. X            }
  1204. X        if (! (hz_str = getenv("HZ")))
  1205. X            hz_str = DEFAULT_HZ;
  1206. X        Hertz = atoi(hz_str);
  1207. X        if ((KmemFd = open("/dev/kmem", O_RDONLY)) < 0)
  1208. X            {
  1209. X            DisplayAdd(display, "cannot open kmem ");
  1210. X            return 0;
  1211. X            }
  1212. X        if (lseek(KmemFd, NlistInfo[NL_SYSINFO].n_value, 0) == -1L)
  1213. X            {
  1214. X            char buf[128];
  1215. X            extern char *sys_errlist[];
  1216. X
  1217. X            sprintf(buf, "kmem lseek error %d %s %u ", errno,
  1218. X                sys_errlist[errno], NlistInfo[NL_SYSINFO].n_value);
  1219. X            DisplayAdd(display, buf);
  1220. X            write(fileno(stdout), TermBell, strlen(TermBell));
  1221. X            return 0;
  1222. X            }
  1223. X        if (read(KmemFd, (char *)&sysinfo, sizeof(sysinfo)) < 0)
  1224. X            {
  1225. X            DisplayAdd(display, "kmem read error ");
  1226. X            write(fileno(stdout), TermBell, strlen(TermBell));
  1227. X            return 0;
  1228. X            }
  1229. X        for (i = 0; i < CPU_INFO_SZ; ++i)
  1230. X            SavedCpu[i] = sysinfo.cpu[i];
  1231. X
  1232. X        kmem_status = 1;
  1233. X        }
  1234. X
  1235. X    return kmem_status;
  1236. X    }
  1237. X
  1238. Xint LoadFn(display)
  1239. X
  1240. Xdisplay_t *display;
  1241. X
  1242. X    {
  1243. X    int i;
  1244. X    time_t all_krn;
  1245. X    struct sysinfo sysinfo;
  1246. X    time_t new_cpu[CPU_INFO_SZ];
  1247. X    double total_cpu;
  1248. X    char buf[128];
  1249. X
  1250. X    if (lseek(KmemFd, NlistInfo[NL_SYSINFO].n_value, 0) == -1L)
  1251. X        {
  1252. X        DisplayAdd(display, "kmem lseek error ");
  1253. X        (void)write(fileno(stdout), TermBell, strlen(TermBell));
  1254. X        return 0;
  1255. X        }
  1256. X    if (read(KmemFd, (char *)&sysinfo, sizeof(sysinfo)) < 0)
  1257. X        {
  1258. X        DisplayAdd(display, "kmem read error ");
  1259. X        (void)write(fileno(stdout), TermBell, strlen(TermBell));
  1260. X        return 0;
  1261. X        }
  1262. X
  1263. X    total_cpu = 0.0;
  1264. X    for (i = 0; i < CPU_INFO_SZ; ++i)
  1265. X        {
  1266. X        total_cpu += new_cpu[i] = sysinfo.cpu[i] - SavedCpu[i];
  1267. X        SavedCpu[i] = sysinfo.cpu[i];
  1268. X        }
  1269. X
  1270. X    DisplayAdd(display, "cpu: ");
  1271. X    sprintf(buf, "usr %.0f%%, ", new_cpu[CPU_USER] / total_cpu * 100.0);
  1272. X    DisplayAdd(display, buf);
  1273. X    all_krn = new_cpu[CPU_KERNEL] + new_cpu[CPU_WAIT] + new_cpu[CPU_SXBRK];
  1274. X    sprintf(buf, "krn %.0f%%, ", all_krn / total_cpu * 100.0);
  1275. X    DisplayAdd(display, buf);
  1276. X    sprintf(buf, "idl %.0f%% ", new_cpu[CPU_IDLE] / total_cpu * 100.0);
  1277. X    DisplayAdd(display, buf);
  1278. X
  1279. X    return 1;
  1280. X    }
  1281. X
  1282. Xint UptimeFnInit(display)
  1283. X
  1284. Xdisplay_t *display;
  1285. X
  1286. X    {
  1287. X    time_t lbolt;                     /* a contraction of lightning bolt */
  1288. X
  1289. X    if (LoadFnInit(display) == 0)
  1290. X        return 0;
  1291. X
  1292. X    if (lseek(KmemFd, NlistInfo[NL_LBOLT].n_value, 0) == -1L)
  1293. X        {
  1294. X        DisplayAdd(display, "kmem lbolt lseek error ");
  1295. X        (void)write(fileno(stdout), TermBell, strlen(TermBell));
  1296. X        return 0;
  1297. X        }
  1298. X    if (read(KmemFd, (char *)&lbolt , sizeof(lbolt)) < 0)
  1299. X        {
  1300. X        DisplayAdd(display, "kmem lbolt read error ");
  1301. X        (void)write(fileno(stdout), TermBell, strlen(TermBell));
  1302. X        return 0;
  1303. X        }
  1304. X
  1305. X    BootTime = Now - lbolt / Hertz;
  1306. X    if (BootTime < 0)
  1307. X        DisplayAdd(display, "very strange boottime ");
  1308. X
  1309. X    return 1;
  1310. X    }
  1311. X
  1312. Xint UptimeFn(display)
  1313. X
  1314. Xdisplay_t *display;
  1315. X
  1316. X    {
  1317. X    time_t lbolt;
  1318. X    time_t uptime;
  1319. X    int days, hours, minutes, seconds;
  1320. X    char buf[64];
  1321. X
  1322. X    uptime = Now - BootTime;
  1323. X    days = uptime / (60 * 60 * 24);
  1324. X    uptime -= days * (60 * 60 * 24);
  1325. X    hours = uptime / (60 * 60);
  1326. X    uptime -= hours * (60 * 60);
  1327. X    minutes = uptime / 60;
  1328. X    uptime -= minutes * 60;
  1329. X    seconds = uptime;
  1330. X    sprintf(buf, "ut: %d+%.2d:%.2d:%.2d ", days, hours, minutes, seconds);
  1331. X    DisplayAdd(display, buf);
  1332. X
  1333. X    return 1;
  1334. X    }
  1335. GURK
  1336. chmod 0644 kmem.sysv.c || echo 'restore of kmem.sysv.c fails'
  1337. echo 'mshar: extracting kmem.xenix.c (size: 2701)'
  1338. sed 's/^X//' << 'GURK' > kmem.xenix.c &&
  1339. X
  1340. X/* kmem.xenix.c - kmem routines for Xenix 2.3 */
  1341. X
  1342. X#include <fcntl.h>
  1343. X#include <stdio.h>
  1344. X#include <a.out.h>
  1345. X#include <sys/types.h>
  1346. X#include "types.h"
  1347. X#include "funcs.h"
  1348. X
  1349. X#define XL_AVENRUN 0
  1350. X#define XL_BOOTIME 1
  1351. X
  1352. Xextern long lseek();
  1353. Xextern char *getenv();
  1354. X
  1355. Xextern char *TermBell;
  1356. Xextern time_t Now;
  1357. X
  1358. Xstatic struct xlist XlistInfo[] = {
  1359. X    {0, 0, 0, "_avenrun"},
  1360. X    {0, 0, 0, "_bootime"},
  1361. X    {0}};
  1362. X
  1363. Xstatic int KmemFd;
  1364. Xstatic time_t BootTime;
  1365. X
  1366. Xint LoadFnInit(display)
  1367. X
  1368. Xdisplay_t *display;
  1369. X
  1370. X    {
  1371. X    static int xlist_loaded = 0;
  1372. X    static int kmem_status = 0;
  1373. X
  1374. X    if (! xlist_loaded)
  1375. X        {
  1376. X        xlist_loaded = 1;
  1377. X        if (xlist("/xenix", XlistInfo) < 0)
  1378. X            {
  1379. X            DisplayAdd(display, "xlist error ");
  1380. X            return 0;
  1381. X            }
  1382. X        if (XlistInfo[XL_AVENRUN].xl_value == 0)
  1383. X            {
  1384. X            DisplayAdd(display, "bad avenrun offset ");
  1385. X            write(fileno(stdout), TermBell, strlen(TermBell));
  1386. X            return 0;
  1387. X            }
  1388. X        if (XlistInfo[XL_BOOTIME].xl_value == 0)
  1389. X            {
  1390. X            DisplayAdd(display, "bad bootime offset ");
  1391. X            write(fileno(stdout), TermBell, strlen(TermBell));
  1392. X            return 0;
  1393. X            }
  1394. X        if ((KmemFd = open("/dev/kmem", O_RDONLY)) < 0)
  1395. X            {
  1396. X            DisplayAdd(display, "cannot open kmem ");
  1397. X            return 0;
  1398. X            }
  1399. X        kmem_status = 1;
  1400. X        }
  1401. X
  1402. X    return kmem_status;
  1403. X    }
  1404. X
  1405. Xint LoadFn(display)
  1406. X
  1407. Xdisplay_t *display;
  1408. X
  1409. X    {
  1410. X    short total_cpu;
  1411. X    char buf[32];
  1412. X
  1413. X    if (lseek(KmemFd, XlistInfo[XL_AVENRUN].xl_value, 0) == -1L)
  1414. X        {
  1415. X        DisplayAdd(display, "kmem lseek error ");
  1416. X        (void)write(fileno(stdout), TermBell, strlen(TermBell));
  1417. X        return 0;
  1418. X        }
  1419. X    if (read(KmemFd, (char *)&total_cpu, sizeof(total_cpu)) < 0)
  1420. X        {
  1421. X        DisplayAdd(display, "kmem read error ");
  1422. X        (void)write(fileno(stdout), TermBell, strlen(TermBell));
  1423. X        return 0;
  1424. X        }
  1425. X
  1426. X    DisplayAdd(display, "load: ");
  1427. X    sprintf(buf, "%.2f ", total_cpu / 256.0);
  1428. X    DisplayAdd(display, buf);
  1429. X
  1430. X    return 1;
  1431. X    }
  1432. X
  1433. Xint UptimeFnInit(display)
  1434. X
  1435. Xdisplay_t *display;
  1436. X
  1437. X    {
  1438. X    if (LoadFnInit(display) == 0)
  1439. X        return 0;
  1440. X
  1441. X    if (lseek(KmemFd, XlistInfo[XL_BOOTIME].xl_value, 0) == -1L)
  1442. X        {
  1443. X        DisplayAdd(display, "kmem lbolt lseek error ");
  1444. X        (void)write(fileno(stdout), TermBell, strlen(TermBell));
  1445. X        return 0;
  1446. X        }
  1447. X    if (read(KmemFd, (char *)&BootTime, sizeof(BootTime)) < 0)
  1448. X        {
  1449. X        DisplayAdd(display, "kmem bootime read error ");
  1450. X        (void)write(fileno(stdout), TermBell, strlen(TermBell));
  1451. X        return 0;
  1452. X        }
  1453. X
  1454. X    return 1;
  1455. X    }
  1456. X
  1457. Xint UptimeFn(display)
  1458. X
  1459. Xdisplay_t *display;
  1460. X
  1461. X    {
  1462. X    time_t uptime;
  1463. X    int days, hours, minutes, seconds;
  1464. X    char buf[64];
  1465. X
  1466. X    uptime = Now - BootTime;
  1467. X    days = uptime / (60 * 60 * 24);
  1468. X    uptime -= days * (60 * 60 * 24);
  1469. X    hours = uptime / (60 * 60);
  1470. X    uptime -= hours * (60 * 60);
  1471. X    minutes = uptime / 60;
  1472. X    uptime -= minutes * 60;
  1473. X    seconds = uptime;
  1474. X    sprintf(buf, "ut: %d+%.2d:%.2d:%.2d ", days, hours, minutes, seconds);
  1475. X    DisplayAdd(display, buf);
  1476. X
  1477. X    return 1;
  1478. X    }
  1479. GURK
  1480. chmod 0644 kmem.xenix.c || echo 'restore of kmem.xenix.c fails'
  1481. echo 'mshar: extracting editwarn.c (size: 140)'
  1482. sed 's/^X//' << 'GURK' > editwarn.c &&
  1483. X
  1484. X    /* WARNING - this is a generated file, any changes will
  1485. X     * be lost in the next make.  Edit either kmem.sysv.c or
  1486. X     * kmem.xenix.c.
  1487. X     */
  1488. X
  1489. GURK
  1490. chmod 0644 editwarn.c || echo 'restore of editwarn.c fails'
  1491. echo 'mshar: extracting funcs.h (size: 271)'
  1492. sed 's/^X//' << 'GURK' > funcs.h &&
  1493. Xint LoadFn();
  1494. Xint UsersCountFn();
  1495. Xint UsersFn();
  1496. Xint UptimeFn();
  1497. Xint DateFn();
  1498. Xint BiffFn();
  1499. Xint UsersDelta();
  1500. X
  1501. Xint LoadFnInit();
  1502. Xint UsersCountFnInit();
  1503. Xint UsersFnInit();
  1504. Xint UptimeFnInit();
  1505. Xint DateFnInit();
  1506. Xint BiffFnInit();
  1507. Xint UsersDeltaInit();
  1508. X
  1509. Xvoid DisplayAdd();
  1510. GURK
  1511. chmod 0644 funcs.h || echo 'restore of funcs.h fails'
  1512. echo 'mshar: extracting types.h (size: 363)'
  1513. sed 's/^X//' << 'GURK' > types.h &&
  1514. Xtypedef struct stat_line_info_t {
  1515. X    char *tsl;
  1516. X    int tsl_len;
  1517. X    char *fsl;
  1518. X    int fsl_len;
  1519. X    int width;
  1520. X    } stat_line_info_t;
  1521. X
  1522. Xtypedef struct display_t {
  1523. X    char *buffer;
  1524. X    int display_len;
  1525. X    int buf_len;
  1526. X    stat_line_info_t stat_line_info;
  1527. X    } display_t;
  1528. X
  1529. Xtypedef struct fn_list_t {
  1530. X    int (*fn_name)();
  1531. X    int (*init_fn_name)();
  1532. X    int call;
  1533. X    char flag;
  1534. X    char *desc;
  1535. X    } fn_list_t;
  1536. GURK
  1537. chmod 0644 types.h || echo 'restore of types.h fails'
  1538. exit 0
  1539.  
  1540.  
  1541.