home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / com / bbs / squish / sstat.c < prev    next >
C/C++ Source or Header  |  1992-02-28  |  9KB  |  448 lines

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