ROOTANA
Loading...
Searching...
No Matches
analyzer.cxx
Go to the documentation of this file.
1//
2// ROOT analyzer
3//
4// K.Olchanski
5//
6// $Id$
7//
8
9#include <stdio.h>
10#include <sys/time.h>
11#include <iostream>
12#include <assert.h>
13#include <signal.h>
14#include <string.h> // memcpy()
15#include <stdlib.h> // atoi()
16
17#ifdef HAVE_MIDAS
18#include "TMidasOnline.h"
19#endif
20#include "TMidasEvent.h"
21#include "midasio.h"
22#ifdef HAVE_MIDASSERVER
23#include "midasServer.h"
24#endif
25#ifdef HAVE_LIBNETDIRECTORY
26#include "netDirectoryServer.h"
27#endif
28#ifdef HAVE_XMLSERVER
29#include "xmlServer.h"
30#endif
31
32#ifdef HAVE_ROOT
33#include <TSystem.h>
34#include <TROOT.h>
35#include <TApplication.h>
36#include <TTimer.h>
37#include <TFile.h>
38#include <TDirectory.h>
39#include <TGClient.h>
40#include <TGFrame.h>
41#include <TFolder.h>
42#endif
43
44#include "Globals.h"
45
46// Global Variables
47int gRunNumber = 0;
48bool gIsRunning = false;
49bool gIsPedestalsRun = false;
50bool gIsOffline = false;
52
53#ifdef HAVE_ROOT
55TFile* gOutputFile = NULL;
56#endif
57
58MVOdb* gOdb = NULL;
59
60//TCanvas *gMainWindow = NULL; // the online histogram window
61
62double GetTimeSec()
63{
64 struct timeval tv;
65 gettimeofday(&tv,NULL);
66 return tv.tv_sec + 0.000001*tv.tv_usec;
67}
68
69#ifdef HAVE_ROOT
70class MyPeriodic : public TTimer
71{
72public:
73 typedef void (*TimerHandler)(void);
74
75 int fPeriod_msec;
77 double fLastTime;
78
79 MyPeriodic(int period_msec,TimerHandler handler)
80 {
81 assert(handler != NULL);
82 fPeriod_msec = period_msec;
83 fHandler = handler;
85 Start(period_msec,kTRUE);
86 }
87
88 Bool_t Notify()
89 {
90 double t = GetTimeSec();
91 //printf("timer notify, period %f should be %f!\n",t-fLastTime,fPeriod_msec*0.001);
92
93 if (t - fLastTime >= 0.9*fPeriod_msec*0.001)
94 {
95 //printf("timer: call handler %p\n",fHandler);
96 if (fHandler)
97 (*fHandler)();
98
99 fLastTime = t;
100 }
101
102 Reset();
103 return kTRUE;
104 }
105
107 {
108 TurnOff();
109 }
110};
111#endif
112
113void startRun(int transition,int run,int time)
114{
115 gIsRunning = true;
116 gRunNumber = run;
117 gIsPedestalsRun = false;
118 gOdb->RB("experiment/edit on start/Pedestals run", &gIsPedestalsRun);
119 printf("Begin run: %d, pedestal run: %d\n", gRunNumber, gIsPedestalsRun);
120
121#ifdef HAVE_ROOT
122 if(gOutputFile!=NULL)
123 {
124 gOutputFile->Write();
125 gOutputFile->Close();
126 gOutputFile=NULL;
127 }
128
129 char filename[1024];
130 sprintf(filename, "output%05d.root", run);
131 gOutputFile = new TFile(filename, "RECREATE");
132
133 //if (gOutputFile && !gOutputFile->IsOpen())
134 //gOutputFile = NULL;
135
136 assert(gOutputFile);
137 assert(gOutputFile->IsOpen());
138#endif
139
140 //printf("gOutputFile: %p, isOpen %d\n", gOutputFile, gOutputFile->IsOpen());
141
142#ifdef HAVE_LIBNETDIRECTORY
143 NetDirectoryExport(gOutputFile, "outputFile");
144#endif
145}
146
147void endRun(int transition,int run,int time)
148{
149 gIsRunning = false;
150 gRunNumber = run;
151
152#ifdef HAVE_MIDASSERVER
154 gManaHistosFolder->Clear();
155#endif
156
157#ifdef HAVE_ROOT
158 if (gOutputFile)
159 {
160 gOutputFile->Write();
161 gOutputFile->Close(); //close the histogram file
162 gOutputFile = NULL;
163 }
164#endif
165
166 printf("End of run %d\n",run);
167}
168
169#ifdef HAVE_ROOT
170#include <TH1D.h>
171#endif
172
173void HandleSample(int ichan, void* ptr, int wsize)
174{
175#ifdef HAVE_ROOT
176 uint16_t *samples = (uint16_t*) ptr;
177 int numSamples = wsize;
178
179 if (numSamples != 512)
180 return;
181
182 char name[256];
183 sprintf(name, "channel%d", ichan);
184
185 if (gOutputFile)
186 gOutputFile->cd();
187
188 TH1D* samplePlot = (TH1D*)gDirectory->Get(name);
189
190 if (!samplePlot)
191 {
192 printf("Create [%s]\n", name);
193 samplePlot = new TH1D(name, name, numSamples, 0, numSamples);
194 //samplePlot->SetMinimum(0);
195#ifdef HAVE_MIDASSERVER
197 gManaHistosFolder->Add(samplePlot);
198#endif
199 }
200
201 for(int ti=0; ti<numSamples; ti++)
202 samplePlot->SetBinContent(ti, samples[ti]);
203#endif
204}
205
206
208{
209 int eventId = event.GetEventId();
210
211 if (false&&(eventId == 1))
212 {
213 void *ptr;
214 int size = event.LocateBank(NULL, "CHA3", &ptr);
215 if (ptr)
216 HandleSample(3, ptr, size);
217 }
218 if (false&&(eventId == 1)&&(gIsRunning==true)&&(gIsPedestalsRun==false)) // SIS data
219 {
220 //printf("SIS event\n");
221 //event.Print();
222 //void *ptr;
223 //int size = event.LocateBank(event.GetData(),"MCS",&ptr);
224 //HandleSIS(kMaxSisChannels,size,ptr);
225 }
226 else if (false&&(eventId == 2)&&(gIsRunning==true)) // ADC data
227 {
228 //printf("ADC event\n");
229 //event.Print();
230 //void *ptr;
231 //int size = event.LocateBank(event.GetData(),"ADC",&ptr);
232 //HandleBeamADC(kMaxADCChannels,size,ptr,event);
233 }
234 else if (false&&(eventId==5)&&(gIsRunning==true)&&(gIsPedestalsRun==false))// Scaler data
235 {
236 //event.Print();
237 //void *sclrptr;
238 //int sclrsize = event.LocateBank(event.GetData(),"SCLR",&sclrptr);
239 //void *scrtptr;
240 //int scrtsize = event.LocateBank(event.GetData(),"SCRT",&scrtptr);
241 //HandleScaler(kMaxScalerChannels,sclrsize,sclrptr,scrtsize,scrtptr,event);
242 }
243 else
244 {
245 // unknown event type
246 event.Print();
247 }
248}
249
250void eventHandler(const void*pheader,const void*pdata,int size)
251{
252 TMidasEvent event;
253 memcpy(event.GetEventHeader(), pheader, sizeof(TMidas_EVENT_HEADER));
254 event.SetData(size, (char*)pdata);
255 event.SetBankList();
256 HandleMidasEvent(event);
257}
258
259int ProcessMidasFile(const char*fname)
260{
261 TMReaderInterface* reader = TMNewReader(fname);
262
263 if (reader->fError)
264 {
265 printf("Cannot open input file \"%s\"\n",fname);
266 delete reader;
267 return -1;
268 }
269
270 int i=0;
271 while (1)
272 {
273 TMidasEvent event;
274 if (!TMReadEvent(reader, &event))
275 break;
276
277 int eventId = event.GetEventId();
278 //printf("Have an event of type %d\n",eventId);
279
280 if ((eventId & 0xFFFF) == 0x8000)
281 {
282 // begin run
283 event.Print();
284
285 //char buf[256];
286 //memset(buf,0,sizeof(buf));
287 //memcpy(buf,event.GetData(),255);
288 //printf("buf is [%s]\n",buf);
289
290 //
291 // Load ODB contents from the ODB XML file
292 //
293 if (gOdb)
294 delete gOdb;
295 gOdb = MakeFileDumpOdb(event.GetData(),event.GetDataSize());
296
297 startRun(0,event.GetSerialNumber(),0);
298 }
299 else if ((eventId & 0xFFFF) == 0x8001)
300 {
301 // end run
302 event.Print();
303 }
304 else if ((eventId & 0xFFFF) == 0x8002)
305 {
306 // log message
307 event.Print();
308 printf("Log message: %s\n", event.GetData());
309 }
310 else
311 {
312 event.SetBankList();
313 //event.Print();
314 HandleMidasEvent(event);
315 }
316
317 if((i%500)==0)
318 {
319 //resetClock2time();
320 printf("Processing event %d\n",i);
321 //SISperiodic();
322 //StepThroughSISBuffer();
323 }
324
325 i++;
326 if ((gEventCutoff!=0)&&(i>=gEventCutoff))
327 {
328 printf("Reached event %d, exiting loop.\n",i);
329 break;
330 }
331 }
332
333 reader->Close();
334 delete reader;
335
336 endRun(0,gRunNumber,0);
337
338 return 0;
339}
340
341#ifdef HAVE_MIDAS
342
343#ifdef HAVE_ROOT
345{
346 if (!(TMidasOnline::instance()->poll(0)))
347 gSystem->ExitLoop();
348}
349#endif
350
351#ifdef HAVE_ROOT
352class TApplication;
353#else
354#define TApplication void*
355#endif
356
357int ProcessMidasOnline(TApplication*app, const char* hostname, const char* exptname)
358{
360
361 int err = midas->connect(hostname, exptname, "rootana");
362 if (err != 0)
363 {
364 fprintf(stderr,"Cannot connect to MIDAS, error %d\n", err);
365 return -1;
366 }
367
368 gOdb = MakeMidasOdb(midas->fDB);
369
370 midas->setTransitionHandlers(startRun,endRun,NULL,NULL);
371 midas->registerTransitions();
372
373 /* reqister event requests */
374
376 midas->eventRequest("SYSTEM",-1,-1,(1<<1));
377
378 /* fill present run parameters */
379
380 gRunNumber = 0;
381 gOdb->RI("runinfo/Run number", &gRunNumber);
382
383 int runstate = 0;
384 gOdb->RI("runinfo/State", &runstate);
385 if (runstate == 3)
386 startRun(0,gRunNumber,0);
387
388 printf("Startup: run %d, is running: %d, is pedestals run: %d\n",gRunNumber,gIsRunning,gIsPedestalsRun);
389
390#ifdef HAVE_ROOT
392 //MyPeriodic th(1000,SISperiodic);
393 //MyPeriodic tn(1000,StepThroughSISBuffer);
394 //MyPeriodic to(1000,Scalerperiodic);
395
396 /*---- start main loop ----*/
397
398 //loop_online();
399 app->Run(kTRUE);
400#else
401 // FIXME: running without ROOT will not work!
402#endif
403
404 /* disconnect from experiment */
405 midas->disconnect();
406
407 return 0;
408}
409
410#endif
411
412#ifdef HAVE_ROOT
413#include <TGMenu.h>
414
415class MainWindow: public TGMainFrame {
416
417private:
418 TGPopupMenu* menuFile;
419 //TGPopupMenu* menuControls;
420 TGMenuBar* menuBar;
421 TGLayoutHints* menuBarLayout;
422 TGLayoutHints* menuBarItemLayout;
423
424public:
425 MainWindow(const TGWindow*w,int s1,int s2);
426 virtual ~MainWindow(); // Closing the control window closes the whole program
427 virtual void CloseWindow();
428
429 Bool_t ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2);
430};
431
432#define M_FILE_EXIT 0
433
434Bool_t MainWindow::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
435{
436 // printf("GUI Message %d %d %d\n",(int)msg,(int)parm1,(int)parm2);
437 switch (GET_MSG(msg))
438 {
439 default:
440 break;
441 case kC_COMMAND:
442 switch (GET_SUBMSG(msg))
443 {
444 default:
445 break;
446 case kCM_MENU:
447 switch (parm1)
448 {
449 default:
450 break;
451 case M_FILE_EXIT:
452 if(gIsRunning)
453 endRun(0,gRunNumber,0);
454 gSystem->ExitLoop();
455 break;
456 }
457 break;
458 }
459 break;
460 }
461
462 return kTRUE;
463}
464
465MainWindow::MainWindow(const TGWindow*w,int s1,int s2) // ctor
466 : TGMainFrame(w,s1,s2)
467{
468 //SetCleanup(kDeepCleanup);
469
470 SetWindowName("ROOT Analyzer Control");
471
472 // layout the gui
473 menuFile = new TGPopupMenu(gClient->GetRoot());
474 menuFile->AddEntry("Exit", M_FILE_EXIT);
475
476 menuBarItemLayout = new TGLayoutHints(kLHintsTop|kLHintsLeft, 0, 4, 0, 0);
477
478 menuFile->Associate(this);
479 //menuControls->Associate(this);
480
481 menuBar = new TGMenuBar(this, 1, 1, kRaisedFrame);
482 menuBar->AddPopup("&File", menuFile, menuBarItemLayout);
483 //menuBar->AddPopup("&Controls", menuControls, menuBarItemLayout);
484 menuBar->Layout();
485
486 menuBarLayout = new TGLayoutHints(kLHintsTop|kLHintsLeft|kLHintsExpandX);
487 AddFrame(menuBar,menuBarLayout);
488
489 MapSubwindows();
490 Layout();
491 MapWindow();
492}
493
495{
496 delete menuFile;
497 //delete menuControls;
498 delete menuBar;
499 delete menuBarLayout;
500 delete menuBarItemLayout;
501}
502
504{
505 if(gIsRunning)
506 endRun(0,gRunNumber,0);
507 gSystem->ExitLoop();
508}
509#endif
510
511static bool gEnableShowMem = false;
512
513int ShowMem(const char* label)
514{
515 if (!gEnableShowMem)
516 return 0;
517
518 FILE* fp = fopen("/proc/self/statm","r");
519 if (!fp)
520 return 0;
521
522 int mem = 0;
523 fscanf(fp,"%d",&mem);
524 fclose(fp);
525
526 if (label)
527 printf("memory at %s is %d\n", label, mem);
528
529 return mem;
530}
531
532void help()
533{
534 printf("\nUsage:\n");
535 printf("\n./analyzer.exe [-h] [-Hhostname] [-Eexptname] [-eMaxEvents] [-P9091] [-p9090] [-m] [-g] [file1 file2 ...]\n");
536 printf("\n");
537 printf("\t-h: print this help message\n");
538 printf("\t-T: test mode - start and serve a test histogram\n");
539 printf("\t-Hhostname: connect to MIDAS experiment on given host\n");
540 printf("\t-Eexptname: connect to this MIDAS experiment\n");
541 printf("\t-P: Start the TNetDirectory server on specified tcp port (for use with roody -Plocalhost:9091)\n");
542 printf("\t-p: Start the old midas histogram server on specified tcp port (for use with roody -Hlocalhost:9090)\n");
543 printf("\t-e: Number of events to read from input data files\n");
544 printf("\t-m: Enable memory leak debugging\n");
545 printf("\t-g: Enable graphics display when processing data files\n");
546 printf("\n");
547 printf("Example1: analyze online data: ./analyzer.exe -P9091\n");
548 printf("Example2: analyze existing data: ./analyzer.exe /data/alpha/current/run00500.mid\n");
549 exit(1);
550}
551
552// Main function call
553
554int main(int argc, char *argv[])
555{
556 setbuf(stdout,NULL);
557 setbuf(stderr,NULL);
558
559 signal(SIGILL, SIG_DFL);
560 signal(SIGBUS, SIG_DFL);
561 signal(SIGSEGV, SIG_DFL);
562 signal(SIGPIPE, SIG_DFL);
563
564 std::vector<std::string> args;
565 for (int i=0; i<argc; i++)
566 {
567 if (strcmp(argv[i],"-h")==0)
568 help(); // does not return
569 args.push_back(argv[i]);
570 }
571
572#ifdef HAVE_ROOT
573 TApplication *app = new TApplication("rootana", &argc, argv);
574
575 if(gROOT->IsBatch()) {
576 printf("Cannot run in batch mode\n");
577 return 1;
578 }
579#else
580#ifdef HAVE_MIDAS
581 TApplication *app = NULL;
582#endif
583#endif
584
585 //bool forceEnableGraphics = false;
586 bool testMode = false;
587 int oldTcpPort = 0;
588 int tcpPort = 0;
589 int xmlTcpPort = 0;
590#ifdef HAVE_MIDAS
591 const char* hostname = NULL;
592 const char* exptname = NULL;
593#endif
594 for (unsigned int i=1; i<args.size(); i++) // loop over the commandline options
595 {
596 const char* arg = args[i].c_str();
597 //printf("argv[%d] is %s\n",i,arg);
598
599 if (strncmp(arg,"-e",2)==0) // Event cutoff flag (only applicable in offline mode)
600 gEventCutoff = atoi(arg+2);
601 else if (strncmp(arg,"-m",2)==0) // Enable memory debugging
602 gEnableShowMem = true;
603 else if (strncmp(arg,"-p",2)==0) // Set the histogram server port
604 oldTcpPort = atoi(arg+2);
605 else if (strncmp(arg,"-P",2)==0) // Set the histogram server port
606 tcpPort = atoi(arg+2);
607 else if (strncmp(arg,"-X",2)==0) // Set the histogram server port
608 xmlTcpPort = atoi(arg+2);
609 else if (strcmp(arg,"-T")==0)
610 testMode = true;
611 //else if (strcmp(arg,"-g")==0)
612 // forceEnableGraphics = true;
613#ifdef HAVE_MIDAS
614 else if (strncmp(arg,"-H",2)==0)
615 hostname = strdup(arg+2);
616 else if (strncmp(arg,"-E",2)==0)
617 exptname = strdup(arg+2);
618#endif
619 else if (strcmp(arg,"-h")==0)
620 help(); // does not return
621 else if (arg[0] == '-')
622 help(); // does not return
623 }
624
625#ifdef HAVE_ROOT
626 MainWindow mainWindow(gClient->GetRoot(), 200, 300);
627
628 gROOT->cd();
629 gOnlineHistDir = new TDirectory("rootana", "rootana online plots");
630
631#ifdef HAVE_MIDASSERVER
632 if (oldTcpPort)
633 StartMidasServer(oldTcpPort);
634#else
635 if (oldTcpPort)
636 fprintf(stderr,"ERROR: No support for the old midas server!\n");
637#endif
638#ifdef HAVE_LIBNETDIRECTORY
639 if (tcpPort)
641#else
642 if (tcpPort)
643 fprintf(stderr,"ERROR: No support for the TNetDirectory server!\n");
644#endif
645#ifdef HAVE_XMLSERVER
646 XmlServer* xmlServer = NULL;
647 if (xmlTcpPort)
648 {
649 xmlServer = new XmlServer();
650 xmlServer->SetVerbose(true);
651 xmlServer->Start(xmlTcpPort);
652 xmlServer->Export(gOnlineHistDir, gOnlineHistDir->GetName());
653 }
654#else
655 if (xmlTcpPort)
656 fprintf(stderr,"ERROR: No support for the XML Server!\n");
657#endif
658#endif // HAVE_ROOT
659
660 gIsOffline = false;
661
662 for (unsigned int i=1; i<args.size(); i++)
663 {
664 const char* arg = args[i].c_str();
665
666 if (arg[0] != '-')
667 {
668 gIsOffline = true;
669 //gEnableGraphics = false;
670 //gEnableGraphics |= forceEnableGraphics;
671 ProcessMidasFile(arg);
672 }
673 }
674
675#ifdef HAVE_ROOT
676 if (testMode)
677 {
679 TH1D* hh = new TH1D("test", "test", 100, 0, 100);
680 hh->Fill(1);
681 hh->Fill(10);
682 hh->Fill(50);
683
684 app->Run(kTRUE);
685 return 0;
686 }
687#endif
688
689 // if we processed some data files,
690 // do not go into online mode.
691 if (gIsOffline)
692 return 0;
693
694 gIsOffline = false;
695 //gEnableGraphics = true;
696#ifdef HAVE_MIDAS
697 ProcessMidasOnline(app, hostname, exptname);
698#endif
699
700 return 0;
701}
702
703//end
R__EXTERN TDirectory * gDirectory
void HandleMidasEvent(TMidasEvent &event)
Definition analyzer.cxx:207
int main(int argc, char *argv[])
Definition analyzer.cxx:554
void HandleSample(int ichan, void *ptr, int wsize)
Definition analyzer.cxx:173
MVOdb * gOdb
Definition analyzer.cxx:58
int gEventCutoff
Definition analyzer.cxx:51
void eventHandler(const void *pheader, const void *pdata, int size)
Definition analyzer.cxx:250
bool gIsRunning
Definition analyzer.cxx:48
TDirectory * gOnlineHistDir
Definition analyzer.cxx:54
bool gIsPedestalsRun
Definition analyzer.cxx:49
void startRun(int transition, int run, int time)
Definition analyzer.cxx:113
int ProcessMidasOnline(TApplication *app, const char *hostname, const char *exptname)
Definition analyzer.cxx:357
void MidasPollHandler()
Definition analyzer.cxx:344
int gRunNumber
Definition analyzer.cxx:47
#define M_FILE_EXIT
Definition analyzer.cxx:432
static bool gEnableShowMem
Definition analyzer.cxx:511
void help()
Definition analyzer.cxx:532
bool gIsOffline
Definition analyzer.cxx:50
void endRun(int transition, int run, int time)
Definition analyzer.cxx:147
int ShowMem(const char *label)
Definition analyzer.cxx:513
TFile * gOutputFile
Definition analyzer.cxx:55
double GetTimeSec()
Definition analyzer.cxx:62
int ProcessMidasFile(const char *fname)
Definition analyzer.cxx:259
Definition mvodb.h:21
virtual void RI(const char *varname, int *value, bool create=false, MVOdbError *error=NULL)=0
virtual void RB(const char *varname, bool *value, bool create=false, MVOdbError *error=NULL)=0
virtual void CloseWindow()
TGLayoutHints * menuBarItemLayout
TGLayoutHints * menuBarLayout
TGPopupMenu * menuFile
Definition MainWindow.hxx:8
virtual void CloseWindow()
virtual ~MainWindow()
TGMenuBar * menuBar
Bool_t ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
virtual ~MainWindow()
MainWindow(const TGWindow *w, int s1, int s2)
TimerHandler fHandler
void(* TimerHandler)(void)
Bool_t Notify()
Definition analyzer.cxx:88
MyPeriodic(int period_msec, TimerHandler handler)
Definition analyzer.cxx:79
virtual TObject * Get(const char *namecycle)
virtual Bool_t cd(const char *path=0)
virtual int Close()=0
MIDAS event.
Definition TMidasEvent.h:22
TMidas_EVENT_HEADER * GetEventHeader()
return pointer to the event header
uint32_t GetDataSize() const
return the event size
uint16_t GetEventId() const
return the event id
uint32_t GetSerialNumber() const
return the serial number
char * GetData()
return pointer to the data buffer
void setEventHandler(EventHandler handler)
Specify user handler for data events.
void registerTransitions()
Ask MIDAS to tell us about run transitions.
int disconnect()
Disconnect from MIDAS.
static TMidasOnline * instance()
int connect(const char *hostname, const char *exptname, const char *progname)
Connect to MIDAS experiment.
HNDLE fDB
ODB handle.
void setTransitionHandlers(TransitionHandler start, TransitionHandler stop, TransitionHandler pause, TransitionHandler resume)
Specify user handlers for run transitions.
int eventRequest(const char *bufferName, int eventId, int triggerMask, int samplingType, bool poll=false)
Request data for delivery via callback (setEventHandler) or by polling (via receiveEvent)
void Export(TDirectory *dir, const char *exportName)
void SetVerbose(bool verbose)
void Start(int port)
TMEvent * TMReadEvent(TMReaderInterface *reader)
Definition midasio.cxx:585
TMReaderInterface * TMNewReader(const char *source)
Definition midasio.cxx:447
MVOdb * MakeMidasOdb(int hDB, MVOdbError *error=NULL)
Definition midasodb.cxx:924
MVOdb * MakeFileDumpOdb(const char *buf, int bufsize, MVOdbError *error=NULL)
Access ODB from a midas file dump. FOrmat could be .xml, .json or .odb.
Definition mvodb.cxx:91
TFolder * gManaHistosFolder
void StartMidasServer(int port)
void NetDirectoryExport(TDirectory *dir, const char *exportName)
void StartNetDirectoryServer(int port, TDirectory *dir)