home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / UNIX / ARCHIE / CLIENTS / XARCHIE-.1 / WEIGHT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-22  |  5.2 KB  |  212 lines

  1. /*
  2.  * weight.c : Routines for ordering hosts by "weight"
  3.  *
  4.  * George Ferguson, ferguson@cs.rochester.edu, 23 Apr 1993.
  5.  * Based on a suggestion from Peter J Nilsson (pjn@ida.liu.se).
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include "sysdefs.h"
  10. #include "stringdefs.h"
  11. #include "xtypes.h"
  12. #include "appres.h"
  13. #include "weight.h"
  14. #include "hostname.h"
  15. #include "debug.h"
  16.  
  17. #define Number(arr) (sizeof(arr) / sizeof(arr[0]))
  18.  
  19. #define ISSPACE(C) ((C) == ' ' || (C) == '\t' || (C) == '\n')
  20. #define ISDIGIT(C) ((C) >= '0' && (C) <= '9')
  21.  
  22. #define UNKNOWN_WEIGHT 99
  23.  
  24. /*
  25.  * Functions defined here:
  26.  */
  27. void initHostWeights(),reinitHostWeights();
  28. int hostWeight();
  29.  
  30. static int parseHostWeights();
  31.  
  32. /*
  33.  * Data defined here:
  34.  */
  35. static HostWeightRec *hostWeightList;
  36. static int hostWeightListLen;
  37.  
  38. /*
  39.  * These weight lists are used if the hostWeights resource isn't given.
  40.  * We attempt to determine a useful one by looking at the last component
  41.  * of the hostname, if there is one.
  42.  * The formatting is ugly so we don't have extra spaces on the Settings
  43.  * panel.
  44.  */
  45. static struct _HostWeightDefault {
  46.     char *domain;
  47.     char *weights;
  48. } defaults[] = {
  49.     /* North America, from gf (also used as default) */
  50.     { "us", "1   edu com net gov mil us\n\
  51. 2   ca\n\
  52. 3   uk de nl fi fr eu.net\n\
  53. 100 au nz jp" },
  54. /* For Sweden, from Peter J Nilsson (pjn@ida.liu.se) */
  55.     { "se", "1   se\n\
  56. 2   fi dk no\n\
  57. 10  eu.net nl fr de\n\
  58. 20  edu com gov net\n\
  59. 100 au nz jp" },
  60. /* For Norway, from gf (based on se) */
  61.     { "no", "1   no\n\
  62. 2   fi dk se\n\
  63. 10  eu.net nl fr de\n\
  64. 20  edu com gov net\n\
  65. 100 au nz jp" },
  66. /* For Finland, from gf (based on se) */
  67.     { "fi", "1   si\n\
  68. 2   se dk no\n\
  69. 10  eu.net nl fr de\n\
  70. 20  edu com gov net\n\
  71. 100 au nz jp" },
  72. /* For the UK, from gf */
  73.     { "uk", "1   uk\n\
  74. 2   se fi dk no nl fr de eu.net\n\
  75. 20  edu com gov net mil us\n\
  76. 100 au nz jp" },
  77. /* For New Zealand, from Andy.Linton@comp.vuw.ac.nz */
  78.     { "nz", "1   nz\n\
  79. 10  edu com gov net mil us jp\n\
  80. 20  se fi dk no nl fr de eu.net uk au" },
  81. /* For Australia, from gf (based on nz) */
  82.     { "au", "1   au\n\
  83. 10  edu com gov net mil us jp\n\
  84. 20  se fi dk no nl fr de eu.net uk nz" },
  85. /* For Japan, from gf (a total guess) */
  86.     { "jp", "1   jp\n\
  87. 10  edu com gov net mil us\n\
  88. 20  au nz\
  89. 30  se fi dk no nl fr de eu.net uk" },
  90. };
  91.  
  92.  
  93. /*    -    -    -    -    -    -    -    -    */
  94. void
  95. initHostWeights()
  96. {
  97.     char *hostname,*dot;
  98.     int i,found;
  99.  
  100.     if (appResources.hostWeights == NULL) {
  101.     found = 0;    /* default if none matches */
  102.     hostname = GetHostname();
  103.     if ((dot=rindex(hostname,'.')) != NULL) {
  104.         dot += 1;
  105.         for (i=0; i < Number(defaults); i++) {
  106.         if (strcasecmp(dot,defaults[i].domain) == 0) {
  107.             found = i;
  108.             break;
  109.         }
  110.         }
  111.     }
  112.     appResources.hostWeights = XtNewString(defaults[found].weights);
  113.     }
  114.     reinitHostWeights();
  115. }
  116.  
  117.  
  118. /*
  119.  * This function is called whenever the weight list changes, eg, on
  120.  * the Settings panel as well as at startup.
  121.  */
  122.  
  123. void
  124. reinitHostWeights()
  125. {
  126.     /* Count how many entries there are */
  127.     hostWeightListLen = parseHostWeights(appResources.hostWeights,0);
  128.     /* Allocate the array to store them */
  129.     if (hostWeightList != NULL)
  130.     free((char*)hostWeightList);
  131.     hostWeightList = (HostWeightRec *)calloc(hostWeightListLen,
  132.                          sizeof(HostWeightRec));
  133.     /* Rescan and parse for real */
  134.     (void)parseHostWeights(appResources.hostWeights,1);
  135. }
  136.  
  137. /*
  138.  * Classes are of the form "[weight] host [host] [host] {,\n\0}"
  139.  */
  140.  
  141. /* Each class of hosts is separated by this: */
  142. #define ISCLASSSEP(C)    ((C) == ',' || (C) == '\n')
  143. /* Within classes, each host is separated by this: */
  144. #define ISHOSTSEP(C)    ISSPACE(C)
  145.  
  146. static int
  147. parseHostWeights(s,saveit)
  148. char *s;
  149. int saveit;
  150. {
  151.     char buf[256];
  152.     int i,n,weight;
  153.  
  154.     n = 0;
  155.     weight = 0;
  156.     while (*s) {
  157.     /* Skip spaces and empty classes */
  158.     while (ISSPACE(*s) || ISCLASSSEP(*s))
  159.         s += 1;
  160.     /* Get the weight, if given */
  161.     i = 0;
  162.     while (ISDIGIT(*s))
  163.         buf[i++] = *s++;
  164.     buf[i] = '\0';
  165.     if (saveit && i > 0) {
  166.         weight = atoi(buf);
  167.     }
  168.     /* Get the hosts in the class */
  169.     while (*s && !ISCLASSSEP(*s)) {
  170.         /* Skip spaces, if any */
  171.         while (ISSPACE(*s) || ISHOSTSEP(*s))
  172.         s += 1;
  173.         /* Get the host string */
  174.         i = 0;
  175.         while (*s && !ISHOSTSEP(*s) && !ISCLASSSEP(*s))
  176.         buf[i++] = *s++;
  177.         buf[i] = '\0';
  178.         /* Save this host */
  179.         if (saveit && i > 0) {
  180.         XtFree(hostWeightList[n].name);
  181.         hostWeightList[n].name = XtMalloc(strlen(buf)+1);
  182.         strcpy(hostWeightList[n].name,buf);
  183.         hostWeightList[n].weight = weight;
  184.         DEBUG2("Set weight of \"%s\" = %d\n",buf,weight);
  185.         }
  186.         /* Keep track of how many */
  187.         n += 1;
  188.     }
  189.     }
  190.     /* Return total hosts */
  191.     return(n);
  192. }
  193.  
  194. int
  195. hostWeight(host)
  196. char *host;
  197. {
  198.     int i,offs,hostlen;
  199.  
  200.     hostlen = strlen(host);
  201.     for (i=0; i < hostWeightListLen; i++) {
  202.     if ((offs=hostlen-strlen(hostWeightList[i].name)) < 0)
  203.         offs = 0;
  204.     if (!strcasecmp(host+offs,hostWeightList[i].name)) {
  205.         DEBUG3("Weight of \"%s\" (\"%s\") = %d\n",
  206.            host,host+offs,hostWeightList[i].weight);
  207.         return(hostWeightList[i].weight);
  208.     }
  209.     }
  210.     return(UNKNOWN_WEIGHT);
  211. }
  212.