home *** CD-ROM | disk | FTP | other *** search
- /*
- * weight.c : Routines for ordering hosts by "weight"
- *
- * George Ferguson, ferguson@cs.rochester.edu, 23 Apr 1993.
- * Based on a suggestion from Peter J Nilsson (pjn@ida.liu.se).
- */
-
- #include <stdio.h>
- #include "sysdefs.h"
- #include "stringdefs.h"
- #include "xtypes.h"
- #include "appres.h"
- #include "weight.h"
- #include "hostname.h"
- #include "debug.h"
-
- #define Number(arr) (sizeof(arr) / sizeof(arr[0]))
-
- #define ISSPACE(C) ((C) == ' ' || (C) == '\t' || (C) == '\n')
- #define ISDIGIT(C) ((C) >= '0' && (C) <= '9')
-
- #define UNKNOWN_WEIGHT 99
-
- /*
- * Functions defined here:
- */
- void initHostWeights(),reinitHostWeights();
- int hostWeight();
-
- static int parseHostWeights();
-
- /*
- * Data defined here:
- */
- static HostWeightRec *hostWeightList;
- static int hostWeightListLen;
-
- /*
- * These weight lists are used if the hostWeights resource isn't given.
- * We attempt to determine a useful one by looking at the last component
- * of the hostname, if there is one.
- * The formatting is ugly so we don't have extra spaces on the Settings
- * panel.
- */
- static struct _HostWeightDefault {
- char *domain;
- char *weights;
- } defaults[] = {
- /* North America, from gf (also used as default) */
- { "us", "1 edu com net gov mil us\n\
- 2 ca\n\
- 3 uk de nl fi fr eu.net\n\
- 100 au nz jp" },
- /* For Sweden, from Peter J Nilsson (pjn@ida.liu.se) */
- { "se", "1 se\n\
- 2 fi dk no\n\
- 10 eu.net nl fr de\n\
- 20 edu com gov net\n\
- 100 au nz jp" },
- /* For Norway, from gf (based on se) */
- { "no", "1 no\n\
- 2 fi dk se\n\
- 10 eu.net nl fr de\n\
- 20 edu com gov net\n\
- 100 au nz jp" },
- /* For Finland, from gf (based on se) */
- { "fi", "1 si\n\
- 2 se dk no\n\
- 10 eu.net nl fr de\n\
- 20 edu com gov net\n\
- 100 au nz jp" },
- /* For the UK, from gf */
- { "uk", "1 uk\n\
- 2 se fi dk no nl fr de eu.net\n\
- 20 edu com gov net mil us\n\
- 100 au nz jp" },
- /* For New Zealand, from Andy.Linton@comp.vuw.ac.nz */
- { "nz", "1 nz\n\
- 10 edu com gov net mil us jp\n\
- 20 se fi dk no nl fr de eu.net uk au" },
- /* For Australia, from gf (based on nz) */
- { "au", "1 au\n\
- 10 edu com gov net mil us jp\n\
- 20 se fi dk no nl fr de eu.net uk nz" },
- /* For Japan, from gf (a total guess) */
- { "jp", "1 jp\n\
- 10 edu com gov net mil us\n\
- 20 au nz\
- 30 se fi dk no nl fr de eu.net uk" },
- };
-
-
- /* - - - - - - - - */
- void
- initHostWeights()
- {
- char *hostname,*dot;
- int i,found;
-
- if (appResources.hostWeights == NULL) {
- found = 0; /* default if none matches */
- hostname = GetHostname();
- if ((dot=rindex(hostname,'.')) != NULL) {
- dot += 1;
- for (i=0; i < Number(defaults); i++) {
- if (strcasecmp(dot,defaults[i].domain) == 0) {
- found = i;
- break;
- }
- }
- }
- appResources.hostWeights = XtNewString(defaults[found].weights);
- }
- reinitHostWeights();
- }
-
-
- /*
- * This function is called whenever the weight list changes, eg, on
- * the Settings panel as well as at startup.
- */
-
- void
- reinitHostWeights()
- {
- /* Count how many entries there are */
- hostWeightListLen = parseHostWeights(appResources.hostWeights,0);
- /* Allocate the array to store them */
- if (hostWeightList != NULL)
- free((char*)hostWeightList);
- hostWeightList = (HostWeightRec *)calloc(hostWeightListLen,
- sizeof(HostWeightRec));
- /* Rescan and parse for real */
- (void)parseHostWeights(appResources.hostWeights,1);
- }
-
- /*
- * Classes are of the form "[weight] host [host] [host] {,\n\0}"
- */
-
- /* Each class of hosts is separated by this: */
- #define ISCLASSSEP(C) ((C) == ',' || (C) == '\n')
- /* Within classes, each host is separated by this: */
- #define ISHOSTSEP(C) ISSPACE(C)
-
- static int
- parseHostWeights(s,saveit)
- char *s;
- int saveit;
- {
- char buf[256];
- int i,n,weight;
-
- n = 0;
- weight = 0;
- while (*s) {
- /* Skip spaces and empty classes */
- while (ISSPACE(*s) || ISCLASSSEP(*s))
- s += 1;
- /* Get the weight, if given */
- i = 0;
- while (ISDIGIT(*s))
- buf[i++] = *s++;
- buf[i] = '\0';
- if (saveit && i > 0) {
- weight = atoi(buf);
- }
- /* Get the hosts in the class */
- while (*s && !ISCLASSSEP(*s)) {
- /* Skip spaces, if any */
- while (ISSPACE(*s) || ISHOSTSEP(*s))
- s += 1;
- /* Get the host string */
- i = 0;
- while (*s && !ISHOSTSEP(*s) && !ISCLASSSEP(*s))
- buf[i++] = *s++;
- buf[i] = '\0';
- /* Save this host */
- if (saveit && i > 0) {
- XtFree(hostWeightList[n].name);
- hostWeightList[n].name = XtMalloc(strlen(buf)+1);
- strcpy(hostWeightList[n].name,buf);
- hostWeightList[n].weight = weight;
- DEBUG2("Set weight of \"%s\" = %d\n",buf,weight);
- }
- /* Keep track of how many */
- n += 1;
- }
- }
- /* Return total hosts */
- return(n);
- }
-
- int
- hostWeight(host)
- char *host;
- {
- int i,offs,hostlen;
-
- hostlen = strlen(host);
- for (i=0; i < hostWeightListLen; i++) {
- if ((offs=hostlen-strlen(hostWeightList[i].name)) < 0)
- offs = 0;
- if (!strcasecmp(host+offs,hostWeightList[i].name)) {
- DEBUG3("Weight of \"%s\" (\"%s\") = %d\n",
- host,host+offs,hostWeightList[i].weight);
- return(hostWeightList[i].weight);
- }
- }
- return(UNKNOWN_WEIGHT);
- }
-