1 | // |
---|---|
2 | // Path_UNIX.cpp |
3 | // |
4 | // Library: Foundation |
5 | // Package: Filesystem |
6 | // Module: Path |
7 | // |
8 | // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. |
9 | // and Contributors. |
10 | // |
11 | // SPDX-License-Identifier: BSL-1.0 |
12 | // |
13 | |
14 | |
15 | #include "Poco/Path_UNIX.h" |
16 | #include "Poco/Exception.h" |
17 | #include "Poco/Environment_UNIX.h" |
18 | #include "Poco/Ascii.h" |
19 | #include <unistd.h> |
20 | #include <stdlib.h> |
21 | #include <sys/types.h> |
22 | #if !defined(POCO_VXWORKS) |
23 | #include <pwd.h> |
24 | #endif |
25 | #include <climits> |
26 | |
27 | |
28 | #ifndef PATH_MAX |
29 | #define PATH_MAX 1024 // fallback |
30 | #endif |
31 | |
32 | |
33 | namespace Poco { |
34 | |
35 | |
36 | std::string PathImpl::currentImpl() |
37 | { |
38 | std::string path; |
39 | char cwd[PATH_MAX]; |
40 | if (getcwd(cwd, sizeof(cwd))) |
41 | path = cwd; |
42 | else |
43 | throw SystemException("cannot get current directory"); |
44 | std::string::size_type n = path.size(); |
45 | if (n > 0 && path[n - 1] != '/') path.append("/"); |
46 | return path; |
47 | } |
48 | |
49 | |
50 | std::string PathImpl::homeImpl() |
51 | { |
52 | #if defined(POCO_VXWORKS) |
53 | if (EnvironmentImpl::hasImpl("HOME")) |
54 | return EnvironmentImpl::getImpl("HOME"); |
55 | else |
56 | return "/"; |
57 | #else |
58 | std::string path; |
59 | struct passwd* pwd = getpwuid(getuid()); |
60 | if (pwd) |
61 | path = pwd->pw_dir; |
62 | else |
63 | { |
64 | pwd = getpwuid(geteuid()); |
65 | if (pwd) |
66 | path = pwd->pw_dir; |
67 | else |
68 | if (EnvironmentImpl::hasImpl("HOME")) |
69 | path = EnvironmentImpl::getImpl("HOME"); |
70 | } |
71 | std::string::size_type n = path.size(); |
72 | if (n > 0 && path[n - 1] != '/') path.append("/"); |
73 | return path; |
74 | #endif |
75 | } |
76 | |
77 | |
78 | std::string PathImpl::configHomeImpl() |
79 | { |
80 | #if defined(POCO_VXWORKS) |
81 | return PathImpl::homeImpl(); |
82 | #elif POCO_OS == POCO_OS_MAC_OS_X |
83 | std::string path = PathImpl::homeImpl(); |
84 | std::string::size_type n = path.size(); |
85 | if (n > 0 && path[n - 1] == '/') |
86 | path.append("Library/Preferences/"); |
87 | return path; |
88 | #else |
89 | std::string path; |
90 | if (EnvironmentImpl::hasImpl("XDG_CONFIG_HOME")) |
91 | path = EnvironmentImpl::getImpl("XDG_CONFIG_HOME"); |
92 | if (!path.empty()) |
93 | return path; |
94 | |
95 | path = PathImpl::homeImpl(); |
96 | std::string::size_type n = path.size(); |
97 | if (n > 0 && path[n - 1] == '/') |
98 | path.append(".config/"); |
99 | |
100 | return path; |
101 | #endif |
102 | } |
103 | |
104 | |
105 | std::string PathImpl::dataHomeImpl() |
106 | { |
107 | #if defined(POCO_VXWORKS) |
108 | return PathImpl::homeImpl(); |
109 | #elif POCO_OS == POCO_OS_MAC_OS_X |
110 | std::string path = PathImpl::homeImpl(); |
111 | std::string::size_type n = path.size(); |
112 | if (n > 0 && path[n - 1] == '/') |
113 | path.append("Library/Application Support/"); |
114 | return path; |
115 | #else |
116 | std::string path; |
117 | if (EnvironmentImpl::hasImpl("XDG_DATA_HOME")) |
118 | path = EnvironmentImpl::getImpl("XDG_DATA_HOME"); |
119 | if (!path.empty()) |
120 | return path; |
121 | |
122 | path = PathImpl::homeImpl(); |
123 | std::string::size_type n = path.size(); |
124 | if (n > 0 && path[n - 1] == '/') |
125 | path.append(".local/share/"); |
126 | |
127 | return path; |
128 | #endif |
129 | } |
130 | |
131 | |
132 | std::string PathImpl::cacheHomeImpl() |
133 | { |
134 | #if defined(POCO_VXWORKS) |
135 | return PathImpl::tempImpl(); |
136 | #elif POCO_OS == POCO_OS_MAC_OS_X |
137 | std::string path = PathImpl::homeImpl(); |
138 | std::string::size_type n = path.size(); |
139 | if (n > 0 && path[n - 1] == '/') |
140 | path.append("Library/Caches/"); |
141 | return path; |
142 | #else |
143 | std::string path; |
144 | if (EnvironmentImpl::hasImpl("XDG_CACHE_HOME")) |
145 | path = EnvironmentImpl::getImpl("XDG_CACHE_HOME"); |
146 | if (!path.empty()) |
147 | return path; |
148 | |
149 | path = PathImpl::homeImpl(); |
150 | std::string::size_type n = path.size(); |
151 | if (n > 0 && path[n - 1] == '/') |
152 | path.append(".cache/"); |
153 | |
154 | return path; |
155 | #endif |
156 | } |
157 | |
158 | |
159 | std::string PathImpl::tempImpl() |
160 | { |
161 | std::string path; |
162 | char* tmp = getenv("TMPDIR"); |
163 | if (tmp) |
164 | { |
165 | path = tmp; |
166 | std::string::size_type n = path.size(); |
167 | if (n > 0 && path[n - 1] != '/') path.append("/"); |
168 | } |
169 | else |
170 | { |
171 | path = "/tmp/"; |
172 | } |
173 | return path; |
174 | } |
175 | |
176 | |
177 | std::string PathImpl::configImpl() |
178 | { |
179 | std::string path; |
180 | |
181 | #if POCO_OS == POCO_OS_MAC_OS_X |
182 | path = "/Library/Preferences/"; |
183 | #else |
184 | path = "/etc/"; |
185 | #endif |
186 | return path; |
187 | } |
188 | |
189 | |
190 | std::string PathImpl::nullImpl() |
191 | { |
192 | #if defined(POCO_VXWORKS) |
193 | return "/null"; |
194 | #else |
195 | return "/dev/null"; |
196 | #endif |
197 | } |
198 | |
199 | |
200 | std::string PathImpl::expandImpl(const std::string& path) |
201 | { |
202 | std::string result; |
203 | std::string::const_iterator it = path.begin(); |
204 | std::string::const_iterator end = path.end(); |
205 | if (it != end && *it == '~') |
206 | { |
207 | ++it; |
208 | if (it != end && *it == '/') |
209 | { |
210 | const char* homeEnv = getenv("HOME"); |
211 | if (homeEnv) |
212 | { |
213 | result += homeEnv; |
214 | std::string::size_type resultSize = result.size(); |
215 | if (resultSize > 0 && result[resultSize - 1] != '/') |
216 | result.append("/"); |
217 | } |
218 | else |
219 | { |
220 | result += homeImpl(); |
221 | } |
222 | ++it; |
223 | } |
224 | else result += '~'; |
225 | } |
226 | while (it != end) |
227 | { |
228 | if (*it == '\\') |
229 | { |
230 | ++it; |
231 | if (*it == '$') |
232 | { |
233 | result += *it++; |
234 | } |
235 | } |
236 | else if (*it == '$') |
237 | { |
238 | std::string var; |
239 | ++it; |
240 | if (it != end && *it == '{') |
241 | { |
242 | ++it; |
243 | while (it != end && *it != '}') var += *it++; |
244 | if (it != end) ++it; |
245 | } |
246 | else |
247 | { |
248 | while (it != end && (Ascii::isAlphaNumeric(*it) || *it == '_')) var += *it++; |
249 | } |
250 | char* val = getenv(var.c_str()); |
251 | if (val) result += val; |
252 | } |
253 | else result += *it++; |
254 | } |
255 | return result; |
256 | } |
257 | |
258 | |
259 | void PathImpl::listRootsImpl(std::vector<std::string>& roots) |
260 | { |
261 | roots.clear(); |
262 | roots.push_back("/"); |
263 | } |
264 | |
265 | |
266 | } // namespace Poco |
267 |