23#include "XrdOuc/XrdOucStream.hh"
41#define XPD_MAXLEN 1024
51 static const char *msgtypes[] = {
"Undef",
52 "QuerySessions",
"SessionTag",
"SessionAlias",
"GetWorkers",
"QueryWorkers",
53 "CleanupSessions",
"QueryLogPaths",
"ReadBuffer",
"QueryROOTVersions",
54 "ROOTVersion",
"GroupProperties",
"SendMsgToUser",
"ReleaseWorker",
55 "Exec",
"GetFile",
"PutFile",
"CpFile",
"QueryMssUrl"};
57 if (type < 1000 || type >=
kUndef) {
72 static const char *reqtypes[] = {
"Undef",
73 "XP_login",
"XP_auth",
"XP_create",
"XP_destroy",
"XP_attach",
"XP_detach",
74 "XP_3107",
"XP_3108",
"XP_3109",
"XP_3110",
75 "XP_urgent",
"XP_sendmsg",
"XP_admin",
"XP_interrupt",
"XP_ping",
76 "XP_cleanup",
"XP_readbuf",
"XP_touch",
"XP_ctrlc",
"XR_direct" };
100 if (!p || strlen(p) <= 0 || p[0] ==
'/')
108 XrdOucString env(&p[1]);
109 int isl = env.find(
'/');
111 char *p1 = (isl > 0) ? (
char *)(p + isl + 2) : 0;
112 if (getenv(env.c_str())) {
113 int lenv = strlen(getenv(env.c_str()));
114 int lp1 = p1 ? strlen(p1) : 0;
115 po = (
char *)
malloc(lp1 + lenv + 2);
117 memcpy(po, getenv(env.c_str()), lenv);
119 memcpy(po+lenv+1, p1, lp1);
122 po[lp1 + lenv + 1] = 0;
133 int lpwd = strlen(getenv(
"PWD"));
135 po = (
char *)
malloc(lp + lpwd + 2);
137 memcpy(po, getenv(
"PWD"), lpwd);
138 memcpy(po+lpwd+1, p, lp);
151 char *pd = strchr(pu,
'/');
156 if (strlen(pu) > 0) {
163 int lpd = strlen(pd);
164 po = (
char *)
malloc(lpd + ldir + 2);
166 memcpy(po, ui.
fHomeDir.c_str(), ldir);
167 memcpy(po+ldir+1, pd, lpd);
169 po[lpd + ldir + 1] = 0;
193 char *po = strdup((
char *)p.c_str());
206 while ((*p < 48 || *p > 57) && (*p) !=
'\0')
213 while (*(p+j) >= 48 && *(p+j) <= 57)
218 return strtol(p, 0, 10);
228 if (!grp || strlen(grp) <= 0)
233 struct group *pgr = 0;
235#if defined(__sun) && !defined(__GNUC__)
236 pgr = getgrnam_r(grp, &
gr, buf,
sizeof(buf));
238 getgrnam_r(grp, &
gr, buf,
sizeof(buf), &pgr);
250 return ((
int) -errno);
267 struct group *pgr = 0;
269#if defined(__sun) && !defined(__GNUC__)
270 pgr = getgrgid_r((gid_t)gid, &
gr, buf,
sizeof(buf));
272 getgrgid_r((gid_t)gid, &
gr, buf,
sizeof(buf), &pgr);
284 return ((
int) -errno);
296 if (!usr || strlen(usr) <= 0)
303#if defined(__sun) && !defined(__GNUC__)
304 ppw = getpwnam_r(usr, &pw, buf,
sizeof(buf));
306 getpwnam_r(usr, &pw, buf,
sizeof(buf), &ppw);
320 return ((
int) -errno);
339#if defined(__sun) && !defined(__GNUC__)
340 ppw = getpwuid_r((uid_t)uid, &pw, buf,
sizeof(buf));
342 getpwuid_r((uid_t)uid, &pw, buf,
sizeof(buf), &ppw);
356 return ((
int) -errno);
370 const char *pw = (
const char *)buf;
372 int nw = 0, written = 0;
374 if ((nw = write(fd, pw + written, lw)) < 0) {
375 if (errno == EINTR) {
396 XPDLOC(AUX,
"Aux::LogEmsgToFile")
398 if (flog && strlen(flog)) {
400 int logfd = open(flog, O_WRONLY|O_APPEND, 0644);
402 fcntl(logfd, F_SETFD, FD_CLOEXEC);
404 XrdSysLogger logger(logfd, 0);
405 XrdSysError error(&logger,
"xpd");
407 if (emsg && strlen(emsg) > 0) error.Emsg(
"-E", pfx, emsg);
409 if (fsync(logfd) != 0)
410 TRACE(XERR,
"problem syncing file "<<flog<<
" - errno: "<<errno);
412 if (close(logfd) != 0)
413 TRACE(XERR,
"problem closing file "<<flog<<
" - errno: "<<errno);
415 TRACE(XERR,
"file "<<flog<<
" could not be opened - errno: "<<errno);
418 TRACE(XERR,
"file path undefined!");
432 XPDLOC(AUX,
"Aux::AssertDir")
436 if (!path || strlen(path) <= 0)
440 TRACE(XERR,
"could not get privileges to change ownership");
444 if (mkdir(path, 0755) != 0 && (errno != EEXIST)) {
445 TRACE(XERR,
"unable to create dir: "<<path<<
" (errno: "<<errno<<
")");
451 if (chown(path, ui.
fUid, ui.
fGid) == -1) {
452 TRACE(XERR,
"cannot set user ownership on path (errno: "<<errno<<
")");
469 XPDLOC(AUX,
"Aux::AssertBaseDir")
473 if (!path || strlen(path) <= 0)
476 XrdOucString base(path);
477 if (base.endswith(
"/")) base.erasefromend(1);
478 int isl = base.rfind(
'/');
479 if (isl != 0) base.erase(isl);
480 TRACE(DBG,
"base: " <<base);
483 if (stat(base.c_str(), &st) != 0) {
485 TRACE(XERR,
"unable to stat base path: "<<base<<
" (errno: "<<errno<<
")");
490 if (ui.
fUid != (
int) st.st_uid) {
491 unsigned pa = (st.st_mode & S_IRWXG);
492 if (ui.
fGid != (
int) st.st_gid)
493 pa |= (st.st_mode & S_IRWXO);
497 TRACE(XERR,
"effective user has not full permissions on base path: "<<base);
513 XPDLOC(AUX,
"Aux::ChangeOwn")
517 if (!path || strlen(path) <= 0)
519 DIR *dir = opendir(path);
522 XrdOucString proot(path);
523 if (!proot.endswith(
'/')) proot +=
"/";
525 struct dirent *ent = 0;
526 while ((ent = readdir(dir))) {
527 if (ent->d_name[0] ==
'.' || !strcmp(ent->d_name,
".."))
continue;
528 XrdOucString fn(proot);
533 TRACE(XERR,
"problems changing recursively ownership of: "<<fn);
543 if (errno != 0 && (errno != ENOTDIR)) {
544 TRACE(XERR,
"cannot open "<<path<<
"- errno: "<< errno);
550 TRACE(XERR,
"could not get privileges to change ownership");
554 if (chown(path, ui.
fUid, ui.
fGid) == -1) {
555 TRACE(XERR,
"cannot set user ownership on path (errno: "<<errno<<
")");
570 XPDLOC(AUX,
"Aux::ChangeMod")
572 TRACE(HDBG,
"path: "<<path);
574 if (!path || strlen(path) <= 0)
578 if (stat(path,&st) != 0) {
580 TRACE(XERR,
"unable to stat path: "<<path<<
" (errno: "<<errno<<
")");
588 TRACE(XERR,
"could not get privileges to change ownership");
592 if (chmod(path, mode) == -1) {
593 TRACE(XERR,
"cannot change permissions on path (errno: "<<errno<<
")");
599 if (S_ISDIR(st.st_mode)) {
601 DIR *dir = opendir(path);
603 TRACE(XERR,
"cannot open "<<path<<
"- errno: "<< errno);
606 XrdOucString proot(path);
607 if (!proot.endswith(
'/')) proot +=
"/";
609 struct dirent *ent = 0;
610 while ((ent = readdir(dir))) {
611 if (ent->d_name[0] ==
'.' || !strcmp(ent->d_name,
".."))
continue;
612 XrdOucString fn(proot);
616 if (stat(fn.c_str(),&xst) == 0) {
618 TRACE(HDBG,
"getting {"<<xst.st_uid<<
", "<< xst.st_gid<<
"} identity");
621 TRACE(XERR,
"could not get privileges to change ownership");
626 if (chmod(fn.c_str(), mode) == -1) {
627 TRACE(XERR,
"cannot change permissions on path (errno: "<<errno<<
")");
633 if (S_ISDIR(xst.st_mode)) {
635 TRACE(XERR,
"problems changing recursively permissions of: "<<fn);
641 TRACE(XERR,
"unable to stat dir: "<<fn<<
" (errno: "<<errno<<
")");
659 XPDLOC(AUX,
"Aux::ChangeToDir")
661 TRACE(DBG,
"changing to " << ((dir) ? dir :
"**undef***"));
663 if (!dir || strlen(dir) <= 0)
671 "}, {euid,egid}: {" << geteuid() <<
","<<getegid()<<
"}, {uid,gid}: {"<<getuid()<<
","<<getgid() <<
"}; errno: "<<errno);
674 if (chdir(dir) == -1) {
675 TRACE(XERR,
changeown <<
": can't change directory to '"<< dir<<
"'; {ui.fUid,ui.fGid}: {"<< ui.
fUid <<
","<<ui.
fGid<<
676 "}, {euid,egid}: {" << geteuid() <<
","<<getegid()<<
"}, {uid,gid}: {"<<getuid()<<
","<<getgid() <<
"}; errno: "<<errno);
680 if (chdir(dir) == -1) {
682 ", euid: " << geteuid() <<
", uid:"<<getuid()<<
"; errno: "<<errno);
697 XPDLOC(AUX,
"Aux::SymLink")
699 TRACE(DBG, path<<
" -> "<<link);
701 if (!path || strlen(path) <= 0 || !link || strlen(link) <= 0)
705 if (unlink(link) != 0 && errno != ENOENT) {
706 TRACE(XERR,
"problems unlinking existing symlink "<< link<<
707 " (errno: "<<errno<<
")");
710 if (symlink(path, link) != 0) {
711 TRACE(XERR,
"problems creating symlink " << link<<
712 " (errno: "<<errno<<
")");
730 char *val = s ? s->GetWord() : 0;
731 if (!val || strncmp(val,
"if",2)) {
744 TRACE(ALL,
">>> Warning: 'if' conditions at the end of the directive are deprecated ");
745 TRACE(ALL,
">>> Please use standard Scalla/Xrootd 'if-else-fi' constructs");
746 TRACE(ALL,
">>> (see http://xrootd.slac.stanford.edu/doc/xrd_config/xrd_config.htm)");
749 TRACE(DBG,
"Aux::CheckIf: <pattern>: " <<val);
752 XrdOucString
h(host);
753 return h.matches((
const char *)val);
762 XPDLOC(AUX,
"Aux::GetNumCPUs")
764 static int ncpu = -1;
775 XrdOucString fcpu(
"/proc/cpuinfo");
776 FILE *
fc = fopen(fcpu.c_str(),
"r");
778 if (errno == ENOENT) {
779 TRACE(XERR,
"/proc/cpuinfo missing!!! Something very bad going on");
781 XPDFORM(emsg,
"cannot open %s; errno: %d", fcpu.c_str(), errno);
787 char line[2048] = { 0 };
789 if (!strncmp(
line,
"processor", strlen(
"processor")))
798 FILE *fp = popen(
"psrinfo",
"r");
800 char line[2048] = { 0 };
801 while (fgets(
line,
sizeof(
line), fp))
806#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
809 FILE *fp = popen(
"sysctl -n hw.ncpu",
"r");
811 char line[2048] = { 0 };
812 while (fgets(
line,
sizeof(
line), fp))
818 TRACE(DBG,
"# of cores found: "<<ncpu);
821 return (ncpu <= 0) ? (
int)(-1) : ncpu ;
824#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
837int XrdProofdAux::GetMacProcList(kinfo_proc **plist,
int &nproc)
839 XPDLOC(AUX,
"Aux::GetMacProcList")
844 static const
int name[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
852 if (!plist || (*plist))
870 if ((rc = sysctl((
int *)
name, (
sizeof(
name)/
sizeof(*
name)) - 1,
871 0, &len, 0, 0)) == -1) {
878 res = (kinfo_proc *)
malloc(len);
886 if ((rc = sysctl((
int *)
name, (
sizeof(
name)/
sizeof(*
name)) - 1,
887 res, &len, 0, 0)) == -1) {
892 }
else if (rc == ENOMEM) {
899 }
while (rc == 0 && !done);
902 if (rc != 0 && !res) {
908 nproc = len /
sizeof(kinfo_proc);
923 XPDLOC(AUX,
"Aux::GetProcesses")
928 if (!pn || strlen(pn) <= 0 || !pmap) {
929 TRACE(XERR,
"invalid inputs");
932 TRACE(DBG,
"process name: "<<pn);
936#if defined(linux) || defined(__sun)
938 DIR *dir = opendir(
"/proc");
940 emsg =
"cannot open /proc - errno: ";
942 TRACE(DBG, emsg.c_str());
946 struct dirent *ent = 0;
947 while ((ent = readdir(dir))) {
948 if (
DIGIT(ent->d_name[0])) {
949 XrdOucString fn(
"/proc/", 256);
954 FILE *ffn = fopen(fn.c_str(),
"r");
956 emsg =
"cannot open file ";
957 emsg += fn; emsg +=
" - errno: "; emsg += errno;
964 char line[2048] = { 0 };
965 while (fgets(
line,
sizeof(
line), ffn)) {
967 if (strstr(
line,
"Name:")) {
968 if (strstr(
line, pn)) {
978 fn.replace(
"/status",
"/cmdline");
980 if (!(ffn = fopen(fn.c_str(),
"r"))) {
981 emsg =
"cannot open file ";
982 emsg += fn; emsg +=
" - errno: "; emsg += errno;
990 int pos = 0, ltot = 0, nr = 1;
993 while ((nr = read(fileno(ffn), p + pos, 1)) == -1 && errno == EINTR) {
1002 }
else if (nr > 0) {
1003 if (*p == 0) *p =
' ';
1011 pid = strtol(ent->d_name, 0, 10);
1012 pmap->insert(std::make_pair(pid, cmd));
1020 int ffd = open(fn.c_str(), O_RDONLY);
1022 emsg =
"cannot open file ";
1023 emsg += fn; emsg +=
" - errno: "; emsg += errno;
1029 if (read(ffd, &psi,
sizeof(psinfo_t)) !=
sizeof(psinfo_t)) {
1030 emsg =
"cannot read ";
1031 emsg += fn; emsg +=
": errno: "; emsg += errno;
1037 if (strstr(psi.pr_fname, pn)) {
1039 XrdOucString cmd(psi.pr_fname);
1040 if (cmd.length() > 0) cmd +=
" ";
1041 cmd += psi.pr_psargs;
1043 int pid = strtol(ent->d_name, 0, 10);
1044 pmap->insert(std::make_pair(pid, cmd));
1055#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
1060 if ((ern = XrdProofdAux::GetMacProcList(&pl, np)) != 0) {
1061 emsg =
"cannot get the process list: errno: ";
1070 if (strstr(pl[ii].kp_proc.p_comm, pn)) {
1072 pmap->insert(std::make_pair(pl[ii].kp_proc.p_pid, XrdOucString(pl[ii].kp_proc.p_comm)));
1083 XrdOucString cmd =
"ps ax -ww | grep proofserv 2>/dev/null";
1086 XrdOucString pids =
":";
1087 FILE *fp = popen(cmd.c_str(),
"r");
1089 char line[2048] = { 0 };
1090 while (fgets(
line,
sizeof(
line), fp)) {
1092 pmap->insert(std::make_pair(pid, XrdOucString(
line)));
1115 FILE *fid = fopen(path,
"r");
1118 if (fgets(
line,
sizeof(
line), fid)) {
1123 }
else if (errno != ENOENT) {
1124 XPDFORM(emsg,
"GetIDFromPath: error reading id from: %s (errno: %d)",
1137 if (s && strlen(s) > 0) {
1138 XrdOucString tks(tokens), tok;
1140 while ((from = tks.tokenize(tok, from,
',')) != -1)
1141 if (strstr(s, tok.c_str()))
return 1;
1155 XPDLOC(AUX,
"Aux::VerifyProcessByID")
1159 TRACE(DBG,
"pid: "<<pid);
1163 TRACE(XERR,
"invalid pid");
1170 const char *pn = (pname && strlen(pname) > 0) ? pname :
"proofserv";
1174 XrdOucString fn(
"/proc/");
1177 FILE *ffn = fopen(fn.c_str(),
"r");
1179 if (errno == ENOENT) {
1180 TRACE(DBG,
"process does not exists anymore");
1183 XPDFORM(emsg,
"cannot open %s; errno: %d", fn.c_str(), errno);
1189 char line[2048] = { 0 };
1190 if (fgets(
line,
sizeof(
line), ffn)) {
1195 XPDFORM(emsg,
"cannot read %s; errno: %d", fn.c_str(), errno);
1206 XrdOucString fn(
"/proc/");
1209 int ffd = open(fn.c_str(), O_RDONLY);
1211 if (errno == ENOENT) {
1212 TRACE(DBG,
"VerifyProcessByID: process does not exists anymore");
1215 XPDFORM(emsg,
"cannot open %s; errno: %d", fn.c_str(), errno);
1223 if (read(ffd, &psi,
sizeof(psinfo_t)) !=
sizeof(psinfo_t)) {
1224 XPDFORM(emsg,
"cannot read %s; errno: %d", fn.c_str(), errno);
1238#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
1244 if ((ern = XrdProofdAux::GetMacProcList(&pl, np)) != 0) {
1245 XPDFORM(emsg,
"cannot get the process list: errno: %d", ern);
1252 if (pl[np].kp_proc.p_pid == pid &&
1263 XrdOucString cmd =
"ps ax | grep proofserv 2>/dev/null";
1264 if (pname && strlen(pname))
1265 cmd.replace(
"proofserv", pname);
1266 FILE *fp = popen(cmd.c_str(),
"r");
1268 char line[2048] = { 0 };
1269 while (fgets(
line,
sizeof(
line), fp)) {
1295 XPDLOC(AUX,
"Aux::KillProcess")
1297 TRACE(DBG,
"pid: "<<pid<<
", forcekill: "<< forcekill);
1304 TRACE(XERR,
"could not get privileges");
1310 if (kill(pid, SIGKILL) != 0) {
1311 if (errno != ESRCH) {
1312 XPDFORM(msg,
"kill(pid,SIGKILL) failed for process %d; errno: %d", pid, errno);
1320 if (kill(pid, SIGTERM) != 0) {
1321 if (errno != ESRCH) {
1322 XPDFORM(msg,
"kill(pid,SIGTERM) failed for process %d; errno: %d", pid, errno);
1331 TRACE(DBG,
"process ID "<<pid<<
" not found in the process table");
1348 XPDLOC(AUX,
"Aux::RmDir")
1355 DIR *dir = opendir(path);
1357 TRACE(XERR,
"cannot open dir "<<path<<
" ; error: "<<errno);
1364 struct dirent *ent = 0;
1365 while ((ent = (
struct dirent *)readdir(dir))) {
1367 if (!strcmp(ent->d_name,
".") || !strcmp(ent->d_name,
".."))
continue;
1369 XPDFORM(entry,
"%s/%s", path, ent->d_name);
1370 if (stat(entry.c_str(), &st) != 0) {
1371 TRACE(XERR,
"cannot stat entry "<<entry<<
" ; error: "<<errno);
1376 if (S_ISDIR(st.st_mode)) {
1379 TRACE(XERR,
"problems removing"<<entry<<
" ; error: "<<-rc);
1384 if (unlink(entry.c_str()) != 0) {
1386 TRACE(XERR,
"problems removing"<<entry<<
" ; error: "<<-rc);
1395 if (!rc && rmdir(path) != 0) {
1397 TRACE(XERR,
"problems removing"<<path<<
" ; error: "<<-rc);
1411 XPDLOC(AUX,
"Aux::MvDir")
1415 TRACE(DBG,
"oldpath "<<oldpath<<
", newpath: "<<newpath);
1418 DIR *dir = opendir(oldpath);
1420 TRACE(XERR,
"cannot open dir "<<oldpath<<
" ; error: "<<errno);
1426 if (stat(newpath, &st) != 0 || !S_ISDIR(st.st_mode)) {
1427 TRACE(XERR,
"destination dir "<<newpath<<
1428 " does not exist or is not a directory; errno: "<<errno);
1434 XrdOucString srcentry, dstentry;
1435 struct dirent *ent = 0;
1436 while ((ent = (
struct dirent *)readdir(dir))) {
1438 if (!strcmp(ent->d_name,
".") || !strcmp(ent->d_name,
".."))
continue;
1440 XPDFORM(srcentry,
"%s/%s", oldpath, ent->d_name);
1441 if (stat(srcentry.c_str(), &st) != 0) {
1442 TRACE(XERR,
"cannot stat entry "<<srcentry<<
" ; error: "<<errno);
1447 XPDFORM(dstentry,
"%s/%s", newpath, ent->d_name);
1449 if (S_ISDIR(st.st_mode)) {
1450 mode_t srcmode = st.st_mode;
1452 if (mkdir(dstentry.c_str(), srcmode) != 0 && (errno != EEXIST)) {
1453 TRACE(XERR,
"cannot create entry "<<dstentry<<
" ; error: "<<errno);
1458 TRACE(XERR,
"problems moving "<<srcentry<<
" to "<<dstentry<<
"; error: "<<-rc);
1462 TRACE(XERR,
"problems removing "<<srcentry<<
"; error: "<<-rc);
1467 if (rename(srcentry.c_str(), dstentry.c_str()) != 0) {
1469 TRACE(XERR,
"problems moving "<<srcentry<<
" to "<<dstentry<<
"; error: "<<-rc);
1489 if (utime(path, 0) != 0)
1491 }
else if (opt <= 2) {
1493 if (stat(path, &st) != 0)
1495 struct utimbuf ut = {0,0};
1497 ut.actime = time(0);
1498 ut.modtime = st.st_mtime;
1499 }
else if (opt == 2) {
1500 ut.modtime = time(0);
1501 ut.actime = st.st_atime;
1503 if (utime(path, &ut) != 0)
1518 XPDLOC(AUX,
"Aux::ReadMsg")
1525 if (read(fd, &len,
sizeof(len)) !=
sizeof(len))
1527 TRACE(HDBG,fd<<
": len: "<<len);
1534 while ((nr = read(fd, buf, wanted)) < 0 &&
1544 len = (nr >= len) ? 0 : len - nr;
1545 }
while (nr > 0 && len > 0);
1547 TRACE(HDBG,fd<<
": buf: "<<buf);
1553 TRACE(XERR,
"pipe descriptor undefined: "<<fd);
1564 XrdOucString &before, XrdOucString &after)
1566 XPDLOC(AUX,
"ParsePidPath")
1571 if (path && strlen(path)) {
1574 XrdOucString spid, s(path);
1576 while ((from = s.tokenize(spid, from,
'.')) != -1) {
1577 if (spid.length() > 0) {
1578 if (spid.isdigit()) {
1580 pid = (
int) spid.atoi();
1586 if (nopid && pid > 0) {
1589 if (before.length() > 0) before +=
".";
1592 if (after.length() > 0) after +=
".";
1597 if (pid == 0 && before.length() == 0) {
1603 TRACE(HDBG,
"path: "<<(path ? path :
"<nul>")<<
" --> before: '"<<before
1604 <<
"', pid: "<<pid<<
", after: '"<<after<<
"'");
1616 XrdOucString rest, after;
1619 if (pid >= 0 && rest.length() > 0) {
1623 if ((ip = rest.rfind(
'.')) != STR_NPOS) {
1627 grp.erase(0, ip + 1);
1643 if (!
d || !(
d->fVal))
1655 XPDLOC(AUX,
"DoDirectiveInt")
1657 if (!
d || !(
d->fVal) || !val)
1661 if (rcf && !
d->fRcf)
1666 if (
d->fHost && cfg)
1670 long int v = strtol(val,0,10);
1671 *((
int *)
d->fVal) =
v;
1673 TRACE(DBG,
"set "<<
d->fName<<
" to "<<*((
int *)
d->fVal));
1683 XPDLOC(AUX,
"DoDirectiveString")
1685 if (!
d || !(
d->fVal) || !val)
1689 if (rcf && !
d->fRcf)
1694 if (
d->fHost && cfg)
1698 *((XrdOucString *)
d->fVal) = val;
1700 TRACE(DBG,
"set "<<
d->fName<<
" to "<<*((XrdOucString *)
d->fVal));
1709 const char *host = (
const char *)
h;
1711 if (!
d || !host || strlen(host) <= 0)
1730 if (pipe(
fPipe) != 0) {
1763 XPDLOC(AUX,
"Pipe::Post")
1768 if (msg && strlen(msg) > 0) {
1773 TRACE(HDBG,
fPipe[1] <<
": posting: type: "<<
type<<
", buf: "<<buf);
1774 int len = buf.length() + 1;
1775 XrdSysMutexHelper mh(
fWrMtx);
1776 if (write(
fPipe[1], &len,
sizeof(len)) !=
sizeof(len))
1778 if (write(
fPipe[1], buf.c_str(), len) != len)
1784 TRACE(XERR,
"pipe is invalid");
1793 XPDLOC(AUX,
"Pipe::Recv")
1797 { XrdSysMutexHelper mh(
fRdMtx);
1801 TRACE(HDBG,
fPipe[0] <<
": receiving: msg: "<< buf);
1802 msg.
Init(buf.c_str());
1807 TRACE(XERR,
"pipe is invalid");
1816 XPDLOC(AUX,
"Pipe::Poll")
1821 struct pollfd fds_r;
1822 fds_r.fd =
fPipe[0];
1823 fds_r.events = POLLIN;
1827 int xto = (to > 0) ? to * 1000 : -1;
1828 while ((pollrc = poll(&fds_r, 1, xto)) < 0 && (errno == EINTR)) {
1832 return (pollrc >= 0) ? pollrc : -errno;
1835 TRACE(XERR,
"pipe is invalid");
1853 TRACE(HDBG,
"buf: "<< (
const char *)(buf ? buf :
"+++ empty +++"));
1855 if (buf && strlen(buf) > 0) {
1860 if ((
fFrom =
fBuf.tokenize(ctyp,
fFrom,
' ')) == -1 || ctyp.length() <= 0) {
1861 TRACE(XERR,
"ctyp: "<<ctyp<<
" fFrom: "<<
fFrom);
1866 fType = ctyp.atoi();
1868 TRACE(XERR,
"ctyp: "<<ctyp<<
" fType: "<<
fType);
1874 while (
fBuf.beginswith(
' '))
1894 if ((
fFrom =
fBuf.tokenize(tkn,
fFrom,
' ')) == -1 || tkn.length() <= 0)
1898 TRACE(XERR,
"tkn: "<<tkn<<
" i: "<<i);
1915 if ((
fFrom =
fBuf.tokenize(s,
fFrom,
' ')) == -1 || s.length() <= 0) {
1934 if ((
fFrom =
fBuf.tokenize(tkn,
fFrom,
' ')) == -1 || tkn.length() <= 0) {
1935 TRACE(XERR,
"tkn: "<<tkn<<
" fFrom: "<<
fFrom);
1938 sscanf(tkn.c_str(),
"%p", p);
1966 if (s && strlen(s)) {
1967 XrdOucString kernel(s);
1969 int ib = kernel.find(
'[');
1970 if (ib == STR_NPOS)
return;
1972 int ie = kernel.find(
']', ib + 1);
1973 if (ie == STR_NPOS)
return;
1975 if (ie == ib + 1)
return;
1977 fHead.assign(kernel, 0, ib -1);
1978 fTail.assign(kernel, ie + 1);
1980 XrdOucString tkns(kernel, ib + 1, ie - 1);
1984 while ((from = tkns.tokenize(tkn, from,
',')) != -1) {
1985 if (tkn.length() > 0) {
2006 if (s && strlen(s)) {
2007 XrdOucString str(s);
2008 if (
fHead.length() <= 0 || str.beginswith(
fHead)) {
2009 if (
fTail.length() <= 0 || str.endswith(
fTail)) {
2010 str.replace(
fHead,
"");
2011 str.replace(
fTail,
"");
2012 std::list<XrdProofdMultiStrToken>::iterator it =
fTokens.begin();
2013 for (; it !=
fTokens.end(); ++it) {
2014 if ((*it).Matches(str.c_str()))
2029 XrdOucString str(
fN * (
fHead.length() +
fTail.length() + 4)) ;
2032 std::list<XrdProofdMultiStrToken>::iterator it =
fTokens.begin();
2033 for (; it !=
fTokens.end(); ++it) {
2034 int n = (*it).N(), j = -1;
2037 str += (*it).Export(j);
2044 if (str.endswith(
','))
2045 str.erase(str.rfind(
','));
2058 std::list<XrdProofdMultiStrToken>::iterator it =
fTokens.begin();
2059 for (; it !=
fTokens.end(); ++it) {
2060 int n = (*it).N(), j = -1;
2066 str += (*it).Export(j);
2092 XPDLOC(AUX,
"MultiStrToken::Init")
2100 if (s && strlen(s)) {
2103 int id =
fA.find(
'-');
2104 if (
id == STR_NPOS) {
2111 fB.assign(
fA,
id + 1);
2113 if (
fB.length() <= 0) {
2114 if (
fA.length() > 0) {
2123 char *
a = (
char *)
fA.c_str();
2124 char *
b = (
char *)
fB.c_str();
2125 if (
fA.length() == 1 &&
fB.length() == 1) {
2127 if (
fIa != LONG_MAX) {
2143 emsg =
"not-supported single-field extremes";
2148 if (
fIa != LONG_MAX &&
fIa != LONG_MIN) {
2150 if (
fIb != LONG_MAX &&
fIb != LONG_MIN &&
fIb >=
fIa) {
2156 emsg =
"non-digit or wrong-ordered extremes";
2160 emsg =
"non-digit extremes";
2182 if (s && strlen(s)) {
2184 return ((
fA == s) ? 1 : 0);
2186 XrdOucString str(s);
2189 if (str.length() > 1)
2191 char *ps = (
char *)s;
2193 if (!
DIGIT(*ps) || *ps < fIa || *ps >
fIb)
2197 if (ls == LONG_MAX || ls < fIa || ls >
fIb)
2202 if (ls == LONG_MAX || ls < fIa || ls >
fIb)
2217 XrdOucString tkn(
fA.length());
2241 tkn = (char)(
fIa + next);
2247 XrdOucString tmp(
fA.length());
2248 tmp.form(
"%ld",
fIa + next);
2250 int dl =
fA.length() - tmp.length();
2251 if (dl <= 0)
return tmp;
2254 while (dl--) tkn +=
"0";
2264 int ns,
const char *ss[5],
2266 int np,
void *pp[5],
2267 int nu,
unsigned int ui)
2270 if (!fmt || (len = strlen(fmt)) <= 0)
return;
2272 char si[32], sp[32];
2276 while (i-- > 0) {
if (ss[i]) { len += strlen(ss[i]); } }
2278 while (i-- > 0) { len += 32; }
2283 s.assign(fmt, from);
2284 int nii = 0, nss = 0, npp = 0, nui = 0;
2286 while ((k = s.find(
'%', from)) != STR_NPOS) {
2288 if (s[k+1] ==
's') {
2290 s.replace(
"%s", ss[nss++], k, k + 1);
2293 }
else if (s[k+1] ==
'd') {
2296 s.replace(
"%d", si, k, k + 1);
2299 }
else if (s[k+1] ==
'u') {
2302 s.replace(
"%u", si, k, k + 1);
2305 }
else if (s[k+1] ==
'p') {
2308 s.replace(
"%p", sp, k, k + 1);
2312 if (!replaced) from = k + 1;
2320 const char *
s0,
const char *
s1,
2321 const char *s2,
const char *s3,
const char *s4)
2323 const char *ss[5] = {
s0,
s1, s2, s3, s4};
2324 int ii[6] = {0,0,0,0,0,0};
2325 void *pp[5] = {0,0,0,0,0};
2334 int i1,
int i2,
int i3,
int i4,
int i5)
2336 const char *ss[5] = {0, 0, 0, 0, 0};
2337 int ii[6] = {i0,i1,i2,i3,i4,i5};
2338 void *pp[5] = {0,0,0,0,0};
2347 void *p0,
void *p1,
void *p2,
void *p3,
void *p4)
2349 const char *ss[5] = {0, 0, 0, 0, 0};
2350 int ii[6] = {0,0,0,0,0,0};
2351 void *pp[5] = {p0,p1,p2,p3,p4};
2361 const char *
s1,
const char *s2,
const char *s3)
2363 const char *ss[5] = {
s0,
s1, s2, s3, 0};
2364 int ii[6] = {i0,0,0,0,0,0};
2365 void *pp[5] = {0,0,0,0,0};
2374 int i0,
int i1,
int i2,
int i3)
2376 const char *ss[5] = {
s0,0,0,0,0};
2377 int ii[6] = {i0,i1,i2,i3,0,0};
2378 void *pp[5] = {0,0,0,0,0};
2387 int i0,
int i1,
unsigned int ui)
2389 const char *ss[5] = {
s0,0,0,0,0};
2390 int ii[6] = {i0,i1,0,0,0,0};
2391 void *pp[5] = {0,0,0,0,0};
2400 int i0,
int i1,
int i2)
2402 const char *ss[5] = {
s0,
s1,0,0,0};
2403 int ii[6] = {i0,i1,i2,0,0,0};
2404 void *pp[5] = {0,0,0,0,0};
2413 const char *
s0,
const char *
s1,
const char *s2)
2415 const char *ss[5] = {
s0,
s1,s2,0,0};
2416 int ii[6] = {i0,i1,0,0,0,0};
2417 void *pp[5] = {0,0,0,0,0};
2427 const char *
s1,
const char *s2,
2429 const char *s3,
const char *s4)
2431 const char *ss[5] = {
s0,
s1,s2,s3,s4};
2432 int ii[6] = {i0,i1,0,0,0,0};
2433 void *pp[5] = {0,0,0,0,0};
2442 int i0,
int i1,
const char *
s1,
2443 const char *s2,
const char *s3)
2445 const char *ss[5] = {
s0,
s1,s2,s3,0};
2446 int ii[6] = {i0,i1,0,0,0,0};
2447 void *pp[5] = {0,0,0,0,0};
2456 const char *
s1,
const char *s2,
2457 int i0,
unsigned int ui)
2459 const char *ss[5] = {
s0,
s1,s2,0,0};
2460 int ii[6] = {i0,0,0,0,0,0};
2461 void *pp[5] = {0,0,0,0,0};
2470 const char *
s0,
const char *
s1)
2472 const char *ss[5] = {
s0,
s1,0,0,0};
2473 int ii[6] = {i0,i1,i2,0,0,0};
2474 void *pp[5] = {0,0,0,0,0};
2484 const char *
s1,
const char *s2,
const char *s3,
int i0)
2486 const char *ss[5] = {
s0,
s1,s2,s3,0};
2487 int ii[6] = {i0,0,0,0,0,0};
2488 void *pp[5] = {0,0,0,0,0};
2497 int i3,
const char *
s0)
2499 const char *ss[5] = {
s0,0,0,0,0};
2500 int ii[6] = {i0,i1,i2,i3,0,0};
2501 void *pp[5] = {0,0,0,0,0};
2511 const char *ss[5] = {0,0,0,0,0};
2512 int ii[6] = {i0,i1,0,0,0,0};
2513 void *pp[5] = {p0,0,0,0,0};
2522 int i0,
int i1,
int i2,
void *p0)
2524 const char *ss[5] = {0,0,0,0,0};
2525 int ii[6] = {i0,i1,i2,0,0,0};
2526 void *pp[5] = {p0,0,0,0,0};
2535 int i0,
int i1,
int i2,
int i3,
void *p0)
2537 const char *ss[5] = {0,0,0,0,0};
2538 int ii[6] = {i0,i1,i2,i3,0,0};
2539 void *pp[5] = {p0,0,0,0,0};
2548 void *p0,
int i2,
int i3)
2550 const char *ss[5] = {0,0,0,0,0};
2551 int ii[6] = {i0,i1,i2,i3,0,0};
2552 void *pp[5] = {p0,0,0,0,0};
2562 const char *ss[5] = {0,0,0,0,0};
2563 int ii[6] = {i0,i1,0,0,0,0};
2564 void *pp[5] = {p0,0,0,0,0};
2573 const char *
s0,
void *p0,
int i0,
int i1)
2575 const char *ss[5] = {
s0,0,0,0,0};
2576 int ii[6] = {i0,i1,0,0,0,0};
2577 void *pp[5] = {p0,0,0,0,0};
2586 void *p0,
const char *
s0,
int i0)
2588 const char *ss[5] = {
s0,0,0,0,0};
2589 int ii[6] = {i0,0,0,0,0,};
2590 void *pp[5] = {p0,0,0,0,0};
2599 const char *
s0,
const char *
s1,
void *p0)
2601 const char *ss[5] = {
s0,
s1,0,0,0};
2602 int ii[6] = {0,0,0,0,0,0};
2603 void *pp[5] = {p0,0,0,0,0};
2612 const char *
s0,
const char *
s1,
int i1,
int i2)
2614 const char *ss[5] = {
s0,
s1,0,0,0};
2615 int ii[6] = {i0,i1,i2,0,0,0};
2616 void *pp[5] = {0,0,0,0,0};
2625 const char *
s0,
int i1,
int i2)
2627 const char *ss[5] = {
s0,0,0,0,0};
2628 int ii[6] = {i0,i1,i2,0,0,0};
2629 void *pp[5] = {0,0,0,0,0};
#define TRACE(Flag, Args)
int SetHostInDirectives(const char *, XrdProofdDirective *d, void *h)
Set host field for directive 'd' to (const char *h)
int DoDirectiveInt(XrdProofdDirective *d, char *val, XrdOucStream *cfg, bool rcf)
Process directive for an integer.
int DoDirectiveClass(XrdProofdDirective *d, char *val, XrdOucStream *cfg, bool rcf)
Generic class directive processor.
int DoDirectiveString(XrdProofdDirective *d, char *val, XrdOucStream *cfg, bool rcf)
Process directive for a string.
#define IDXTOLET(ilet, x)
#define LETTOIDX(x, ilet)
#define XpdBadPGuard(g, u)
static struct mg_connection * fc(struct mg_context *ctx)
int Get(int &i)
Get next token and interpret it as an int.
int Init(const char *buf)
Init from buffer.
static int ChangeOwn(const char *path, XrdProofUI ui)
Change the ownership of 'path' to the entity described by 'ui'.
static int GetUserInfo(const char *usr, XrdProofUI &ui)
Get information about user 'usr' in a thread safe way.
static int MvDir(const char *oldpath, const char *newpath)
Move content of directory at oldpath to newpath.
static int Touch(const char *path, int opt=0)
Set access (opt == 1), modify (opt =2 ) or access&modify (opt = 0, default) times of path to current ...
static void Form(XrdOucString &s, const char *fmt, int ns, const char *ss[5], int ni, int ii[6], int np, void *pp[5], int nu=0, unsigned int ui=0)
Recreate the string according to 'fmt', the up to 5 'const char *', up to 6 'int' arguments,...
static int ParseUsrGrp(const char *path, XrdOucString &usr, XrdOucString &grp)
Parse a path in the form of "<usr>[.<grp>][.<pid>]", filling 'usr' and 'grp'.
static int AssertDir(const char *path, XrdProofUI ui, bool changeown)
Make sure that 'path' exists and is owned by the entity described by 'ui'.
static int VerifyProcessByID(int pid, const char *pname="proofserv")
Check if a process named 'pname' and process 'pid' is still in the process table.
static long int GetLong(char *str)
Extract first integer from string at 'str', if any.
static const char * ProofRequestTypes(int type)
Translates the proof request type in a human readable string.
static int KillProcess(int pid, bool forcekill, XrdProofUI ui, bool changeown)
Kill the process 'pid'.
static bool HasToken(const char *s, const char *tokens)
Returns true is 's' contains at least one of the comma-separated tokens in 'tokens'.
static int GetGroupInfo(const char *grp, XrdProofGI &gi)
Get information about group with 'gid' in a thread safe way.
static int ChangeToDir(const char *dir, XrdProofUI ui, bool changeown)
Change current directory to 'dir'.
static int ChangeMod(const char *path, unsigned int mode)
Change the permission mode of 'path' to 'mode'.
static int GetNumCPUs()
Find out and return the number of CPUs in the local machine.
static int GetProcesses(const char *pn, std::map< int, XrdOucString > *plist)
Get from the process table list of PIDs for processes named "proofserv' For {linux,...
static int ReadMsg(int fd, XrdOucString &msg)
Receive 'msg' from pipe fd.
static int GetIDFromPath(const char *path, XrdOucString &emsg)
Extract an integer from a file.
static int Write(int fd, const void *buf, size_t nb)
Write nb bytes at buf to descriptor 'fd' ignoring interrupts Return the number of bytes written or -1...
static XrdSysRecMutex fgFormMutex
static void LogEmsgToFile(const char *flog, const char *emsg, const char *pfx=0)
Logs error message 'emsg' to file 'flog' using standard technology.
static int RmDir(const char *path)
Remove directory at path and its content.
static int SymLink(const char *path, const char *link)
Create a symlink 'link' to 'path' Return 0 in case of success, -1 in case of error.
static const char * AdminMsgType(int type)
Translates the admin message type in a human readable string.
static int CheckIf(XrdOucStream *s, const char *h)
Check existence and match condition of an 'if' directive If none (valid) is found,...
static char * Expand(char *p)
Expand path 'p' relative to: $HOME if begins with ~/ <user>'s $HOME if begins with ~<user>/ $PWD if d...
static int ParsePidPath(const char *path, XrdOucString &before, XrdOucString &after)
Parse a path in the form of "<before>[.<pid>][.<after>]", filling 'rest' and returning 'pid'.
static int AssertBaseDir(const char *path, XrdProofUI ui)
Make sure that the base dir of 'path' is either owned by 'ui' or gives full permissions to 'ui'.
XrdOucString Export(int &next)
Export 'next' token; use next < 0 start from the first.
bool Matches(const char *s)
Return true if 's' is compatible with this token.
void Init(const char *s)
Init the multi-string token.
XrdOucString Export()
Return a string with comma-separated elements.
void Init(const char *s)
Init the multi-string handler.
std::list< XrdProofdMultiStrToken > fTokens
XrdOucString Get(int i)
Return i-th combination (i : 0 -> fN-1)
bool Matches(const char *s)
Return true if 's' is compatible with this multi-string.
int Recv(XpdMsg &msg)
Recv message from the pipe.
int Poll(int to=-1)
Poll over the read pipe for to secs; return whatever poll returns.
void Close()
If open, close and invalidated the pipe descriptors.
XrdProofdPipe()
Constructor: create the pipe.
virtual ~XrdProofdPipe()
Destructor.
int Post(int type, const char *msg)
Post message on the pipe.
int changeown(const std::string &path, uid_t u, gid_t g)
Change the ownership of 'path' to the entity described by {u,g}.