XRootD
Loading...
Searching...
No Matches
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
45const 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
100int 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
146int 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
171char *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_ACCMODE) == O_RDONLY) *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}
#define SEC_HOST
#define CMS_CID
#define XRD_INS
#define SEC_USER
int Parse(const char *oname, char *msg)
int Subs(XrdOucMsubsInfo &Info, char **Data, int *Dlen)
XrdOucMsubs(XrdSysError *errp)
static const int maxElem
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)