XRootD
XrdCksAssist.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d C k s A s s i s t . c c */
4 /* */
5 /* (c) 2017 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 <cctype>
32 #include <cerrno>
33 #include <string>
34 #include <cstring>
35 #include <strings.h>
36 #include <ctime>
37 #include <vector>
38 #include <sys/types.h>
39 
40 #include "XrdCks/XrdCksData.hh"
41 
42 /******************************************************************************/
43 /* S t a t i c s */
44 /******************************************************************************/
45 
46 namespace
47 {
48 struct csTable {const char *csName; int csLenC; int csLenB;} csTab[]
49  = {{"adler32", 8, 4},
50  {"crc32", 8, 4},
51  {"crc64", 16, 8},
52  {"md5", 32, 16},
53  {"sha1", 40, 20},
54  {"sha2", 64, 32},
55  {"sha256", 64, 32},
56  {"sha512", 128, 64}
57  };
58 
59 static const int csNum = sizeof(csTab)/sizeof(csTable);
60 
61 bool LowerCase(const char *src, char *dst, int dstlen)
62 {
63  int n = strlen(src);
64 
65 // Verify that the result will fit in the supplied buffer with a null
66 //
67  if (n >= dstlen) return false;
68 
69 // Convert to ower case with trailing nulls
70 //
71  memset(dst+n, 0, dstlen-n);
72  for (int i = 0; i < n; i++) dst[i] = tolower(src[i]);
73  return true;
74 }
75 }
76 
77 /******************************************************************************/
78 /* X r d C k s A t t r D a t a */
79 /******************************************************************************/
80 
81 // Return the data portion of a checksum attribute so that it can be use
82 // to set an attribute value.
83 
84 std::vector<char> XrdCksAttrData(const char *cstype,
85  const char *csval, time_t mtime)
86 {
87  std::vector<char> cksError; // Null vector
88  XrdCksData cksData;
89  char csName[XrdCksData::NameSize];
90  int n = strlen(cstype);
91 
92 // Convert the checksum type to lower case
93 //
94  if (!LowerCase(cstype, csName, sizeof(csName)))
95  {errno = ENAMETOOLONG; return cksError;}
96 
97 // For cheksums we know, verify that the legnth of the input string
98 // corresponds to the checksum type.
99 //
100  n = strlen(csval);
101  for (int i = 0; i < csNum; i++)
102  {if (!strcmp(csTab[i].csName, csName) && csTab[i].csLenC != n)
103  {errno = EINVAL; return cksError;}
104  }
105 
106 // we simply fill out the cksdata structure with the provided information
107 //
108  if (!cksData.Set(csName)) {errno = ENAMETOOLONG; return cksError;}
109  if (!cksData.Set(csval, n)) {errno = EOVERFLOW; return cksError;}
110  cksData.fmTime = mtime;
111  cksData.csTime = time(0) - mtime;
112 
113 // Convert the checksum data to a string of bytes and return the vector
114 //
115  return std::vector<char>( (char *)&cksData,
116  ((char *)&cksData) + sizeof(cksData));
117 }
118 
119 /******************************************************************************/
120 /* X r d C k s A t t r N a m e */
121 /******************************************************************************/
122 
123 // Return the extended attribute variable name for a particular checksum type.
124 
125 std::string XrdCksAttrName(const char *cstype, const char *nspfx)
126 {
127  std::string xaName;
128  char csName[XrdCksData::NameSize];
129  int pfxlen = strlen(nspfx);
130 
131 // Do some easy checks for this we know are common
132 //
133  if (!pfxlen)
134  {if (!strcmp(cstype, "adler32")) return std::string("XrdCks.adler32");
135  if (!strcmp(cstype, "md5" )) return std::string("XrdCks.md5");
136  if (!strcmp(cstype, "crc32" )) return std::string("XrdCks.crc32");
137  }
138 
139 // Convert the checksum type to lower case
140 //
141  if (!LowerCase(cstype, csName, sizeof(csName)))
142  {errno = ENAMETOOLONG; return xaName;}
143 
144 // Reserve storage for the string and construct the variable name
145 //
146  xaName.reserve(strlen(nspfx) + strlen(cstype) + 8);
147  if (pfxlen)
148  {xaName = nspfx;
149  if (nspfx[pfxlen-1] != '.') xaName += '.';
150  }
151  xaName += "XrdCks.";
152  xaName += csName;
153 
154 // Return the variable name
155 //
156  return xaName;
157 }
158 
159 /******************************************************************************/
160 /* X r d C k s A t t r V a l u e */
161 /******************************************************************************/
162 
163 std::string XrdCksAttrValue(const char *cstype,
164  const char *csbuff, int csblen)
165 {
166  XrdCksData cksData;
167  std::string csError;
168  char csBuff[XrdCksData::ValuSize*2+1];
169 
170 // Verify that the length matches our object length
171 //
172  if (csblen != (int)sizeof(cksData)) {errno = EMSGSIZE; return csError;}
173 
174 // Copy the buffer into the object
175 //
176  memcpy(&cksData, csbuff, sizeof(cksData));
177 
178 // Now verify that all the fields are consistent
179 //
180  if (strncasecmp(cksData.Name, cstype, XrdCksData::NameSize))
181  {errno = ENOENT; return csError;}
182  if (cksData.Length <= 0 || cksData.Length > XrdCksData::ValuSize)
183  {errno = EINVAL; return csError;}
184 
185 // For known checksum values make sure the length matches
186 //
187  for (int i = 0; i < csNum; i++)
188  {if (!strcmp(csTab[i].csName, cstype)
189  && csTab[i].csLenB != int(cksData.Length))
190  {errno = EINVAL; return csError;}
191  }
192 
193 // Convert value to a hex string
194 //
195  if (!cksData.Get(csBuff, sizeof(csBuff)))
196  {errno = EOVERFLOW; return csError;}
197 
198 // Return string version of the hex string
199 //
200  return std::string(csBuff);
201 }
std::vector< char > XrdCksAttrData(const char *cstype, const char *csval, time_t mtime)
Definition: XrdCksAssist.cc:84
std::string XrdCksAttrName(const char *cstype, const char *nspfx)
std::string XrdCksAttrValue(const char *cstype, const char *csbuff, int csblen)
static const int ValuSize
Definition: XrdCksData.hh:42
int Set(const char *csName)
Definition: XrdCksData.hh:81
int Get(char *Buff, int Blen)
Definition: XrdCksData.hh:69
char Length
Definition: XrdCksData.hh:52
static const int NameSize
Definition: XrdCksData.hh:41
char Name[NameSize]
Definition: XrdCksData.hh:44