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 | **/ |
42 | class PathUtils |
43 | { |
44 | public: |
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 | |