78{
80 {public:
83
87};
88
90 {public:
91 std::map<std::string, int>
actMap;
92 std::map<std::string, MapInfo>
r2aMap;
93 std::map<std::string, MapInfo>
u2aMap;
99
102 };
103
104
105
106std::map<std::string, ExpInfo>
expMap;
108std::map<std::string, ExpInfo*>
v2eMap;
109
110
111
119
120
122
125static
129
130static const int domAny = 0;
131static const int domLcl = 1;
132static const int domRmt = 2;
133
138
143
147
151
154
156 std::set<std::string>
x2aSet;
157 std::set<std::string>
x2eSet;
158
161 };
162
164}
166
167
168
169
170
171
172
173
174
176 const char *path,
177 const char *cgi,
178 const char *app)
179{
181 int eCode, aCode;
182
183
184
189 {
const char *urName = addrInfo.
Name();
191 {const char *dot = index(urName, '.');
193 }
194 }
196 {
DBGID(client.
tident,
"Skipping sending flow info; unwanted domain");
197 return 0;
198 }
199 }
200
201
202
203
204 if (!getCodes(client, path, cgi, eCode, aCode))
205 {
TRACE(
"Unable to determine experiment; flow not marked.");
206 return 0;
207 }
208
209
210
213}
214
215
216
220{
221
222
223
224
225
226
227
228
229
230
231
232
233
236 if (pmFF->
Start(addrInfo))
return pmFF;
237 delete pmFF;
238 }
239
240
241
242 return 0;
243}
244
245
246
247
248
251{
252 class DelCfgInfo
253 {
public: DelCfgInfo(
CfgInfo *&cfg) : cfgInfo(cfg) {}
254 ~DelCfgInfo() {if (cfgInfo) {delete cfgInfo; cfgInfo = 0;}}
255 private:
258
259
260
263 return 0;
264 }
265
266
267
271 fatal = false;
272
273
274
279 } else {
281 eLog->
Say(
"Config warning: firefly disabled; "
282 "configuration incomplete!");
283 return 0;
284 }
286
287
288
290
291
292
295 eLog->
Say(
"Config warning: ignoring defsfile; "
296 "no mappings have been specified!");
298 } else {
300 {
eLog->
Say(
"Config invalid: pmark mappings cannot be resolved "
301 "without specifying defsfile!");
302 fatal = true;
303 return 0;
304 }
306 if (!ConfigDefs())
308 {fatal = true;
309 return 0;
310 }
311 eLog->
Say(
"Config warning: pmark ignoring defsfile; "
312 "unable to process and nofail is in effect!");
313 }
314 }
315
316
317
318
320
321
322
323 bool aOK = false;
326 char buff[1024];
328 if (eTxt)
329 {snprintf(buff,
sizeof(buff),
"%s:%d; %s",
ffDest,
ffPortD, eTxt);
330 eLog->
Emsg(
"Config",
"pmark unable to create UDP tunnel to", buff);
332 fatal = true;
333 return 0;
334 }
335 if (spec.
Format(buff,
sizeof(buff)))
337 if (!aOK)
338 {
eLog->
Emsg(
"Config",
"pmark unable to create UDP tunnel to",
ffDest);
339 fatal = true;
343 return 0;
344 }
345 }
346
347
348
351 if (!aOK)
352 {
eLog->
Emsg(
"Config",
"pmark unable to create origin UDP tunnel");
353 fatal = true;
355 return 0;
356 }
357 }
358
359
360
362
363
364
368 else eDest->
Say(
"Config warning: Unable to determine local domain; "
369 " domain check restricted to IP address type!");
370 }
371
372
373
375}
376
377
378
379
380
381namespace
382{
383bool Recover()
384{
385 if (!
noFail)
return false;
387 return true;
388}
389}
390
391bool XrdNetPMarkCfg::ConfigDefs()
392{
393 class Const2Char
394 {public:
395 char *data;
396 Const2Char(const char *str) : data(strdup(str)) {}
397 ~Const2Char() {free(data);}
398 };
400 std::set<std::string>::iterator it;
401 std::map<std::string, ExpInfo>::iterator itE;
402 bool isDload, aOK = true;
403
404
405
407 return Recover();
408
409
410
411 aOK = LoadFile();
412
413
414
416
417
418
419 if (!aOK) return Recover();
420
421
422
424 {Const2Char pv(it->c_str());
425 if (!ConfigPV2E(pv.data)) aOK = false;
426 }
428
429
430
432 {Const2Char ru(it->c_str());
433 if (!ConfigRU2A(ru.data)) aOK = false;
434 }
436
437
438
439
441 while(itE !=
expMap.end())
442 {if (itE->second.inUse)
443 {itE->second.Roles = itE->second.r2aMap.size() != 0;
444 itE->second.Users = itE->second.u2aMap.size() != 0;
445 itE++;
446 } else {
447 DEBUG(
"Deleting unused experiment '"<<itE->first.c_str()<<
"'");
449 }
450 }
451 if (aOK &&
expMap.size() == 0)
454 {
eDest->
Say(
"Config warning: No experiments referenced; "
455 "packet marking restricted to scitagged url's!");
456 } else {
457 eDest->
Say(
"Config warning: No experiments referenced and scitags "
458 "not enabled; packet marking has been disabled!");
460 }
461 } else if (!aOK)
466 }
467 return aOK;
468}
469
470
471
472
473
474namespace
475{
476void Complain(const char *rWho, const char *rName,
477 const char *uWho, const char *uName, const char *eName=0)
478{
479 char *et0P = 0, eText0[256], eText1[256], eText2[256];
480 if (eName)
481 {snprintf(eText0, sizeof(eText0), "experiment %s", eName);
482 et0P = eText0;
483 }
484 snprintf(eText1, sizeof(eText1), "%s '%s'", rWho, rName);
485 snprintf(eText2, sizeof(eText2), "%s '%s'", uWho, uName);
486 eDest->
Say(
"Config failure: ",et0P, eText1,
" references undefined ",eText2);
487}
488}
489
490
491
492bool XrdNetPMarkCfg::ConfigPV2E(char *info)
493{
494 std::map<std::string, ExpInfo >::iterator itE;
495 std::map<std::string, ExpInfo*>::iterator itV;
496 char *eName, *xName, *xType = info;
497 xName = index(info, ' '); *xName = 0; xName++;
498 eName = index(xName, ' '); *eName = 0; eName++;
499
500 if ((itE =
expMap.find(std::string(eName))) ==
expMap.end())
501 {Complain(xType, xName, "experiment", eName);
502 return false;
503 }
504 itE->second.inUse = true;
505
506 if (*xType == 'd')
508 return true;
509 }
510
511 if (*xType == 'p')
513 if (p2nP)
516 } else {
518 (xName, eName, &(itE->second)));
520 }
521 } else {
522 itV =
v2eMap.find(std::string(xName));
523 if (itV !=
v2eMap.end()) itV->second = &(itE->second);
524 else v2eMap[xName] = &(itE->second);
525 }
526
527 return true;
528}
529
530
531
532
533
534
535
536bool XrdNetPMarkCfg::ConfigRU2A(char *info)
537{
538 std::map<std::string, int>::iterator itA;
539 std::map<std::string, ExpInfo>::iterator itE;
540 std::map<std::string, MapInfo>::iterator itX;
541 char *aName, *eName, *xName, *xType;
542 eName = info;
543 xType = index(info, ' '); *xType = 0; xType++;
544 xName = index(xType, ' '); *xName = 0; xName++;
545 aName = index(xName, ' '); *aName = 0; aName++;
546
547 if ((itE =
expMap.find(std::string(eName))) ==
expMap.end())
548 {Complain(xType, xName, "experiment", eName);
549 return false;
550 }
551
552 itA = itE->second.actMap.find(std::string(aName));
553 if (itA == itE->second.actMap.end())
554 {Complain(xType, xName, "activity", aName, eName);
555 return false;
556 }
557
558 if (*xType == 'd') itE->second.dAct = itA->second;
559 else {std::map<std::string, MapInfo> &xMap =
560 (*xType == 'r' ? itE->second.r2aMap : itE->second.u2aMap);
561
562 itX = xMap.find(std::string(xName));
563 if (itX != xMap.end())
564 {itX->second.Name = aName; itX->second.Code = itA->second;}
565 else xMap[std::string(xName)] =
MapInfo(aName, itA->second);
566 }
567
568 return true;
569}
570
571
572
573
574
575namespace
576{
577const char *Code2S(int code)
578{
579 static char buff[16];
580 snprintf(buff, sizeof(buff), " [%d]", code);
581 return buff;
582}
583
584void ShowActs(std::map<std::string, MapInfo>& map, const char *hdr,
585 const char *mName)
586{
587 std::map<std::string, MapInfo>::iterator it;
588
589 for (it = map.begin(); it != map.end(); it++)
590 {
eDest->
Say(hdr, mName, it->first.c_str(),
" activity ",
591 it->second.Name.c_str(), Code2S(it->second.Code));
592 }
593}
594}
595
596void XrdNetPMarkCfg::Display()
597{
598 std::map<std::string, ExpInfo>::iterator itE;
599 std::map<int, std::vector<const char*>> pvRefs;
600 const char *hdr = " ", *hdrplu = " ++ ";
601 char buff[80];
602
603
604
605 std::map<int, std::vector<const char*>>::iterator it2E;
607
608 while(p2e)
610 if ((it2E = pvRefs.find(expinfo->
Code)) != pvRefs.end())
611 it2E->second.push_back(p2e->
thePath());
612 else {std::vector<const char*> vec;
614 pvRefs[expinfo->
Code] = vec;
615 }
617 }
618
619
620
621 std::map<std::string, ExpInfo*>::iterator itV;
623 {int eCode = itV->second->Code;
624 if ((it2E = pvRefs.find(eCode)) != pvRefs.end())
625 it2E->second.push_back(itV->first.c_str());
626 else {std::vector<const char*> vec;
627 vec.push_back(itV->first.c_str());
628 pvRefs[eCode] = vec;
629 }
630 }
631
632
633
634
635 snprintf(buff,
sizeof(buff),
"%d",
static_cast<int>(
expMap.size()));
636 const char *txt = (
expMap.size() == 1 ?
" expirement " :
" experiments ");
637 eDest->
Say(
"Config pmark results: ", buff, txt,
"directly referenced:");
638
639
640
642 {int expCode = itE->second.Code;
643 eDest->
Say(hdr, itE->first.c_str(), Code2S(expCode),
644 (&itE->second ==
expDflt ?
" (default)" : 0));
645 if ((it2E = pvRefs.find(expCode)) != pvRefs.end())
646 {std::vector<const char*> &vec = it2E->second;
647 for (int i = 0; i < (int)vec.size(); i++)
648 {const char *rType = (*vec[i] == '/' ? "path " : "vorg ");
650 }
651 }
652 if (itE->second.u2aMap.size() != 0)
653 ShowActs(itE->second.u2aMap, hdrplu, "user ");
654 if (itE->second.r2aMap.size() != 0)
655 ShowActs(itE->second.r2aMap, hdrplu, "role ");
656 if (itE->second.dAct >= 0)
657 {std::map<std::string, int>::iterator itA;
658 int aCode = itE->second.dAct;
659 for (itA = itE->second.actMap.begin();
660 itA != itE->second.actMap.end(); itA++)
661 {if (aCode == itA->second)
662 {
eDest->
Say(hdrplu,
"Default activity ",
663 itA->first.c_str(), Code2S(aCode));
664 break;
665 }
666 }
667 if (itA == itE->second.actMap.end()) itE->second.dAct = -1;
668 }
669 }
670}
671
672
673
674
675
676const char *XrdNetPMarkCfg::Extract(const char *sVec, char *buff, int blen)
677{
678 const char *space;
679
680
681
682 if (!(space = index(sVec, ' '))) return sVec;
683
684
685
686 int n = space - sVec;
687 if (!n || n >= blen) return 0;
688 snprintf(buff, blen, "%.*s", n, sVec);
689 return buff;
690}
691
692
693
694
695
696bool XrdNetPMarkCfg::FetchFile()
697{
700 char tmo[16], outfile[512];
701 int rc;
702
703
704
706 {
eDest->
Emsg(
"Config", rc,
"setup job to fetch defsfile");
707 return false;
708 }
709
710
711
712 snprintf(outfile, sizeof(outfile), "/tmp/XrdPMark-%ld.json",
713 static_cast<long>(getpid()));
715
716
717
718 snprintf(tmo,
sizeof(tmo),
"%d",
Cfg->
defsTO);
722
723
724
729 }
730
731
732
734 if (rc)
735 {snprintf(outfile, sizeof(outfile), "failed with rc=%d", rc);
737 return false;
738 }
739
740
741
743 return true;
744}
745
746
747
748
749
750bool XrdNetPMarkCfg::getCodes(
XrdSecEntity &client,
const char *path,
751 const char *cgi, int &ecode, int &acode)
752{
754
755
756
758
759
760
762
763
764
767 if (p2nP) expP = p2nP->
theValu();
768 }
769
770
771
773 {std::map<std::string, ExpInfo*>::iterator itV;
774 char voBuff[256];
775 const char *VO = Extract(client.
vorg, voBuff,
sizeof(voBuff));
777 expP = itV->second;
778 }
779
780
781
783
784
785
786 if (!expP) return false;
788
789
790
792 {std::map<std::string, MapInfo>::iterator itU;
793 itU = expP->
u2aMap.find(std::string(client.
name));
794 if (itU != expP->
u2aMap.end())
795 {acode = itU->second.Code;
796 return true;
797 }
798 }
799
800
801
803 {std::map<std::string, MapInfo>::iterator itR;
804 char roBuff[256];
805 const char *RO = Extract(client.
role, roBuff,
sizeof(roBuff));
806 if (RO)
807 {itR = expP->
r2aMap.find(std::string(client.
role));
808 if (itR != expP->
r2aMap.end())
809 {acode = itR->second.Code;
810 return true;
811 }
812 }
813 }
814
815
816
817 acode = (expP->
dAct >= 0 ? expP->
dAct : 0);
818 return true;
819}
820
821
822
823
824
825using json = nlohmann::json;
826
827namespace
828{
829const char *MsgTrim(const char *msg)
830{
831 const char *sP;
832 if ((sP = index(msg, ' ')) && *(sP+1)) return sP+1;
833 return msg;
834}
835}
836
837bool XrdNetPMarkCfg::LoadFile()
838{
839 struct fBuff {char *buff; fBuff() : buff(0) {}
840 ~fBuff() {if (buff) free(buff);}
841 } defs;
842 int rc;
843
844
845
848 return false;
849 }
850
851
852
853
854 try {bool result = LoadJson(defs.buff);
855 return result;
856 } catch (json::exception& e)
857 {
eDest->
Emsg(
"Config",
"Unable to process defsfile;",
858 MsgTrim(e.what()));
859 }
860 return false;
861}
862
863
864
865
866
867bool XrdNetPMarkCfg::LoadJson(char *buff)
868{
870 std::map<std::string, ExpInfo>::iterator itE;
871
872
873
874 j = json::parse(buff);
875
876
877
878 std::string modDate;
879 json j_mod = j[
"modified"];
880 if (j_mod != 0) modDate = j_mod.get<std::string>();
881 else modDate = "*unspecified*";
882
884 "' last modified on ", modDate.c_str());
885
886
887
888 json j_exp = j[
"experiments"];
889 if (j_exp == 0)
890 {
eDest->
Emsg(
"Config",
"The defsfile does not define any experiments!");
891 return false;
892 }
893
894
895
896
897 for (auto it : j_exp)
898 {std::string expName = it["expName"].get<std::string>();
899 if (expName.empty()) continue;
900 if (!it[
"expId"].is_number() || it[
"expId"] <
minExpID || it[
"expId"] >
maxExpID)
901 {
eDest->
Say(
"Config warning: ignoring experiment '", expName.c_str(),
902 "'; associated ID is invalid.");
903 continue;
904 }
906
908 {
eDest->
Say(
"Config warning: ignoring experiment '", expName.c_str(),
909 "'; map insertion failed!");
910 continue;
911 }
912
913 json j_acts = it[
"activities"];
914 if (j_acts == 0)
915 {
eDest->
Say(
"Config warning: ignoring experiment '", expName.c_str(),
916 "'; has no activities!");
917 continue;
918 }
919
920 for (unsigned int i = 0; i < j_acts.size(); i++)
921 {std::string actName = j_acts[i]["activityName"].get<std::string>();
922 if (actName.empty()) continue;
923 if (!j_acts[i]["activityId"].is_number()
924 || j_acts[i][
"activityId"] <
minActID
925 || j_acts[i][
"activityId"] >
maxActID)
926 {
eDest->
Say(
"Config warning:",
"ignoring ", expName.c_str(),
927 " actitivity '", actName.c_str(),
928 "'; associated ID is invalid.");
929 continue;
930 }
931 itE->second.actMap[actName] = j_acts[i]["activityId"].get<int>();
932 }
933 }
934
935
936
938 {
eDest->
Say(
"Config warning: unable to define any experiments via defsfile!");
939 return false;
940 }
941 return true;
942}
943
944
945
946
947
949{
950
951
952
953
954
955
956
957
958
959
960
961 std::string name;
962 char *val;
963
964
965
967
968
969
970 if (!(val =
Config.GetWord()))
971 {
eLog->
Say(
"Config invalid: pmark argument not specified");
return 1;}
972
973
974
975do{if (!strcmp("debug", val) || !strcmp("nodebug", val))
977 continue;
978 }
979
980 if (!strcmp("defsfile", val))
981 {
if (!(val =
Config.GetWord()))
982 {
eLog->
Say(
"Config invalid: pmark defsfile value not specified");
983 return 1;
984 }
985
986 if (*val == '/')
988 continue;
989 }
990
991 if (strcmp("curl", val) && strcmp("wget", val))
992 {
eLog->
Say(
"Config invalid: unknown defsfile transfer agent '",val,
"'");
993 return 1;
994 }
996 {
eLog->
Say(
"Config invalid: defsfile transfer agent '",val,
"' not found.");
997 return 1;
998 }
999
1000 if (*val == 'c')
1002 } else {
1004 }
1005
1007 if (val && isdigit(*val))
1009 return 1;
1011 }
1012
1013 if (!val) {
eLog->
Say(
"Config invalid: pmark defsfile url not specified");
1014 return 1;
1015 }
1017 continue;
1018 }
1019
1020 if (!strcmp("domain", val))
1021 {
if (!(val =
Config.GetWord()))
1022 {
eLog->
Say(
"Config invalid: pmark domain value not specified");
1023 return 1;
1024 }
1025 if (!strcmp(val, "any" )
1029 else {
eLog->
Say(
"Config invalid: pmark invalid domain determinant '",
1030 val, "'");
1031 return 1;
1032 }
1033 continue;
1034 }
1035
1036 if (!strcmp("fail", val) || !strcmp("nofail", val))
1038 continue;
1039 }
1040
1041
1042
1043
1044 if (!strcmp("ffdest", val))
1045 {const char *addtxt = "";
1046 char *colon, *comma;
1047 int xPort;
1049 do {if (!val || *val == 0 || *val == ',' || *val == ':')
1050 {
eLog->
Say(
"Config invalid: pmark ffdest value not specified",
1051 addtxt); return 1;
1052 }
1053 if ((comma = index(val, ','))) *comma++ = 0;
1054 if ((colon = index(val, ':')))
1055 {*colon++ = 0;
1057 return 1;
1059 if (!strcmp(val,
"origin"))
ffPortO = xPort;
1063 }
1064 addtxt = " after comma";
1065 } while((val = comma));
1067 continue;
1068 }
1069
1070 if (!strcmp("ffecho", val))
1071 {
if (!(val =
Config.GetWord()))
1072 {
eLog->
Say(
"Config invalid: pmark ffecho value not specified");
1073 return 1;
1074 }
1077 continue;
1078 }
1079
1080 if (!strcmp("map2act", val))
1081 {
if (!(val =
Config.GetWord()))
1082 {
eLog->
Say(
"Config invalid: pmark activity experiment not specified");
1083 return 1;
1084 }
1085 name = val;
1086
1087 if (!(val =
Config.GetWord()))
1088 {
eLog->
Say(
"Config invalid: pmark activity determinant not specified");
1089 return 1;
1090 }
1091
1092 const char *adet;
1093 if (!strcmp(val, "default")) adet = "dflt";
1094 else if (!strcmp(val, "role")) adet = "role";
1095 else if (!strcmp(val, "user")) adet = "user";
1096 else {
eLog->
Say(
"Config invalid: pmark invalid activity determinant '",
1097 val, "'");
1098 return 1;
1099 }
1100 name += ' '; name += val;
1101
1102 if (*adet !=
'd' && !(val =
Config.GetWord()))
1103 {
eLog->
Say(
"Config invalid: pmark activity", adet,
"not specified");
1104 return 1;
1105 }
1106 name += ' '; name += val;
1107
1108 if (!(val =
Config.GetWord()))
1109 {
eLog->
Say(
"Config invalid: pmark", adet,
"activity not specified");
1110 return 1;
1111 }
1112 name += ' '; name += val;
1113
1115 continue;
1116 }
1117
1118 if (!strcmp("map2exp", val))
1119 {
if (!(val =
Config.GetWord()))
1120 {
eLog->
Say(
"Config invalid: pmark map2exp type not specified");
1121 return 1;
1122 }
1123 if (strcmp("default", val) && strcmp("path", val)
1124 && strcmp("vo", val) && strcmp("vorg", val))
1125 {
eLog->
Say(
"Config invalid: invalid pmark map2exp type, '",val,
"'.");
1126 return 1;
1127 }
1128 name = val;
1129
1130 if (*val !=
'd' && !(val =
Config.GetWord()))
1131 {
eLog->
Say(
"Config invalid: pmark map2exp ", name.c_str(),
1132 "not specified");
1133 return 1;
1134 }
1135 name += ' '; name += val;
1136
1137 if (!(val =
Config.GetWord()))
1138 {
eLog->
Say(
"Config invalid: pmark map2exp expirement not specified");
1139 return 1;
1140 }
1141 name += ' '; name += val;
1142
1144 continue;
1145 }
1146
1147 if (!strcmp("trace", val) || !strcmp("notrace", val))
1149 continue;
1150 }
1151
1152 if (!strcmp("use", val))
1153 {
if (!(val =
Config.GetWord()))
1154 {
eLog->
Say(
"Config invalid: pmark use argument not specified");
1155 return 1;
1156 }
1157 bool argOK = false;
1158 char *arg;
1159 do {bool theval = strncmp(val, "no", 2) != 0;
1160 arg = (!theval ? val += 2 : val);
1161 if (!strcmp("flowlabel", arg))
1163 else if (!strcmp("flowlabel+ff", arg))
1165 else if (!strcmp("firefly", arg))
1166 {
useFFly = (theval ? 1 : 0); argOK =
true;}
1167 else if (!strcmp(
"scitag", arg)) {
useSTag = theval; argOK =
true;}
1168 else if (argOK) {
Config.RetToken();
break;}
1169 else {
eLog->
Say(
"Config invalid: 'use ",val,
"' is invalid");
1170 return 1;
1171 }
1172 }
while((val =
Config.GetWord()));
1173 if (!val) break;
1174 continue;
1175 }
1176
1177 eLog->
Say(
"Config warning: ignoring unknown pmark argument'",val,
"'.");
1178
1179 }
while ((val =
Config.GetWord()));
1180
1181 return 0;
1182}
static XrdSysError eDest(0,"crypto_")
static bool isHostName(const char *name)
int Format(char *bAddr, int bLen, fmtUse fmtType=fmtAuto, int fmtOpts=0)
const char * Name(const char *eName=0, const char **eText=0)
const char * Set(const char *hSpec, int pNum=PortInSpec)
static int Parse(XrdSysError *eLog, XrdOucStream &Config)
static XrdNetPMark * Config(XrdSysError *eLog, XrdScheduler *sched, XrdSysTrace *trc, bool &fatal)
XrdNetPMark::Handle * Begin(XrdSecEntity &Client, const char *path=0, const char *cgi=0, const char *app=0) override
std::map< std::string, int > actMap
std::map< std::string, MapInfo > u2aMap
std::map< std::string, MapInfo > r2aMap
bool Start(XrdNetAddrInfo &addr)
static bool getEA(const char *cgi, int &ecode, int &acode)
static const int maxExpID
static const int minActID
static const int maxActID
static const int minExpID
static char * MyHostName(const char *eName="*unknown*", const char **eText=0)
void RepName(const char *newname)
void Insert(XrdOucMapP2X< T > *newp)
XrdOucMapP2X< T > * Match(const char *pd, const int pl=0)
XrdOucMapP2X< T > * Find(const char *path)
XrdOucMapP2X< T > * theNext()
const char * c_str() const
static bool findPgm(const char *pgm, XrdOucString &path)
static char * getFile(const char *path, int &rc, int maxsz=10240, bool notempty=true)
static int a2tm(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
static int a2p(XrdSysError &, const char *ptype, const char *val, bool anyOK=true)
char * vorg
Entity's virtual organization(s)
XrdNetAddrInfo * addrInfo
Entity's connection details.
const char * tident
Trace identifier always preset.
char * name
Entity's name.
char * role
Entity's role(s)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
void Say(const char *text1, const char *text2=0, const char *txt3=0, const char *text4=0, const char *text5=0, const char *txt6=0)
std::map< std::string, ExpInfo > expMap
std::map< std::string, ExpInfo * > v2eMap
XrdOucMapP2X< ExpInfo * > p2eMap
std::set< std::string > x2eSet
const char * pgmOpts[pgmOptN]
std::set< std::string > x2aSet