XRootD
XrdOucMsubs.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d O u c M s u b s . c c */
4 /* */
5 /* (c) 2006 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 <sys/types.h>
32 #include <sys/stat.h>
33 #include <fcntl.h>
34 
35 #include <cctype>
36 #include <cstdio>
37 #include <strings.h>
38 
39 #include "XrdOuc/XrdOucMsubs.hh"
40 
41 /******************************************************************************/
42 /* G l o b a l s */
43 /******************************************************************************/
44 
45 const char *XrdOucMsubs::vName[vMax] = {0};
46 
47 /******************************************************************************/
48 /* C o n s t r u c t o r */
49 /******************************************************************************/
50 
52 {
53 
54  if (vName[0] == 0)
55  {vName[0] = "$";
56  vName[vCGI] = "$CGI";
57  vName[vLFN] = "$LFN";
58  vName[vPFN] = "$PFN";
59  vName[vRFN] = "$RFN";
60  vName[vLFN2] = "$LFN2";
61  vName[vPFN2] = "$PFN2";
62  vName[vRFN2] = "$RFN2";
63  vName[vFM] = "$FMODE";
64  vName[vNFY] = "$NOTIFY";
65  vName[vOFL] = "$OFLAG";
66  vName[vOPT] = "$OPTS";
67  vName[vPTY] = "$PRTY";
68  vName[vUSR] = "$USER";
69  vName[vHST] = "$HOST";
70  vName[vRID] = "$RID";
71  vName[vTID] = "$TID";
72  vName[vMDP] = "$MDP";
73  vName[vSRC] = "$SRC";
74  vName[vDST] = "$DST";
75  vName[vCID] = "$CID";
76  vName[vINS] = "$INS";
77  }
78  mText = 0;
79  mData[0] = 0; mDlen[0] = 0;
80  numElem = 0;
81  eDest = errp;
82 }
83 
84 /******************************************************************************/
85 /* D e s t r u c t o r */
86 /******************************************************************************/
87 
89 { int i;
90 
91  if (mText) free(mText);
92 
93  for (i = 0; i < numElem; i++) if (mDlen[i] < 0) free(mData[i]);
94 }
95 
96 /******************************************************************************/
97 /* P a r s e */
98 /******************************************************************************/
99 
100 int XrdOucMsubs::Parse(const char *dName, char *msg)
101 {
102  char ctmp, *vp, *ip, *lastp, *infop;
103  int i, j = 0;
104 
105 // Setup the additional stage information vector. Variable substitution:
106 // <data>$var<data>.... (max of MaxArgs substitutions)
107 //
108  lastp = infop = mText = strdup(msg);
109  while ((ip = index(infop, '$')) && j < maxElem)
110  if (isalnum(*(ip+1)) && (infop == ip || *(ip-1) != '\\'))
111  {if ((mDlen[j] = ip-lastp)) mData[j++] = lastp;
112  vp = ip; ip++;
113  while(isalnum(*ip) || *ip == '.') ip++;
114  ctmp = *ip; *ip = '\0';
115  mDlen[j] = -(ip-vp);
116  mData[j] = vp = strdup(vp); mData[j++]++;
117  *ip = ctmp; lastp = infop = ip;
118  if (isupper(*(vp+1)))
119  for (i = 1; i < vMax; i++)
120  if (!strcmp(vp, vName[i]))
121  {mDlen[j-1] = i; mData[j-1] = 0; free(vp); break;}
122  } else if (ip != infop && *(ip-1) == '\\')
123  {if ((mDlen[j] = (ip-lastp)-1) > 0) mData[j++] = lastp;
124  lastp = ip; infop = ip+1;
125  } else infop = ip+1;
126 
127 // Make sure we have not exceeded the array
128 //
129  if (j < maxElem)
130  {if ((mDlen[j] = strlen(lastp))) mData[j++] = lastp;
131  numElem = j;
132  } else {
133  eDest->Emsg(dName, "Too many variables in", dName, "string.");
134  return 0;
135  }
136 
137 // All done
138 //
139  return 1;
140 }
141 
142 /******************************************************************************/
143 /* S u b s */
144 /******************************************************************************/
145 
146 int XrdOucMsubs::Subs(XrdOucMsubsInfo &Info, char **Data, int *Dlen)
147 {
148  int k;
149 
150 // Perform substitutions
151 //
152  for (k = 0; k < numElem; k++)
153  { if (!mData[k])
154  {Data[k] = getVal(Info, mDlen[k]);
155  Dlen[k] = strlen(Data[k]);
156  }
157  else if (mDlen[k] < 0)
158  {if ((Data[k] = Info.Env->Get(mData[k])))
159  Dlen[k] = strlen(Data[k]);
160  else {Data[k]=mData[k]-1; Dlen[k]=(-mDlen[k]);}
161  }
162  else {Data[k] = mData[k]; Dlen[k] = mDlen[k];}
163  }
164  return numElem;
165 }
166 
167 /******************************************************************************/
168 /* g e t V a l */
169 /******************************************************************************/
170 
171 char *XrdOucMsubs::getVal(XrdOucMsubsInfo &Info, int vNum)
172 {
173  char buff[1024];
174  char *op;
175  int n;
176 
177  switch(vNum)
178  {case vLFN: return (char *)Info.lfn;
179 
180  case vPFN: if (Info.pfn) return (char *)Info.pfn;
181  if (!Info.N2N) return (char *)Info.lfn;
182  if (Info.pfnbuff) return Info.pfnbuff;
183  if (Info.N2N->lfn2pfn(Info.lfn,buff,sizeof(buff))) break;
184  Info.pfnbuff = strdup(buff);
185  return Info.pfnbuff;
186 
187  case vRFN: if (!Info.N2N) return (char *)Info.lfn;
188  if (Info.rfnbuff) return Info.rfnbuff;
189  if (Info.N2N->lfn2rfn(Info.lfn,buff,sizeof(buff))) break;
190  Info.rfnbuff = strdup(buff);
191  return Info.rfnbuff;
192 
193  case vLFN2:
194  case vNFY:
195  case vSRC: if (Info.lfn2) return (char *)Info.lfn2;
196  break;
197 
198  case vDST: if (Info.pfn2) return (char *)Info.pfn2;
199  break;
200 
201  case vPFN2: if (!Info.lfn2) break;
202  if (Info.pfn2) return (char *)Info.pfn2;
203  if (!Info.N2N) return (char *)Info.lfn2;
204  if (Info.pfn2buff) return Info.pfn2buff;
205  if (Info.N2N->lfn2pfn(Info.lfn2,buff,sizeof(buff))) break;
206  Info.pfn2buff = strdup(buff);
207  return Info.pfn2buff;
208 
209  case vRFN2: if (!Info.lfn2) break;
210  if (!Info.N2N) return (char *)Info.lfn2;
211  if (Info.rfn2buff) return Info.rfn2buff;
212  if (Info.N2N->lfn2rfn(Info.lfn2,buff,sizeof(buff))) break;
213  Info.rfn2buff = strdup(buff);
214  return Info.rfn2buff;
215 
216  case vFM: sprintf(Info.mbuff, "%o", static_cast<int>(Info.Mode));
217  return Info.mbuff;
218 
219  case vOFL: op = Info.obuff;
220  if (!(Info.Oflag & (O_WRONLY | O_RDWR))) *op++ = 'r';
221  else {*op++ = 'w';
222  if (Info.Oflag & O_CREAT) *op++ = 'c';
223  if (Info.Oflag & O_EXCL) *op++ = 'x';
224  if (Info.Oflag & O_TRUNC) *op++ = 't';
225  }
226  *op = '\0';
227  return Info.obuff;
228 
229  case vMDP:
230  case vOPT: if (Info.misc) return (char *)Info.misc;
231  break;
232 
233  case vPTY: sprintf(Info.mbuff, "%d", static_cast<int>(Info.Mode));
234  return Info.mbuff;
235 
236  case vHST: if ((op = Info.Env->Get(SEC_HOST))) return op;
237  break;
238 
239  case vUSR: if ((op = Info.Env->Get(SEC_USER))) return op;
240  break;
241 
242  case vRID: if (Info.Rid) return (char *)Info.Rid;
243  return (char *)Info.Tid;
244 
245  case vTID: return (char *)Info.Tid;
246 
247  case vCGI: if (!(op = Info.Env->Env(n))) op = (char *)"";
248  return op;
249 
250  case vCID: if ((op = Info.Env->Get(CMS_CID))) return op;
251  break;
252 
253  case vINS: if ((op = Info.Env->Get(XRD_INS))) return op;
254  break;
255 
256  default: return (char *)"$";
257  }
258  return (char *)vName[vNum];
259 }
@ Info
#define SEC_HOST
Definition: XrdOucMsubs.hh:45
#define CMS_CID
Definition: XrdOucMsubs.hh:43
#define XRD_INS
Definition: XrdOucMsubs.hh:47
#define SEC_USER
Definition: XrdOucMsubs.hh:44
int Parse(const char *oname, char *msg)
Definition: XrdOucMsubs.cc:100
int Subs(XrdOucMsubsInfo &Info, char **Data, int *Dlen)
Definition: XrdOucMsubs.cc:146
XrdOucMsubs(XrdSysError *errp)
Definition: XrdOucMsubs.cc:51
static const int maxElem
Definition: XrdOucMsubs.hh:94
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95