XRootD
XrdSsiUtils.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d S s i U t i l s . c c */
4 /* */
5 /* (c) 2015 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* Produced by Andrew Hanushevsky for Stanford University under contract */
7 /* DE-AC02-76-SFO0515 with the Department of Energy */
8 /* */
9 /* This file is part of the XRootD software suite. */
10 /* */
11 /* XRootD is free software: you can redistribute it and/or modify it under */
12 /* the terms of the GNU Lesser General Public License as published by the */
13 /* Free Software Foundation, either version 3 of the License, or (at your */
14 /* option) any later version. */
15 /* */
16 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
17 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
18 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
19 /* License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
23 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
24 /* */
25 /* The copyright holder's institutional names and contributor's names may not */
26 /* be used to endorse or promote products derived from this software without */
27 /* specific prior written permission of the institution or contributor. */
28 /******************************************************************************/
29 
30 #include <cstdio>
31 #include <cstring>
32 #include <sys/types.h>
33 
34 #include "XProtocol/XProtocol.hh"
35 
36 #include "Xrd/XrdScheduler.hh"
37 
39 
40 #include "XrdOuc/XrdOucERoute.hh"
41 #include "XrdOuc/XrdOucErrInfo.hh"
42 
44 
45 #include "XrdSsi/XrdSsiAtomics.hh"
46 #include "XrdSsi/XrdSsiErrInfo.hh"
47 #include "XrdSsi/XrdSsiRequest.hh"
49 #include "XrdSsi/XrdSsiRRAgent.hh"
50 #include "XrdSsi/XrdSsiUtils.hh"
51 
52 #include "XrdSys/XrdSysError.hh"
53 
54 /******************************************************************************/
55 /* G l o b a l s */
56 /******************************************************************************/
57 
58 namespace XrdSsi
59 {
60 extern XrdSysError Log;
61 extern XrdScheduler *schedP;
62 };
63 
64 using namespace XrdSsi;
65 
66 /******************************************************************************/
67 /* L o c a l C l a s s e s */
68 /******************************************************************************/
69 
70 class PostError : public XrdJob, public XrdSsiResponder
71 {
72 public:
73 
74 void DoIt() {myMutex.Lock();
75  if ( isActive) SetErrResponse(eTxt, eNum);
76  if (!isActive) delete this;
77  else {isActive = false;
78  myMutex.UnLock();
79  }
80  }
81 
82 virtual void Finished( XrdSsiRequest &rqstR,
83  const XrdSsiRespInfo &rInfo,
84  bool cancel=false)
85  {UnBindRequest();
86  myMutex.Lock();
87  if (!isActive) delete this;
88  else {isActive = false;
89  myMutex.UnLock();
90  }
91  }
92 
93  PostError(XrdSsiRequest *rP, char *emsg, int ec)
94  : myMutex(XrdSsiMutex::Recursive),
95  reqP(rP), eTxt(emsg), eNum(ec), isActive(true)
96  {XrdSsiRRAgent::SetMutex(rP, &myMutex);
97  BindRequest(*reqP);
98  }
99 
100 virtual ~PostError() {myMutex.UnLock();
101  if (eTxt) free(eTxt);
102  }
103 
104 private:
105 XrdSsiMutex myMutex; // Allow possible rentry via SetErrResponse()
106 XrdSsiRequest *reqP;
107 char *eTxt;
108 int eNum;
109 bool isActive;
110 };
111 
112 /******************************************************************************/
113 /* b 2 x */
114 /******************************************************************************/
115 
116 char *XrdSsiUtils::b2x(const char *ibuff, int ilen, char *obuff, int olen,
117  char xbuff[4])
118 {
119  static char hv[] = "0123456789abcdef";
120  char *oP = obuff;
121 
122  // Gaurd against too short of an output buffer (minimum if 3 bytes)
123  //
124  if (olen < 3)
125  {*obuff = 0;
126  strcpy(xbuff, "...");
127  return obuff;
128  }
129 
130  // Make sure we have something to format
131  //
132  if (ilen < 1)
133  {*obuff = 0;
134  *xbuff = 0;
135  return obuff;
136  }
137 
138  // Do length adjustment, as needed
139  //
140  if (ilen*2 < olen) *xbuff = 0;
141  else {ilen = (olen-1)/2;
142  strcpy(xbuff, "...");
143  }
144 
145  // Format the data. We know it will fit with a trailing null byte.
146  //
147  for (int i = 0; i < ilen; i++) {
148  *oP++ = hv[(ibuff[i] >> 4) & 0x0f];
149  *oP++ = hv[ ibuff[i] & 0x0f];
150  }
151  *oP = '\0';
152  return obuff;
153 }
154 
155 /******************************************************************************/
156 /* E m s g */
157 /******************************************************************************/
158 
159 int XrdSsiUtils::Emsg(const char *pfx, // Message prefix value
160  int ecode, // The error code
161  const char *op, // Operation being performed
162  const char *path, // Operation target
163  XrdOucErrInfo &eDest) // Plase to put error
164 {
165  char buffer[2048];
166 
167 // Get correct error code and path
168 //
169  if (ecode < 0) ecode = -ecode;
170  if (!path) path = "???";
171 
172 // Format the error message
173 //
174  XrdOucERoute::Format(buffer, sizeof(buffer), ecode, op, path);
175 
176 // Put the message in the log
177 //
178  Log.Emsg(pfx, eDest.getErrUser(), buffer);
179 
180 // Place the error message in the error object and return
181 //
182  eDest.setErrInfo(ecode, buffer);
183  return SFS_ERROR;
184 }
185 
186 
187 /******************************************************************************/
188 /* G e t E r r */
189 /******************************************************************************/
190 
191 int XrdSsiUtils::GetErr(XrdCl::XRootDStatus &Status, std::string &eText)
192 {
193 
194 // If this is an xrootd error then get the xrootd generated error
195 //
196  if (Status.code == XrdCl::errErrorResponse)
197  {eText = Status.GetErrorMessage();
198  return MapErr(Status.errNo);
199  }
200 
201 // Internal error, we will need to copy strings here
202 //
203  eText = Status.ToStr();
204  return (Status.errNo ? Status.errNo : EFAULT);
205 }
206 
207 /******************************************************************************/
208 /* M a p E r r */
209 /******************************************************************************/
210 
211 int XrdSsiUtils::MapErr(int xEnum)
212 {
213  return XProtocol::mapError(xEnum);
214 }
215 
216 /******************************************************************************/
217 /* R e t E r r */
218 /******************************************************************************/
219 
220 void XrdSsiUtils::RetErr(XrdSsiRequest &reqP, const char *eTxt, int eNum)
221 {
222 
223 // Schedule an error callback
224 //
225  XrdSsi::schedP->Schedule(new PostError(&reqP, strdup(eTxt), eNum));
226 }
227 
228 /******************************************************************************/
229 /* S e t E r r */
230 /******************************************************************************/
231 
233 {
234 
235 // If this is an xrootd error then get the xrootd generated error
236 //
237  if (Status.code == XrdCl::errErrorResponse)
238  {eInfo.Set(Status.GetErrorMessage().c_str(), MapErr(Status.errNo));
239  } else {
240  eInfo.Set(Status.ToStr().c_str(), (Status.errNo ? Status.errNo:EFAULT));
241  }
242 }
static XrdSysError eDest(0,"crypto_")
int emsg(int rc, char *msg)
#define SFS_ERROR
virtual void Finished(XrdSsiRequest &rqstR, const XrdSsiRespInfo &rInfo, bool cancel=false)
Definition: XrdSsiUtils.cc:82
virtual ~PostError()
Definition: XrdSsiUtils.cc:100
PostError(XrdSsiRequest *rP, char *emsg, int ec)
Definition: XrdSsiUtils.cc:93
void DoIt()
Definition: XrdSsiUtils.cc:74
static int mapError(int rc)
Definition: XProtocol.hh:1361
const std::string & GetErrorMessage() const
Get error message.
std::string ToStr() const
Convert to string.
Definition: XrdJob.hh:43
static int Format(char *buff, int blen, int ecode, const char *etxt1, const char *etxt2=0)
Definition: XrdOucERoute.cc:44
void Schedule(XrdJob *jp)
void Set(const char *eMsg=0, int eNum=0, int eArg=0)
static void SetMutex(XrdSsiRequest *rP, XrdSsiMutex *mP)
static int GetErr(XrdCl::XRootDStatus &Status, std::string &eText)
Definition: XrdSsiUtils.cc:191
static int Emsg(const char *pfx, int ecode, const char *op, const char *path, XrdOucErrInfo &eDest)
Definition: XrdSsiUtils.cc:159
static char * b2x(const char *ibuff, int ilen, char *obuff, int olen, char xbuff[4])
Definition: XrdSsiUtils.cc:116
static void RetErr(XrdSsiRequest &reqP, const char *eTxt, int eNum)
Definition: XrdSsiUtils.cc:220
static int MapErr(int xEnum)
Definition: XrdSsiUtils.cc:211
static void SetErr(XrdCl::XRootDStatus &Status, XrdSsiErrInfo &eInfo)
Definition: XrdSsiUtils.cc:232
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95
const uint16_t errErrorResponse
Definition: XrdClStatus.hh:105
XrdScheduler * schedP
Definition: XrdSsiClient.cc:74
XrdSysError Log
uint16_t code
Error type, or additional hints on what to do.
Definition: XrdClStatus.hh:147
uint32_t errNo
Errno, if any.
Definition: XrdClStatus.hh:148