1/*
2 * PROGRAM: JRD FileSystem Path Handler
3 * MODULE: path_utils.h
4 * DESCRIPTION: Abstract class for file path management
5 *
6 * The contents of this file are subject to the Initial
7 * Developer's Public License Version 1.0 (the "License");
8 * you may not use this file except in compliance with the
9 * License. You may obtain a copy of the License at
10 * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
11 *
12 * Software distributed under the License is distributed AS IS,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied.
14 * See the License for the specific language governing rights
15 * and limitations under the License.
16 *
17 * The Original Code was created by John Bellardo
18 * for the Firebird Open Source RDBMS project.
19 *
20 * Copyright (c) 2002 John Bellardo <bellardo at cs.ucsd.edu>
21 * and all contributors signed below.
22 *
23 * All Rights Reserved.
24 * Contributor(s): ______________________________________.
25 *
26 */
27
28#ifndef JRD_OS_PATH_UTILS_H
29#define JRD_OS_PATH_UTILS_H
30
31#include "../common/classes/fb_string.h"
32#include "../../common/classes/alloc.h"
33
34
35/** This is a utility class that provides a platform independent way to do some
36 file path operations. The operations include determining if a path is
37 relative ro absolute, combining to paths to form a new path (adding directory
38 separator), isolating the last component in a path, and getting a listing
39 of all the files in a given directory. Each supported platform will require
40 an implementation of these abstractions that is appropriate for that platform.
41**/
42class PathUtils
43{
44public:
45 /// The directory separator for the platform.
46 static const char dir_sep;
47
48 /// String used to point to parent directory
49 static const char* up_dir_link;
50
51 /// The directory list separator for the platform.
52 static const char dir_list_sep;
53
54 /** An abstract base class for iterating through the contents of a directory.
55 Instances of this class are created using the newDirItr method of
56 the PathUtils class. Each platform implementation is expected to
57 subclass dir_iterator to create dir_iterator objects that function
58 correctly on the platform.
59 **/
60 class dir_iterator : protected Firebird::AutoStorage
61 {
62 public:
63 /// The constructor requires a string that is the path of the
64 /// directory being iterater.
65 /// dir_iterator may be located on stack, therefore use AutoStorage
66 dir_iterator(MemoryPool& p, const Firebird::PathName& dir)
67 : AutoStorage(p), dirPrefix(getPool(), dir)
68 {}
69
70 dir_iterator(const Firebird::PathName& dir)
71 : AutoStorage(), dirPrefix(getPool(), dir)
72 {}
73
74 /// destructor provided for memory cleanup.
75 virtual ~dir_iterator() {}
76
77 /// The prefix increment operator (++itr) advances the iteration by
78 /// one and returns a reference to itself to allow cascading operations.
79 virtual const dir_iterator& operator++() = 0;
80
81 /// The dereference operator returns a reference to the current
82 /// item in the iteration. This path is prefixed with the path of
83 /// the directory. If the last element of the path is wanted use
84 /// PathUtils::splitLastComponent on the result of this function.
85 virtual const Firebird::PathName& operator*() = 0;
86
87 /// Tests if the iterator has reached the end of the iteration.
88 /// It is implemented in such a way to make the following for loop
89 /// work correctly: for (dir_iterator *itr = PathUtils::newDirItr(); *itr; ++(*itr))
90 virtual operator bool() = 0;
91
92 protected:
93 /// Stores the path to the directory as given in the constructor.
94 const Firebird::PathName dirPrefix;
95
96 private:
97 /// default constructor not allowed.
98 dir_iterator(); // no impl
99 /// copy constructor not allowed
100 dir_iterator(const dir_iterator&); // no impl
101 /// assignment operator not allowed
102 const dir_iterator& operator=(const dir_iterator&); // no impl
103
104 };
105
106 /** isRelative returns true if the given path is relative, and false if not.
107 A relative path is one specified in relation to the current directory.
108 For example, the path 'firebird/bin' is a relative path in unix while
109 the path '/opt/firebird/bin' is not.
110 **/
111 static bool isRelative(const Firebird::PathName& path);
112
113 /** isSymLink returns true if the given path is symbolic link, and false if not.
114 Use of this links may provide way to override system security.
115 Example: ln -s /usr/firebird/ExternalTables/mytable /etc/xinet.d/remoteshell
116 and insert desired rows into mytable.
117 **/
118 static bool isSymLink(const Firebird::PathName& path);
119
120 /** canAccess returns true if the given path can be accessed
121 by this process. mode - like in ACCESS(2).
122 **/
123 static bool canAccess(const Firebird::PathName& path, int mode);
124
125 /** Concatenates the two paths given in the second and third parameters,
126 and writes the resulting path into the first parameter. The
127 two path input arguments (arg 2 and 3) are concatenated in the order
128 arg2 arg3. The concatenation is done is such a way as to remove
129 any duplicate directory separators that may have resulted from
130 a simple string concatenation of the arguments with the directory
131 separator character.
132 **/
133 static void concatPath(Firebird::PathName&, const Firebird::PathName&,
134 const Firebird::PathName&);
135
136 // Tries to ensure our path finishes with a platform-specific directory separator.
137 // We don't work correctly with MBCS.
138 static void ensureSeparator(Firebird::PathName& in_out);
139
140 /** splitLastComponent takes a path as the third argument and
141 removes the last component in that path (usually a file or directory name).
142 The removed component is returned in the second parameter, and the path left
143 after the component is removed is returned in the first parameter.
144 If the input path has only one component that component is returned in the
145 second parameter and the first parameter is set to the empty string.
146 **/
147 static void splitLastComponent(Firebird::PathName&, Firebird::PathName&,
148 const Firebird::PathName&);
149
150 /** splitPrefix takes a path as the first argument, splits OS-dependent prefix
151 from it (something like C:\, D: or \ in windows or / in posix),
152 and returns stripped path inplace, i.e. as first argument.
153 Prefix is returned as the second argument.
154 **/
155 static void splitPrefix(Firebird::PathName& path, Firebird::PathName& prefix);
156
157 /** This is the factory method for allocating dir_iterator objects.
158 It takes a reference to a memory pool to use for all heap allocations,
159 and the path of the directory to iterate (in that order). It is the
160 responsibility of the caller to delete the object when they are done with it.
161 All errors result in either exceptions being thrown, or a valid empty
162 dir_iterator being returned.
163 **/
164 static dir_iterator* newDirItr(MemoryPool&, const Firebird::PathName&);
165
166 /** setDirIterator converts all dir iterators to one required on current
167 platform.
168 **/
169 static void setDirIterator(char* path);
170};
171
172#endif // JRD_OS_PATH_UTILS_H
173
174