00001
00002
00003
00004
00005 #include <iostream>
00006 #include <stdlib.h>
00007
00008 #include <unistd.h>
00009
00010 #include "OnlineUtil/msgLogLib/msgLog.h"
00011 #include "OnlineUtil/minosDaq.h"
00012
00013 #include <signal.h>
00014 #include <string>
00015 #include <map>
00016
00017 #include "TROOT.h"
00018 #include "TRint.h"
00019 #include "TVirtualX.h"
00020 #include "TGuiFactory.h"
00021
00022 #include "TServerSocket.h"
00023 #include "TSocket.h"
00024 #include "TMessage.h"
00025
00026 #include "Rotorooter/RotoServer.h"
00027 #include "Rotorooter/RotoObjectifier.h"
00028 #include "Rotorooter/MsgLogTErrorHandler.h"
00029
00030 #include "RawData/RawBlockId.h"
00031 #include "RawData/RawBlockRegistry.h"
00032 #include "RawData/RawBlockProxy.h"
00033 #include "RawData/RawDataBlock.h"
00034
00035 #include "RawData/RawRecord.h"
00036
00037
00038
00039 RotoServer* server = 0;
00040
00041
00042 static void roto_sighandler(int dummy)
00043 {
00044 if (server) {
00045 logNotice("roto_sighandler signal %d; attempt shutdown",dummy);
00046
00047
00048 delete server;
00049 logNotice("roto_sighandler exit");
00050
00051 } else {
00052 logNotice("roto_sighandler signal %d, but no server",dummy);
00053
00054 }
00055
00056 msgLogCleanup();
00057
00058 exit(1);
00059 }
00060
00061
00062 int config_autosave(const char* config);
00063 int config_compress(const char* config);
00064 int config_basketsize(const char* config);
00065 int parse_port(const char* opt, string& inputFileName);
00066
00067
00068
00069 int main(int argc, char **argv)
00070 {
00071 int copt;
00072
00073 Bool_t allow_overwrite = kFALSE;
00074 string inputFileName;
00075 Int_t port = ROOTER_PORT_DAQ;
00076 Int_t nwords = 2*1024*1024;
00077 Int_t tcp_nodelay_flag = 1;
00078 const Char_t* autosave_config = 0;
00079 const Char_t* compress_config = 0;
00080 const Char_t* basketsize_config = 0;
00081 const Char_t* bin_output_file = 0;
00082 const Char_t* symlink_config = 0;
00083
00084
00085
00086
00087 SetErrorHandler(MsgLogTErrorHandler);
00088
00089 #ifdef ALLOW_FORCE
00090 Detector::Detector_t forceDetector = Detector::kUnknown;
00091 SimFlag::SimFlag_t forceSimFlag = SimFlag::kUnknown;
00092 const char* optlist = "aep:b:c:C:B:D:v:z:hd:sl:";
00093 #else
00094 const char* optlist = "aep:b:c:C:B:D:v:z:hl:";
00095 #endif
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 msgLogInit(argv[0]);
00117 msgLogNodeIdSet(MINOS_ROOTER);
00118 logInfo("rotorooter command line configuration\n");
00119
00120 while ((copt = getopt(argc, argv, optlist)) != EOF) {
00121 switch (copt) {
00122 case 'a':
00123 allow_overwrite = kTRUE;
00124 break;
00125 case 'e':
00126 msgLogLocalEchoSet(1);
00127 break;
00128 case 'p':
00129
00130 port = parse_port(optarg, inputFileName);
00131 break;
00132 case 'b':
00133 nwords = atoi(optarg);
00134 break;
00135 case 'c':
00136 autosave_config = optarg;
00137 break;
00138 case 'C':
00139 compress_config = optarg;
00140 break;
00141 case 'B':
00142 basketsize_config = optarg;
00143 break;
00144 case 'D':
00145 tcp_nodelay_flag = atoi(optarg);
00146 break;
00147 case 'v':
00148 logDebugLevelSet(atoi(optarg));
00149 break;
00150 case 'z':
00151 bin_output_file = optarg;
00152 break;
00153 case 'h':
00154 printf(" usage: %s -a -p<port#> -b<buffersize> -e\n", argv[0]);
00155 printf(" -a: allow file overwriting\n");
00156 printf(" -p: port number rotorooter is listening on\n");
00157 printf(" or file name or \"dcs\"/\"daq\", \"dcs\", \"beammon\"\n");
00158 printf(" -b: initial buffer size in long words\n");
00159 printf(" -e: direct msgLog errors to stdout as well\n");
00160 printf(" -v: msgLog debug level\n");
00161 printf(" -c: autosave config \"streamName,nrec,nsec[;streamName,nrec,nsec]\"\n");
00162 printf(" -C: compression config \"streamName,level[;streamName,level]\"\n");
00163 printf(" -B: basketsize config \"streamName,size[;streamName,size]\"\n");
00164 printf(" -D: TCP_NODELAY flag\n");
00165 printf(" -z: make copy of flat data to binary file\n");
00166 #ifdef ALLOW_FORCE
00167 printf(" -d: detector override\n");
00168 printf(" -s: simflag override\n");
00169 #endif
00170 printf(" -l: symlink to this file on each successful open\n");
00171 printf(" -h: print this message\n");
00172 exit(1);
00173 break;
00174 default:
00175 printf(" unrecognized option '%c'\n",(char)optopt);
00176 exit(1);
00177 break;
00178 #ifdef ALLOW_FORCE
00179 case 'd':
00180 {
00181
00182 Detector::Detector_t dlist[] = { Detector::kNear,
00183 Detector::kFar,
00184 Detector::kCalDet };
00185 int n = sizeof(dlist)/sizeof(forceDetector);
00186 string user = optarg;
00187
00188 for (int i = 0; i < n; i++) {
00189 if ( Detector::AsString(dlist[i]) == user)
00190 forceDetector = dlist[i];
00191 }
00192
00193 if (Detector::kUnknown == forceDetector) {
00194 printf(" -d flag (force detector type) unknown value: %s\n",
00195 user.c_str());
00196 printf(" must be followed by exactly one of: %s",
00197 Detector::AsString(dlist[0]));
00198 for (int i = 1; i < n; i++ ) printf(", %s",
00199 Detector::AsString(dlist[i]));
00200 printf("\n");
00201 forceDetector = Detector::kUnknown;
00202 exit(1);
00203 }
00204 }
00205 break;
00206 case 's':
00207 {
00208
00209 SimFlag::SimFlag_t slist[] = { SimFlag::kData,
00210 SimFlag::kDaqFakeData,
00211 SimFlag::kMC,
00212 SimFlag::kReroot };
00213 int n = sizeof(slist)/sizeof(forceSimFlag);
00214 string user = optarg;
00215
00216 for (int i = 0; i < n; i++) {
00217 if ( SimFlag::AsString(slist[i]) == user)
00218 forceSimFlag = slist[i];
00219 }
00220
00221 if (SimFlag::kUnknown == forceSimFlag) {
00222 printf(" -s flag (force simflag) unknown value: %s\n",
00223 user.c_str());
00224 printf(" must be followed by exactly one of: %s",
00225 SimFlag::AsString(slist[0]));
00226 for (int i = 1; i < n; i++ ) printf(", %s",
00227 SimFlag::AsString(slist[i]));
00228 printf("\n");
00229 forceSimFlag = SimFlag::kUnknown;
00230 exit(1);
00231 }
00232 }
00233 break;
00234 #endif
00235 case 'l':
00236 symlink_config = optarg;
00237 break;
00238 }
00239 }
00240
00241 logNotice("starting %s port %d, inputFileName '%s'",
00242 argv[0],port,inputFileName.c_str());
00243
00244
00245 if ( port )
00246 server = new RotoServer(port,nwords,allow_overwrite,tcp_nodelay_flag);
00247 else
00248 server = new RotoServer(inputFileName.c_str(),nwords,allow_overwrite);
00249
00250
00251 struct sigaction termAction ;
00252 termAction.sa_handler = roto_sighandler ;
00253 sigemptyset (&termAction.sa_mask) ;
00254 termAction.sa_flags = 0 ;
00255 sigaction (SIGHUP, &termAction, NULL) ;
00256 sigaction (SIGINT, &termAction, NULL) ;
00257 sigaction (SIGTERM, &termAction, NULL) ;
00258
00259 #ifdef ALLOW_FORCE
00260 if (Detector::kUnknown != forceDetector) {
00261
00262 logNotice("DANGER! overriding detector in all block IDs: %s",
00263 Detector::AsString(forceDetector));
00264 RotoObjectifier::SetForceDetector(forceDetector);
00265 }
00266 if (SimFlag::kUnknown != forceSimFlag) {
00267
00268 logNotice("DANGER! overriding simflag in all block IDs: %s",
00269 SimFlag::AsString(forceSimFlag));
00270 RotoObjectifier::SetForceSimFlag(forceSimFlag);
00271 }
00272 #endif
00273
00274
00275
00276 gROOT->SetBatch();
00277 if (gGuiFactory != gBatchGuiFactory) delete gGuiFactory;
00278 gGuiFactory = gBatchGuiFactory;
00279 #ifndef WIN32
00280 if (gVirtualX != gGXBatch) delete gVirtualX;
00281 #endif
00282 gVirtualX = gGXBatch;
00283
00284
00285 Int_t nerr = 0;
00286 if (autosave_config) nerr += config_autosave(autosave_config);
00287 if (compress_config) nerr += config_compress(compress_config);
00288 if (basketsize_config) nerr += config_basketsize(basketsize_config);
00289
00290 if (bin_output_file) nerr += server->SetFlatBinaryOutputFile(bin_output_file);
00291
00292 if (symlink_config) server->SetSymlink(symlink_config);
00293
00294 server->Run();
00295 delete server;
00296
00297 logNotice("stopping %s",argv[0]);
00298 msgLogCleanup();
00299
00300 return 0;
00301 }
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 int config_autosave(const char* config)
00320 {
00321 int nerr = 0;
00322 int len = strlen(config);
00323 char *wcopy = (char*)malloc(len+1);
00324 char stream[1024];
00325 const char *p1;
00326 char *p2;
00327 char achar;
00328 int nrec,nsec, nitems;
00329
00330
00331 p1 = config; p2 = wcopy;
00332 while (p2 < wcopy+len) {
00333 achar = *p1;
00334 if (achar != ',') *p2 = achar;
00335 else *p2 = ' ';
00336 p1++; p2++;
00337 }
00338
00339 p2 = wcopy;
00340 while (p2 < wcopy+len) {
00341 nitems = sscanf(p2,"%s %d %d",stream,&nrec,&nsec);
00342 if (nitems != 3) {
00343 logNotice("config_autosave: only %d items from \"%s\"\n",nitems,p2);
00344 nerr += 1;
00345 }
00346 else
00347 nerr += server->SetAutoSaveConfig(stream,nrec,nsec);
00348
00349 p2 = strchr(p2,';');
00350 if (!p2) break;
00351 p2++;
00352 }
00353
00354
00355 free(wcopy);
00356 wcopy = 0;
00357
00358 return nerr;
00359 }
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 int config_compress(const char* config)
00378 {
00379 int nerr = 0;
00380 int len = strlen(config);
00381 char *wcopy = (char*)malloc(len+1);
00382 char stream[1024];
00383 const char *p1;
00384 char *p2;
00385 char achar;
00386 int level, nitems;
00387
00388
00389 p1 = config; p2 = wcopy;
00390 while (p2 < wcopy+len) {
00391 achar = *p1;
00392 if (achar != ',') *p2 = achar;
00393 else *p2 = ' ';
00394 p1++; p2++;
00395 }
00396
00397 p2 = wcopy;
00398 while (p2 < wcopy+len) {
00399 nitems = sscanf(p2,"%s %d",stream,&level);
00400 if (nitems != 2) {
00401 logNotice("config_compress: only %d items from \"%s\"\n",nitems,p2);
00402 nerr += 1;
00403 }
00404 else
00405 nerr += server->SetCompressConfig(stream,level);
00406
00407 p2 = strchr(p2,';');
00408 if (!p2) break;
00409 p2++;
00410 }
00411
00412
00413 free(wcopy);
00414 wcopy = 0;
00415
00416 return nerr;
00417 }
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 int config_basketsize(const char* config)
00436 {
00437 int nerr = 0;
00438 int len = strlen(config);
00439 char *wcopy = (char*)malloc(len+1);
00440 char stream[1024];
00441 const char *p1;
00442 char *p2;
00443 char achar;
00444 int basketsize, nitems;
00445
00446
00447 p1 = config; p2 = wcopy;
00448 while (p2 < wcopy+len) {
00449 achar = *p1;
00450 if (achar != ',') *p2 = achar;
00451 else *p2 = ' ';
00452 p1++; p2++;
00453 }
00454
00455 p2 = wcopy;
00456 while (p2 < wcopy+len) {
00457 nitems = sscanf(p2,"%s %d",stream,&basketsize);
00458 if (nitems != 2) {
00459 logNotice("config_basketsize: only %d items from \"%s\"\n",nitems,p2);
00460 nerr += 1;
00461 }
00462 else
00463 nerr += server->SetBasketSizeConfig(stream,basketsize);
00464
00465 p2 = strchr(p2,';');
00466 if (!p2) break;
00467 p2++;
00468 }
00469
00470
00471 free(wcopy);
00472 wcopy = 0;
00473
00474 return nerr;
00475 }
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495 int parse_port(const char* optarg, string& inputFileName)
00496 {
00497 int port = ROOTER_PORT_DAQ;
00498
00499 enum ptype { kNumeric, kSpecial, kIsFile };
00500 ptype pType = kNumeric;
00501
00502
00503
00504 const char* c = optarg;
00505 while ( *c != '\0' ) {
00506 if ( ! isdigit(*c) ) {
00507
00508 pType = kIsFile;
00509 inputFileName = optarg;
00510 break;
00511 }
00512 c++;
00513 }
00514
00515
00516
00517
00518 if ( pType != kNumeric ) {
00519
00520 std::map<string,int> specialNames;
00521 specialNames["dcp"] = ROOTER_PORT_DAQ;
00522 specialNames["DCP"] = ROOTER_PORT_DAQ;
00523 specialNames["daq"] = ROOTER_PORT_DAQ;
00524 specialNames["DAQ"] = ROOTER_PORT_DAQ;
00525 specialNames["dcs"] = ROOTER_PORT_DCS;
00526 specialNames["DCS"] = ROOTER_PORT_DCS;
00527 specialNames["beammon"] = ROOTER_PORT_BEAMMON;
00528 specialNames["BEAMMON"] = ROOTER_PORT_BEAMMON;
00529 specialNames["BeamMon"] = ROOTER_PORT_BEAMMON;
00530
00531 int specialPort = specialNames[inputFileName];
00532 if (specialPort) {
00533 port = specialPort;
00534
00535 pType = kSpecial;
00536 }
00537 }
00538
00539 if ( pType == kNumeric) port = atoi(optarg);
00540 else if ( pType == kIsFile ) port = 0;
00541
00542 return port;
00543 }