00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "Aria.h"
00027 #include "ArExport.h"
00028 #include "ArServerHandlerConfig.h"
00029
00030 #include "ArClientArgUtils.h"
00031
00043 AREXPORT ArServerHandlerConfig::ArServerHandlerConfig(ArServerBase *server,
00044 ArConfig *config,
00045 const char *defaultFile,
00046 const char *defaultFileBaseDirectory) :
00047 myServer(server),
00048 myConfig(config),
00049 myDefault(NULL),
00050 myPreWriteCallbacks(),
00051 myPostWriteCallbacks(),
00052 myGetConfigBySectionsCB(this, &ArServerHandlerConfig::getConfigBySections),
00053 myGetConfigCB(this, &ArServerHandlerConfig::getConfig),
00054 mySetConfigCB(this, &ArServerHandlerConfig::setConfig),
00055 myReloadConfigCB(this, &ArServerHandlerConfig::reloadConfig),
00056 myGetConfigDefaultsCB(this, &ArServerHandlerConfig::getConfigDefaults),
00057 myGetConfigSectionFlagsCB(this,
00058 &ArServerHandlerConfig::getConfigSectionFlags)
00059 {
00060 myServer->addData("getConfigBySections",
00061 "Gets the configuration information from the server",
00062 &myGetConfigBySectionsCB,
00063 "none",
00064 "A single packet is sent for each config section. Too complex to describe here. Use ArClientHandlerConfig if desired.",
00065 "ConfigEditing", "RETURN_UNTIL_EMPTY");
00066
00067
00068 myServer->addData("getConfig",
00069 "gets the configuration information from the server",
00070 &myGetConfigCB,
00071 "none",
00072 "deprecated (getConfigBySections is preferred). Too complex to describe here. Use ArClientHandlerConfig if desired.",
00073 "ConfigEditing", "RETURN_SINGLE");
00074
00075 myServer->addData("setConfig",
00076 "takes a config back from the client to use",
00077 &mySetConfigCB,
00078 "Repeating pairs of strings which are parameter name and value to parse",
00079 "string: if empty setConfig worked, if the string isn't empty then it is the first error that occured (all non-error parameters are parsed, and only the first error is reported)",
00080 "ConfigEditing", "RETURN_SINGLE");
00081
00082 myServer->addData("reloadConfig",
00083 "reloads the configuration file last loaded",
00084 &myReloadConfigCB, "none", "none",
00085 "ConfigEditing", "RETURN_SINGLE");
00086
00087 myServer->addData("configUpdated",
00088 "gets sent when the config is updated",
00089 NULL, "none", "none",
00090 "ConfigEditing", "RETURN_SINGLE");
00091
00092 myServer->addData("getConfigSectionFlags",
00093 "gets the flags for each section of the config",
00094 &myGetConfigSectionFlagsCB,
00095 "none",
00096 "byte4: number of sections; repeating for number of sections (string: section; string: flags (separated by |))",
00097 "ConfigEditing", "RETURN_SINGLE");
00098
00099 if (defaultFile != NULL)
00100 myDefaultFile = defaultFile;
00101 if (defaultFileBaseDirectory != NULL)
00102 myDefaultFileBaseDir = defaultFileBaseDirectory;
00103 loadDefaultsFromFile();
00104 }
00105
00106 AREXPORT ArServerHandlerConfig::~ArServerHandlerConfig()
00107 {
00108
00109 }
00110
00111 AREXPORT bool ArServerHandlerConfig::loadDefaultsFromFile(void)
00112 {
00113 bool ret = true;
00114
00115 lockConfig();
00116 if (myDefault != NULL)
00117 {
00118 delete myDefault;
00119 myDefault = NULL;
00120 }
00121
00122 if (!myDefaultFile.empty())
00123 {
00124 createDefaultConfig(myDefaultFileBaseDir.c_str());
00125 myDefault->clearAllValueSet();
00126
00127 if (myDefault->parseFile(myDefaultFile.c_str()))
00128 {
00129 addDefaultServerCommands();
00130 }
00131 else
00132 {
00133 ret = false;
00134 ArLog::log(ArLog::Normal, "Did not load default file '%s' successfully, not allowing getDefault", myDefaultFile.c_str());
00135 delete myDefault;
00136 myDefault = NULL;
00137 }
00138 if (myDefault != NULL)
00139 myDefault->removeAllUnsetValues();
00140 }
00141 unlockConfig();
00142 ArNetPacket emptyPacket;
00143 myServer->broadcastPacketTcp(&emptyPacket, "configDefaultsUpdated");
00144 return ret;
00145 }
00146
00147 AREXPORT bool ArServerHandlerConfig::loadDefaultsFromPacket(
00148 ArNetPacket *packet)
00149 {
00150 bool ret = true;
00151
00152 lockConfig();
00153 if (myDefault != NULL)
00154 {
00155 delete myDefault;
00156 myDefault = NULL;
00157 }
00158
00159 createDefaultConfig(NULL);
00160 myDefault->clearAllValueSet();
00161
00162 if (internalSetConfig(NULL, packet))
00163 {
00164 addDefaultServerCommands();
00165 }
00166 else
00167 {
00168 ArLog::log(ArLog::Normal, "Did not load default from packet successfully, not allowing getDefault");
00169 delete myDefault;
00170 myDefault = NULL;
00171 }
00172 if (myDefault != NULL)
00173 myDefault->removeAllUnsetValues();
00174 unlockConfig();
00175 ArNetPacket emptyPacket;
00176 myServer->broadcastPacketTcp(&emptyPacket, "configDefaultsUpdated");
00177 return ret;
00178 }
00179
00180 AREXPORT void ArServerHandlerConfig::createEmptyConfigDefaults(void)
00181 {
00182 lockConfig();
00183 if (myDefault != NULL)
00184 {
00185 delete myDefault;
00186 myDefault = NULL;
00187 }
00188
00189 addDefaultServerCommands();
00190 unlockConfig();
00191 ArNetPacket emptyPacket;
00192 myServer->broadcastPacketTcp(&emptyPacket, "configDefaultsUpdated");
00193 }
00194
00201 void ArServerHandlerConfig::createDefaultConfig(const char *defaultFileBaseDir)
00202 {
00203
00204
00205 myDefault = new ArConfig(defaultFileBaseDir, false, false, false, false);
00206
00207 std::list<ArConfigSection *>::iterator sectionIt;
00208 std::list<ArConfigArg>::iterator paramIt;
00209 ArConfigSection *section = NULL;
00210 std::list<ArConfigArg> *params = NULL;
00211 ArConfigArg param;
00212 for (sectionIt = myConfig->getSections()->begin();
00213 sectionIt != myConfig->getSections()->end();
00214 sectionIt++)
00215 {
00216 section = (*sectionIt);
00217 params = section->getParams();
00218 for (paramIt = params->begin(); paramIt != params->end(); paramIt++)
00219 {
00220 param = (*paramIt);
00221 switch (param.getType()) {
00222 case ArConfigArg::INT:
00223 myDefault->addParam(
00224 ArConfigArg(param.getName(), param.getInt(),
00225 param.getDescription(),
00226 param.getMinInt(), param.getMaxInt()),
00227 section->getName(),
00228 param.getConfigPriority(),
00229 param.getDisplayHint());
00230 break;
00231 case ArConfigArg::DOUBLE:
00232 myDefault->addParam(
00233 ArConfigArg(param.getName(), param.getDouble(),
00234 param.getDescription(),
00235 param.getMinDouble(), param.getMaxDouble()),
00236 section->getName(),
00237 param.getConfigPriority(),
00238 param.getDisplayHint());
00239 break;
00240
00241 case ArConfigArg::BOOL:
00242 myDefault->addParam(
00243 ArConfigArg(param.getName(), param.getBool(),
00244 param.getDescription()),
00245 section->getName(),
00246 param.getConfigPriority(),
00247 param.getDisplayHint());
00248 break;
00249
00250 case ArConfigArg::STRING:
00251 myDefault->addParam(
00252 ArConfigArg(param.getName(), (char *)param.getString(),
00253 param.getDescription(), 0),
00254 section->getName(),
00255 param.getConfigPriority(),
00256 param.getDisplayHint());
00257 break;
00258
00259 case ArConfigArg::SEPARATOR:
00260 myDefault->addParam(
00261 ArConfigArg(ArConfigArg::SEPARATOR),
00262 section->getName(),
00263 param.getConfigPriority(),
00264 param.getDisplayHint());
00265 break;
00266 default:
00267 break;
00268 }
00269 }
00270 }
00271 }
00272
00273 void ArServerHandlerConfig::addDefaultServerCommands(void)
00274 {
00275 if (myAddedDefaultServerCommands)
00276 return;
00277
00278 myServer->addData("getConfigDefaults",
00279 "Gets the config default values ",
00280 &myGetConfigDefaultsCB,
00281 "string: section to load, empty string means get the whole thing",
00282 "repeating strings that are the parameters and arguments to parse, but use ArClientHandlerConfig to handle this if you want",
00283 "ConfigEditing");
00284 myServer->addData("configDefaultsUpdated",
00285 "Gets sent when the config defaults are updated",
00286 NULL, "none", "none",
00287 "ConfigEditing", "RETURN_SINGLE");
00288 myAddedDefaultServerCommands = true;
00289 }
00290 AREXPORT void ArServerHandlerConfig::handleGetConfig(ArServerClient *client,
00291 ArNetPacket *packet,
00292 bool isMultiplePackets)
00293 {
00294
00295 ArConfigArg param;
00296
00297
00298
00299 ArClientArg clientArg(isMultiplePackets);
00300
00301 std::set<std::string> sent;
00302
00303 ArNetPacket sending;
00304 ArLog::log(ArLog::Normal, "Config requested.");
00305
00306 std::list<ArConfigSection *> *sections = myConfig->getSections();
00307 for (std::list<ArConfigSection *>::iterator sIt = sections->begin();
00308 sIt != sections->end();
00309 sIt++)
00310 {
00311
00312 if (isMultiplePackets) {
00313 sending.empty();
00314 }
00315
00316
00317 sent.clear();
00318
00319 ArConfigSection *section = (*sIt);
00320 if (section == NULL) {
00321 continue;
00322 }
00323
00324 sending.byteToBuf('S');
00325 sending.strToBuf(section->getName());
00326 sending.strToBuf(section->getComment());
00327
00328 ArLog::log(ArLog::Verbose, "Sending config section %s...", section->getName());
00329
00330
00331 std::list<ArConfigArg> *params = section->getParams();
00332 for (std::list<ArConfigArg>::iterator pIt = params->begin();
00333 pIt != params->end();
00334 pIt++)
00335 {
00336 param = (*pIt);
00337
00338 bool isCheckableName =
00339 (param.getType() != ArConfigArg::DESCRIPTION_HOLDER &&
00340 param.getType() != ArConfigArg::SEPARATOR &&
00341 param.getType() != ArConfigArg::STRING_HOLDER);
00342
00343
00344 if (isCheckableName &&
00345 sent.find(param.getName()) != sent.end()) {
00346 continue;
00347 }
00348 else if (isCheckableName) {
00349 sent.insert(param.getName());
00350 }
00351
00352 if (clientArg.isSendableParamType(param))
00353 {
00354 sending.byteToBuf('P');
00355
00356 bool isSuccess = clientArg.createPacket(param,
00357 &sending);
00358
00359 }
00360 }
00361
00362 if (!sending.isValid()) {
00363
00364 ArLog::log(ArLog::Terse, "Config section %s cannot be sent; packet size exceeded",
00365 section->getName());
00366
00367 }
00368 else if (isMultiplePackets) {
00369
00370 client->sendPacketTcp(&sending);
00371
00372 }
00373
00374 }
00375
00376
00377
00378 if (isMultiplePackets) {
00379
00380 sending.empty();
00381 client->sendPacketTcp(&sending);
00382 }
00383 else {
00384
00385
00386
00387
00388 if (!sending.isValid()) {
00389 ArLog::log(ArLog::Terse, "Error sending config; packet size exceeded");
00390 sending.empty();
00391 }
00392
00393 client->sendPacketTcp(&sending);
00394
00395 }
00396
00397 }
00398
00399
00400 AREXPORT void ArServerHandlerConfig::getConfigBySections(ArServerClient *client,
00401 ArNetPacket *packet)
00402 {
00403 handleGetConfig(client,
00404 packet,
00405 true);
00406
00407 }
00408
00409 AREXPORT void ArServerHandlerConfig::getConfig(ArServerClient *client,
00410 ArNetPacket *packet)
00411 {
00412 handleGetConfig(client,
00413 packet,
00414 false);
00415
00416 }
00417
00418
00419
00420 AREXPORT void ArServerHandlerConfig::setConfig(ArServerClient *client,
00421 ArNetPacket *packet)
00422 {
00423 internalSetConfig(client, packet);
00424 }
00425
00430 bool ArServerHandlerConfig::internalSetConfig(ArServerClient *client,
00431 ArNetPacket *packet)
00432 {
00433 char param[1024];
00434 char argument[1024];
00435 char errorBuffer[1024];
00436 char firstError[1024];
00437 ArNetPacket retPacket;
00438 ArConfig *config;
00439 bool ret = true;
00440
00441 if (client != NULL)
00442 config = myConfig;
00443 else
00444 config = myDefault;
00445
00446 if (client != NULL)
00447 lockConfig();
00448 ArArgumentBuilder *builder = NULL;
00449 if (client != NULL)
00450 ArLog::log(ArLog::Normal, "Got new config from client %s", client->getIPString());
00451 else
00452 ArLog::log(ArLog::Verbose, "New default config");
00453 errorBuffer[0] = '\0';
00454 firstError[0] = '\0';
00455
00456 while (packet->getDataReadLength() < packet->getDataLength())
00457 {
00458 packet->bufToStr(param, sizeof(param));
00459 packet->bufToStr(argument, sizeof(argument));
00460
00461 builder = new ArArgumentBuilder;
00462 builder->setExtraString(param);
00463 builder->add(argument);
00464 ArLog::log(ArLog::Verbose, "Config: %s %s", param, argument);
00465
00466
00467 if ((strcasecmp(param, "Section") == 0 &&
00468 !config->parseSection(builder, errorBuffer, sizeof(errorBuffer))) ||
00469 (strcasecmp(param, "Section") != 0 &&
00470 !config->parseArgument(builder, errorBuffer, sizeof(errorBuffer))))
00471 {
00472 if (firstError[0] == '\0')
00473 strcpy(firstError, errorBuffer);
00474 }
00475 delete builder;
00476 builder = NULL;
00477 }
00478 if (firstError[0] == '\0')
00479 {
00480 if (config->callProcessFileCallBacks(true,
00481 errorBuffer,
00482 sizeof(errorBuffer)))
00483 {
00484 if (client != NULL)
00485 ArLog::log(ArLog::Normal, "New config from client %s was fine.",
00486 client->getIPString());
00487 else
00488 ArLog::log(ArLog::Verbose, "New default config was fine.");
00489 retPacket.strToBuf("");
00490 writeConfig();
00491 }
00492 else
00493 {
00494 ret = false;
00495 if (firstError[0] == '\0')
00496 strcpy(firstError, errorBuffer);
00497
00498 if (firstError[0] == '\0')
00499 strcpy(firstError, "Error processing");
00500
00501 if (client != NULL)
00502 ArLog::log(ArLog::Normal,
00503 "New config from client %s had errors processing ('%s').",
00504 client->getIPString(), firstError);
00505 else
00506 ArLog::log(ArLog::Normal,
00507 "New default config had errors processing ('%s').",
00508 firstError);
00509 retPacket.strToBuf(firstError);
00510 }
00511 }
00512 else
00513 {
00514 ret = false;
00515 if (client != NULL)
00516 ArLog::log(ArLog::Normal,
00517 "New config from client %s had at least this problem: %s",
00518 client->getIPString(), firstError);
00519 else
00520 ArLog::log(ArLog::Normal,
00521 "New default config had at least this problem: %s",
00522 firstError);
00523 retPacket.strToBuf(firstError);
00524 }
00525
00526
00527 if (client != NULL)
00528 client->sendPacketTcp(&retPacket);
00529 if (client != NULL)
00530 unlockConfig();
00531 if (client != NULL)
00532 configUpdated(client);
00533
00534 return ret;
00535 }
00536
00537 AREXPORT void ArServerHandlerConfig::reloadConfig(ArServerClient *client,
00538 ArNetPacket *packet)
00539 {
00540 myConfig->parseFile(myConfig->getFileName(), true);
00541 configUpdated();
00542 }
00543
00544 AREXPORT void ArServerHandlerConfig::getConfigDefaults(ArServerClient *client,
00545 ArNetPacket *packet)
00546 {
00547 char sectionRequested[512];
00548 sectionRequested[0] = '\0';
00549 ArNetPacket sending;
00550
00551 if (myDefault == NULL)
00552 {
00553 ArLog::log(ArLog::Normal, "ArServerHandlerConfig::getConfigDefaults: No default config to get");
00554 client->sendPacketTcp(&sending);
00555 return;
00556 }
00557 myConfigMutex.lock();
00558
00559 if (packet->getDataReadLength() < packet->getDataLength())
00560 packet->bufToStr(sectionRequested, sizeof(sectionRequested));
00561
00562
00563
00564 ArClientArg clientArg;
00565
00566 if (sectionRequested[0] == '\0')
00567 ArLog::log(ArLog::Normal, "Sending all defaults to client");
00568 else
00569 ArLog::log(ArLog::Normal, "Sending defaults for section '%s' to client",
00570 sectionRequested);
00571
00572
00573 std::list<ArConfigSection *> *sections = myDefault->getSections();
00574
00575 for (std::list<ArConfigSection *>::iterator sIt = sections->begin();
00576 sIt != sections->end();
00577 sIt++)
00578 {
00579 ArConfigSection *section = (*sIt);
00580
00581 if (section == NULL) {
00582 continue;
00583 }
00584
00585
00586 if (sectionRequested[0] != '\0' &&
00587 ArUtil::strcasecmp(sectionRequested, section->getName()) != 0) {
00588 continue;
00589 }
00590
00591 sending.strToBuf("Section");
00592 sending.strToBuf(section->getName());
00593
00594 std::list<ArConfigArg> *params = section->getParams();
00595
00596 for (std::list<ArConfigArg>::iterator pIt = params->begin();
00597 pIt != params->end();
00598 pIt++)
00599 {
00600 ArConfigArg ¶m = (*pIt);
00601
00602 if (!clientArg.isSendableParamType(param)) {
00603 continue;
00604 }
00605
00606 sending.strToBuf(param.getName());
00607 clientArg.argTextToBuf(param, &sending);
00608
00609 }
00610 }
00611 myConfigMutex.unlock();
00612
00613 client->sendPacketTcp(&sending);
00614 }
00615
00616
00617 AREXPORT void ArServerHandlerConfig::addPreWriteCallback(
00618 ArFunctor *functor, ArListPos::Pos position)
00619 {
00620 if (position == ArListPos::FIRST)
00621 myPreWriteCallbacks.push_front(functor);
00622 else if (position == ArListPos::LAST)
00623 myPreWriteCallbacks.push_back(functor);
00624 else
00625 ArLog::log(ArLog::Terse,
00626 "ArServerHandlerConfig::addPreWriteCallback: Invalid position.");
00627 }
00628
00629 AREXPORT void ArServerHandlerConfig::remPreWriteCallback(
00630 ArFunctor *functor)
00631 {
00632 myPreWriteCallbacks.remove(functor);
00633 }
00634
00635 AREXPORT void ArServerHandlerConfig::addPostWriteCallback(
00636 ArFunctor *functor, ArListPos::Pos position)
00637 {
00638 if (position == ArListPos::FIRST)
00639 myPostWriteCallbacks.push_front(functor);
00640 else if (position == ArListPos::LAST)
00641 myPostWriteCallbacks.push_back(functor);
00642 else
00643 ArLog::log(ArLog::Terse,
00644 "ArServerHandlerConfig::addPostWriteCallback: Invalid position.");
00645 }
00646
00647 AREXPORT void ArServerHandlerConfig::remPostWriteCallback(
00648 ArFunctor *functor)
00649 {
00650 myPostWriteCallbacks.remove(functor);
00651 }
00652
00653 AREXPORT void ArServerHandlerConfig::addConfigUpdatedCallback(
00654 ArFunctor *functor, ArListPos::Pos position)
00655 {
00656 if (position == ArListPos::FIRST)
00657 myConfigUpdatedCallbacks.push_front(functor);
00658 else if (position == ArListPos::LAST)
00659 myConfigUpdatedCallbacks.push_back(functor);
00660 else
00661 ArLog::log(ArLog::Terse,
00662 "ArServerHandlerConfig::addConfigUpdatedCallback: Invalid position.");
00663 }
00664
00665 AREXPORT void ArServerHandlerConfig::remConfigUpdatedCallback(
00666 ArFunctor *functor)
00667 {
00668 myConfigUpdatedCallbacks.remove(functor);
00669 }
00670
00671 AREXPORT bool ArServerHandlerConfig::writeConfig(void)
00672 {
00673 bool ret;
00674 std::list<ArFunctor *>::iterator fit;
00675
00676 if (myConfig->getFileName() != NULL &&
00677 strlen(myConfig->getFileName()) > 0)
00678 {
00679
00680 for (fit = myPreWriteCallbacks.begin();
00681 fit != myPreWriteCallbacks.end();
00682 fit++)
00683 {
00684 (*fit)->invoke();
00685 }
00686
00687
00688 ArLog::log(ArLog::Normal, "Writing config file %s",
00689 myConfig->getFileName());
00690 ret = myConfig->writeFile(myConfig->getFileName());
00691
00692
00693
00694 for (fit = myPostWriteCallbacks.begin();
00695 fit != myPostWriteCallbacks.end();
00696 fit++)
00697 {
00698 (*fit)->invoke();
00699 }
00700 }
00701 return ret;
00702 }
00703
00704 AREXPORT bool ArServerHandlerConfig::configUpdated(ArServerClient *client)
00705 {
00706 ArNetPacket emptyPacket;
00707
00708 std::list<ArFunctor *>::iterator fit;
00709
00710
00711 for (fit = myConfigUpdatedCallbacks.begin();
00712 fit != myConfigUpdatedCallbacks.end();
00713 fit++)
00714 {
00715 (*fit)->invoke();
00716 }
00717
00718
00719 return myServer->broadcastPacketTcpWithExclusion(&emptyPacket,
00720 "configUpdated", client);
00721 }
00722
00723 AREXPORT void ArServerHandlerConfig::getConfigSectionFlags(
00724 ArServerClient *client, ArNetPacket *packet)
00725 {
00726 ArLog::log(ArLog::Normal, "Config section flags requested.");
00727
00728 ArNetPacket sending;
00729
00730 std::list<ArConfigSection *> *sections = myConfig->getSections();
00731 std::list<ArConfigSection *>::iterator sIt;
00732 sending.byte4ToBuf(sections->size());
00733
00734 for (sIt = sections->begin(); sIt != sections->end(); sIt++)
00735 {
00736
00737 ArConfigSection *section = (*sIt);
00738 if (section == NULL)
00739 {
00740 sending.strToBuf("");
00741 sending.strToBuf("");
00742 }
00743 else
00744 {
00745 sending.strToBuf(section->getName());
00746 sending.strToBuf(section->getFlags());
00747 }
00748 }
00749 client->sendPacketTcp(&sending);
00750 }