XRootD
XrdOucEnv.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d O u c E n v . c c */
4 /* */
5 /* (c) 2003 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* All Rights Reserved */
7 /* Produced by Andrew Hanushevsky for Stanford University under contract */
8 /* DE-AC02-76-SFO0515 with the Department of Energy */
9 /* */
10 /* This file is part of the XRootD software suite. */
11 /* */
12 /* XRootD is free software: you can redistribute it and/or modify it under */
13 /* the terms of the GNU Lesser General Public License as published by the */
14 /* Free Software Foundation, either version 3 of the License, or (at your */
15 /* option) any later version. */
16 /* */
17 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20 /* License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25 /* */
26 /* The copyright holder's institutional names and contributor's names may not */
27 /* be used to endorse or promote products derived from this software without */
28 /* specific prior written permission of the institution or contributor. */
29 /******************************************************************************/
30 
31 #include "string.h"
32 #include "stdio.h"
33 #include <cstdlib>
34 
35 #include "XrdOuc/XrdOucEnv.hh"
36 #include "XrdOuc/XrdOucString.hh"
37 
38 /******************************************************************************/
39 /* C o n s t r u c t o r */
40 /******************************************************************************/
41 
42 XrdOucEnv::XrdOucEnv(const char *vardata, int varlen,
43  const XrdSecEntity *secent)
44  : env_Hash(8,13), secEntity(secent)
45 {
46  char *vdp, varsave, *varname, *varvalu;
47 
48  if (!vardata) {global_env = 0; global_len = 0; return;}
49 
50 // Get the length of the global information (don't rely on its being correct)
51 //
52  if (!varlen) varlen = strlen(vardata);
53 
54 // We want our env copy to start with a single ampersand
55 //
56  while(*vardata == '&' && varlen) {vardata++; varlen--;}
57  if (!varlen) {global_env = 0; global_len = 0; return;}
58  global_env = (char *)malloc(varlen+2);
59  *global_env = '&'; vdp = global_env+1;
60  memcpy((void *)vdp, (const void *)vardata, (size_t)varlen);
61  *(vdp+varlen) = '\0'; global_len = varlen+1;
62 
63 // scan through the string looking for '&'
64 //
65  while(*vdp)
66  {while(*vdp == '&') vdp++;
67  varname = vdp;
68 
69  while(*vdp && *vdp != '=' && *vdp != '&') vdp++; // &....=
70  if (!*vdp) break;
71  if (*vdp == '&') continue;
72  *vdp = '\0';
73  varvalu = ++vdp;
74 
75  while(*vdp && *vdp != '&') vdp++; // &....=....&
76  varsave = *vdp; *vdp = '\0';
77 
78  if (*varname && *varvalu)
79  env_Hash.Rep(varname, strdup(varvalu), 0, Hash_dofree);
80 
81  *vdp = varsave; *(varvalu-1) = '=';
82  }
83  return;
84 }
85 
86 /******************************************************************************/
87 /* D e l i m i t */
88 /******************************************************************************/
89 
90 char *XrdOucEnv::Delimit(char *value)
91 {
92  while(*value) if (*value == ',') {*value = '\0'; return ++value;}
93  else value++;
94  return (char *)0;
95 }
96 
97 /******************************************************************************/
98 /* Private: E n v B u i l d T i d y */
99 /******************************************************************************/
100 
101 #define TIDY_ENVVAR " Xrd Ouc Env "
102 
103 void XrdOucEnv::EnvBuildTidy()
104 {
105  char *tidyEnv, *authInfo, *accessAuthInfo = nullptr, *working=global_env;
106  int aBeg, aEnd, aCount = 6;
107 
108 // We need to sanitize the current env string by removing auth info. If there
109 // is no auth information, then we can short circuit this.
110 //
111  if ((authInfo = strstr(global_env, "authz=")) == 0 && (accessAuthInfo = strstr(global_env, "access_token=")) == 0)
112  {Put(TIDY_ENVVAR, "");
113  return;
114  }
115 
116 // Get position of the auth string and check if we can do a fast deletion.
117 // Otherwise, we must trudge along.
118 //
119  for (int idx = 0; idx < 2; idx++)
120  {if (idx == 1)
121  {if (authInfo)
122  {working=Get(TIDY_ENVVAR);
123  accessAuthInfo = strstr(working, "access_token=");
124  }
125  aCount = 13;
126  authInfo = accessAuthInfo;
127  }
128  if (!authInfo) continue;
129  aBeg = authInfo - working;
130  if (aBeg && working[aBeg-1] == '&') aBeg--;
131  if (!(tidyEnv = index(authInfo+aCount, '&')))
132  {char aSave = working[aBeg];
133  if (aBeg) {
134  working[aBeg] = 0;
135  Put(TIDY_ENVVAR, working);
136  working[aBeg] = aSave;
137  } else {
138  Put(TIDY_ENVVAR, "&");
139  }
140  } else {
141  XrdOucString tidyStr(working);
142  do{if ((aEnd = tidyStr.find('&', aBeg+aCount)) == STR_NPOS)
143  {tidyStr.erase(aBeg);
144  break;
145  }
146  tidyStr.erase(aBeg, aEnd-aBeg);
147  } while((aBeg = tidyStr.find(idx ? "&access_token=" : "&authz=")) != STR_NPOS);
148  if (!tidyStr.length())
149  Put(TIDY_ENVVAR, "&");
150  else
151  Put(TIDY_ENVVAR, tidyStr.c_str());
152  }
153  }
154 }
155 
156 /******************************************************************************/
157 /* E n v T i d y */
158 /******************************************************************************/
159 
160 char *XrdOucEnv::EnvTidy(int &envlen)
161 {
162  char *tidyEnv;
163  int tries = 1;
164 
165 // Check if there is no env
166 //
167  if ((envlen = global_len) == 0 || global_env == 0) return 0;
168 
169 // Check if we have produced a tidy version. If noo build one and try again.
170 //
171 do{if ((tidyEnv = Get(TIDY_ENVVAR)))
172  {if (*tidyEnv == 0) break;
173  envlen = strlen(tidyEnv);
174  return tidyEnv;
175  }
176  EnvBuildTidy();
177  } while(tries--);
178 
179 // Return standard env
180 //
181  return Env(envlen);
182 }
183 
184 /******************************************************************************/
185 /* E x p o r t */
186 /******************************************************************************/
187 
188 int XrdOucEnv::Export(const char *Var, const char *Val)
189 {
190  int vLen = strlen(Var);
191  char *eBuff;
192 
193 // If this is a null value then substitute a null string
194 //
195  if (!Val) Val = "";
196 
197 // Allocate memory. Note that this memory will appear to be lost.
198 //
199  eBuff = (char *)malloc(vLen+strlen(Val)+2); // +2 for '=' and '\0'
200 
201 // Set up envar
202 //
203  strcpy(eBuff, Var);
204  *(eBuff+vLen) = '=';
205  strcpy(eBuff+vLen+1, Val);
206  return putenv(eBuff);
207 }
208 
209 /******************************************************************************/
210 
211 int XrdOucEnv::Export(const char *Var, int Val)
212 {
213  char buff[32];
214  sprintf(buff, "%d", Val);
215  return Export(Var, buff);
216 }
217 
218 
219 /******************************************************************************/
220 /* I m p o r t */
221 /******************************************************************************/
222 bool XrdOucEnv::Import( const char *var, char *&val )
223 {
224  char *value = getenv( var );
225  if( !value || !*value )
226  return false;
227 
228  val = value;
229  return true;
230 }
231 
232 /******************************************************************************/
233 /* I m p o r t */
234 /******************************************************************************/
235 bool XrdOucEnv::Import( const char *var, long &val )
236 {
237  char *value;
238  if( !Import( var, value ) )
239  return false;
240 
241  char *status;
242  val = strtol( value, &status, 0 );
243 
244  if( *status != 0 )
245  return false;
246  return true;
247 }
248 
249 /******************************************************************************/
250 /* G e t I n t */
251 /******************************************************************************/
252 
253 long XrdOucEnv::GetInt(const char *varname)
254 {
255  char *cP;
256 
257 // Retrieve a char* value from the Hash table and convert it into a long.
258 // Return -999999999 if the varname does not exist
259 //
260  if ((cP = env_Hash.Find(varname)) == NULL) return -999999999;
261  return atol(cP);
262 }
263 
264 /******************************************************************************/
265 /* P u t I n t */
266 /******************************************************************************/
267 
268 void XrdOucEnv::PutInt(const char *varname, long value)
269 {
270 // Convert the long into a char* and the put it into the hash table
271 //
272  char stringValue[24];
273  sprintf(stringValue, "%ld", value);
274  env_Hash.Rep(varname, strdup(stringValue), 0, Hash_dofree);
275 }
276 
277 /******************************************************************************/
278 /* G e t P t r */
279 /******************************************************************************/
280 
281 void *XrdOucEnv::GetPtr(const char *varname)
282 {
283  void *Valp;
284  char *cP, *Value = (char *)&Valp;
285  int cLen, n, i = 0, Odd = 0;
286 
287 // Retrieve the variable from the hash
288 //
289  if ((cP = env_Hash.Find(varname)) == NULL) return (void *)0;
290 
291 // Verify that the string is not too long or too short
292 //
293  if ((cLen = strlen(cP)) != (int)sizeof(void *)*2) return (void *)0;
294 
295 // Now convert the hex string back to its pointer value
296 //
297  while(cLen--)
298  { if (*cP >= '0' && *cP <= '9') n = *cP-48;
299  else if (*cP >= 'a' && *cP <= 'f') n = *cP-87;
300  else if (*cP >= 'A' && *cP <= 'F') n = *cP-55;
301  else return (void *)0;
302  if (Odd) Value[i++] |= n;
303  else Value[i ] = n << 4;
304  cP++; Odd = ~Odd;
305  }
306 
307 // All done, return the actual pointer value
308 //
309  return Valp;
310 }
311 
312 /******************************************************************************/
313 /* P u t P t r */
314 /******************************************************************************/
315 
316 void XrdOucEnv::PutPtr(const char *varname, void *value)
317 {
318  static char hv[] = "0123456789abcdef";
319  char Buff[sizeof(void *)*2+1], *Value = (char *)&value;
320  int i, j = 0;
321 
322 // Convert the pointer value to a hex string
323 //
324  if (value) for (i = 0; i <(int)sizeof(void *); i++)
325  {Buff[j++] = hv[(Value[i] >> 4) & 0x0f];
326  Buff[j++] = hv[ Value[i] & 0x0f];
327  }
328  Buff[j] = '\0';
329 
330 // Replace the value in he hash
331 //
332  env_Hash.Rep(varname, strdup(Buff), 0, Hash_dofree);
333 }
#define TIDY_ENVVAR
Definition: XrdOucEnv.cc:101
@ Hash_dofree
Definition: XrdOucHash.hh:56
#define STR_NPOS
void PutInt(const char *varname, long value)
Definition: XrdOucEnv.cc:268
long GetInt(const char *varname)
Definition: XrdOucEnv.cc:253
char * EnvTidy(int &envlen)
Definition: XrdOucEnv.cc:160
static bool Import(const char *var, char *&val)
Definition: XrdOucEnv.cc:222
static int Export(const char *Var, const char *Val)
Definition: XrdOucEnv.cc:188
void * GetPtr(const char *varname)
Definition: XrdOucEnv.cc:281
char * Get(const char *varname)
Definition: XrdOucEnv.hh:69
void PutPtr(const char *varname, void *value)
Definition: XrdOucEnv.cc:316
char * Env(int &envlen)
Definition: XrdOucEnv.hh:48
void Put(const char *varname, const char *value)
Definition: XrdOucEnv.hh:85
char * Delimit(char *value)
Definition: XrdOucEnv.cc:90
XrdOucEnv(const char *vardata=0, int vardlen=0, const XrdSecEntity *secent=0)
Definition: XrdOucEnv.cc:42
T * Rep(const char *KeyVal, T *KeyData, const int LifeTime=0, XrdOucHash_Options opt=Hash_default)
Definition: XrdOucHash.hh:166
T * Find(const char *KeyVal, time_t *KeyTime=0)
Definition: XrdOucHash.icc:160
const char * c_str() const
int erase(int start=0, int size=0)
int find(const char c, int start=0, bool forward=1)
int length() const