home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / sqdev200.zip / samples / sstat.c < prev    next >
C/C++ Source or Header  |  1994-05-23  |  9KB  |  452 lines

  1. #pragma off(unreferenced)
  2. static char rcs_id[]="$Id: sstat.c 1.3 1993/12/05 06:06:29 sjd Exp $";
  3. #pragma on(unreferenced)
  4.  
  5. /*#define DEBUG*/
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include <io.h>
  11. #include <fcntl.h>
  12. #include "prog.h"
  13. #include "sstat.h"
  14. #include "sstatp.h"
  15.  
  16. static struct _ahlist *ahlist=NULL;
  17. static struct _nodtot *nodtot=NULL;
  18. static struct _sscfg sc;
  19.  
  20. void _fast NoMem(void);
  21.  
  22.  
  23. static int near MatchNN(NETADDR *n1, NETADDR *n2)
  24. {
  25.   return (n1->zone==n2->zone &&
  26.           n1->net ==n2->net  &&
  27.           n1->node==n2->node &&
  28.           n1->point==n2->point);
  29. }
  30.  
  31.  
  32.  
  33. static int near DoThisArea(char *tag)
  34. {
  35.   struct _arealist *al;
  36.  
  37.   if (sc.do_all)
  38.     return TRUE;
  39.   
  40.   for (al=sc.area; al; al=al->next)
  41.     if (eqstri(tag, al->tag))
  42.       return TRUE;
  43.     
  44.   return FALSE;
  45. }
  46.  
  47. static int near DoThisNode(NETADDR *n)
  48. {
  49.   struct _nodelist *nl;
  50.   
  51.   for (nl=sc.node; nl; nl=nl->next)
  52.     if (MatchNN(&nl->n, n))
  53.       return TRUE;
  54.     
  55.   return FALSE;
  56. }
  57.  
  58.  
  59.  
  60. /* Read all of the specified nodes in from the SQUISH.STA stats file */
  61.  
  62. static void near ReadArea(int fd, struct _ahlist *al, struct _tarea *ta)
  63. {
  64.   struct _tnode tn;
  65.   struct _stlist *sl;
  66.   struct _nodtot *nt;
  67.  
  68.  
  69.   al->in_msgs += ta->in_msgs;
  70.   al->in_bytes += ta->in_bytes/100;
  71.  
  72.   while (ta->n_nodes--)
  73.   {
  74.     if (read(fd, (char *)&tn, sizeof tn) != sizeof tn)
  75.       return;
  76.     
  77.     #ifdef DEBUG
  78.     printf("    Node         = %s\n", Address(&tn.node));
  79.     printf("        OutMsgs  = %ld\n", tn.out_msgs);
  80.     printf("        OutBytes = %ld\n", tn.out_bytes);
  81.     #endif
  82.  
  83.     /* Only process the specified nodes */
  84.       
  85.     if (! DoThisNode(&tn.node))
  86.       continue;
  87.     
  88.     for (sl=al->slist; sl; sl=sl->next)
  89.       if (MatchNN(&sl->node, &tn.node))
  90.         break;
  91.       
  92.     if (sl==NULL)
  93.     {
  94.       sl=smalloc(sizeof(struct _stlist));
  95.       
  96.       sl->next=al->slist;
  97.       al->slist=sl;
  98.     }
  99.  
  100.     /* Make sure that this node is already in the llist of node totals */
  101.  
  102.     for (nt=nodtot; nt; nt=nt->next)
  103.       if (MatchNN(&nt->node, &tn.node))
  104.         break;
  105.  
  106.     /* Not there, so add it */
  107.  
  108.     if (nt==NULL)
  109.     {
  110.       nt=smalloc(sizeof(struct _nodtot));
  111.  
  112.       nt->node=tn.node;
  113.  
  114.       nt->next=nodtot;
  115.       nodtot=nt;
  116.     }
  117.     
  118.     sl->node=tn.node;
  119.     sl->out_msgs += tn.out_msgs;
  120.     sl->out_bytes += tn.out_bytes/100;
  121.   }
  122. }
  123.  
  124.  
  125.  
  126.  
  127.  
  128. static void near ParseStats(int fd)
  129. {
  130.   struct _thdr th;
  131.   struct _tarea tarea;
  132.   struct _ahlist *al;
  133.  
  134.   while (read(fd, (char *)&th, sizeof th)==sizeof th)
  135.   {
  136.     if (th.type != TYPE_AREA)
  137.     {
  138.       lseek(fd, th.len, SEEK_CUR);
  139.       continue;
  140.     }
  141.  
  142.     /* Read frame from file and then copy to the tarea structure */
  143.  
  144.     if (read(fd, (char *)&tarea, sizeof tarea) != sizeof tarea)
  145.       break;
  146.  
  147.     #ifdef DEBUG
  148.     printf("Area: %s\n", tarea.tag);
  149.     printf(" InMsgs: %lu\n", tarea.in_msgs);
  150.     printf("InBytes: %lu\n", tarea.in_bytes);
  151.     #endif
  152.  
  153.     for (al=ahlist; al; al=al->next)
  154.       if (eqstri(tarea.tag, al->tag))
  155.         break;
  156.  
  157.     /* This area not found */
  158.  
  159.     if (al==NULL)
  160.     {
  161.       al=smalloc(sizeof(struct _ahlist));
  162.  
  163.       strcpy(al->tag, tarea.tag);
  164.  
  165.       al->next=ahlist;
  166.       ahlist=al;
  167.     }
  168.  
  169.     ReadArea(fd, al, &tarea);
  170.   }
  171. }
  172.  
  173.  
  174.  
  175.  
  176.  
  177. static int near Percent1(dword a, dword b)
  178. {
  179.   return (int)(a*100L/b);
  180. }
  181.  
  182.  
  183.  
  184.  
  185. static int near Percent2(dword a, dword b)
  186. {
  187.   return (int)((a*10000L/b) % 100L);
  188. }
  189.  
  190. #define Percent(a, b) Percent1(a,b), Percent2(a,b)
  191.  
  192.  
  193.  
  194.  
  195. static void near CalcTotals(dword *total_in_bytes, dword *total_in_msgs)
  196. {
  197.   struct _ahlist *al;
  198.   struct _stlist *sl;
  199.  
  200.   *total_in_bytes=*total_in_msgs=0;
  201.  
  202.   for (al=ahlist; al; al=al->next)
  203.   {
  204.     if (! DoThisArea(al->tag))
  205.       continue;
  206.     
  207.     al->total_out_bytes=al->total_out_msgs=0;
  208.  
  209.     for (sl=al->slist; sl; sl=sl->next)
  210.     {
  211.       al->total_out_bytes += sl->out_bytes;
  212.       al->total_out_msgs  += sl->out_msgs;
  213.     }
  214.  
  215.     if (al->total_out_bytes==0 && al->total_out_msgs==0)
  216.       continue;
  217.  
  218.     *total_in_bytes += al->in_bytes;
  219.     *total_in_msgs  += al->in_msgs;
  220.   }
  221. }
  222.  
  223.  
  224.  
  225.  
  226. static void near CalculateStats(dword total_in_bytes, dword total_in_msgs)
  227. {
  228.   struct _ahlist *al;
  229.   struct _stlist *sl;
  230.   struct _nodtot *nt;
  231.  
  232.   for (al=ahlist; al; al=al->next)
  233.   {
  234.     if (! DoThisArea(al->tag))
  235.       continue;
  236.  
  237.     printf("\nArea %s\n", al->tag);
  238.  
  239.     printf("  BYTES IN : %8ld (%02d.%02d%% of total bytes in)\n",
  240.            al->in_bytes*100L,
  241.            (int)(al->in_bytes*100/total_in_bytes),
  242.            (int)((al->in_bytes*10000/total_in_bytes) % 100));
  243.  
  244.     printf("  BYTES OUT: %8ld\n",
  245.            al->total_out_bytes*100L);
  246.  
  247.     printf("   MSGS IN : %8ld (%02d.%02d%% of total msgs in)\n",
  248.            al->in_msgs,
  249.            (int)(al->in_msgs*100/total_in_msgs),
  250.            (int)((al->in_msgs*10000/total_in_msgs) % 100));
  251.  
  252.     printf("   MSGS OUT: %8ld\n\n",
  253.            al->total_out_msgs);
  254.  
  255.     /* Don't log areas with no output */
  256.  
  257.     if (total_in_bytes==0 || total_in_msgs==0 ||
  258.         al->total_out_bytes==0 || al->total_out_msgs==0)
  259.     {
  260.       printf("   (No outbound traffic for specified nodes.)\n");
  261.       continue;
  262.     }
  263.  
  264.     printf("   Node            Byte Out MsgOut %% Bytes %%  Msgs %% TBCst %% TMCst\n");
  265.     printf("   --------------- -------- ------ ------- ------- ------- -------\n");
  266.  
  267.     for (sl=al->slist; sl; sl=sl->next)
  268.     {
  269.       double area_percent_bytes, area_percent_msgs;
  270.  
  271.       area_percent_bytes=((double)sl->out_bytes/(double)al->total_out_bytes)*
  272.                          ((double)al->in_bytes /(double)total_in_bytes)*
  273.                           (double)100;
  274.  
  275.       area_percent_msgs =((double)sl->out_msgs/(double)al->total_out_msgs)*
  276.                          ((double)al->in_msgs /(double)total_in_msgs)*
  277.                           (double)100;
  278.  
  279.       printf("   %-15s %8ld %6ld %3d.%02d%% %3d.%02d%% %6.02f%% %6.02f%%\n",
  280.              Address(&sl->node),
  281.              sl->out_bytes*100L,
  282.              sl->out_msgs,
  283.              Percent(sl->out_bytes, al->total_out_bytes),
  284.              Percent(sl->out_msgs,  al->total_out_msgs),
  285.              area_percent_bytes,
  286.              area_percent_msgs);
  287.  
  288.       for (nt=nodtot; nt; nt=nt->next)
  289.         if (MatchNN(&nt->node, &sl->node))
  290.         {
  291.           nt->total_percent_bytes += area_percent_bytes;
  292.           nt->total_percent_msgs  += area_percent_msgs;
  293.           break;
  294.         }
  295.     }
  296.   }
  297.  
  298.   printf("\nNODE TOTALS:\n\n");
  299.  
  300.   printf("   Node             %%Bytes %% Msgs\n");
  301.   printf("   ---------------- ------ ------\n");
  302.  
  303.   for (nt=nodtot; nt; nt=nt->next)
  304.   {
  305.     printf("   %-15s  %05.02f%% %05.02f%%\n",
  306.            Address(&nt->node),
  307.            nt->total_percent_bytes,
  308.            nt->total_percent_msgs);
  309.   }
  310.  
  311. }
  312.  
  313.  
  314.  
  315.  
  316.  
  317. static void near ParseConfigLine(char *line)
  318. {
  319.   static char *cfgdelim=" \t\n\r,";
  320.   char *s;
  321.  
  322.   /* Strip off any comments */
  323.   
  324.   if ((s=strchr(line, ';')) != NULL)
  325.     *s='\0';
  326.  
  327.  
  328.   /* Grab a word from the config */
  329.   
  330.   s=strtok(line, cfgdelim);
  331.   
  332.   /* Nodes to track */
  333.   
  334.   if (s==NULL)
  335.     return;
  336.  
  337.   if (eqstri(s, "track"))
  338.   {
  339.     struct _nodelist *node;
  340.     NETADDR last;
  341.   
  342.     memset(&last, '\0', sizeof(NETADDR));
  343.  
  344.  
  345.     /* Parse all net/node numbers off this line */
  346.     
  347.     while ((s=strtok(NULL, cfgdelim)) != NULL)
  348.     {
  349.       node=smalloc(sizeof(struct _nodelist));
  350.  
  351.       node->n=last;
  352.       
  353.       ParseNN(s, &node->n.zone, &node->n.net,
  354.               &node->n.node, &node->n.point, FALSE);
  355.       
  356.       last=node->n;
  357.  
  358.       /* Append to linked list */
  359.       
  360.       node->next=sc.node;
  361.       sc.node=node;
  362.     }
  363.   }
  364.   else if (eqstri(s, "area"))
  365.   {
  366.     struct _arealist *area;
  367.     
  368.     while ((s=strtok(NULL, cfgdelim)) != NULL)
  369.     {
  370.       if (eqstri(s, "all"))
  371.         sc.do_all=TRUE;
  372.       else
  373.       {
  374.         area=smalloc(sizeof(struct _arealist));
  375.       
  376.         area->tag=sstrdup(s);
  377.       
  378.         area->next=sc.area;
  379.         sc.area=area;
  380.       }
  381.     }
  382.   }
  383.   else
  384.   {
  385.     printf("Invalid keyword in config file: `%s'\n", s);
  386.   }
  387. }
  388.  
  389.  
  390.  
  391.  
  392.  
  393. static void near ParseConfig(char *cfg)
  394. {
  395.   FILE *fp;
  396.   char line[PATHLEN];
  397.   
  398.   sc.node=NULL;
  399.   sc.area=NULL;
  400.   sc.do_all=FALSE;
  401.   
  402.   if (cfg==NULL)
  403.     cfg="SSTAT.CFG";
  404.   
  405.   if ((fp=shfopen(cfg, "r", O_RDONLY))==NULL)
  406.   {
  407.     printf("Error opening `%s'!\n", cfg);
  408.     exit(1);
  409.   }
  410.   
  411.   while (fgets(line, PATHLEN, fp))
  412.     ParseConfigLine(line);
  413.   
  414.   fclose(fp);
  415. }
  416.  
  417.  
  418.  
  419.  
  420.  
  421. int _stdc main(int argc, char *argv[])
  422. {
  423.   dword total_in_bytes, total_in_msgs;
  424.   int fd;
  425.  
  426.   NW(argc);
  427.   NW(argv);
  428.   
  429.   ParseConfig(argv[1]);
  430.  
  431.   if ((fd=open("SQUISH.STT", O_RDONLY | O_BINARY))==-1)
  432.   {
  433.     printf("Error!  No statistics file to read!\n");
  434.     return 1;
  435.   }
  436.  
  437.   ParseStats(fd);
  438.   close(fd);
  439.  
  440.   CalcTotals(&total_in_bytes, &total_in_msgs);
  441.   CalculateStats(total_in_bytes, total_in_msgs);
  442.  
  443.   return 0;
  444. }
  445.  
  446. void _fast NoMem(void)
  447. {
  448.   printf("Ran out of memory!\n");
  449.   exit(1);
  450. }
  451.  
  452.