XRootD
Loading...
Searching...
No Matches
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
46namespace
47{
48struct 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
59static const int csNum = sizeof(csTab)/sizeof(csTable);
60
61bool 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
84std::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
125std::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
163std::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)
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
static const int NameSize
Definition XrdCksData.hh:41
char Name[NameSize]
Definition XrdCksData.hh:44