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 "ArServerBase.h"
00029 #include "ArServerCommands.h"
00030 #include "ArClientCommands.h"
00031
00032
00033 AREXPORT ArServerBase::ArServerBase(bool addAriaExitCB,
00034 const char * serverName) :
00035 myProcessPacketCB(this, &ArServerBase::processPacket),
00036 mySendUdpCB(this, &ArServerBase::sendUdp),
00037 myAriaExitCB(this, &ArServerBase::close),
00038 myGetFrequencyCB(this, &ArServerBase::getFrequency, 0, true)
00039 {
00040 if (serverName != NULL && serverName[0] > 0)
00041 myServerName = serverName;
00042 else
00043 myServerName = "ArNetServer";
00044 setThreadName("ArServerBase");
00045 myTcpPort = 0;
00046 myUdpPort = 0;
00047 myRejecting = 0;
00048 myOpened = false;
00049 myUdpReceiver.setProcessPacketCB(&myProcessPacketCB);
00050 myNextDataNumber = 256;
00051 myUserInfo = NULL;
00052 myAriaExitCB.setName("ArServerBaseExit");
00053 if (addAriaExitCB)
00054 Aria::addExitCallback(&myAriaExitCB, 20);
00055 }
00056
00057 AREXPORT ArServerBase::~ArServerBase()
00058 {
00059 close();
00060 }
00061
00070 AREXPORT bool ArServerBase::open(unsigned int port, const char *openOnIP)
00071 {
00072 myDataMutex.lock();
00073 myTcpPort = port;
00074
00075 if (myTcpSocket.open(myTcpPort, ArSocket::TCP, openOnIP))
00076 {
00077 myTcpSocket.setLinger(0);
00078 myTcpSocket.setNonBlock();
00079 }
00080 else
00081 {
00082 myOpened = false;
00083 myDataMutex.unlock();
00084 return false;
00085 }
00086
00087 if (myUdpSocket.create(ArSocket::UDP) &&
00088 myUdpSocket.findValidPort(myTcpPort, openOnIP) &&
00089 myUdpSocket.setNonBlock())
00090 {
00091
00092 myUdpPort = ArSocket::netToHostOrder(myUdpSocket.inPort());
00093 myUdpReceiver.setSocket(&myUdpSocket);
00094 if (openOnIP != NULL)
00095 ArLog::log(ArLog::Normal,
00096 "%s started on tcp port %d and udp port %d on ip %s.",
00097 myServerName.c_str(), myTcpPort, myUdpPort, openOnIP);
00098 else
00099 ArLog::log(ArLog::Normal, "%s started on tcp port %d and udp port %d.",
00100 myServerName.c_str(), myTcpPort, myUdpPort);
00101
00102 }
00103 else
00104 {
00105 myOpened = false;
00106 myTcpSocket.close();
00107 myDataMutex.unlock();
00108 return false;
00109 }
00110 myOpened = true;
00111 myDataMutex.unlock();
00112 return true;
00113 }
00114
00115 AREXPORT void ArServerBase::close(void)
00116 {
00117 std::list<ArServerClient *>::iterator it;
00118 ArServerClient *client;
00119
00120 myClientsMutex.lock();
00121 if (!myOpened)
00122 {
00123 myClientsMutex.unlock();
00124 return;
00125 }
00126
00127 ArLog::log(ArLog::Normal, "Server shutting down.");
00128 myOpened = false;
00129
00130 for (it = myClients.begin(); it != myClients.end(); ++it)
00131 {
00132 client = (*it);
00133 client->shutdown();
00134 printf("Sending shutdown\n");
00135 }
00136
00137 ArUtil::sleep(10);
00138
00139 while ((it = myClients.begin()) != myClients.end())
00140 {
00141 client = (*it);
00142 myClients.pop_front();
00143 delete client;
00144 }
00145 myTcpSocket.close();
00146 myUdpSocket.close();
00147 myClientsMutex.unlock();
00148 }
00149
00150 void ArServerBase::acceptTcpSockets(void)
00151 {
00152 ArSocket socket;
00153
00154 myClientsMutex.lock();
00155
00156
00157
00158
00159 while (myTcpSocket.accept(&socket) && socket.getFD() >= 0)
00160 {
00161 finishAcceptingSocket(&socket, false);
00162 }
00163 myClientsMutex.unlock();
00164 }
00165
00166 AREXPORT void ArServerBase::makeNewServerClientFromSocket(ArSocket *socket,
00167 bool doNotReject)
00168 {
00169 myDataMutex.lock();
00170 finishAcceptingSocket(socket, true, doNotReject);
00171 myDataMutex.unlock();
00172 }
00173
00174 AREXPORT void ArServerBase::finishAcceptingSocket(ArSocket *socket,
00175 bool skipPassword,
00176 bool doNotReject)
00177 {
00178 ArServerClient *client;
00179 bool foundAuthKey;
00180 std::list<ArServerClient *>::iterator it;
00181 bool thisKeyBad;
00182 long authKey;
00183 long introKey;
00184 ArNetPacket packet;
00185 int iterations;
00186
00187 ArLog::log(ArLog::Verbose, "New connection from %s", socket->getIPString());
00188
00189
00190
00191
00192
00193
00194 for (foundAuthKey = false, authKey = ArMath::random(), iterations = 0;
00195 !foundAuthKey && iterations < 10000;
00196 iterations++, authKey = ArMath::random())
00197 {
00198
00199 for (thisKeyBad = false, it = myClients.begin();
00200 !thisKeyBad && it != myClients.end();
00201 ++it)
00202 {
00203 if (authKey == (*it)->getAuthKey())
00204 thisKeyBad = true;
00205 }
00206
00207
00208 if (!thisKeyBad)
00209 foundAuthKey = true;
00210 }
00211 if (!foundAuthKey)
00212 authKey = 0;
00213
00214
00215
00216 introKey = ArMath::random();
00217 std::string passwordKey;
00218 int numInPasswordKey = ArMath::random() % 100;
00219 int i;
00220 passwordKey = "";
00221 if (!skipPassword)
00222 {
00223 for (i = 0; i < numInPasswordKey; i++)
00224 passwordKey += '0' + ArMath::random() % ('z' - '0');
00225 }
00226 int reject;
00227 const char *rejectString;
00228 if (doNotReject)
00229 {
00230 reject = 0;
00231 rejectString = "";
00232 }
00233 else
00234 {
00235 reject = myRejecting;
00236 rejectString = myRejectingString.c_str();
00237 }
00238 client = new ArServerClient(socket, myUdpPort, authKey, introKey,
00239 &mySendUdpCB, &myDataMap,
00240 passwordKey.c_str(), myServerKey.c_str(),
00241 myUserInfo, reject, rejectString);
00242
00243 myClients.push_front(client);
00244 }
00245
00246 AREXPORT int ArServerBase::getNumClients(void)
00247 {
00248 int ret;
00249 myClientsMutex.lock();
00250 ret = myClients.size();
00251 myClientsMutex.unlock();
00252 return ret;
00253 }
00254
00255 AREXPORT void ArServerBase::run(void)
00256 {
00257 runInThisThread();
00258 }
00259
00260 AREXPORT void ArServerBase::runAsync(void)
00261 {
00262 create();
00263 }
00264
00265 AREXPORT void *ArServerBase::runThread(void *arg)
00266 {
00267 threadStarted();
00268 while (myRunning)
00269 {
00270 loopOnce();
00271 ArUtil::sleep(1);
00272 }
00273 close();
00274 return NULL;
00275 }
00276
00277
00288 AREXPORT bool ArServerBase::broadcastPacketTcp(ArNetPacket *packet,
00289 const char *name)
00290 {
00291 return broadcastPacketTcpWithExclusion(packet, name, NULL);
00292 }
00293
00304 AREXPORT bool ArServerBase::broadcastPacketTcpWithExclusion(
00305 ArNetPacket *packet, const char *name, ArServerClient *excludeClient)
00306 {
00307
00308 std::map<unsigned int, ArServerData *>::iterator it;
00309 unsigned int command;
00310
00311 myDataMutex.lock();
00312 for (it = myDataMap.begin(); it != myDataMap.end(); it++)
00313 {
00314 if (!strcmp((*it).second->getName(), name))
00315 command = (*it).second->getCommand();
00316 }
00317 if (command == 0)
00318 {
00319 ArLog::log(ArLog::Terse, "ArServerBase::broadcastPacket: no command by name of \"%s\"", name);
00320 myDataMutex.unlock();
00321 return false;
00322 }
00323 myDataMutex.unlock();
00324 return broadcastPacketTcpByCommandWithExclusion(packet, command,
00325 excludeClient);
00326 }
00327
00339 AREXPORT bool ArServerBase::broadcastPacketTcpByCommand(
00340 ArNetPacket *packet, unsigned int command)
00341 {
00342 return broadcastPacketTcpByCommandWithExclusion(packet, command, NULL);
00343 }
00344
00355 AREXPORT bool ArServerBase::broadcastPacketTcpByCommandWithExclusion(
00356 ArNetPacket *packet, unsigned int command,
00357 ArServerClient *excludeClient)
00358 {
00359 std::list<ArServerClient *>::iterator lit;
00360
00361 ArNetPacket emptyPacket;
00362
00363 myClientsMutex.lock();
00364 emptyPacket.empty();
00365
00366 if (!myOpened)
00367 {
00368 ArLog::log(ArLog::Verbose, "ArServerBase::broadcastPacket: server not open to send packet.");
00369 myClientsMutex.unlock();
00370 return false;
00371 }
00372
00373 if (packet == NULL)
00374 packet = &emptyPacket;
00375
00376 packet->setCommand(command);
00377 for (lit = myClients.begin(); lit != myClients.end(); ++lit)
00378 {
00379 if (excludeClient == NULL || (*lit) != excludeClient)
00380 (*lit)->broadcastPacketTcp(packet);
00381 }
00382
00383 myClientsMutex.unlock();
00384 return true;
00385 }
00386
00398 AREXPORT bool ArServerBase::broadcastPacketUdp(ArNetPacket *packet,
00399 const char *name)
00400 {
00401 return broadcastPacketUdpWithExclusion(packet, name, NULL);
00402 }
00403
00415 AREXPORT bool ArServerBase::broadcastPacketUdpWithExclusion(
00416 ArNetPacket *packet, const char *name, ArServerClient *excludeClient)
00417 {
00418
00419 std::map<unsigned int, ArServerData *>::iterator it;
00420 unsigned int command = 0;
00421
00422 myDataMutex.lock();
00423 for (it = myDataMap.begin(); it != myDataMap.end(); it++)
00424 {
00425 if (!strcmp((*it).second->getName(), name))
00426 command = (*it).second->getCommand();
00427 }
00428 if (command == 0)
00429 {
00430 ArLog::log(ArLog::Terse, "ArServerBase::broadcastPacket: no command by name of \"%s\"", name);
00431 myDataMutex.unlock();
00432 return false;
00433 }
00434 myDataMutex.unlock();
00435 return broadcastPacketUdpByCommandWithExclusion(packet, command,
00436 excludeClient);
00437 }
00438
00450 AREXPORT bool ArServerBase::broadcastPacketUdpByCommand(
00451 ArNetPacket *packet, unsigned int command)
00452 {
00453 return broadcastPacketUdpByCommandWithExclusion(packet, command, NULL);
00454 }
00455
00466 AREXPORT bool ArServerBase::broadcastPacketUdpByCommandWithExclusion(
00467 ArNetPacket *packet, unsigned int command,
00468 ArServerClient *excludeClient)
00469 {
00470 std::list<ArServerClient *>::iterator lit;
00471 ArNetPacket emptyPacket;
00472
00473 myClientsMutex.lock();
00474 emptyPacket.empty();
00475
00476 if (!myOpened)
00477 {
00478 ArLog::log(ArLog::Verbose, "ArServerBase::broadcastPacket: server not open to send packet.");
00479 myClientsMutex.unlock();
00480 return false;
00481 }
00482
00483 if (packet == NULL)
00484 packet = &emptyPacket;
00485
00486 packet->setCommand(command);
00487 for (lit = myClients.begin(); lit != myClients.end(); ++lit)
00488 {
00489 if (excludeClient == NULL || (*lit) != excludeClient)
00490 (*lit)->broadcastPacketUdp(packet);
00491 }
00492 myClientsMutex.unlock();
00493 return true;
00494 }
00495
00502 AREXPORT unsigned int ArServerBase::findCommandFromName(const char *name)
00503 {
00504
00505 std::map<unsigned int, ArServerData *>::iterator it;
00506 unsigned int num = 0;
00507 myDataMutex.lock();
00508
00509 for (it = myDataMap.begin(); it != myDataMap.end(); it++)
00510 {
00511 if (!strcmp((*it).second->getName(), name))
00512 num = (*it).second->getCommand();
00513 }
00514 if (num == 0)
00515 {
00516 ArLog::log(ArLog::Verbose, "ArServerBase::findCommandFromName: no command by name of \"%s\"", name);
00517 myDataMutex.unlock();
00518 return 0;
00519 }
00520 myDataMutex.unlock();
00521 return num;
00522 }
00523
00531 AREXPORT void ArServerBase::loopOnce(void)
00532 {
00533 std::list<ArServerClient *>::iterator it;
00534
00535
00536 std::list<ArServerClient *> removeList;
00537 ArServerClient *client;
00538
00539 myDataMutex.lock();
00540 if (!myOpened)
00541 {
00542 myDataMutex.unlock();
00543 return;
00544 }
00545 myDataMutex.unlock();
00546 acceptTcpSockets();
00547
00548 myUdpReceiver.readData();
00549
00550
00551
00552
00553 for (it = myClients.begin(); it != myClients.end(); ++it)
00554 {
00555 client = (*it);
00556 if (!client->tcpCallback())
00557 {
00558 removeList.push_front(client);
00559 }
00560 }
00561 while ((it = removeList.begin()) != removeList.end())
00562 {
00563 client = (*it);
00564 myClients.remove(client);
00565 for (std::list<ArFunctor1<ArServerClient*> *>::iterator rci = myClientRemovedCallbacks.begin();
00566 rci != myClientRemovedCallbacks.end();
00567 rci++) {
00568 if (*rci) {
00569 (*rci)->invoke(client);
00570 }
00571 }
00572
00573 delete client;
00574 removeList.pop_front();
00575 }
00576
00577 for (it = myClients.begin(); it != myClients.end(); ++it)
00578 {
00579 client = (*it);
00580 client->handleRequests();
00581 }
00582
00583
00584
00585 myCycleCallbacksMutex.lock();
00586
00587 for(std::list<ArFunctor*>::const_iterator f = myCycleCallbacks.begin();
00588 f != myCycleCallbacks.end(); f++)
00589 {
00590 if(*f) (*f)->invoke();
00591 }
00592 myCycleCallbacksMutex.unlock();
00593 }
00594
00595 AREXPORT void ArServerBase::processPacket(ArNetPacket *packet, struct sockaddr_in *sin)
00596 {
00597 std::list<ArServerClient *>::iterator it;
00598 unsigned char *bytes = (unsigned char *)&sin->sin_addr.s_addr;
00599 ArServerClient *client;
00600 struct sockaddr_in *clientSin;
00601
00602 myClientsMutex.lock();
00603
00604 if (packet->getCommand() == ArClientCommands::UDP_INTRODUCTION)
00605 {
00606 long authKey;
00607 bool matched;
00608
00609 authKey = packet->bufToUByte4();
00610 for (matched = false, it = myClients.begin();
00611 !matched && it != myClients.end(); ++it)
00612 {
00613 client = (*it);
00614 if (client->getAuthKey() == authKey)
00615 {
00616 packet->resetRead();
00617 client->processAuthPacket(packet, sin);
00618 }
00619 }
00620 myClientsMutex.unlock();
00621 return;
00622 }
00623
00624
00625
00626
00627
00628 for (it = myClients.begin(); it != myClients.end(); ++it)
00629 {
00630 client = (*it);
00631 clientSin = client->getUdpAddress();
00632 if (clientSin->sin_port == sin->sin_port &&
00633 clientSin->sin_addr.s_addr == sin->sin_addr.s_addr)
00634 {
00635 client->processPacket(packet, false);
00636 myClientsMutex.unlock();
00637 return;
00638 }
00639 }
00640
00641 printf("UDP Packet from bogus source %d.%d.%d.%d %d\n", bytes[0],
00642 bytes[1], bytes[2], bytes[3],
00643 ArSocket::netToHostOrder(sin->sin_port));
00644 myClientsMutex.unlock();
00645 }
00646
00647 AREXPORT bool ArServerBase::sendUdp(ArNetPacket *packet, struct sockaddr_in *sin)
00648 {
00649 bool ret;
00650
00651 ret = myUdpSocket.sendTo(packet->getBuf(), packet->getLength(), sin);
00652 return ret;
00653 }
00654
00679 AREXPORT bool ArServerBase::addData(
00680 const char *name, const char *description,
00681 ArFunctor2<ArServerClient *, ArNetPacket *> * functor,
00682 const char *argumentDescription, const char *returnDescription,
00683 const char *commandGroup, const char *dataFlags)
00684 {
00685 return addDataAdvanced(name, description, functor, argumentDescription,
00686 returnDescription, commandGroup, dataFlags);
00687 }
00688
00713 AREXPORT bool ArServerBase::addDataAdvanced(
00714 const char *name, const char *description,
00715 ArFunctor2<ArServerClient *, ArNetPacket *> * functor,
00716 const char *argumentDescription, const char *returnDescription,
00717 const char *commandGroup, const char *dataFlags,
00718 unsigned int advancedCommandNumber,
00719 ArFunctor2<long, unsigned int> *requestChangedFunctor,
00720 ArFunctor2<ArServerClient *, ArNetPacket *> *requestOnceFunctor)
00721 {
00722 ArServerData *serverData;
00723 std::map<unsigned int, ArServerData *>::iterator it;
00724
00725 myDataMutex.lock();
00726
00727
00728
00729 for (it = myDataMap.begin(); it != myDataMap.end(); it++)
00730 {
00731 if (!strcmp((*it).second->getName(), name))
00732 {
00733 ArLog::log(ArLog::Verbose, "ArServerBase::addData: already have data for name \"%s\", could not add it.", name);
00734 myDataMutex.unlock();
00735 return false;
00736 }
00737 }
00738 ArLog::log(ArLog::Verbose, "ArServerBase::addData: name \"%s\" mapped to number %d", name, myNextDataNumber);
00739 if (advancedCommandNumber != 0)
00740 {
00741 if (advancedCommandNumber < myNextDataNumber)
00742 {
00743 ArLog::log(ArLog::Normal, "ArServerBase::addData: Advanced command number given for %s but the number is too low, it wasn't added", name);
00744 myDataMutex.unlock();
00745 return false;
00746 }
00747 else
00748 myNextDataNumber = advancedCommandNumber;
00749 }
00750 serverData = new ArServerData(name, description, myNextDataNumber,
00751 functor, argumentDescription,
00752 returnDescription, commandGroup, dataFlags,
00753 &myGetFrequencyCB, requestChangedFunctor,
00754 requestOnceFunctor);
00755 if (myAdditionalDataFlags.size() > 0)
00756 serverData->addDataFlags(myAdditionalDataFlags.c_str());
00757 myDataMap[myNextDataNumber] = serverData;
00758 myNextDataNumber++;
00759 myDataMutex.unlock();
00760 return true;
00761 }
00762
00763
00767 AREXPORT void ArServerBase::addCycleCallback(ArFunctor* functor)
00768 {
00769 myCycleCallbacksMutex.lock();
00770 myCycleCallbacks.push_back(functor);
00771 myCycleCallbacksMutex.unlock();
00772 }
00773
00778 AREXPORT void ArServerBase::remCycleCallback(ArFunctor* functor)
00779 {
00780 myCycleCallbacksMutex.lock();
00781 myCycleCallbacks.remove(functor);
00782 myCycleCallbacksMutex.unlock();
00783 }
00784
00789 AREXPORT void ArServerBase::addClientRemovedCallback(ArFunctor1<ArServerClient *> *functor)
00790 {
00791 myDataMutex.lock();
00792 myClientRemovedCallbacks.push_back(functor);
00793 myDataMutex.unlock();
00794 }
00795
00800 AREXPORT void ArServerBase::remClientRemovedCallback(ArFunctor1<ArServerClient *> *functor)
00801 {
00802 myDataMutex.lock();
00803 myClientRemovedCallbacks.remove(functor);
00804 myDataMutex.unlock();
00805 }
00806
00807
00808 AREXPORT bool ArServerBase::loadUserInfo(const char *fileName,
00809 const char *baseDirectory)
00810 {
00811 if (myUserInfo != NULL)
00812 {
00813 delete myUserInfo;
00814 myUserInfo = NULL;
00815 }
00816 ArServerUserInfo *userInfo = new ArServerUserInfo;
00817 userInfo->setBaseDirectory(baseDirectory);
00818 if (!userInfo->readFile(fileName))
00819 {
00820 ArLog::log(ArLog::Terse, "ArServerBase::loadUserInfo: Could not load user info for %s", myServerName.c_str());
00821 delete userInfo;
00822 return false;
00823 }
00824 if (!userInfo->doNotUse())
00825 {
00826 ArLog::log(ArLog::Normal, "Loaded user information for %s",
00827 myServerName.c_str());
00828 myDataMutex.lock();
00829 myUserInfo = userInfo;
00830 myDataMutex.unlock();
00831 }
00832 else
00833 {
00834 ArLog::log(ArLog::Normal,
00835 "Loaded user information for %s but not using it",
00836 myServerName.c_str());
00837 delete userInfo;
00838 }
00839 return true;
00840 }
00841
00842 AREXPORT void ArServerBase::logUserInfo(void)
00843 {
00844 myDataMutex.lock();
00845 if (myUserInfo == NULL)
00846 ArLog::log(ArLog::Terse,
00847 "No user name or password needed to connect to %s",
00848 myServerName.c_str());
00849 else
00850 myUserInfo->logUsers();
00851 myDataMutex.unlock();
00852 }
00853
00859 AREXPORT void ArServerBase::logCommandGroups(void)
00860 {
00861 logCommandGroupsToFile(NULL);
00862 }
00863
00867 AREXPORT void ArServerBase::logCommandGroupsToFile(const char *fileName)
00868 {
00869 std::map<unsigned int, ArServerData *>::iterator dit;
00870
00871 std::multimap<std::string, std::string> groups;
00872 std::multimap<std::string, std::string>::iterator git;
00873
00874 myDataMutex.lock();
00875 for (dit = myDataMap.begin(); dit != myDataMap.end(); dit++)
00876 {
00877 std::string group;
00878 std::string command;
00879 command = (*dit).second->getName();
00880 if ((*dit).second->getCommandGroup() == NULL)
00881 group = "";
00882 else
00883 group = (*dit).second->getCommandGroup();
00884
00885 groups.insert(std::pair<std::string, std::string>(group, command));
00886 }
00887
00888 FILE *file = NULL;
00889 if (fileName != NULL)
00890 {
00891 file = fopen(fileName, "w");
00892 }
00893
00894 char descLine[10000];
00895 std::string line;
00896 std::string lastGroup;
00897 bool first = true;
00898 bool firstGroup = true;
00899 std::map<std::string, std::string>::iterator dIt;
00900 std::string listOfGroups = "Groups";
00901
00902 for (git = groups.begin(); git != groups.end(); git++)
00903 {
00904 if (ArUtil::strcasecmp((*git).first, lastGroup) != 0 || firstGroup)
00905 {
00906 if (!firstGroup)
00907 {
00908 if (file != NULL)
00909 fprintf(file, "%s", line.c_str());
00910 else
00911 ArLog::log(ArLog::Terse, "%s", line.c_str());
00912 }
00913 first = true;
00914 firstGroup = false;
00915 lastGroup = (*git).first;
00916 listOfGroups += " ";
00917 if (lastGroup.size() == 0)
00918 listOfGroups += "None";
00919 else
00920 listOfGroups += lastGroup;
00921 }
00922 if (first)
00923 {
00924 line = "CommandGroup ";
00925 if ((*git).first.size() == 0)
00926 {
00927 line += "None";
00928 }
00929 else
00930 {
00931
00932 if ((dIt = myGroupDescription.find((*git).first)) !=
00933 myGroupDescription.end())
00934 snprintf(descLine, sizeof(descLine),
00935 "CommandGroup %s has description %s",
00936 (*git).first.c_str(), (*dIt).second.c_str());
00937 else
00938 snprintf(descLine, sizeof(descLine),
00939 "CommandGroup %s has no description",
00940 (*git).first.c_str());
00941 if (file != NULL)
00942 fprintf(file, "%s\n", descLine);
00943 else
00944 ArLog::log(ArLog::Terse, "%s", descLine);
00945
00946 line += (*git).first.c_str();
00947 }
00948 line += " is";
00949
00950
00951 }
00952 line += " ";
00953 line += (*git).second.c_str();
00954 first = false;
00955 }
00956 if (!firstGroup && !first)
00957 {
00958 if (file != NULL)
00959 fprintf(file, "%s\n", line.c_str());
00960 else
00961 ArLog::log(ArLog::Terse, "%s", line.c_str());
00962 }
00963 if (file != NULL)
00964 fprintf(file, "%s\n", listOfGroups.c_str());
00965 else
00966 ArLog::log(ArLog::Terse, "%s", listOfGroups.c_str());
00967 myDataMutex.unlock();
00968 }
00969
00970
00984 AREXPORT void ArServerBase::setGroupDescription(const char *cmdGrpName, const char *cmdGrpDesc)
00985 {
00986 myDataMutex.lock();
00987 myGroupDescription.insert(std::pair<std::string, std::string>(cmdGrpName, cmdGrpDesc));
00988 myDataMutex.unlock();
00989 }
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004 AREXPORT void ArServerBase::logGroupDescriptions(void)
01005 {
01006
01007
01008
01009 logGroupDescriptionsToFile(NULL);
01010 }
01011
01012 AREXPORT void ArServerBase::logGroupDescriptionsToFile(const char *fileName)
01013 {
01014 myDataMutex.lock();
01015 std::map<std::string, std::string>::iterator d_itr;
01016 char line[1024];
01017 FILE *file = NULL;
01018 if (fileName != NULL)
01019 file = fopen(fileName, "w");
01020
01021
01022 for (d_itr = myGroupDescription.begin(); d_itr != myGroupDescription.end(); d_itr++)
01023 {
01024 snprintf(line, sizeof(line), "%-29s %s", (*d_itr).first.c_str(), (*d_itr).second.c_str());
01025
01026 if (file != NULL)
01027 fprintf(file, "%s\n", line);
01028 else
01029 ArLog::log(ArLog::Terse, "%s", line);
01030 }
01031 if (fileName != NULL)
01032 fclose (file);
01033 myDataMutex.unlock();
01034 }
01035
01036
01037
01043 AREXPORT void ArServerBase::setServerKey(const char *serverKey)
01044 {
01045 myDataMutex.lock();
01046
01047
01048 if ((serverKey == NULL || serverKey[0] == '\0') && myServerKey.size() > 0)
01049 ArLog::log(ArLog::Normal, "Clearing server key");
01050 if (serverKey != NULL && serverKey[0] != '\0')
01051 ArLog::log(ArLog::Normal, "Setting new server key");
01052 if (serverKey != NULL)
01053 myServerKey = serverKey;
01054 else
01055 myServerKey = "";
01056 myDataMutex.unlock();
01057 }
01058
01059 AREXPORT void ArServerBase::rejectSinceUsingCentralServer(
01060 const char *centralServerIPString)
01061 {
01062 myDataMutex.lock();
01063 myRejecting = 2;
01064 myRejectingString = centralServerIPString;
01065 myDataMutex.unlock();
01066 }
01067
01068 AREXPORT void ArServerBase::logTracking(bool terse)
01069 {
01070 std::list<ArServerClient *>::iterator lit;
01071
01072 myClientsMutex.lock();
01073
01074 for (lit = myClients.begin(); lit != myClients.end(); ++lit)
01075 (*lit)->logTracking(terse);
01076
01077 ArLog::log(ArLog::Terse, "");
01078
01079 if (!terse)
01080 {
01081 ArLog::log(ArLog::Terse, "%-85s %7ld udp rcvs %10ld udp B",
01082 "Low Level UDP Received (all conns)", myUdpSocket.getRecvs(),
01083 myUdpSocket.getBytesRecvd());
01084 ArLog::log(ArLog::Terse, "%-85s %7ld udp snds %10ld udp B",
01085 "Low Level UDP Sent (all conns)", myUdpSocket.getSends(),
01086 myUdpSocket.getBytesSent());
01087
01088 ArLog::log(ArLog::Terse, "");
01089 }
01090 myClientsMutex.unlock();
01091 }
01092
01093 AREXPORT void ArServerBase::resetTracking(void)
01094 {
01095 std::list<ArServerClient *>::iterator lit;
01096
01097 myClientsMutex.lock();
01098
01099 for (lit = myClients.begin(); lit != myClients.end(); ++lit)
01100 (*lit)->resetTracking();
01101 myClientsMutex.unlock();
01102 myDataMutex.lock();
01103 myUdpSocket.resetTracking();
01104 myDataMutex.unlock();
01105 }
01106
01107 AREXPORT const ArServerUserInfo* ArServerBase::getUserInfo(void) const
01108 {
01109 return myUserInfo;
01110 }
01111
01112 AREXPORT void ArServerBase::setUserInfo(const ArServerUserInfo *userInfo)
01113 {
01114 myDataMutex.lock();
01115 myUserInfo = userInfo;
01116 myDataMutex.unlock();
01117 }
01130 AREXPORT long ArServerBase::getFrequency(unsigned int command,
01131 bool internalCall)
01132 {
01133 std::list<ArServerClient *>::iterator it;
01134 long ret = -2;
01135 long clientFreq;
01136
01137 if (!internalCall)
01138 myClientsMutex.lock();
01139
01140 for (it = myClients.begin(); it != myClients.end(); it++)
01141 {
01142 clientFreq = (*it)->getFrequency(command);
01143
01144
01145 if (clientFreq >= 0 && (ret < 0 || (ret >= 0 && clientFreq < ret)))
01146 ret = clientFreq;
01147
01148
01149 else if (clientFreq == -1 && ret == -2)
01150 ret = -1;
01151 }
01152
01153 if (!internalCall)
01154 myClientsMutex.unlock();
01155
01156 return ret;
01157 }
01158
01164 AREXPORT void ArServerBase::setAdditionalDataFlags(
01165 const char *additionalDataFlags)
01166 {
01167 myDataMutex.lock();
01168 if (additionalDataFlags == NULL || additionalDataFlags[0] == '\0')
01169 myAdditionalDataFlags = "";
01170 else
01171 myAdditionalDataFlags = additionalDataFlags;
01172 myDataMutex.unlock();
01173 }
01174
01175
01176 AREXPORT bool ArServerBase::dataHasFlag(const char *name,
01177 const char *dataFlag)
01178 {
01179 unsigned int command;
01180 if ((command = findCommandFromName(name)) == 0)
01181 {
01182 ArLog::log(ArLog::Verbose,
01183 "ArServerBase::dataHasFlag: %s is not data that is on the server",
01184 name);
01185 return false;
01186 }
01187
01188 return dataHasFlagByCommand(findCommandFromName(name), dataFlag);
01189 }
01190
01191 AREXPORT bool ArServerBase::dataHasFlagByCommand(unsigned int command,
01192 const char *dataFlag)
01193 {
01194 std::map<unsigned int, ArServerData *>::iterator dIt;
01195 bool ret;
01196
01197 myDataMutex.lock();
01198 if ((dIt = myDataMap.find(command)) == myDataMap.end())
01199 ret = false;
01200 else
01201 ret = (*dIt).second->hasDataFlag(dataFlag);
01202 myDataMutex.unlock();
01203
01204 return ret;
01205 }
01206
01207 AREXPORT unsigned int ArServerBase::getTcpPort(void)
01208 {
01209 return myTcpPort;
01210 }
01211
01212 AREXPORT unsigned int ArServerBase::getUdpPort(void)
01213 {
01214 return myUdpPort;
01215 }