Changeset View
Changeset View
Standalone View
Standalone View
src/xattr_p.h
Show First 20 Lines • Show All 154 Lines • ▼ Show 20 Line(s) | |||||
155 | } | 155 | } | ||
156 | 156 | | |||
157 | inline bool k_isSupported(const QString& path) | 157 | inline bool k_isSupported(const QString& path) | ||
158 | { | 158 | { | ||
159 | auto ret = k_getxattr(path, QStringLiteral("user.test"), nullptr); | 159 | auto ret = k_getxattr(path, QStringLiteral("user.test"), nullptr); | ||
160 | return (ret >= 0) || (errno != ENOTSUP); | 160 | return (ret >= 0) || (errno != ENOTSUP); | ||
161 | } | 161 | } | ||
162 | 162 | | |||
163 | | ||||
164 | static KFileMetaData::UserMetaData::Attribute _mapAttribute(const QByteArray& key) | ||||
165 | { | ||||
166 | using KFileMetaData::UserMetaData; | ||||
167 | if (key == "user.xdg.tags") { | ||||
168 | return UserMetaData::Attribute::Tags; | ||||
169 | } | ||||
170 | if (key == "user.baloo.rating") { | ||||
171 | return UserMetaData::Attribute::Rating; | ||||
172 | } | ||||
173 | if (key == "user.xdg.comment") { | ||||
174 | return UserMetaData::Attribute::Comment; | ||||
175 | } | ||||
176 | if (key == "user.xdg.origin.url") { | ||||
177 | return UserMetaData::Attribute::OriginUrl; | ||||
178 | } | ||||
179 | if (key == "user.xdg.origin.email.subject") { | ||||
180 | return UserMetaData::Attribute::OriginEmailSubject; | ||||
181 | } | ||||
182 | if (key == "user.xdg.origin.email.sender") { | ||||
183 | return UserMetaData::Attribute::OriginEmailSender; | ||||
184 | } | ||||
185 | if (key == "user.xdg.origin.email.message-id") { | ||||
186 | return UserMetaData::Attribute::OriginEmailMessageId; | ||||
187 | } | ||||
188 | return UserMetaData::Attribute::Other; | ||||
189 | } | ||||
190 | | ||||
191 | #if defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) | ||||
192 | static QList<QByteArray> _split_length_value(QByteArray data) | ||||
193 | { | ||||
194 | int pos = 0; | ||||
arrowdUnsubmitted Done arrowd: ```
variable 'pos' is uninitialized
``` | |||||
195 | QList<QByteArray> entries; | ||||
196 | | ||||
197 | while (pos < data.size()) { | ||||
198 | unsigned char len = data[pos]; | ||||
199 | if (pos + 1 + len <= data.size()) { | ||||
200 | auto value = data.mid(pos + 1, len); | ||||
201 | entries.append(value); | ||||
202 | } | ||||
203 | pos += 1 + len; | ||||
204 | } | ||||
arrowd: ```
error: use of undeclared identifier 'attributeName'
```
| |||||
205 | return entries; | ||||
206 | } | ||||
@arrowd - please add a qDebug() << "extattr_list size:" << size; here bruns: @arrowd - please add a `qDebug() << "extattr_list size:" << size;` here | |||||
207 | #endif | ||||
208 | | ||||
209 | KFileMetaData::UserMetaData::Attributes k_queryAttributes(const QString& path, | ||||
210 | KFileMetaData::UserMetaData::Attributes attributes) | ||||
211 | { | ||||
212 | using KFileMetaData::UserMetaData; | ||||
213 | | ||||
214 | const QByteArray p = QFile::encodeName(path); | ||||
215 | const char* encodedPath = p.constData(); | ||||
216 | | ||||
217 | #if defined(Q_OS_LINUX) | ||||
218 | const ssize_t size = listxattr(encodedPath, nullptr, 0); | ||||
219 | #elif defined(Q_OS_MAC) | ||||
220 | const ssize_t size = listxattr(encodedPath, nullptr, 0, 0); | ||||
221 | #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) | ||||
222 | const ssize_t size = extattr_list_file(encodedPath, EXTATTR_NAMESPACE_USER, nullptr, 0); | ||||
223 | #endif | ||||
224 | | ||||
225 | if (size == 0) { | ||||
226 | return UserMetaData::Attribute::None; | ||||
227 | } | ||||
228 | | ||||
229 | if (size == -1 && errno == ENOTSUP) { | ||||
230 | return UserMetaData::Attribute::None; | ||||
231 | } | ||||
arrowd: Ditto.
Also, `size` should be `r`, probably, see below. | |||||
bruns: Why ditto? | |||||
arrowd: Right, no need to change there. | |||||
232 | | ||||
@arrowd - please add a qDebug() << "extattr_list r:" << r << data; here bruns: @arrowd - please add a `qDebug() << "extattr_list r:" << r << data;` here | |||||
233 | if (size == -1 && errno == E2BIG) { | ||||
234 | return UserMetaData::Attribute::All; | ||||
arrowd: ```
error: use of undeclared identifier 'r'
``` | |||||
235 | } | ||||
236 | | ||||
237 | if (size > 0 && attributes == UserMetaData::Attribute::Any) { | ||||
238 | return UserMetaData::Attribute::All; | ||||
239 | } | ||||
240 | | ||||
241 | QByteArray data(size, Qt::Uninitialized); | ||||
242 | | ||||
243 | while (true) { | ||||
244 | #if defined(Q_OS_LINUX) | ||||
245 | const ssize_t r = listxattr(encodedPath, data.data(), data.size()); | ||||
246 | #elif defined(Q_OS_MAC) | ||||
247 | const ssize_t r = listxattr(encodedPath, data.data(), data.size(), 0); | ||||
248 | #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) | ||||
249 | const ssize_t r = extattr_list_file(encodedPath, EXTATTR_NAMESPACE_USER, data.data(), data.size()); | ||||
250 | #endif | ||||
251 | | ||||
252 | if (r == 0) { | ||||
253 | return UserMetaData::Attribute::None; | ||||
254 | } | ||||
255 | | ||||
256 | if (r < 0 && errno != ERANGE) { | ||||
257 | return UserMetaData::Attribute::None; | ||||
258 | } | ||||
259 | | ||||
260 | if (r > 0) { | ||||
261 | data.resize(r); | ||||
262 | break; | ||||
263 | } else { | ||||
264 | data.resize(data.size() * 2); | ||||
265 | } | ||||
266 | } | ||||
267 | | ||||
268 | UserMetaData::Attributes fileAttributes = UserMetaData::Attribute::None; | ||||
269 | QByteArray prefix = QByteArray::fromRawData("user.", 5); | ||||
270 | #if defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) | ||||
271 | const auto entries = _split_length_value(data); | ||||
272 | #else | ||||
273 | const auto entries = data.split('\0'); | ||||
274 | #endif | ||||
275 | for (const auto entry : entries) { | ||||
276 | if (!entry.startsWith(prefix)) { | ||||
277 | continue; | ||||
278 | } | ||||
279 | fileAttributes |= _mapAttribute(entry); | ||||
280 | fileAttributes &= attributes; | ||||
281 | | ||||
282 | if (fileAttributes == attributes) { | ||||
283 | break; | ||||
284 | } | ||||
285 | } | ||||
286 | | ||||
287 | return fileAttributes; | ||||
288 | } | ||||
289 | | ||||
163 | #elif defined(Q_OS_WIN) | 290 | #elif defined(Q_OS_WIN) | ||
164 | 291 | | |||
165 | inline ssize_t k_getxattr(const QString& path, const QString& name, QString* value) | 292 | inline ssize_t k_getxattr(const QString& path, const QString& name, QString* value) | ||
166 | { | 293 | { | ||
167 | const QString fullADSName = path + QLatin1Char(':') + name; | 294 | const QString fullADSName = path + QLatin1Char(':') + name; | ||
168 | HANDLE hFile = ::CreateFileW(reinterpret_cast<const WCHAR*>(fullADSName.utf16()), GENERIC_READ, FILE_SHARE_READ, NULL, | 295 | HANDLE hFile = ::CreateFileW(reinterpret_cast<const WCHAR*>(fullADSName.utf16()), GENERIC_READ, FILE_SHARE_READ, NULL, | ||
169 | OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); | 296 | OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); | ||
170 | 297 | | |||
▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Line(s) | 399 | { | |||
273 | QFileInfo f(path); | 400 | QFileInfo f(path); | ||
274 | const QString drive = QString(f.absolutePath().left(2)) + QStringLiteral("\\"); | 401 | const QString drive = QString(f.absolutePath().left(2)) + QStringLiteral("\\"); | ||
275 | WCHAR szFSName[MAX_PATH]; | 402 | WCHAR szFSName[MAX_PATH]; | ||
276 | DWORD dwVolFlags; | 403 | DWORD dwVolFlags; | ||
277 | ::GetVolumeInformationW(reinterpret_cast<const WCHAR*>(drive.utf16()), NULL, 0, NULL, NULL, &dwVolFlags, szFSName, MAX_PATH); | 404 | ::GetVolumeInformationW(reinterpret_cast<const WCHAR*>(drive.utf16()), NULL, 0, NULL, NULL, &dwVolFlags, szFSName, MAX_PATH); | ||
278 | return ((dwVolFlags & FILE_NAMED_STREAMS) && _wcsicmp(szFSName, L"NTFS") == 0); | 405 | return ((dwVolFlags & FILE_NAMED_STREAMS) && _wcsicmp(szFSName, L"NTFS") == 0); | ||
279 | } | 406 | } | ||
280 | 407 | | |||
408 | KFileMetaData::UserMetaData::Attributes k_queryAttributes(const QString& path, | ||||
409 | KFileMetaData::UserMetaData::Attributes attributes) | ||||
410 | { | ||||
411 | if (!k_isSupported(path)) { | ||||
412 | return UserMetaData::Attribute::None; | ||||
413 | } | ||||
414 | | ||||
415 | // TODO - this is mostly a stub, streams should be enumerated, see k_hasAttribute above | ||||
416 | if (attributes == UserMetaData::Attribute::Any) { | ||||
417 | return UserMetaData::Attribute::All; | ||||
418 | } | ||||
419 | return attributes; | ||||
420 | } | ||||
421 | | ||||
281 | #else | 422 | #else | ||
282 | inline ssize_t k_getxattr(const QString&, const QString&, QString*) | 423 | inline ssize_t k_getxattr(const QString&, const QString&, QString*) | ||
283 | { | 424 | { | ||
284 | return 0; | 425 | return 0; | ||
285 | } | 426 | } | ||
286 | 427 | | |||
287 | inline int k_setxattr(const QString&, const QString&, const QString&) | 428 | inline int k_setxattr(const QString&, const QString&, const QString&) | ||
288 | { | 429 | { | ||
Show All 9 Lines | |||||
298 | { | 439 | { | ||
299 | return false | 440 | return false | ||
300 | } | 441 | } | ||
301 | 442 | | |||
302 | inline bool k_isSupported(const QString&) | 443 | inline bool k_isSupported(const QString&) | ||
303 | { | 444 | { | ||
304 | return false; | 445 | return false; | ||
305 | } | 446 | } | ||
447 | | ||||
448 | KFileMetaData::UserMetaData::Attributes k_queryAttributes(const QString&, | ||||
449 | KFileMetaData::UserMetaData::Attributes attributes) | ||||
450 | { | ||||
451 | return UserMetaData::Attribute::None; | ||||
452 | } | ||||
453 | | ||||
306 | #endif | 454 | #endif | ||
307 | 455 | | |||
308 | #endif // KFILEMETADATA_XATTR_P_H | 456 | #endif // KFILEMETADATA_XATTR_P_H |