00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 const char *XrdOucMsubsCVSID = "$Id: XrdOucMsubs.cc 35287 2010-09-14 21:19:35Z ganis $";
00014
00015 #include <sys/types.h>
00016 #include <sys/stat.h>
00017 #include <fcntl.h>
00018
00019 #include <ctype.h>
00020 #include <stdio.h>
00021 #include <strings.h>
00022
00023 #include "XrdOuc/XrdOucMsubs.hh"
00024
00025
00026
00027
00028
00029 const char *XrdOucMsubs::vName[vMax] = {0};
00030
00031
00032
00033
00034
00035 XrdOucMsubs::XrdOucMsubs(XrdSysError *errp)
00036 {
00037
00038 if (vName[0] == 0)
00039 {vName[0] = "$";
00040 vName[vCGI] = "$CGI";
00041 vName[vLFN] = "$LFN";
00042 vName[vPFN] = "$PFN";
00043 vName[vRFN] = "$RFN";
00044 vName[vLFN2] = "$LFN2";
00045 vName[vPFN2] = "$PFN2";
00046 vName[vRFN2] = "$RFN2";
00047 vName[vFM] = "$FMODE";
00048 vName[vNFY] = "$NOTIFY";
00049 vName[vOFL] = "$OFLAG";
00050 vName[vOPT] = "$OPTS";
00051 vName[vPTY] = "$PRTY";
00052 vName[vUSR] = "$USER";
00053 vName[vHST] = "$HOST";
00054 vName[vRID] = "$RID";
00055 vName[vTID] = "$TID";
00056 vName[vMDP] = "$MDP";
00057 vName[vSRC] = "$SRC";
00058 vName[vDST] = "$DST";
00059 vName[vCID] = "$CID";
00060 vName[vINS] = "$INS";
00061 }
00062 mText = 0;
00063 mData[0] = 0; mDlen[0] = 0;
00064 numElem = 0;
00065 eDest = errp;
00066 }
00067
00068
00069
00070
00071
00072 XrdOucMsubs::~XrdOucMsubs()
00073 { int i;
00074
00075 if (mText) free(mText);
00076
00077 for (i = 0; i < numElem; i++) if (mDlen[i] < 0) free(mData[i]);
00078 }
00079
00080
00081
00082
00083
00084 int XrdOucMsubs::Parse(const char *dName, char *msg)
00085 {
00086 char ctmp, *vp, *ip, *lastp, *infop;
00087 int i, j = 0;
00088
00089
00090
00091
00092 lastp = infop = mText = strdup(msg);
00093 while ((ip = index(infop, '$')) && j < maxElem)
00094 if (isalnum(*(ip+1)) && (infop == ip || *(ip-1) != '\\'))
00095 {if ((mDlen[j] = ip-lastp)) mData[j++] = lastp;
00096 vp = ip; ip++;
00097 while(isalnum(*ip) || *ip == '.') ip++;
00098 ctmp = *ip; *ip = '\0';
00099 mDlen[j] = -(ip-vp);
00100 mData[j] = vp = strdup(vp); mData[j++]++;
00101 *ip = ctmp; lastp = infop = ip;
00102 if (isupper(*(vp+1)))
00103 for (i = 1; i < vMax; i++)
00104 if (!strcmp(vp, vName[i]))
00105 {mDlen[j-1] = i; mData[j-1] = 0; free(vp); break;}
00106 } else if (ip != infop && *(ip-1) == '\\')
00107 {if ((mDlen[j] = (ip-lastp)-1) > 0) mData[j++] = lastp;
00108 lastp = ip; infop = ip+1;
00109 } else infop = ip+1;
00110
00111
00112
00113 if (j < maxElem)
00114 {if ((mDlen[j] = strlen(lastp))) mData[j++] = lastp;
00115 numElem = j;
00116 } else {
00117 eDest->Emsg(dName, "Too many variables in", dName, "string.");
00118 return 0;
00119 }
00120
00121
00122
00123 return 1;
00124 }
00125
00126
00127
00128
00129
00130 int XrdOucMsubs::Subs(XrdOucMsubsInfo &Info, char **Data, int *Dlen)
00131 {
00132 int k;
00133
00134
00135
00136 for (k = 0; k < numElem; k++)
00137 { if (!mData[k])
00138 {Data[k] = getVal(Info, mDlen[k]);
00139 Dlen[k] = strlen(Data[k]);
00140 }
00141 else if (mDlen[k] < 0)
00142 {if ((Data[k] = Info.Env->Get(mData[k])))
00143 Dlen[k] = strlen(Data[k]);
00144 else {Data[k]=mData[k]-1; Dlen[k]=(-mDlen[k]);}
00145 }
00146 else {Data[k] = mData[k]; Dlen[k] = mDlen[k];}
00147 }
00148 return numElem;
00149 }
00150
00151
00152
00153
00154
00155 char *XrdOucMsubs::getVal(XrdOucMsubsInfo &Info, int vNum)
00156 {
00157 char buff[1024];
00158 char *op;
00159 int n;
00160
00161 switch(vNum)
00162 {case vLFN: return (char *)Info.lfn;
00163
00164 case vPFN: if (Info.pfn) return (char *)Info.pfn;
00165 if (!Info.N2N) return (char *)Info.lfn;
00166 if (Info.pfnbuff) return Info.pfnbuff;
00167 if (Info.N2N->lfn2pfn(Info.lfn,buff,sizeof(buff))) break;
00168 Info.pfnbuff = strdup(buff);
00169 return Info.pfnbuff;
00170
00171 case vRFN: if (!Info.N2N) return (char *)Info.lfn;
00172 if (Info.rfnbuff) return Info.rfnbuff;
00173 if (Info.N2N->lfn2rfn(Info.lfn,buff,sizeof(buff))) break;
00174 Info.rfnbuff = strdup(buff);
00175 return Info.rfnbuff;
00176
00177 case vLFN2:
00178 case vNFY:
00179 case vSRC: if (Info.lfn2) return (char *)Info.lfn2;
00180 break;
00181
00182 case vDST: if (Info.pfn2) return (char *)Info.pfn2;
00183 break;
00184
00185 case vPFN2: if (!Info.lfn2) break;
00186 if (Info.pfn2) return (char *)Info.pfn2;
00187 if (!Info.N2N) return (char *)Info.lfn2;
00188 if (Info.pfn2buff) return Info.pfn2buff;
00189 if (Info.N2N->lfn2pfn(Info.lfn2,buff,sizeof(buff))) break;
00190 Info.pfn2buff = strdup(buff);
00191 return Info.pfn2buff;
00192
00193 case vRFN2: if (!Info.lfn2) break;
00194 if (!Info.N2N) return (char *)Info.lfn2;
00195 if (Info.rfn2buff) return Info.rfn2buff;
00196 if (Info.N2N->lfn2rfn(Info.lfn2,buff,sizeof(buff))) break;
00197 Info.rfn2buff = strdup(buff);
00198 return Info.rfn2buff;
00199
00200 case vFM: sprintf(Info.mbuff, "%o", static_cast<int>(Info.Mode));
00201 return Info.mbuff;
00202
00203 case vOFL: op = Info.obuff;
00204 if (!(Info.Oflag & (O_WRONLY | O_RDWR))) *op++ = 'r';
00205 else {*op++ = 'w';
00206 if (Info.Oflag & O_CREAT) *op++ = 'c';
00207 if (Info.Oflag & O_EXCL) *op++ = 'x';
00208 if (Info.Oflag & O_TRUNC) *op++ = 't';
00209 }
00210 *op = '\0';
00211 return Info.obuff;
00212
00213 case vMDP:
00214 case vOPT: if (Info.misc) return (char *)Info.misc;
00215 break;
00216
00217 case vPTY: sprintf(Info.mbuff, "%d", static_cast<int>(Info.Mode));
00218 return Info.mbuff;
00219
00220 case vHST: if ((op = Info.Env->Get(SEC_HOST))) return op;
00221 break;
00222
00223 case vUSR: if ((op = Info.Env->Get(SEC_USER))) return op;
00224 break;
00225
00226 case vRID: if (Info.Rid) return (char *)Info.Rid;
00227 case vTID: return (char *)Info.Tid;
00228
00229 case vCGI: if (!(op = Info.Env->Env(n))) op = (char *)"";
00230 return op;
00231
00232 case vCID: if ((op = Info.Env->Get(CMS_CID))) return op;
00233 break;
00234
00235 case vINS: if ((op = Info.Env->Get(XRD_INS))) return op;
00236 break;
00237
00238 default: return (char *)"$";
00239 }
00240 return (char *)vName[vNum];
00241 }