From bcacd4af98df7a2a3346317907d75c3c6bb9b32a Mon Sep 17 00:00:00 2001 From: Andrew Hanushevsky Date: Wed, 6 Apr 2022 22:32:20 -0700 Subject: [PATCH] [Server] Allow set variable values to come from a file. --- src/XrdOuc/XrdOucStream.cc | 57 ++++++++++++++++++++++++++++++++------ src/XrdOuc/XrdOucStream.hh | 1 + 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/XrdOuc/XrdOucStream.cc b/src/XrdOuc/XrdOucStream.cc index 8460e171f4f..1eba3f8e912 100644 --- a/src/XrdOuc/XrdOucStream.cc +++ b/src/XrdOuc/XrdOucStream.cc @@ -1318,6 +1318,32 @@ char *XrdOucStream::doif() return 0; } +/******************************************************************************/ +/* g e t V a l u e */ +/******************************************************************************/ + +int XrdOucStream::getValue(const char *path, char *vbuff, int vbsz) +{ + struct stat Stat; + int n, rc = 0, vFD; + +// Make sure the file exists and it not too big +// + if (stat(path, &Stat)) return errno; + if (Stat.st_size >= vbsz) return EFBIG; + +// Open the file and read it in +// + if ((vFD = XrdSysFD_Open(path, O_RDONLY)) < 0) return errno; + if ((n = read(vFD, vbuff, vbsz-1)) >= 0) vbuff[n] = 0; + else rc = errno; + +// All done +// + close(vFD); + return rc; +} + /******************************************************************************/ /* i s S e t */ /******************************************************************************/ @@ -1327,8 +1353,9 @@ int XrdOucStream::isSet(char *var) static const char *Mtxt1[2] = {"setenv", "set"}; static const char *Mtxt2[2] = {"Setenv variable", "Set variable"}; static const char *Mtxt3[2] = {"Variable", "Environmental variable"}; - char *tp, *vn, *vp, *pv, Vname[64], ec, Nil = 0; - int sawEQ, Set = 1; + char *tp, *vn, *vp, *pv, Vname[64], ec, Nil = 0, sawIT = 0; + int Set = 1; + char valBuff[1024]; // Process set var = value | set -v | setenv = value // @@ -1354,10 +1381,10 @@ int XrdOucStream::isSet(char *var) } } -// Next may be var= | var | var=val +// Next may be var= | var | var=val | var< | var= sizeof(Vname)) return xMsg(Mtxt2[Set],tp,"is too long."); if (!Set && !strncmp("XRD", Vname, 3)) @@ -1371,12 +1398,26 @@ int XrdOucStream::isSet(char *var) // Now look for the value // - if (sawEQ) tp = vp; - else if (!(tp = GetToken()) || *tp != '=') + if (sawIT) tp = vp; + else if (!(tp = GetToken()) || (*tp != '=' && *tp != '<')) return xMsg("Missing '=' after", Mtxt1[Set], Vname); - else tp++; + else {sawIT = *tp; tp++;} if (!*tp && !(tp = GetToken())) tp = (char *)""; +// Handle reading value from a file +// + if (sawIT == '<') + {int rc; + if (!*tp) return xMsg(Mtxt2[Set], Vname, "path to value not specified"); + if ((rc = getValue(tp, valBuff, sizeof(valBuff)))) + {char tbuff[512]; + snprintf(tbuff, sizeof(tbuff), "cannot be set via path %s; %s", + tp, XrdSysE2T(rc)); + return xMsg(Mtxt2[Set], Vname, tbuff); + } + tp = valBuff; + } + // The value may be '$var', in which case we need to get it out of the env if // this is a set or from our environment if this is a setenv // diff --git a/src/XrdOuc/XrdOucStream.hh b/src/XrdOuc/XrdOucStream.hh index 5ca35615572..2f341573204 100644 --- a/src/XrdOuc/XrdOucStream.hh +++ b/src/XrdOuc/XrdOucStream.hh @@ -241,6 +241,7 @@ private: char *doelse(); char *doif(); bool Echo(int ec, const char *t1, const char *t2=0, const char *t3=0); + int getValue(const char *path, char *vbuff, int vbsz); int isSet(char *var); char *vSubs(char *Var); int xMsg(const char *txt1, const char *txt2=0, const char *txt3=0);