home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / alt / irc / 4595 < prev    next >
Encoding:
Text File  |  1992-12-11  |  15.3 KB  |  696 lines

  1. Path: sparky!uunet!munnari.oz.au!manuel.anu.edu.au!coombs!avalon
  2. From: avalon@coombs.anu.edu.au (Darren Reed)
  3. Newsgroups: alt.irc
  4. Subject: stats programs...
  5. Date: 11 Dec 92 21:18:09 GMT
  6. Organization: Australian National University
  7. Lines: 685
  8. Message-ID: <avalon.724108689@coombs>
  9. NNTP-Posting-Host: 150.203.76.2
  10.  
  11. There has bee a lot of interest (seemingly) in stats recently...
  12. well here is a couple of programs I wrote way back to check up on
  13. how the net is behaving and whats happening where...both programs
  14. run as clients and use a bit of curses to do their work.
  15.  
  16. I guess if you made them log what retrieved rather than display it,
  17. and then ran it for a while (week at least!) you could compile some
  18. rather interesting stats which might even be of use.
  19.  
  20. avalon
  21.  
  22. -cut here--cut here--cut here--cut here--cut here--cut here--cut here--cut here-
  23. # This is a shell archive.  Save it in a file, remove anything before
  24. # this line, and then unpack it by entering "sh file".  Note, it may
  25. # create directories; files and directories will be owned by you and
  26. # have default permissions.
  27. #
  28. # This archive contains:
  29. #
  30. #    stat/Makefile
  31. #    stat/README
  32. #    stat/cmdmon.c
  33. #    stat/flowmon.c
  34. #
  35. echo x - stat/Makefile
  36. sed 's/^X//' >stat/Makefile << 'END-of-stat/Makefile'
  37. X# Makefile (C)1992 Darren Reed
  38. X# Makefile for realtime server stats clients
  39. X#
  40. XLIBS=-lcurses -ltermcap
  41. XCFLAGS=-O
  42. XPROGS=cmdmon flowmon
  43. X
  44. Xall: $(PROGS)
  45. X
  46. Xcmdmon: cmdmon.c
  47. X    $(CC) $@.c $(CFLAGS) -o $@ $(LIBS)
  48. X
  49. Xflowmon: flowmon.c
  50. X    $(CC) $@.c $(CFLAGS) -o $@ $(LIBS)
  51. X
  52. Xclean:
  53. X    /bin/rm -f core *.o $(PROGS)
  54. END-of-stat/Makefile
  55. echo x - stat/README
  56. sed 's/^X//' >stat/README << 'END-of-stat/README'
  57. X
  58. XSimple...
  59. X
  60. XEdit them to set the nicks, user info and server and then get them compiled.
  61. X
  62. Xthen run using
  63. X
  64. Xcmdmon [ server [ port [ updatedelay ] ] ]
  65. Xflowmon [ server [ port [ updatedelay ] ] ]
  66. X
  67. XBrief.
  68. X------
  69. X
  70. Xcmdmon
  71. X
  72. X   Shows the changing use of the most used commands on the server in sorted
  73. Xorder of most used to least used.
  74. X
  75. Xflowmon
  76. X
  77. X   Shows the flow of data into a server and out its links.  Can be very
  78. Xuseful.
  79. X
  80. XBoth use curses to maintain the display and should show as many entries
  81. Xas possible.
  82. X
  83. XThere are probably bugs somewhere too.
  84. END-of-stat/README
  85. echo x - stat/cmdmon.c
  86. sed 's/^X//' >stat/cmdmon.c << 'END-of-stat/cmdmon.c'
  87. X/*
  88. X * cmdmon.c (C)1992 Darren Reed
  89. X * monitor number of commands processed by a server
  90. X *
  91. X */
  92. X#include <sys/types.h>
  93. X#include <sys/time.h>
  94. X#include <netinet/in.h>
  95. X#include <sys/socket.h>
  96. X#include <stdio.h>
  97. X#include <curses.h>
  98. X#include <netdb.h>
  99. X/*
  100. X * change this.
  101. X */
  102. Xchar signon[] ="NICK changethis\n\rUSER foobar foobar foobar foobar\n\r";
  103. X/*
  104. X * leave these
  105. X */
  106. Xchar pong[] = "PONG ping\n\r";
  107. Xchar statsm[] ="STATS M\n\r";
  108. X
  109. X#define    SERVERIP    "a.server.ip.goes.here"
  110. X#define    SERVERPORT    -1
  111. X#define    UPDATEDELAY    60
  112. X
  113. Xchar    buff[512], serv[60], nick[20], msg[20], *server;
  114. Xint    cnt, port;
  115. X
  116. Xmain(argc, argv)
  117. Xint    argc;
  118. Xchar    *argv[];
  119. X{
  120. X    struct sockaddr_in serv;
  121. X    FILE    *f;
  122. X    int    sock, sl, statsl, pl, num, fields, off = 0;
  123. X    long    last, lastm, waittime;
  124. X    char    *t;
  125. X    struct    hostent *hp = NULL;
  126. X
  127. X    sl = strlen(signon);
  128. X    pl = strlen(pong);
  129. X    statsl = strlen(statsm);
  130. X    bzero(&serv, sizeof(serv));
  131. X    /*
  132. X     * ip# of server to connect to
  133. X     */
  134. X    server = (argc > 1) ? argv[1] : SERVERIP;
  135. X    port = (argc > 2 ) ? atoi(argv[2]) : SERVERPORT;
  136. X    waittime = (argc > 3) ? atoi(argv[3]) : UPDATEDELAY;
  137. X
  138. X    if (!isdigit(*server))
  139. X        {
  140. X        hp = gethostbyname(server);
  141. X        if (hp)
  142. X            bcopy(hp->h_addr_list[0], (char *)&serv.sin_addr,
  143. X                sizeof(struct in_addr));
  144. X        else
  145. X            {
  146. X            printf("Couldnt lookup %s\n",server);
  147. X            exit(0);
  148. X            }
  149. X        }
  150. X    else
  151. X        serv.sin_addr.s_addr = inet_addr(server);
  152. X    serv.sin_port = htons(port);
  153. X    serv.sin_family = AF_INET;
  154. X
  155. X    if ((sock = socket(AF_INET, SOCK_STREAM, 0))<0) {
  156. X        perror("socket");
  157. X        exit(-1);
  158. X    }
  159. X
  160. X    if (connect(sock, (char *)&serv, sizeof(serv))==-1) {
  161. X        perror("connect");
  162. X        exit(-1);
  163. X    }
  164. X    /*if (fork())
  165. X        exit(0);*/
  166. X    write(sock, signon, sl);
  167. X    write(sock, statsm, strlen(statsm)+1);
  168. X    lastm = last = time(0);
  169. X
  170. X    initscr();
  171. X    clear();
  172. X    refresh();
  173. X    while (1) {
  174. X        fd_set rd;
  175. X        struct timeval wait;
  176. X        int len, n;
  177. X        char *pr = NULL, *s;
  178. X
  179. X        wait.tv_sec = waittime;
  180. X        wait.tv_usec = 0;
  181. X        FD_ZERO(&rd);
  182. X        FD_SET(sock, &rd);
  183. X        n = select(FD_SETSIZE, &rd, 0, 0, &wait);
  184. X
  185. X        if (FD_ISSET(sock, &rd))
  186. X            {
  187. X            if ((len=read(sock, buff+off, sizeof(buff)-1-off))<=0) {
  188. X                s_error(s);
  189. X                exit(-1);
  190. X            }
  191. X            buff[off+len] = 0;
  192. X            pr = buff;
  193. X            for (s = (char *)index(buff, '\n');s;
  194. X                 pr = s, s = (char *)index(pr, '\n'))
  195. X                {
  196. X                off = 0;
  197. X                *s++ = '\0';
  198. X                if (t = (char *)index(pr, ' '))
  199. X                    if (!isdigit(*(t+1)))
  200. X                        continue;
  201. X                fields = sscanf(pr,":%s %d %s",
  202. X                        serv, &num, nick);
  203. X                if (fields != 3)
  204. X                    continue;
  205. X                if (num == 219)
  206. X                    showstats();
  207. X                else if (num == 212)
  208. X                    {
  209. X                    fields = sscanf(pr,":%s %d %s %s %d",
  210. X                            serv, &num, nick,
  211. X                            msg, &cnt);
  212. X                    if (fields == 5)
  213. X                        dostats();
  214. X                    }
  215. X                }
  216. X            if (pr && (off=strlen(pr)))
  217. X                bcopy(pr, buff, off+1);
  218. X        }
  219. X        if (time(0)-last > 30) {
  220. X            write(sock, pong, pl);
  221. X            last = time(0);
  222. X        }
  223. X        if (time(0)-lastm > waittime) {
  224. X            write(sock, statsm, statsl);
  225. X            lastm = time(0);
  226. X        }
  227. X    }
  228. X}
  229. X
  230. Xs_error(fd)
  231. Xint    fd;
  232. X{
  233. X}
  234. X
  235. X#define MSG_PRIVATE  "PRIVMSG"
  236. X#define MSG_WHO      "WHO"
  237. X#define MSG_WHOIS    "WHOIS"
  238. X#define MSG_WHOWAS   "WHOWAS"
  239. X#define MSG_USER     "USER"
  240. X#define MSG_NICK     "NICK"
  241. X#define MSG_SERVER   "SERVER"
  242. X#define MSG_LIST     "LIST"
  243. X#define MSG_TOPIC    "TOPIC"
  244. X#define MSG_INVITE   "INVITE"
  245. X#define MSG_VERSION  "VERSION"
  246. X#define MSG_QUIT     "QUIT"
  247. X#define MSG_SQUIT    "SQUIT"
  248. X#define MSG_KILL     "KILL"
  249. X#define MSG_INFO     "INFO"
  250. X#define MSG_LINKS    "LINKS"
  251. X#define MSG_SUMMON   "SUMMON"
  252. X#define MSG_STATS    "STATS"
  253. X#define MSG_USERS    "USERS"
  254. X#define MSG_RESTART  "RESTART"
  255. X#define MSG_HELP     "HELP"
  256. X#define MSG_WHOREPLY "WHOREPLY"
  257. X#define MSG_ERROR    "ERROR"
  258. X#define MSG_AWAY     "AWAY"
  259. X#define MSG_DIE      "DIE"
  260. X#define MSG_CONNECT  "CONNECT"
  261. X#define MSG_PING     "PING"
  262. X#define MSG_PONG     "PONG"
  263. X#define MSG_OPER     "OPER"
  264. X#define MSG_PASS     "PASS"
  265. X#define MSG_WALLOPS  "WALLOPS"
  266. X#define MSG_TIME     "TIME"
  267. X#define MSG_REHASH   "REHASH"
  268. X#define MSG_NAMES    "NAMES"
  269. X#define MSG_NAMREPLY "NAMREPLY"
  270. X#define MSG_ADMIN    "ADMIN"
  271. X#define MSG_TRACE    "TRACE"
  272. X#define MSG_LINREPLY "LINREPLY"
  273. X#define MSG_NOTICE   "NOTICE"
  274. X#define MSG_JOIN     "JOIN"
  275. X#define MSG_PART     "PART"
  276. X#define MSG_LUSERS   "LUSERS"
  277. X#define MSG_MOTD     "MOTD"
  278. X#define MSG_MODE     "MODE"
  279. X#define MSG_KICK     "KICK"
  280. X#define MSG_SERVICE  "SERVICE"
  281. X#define MSG_USERHOST "USERHOST"
  282. X#define MSG_ISON     "ISON"
  283. X#define MSG_SERVICE  "SERVICE"
  284. X#define MSG_NOTE     "NOTE"
  285. X#define MSG_SQUERY   "SQUERY"
  286. X#define MSG_SERVLIST "SERVLIST"
  287. X#define MSG_SERVSET  "SERVSET"
  288. X#define    MSG_HASH     "HASH"
  289. X
  290. Xtypedef struct    Message {
  291. X  char    *cmd;
  292. X  int    count;
  293. X  int    lcount;
  294. X} MType;
  295. X
  296. Xstruct Message msgtab[] = {
  297. X  { MSG_PRIVATE    , 0, 0 },
  298. X  { MSG_NICK    , 0, 0 },
  299. X  { MSG_NOTICE    , 0, 0 },
  300. X  { MSG_USER    , 0, 0 },
  301. X  { MSG_JOIN    , 0, 0 },
  302. X  { MSG_QUIT    , 0, 0 },
  303. X  { MSG_MODE    , 0, 0 },
  304. X  { MSG_PART    , 0, 0 },
  305. X  { MSG_AWAY    , 0, 0 },
  306. X  { MSG_SERVER    , 0, 0 },
  307. X  { MSG_PONG    , 0, 0 },
  308. X  { MSG_WHOIS    , 0, 0 },
  309. X  { MSG_WALLOPS    , 0, 0 },
  310. X  { MSG_TOPIC    , 0, 0 },
  311. X  { MSG_SQUIT    , 0, 0 },
  312. X  { MSG_OPER    , 0, 0 },
  313. X  { MSG_WHO    , 0, 0 },
  314. X  { MSG_USERHOST    , 0, 0 },
  315. X  { MSG_KICK    , 0, 0 },
  316. X  { MSG_WHOWAS    , 0, 0 },
  317. X  { MSG_LIST    , 0, 0 },
  318. X  { MSG_NAMES    , 0, 0 },
  319. X  { MSG_INVITE    , 0, 0 },
  320. X  { MSG_PING    , 0, 0 },
  321. X  { MSG_ISON    , 0, 0 },
  322. X  { MSG_KILL    , 0, 0 },
  323. X  { MSG_TRACE    , 0, 0 },
  324. X  { MSG_PASS    , 0, 0 },
  325. X  { MSG_LUSERS    , 0, 0 },
  326. X  { MSG_TIME    , 0, 0 },
  327. X  { MSG_CONNECT    , 0, 0 },
  328. X  { MSG_VERSION    , 0, 0 },
  329. X  { MSG_STATS    , 0, 0 },
  330. X  { MSG_LINKS    , 0, 0 },
  331. X  { MSG_ADMIN    , 0, 0 },
  332. X  { MSG_ERROR    , 0, 0 },
  333. X  { MSG_USERS    , 0, 0 },
  334. X  { MSG_REHASH    , 0, 0 },
  335. X  { MSG_SUMMON    , 0, 0 },
  336. X  { MSG_HELP    , 0, 0 },
  337. X  { MSG_INFO    , 0, 0 },
  338. X  { MSG_MOTD    , 0, 0 },
  339. X  { MSG_NOTE    , 0, 0 },
  340. X  { MSG_SERVICE    , 0, 0 },
  341. X  { MSG_SERVSET    , 0, 0 },
  342. X  { MSG_SQUERY    , 0, 0 },
  343. X  { MSG_SERVLIST    , 0, 0 },
  344. X  { MSG_HASH    , 0, 0 },
  345. X  { MSG_RESTART    , 0, 0 },
  346. X  { MSG_DIE    , 0, 0 },
  347. X  { (char *) 0    , 0, 0 }
  348. X};
  349. X
  350. Xdostats()
  351. X{
  352. Xregister int i;
  353. X
  354. Xfor (i = 0; msgtab[i].cmd; i++)
  355. X    if (!strcasecmp(msgtab[i].cmd, msg))
  356. X        {
  357. X        msgtab[i].lcount = msgtab[i].count;
  358. X        msgtab[i].count = cnt;
  359. X        return;
  360. X        }
  361. X}
  362. X
  363. Xsortm(p1, p2)
  364. Xregister MType *p1, *p2;
  365. X{
  366. X    return (p2->count - p1->count);
  367. X}
  368. Xshowstats()
  369. X{
  370. X    static int entries = sizeof(msgtab)/sizeof(MType);
  371. X    int i, show;
  372. X    long now = time(0);
  373. X
  374. X    show = entries;
  375. X    if (show > LINES - 3)
  376. X        show = LINES -3;
  377. X
  378. X    qsort(msgtab, sizeof(msgtab)/sizeof(MType), sizeof(MType), sortm);
  379. X    move(0,0);
  380. X    refresh();
  381. X    mvcur(LINES-1,COLS-1,0,0);
  382. X    refresh();
  383. X    printw("%s", ctime(&now));
  384. X    printw("Command    Count     LastCount Change %s %d\n", server,port);
  385. X    printw("---------- --------- --------- ------\n");
  386. X    for (i = 0; i < show; i++)
  387. X        {
  388. X        printw("%-10s %9d %9d %6d\n",
  389. X            msgtab[i].cmd, msgtab[i].count, msgtab[i].lcount,
  390. X            msgtab[i].count - msgtab[i].lcount);
  391. X        }
  392. X    refresh();
  393. X    mvcur(LINES-1,COLS-1,0,0);
  394. X    refresh();
  395. X}
  396. END-of-stat/cmdmon.c
  397. echo x - stat/flowmon.c
  398. sed 's/^X//' >stat/flowmon.c << 'END-of-stat/flowmon.c'
  399. X/*
  400. X * flownmon.c (C)1992 Darren Reed.
  401. X * monitors data flow over irc server connections.
  402. X * maybe of use to someone.
  403. X */
  404. X#include <sys/types.h>
  405. X#include <sys/time.h>
  406. X#include <netinet/in.h>
  407. X#include <sys/socket.h>
  408. X#include <stdio.h>
  409. X#include <curses.h>
  410. X#include <netdb.h>
  411. X/*
  412. X * change this.
  413. X */
  414. Xchar signon[] ="NICK changethis\n\rUSER foobar foobar foobar foobar\n\r";
  415. X/*
  416. X * leave these
  417. X */
  418. Xchar pong[] = "PONG ping\n\r";
  419. Xchar statsm[] ="STATS l *\n\r";
  420. Xchar operm[] = "OPER ---- -----\n\r";
  421. X
  422. X#define    SERVERIP    "a.server.ip.num.goes.here"
  423. X#define    SERVERPORT    -1
  424. X#define    UPDATEDELAY    10
  425. X
  426. Xchar    buff[8192], servn[60], nick[20], msg[20];
  427. Xchar    *server, name[60], pbuf[512];
  428. Xint    port, numb;
  429. Xlong    sq, sm, sb, rm, rb, scantime;
  430. X
  431. Xstruct stats {
  432. X    int    sndq, sndm, sndb, rcvm, rcvb;
  433. X};
  434. X
  435. Xtypedef struct    Message {
  436. X    char    cnam[60];
  437. X    struct    stats    now;
  438. X     struct    stats    old;
  439. X    long    update;
  440. X} MType;
  441. X
  442. Xstruct Message msgtab[256];
  443. X
  444. Xmain(argc, argv)
  445. Xint    argc;
  446. Xchar    *argv[];
  447. X{
  448. X    struct sockaddr_in serv;
  449. X    FILE    *f;
  450. X    int    sock, sl, statsl, pl, fields, off = 0, len = 0;
  451. X    int    waittime;
  452. X    long    last, lastm;
  453. X    struct    hostent *hp = NULL;
  454. X
  455. X    bzero(msgtab, sizeof(msgtab));
  456. X    sl = strlen(signon);
  457. X    pl = strlen(pong);
  458. X    statsl = strlen(statsm);
  459. X    bzero(&serv, sizeof(serv));
  460. X    /*
  461. X     * ip# of server to connect to
  462. X     */
  463. X    server = (argc > 1) ? argv[1] : SERVERIP;
  464. X    port = (argc > 2 ) ? atoi(argv[2]) : SERVERPORT;
  465. X    waittime = (argc > 3 ) ? atoi(argv[3]) : 30;
  466. X
  467. X    if (!isdigit(*server))
  468. X        {
  469. X        hp = gethostbyname(server);
  470. X        if (hp)
  471. X            bcopy(hp->h_addr_list[0], (char *)&serv.sin_addr,
  472. X                sizeof(struct in_addr));
  473. X        else
  474. X            {
  475. X            printf("couldnt lookup %s\n",server);
  476. X            exit(0);
  477. X            }
  478. X        }
  479. X    else
  480. X        serv.sin_addr.s_addr = inet_addr(server);
  481. X    printf("Connecting to %s\n", inet_ntoa(serv.sin_addr));
  482. X    serv.sin_port = htons(port);
  483. X    serv.sin_family = AF_INET;
  484. X
  485. X    if ((sock = socket(AF_INET, SOCK_STREAM, 0))<0) {
  486. X        perror("socket");
  487. X        exit(-1);
  488. X    }
  489. X
  490. X    if (connect(sock, (char *)&serv, sizeof(serv))==-1) {
  491. X        perror("connect");
  492. X        exit(-1);
  493. X    }
  494. X    printf("Connected.\n");
  495. X    write(sock, signon, sl);
  496. X/*    write(sock, operm, strlen(operm));*/
  497. X    write(sock, statsm, strlen(statsm)+1);
  498. X    scantime = lastm = last = time(0);
  499. X
  500. X    initscr();
  501. X    clear();
  502. X    refresh();
  503. X
  504. X    off = 0;
  505. X    pbuf[off] = '\0';
  506. X
  507. X    while (1) {
  508. X        fd_set rd;
  509. X        struct timeval wait;
  510. X        int n;
  511. X        char *pr = NULL, *s = NULL, *t = NULL;
  512. X
  513. X        wait.tv_sec = 10;
  514. X        wait.tv_usec = 0;
  515. X        FD_ZERO(&rd);
  516. X        FD_SET(sock, &rd);
  517. X        n = select(FD_SETSIZE, &rd, 0, 0, &wait);
  518. X
  519. X        if (FD_ISSET(sock, &rd))
  520. X            {
  521. X            len = sizeof(buff) - 1;
  522. X            if ((len = read(sock, buff, len)) <= 0) {
  523. X                s_error(s);
  524. X                exit(-1);
  525. X            }
  526. X            buff[len] = 0;
  527. X            while (s = (char *)index(buff, '\n'))
  528. X                {
  529. X                *s++ = '\0';
  530. X                strncat(pbuf, buff,
  531. X                    sizeof(pbuf)- stlen(pbuf));
  532. X                len -= (stlen(buff) + 1);
  533. X                if (len >= 0)
  534. X                    movemem(s, buff, len+1);
  535. X                if (t = (char *)index(pbuf, ' '))
  536. X                    if (!isdigit(*++t))
  537. X                        goto parsegoto;
  538. X                fields = sscanf(pbuf,":%s %d %s",
  539. X                        servn, &numb, nick);
  540. X                if (fields != 3)
  541. X                    goto parsegoto;
  542. X                if (numb < 211 || numb > 219)
  543. X                    goto parsegoto;
  544. X                if (numb == 219)
  545. X                    showstats();
  546. X                else if (numb == 211)
  547. X                    {
  548. X                    fields = sscanf(pbuf,
  549. X                        ":%s %d %s %s %d %d %d %d %d",
  550. X                        servn, &numb, nick, name,
  551. X                        &sq, &sm, &sb, &rm, &rb);
  552. X                    if (fields == 9)
  553. X                        dostats();
  554. X                    else
  555. X                        goto parsegoto;
  556. X                    }
  557. Xparsegoto:
  558. X                pbuf[0] = '\0';
  559. X                }
  560. X            if (len > 0)
  561. X                {
  562. X                movemem(buff, pbuf, len+1);
  563. X                pbuf[len+1] = '\0';
  564. X                }
  565. X            else
  566. X                pbuf[0] = buff[0] = '\0';
  567. X        }
  568. X        if (time(0)-last > waittime) {
  569. X            write(sock, pong, pl);
  570. X            last = time(0);
  571. X        }
  572. X        if (time(0)-lastm > 10) {
  573. X            write(sock, statsm, statsl);
  574. X            scantime = lastm = time(0);
  575. X        }
  576. X    }
  577. X}
  578. X
  579. Xs_error(fd)
  580. Xint    fd;
  581. X{
  582. X}
  583. X
  584. Xdostats()
  585. X{
  586. Xregister int i;
  587. X
  588. X    for (i = 0; i < 256; i++)
  589. X        if (!strcasecmp(msgtab[i].cnam, name))
  590. X            {
  591. X            bcopy(&msgtab[i].now, &msgtab[i].old,
  592. X                sizeof(struct stats));
  593. X            msgtab[i].now.sndq = sq;
  594. X            msgtab[i].now.sndb = sb;
  595. X            msgtab[i].now.sndm = sm;
  596. X            msgtab[i].now.rcvb = rb;
  597. X            msgtab[i].now.rcvm = rm;
  598. X            msgtab[i].update = scantime;
  599. X            return;
  600. X            }
  601. X
  602. X    for (i = 0; i < 256; i++)
  603. X        if (!*msgtab[i].cnam)
  604. X            {
  605. X            strcpy(msgtab[i].cnam, name);
  606. X            msgtab[i].now.sndq = sq;
  607. X            msgtab[i].now.sndb = sb;
  608. X            msgtab[i].now.sndm = sm;
  609. X            msgtab[i].now.rcvb = rb;
  610. X            msgtab[i].now.rcvm = rm;
  611. X                msgtab[i].update = scantime;
  612. X            break;
  613. X            }
  614. X}
  615. X
  616. Xremoveold()
  617. X{
  618. X    register    int i;
  619. X
  620. X    for (i = 0; i < 256; i++)
  621. X        if (msgtab[i].update && msgtab[i].update != scantime)
  622. X            {
  623. X            msgtab[i].now.rcvb = 0;
  624. X            msgtab[i].now.sndb = 0;
  625. X            *msgtab[i].cnam = '\0';
  626. X            }
  627. X}
  628. X
  629. Xsortm(p1, p2)
  630. Xregister MType *p1, *p2;
  631. X{
  632. X    return (p2->now.rcvb - p1->now.rcvb);
  633. X}
  634. Xshowstats()
  635. X{
  636. X    static int entries = sizeof(msgtab)/sizeof(MType);
  637. X    int i, show;
  638. X    long now = time(0);
  639. X    char    *s;
  640. X
  641. X    if ((show = entries) > LINES - 3)
  642. X        show = LINES - 3;
  643. X
  644. X    removeold();
  645. X    qsort(msgtab, sizeof(msgtab)/sizeof(MType), sizeof(MType), sortm);
  646. X    move(0,0);
  647. X    refresh();
  648. X    mvcur(LINES-1,COLS-1,0,0);
  649. X    refresh();
  650. X    printw("%s %d %s", server, port, ctime(&now));
  651. X    printw("Connection                SendQ  SendM     SendB      \
  652. X RecvM     RecvB\n");
  653. X    printw("------------------------- ------ --------- -----------\
  654. X --------- -----------\n");
  655. X    for (i = 0; i < show; i++)
  656. X        {
  657. X        if (!*msgtab[i].cnam)
  658. X            clrtoeol();
  659. X        else
  660. X            {
  661. X            printw("%-25.25s %6d %9d %11d ",
  662. X                msgtab[i].cnam,
  663. X                msgtab[i].now.sndq,
  664. X                msgtab[i].now.sndm - msgtab[i].old.sndm,
  665. X                msgtab[i].now.sndb - msgtab[i].old.sndb);
  666. X            printw("%9d %11d\n",
  667. X                msgtab[i].now.rcvm - msgtab[i].old.rcvm,
  668. X                msgtab[i].now.rcvb - msgtab[i].old.rcvb);
  669. X            }
  670. X        }
  671. X    refresh();
  672. X    mvcur(LINES-1,COLS-1,0,0);
  673. X    refresh();
  674. X}
  675. X
  676. X
  677. Xmovemem(s,t,l)
  678. Xregister char *s, *t;
  679. Xregister int l;
  680. X{
  681. X    for (; l >= 0; l--, s++, t++) *t = *s;
  682. X}
  683. X
  684. Xint    stlen(s)
  685. Xregister char *s;
  686. X{
  687. X    register int i = 0;
  688. X
  689. X    for (; *s; s++, i++)
  690. X        ;
  691. X    return i;
  692. X}
  693. END-of-stat/flowmon.c
  694. exit
  695.  
  696.