00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <stdio.h>
00013 #include <stdlib.h>
00014 #include <assert.h>
00015
00016 #include "xmlServer.h"
00017
00018
00019
00020 #if 1
00021 #define THREADRETURN
00022 #define THREADTYPE void
00023 #endif
00024 #if defined( OS_WINNT )
00025 #define THREADRETURN 0
00026 #define THREADTYPE DWORD WINAPI
00027 #endif
00028 #ifndef THREADTYPE
00029 #define THREADTYPE int
00030 #define THREADRETURN 0
00031 #endif
00032
00033 #include <TROOT.h>
00034 #include <TClass.h>
00035 #include <TDirectory.h>
00036 #include <TKey.h>
00037 #include <TFolder.h>
00038 #include <TSocket.h>
00039 #include <TServerSocket.h>
00040 #include <TThread.h>
00041 #include <TMessage.h>
00042 #include <TObjString.h>
00043 #include <TH1.h>
00044 #include <TCutG.h>
00045 #include <TBufferXML.h>
00046
00047 #include <deque>
00048 #include <map>
00049 #include <string>
00050
00051 class XLockRootGuard
00052 {
00053 public:
00054 bool fIsLocked;
00055
00056 XLockRootGuard()
00057 {
00058 TThread::Lock();
00059 fIsLocked = true;
00060 }
00061
00062 ~XLockRootGuard()
00063 {
00064 if (fIsLocked)
00065 Unlock();
00066 }
00067
00068 void Unlock()
00069 {
00070 fIsLocked = false;
00071 TThread::UnLock();
00072 };
00073 };
00074
00075 static bool gVerbose = false;
00076
00077 static std::deque<std::string> gExports;
00078 static std::map<std::string,std::string> gExportNames;
00079
00080
00081
00082 static std::string HtmlEncode(const char* s)
00083 {
00084 std::string r;
00085 while (*s) {
00086 char c = *s;
00087 if (c == '<') {
00088 r += "<";
00089 } else if (c == '>') {
00090 r += ">";
00091 } else if (c == '&') {
00092 r += "&";
00093 } else {
00094 r += c;
00095 }
00096 s++;
00097 }
00098 return r;
00099 }
00100
00101 static std::string UrlEncode(const char* s)
00102 {
00103 std::string r;
00104 while (*s) {
00105 char c = *s;
00106 if (isalpha(c)) {
00107 r += c;
00108 } else if (isdigit(c)) {
00109 r += c;
00110 } else {
00111 char buf[16];
00112 sprintf(buf, "%%%02x", c);
00113 r += buf;
00114 }
00115 s++;
00116 }
00117 return r;
00118 }
00119
00120 static int atohex(int a)
00121 {
00122 if (a>='0' && a<='9')
00123 return a-'0';
00124 if (a>='a' && a<='f')
00125 return a-'a'+10;
00126 if (a>='A' && a<='F')
00127 return a-'A'+10;
00128 return 0;
00129 }
00130
00131 static std::string HtmlDecode(const char* s)
00132 {
00133 std::string r;
00134 while (*s) {
00135 if (*s == '%') {
00136 s++;
00137 char c = 0;
00138 c = c*16 + atohex(s[0]);
00139 c = c*16 + atohex(s[1]);
00140 r += c;
00141
00142
00143 if (*s)
00144 s++;
00145 if (*s)
00146 s++;
00147 } else {
00148 r += *s++;
00149 }
00150 }
00151 return r;
00152 }
00153
00154
00155
00156 static TObject* FollowPath(TObject* container, char* path)
00157 {
00158 if (0)
00159 printf("Follow path [%s] in container %p\n", path, container);
00160
00161 while (1)
00162 {
00163 while (*path == '/')
00164 path++;
00165
00166 char* s = strchr(path,'/');
00167
00168 if (s)
00169 *s = 0;
00170
00171 TObject *obj = NULL;
00172
00173 std::string xpath = HtmlDecode(path);
00174
00175
00176 if (container->InheritsFrom(TDirectory::Class()))
00177 obj = ((TDirectory*)container)->FindObject(xpath.c_str());
00178 else if (container->InheritsFrom(TFolder::Class()))
00179 obj = ((TFolder*)container)->FindObject(xpath.c_str());
00180 else if (container->InheritsFrom(TCollection::Class()))
00181 obj = ((TCollection*)container)->FindObject(xpath.c_str());
00182 else
00183 {
00184 fprintf(stderr, "XmlServer: ERROR: Container \'%s\' of type %s is not a TDirectory, TFolder or TCollection\n", container->GetName(), container->IsA()->GetName());
00185 return NULL;
00186 }
00187
00188 if (!obj)
00189 return NULL;
00190
00191 if (!s)
00192 return obj;
00193
00194 container = obj;
00195
00196 path = s+1;
00197 }
00198
00199 }
00200
00201 static TObject* FindTopLevelObject(const char* name)
00202 {
00203 TObject *obj = NULL;
00204
00205 obj = gROOT->GetListOfFiles()->FindObject(name);
00206 if (obj)
00207 return obj;
00208 obj = gROOT->FindObjectAny(name);
00209 if (obj)
00210 return obj;
00211 return NULL;
00212 }
00213
00214 static TObject* TopLevel(char* path, char**opath)
00215 {
00216 if (0)
00217 printf("Extract top level object from [%s]\n", path);
00218
00219 while (*path == '/')
00220 path++;
00221
00222 char* s = strchr(path,'/');
00223
00224 if (s)
00225 {
00226 *s = 0;
00227 *opath = s+1;
00228 }
00229 else
00230 {
00231 *opath = NULL;
00232 }
00233
00234 std::string xpath = HtmlDecode(path);
00235
00236 TObject *obj = NULL;
00237
00238 for (unsigned int i=0; i<gExports.size(); i++)
00239 {
00240 const char* ename = gExports[i].c_str();
00241
00242 if (strcmp(xpath.c_str(), ename) == 0)
00243 {
00244 const char* xname = gExportNames[ename].c_str();
00245 obj = FindTopLevelObject(xname);
00246
00247 break;
00248 }
00249 }
00250
00251 if (!obj)
00252 {
00253 fprintf(stderr, "XmlServer: ERROR: Top level object \'%s\' not found in exports list\n", xpath.c_str());
00254 return NULL;
00255 }
00256
00257 return obj;
00258 }
00259
00260 static TObject* FollowPath(char* path)
00261 {
00262 if (0)
00263 printf("Follow path [%s]\n", path);
00264
00265 char *s;
00266 TObject *obj = TopLevel(path, &s);
00267
00268 if (!obj)
00269 return NULL;
00270
00271 if (!s)
00272 return obj;
00273
00274 return FollowPath(obj, s);
00275 }
00276
00277
00278
00279 static void ResetObject(TObject* obj)
00280 {
00281 assert(obj!=NULL);
00282
00283 if (gVerbose)
00284 printf("ResetObject object %p name [%s] type [%s]\n", obj, obj->GetName(), obj->IsA()->GetName());
00285
00286 if (obj->InheritsFrom(TH1::Class()))
00287 {
00288 ((TH1*)obj)->Reset();
00289 }
00290 else if (obj->InheritsFrom(TDirectory::Class()))
00291 {
00292 TDirectory* dir = (TDirectory*)obj;
00293 TList* objs = dir->GetList();
00294
00295 TIter next = objs;
00296 while(1)
00297 {
00298 TObject *obj = next();
00299 if (obj == NULL)
00300 break;
00301 ResetObject(obj);
00302 }
00303 }
00304 }
00305
00306
00307
00308 static void SendString(TSocket* sock, const char* str)
00309 {
00310 sock->SendRaw(str, strlen(str));
00311 }
00312
00313 static void SendHttpReply(TSocket* sock, const char* mimetype, const char* message)
00314 {
00315 char buf[256];
00316 int len = strlen(message);
00317 SendString(sock, "HTTP/1.1 200 OK\n");
00318
00319 SendString(sock, "Server: ROOTANA xmlServer\n");
00320 sprintf(buf, "Content-Length: %d\n", len);
00321 SendString(sock, buf);
00322
00323 sprintf(buf, "Content-Type: %s\n", mimetype);
00324 SendString(sock, buf);
00325
00326 SendString(sock, "\n");
00327 SendString(sock, message);
00328 printf("XmlServer: Reply content-length %d, content-type %s\n", len, mimetype);
00329 }
00330
00331 static void SendHttpReply(TSocket* sock, const char* mimetype, const std::string& str)
00332 {
00333 SendHttpReply(sock, mimetype, str.c_str());
00334 }
00335
00336
00337
00338 static std::string HtmlTag(const char* tag, const char* contents)
00339 {
00340 std::string s;
00341 s += "<";
00342 s += tag;
00343 s += ">";
00344 s += contents;
00345 s += "</";
00346 s += tag;
00347 s += ">";
00348 return s;
00349 }
00350
00351 static std::string HtmlTag(const char* tag, const std::string& contents)
00352 {
00353 std::string s;
00354 s += "<";
00355 s += tag;
00356 s += ">";
00357 s += contents;
00358 s += "</";
00359 s += tag;
00360 s += ">";
00361 return s;
00362 }
00363
00364
00365
00366 std::string MakeXmlEntry(const TObject* obj)
00367 {
00368 const char* objname = obj->GetName();
00369 const char* classname = obj->ClassName();
00370 bool isSubdir = false;
00371 std::string xkey = "";
00372
00373 if (obj->InheritsFrom(TKey::Class())) {
00374 TKey* key = (TKey*)obj;
00375 classname = key->GetClassName();
00376 xkey = "<key/>";
00377 }
00378
00379 const TClass *xclass = TClass::GetClass(classname);
00380
00381 if (xclass->InheritsFrom(TDirectory::Class()))
00382 isSubdir = true;
00383
00384 if (xclass->InheritsFrom(TFolder::Class()))
00385 isSubdir = true;
00386
00387 if (xclass->InheritsFrom(TCollection::Class()))
00388 isSubdir = true;
00389
00390
00391
00392 if (isSubdir)
00393 return HtmlTag("subdir", HtmlTag("name", HtmlEncode(objname)) + HtmlTag("class", HtmlEncode(classname)) + xkey) + "\n";
00394 else
00395 return HtmlTag("object", HtmlTag("name", HtmlEncode(objname)) + HtmlTag("class", HtmlEncode(classname)) + xkey) + "\n";
00396 }
00397
00398 std::string MakeHtmlEntry(const TObject* obj, const char* path)
00399 {
00400 const char* objname = obj->GetName();
00401 const char* classname = obj->ClassName();
00402 bool isKey = false;
00403
00404 if (obj->InheritsFrom(TKey::Class())) {
00405 TKey* key = (TKey*)obj;
00406 classname = key->GetClassName();
00407 isKey = true;
00408 }
00409
00410 std::string s;
00411
00412 s += "<a href=\"";
00413 s += path;
00414 s += "/";
00415 s += UrlEncode(objname);
00416 s += "\">";
00417 s += objname;
00418 s += "</a>\n";
00419 s += " (";
00420 s += classname;
00421 s += ")";
00422 if (isKey)
00423 s += "-KEY";
00424 s += " ";
00425 s += "<a href=\"";
00426 s += path;
00427 s += "/";
00428 s += UrlEncode(objname);
00429 s += ".xml";
00430 s += "\">";
00431 s += "XML</a>\n";
00432
00433 return s;
00434 }
00435
00436
00437
00438 static void SendFile(TSocket* sock, const char* filename, const char* mimetype)
00439 {
00440 std::string f = filename;
00441 std::string reply;
00442 FILE *fp = fopen(f.c_str(), "r");
00443 if (!fp) {
00444 std::string home = getenv("HOME");
00445 f = home + "/packages/rootana/libXmlServer/" + filename;
00446 fp = fopen(f.c_str(), "r");
00447 }
00448 printf("sending file %s, fp %p\n", f.c_str(), fp);
00449 if (fp) {
00450 while (1) {
00451 char buf[1024+1];
00452 int rd = fread(buf, 1, sizeof(buf)-1, fp);
00453 if (rd <= 0)
00454 break;
00455 buf[rd] = 0;
00456 reply += buf;
00457 }
00458 fclose(fp);
00459 }
00460 SendHttpReply(sock, mimetype, reply);
00461 }
00462
00463
00464
00465 static THREADTYPE xroot_server_thread(void *arg)
00466
00467
00468
00469 {
00470 char request[2560];
00471
00472 TSocket *sock = (TSocket *) arg;
00473
00474
00475 do {
00476
00477
00478 int rd = sock->RecvRaw(request, sizeof(request), kDontBlock);
00479 if (rd <= 0)
00480 {
00481 if (gVerbose)
00482 fprintf(stderr, "XmlServer: connection from %s closed\n", sock->GetInetAddress().GetHostName());
00483 sock->Close();
00484 delete sock;
00485 return THREADRETURN;
00486 }
00487
00488 if (1) {
00489 char *p;
00490 p = strchr(request, '\n');
00491 if (p)
00492 *p = 0;
00493
00494 p = strchr(request, '\r');
00495 if (p)
00496 *p = 0;
00497 }
00498
00499 if (gVerbose)
00500 printf("XmlServer: Request [%s] from %s\n", request, sock->GetInetAddress().GetHostName());
00501
00502 if (0) {}
00503 else if (strstr(request, "GET / "))
00504 {
00505
00506
00507 XLockRootGuard lock;
00508
00509 std::string reply;
00510
00511 reply += "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n";
00512 reply += HtmlTag("title", "Export list") + "\n";
00513 reply += "</head><body>\n";
00514 reply += HtmlTag("h1", "Export list") + "\n";
00515
00516 for (unsigned int i=0; i<gExports.size(); i++) {
00517 const char* ename = gExports[i].c_str();
00518 const char* xname = gExportNames[ename].c_str();
00519
00520 TObject* obj = FindTopLevelObject(xname);
00521
00522 if (obj) {
00523 std::string s;
00524 s += " ";
00525 s += "<a href=\"";
00526 s += UrlEncode(ename);
00527 s += "\">";
00528 s += ename;
00529 s += "</a>\n";
00530 s += "<a href=\"";
00531 s += UrlEncode(ename);
00532 s += ".xml";
00533 s += "\">";
00534 s += "XML</a>\n";
00535 reply += HtmlTag("p", s) + "\n";
00536 } else {
00537 std::string s;
00538 s += ename;
00539 s += " (cannot be found. maybe deleted?)\n";
00540 reply += HtmlTag("p", s) + "\n";
00541 }
00542 }
00543
00544 lock.Unlock();
00545
00546 reply += "</body></html>\n";
00547 SendHttpReply(sock, "text/html", reply);
00548 }
00549
00550
00551
00552
00553 else if (strstr(request, "js/jquery.min.js "))
00554 {
00555 SendFile(sock, "jquery.min.js", "text/javascript");
00556 }
00557 else if (strstr(request, "js/highcharts.js "))
00558 {
00559 SendFile(sock, "highcharts.js", "text/javascript");
00560 }
00561 else if (strstr(request, "js/exporting.js "))
00562 {
00563 SendFile(sock, "exporting.js", "text/javascript");
00564 }
00565 else if (strstr(request, "GET /favicon.ico "))
00566 {
00567 std::string reply;
00568
00569 reply += "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n";
00570 reply += HtmlTag("title", "No favicon") + "\n";
00571 reply += "</head><body>\n";
00572 reply += HtmlTag("h1", "No favicon") + "\n";
00573 reply += HtmlTag("p", "No favicon") + "\n";
00574 reply += "</body></html>\n";
00575 SendHttpReply(sock, "text/html", reply);
00576 }
00577 else if (strstr(request, "GET /index.xml "))
00578 {
00579
00580
00581 XLockRootGuard lock;
00582
00583 std::string xml;
00584
00585 xml += "<xml>\n";
00586 xml += "<dir>\n";
00587
00588 for (unsigned int i=0; i<gExports.size(); i++)
00589 {
00590 const char* ename = gExports[i].c_str();
00591 const char* xname = gExportNames[ename].c_str();
00592
00593 TObject* obj = FindTopLevelObject(xname);
00594
00595 if (!obj) {
00596 xml += HtmlTag("subdir", HtmlTag("name", HtmlEncode(ename)) + "<deleted/>") + "\n";
00597 continue;
00598 }
00599
00600 const char* cname = obj->ClassName();
00601
00602 xml += HtmlTag("subdir", HtmlTag("name", HtmlEncode(ename)) + HtmlTag("class", HtmlEncode(cname))) + "\n";
00603 }
00604
00605 lock.Unlock();
00606
00607 xml += "</dir>\n";
00608 xml += "</xml>\n";
00609
00610 SendHttpReply(sock, "application/xml", xml);
00611 }
00612 else if (strncmp(request, "GET /", 5) == 0)
00613 {
00614 XLockRootGuard lock;
00615
00616 char* dirname = request + 5;
00617
00618 char* x = strstr(dirname, " HTTP");
00619 if (x)
00620 *x = 0;
00621
00622 bool xmlOutput = false;
00623
00624 x = strstr(dirname, ".xml");
00625 if (x) {
00626 *x = 0;
00627 xmlOutput = true;
00628 }
00629
00630 std::string path;
00631 path += "/";
00632 path += dirname;
00633
00634 std::string xpath = HtmlDecode(dirname);
00635
00636
00637
00638 TObject* obj = FollowPath(dirname);
00639
00640 if (!obj) {
00641 std::string reply;
00642 std::string buf;
00643
00644 reply += "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n";
00645
00646 buf = "Not found ";
00647 buf += xpath;
00648 reply += HtmlTag("title", buf) + "\n";
00649 reply += "</head><body>\n";
00650 reply += HtmlTag("h1", buf) + "\n";
00651
00652 reply += HtmlTag("p", "Object not found");
00653
00654 reply += "</body></html>\n";
00655 SendHttpReply(sock, "text/html", reply);
00656
00657 } else if (obj && obj->InheritsFrom(TDirectory::Class())) {
00658 TDirectory* dir = (TDirectory*)obj;
00659
00660 std::string reply;
00661 std::string buf;
00662 std::string xml;
00663
00664 xml += "<xml>\n";
00665 xml += "<dir>\n";
00666
00667 reply += "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n";
00668
00669 buf = "Dir ";
00670 buf += xpath;
00671 reply += HtmlTag("title", buf) + "\n";
00672 reply += "</head><body>\n";
00673 reply += HtmlTag("h1", buf) + "\n";
00674
00675
00676
00677
00678 std::map<std::string, std::string> alist;
00679
00680 if (1) {
00681 TList* keys = dir->GetListOfKeys();
00682
00683
00684
00685
00686 TIter next = keys;
00687 while(1) {
00688 TObject *obj = next();
00689
00690
00691
00692 if (obj == NULL)
00693 break;
00694
00695 std::string a = HtmlTag("p", MakeHtmlEntry(obj, path.c_str())) + "\n";
00696
00697 reply += a;
00698
00699 xml += MakeXmlEntry(obj);
00700 }
00701 }
00702
00703 if (1) {
00704 TList* objs = dir->GetList();
00705
00706
00707
00708
00709 TIter next = objs;
00710 while(1)
00711 {
00712 TObject *obj = next();
00713
00714
00715
00716 if (obj == NULL)
00717 break;
00718
00719 std::string a = HtmlTag("p", MakeHtmlEntry(obj, path.c_str())) + "\n";
00720
00721 reply += a;
00722
00723 xml += MakeXmlEntry(obj);
00724 }
00725 }
00726
00727 lock.Unlock();
00728
00729 if (1) {
00730 std::map<std::string, std::string>::iterator iter = alist.begin();
00731 for (; iter!=alist.end(); iter++) {
00732
00733
00734 reply += iter->second;
00735 }
00736 }
00737
00738 reply += "</body></html>\n";
00739
00740 xml += "</dir></xml>\n";
00741
00742 if (xmlOutput)
00743 SendHttpReply(sock, "application/xml", xml);
00744 else
00745 SendHttpReply(sock, "text/html", reply);
00746
00747 } else if (obj && obj->InheritsFrom(TFolder::Class())) {
00748 TFolder* folder = (TFolder*)obj;
00749
00750
00751
00752
00753 std::string xml;
00754
00755 xml += "<xml>\n";
00756 xml += "<dir>\n";
00757
00758 std::string reply;
00759 std::string buf;
00760
00761 reply += "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n";
00762
00763 buf = "Folder ";
00764 buf += xpath;
00765 reply += HtmlTag("title", buf) + "\n";
00766 reply += "</head><body>\n";
00767 reply += HtmlTag("h1", buf) + "\n";
00768
00769 TIterator *iterator = folder->GetListOfFolders()->MakeIterator();
00770
00771 while (1)
00772 {
00773 TNamed *obj = (TNamed*)iterator->Next();
00774 if (obj == NULL)
00775 break;
00776
00777 reply += HtmlTag("p", MakeHtmlEntry(obj, path.c_str())) + "\n";
00778 xml += MakeXmlEntry(obj);
00779 }
00780
00781 delete iterator;
00782
00783 lock.Unlock();
00784
00785 xml += "</dir></xml>\n";
00786 reply += "</body></html>\n";
00787
00788 if (xmlOutput)
00789 SendHttpReply(sock, "application/xml", xml);
00790 else
00791 SendHttpReply(sock, "text/html", reply);
00792
00793 } else if (obj && obj->InheritsFrom(TCollection::Class())) {
00794 TCollection* collection = (TCollection*)obj;
00795
00796
00797
00798
00799
00800
00801 std::string xml;
00802
00803 xml += "<xml>\n";
00804 xml += "<dir>\n";
00805
00806 std::string reply;
00807 std::string buf;
00808
00809 reply += "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n";
00810
00811 buf = "Collection ";
00812 buf += xpath;
00813 reply += HtmlTag("title", buf) + "\n";
00814 reply += "</head><body>\n";
00815 reply += HtmlTag("h1", buf) + "\n";
00816
00817 TIterator *iterator = collection->MakeIterator();
00818
00819 while (1)
00820 {
00821 TNamed *obj = (TNamed*)iterator->Next();
00822 if (obj == NULL)
00823 break;
00824
00825 reply += HtmlTag("p", MakeHtmlEntry(obj, path.c_str())) + "\n";
00826 xml += MakeXmlEntry(obj);
00827 }
00828
00829 delete iterator;
00830
00831 lock.Unlock();
00832
00833 xml += "</dir></xml>\n";
00834 reply += "</body></html>\n";
00835
00836 if (xmlOutput)
00837 SendHttpReply(sock, "application/xml", xml);
00838 else
00839 SendHttpReply(sock, "text/html", reply);
00840
00841 } else {
00842 if (xmlOutput) {
00843 std::string xml;
00844 xml += "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
00845 xml += "<xml>\n";
00846 xml += "<ROOTobject>\n";
00847 TString msg = TBufferXML::ConvertToXML(obj);
00848 xml += msg;
00849 xml += "</ROOTobject>\n";
00850 xml += "</xml>\n";
00851 lock.Unlock();
00852 SendHttpReply(sock, "application/xml", xml);
00853 } else {
00854 SendFile(sock, "plot.html", "text/html");
00855 if (0) {
00856 std::string reply;
00857 std::string buf;
00858
00859 reply += "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n";
00860
00861 buf = "Object ";
00862 buf += xpath;
00863 reply += HtmlTag("title", buf) + "\n";
00864 reply += "</head><body>\n";
00865 reply += HtmlTag("h1", buf) + "\n";
00866
00867 reply += HtmlTag("p", obj->GetName());
00868 reply += HtmlTag("p", obj->ClassName());
00869
00870 reply += "</body></html>\n";
00871 SendHttpReply(sock, "text/html", reply);
00872 }
00873 }
00874 }
00875 }
00876 #if 0
00877 else if (strncmp(request, "ResetTH1 ", 9) == 0)
00878 {
00879 XLockRootGuard lock;
00880
00881 char* path = request + 9;
00882
00883 if (strlen(path) > 1)
00884 {
00885 TObject *obj = FollowPath(path);
00886
00887 if (obj)
00888 ResetObject(obj);
00889 }
00890 else
00891 {
00892 for (unsigned int i=0; i<gExports.size(); i++)
00893 {
00894 const char* ename = gExports[i].c_str();
00895 const char* xname = gExportNames[ename].c_str();
00896
00897 TObject* obj = FindTopLevelObject(xname);
00898
00899 if (!obj)
00900 {
00901 fprintf(stderr, "XmlServer: ResetTH1: Exported name \'%s\' cannot be found!\n", xname);
00902 continue;
00903 }
00904
00905 ResetObject(obj);
00906 }
00907 }
00908
00909
00910
00911
00912
00913 lock.Unlock();
00914
00915
00916 const char *msg = "Success";
00917 sock->SendRaw(msg, strlen(msg) + 1);
00918 }
00919 #endif
00920 else
00921 {
00922 fprintf(stderr, "XmlServer: Received unknown request \"%s\"\n", request);
00923
00924 std::string reply;
00925 reply += "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n";
00926 reply += HtmlTag("title", "Unknown request") + "\n";
00927 reply += "</head><body>\n";
00928 reply += HtmlTag("h1", "Unknown request") + "\n";
00929 reply += HtmlTag("p", request) + "\n";
00930 reply += "</body></html>\n";
00931 SendHttpReply(sock, "text/html", reply);
00932 }
00933 } while (1);
00934
00935 return THREADRETURN;
00936 }
00937
00938
00939
00940 static THREADTYPE xsocket_listener(void *arg)
00941 {
00942
00943
00944
00945 int port = *(int *) arg;
00946
00947 fprintf(stderr, "XmlServer: Listening on port %d...\n", port);
00948 TServerSocket *lsock = new TServerSocket(port, kTRUE);
00949
00950 while (1)
00951 {
00952 TSocket *sock = lsock->Accept();
00953
00954 if (sock==NULL)
00955 {
00956 fprintf(stderr, "XmlServer: TSocket->Accept() error\n");
00957 break;
00958 }
00959
00960 if (gVerbose)
00961 fprintf(stderr, "XmlServer: connection from %s\n", sock->GetInetAddress().GetHostName());
00962
00963 #if 1
00964 TThread *thread = new TThread("XmlServer", xroot_server_thread, sock);
00965 thread->Run();
00966 #else
00967 LPDWORD lpThreadId = 0;
00968 CloseHandle(CreateThread(NULL, 1024, &xroot_server_thread, sock, 0, lpThreadId));
00969 #endif
00970 }
00971
00972 return THREADRETURN;
00973 }
00974
00975
00976
00977 void XmlServer::SetVerbose(bool verbose)
00978 {
00979 gVerbose = verbose;
00980 }
00981
00982
00983
00984 void XmlServer::Export(TDirectory* dir, const char* exportName)
00985 {
00986 if (gVerbose)
00987 printf("Export TDirectory %p named [%s] of type [%s] as [%s]\n", dir, dir->GetName(), dir->IsA()->GetName(), exportName);
00988
00989 bool found = false;
00990 for (unsigned int i=0; i<gExports.size(); i++)
00991 {
00992 const char* ename = gExports[i].c_str();
00993 if (strcmp(ename, exportName) == 0)
00994 found = true;
00995 }
00996
00997 if (!found)
00998 gExports.push_back(exportName);
00999 gExportNames[exportName] = dir->GetName();
01000 }
01001
01002 void XmlServer::Export(TFolder* folder, const char* exportName)
01003 {
01004 if (gVerbose)
01005 printf("Export TFolder %p named [%s] of type [%s] as [%s]\n", folder, folder->GetName(), folder->IsA()->GetName(), exportName);
01006
01007 bool found = false;
01008 for (unsigned int i=0; i<gExports.size(); i++)
01009 {
01010 const char* ename = gExports[i].c_str();
01011 if (strcmp(ename, exportName) == 0)
01012 found = true;
01013 }
01014
01015 if (!found)
01016 gExports.push_back(exportName);
01017 gExportNames[exportName] = folder->GetName();
01018 }
01019
01020 void XmlServer::Export(TCollection* collection, const char* exportName)
01021 {
01022 if (gVerbose)
01023 printf("Export TCollection %p named [%s] of type [%s] as [%s]\n", collection, collection->GetName(), collection->IsA()->GetName(), exportName);
01024
01025 bool found = false;
01026 for (unsigned int i=0; i<gExports.size(); i++)
01027 {
01028 const char* ename = gExports[i].c_str();
01029 if (strcmp(ename, exportName) == 0)
01030 found = true;
01031 }
01032
01033 if (!found)
01034 gExports.push_back(exportName);
01035 gExportNames[exportName] = collection->GetName();
01036 }
01037
01038 void XmlServer::Start(int port)
01039 {
01040 if (port==0)
01041 return;
01042
01043
01044
01045 static int pport = port;
01046 #if 1
01047 TThread *thread = new TThread("XmlServer", xsocket_listener, &pport);
01048 thread->Run();
01049 #else
01050 LPDWORD lpThreadId = 0;
01051 CloseHandle(CreateThread(NULL, 1024, &xroot_socket_server, &pport, 0, lpThreadId));
01052 #endif
01053 }
01054
01055
01056
01057
01058
01059
01060
01061