AREXPORT void ArServerHandlerConfig::getConfigSectionFlags(
	ArServerClient *client, ArNetPacket *packet)
{
  ArLog::log(ArLog::Normal, "Config section flags requested.");

  ArNetPacket sending;

  std::list<ArConfigSection *> *sections = myConfig->getSections();
  std::list<ArConfigSection *>::iterator sIt;
  sending.byte4ToBuf(sections->size());

  for (sIt = sections->begin(); sIt != sections->end(); sIt++)
  {

    ArConfigSection *section = (*sIt);
    if (section == NULL) 
    {
      sending.strToBuf("");
      sending.strToBuf("");
    }
    else
    {
      sending.strToBuf(section->getName());
      sending.strToBuf(section->getFlags());
    }
  }
  client->sendPacketTcp(&sending);
}
AREXPORT void ArClientHandlerConfig::saveConfigToServer(
	  ArConfig *config, 
	  const std::set<std::string, ArStrCaseCmpOp> *ignoreTheseSections)
{
  //ArConfigArg param;
  ArClientArg clientArg;

  ArNetPacket sending;
  ArLog::log(ArLog::Normal, "%sSaving config to server", myLogPrefix.c_str());

  myDataMutex.lock();
  std::list<ArConfigSection *> *sections = config->getSections();
  for (std::list<ArConfigSection *>::iterator sIt = sections->begin(); 
       sIt != sections->end(); 
       sIt++)
  {
    ArConfigSection *section = (*sIt);
    // if we're ignoring sections and we're ignoring this one, then
    // don't send it
    if (ignoreTheseSections != NULL && 
	(ignoreTheseSections->find(section->getName()) != 
	 ignoreTheseSections->end()))
    {
      ArLog::log(ArLog::Verbose, "Not sending section %s", 
		 section->getName());
      continue;
    }
    sending.strToBuf("Section");
    sending.strToBuf(section->getName());
    std::list<ArConfigArg> *params = section->getParams();

    for (std::list<ArConfigArg>::iterator pIt = params->begin(); 
         pIt != params->end(); 
         pIt++)
    {
      ArConfigArg &param = (*pIt);

      if (!clientArg.isSendableParamType(param)) {
        continue;
      }

      sending.strToBuf(param.getName());

      clientArg.argTextToBuf(param, &sending);

    } // end for each param
  } // end for each section

  myDataMutex.unlock();
  myClient->requestOnce("setConfig", &sending);
}
AREXPORT void ArServerHandlerConfig::getConfigDefaults(ArServerClient *client, 
                                                       ArNetPacket *packet)
{
  char sectionRequested[512];
  sectionRequested[0] = '\0';
  ArNetPacket sending;

  if (myDefault == NULL)
  {
    ArLog::log(ArLog::Normal, "ArServerHandlerConfig::getConfigDefaults: No default config to get");
    client->sendPacketTcp(&sending);
    return;
  }
  myConfigMutex.lock();
  // if we have a section name pick it up, otherwise we send everything
  if (packet->getDataReadLength() < packet->getDataLength())
    packet->bufToStr(sectionRequested, sizeof(sectionRequested));

  //ArConfigArg param;

  ArClientArg clientArg;

  if (sectionRequested[0] == '\0')
    ArLog::log(ArLog::Normal, "Sending all defaults to client");
  else
    ArLog::log(ArLog::Normal, "Sending defaults for section '%s' to client",
               sectionRequested);


  std::list<ArConfigSection *> *sections = myDefault->getSections();

  for (std::list<ArConfigSection *>::iterator sIt = sections->begin(); 
       sIt != sections->end(); 
       sIt++)
  {
    ArConfigSection *section = (*sIt);

    if (section == NULL) {
      continue; // Should never happen...
    }

    // if we're not sending them all and not in the right section just cont
    if (sectionRequested[0] != '\0' &&
        ArUtil::strcasecmp(sectionRequested, section->getName()) != 0) {
      continue;
    }

    sending.strToBuf("Section");
    sending.strToBuf(section->getName());

    std::list<ArConfigArg> *params = section->getParams();

    for (std::list<ArConfigArg>::iterator pIt = params->begin(); 
         pIt != params->end(); 
         pIt++)
    {
      ArConfigArg &param = (*pIt);

      if (!clientArg.isSendableParamType(param)) {
        continue;
      }

      sending.strToBuf(param.getName());
      clientArg.argTextToBuf(param, &sending);

    } // end for each param
  } // end for each section
  myConfigMutex.unlock();

  client->sendPacketTcp(&sending);
}
/**
 * @param client the ArServerClient * to which to send the config
 * @param packet the ArNetPacket * which accompanied the client's request
 * @param isMultiplePackets a bool set to true if the server should send a
 * packet for each config section followed by the empty packet; false if 
 * the server should send the entire config in one packet (i.e. the old style)
 * @param lastPriority the last ArPriority::Priority that should be sent 
 * to the client (this is the greatest numerical value and the least 
 * semantic priority).
**/
AREXPORT void ArServerHandlerConfig::handleGetConfig(ArServerClient *client, 
                                                     ArNetPacket *packet,
                                                     bool isMultiplePackets,
                                                     ArPriority::Priority lastPriority)
{

  ArConfigArg param;

 
  // The multiple packets method also sends display hints with the parameters;
  // the old single packet method does not.
  ArClientArg clientArg(isMultiplePackets,
                        lastPriority);

  std::set<std::string> sent;

  ArNetPacket sending;
  ArLog::log(ArLog::Normal, "Config requested.");

  std::list<ArConfigSection *> *sections = myConfig->getSections();
  for (std::list<ArConfigSection *>::iterator sIt = sections->begin(); 
       sIt != sections->end(); 
       sIt++)
  {
    // Clear the packet...
    if (isMultiplePackets) {
      sending.empty();
    }

    // clear out the sent list between sections
    sent.clear();

    ArConfigSection *section = (*sIt);
    if (section == NULL) {
      continue;
    }

    sending.byteToBuf('S');
    sending.strToBuf(section->getName());
    sending.strToBuf(section->getComment());

    ArLog::log(ArLog::Verbose, "Sending config section %s...", section->getName());

    //printf("S %s %s\n", section->getName(), section->getComment());
    std::list<ArConfigArg> *params = section->getParams();
    for (std::list<ArConfigArg>::iterator pIt = params->begin(); 
         pIt != params->end(); 
         pIt++)
    {
      param = (*pIt);

      bool isCheckableName = 
      (param.getType() != ArConfigArg::DESCRIPTION_HOLDER && 
       param.getType() != ArConfigArg::SEPARATOR &&
       param.getType() != ArConfigArg::STRING_HOLDER);

      // if we've already sent it don't send it again
      if (isCheckableName &&
          sent.find(param.getName()) != sent.end()) {
        continue;
      }
      else if (isCheckableName) {
        sent.insert(param.getName());
      }

      if (clientArg.isSendableParamType(param))
      {
        sending.byteToBuf('P');

        bool isSuccess = clientArg.createPacket(param,
                                                &sending);

      }
    } // end for each parameter

    if (!sending.isValid()) {

      ArLog::log(ArLog::Terse, "Config section %s cannot be sent; packet size exceeded",
                 section->getName());

    } // end if length exceeded...
    else if (isMultiplePackets) {

      client->sendPacketTcp(&sending);

    } // end else send in chunks...

  } // end for each section

  // If sending each section in individual packets, then send an empty packet 
  // to indicate the end of the config data.
  if (isMultiplePackets) {

    sending.empty();
    client->sendPacketTcp(&sending);
  }
  else { //  send the entire config in one packet

    // If the config is too big to fit in the packet, then just send an empty
    // packet (to try to prevent an older client from crashing)
    // TODO: Is there any better way to notify the user of an error....
    if (!sending.isValid()) {
      ArLog::log(ArLog::Terse, "Error sending config; packet size exceeded");
      sending.empty();
    }

    client->sendPacketTcp(&sending);

  } // end else send the entire packet

} // end method getConfigBySections
/** 
    @internal

    doesn't delete the old one, do that if you're going to call this
    yourself and make sure you lock around all that (okay, it deletes
    it now, but the stuff that calls it should still take care of it)
**/
void ArServerHandlerConfig::createDefaultConfig(const char *defaultFileBaseDir)
{
  if (myDefault != NULL)
  {
    delete myDefault;
    myDefault = NULL;
  }
  // copy that config (basedir will be NULL if we're not loading from
  // a file)... don't have the default save unknown values
  myDefault = new ArConfig(defaultFileBaseDir, false, false, false, false);

  std::list<ArConfigSection *>::iterator sectionIt;
  std::list<ArConfigArg>::iterator paramIt;
  ArConfigSection *section = NULL;
  std::list<ArConfigArg> *params = NULL;
  ArConfigArg param;
  for (sectionIt = myConfig->getSections()->begin(); 
       sectionIt != myConfig->getSections()->end(); 
       sectionIt++)
  {
    section = (*sectionIt);
    params = section->getParams();
    for (paramIt = params->begin(); paramIt != params->end(); paramIt++)
    {
      param = (*paramIt);
      switch (param.getType()) {
      case ArConfigArg::INT:
	myDefault->addParam(
		ArConfigArg(param.getName(), param.getInt(), 
			    param.getDescription(), 
			    param.getMinInt(), param.getMaxInt()), 
		section->getName(), 
		param.getConfigPriority(),
		param.getDisplayHint());
	break;
      case ArConfigArg::DOUBLE:
	myDefault->addParam(
		ArConfigArg(param.getName(), param.getDouble(), 
			    param.getDescription(),
			    param.getMinDouble(), param.getMaxDouble()), 
		section->getName(), 
		param.getConfigPriority(),
		param.getDisplayHint());
	break;
	
      case ArConfigArg::BOOL:
	myDefault->addParam(
		ArConfigArg(param.getName(), param.getBool(), 
			    param.getDescription()),
		section->getName(), 
		param.getConfigPriority(),
		param.getDisplayHint());
	break;
	
      case ArConfigArg::STRING:
	myDefault->addParam(
		ArConfigArg(param.getName(), (char *)param.getString(), 
			    param.getDescription(), 0),
		section->getName(), 
		param.getConfigPriority(),
		param.getDisplayHint());
	break;
	
      case ArConfigArg::SEPARATOR:
	myDefault->addParam(
		ArConfigArg(ArConfigArg::SEPARATOR),
		section->getName(), 
		param.getConfigPriority(),
		param.getDisplayHint());
	break;
      default:
	break;
      } // end switch param type
    } // end for each param
  } // end for each section
}
Пример #6
0
int main(int argc, char **argv)
{
  Aria::init();
  ArArgumentParser argParser(&argc, argv);
  argParser.loadDefaultArguments();
  if (argc < 2 || !Aria::parseArgs() || argParser.checkArgument("-help"))
  {
    ArLog::log(ArLog::Terse, "configExample usage: configExample <config file>.\nFor example, \"configExample examples/configExample.cfg\".");
    Aria::logOptions();
    Aria::shutdown();
    return 1;
  }
  
  // Object containing config parameters, and responding to changes:
  ConfigExample configExample;

  // Load a config file given on the command line into the global 
  // ArConfig object kept by Aria.  Normally ArConfig expects config
  // files to be in the main ARIA directory (i.e. /usr/local/Aria or
  // a directory specified by the $ARIA environment variable).
  char error[512];
  const char* filename = argParser.getArg(1);
  ArConfig* config = Aria::getConfig();
  ArLog::log(ArLog::Normal, "configExample: loading configuration file \"%s\"...", filename);
  if (! config->parseFile(filename, true, false, error, 512) )
  {
    ArLog::log(ArLog::Terse, "configExample: Error loading configuration file \"%s\" %s. Try \"examples/configExample.cfg\".", filename, error);
    Aria::shutdown();
    return -1;
  }

  ArLog::log(ArLog::Normal, "configExample: Loaded configuration file \"%s\".", filename);
  
  // After changing a config value, you should invoke the callbacks:
  ArConfigSection* section = config->findSection("Example Section");
  if (section)
  {
    ArConfigArg* arg = section->findParam("ExampleBoolParameter");
    if (arg)
    {
      arg->setBool(!arg->getBool());
      if (! config->callProcessFileCallBacks(false, error, 512) )
      {
        ArLog::log(ArLog::Terse, "configExample: Error processing modified config: %s.", error);
      }
      else
      {
        ArLog::log(ArLog::Normal, "configExample: Successfully modified config and invoked callbacks.");
      }
    }
  }

  // You can save the configuration as well:
  ArLog::log(ArLog::Normal, "configExample: Saving configuration...");
  if(!config->writeFile(filename))
  {
    ArLog::log(ArLog::Terse, "configExample: Error saving configuration to file \"%s\"!", filename);
  }

  // end of program.
  ArLog::log(ArLog::Normal, "configExample: end of program.");
  Aria::shutdown();
  return 0;
}