etcFiles.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2016 OpenFOAM Foundation
9  Copyright (C) 2017-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "etcFiles.H"
30 #include "foamVersion.H"
31 #include "OSspecific.H"
32 
33 #ifdef FULLDEBUG
34 #ifndef FOAM_RESOURCE_USER_CONFIG_DIRNAME
35 # warning FOAM_RESOURCE_USER_CONFIG_DIRNAME undefined (was this intentional?)
36 #endif
37 
38 #ifndef FOAM_RESOURCE_SITE_ENVNAME
39 # warning FOAM_RESOURCE_SITE_ENVNAME undefined (was this intentional?)
40 #endif
41 
42 #ifndef FOAM_RESOURCE_SITE_FALLBACK_ENVNAME
43 # warning FOAM_RESOURCE_SITE_FALLBACK_ENVNAME undefined (was this intentional?)
44 #endif
45 #endif
46 
47 // Always use these names
48 #undef FOAM_PROJECT_ENVNAME
49 #define FOAM_PROJECT_ENVNAME "WM_PROJECT_DIR"
50 
51 // * * * * * * * * * * * * * * Static Functions * * * * * * * * * * * * * * //
52 
53 //
54 // Some of these could be exposed too (if required),
55 // but are fairly special purpose.
56 //
57 
58 namespace
59 {
60 
61 // Return the file location mode as a string.
62 //
63 // - u : location mask 0700
64 // - g : location mask 0070
65 // - o : location mask 0007
66 static inline std::string locationToString(unsigned short location)
67 {
68  std::string mode;
69 
70  if (location & 0700) { mode += 'u'; } // User
71  if (location & 0070) { mode += 'g'; } // Group
72  if (location & 0007) { mode += 'o'; } // Other
73  if (mode.empty()) { mode = "???"; }
74 
75  return mode;
76 }
77 
78 
79 // Error handling when a mandatory entry is not found
80 static inline void errorMandatoryNotFound
81 (
82  const std::string& name,
83  unsigned short location
84 )
85 {
86  // Abort when mandatory entry was not found.
87  // Use a direct exit, since this could occur before anything is
88  // setup at all.
89 
90  std::cerr
91  << "--> FOAM FATAL ERROR :\n"
92  " Could not find mandatory etc entry (mode="
93  << locationToString(location) << ")\n '"
94  << name << "'\n"
95  << std::endl;
96  std::exit(1);
97 }
98 
99 
100 // Assign 'queried' parameter to the user resource directory.
101 // Return true if this directory exists.
102 //
103 // Corresponds to foamEtcFile -mode=u
104 // Looks for
105 // - ~/.OpenFOAM
106 static inline bool userResourceDir(Foam::fileName& queried)
107 {
108  #ifdef FOAM_RESOURCE_USER_CONFIG_DIRNAME
110  if (Foam::isDir(queried))
111  {
112  // If home() fails, it will have actually queried "./.OpenFOAM"
113  // instead.
114  // But we would have worse problems elsewhere if that were the case.
115  return true;
116  }
117  #endif
118 
119  return false;
120 }
121 
122 
123 // Assign 'queried' parameter to the group resource directory.
124 // Return true if this directory exists.
125 // Otherwise clears the parameter and returns false.
126 //
127 // Corresponds to foamEtcFile -mode=g
128 // Looks for
129 // - ${WM_PROJECT_SITE}/etc
130 // - ${WM_PROJECT_DIR}/site/etc
131 //
132 // Optionally (compile-time defined):
133 // - FOAM_CONFIGURED_PROJECT_DIR/site/etc
134 static inline bool groupResourceDir(Foam::fileName& queried)
135 {
136  #ifdef FOAM_RESOURCE_SITE_ENVNAME
137  queried = Foam::getEnv(FOAM_RESOURCE_SITE_ENVNAME)/"etc";
138  if (queried.size() > 4)
139  {
140  return Foam::isDir(queried);
141  }
142  #endif
143 
144  // Fallback when WM_PROJECT_SITE is unset
145 
146  #ifdef FOAM_RESOURCE_SITE_FALLBACK_ENVNAME
148  if (queried.size() > 9 && Foam::isDir(queried))
149  {
150  return true;
151  }
152  #endif
153 
154  // Compile-time paths
155  #ifdef FOAM_CONFIGURED_PROJECT_DIR
156  queried = FOAM_CONFIGURED_PROJECT_DIR "/site/etc";
157  if (queried.size() > 9 && Foam::isDir(queried))
158  {
159  return true;
160  }
161  #endif
162 
163  queried.clear();
164  return false;
165 }
166 
167 
168 // Assign 'queried' parameter to the OpenFOAM etc/ resource directory.
169 // Return true if it exists.
170 // Otherwise clears the parameter and returns false.
171 //
172 // Corresponds to foamEtcFile -mode=o
173 // Looks for
174 // - ${WM_PROJECT_DIR}/etc
175 //
176 // Optionally (compile-time defined):
177 // - FOAM_CONFIGURED_PROJECT_ETC
178 // - FOAM_CONFIGURED_PROJECT_DIR/"etc"
179 static inline bool projectResourceDir(Foam::fileName& queried)
180 {
181  queried = Foam::getEnv(FOAM_PROJECT_ENVNAME)/"etc";
182  if (queried.size() > 4 && Foam::isDir(queried))
183  {
184  return true;
185  }
186 
187  // Compile-time paths
188 
189  #ifdef FOAM_CONFIGURED_PROJECT_ETC
190  queried = FOAM_CONFIGURED_PROJECT_ETC;
191  if (Foam::isDir(queried))
192  {
193  return true;
194  }
195  #endif
196 
197  #ifdef FOAM_CONFIGURED_PROJECT_DIR
198  queried = FOAM_CONFIGURED_PROJECT_DIR "/etc";
199  if (queried.size() > 4 && Foam::isDir(queried))
200  {
201  return true;
202  }
203  #endif
204 
205  queried.clear();
206  return false;
207 }
208 
209 
210 // Check if the named file/directory matches the type required.
211 //
212 // - typeRequired (UNDEFINED) => accept either FILE or DIRECTORY
213 // - typeRequired (FILE | DIRECTORY) => accept only that type
214 static inline bool accept
215 (
216  const Foam::fileName& name,
217  const Foam::fileName::Type typeRequired
218 )
219 {
220  // followLink(true), checkGzip(true)
221  // -> returns (UNDEFINED | FILE | DIRECTORY), no need to check for (LINK)
222  const auto t = name.type(true, true);
223 
224  return
225  (
226  // Found something?
227  Foam::fileName::Type::UNDEFINED != t
228  &&
229  (
230  // Any particular type required?
231  Foam::fileName::Type::UNDEFINED == typeRequired
232  ? (Foam::fileName::Type::UNDEFINED != t)
233  : (typeRequired == t)
234  )
235  );
236 }
237 
238 } // End anonymous namespace
239 
240 
241 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
242 
244 {
245  // Use foamVersion::api (instead of the OPENFOAM define) to ensure this
246  // stays properly synchronized with the build information
247  const Foam::fileName version(std::to_string(Foam::foamVersion::api));
248 
249  Foam::fileNameList list(5);
250  Foam::fileName queried;
251  label nDirs = 0;
252 
253  // User resource directories
254  if (userResourceDir(queried) || (!test && queried.size()))
255  {
256  list[nDirs++] = queried/version;
257  list[nDirs++] = queried;
258  }
259 
260  // Group (site) resource directories
261  if (groupResourceDir(queried) || (!test && queried.size()))
262  {
263  list[nDirs++] = queried/version;
264  list[nDirs++] = queried;
265  }
266 
267  // Other (project) resource directory
268  if (projectResourceDir(queried) || (!test && queried.size()))
269  {
270  list[nDirs++] = queried;
271  }
272 
273  list.resize(nDirs);
274 
275  return list;
276 }
277 
278 
280 (
281  const Foam::fileName& name,
282  unsigned short location,
283  const Foam::fileName::Type typeRequired,
284  const bool findFirst
285 )
286 {
287  // Debug Tracing
288  // std::cerr
289  // << "search ("<< locationToString(location) << "): "
290  // << name.c_str() << '\n';
291 
292  if (!(location & 0777))
293  {
294  // Warn about bad location (mode) ... or make it FATAL?
295  std::cerr
296  << "--> FOAM Error :\n "
297  "No user/group/other location specified for 'etc' file"
298  " or directory\n '"
299  << name.c_str() << "'\n\n" << std::endl;
300  }
301 
302  // Use foamVersion::api (instead of the OPENFOAM define) to ensure this
303  // stays properly synchronized with the build information
304  const Foam::fileName version(std::to_string(Foam::foamVersion::api));
305 
306  Foam::fileNameList list;
307  Foam::fileName queried, candidate;
308 
309  if (fileName::Type::FILE == typeRequired && name.empty())
310  {
311  // FILE must have a name to be found!
312  return list;
313  }
314 
315 
316  // User resource directories
317  if ((location & 0700) && userResourceDir(queried))
318  {
319  candidate = queried/version/name;
320  if (accept(candidate, typeRequired))
321  {
322  list.append(std::move(candidate));
323  if (findFirst)
324  {
325  return list;
326  }
327  }
328 
329  candidate = queried/name;
330  if (accept(candidate, typeRequired))
331  {
332  list.append(std::move(candidate));
333  if (findFirst)
334  {
335  return list;
336  }
337  }
338  }
339 
340 
341  // Group (site) resource directories
342  if ((location & 0070) && groupResourceDir(queried))
343  {
344  candidate = queried/version/name;
345  if (accept(candidate, typeRequired))
346  {
347  list.append(std::move(candidate));
348  if (findFirst)
349  {
350  return list;
351  }
352  }
353 
354  candidate = queried/name;
355  if (accept(candidate, typeRequired))
356  {
357  list.append(std::move(candidate));
358  if (findFirst)
359  {
360  return list;
361  }
362  }
363  }
364 
365 
366  // Other (project) resource directory
367  if ((location & 0007) && projectResourceDir(queried))
368  {
369  candidate = queried/name;
370  if (accept(candidate, typeRequired))
371  {
372  list.append(std::move(candidate));
373  }
374  }
375 
376  return list;
377 }
378 
379 
381 (
382  const fileName& name,
383  unsigned short location,
384  const bool findFirst
385 )
386 {
387  return findEtcEntries(name, location, fileName::Type::DIRECTORY, findFirst);
388 }
389 
390 
392 (
393  const fileName& name,
394  const bool mandatory,
395  unsigned short location,
396  const bool findFirst
397 )
398 {
399  // Note: findEtcEntries checks name.size() for FILE
400  fileNameList list
401  (
402  findEtcEntries(name, location, fileName::Type::FILE, findFirst)
403  );
404 
405  if (mandatory && list.empty())
406  {
407  errorMandatoryNotFound(name, location);
408  }
409 
410  return list;
411 }
412 
413 
415 (
416  const fileName& name,
417  unsigned short location,
418  const Foam::fileName::Type typeRequired
419 )
420 {
421  // With findFirst(true)
422  fileNameList list(findEtcEntries(name, location, typeRequired, true));
423 
424  fileName found;
425 
426  if (list.size())
427  {
428  found = std::move(list.first());
429  }
430 
431  return found;
432 }
433 
434 
436 (
437  const fileName& name,
438  unsigned short location
439 )
440 {
441  return findEtcEntry(name, location, fileName::Type::DIRECTORY);
442 }
443 
444 
446 (
447  const fileName& name,
448  const bool mandatory,
449  unsigned short location
450 )
451 {
452  fileName found(findEtcEntry(name, location, fileName::Type::FILE));
453 
454  if (mandatory && found.empty())
455  {
456  errorMandatoryNotFound(name, location);
457  }
458 
459  return found;
460 }
461 
462 
463 // ************************************************************************* //
OSspecific.H
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
FOAM_RESOURCE_SITE_FALLBACK_ENVNAME
#define FOAM_RESOURCE_SITE_FALLBACK_ENVNAME
Definition: foamVersion.H:79
FOAM_PROJECT_ENVNAME
#define FOAM_PROJECT_ENVNAME
Definition: etcFiles.C:49
Foam::etcDirs
fileNameList etcDirs(bool test=true)
The etc search directories in the normal search order.
Definition: etcFiles.C:243
Foam::findEtcDirs
fileNameList findEtcDirs(const fileName &name, unsigned short location=0777, const bool findFirst=false)
Search for directories from user/group/other etc locations.
Definition: etcFiles.C:381
Foam::findEtcEntry
fileName findEtcEntry(const fileName &name, unsigned short location=0777, const fileName::Type typeRequired=fileName::Type::UNDEFINED)
Search for a single FILE or DIRECTORY within the etc directories.
Definition: etcFiles.C:415
Foam::fileName::Type
Type
Enumerations to handle directory entry types.
Definition: fileName.H:76
Foam::List::append
void append(const T &val)
Append an element at the end of the list.
Definition: ListI.H:182
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::getEnv
string getEnv(const std::string &envName)
Get environment value for given envName.
Definition: MSwindows.C:371
FOAM_RESOURCE_SITE_ENVNAME
#define FOAM_RESOURCE_SITE_ENVNAME
The env name for site-resources to obtain a site-resources directory.
Definition: foamVersion.H:71
Foam::mode
mode_t mode(const fileName &name, const bool followLink=true)
Return the file mode, normally following symbolic links.
Definition: MSwindows.C:564
Foam::foamVersion::api
const int api
Foam::findEtcFile
fileName findEtcFile(const fileName &name, const bool mandatory=false, unsigned short location=0777)
Search for a single FILE within the etc directories.
Definition: etcFiles.C:446
Foam::findEtcDir
fileName findEtcDir(const fileName &name, unsigned short location=0777)
Search for a single FILE within the etc directories.
Definition: etcFiles.C:436
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::findEtcFiles
fileNameList findEtcFiles(const fileName &name, const bool mandatory=false, unsigned short location=0777, const bool findFirst=false)
Search for files from user/group/other etc locations.
Definition: etcFiles.C:392
Foam::List::resize
void resize(const label newSize)
Adjust allocated size of list.
Definition: ListI.H:139
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::foamVersion::version
const std::string version
OpenFOAM version (name or stringified number) as a std::string.
found
bool found
Definition: TABSMDCalcMethod2.H:32
etcFiles.H
Functions to search 'etc' directories for configuration files etc.
FOAM_RESOURCE_USER_CONFIG_DIRNAME
#define FOAM_RESOURCE_USER_CONFIG_DIRNAME
Definition: JobInfo.C:40
Foam::home
fileName home()
Return home directory path name for the current user.
Definition: MSwindows.C:449
Foam::List< fileName >
Foam::findEtcEntries
fileNameList findEtcEntries(const fileName &name, unsigned short location=0777, const fileName::Type typeRequired=fileName::Type::UNDEFINED, const bool findFirst=false)
Search for files or directories from user/group/other etc locations.
Definition: etcFiles.C:280
Foam::isDir
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: MSwindows.C:643
foamVersion.H