All pastes #277247 Raw Edit

Miscellany

public text v1 · immutable
·published 2006-12-13 01:08 UTC
rendered paste body
static void SaveMetasCache()
{
  FILE *cache;
  char cacheFileName[PATH_MAX];
  char tmpFileName[PATH_MAX];
  char str[LINE];
  int i, len;

  /* overwrite existing file if possible */
  if (metaUDPCache && !findfile(metaUDPCache, cacheFileName))
      strcpy(cacheFileName, metaUDPCache);

  if (metaUDPCache)
  {
      len = strlen(cacheFileName);
      strcpy(tmpFileName, cacheFileName);

      /* create a temporary file with roughly the same name */
      if ((cacheFileName[len - 1] == 'T') || (cacheFileName[len - 1] == 't'))
        tmpFileName[len-1] = 'R';
      else
        tmpFileName[len-1] = 'T';
      
      cache = fopen(tmpFileName, "w");

      if (cache == NULL)
      {
      	  LineToConsole ("Cannot create a metaUDPCache temporary file `%s'\n",
                          tmpFileName);
          LineToConsole("Meta-server read will not be cached.\n");
      }
  }
  else
  {
      cache = NULL;
  }

  if (cache != NULL)
  {
      /* Save status level and number of servers on first line - these variables
         determine whether to use the cache during LoadMetasCache() */
      sprintf (str, "%d,%d\n", statusLevel, num_servers);
      fputs (str, cache);
      
      /* Save important data in a similar, but not identical, manner to how the
         metaserver sends the UDP metadata.  The internal status types are not saved,
         instead they default to "Active". */
      for (i = 0; i < num_servers; i++)
      {
          sprintf(str,"%s,%d,%lld,%d,%d,%d,%d,%c\n",
          serverlist[i].address,
          serverlist[i].port,
          serverlist[i].when,
          serverlist[i].age,
          serverlist[i].lifetime,
          serverlist[i].players,
          ((serverlist[i].status <= statusNull) ? serverlist[i].status : statusNull),
          serverlist[i].typeflag);
          fputs (str, cache);
      }
      fclose(cache);

      /* Can't rename file to existing name under NT */
#ifdef _MSC_VER
      _unlink(metaUDPCache);
#else
      unlink(metaUDPCache);
#endif
  
      if (rename(tmpFileName, metaUDPCache) == -1)
	perror("Could not rename new cache file");
  }

}

static void LoadMetasCache()
{
  FILE *cache;
  char *buffer;
  char *p;
  char cacheFileName[PATH_MAX];
  long lSize;
  int  i, j;
  int invalid[MAX_SERVERS] = {0};


  if(!metaUDPCache)
  {
      num_servers = 0;
      return;
  }

  cache = fopen(cacheFileName, "r");
  if (cache == NULL) 
  { 
      num_servers = 0; 
      return; 
  }
  /* Obtain file size. */
  fseek (cache , 0 , SEEK_END);
  lSize = ftell (cache);
  rewind (cache);

  /* Allocate memory to contain the whole file. */
  buffer = (char*) malloc (lSize);
  if (buffer == NULL)
  {
      num_servers = 0;
      fclose(cache);
      return;
  }

  /* Copy the file into the buffer. */
  fread (buffer,1,lSize,cache);

  /* Read in statusLevel */
  p = strtok(buffer,",");
  if (p == NULL)
  {
      num_servers = 0;
      fclose(cache);
      return;
  }
  i = atoi(p);

  /* Ignore the cache if user changed statusLevel */
  if (i != statusLevel)
  {
      num_servers = 0;
      fclose(cache);
      return; 
  }
  
  /* Read in number of servers */
  p = strtok(NULL,"\n");
  if (p == NULL)
  {
      num_servers = 0;
      fclose(cache);
      return;
  }
  num_servers = atoi(p);

  /* Allocate memory for server list */
  serverlist = (struct servers *) malloc(sizeof(struct servers)*num_servers);

  /* Load servers into server list */
  for(i = 0; i < num_servers; i++)
  {
    p = strtok(NULL,",");		/* hostname */
    if (p == NULL) {
    	invalid[i] = 1;
    	continue;
    }
    strcpy(serverlist[i].address, p);

    p = strtok(NULL,",");		/* port */
    if (p == NULL) {
    	invalid[i] = 1;
    	continue;
    }
    serverlist[i].port = atoi(p);

    p = strtok(NULL,",");		/* when */
    if (p == NULL) {
    	invalid[i] = 1;
    	continue;
    }
    serverlist[i].when = atoi(p);

    p = strtok(NULL,",");		/* age */
    if (p == NULL) {
    	invalid[i] = 1;
    	continue;
    }
    serverlist[i].age = atoi(p);

    p = strtok(NULL,",");		/* lifetime */
    if (p == NULL) {
    	invalid[i] = 1;
    	continue;
    }
    serverlist[i].lifetime = atoi(p);

    p = strtok(NULL,",");		/* players */
    if (p == NULL) {
    	invalid[i] = 1;
    	continue;
    }
    serverlist[i].players = atoi(p);

    p = strtok(NULL,",");		/* status */
    if (p == NULL) {
    	invalid[i] = 1;
    	continue;
    }
    serverlist[i].status = atoi(p);

    p = strtok(NULL,"\n");		/* type */
    if (p == NULL) {
    	invalid[i] = 1;
    	continue;
    }
    serverlist[i].typeflag = p[0];

    strcpy(serverlist[i].comment, "");
 
    /* mark each server as needing to be refreshed */
    serverlist[i].refresh = 1;

#ifdef METAPING
    /* Initialize the ping rtt fields */
    for (j = 0; j < RTT_AVG_BUFLEN; ++j )
        serverlist[i].pkt_rtt[j] = (unsigned long) -1;
#endif
  }

  fclose(cache);

  /* hunt and kill old server lines from cache */
  for(i=0;i<num_servers;i++)
  {
      /* skip the deletion below if the entry was received recently,
         and all the data was valid */
      if (serverlist[i].lifetime-- > 0 && !invalid[i]) continue;

      /* delete this entry by moving the ones above down */
      for(j=i;j<num_servers-1;j++)
      {
	  memcpy(&serverlist[j],&serverlist[j+1],sizeof(struct servers));
      }
      
      /* adjust the current entry pointer, limit, and resize the memory */
      i--;
      num_servers--;
      serverlist = 
	(struct servers *) realloc(serverlist, 
				   sizeof(struct servers) * ( num_servers ));
  }
}