/** * @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