home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 2 / amigaformatcd02.iso / comms / netsoftware / nethandler.lha / NetHandler / util / netstat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-09-17  |  11.5 KB  |  464 lines

  1. #include <exec/types.h>
  2. #include <exec/memory.h>
  3. #include <intuition/intuition.h>
  4. #include <graphics/gfxmacros.h>
  5. #include <graphics/rastport.h>
  6. #include <libraries/dos.h>
  7. #include <proto/intuition.h>
  8. #include <proto/dos.h>
  9. #include <proto/exec.h>
  10. #include <proto/graphics.h>
  11. #include <string.h>
  12. #include "netstat.h"
  13.  
  14. #define MAXSTATS 300
  15. #define XOFF      10
  16. #define YOFF      40
  17. #define TIMEINTERVAL 1
  18. #define YMARGIN   12
  19. #define MINPEAK  400
  20. #define TEXT1   (6*8) 
  21. #define TEXT2   (25*8)
  22. #define XMARGIN   12
  23. #define MKBADDR(x)      ((BPTR)((long)x >> 2))
  24.  
  25. struct NewWindow NewWindowStructure1 = {
  26.    0,0,
  27.    XOFF+MAXSTATS+XMARGIN, YOFF+YMARGIN+50,
  28.    0,1,
  29.    MENUPICK+CLOSEWINDOW+REFRESHWINDOW+NEWSIZE,
  30.    WINDOWDRAG+WINDOWDEPTH+WINDOWCLOSE+WINDOWSIZING+SIMPLE_REFRESH,
  31.    NULL,
  32.    NULL,
  33.    "Software Distillery NET: Status",
  34.    NULL,
  35.    NULL,
  36.    XOFF+MAXSTATS+XMARGIN,YOFF+YMARGIN+20,
  37.    9999,9999,
  38.    WBENCHSCREEN
  39. };
  40.  
  41. int xsize = 300;
  42. int ysize = 100;
  43. int yscale = 100;
  44. long peak = 0;
  45.  
  46. void main(int, char **);
  47. void MemCleanup(void);
  48. void refresh(void);
  49. void QueueTimer(struct timerequest *, ULONG);
  50. void setscale(void);
  51. void update(void);
  52. int dispvals(void);
  53. void DeleteIOReq(struct IOStdReq *);
  54. long sendpkt(struct MsgPort *, long, long*, long);
  55. struct IOStdReq *CreateIOReq(struct MsgPort *, int);
  56.  
  57. /* Global variables */
  58.  
  59. struct Window *Window;
  60. struct TmpRas tmpras;
  61. long wstats[MAXSTATS], rstats[MAXSTATS];
  62. int statpos;
  63.  
  64.  
  65. void main(argc, argv)
  66. int argc;
  67. char **argv;
  68. {
  69.    WORD areabuffer[300];
  70.    struct IntuiMessage *message;
  71.    int run;
  72.    ULONG portmask, waitmask, windmask, timemask;
  73. /* struct MenuItem *item; */
  74.    struct MsgPort *port;
  75.    struct AreaInfo myAreaInfo;
  76.    struct statmsg *statmsg;
  77.    struct MsgPort *proc;
  78.    long args[8];
  79.    struct timerequest *timerreq;
  80.    struct MsgPort     *timerport;
  81.  
  82.    timerreq            = NULL;
  83.    timerport           = NULL;
  84.    proc                = NULL;
  85.    Window              = NULL;
  86.    port                = NULL;
  87.    args[0]             = 0;
  88.    if ((IntuitionBase = (struct IntuitionBase *)
  89.                 OpenLibrary("intuition.library", 0)) == NULL) goto done;
  90.    if ((GfxBase = (struct GfxBase *)
  91.          OpenLibrary("graphics.library", 0)) == NULL) goto done;
  92.    if ((Window = OpenWindow(&NewWindowStructure1)) == NULL) goto done;
  93.  
  94.    if ((port = CreatePort("netstat_port", 0)) == NULL) goto done;
  95.    if ((timerport = CreatePort(NULL, 0)) == NULL) goto done;
  96.    if ((timerreq  = (struct timerequest *)
  97.            CreateIOReq(timerport, sizeof(struct timerequest))) == NULL)
  98.         goto done;
  99.    if (OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)timerreq, 0))
  100.           goto done;
  101.  
  102.    InitArea(&myAreaInfo, areabuffer, 175);
  103.    Window->RPort->AreaInfo = &myAreaInfo;
  104.    Window->RPort->TmpRas = InitTmpRas(&tmpras, AllocRaster(600, 175),
  105.                            RASSIZE(600, 175));
  106.    if ((argc > 1) &&
  107.        ((proc = (struct MsgPort *)DeviceProc(argv[1])) != NULL))
  108.       {
  109.       args[0] = 0x40000002;
  110.       args[1] = MKBADDR(port);
  111.       sendpkt(proc, 2010, args, 2);
  112.       }
  113.  
  114.    memset((char *)wstats, 0, sizeof(wstats));
  115.    memset((char *)rstats, 0, sizeof(rstats));
  116.    statpos = 0;
  117.    peak = 0;
  118.    ysize = Window->Height-(YOFF+YMARGIN);
  119.    if (ysize < 20) ysize = 20;
  120.    setscale();
  121.    refresh();
  122.  
  123.    run = 0;
  124.  
  125.    windmask = 1 << Window->UserPort->mp_SigBit;
  126.    portmask = 1 << port->mp_SigBit;
  127.    timemask = (1 << timerport->mp_SigBit);
  128.    QueueTimer(timerreq, TIMEINTERVAL);
  129.    while(run == 0)
  130.       {
  131.       waitmask = Wait(windmask | portmask | timemask);
  132.       if (waitmask & timemask)
  133.          {
  134.          /* get rid of the message */
  135.          (void)GetMsg(timerport);
  136.          QueueTimer(timerreq, TIMEINTERVAL);
  137.          /* Also, we want to scroll the entire thing left one pixel */
  138.          update();
  139.  
  140.          statpos ++;
  141.          if (statpos >= MAXSTATS)
  142.             statpos = 0;
  143.          wstats[statpos] = rstats[statpos] = 0;
  144.          }
  145.       if (waitmask & portmask)
  146.          {
  147.          statmsg = (struct statmsg *)GetMsg(port);
  148.          if (statmsg->direction)
  149.             rstats[statpos] += statmsg->count;
  150.          else
  151.             wstats[statpos] += statmsg->count;
  152.          ReplyMsg((struct Message *)statmsg);
  153.          }
  154.       if (waitmask & windmask)
  155.          {
  156.          while ((message = (struct IntuiMessage *)
  157.                        GetMsg(Window->UserPort)) != NULL)
  158.             {
  159.             switch(message->Class)
  160.                {
  161.                case CLOSEWINDOW:
  162.                   run = -1;
  163.                   break;
  164. #if 0
  165.                case MENUPICK:
  166.               item = ItemAddress(&MenuList1, message->Code);
  167.                   switch(item->Command)
  168.                      {
  169.                      case 1:
  170.                          run = 1;
  171.                      default:
  172.                          run = 1;
  173.                          break;
  174.                      }
  175.                   break;
  176. #endif
  177.  
  178.                case NEWSIZE:
  179.                case REFRESHWINDOW:
  180.                   ysize = Window->Height-(YOFF+YMARGIN);
  181.                   if (ysize < 20) ysize = 20;
  182.                   setscale();
  183.                   refresh();
  184.           break;
  185.  
  186.                default:
  187.                   break;
  188.                }
  189.             ReplyMsg((struct Message *)message);
  190.             }
  191.          }
  192.       }
  193.  
  194.    Wait(timemask);
  195.  
  196.    Window->RPort->TmpRas = NULL;
  197.    FreeRaster(tmpras.RasPtr, 600, 175);
  198.  
  199. done:
  200.    if (args[0] && proc != NULL)
  201.       {
  202.       args[1] = 0;
  203.       sendpkt(proc,2010,args,2);
  204.       }
  205.  
  206.    /* Reply to any outstanding messages */
  207.    while(statmsg = (struct statmsg *)GetMsg(port)) 
  208.       ReplyMsg((struct Message *)statmsg);
  209.  
  210.    if (timerreq != NULL)
  211.       {
  212.       if (timerreq->tr_node.io_Device != NULL)
  213.          {
  214.          AbortIO( (struct IORequest *)timerreq );
  215.          CloseDevice((struct IORequest *)timerreq);
  216.          }
  217.       DeleteIOReq((struct IOStdReq *)timerreq);
  218.       }
  219.   if (timerport != NULL)     DeletePort(timerport);
  220.   if (Window != NULL) CloseWindow(Window);
  221.   if (IntuitionBase != NULL) CloseLibrary((struct Library *)IntuitionBase);
  222.   if (GfxBase != NULL)       CloseLibrary((struct Library *)GfxBase);
  223.   if (port != NULL)          DeletePort(port);
  224.   XCEXIT(0L);
  225. }
  226.  
  227. void setscale()
  228. {
  229. /* Now recalculate the scale */
  230. if (peak < MINPEAK)
  231.    yscale = MINPEAK/ysize;
  232. else
  233.    yscale = (peak*5)/(ysize*4);
  234.  
  235. }
  236. int dispvals()
  237. {
  238. char buf[80];
  239. long reads, writes, perf;
  240. struct RastPort *rp = Window->RPort;
  241. static long lr, lw, lp, lk;
  242.  
  243. reads = rstats[statpos];
  244. writes = wstats[statpos];
  245. perf = reads+writes;
  246.  
  247. /* Have we hit a new high? */
  248. if (perf > peak)
  249.    {
  250.    peak = perf;
  251.    /* Will this shoot off the end of the graph ? */
  252.    if ((peak/yscale) > ysize)
  253.       {
  254.       setscale();
  255.       return(1);
  256.       }
  257.    }
  258.  
  259. SetAPen(rp, 0);
  260. if (lp != perf || lr != reads)
  261.    RectFill(rp, XOFF+TEXT1, YOFF-28, XOFF+TEXT1+(7*8), YOFF-1);
  262. if (lk != peak || lw != writes)
  263.    RectFill(rp, XOFF+TEXT2, YOFF-28, XOFF+TEXT2+(7*8), YOFF-1);
  264.  
  265. lp = perf;
  266. lr = reads;
  267. lk = peak;
  268. lw = writes;
  269.  
  270. SetAPen(rp, 3);
  271. sprintf(buf, "%7d", perf);
  272. Move(rp, XOFF+TEXT1, YOFF-20);
  273. Text(rp, buf, 7);
  274.  
  275. sprintf(buf, "%7d", peak);
  276. Move(rp, XOFF+TEXT2, YOFF-20);
  277. Text(rp, buf, 7);
  278.  
  279. sprintf(buf, "%7d", reads);
  280. Move(rp, XOFF+TEXT1, YOFF-10);
  281. Text(rp, buf, 7);
  282.  
  283. sprintf(buf, "%7d", writes);
  284. Move(rp, XOFF+TEXT2, YOFF-10);
  285. Text(rp, buf, 7);
  286. return(0);
  287. }
  288.  
  289. void update()
  290. {
  291. short rsize, wsize;
  292. struct RastPort *rp = Window->RPort;
  293.  
  294. if (dispvals())
  295.    {
  296.    refresh();
  297.    return;
  298.    }
  299.  
  300. ScrollRaster(rp, 1, 0, XOFF, YOFF, XOFF+xsize, YOFF+ysize);
  301. /* Now update the data for the one we just finished */
  302. rsize = rstats[statpos]/yscale;
  303. wsize = wstats[statpos]/yscale;
  304. /* Now display the line at the right place for the read and then the write */
  305. Move(rp, XOFF+MAXSTATS, YOFF+ysize);
  306. if (rsize)
  307.    {
  308.    SetAPen(rp, 2);
  309.    Draw(rp, XOFF+MAXSTATS, YOFF+ysize-rsize);
  310.    }
  311. if (wsize)
  312.    {
  313.    SetAPen(rp, 3);
  314.    Draw(rp, XOFF+MAXSTATS, YOFF+ysize-rsize-wsize);
  315.    }
  316. /* And put a point where the limit is */
  317. SetAPen(rp, 1);
  318. WritePixel(rp, XOFF+MAXSTATS, YOFF+ysize-(peak/yscale));
  319. }
  320.  
  321. void refresh()
  322. {
  323. int i, j;
  324. short rsize, wsize;
  325. struct RastPort *rp = Window->RPort;
  326. char *p;
  327.  
  328. SetAPen(rp, 0);
  329. RectFill(rp, XOFF, YOFF, XOFF+MAXSTATS+1, YOFF+ysize);
  330.  
  331. p = "Total:        Bps    Peak:        Bps";
  332. SetAPen(rp, 1);
  333. Move(rp, XOFF, YOFF-20);
  334. Text(rp, p, strlen(p));
  335.  
  336. p = "Reads:        Bps  Writes:        Bps";
  337. Move(rp, XOFF, YOFF-10);
  338. Text(rp, p, strlen(p));
  339.  
  340. SetAPen(rp, 3);
  341. p = " © 1989 The Software Distillery";
  342. Move(rp, XOFF, YOFF+ysize+9);
  343. Text(rp, p, strlen(p));
  344. dispvals();
  345.  
  346. SetAPen(rp, 1);
  347. SetDrMd(rp, JAM1);
  348. Move(rp, XOFF-1, YOFF);
  349. Draw(rp, XOFF-1, YOFF+1+ysize);
  350. Draw(rp, XOFF+1+xsize, YOFF+1+ysize);
  351.  
  352. i = statpos+1;
  353. for (j = 0; j < MAXSTATS; j++)
  354.    {
  355.    if (i >= MAXSTATS) i = 0;
  356.    rsize = rstats[i]/yscale;
  357.    wsize = wstats[i]/yscale;
  358.    /* Now display the line at the right place for the read and then the write */
  359.    Move(rp, XOFF+j, YOFF+ysize);
  360.    if (rsize)
  361.       {
  362.       SetAPen(rp, 2);
  363.       Draw(rp, XOFF+j, YOFF+ysize-rsize);
  364.       }
  365.    if (wsize)
  366.       {
  367.       SetAPen(rp, 3);
  368.       Draw(rp, XOFF+j, YOFF+ysize-rsize-wsize);
  369.       }
  370.    i++;
  371.    }
  372. SetAPen(rp, 1);
  373. Move(rp, XOFF, YOFF+ysize-(peak/yscale));
  374. Draw(rp, XOFF+MAXSTATS, YOFF+ysize-(peak/yscale));
  375. }
  376.  
  377. /************************************************************************/
  378. /* Queue a timer to go off in a given number of seconds                 */
  379. /************************************************************************/
  380. void QueueTimer(tr, seconds)
  381. struct timerequest *tr;
  382. ULONG seconds;
  383. {
  384.    tr->tr_node.io_Command = TR_ADDREQUEST;   /* add a new timer request */
  385.    tr->tr_time.tv_secs =  seconds;            /* seconds */
  386.    tr->tr_time.tv_micro = 0;
  387.    SendIO( (struct IORequest *)tr );
  388. }
  389.  
  390.  
  391. struct IOStdReq *CreateIOReq(port, size)
  392. struct MsgPort *port;
  393. int size;
  394. {
  395.    register struct IOStdReq *ioReq;
  396.  
  397.    if ((ioReq = (struct IOStdReq *)
  398.                 AllocMem(size, MEMF_CLEAR | MEMF_PUBLIC)) != NULL)
  399.       {
  400.       ioReq->io_Message.mn_Node.ln_Type = NT_MESSAGE;
  401.       ioReq->io_Message.mn_Node.ln_Pri  = 0;
  402.       ioReq->io_Message.mn_Length       = size;
  403.       ioReq->io_Message.mn_ReplyPort    = port;
  404.       }
  405.    return(ioReq);
  406. }
  407.  
  408. void DeleteIOReq(ioReq)
  409. register struct IOStdReq *ioReq;
  410. {
  411.    ioReq->io_Message.mn_Node.ln_Type = 0xff;
  412.    ioReq->io_Device = (struct Device *) -1;
  413.    ioReq->io_Unit = (struct Unit *) -1;
  414.  
  415.    FreeMem( (char *)ioReq, ioReq->io_Message.mn_Length);
  416. }
  417.  
  418. LONG sendpkt(pid,action,args,nargs)
  419. struct MsgPort *pid;  /* process indentifier ... (handlers message port ) */
  420. LONG action,          /* packet type ... (what you want handler to do )   */
  421.      args[],          /* a pointer to a argument list */
  422.      nargs;           /* number of arguments in list  */
  423.    {
  424.    struct MsgPort        *replyport;
  425.    struct StandardPacket *packet;
  426.  
  427.    LONG  count, *pargs, res1;
  428.  
  429.    replyport = (struct MsgPort *) CreatePort(NULL,0);
  430.    if(!replyport) return(NULL);
  431.  
  432.    packet = (struct StandardPacket *) 
  433.       AllocMem((long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR);
  434.    if(!packet) 
  435.       {
  436.       DeletePort(replyport);
  437.       return(NULL);
  438.       }
  439.  
  440.    packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt);
  441.    packet->sp_Pkt.dp_Link         = &(packet->sp_Msg);
  442.    packet->sp_Pkt.dp_Port         = replyport;
  443.    packet->sp_Pkt.dp_Type         = action;
  444.  
  445.    /* copy the args into the packet */
  446.    pargs = &(packet->sp_Pkt.dp_Arg1);       /* address of first argument */
  447.    for(count=0;count < nargs;count++) 
  448.       pargs[count]=args[count];
  449.  
  450.    PutMsg(pid,(struct Message *)packet); /* send packet */
  451.  
  452.    WaitPort(replyport);
  453.    GetMsg(replyport); 
  454.  
  455.    res1 = packet->sp_Pkt.dp_Res1;
  456.  
  457.    FreeMem((char *)packet,(long)sizeof(struct StandardPacket));
  458.    DeletePort(replyport); 
  459.  
  460.    return(res1);
  461. }
  462.  
  463. void MemCleanup(){}
  464.