XRootD
XrdOssCsiConfig.hh
Go to the documentation of this file.
1 #ifndef _XRDOSSCSICONFIG_H
2 #define _XRDOSSCSICONFIG_H
3 /******************************************************************************/
4 /* */
5 /* X r d O s s C s i C o n f i g . h h */
6 /* */
7 /* (C) Copyright 2021 CERN. */
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 /* In applying this licence, CERN does not waive the privileges and */
17 /* immunities granted to it by virtue of its status as an Intergovernmental */
18 /* Organization or submit itself to any jurisdiction. */
19 /* */
20 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
21 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
22 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
23 /* License for more details. */
24 /* */
25 /* You should have received a copy of the GNU Lesser General Public License */
26 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
27 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
28 /* */
29 /* The copyright holder's institutional names and contributor's names may not */
30 /* be used to endorse or promote products derived from this software without */
31 /* specific prior written permission of the institution or contributor. */
32 /******************************************************************************/
33 
34 #include "XrdOss/XrdOss.hh"
35 #include "XrdOuc/XrdOucStream.hh"
36 #include "XrdOuc/XrdOucEnv.hh"
37 #include "XrdSys/XrdSysLogger.hh"
38 
39 #include <string>
40 
41 class TagPath
42 {
43 public:
44 
45  TagPath() : prefix_("/.xrdt"), suffix_(".xrdt") { calcPrefixElements(); }
46  ~TagPath() { }
47 
48  // path may be full path (relative or absolute) or if we're using empty prefix_
49  // the path can also be a single name entry, found during a directory listing
50  // will also match the prefix_ directory
51  bool isTagFile(const char *path)
52  {
53  if (!path || !*path) return false;
54  std::string s(path);
55  simplePath(s);
56  // if prefix_ set, the test is to match if "path" is equal to or starts with prefix_
57  // we do not require matching suffix_, this will also match the prefix_ directory
58  if (!prefix_.empty())
59  {
60  if (s.find(prefix_) == 0)
61  {
62  if (prefix_.length() == s.length()) return true;
63  if (s[prefix_.length()] == '/') return true;
64  }
65  return false;
66  }
67  // prefix_ not set, test is if "path" ends with suffix_
68  const size_t haystack = s.length();
69  const size_t needle = suffix_.length();
70  if (haystack >= needle && s.substr(haystack-needle, std::string::npos) == suffix_) return true;
71  return false;
72  }
73 
74  int SetPrefix(XrdSysError &Eroute, const std::string &v)
75  {
76  if (!v.empty() && v[0] != '/')
77  {
78  Eroute.Emsg("Config","prefix must be empty or start with /");
79  return 1;
80  }
81  prefix_ = v;
82  calcPrefixElements();
83  return XrdOssOK;
84  }
85 
86  bool hasPrefix() { return !prefix_.empty(); }
87 
88  //
89  // to convert a data directory to corresponding tag directory
90  std::string makeBaseDirname(const char *path)
91  {
92  if (!path || !*path || prefix_.empty()) return std::string();
93 
94  std::string p(path);
95  bool wasabs = false;
96  simplePath(p,&wasabs);
97  std::string ret = (wasabs) ? prefix_ : prefix_.substr(1);
98  if (p.length()>1) ret += p;
99  return ret;
100  }
101 
102  //
103  // test if path is the directory containing the
104  // base directory of the tags: only expected to
105  // be called if prefix_ is not empty.
106  bool matchPrefixDir(const char *path)
107  {
108  if (!path || !*path || prefix_.empty()) return false;
109 
110  std::string p(path);
111  simplePath(p);
112  if (prefixstart_ == p) return true;
113  return false;
114  }
115 
116  // the name (not path) of directory containing the tags
117  // only called if prefix_ not empty and matchPrefixDir is true
118  std::string getPrefixName()
119  {
120  return prefixend_;
121  }
122 
123  // take datafile name at path and convert it to filename of tagfile
124  std::string makeTagFilename(const char *path)
125  {
126  if (!path || !*path) return std::string();
127  std::string p(path);
128  bool wasabs = false;
129  simplePath(p,&wasabs);
130  if (wasabs) return prefix_ + p + suffix_;
131  return prefix_.substr(1) + p + suffix_;
132  }
133 
134  // user specified prefix; empty or otherwise always has a leading '/'
135  // is the location of a directory under which all tag files are stored
136  std::string prefix_;
137 
138 private:
139  void calcPrefixElements()
140  {
141  prefixstart_.clear();
142  prefixend_.clear();
143  if (prefix_.empty()) return;
144  simplePath(prefix_);
145  const size_t idx = prefix_.rfind("/");
146  prefixstart_ = prefix_.substr(0,idx);
147  if (prefixstart_.empty()) prefixstart_ = std::string("/");
148  prefixend_ = prefix_.substr(idx+1,std::string::npos);
149  }
150 
151  // remove double slashes, trailing slashes and ensure a leading
152  // slash.
153  //
154  // The input/output 'str' parameter is the path to be modified.
155  // The output 'ls' parameter, if non-null, is set to indicate if
156  // the input path had a leading slash.
157  void simplePath(std::string &str, bool *ls=nullptr)
158  {
159  // replace double slashes with single
160  size_t i=0;
161  do {
162  i = str.find("//", i);
163  if (i == std::string::npos) break;
164  str.erase(i, 1);
165  } while (!str.empty());
166 
167  // remove trailing /
168  if (str.length()>1 && str[str.length()-1] == '/')
169  {
170  str.erase( str.end()-1 );
171  }
172 
173  if (ls) *ls=(str.length() ? true : false);
174 
175  if (str.length() && str[0] != '/')
176  {
177  str = "/" + str;
178  if (ls) *ls = false;
179  }
180  }
181 
182  std::string prefixstart_;
183  std::string prefixend_;
184  const std::string suffix_;
185 };
186 
188 {
189 public:
190 
191  XrdOssCsiConfig() : fillFileHole_(true), xrdtSpaceName_("public"), allowMissingTags_(true), disablePgExtend_(false), disableLooseWrite_(false) { }
193 
194  int Init(XrdSysError &, const char *, const char *, XrdOucEnv *);
195 
196  bool fillFileHole() const { return fillFileHole_; }
197 
198  std::string xrdtSpaceName() const { return xrdtSpaceName_; }
199 
200  bool allowMissingTags() const { return allowMissingTags_; }
201 
202  bool disablePgExtend() const { return disablePgExtend_; }
203 
204  bool disableLooseWrite() const { return disableLooseWrite_; }
205 
207 
208 private:
209  int readConfig(XrdSysError &, const char *);
210 
211  int ConfigXeq(char *, XrdOucStream &, XrdSysError &);
212 
213  int xtrace(XrdOucStream &, XrdSysError &);
214 
215  bool fillFileHole_;
216  std::string xrdtSpaceName_;
217  bool allowMissingTags_;
218  bool disablePgExtend_;
219  bool disableLooseWrite_;
220 };
221 
222 #endif
#define XrdOssOK
Definition: XrdOss.hh:50
std::string getPrefixName()
bool matchPrefixDir(const char *path)
std::string makeBaseDirname(const char *path)
std::string makeTagFilename(const char *path)
bool hasPrefix()
std::string prefix_
bool isTagFile(const char *path)
int SetPrefix(XrdSysError &Eroute, const std::string &v)
bool fillFileHole() const
std::string xrdtSpaceName() const
int Init(XrdSysError &, const char *, const char *, XrdOucEnv *)
bool disableLooseWrite() const
bool disablePgExtend() const
bool allowMissingTags() const
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95