1/*
2 * Copyright (C) by Olivier Goffart <ogoffart@owncloud.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#pragma once
20
21#include "config.h"
22
23#include <QString>
24#include <ctime>
25#include <QFileInfo>
26#include <QLoggingCategory>
27
28#include <ocsynclib.h>
29
30class QFile;
31
32namespace OCC {
33
34OCSYNC_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcFileSystem)
35
36/**
37 * \addtogroup libsync
38 * @{
39 */
40
41/**
42 * @brief This file contains file system helper
43 */
44namespace FileSystem {
45
46 /**
47 * @brief Mark the file as hidden (only has effects on windows)
48 */
49 void OCSYNC_EXPORT setFileHidden(const QString &filename, bool hidden);
50
51 /**
52 * @brief Marks the file as read-only.
53 *
54 * On linux this either revokes all 'w' permissions or restores permissions
55 * according to the umask.
56 */
57 void OCSYNC_EXPORT setFileReadOnly(const QString &filename, bool readonly);
58
59 /**
60 * @brief Marks the file as read-only.
61 *
62 * It's like setFileReadOnly(), but weaker: if readonly is false and the user
63 * already has write permissions, no change to the permissions is made.
64 *
65 * This means that it will preserve explicitly set rw-r--r-- permissions even
66 * when the umask is 0002. (setFileReadOnly() would adjust to rw-rw-r--)
67 */
68 void OCSYNC_EXPORT setFileReadOnlyWeak(const QString &filename, bool readonly);
69
70 /**
71 * @brief Try to set permissions so that other users on the local machine can not
72 * go into the folder.
73 */
74 void OCSYNC_EXPORT setFolderMinimumPermissions(const QString &filename);
75
76 /** convert a "normal" windows path into a path that can be 32k chars long. */
77 QString OCSYNC_EXPORT longWinPath(const QString &inpath);
78
79 /**
80 * @brief Checks whether a file exists.
81 *
82 * Use this over QFileInfo::exists() and QFile::exists() to avoid bugs with lnk
83 * files, see above.
84 */
85 bool OCSYNC_EXPORT fileExists(const QString &filename, const QFileInfo & = QFileInfo());
86
87 /**
88 * @brief Rename the file \a originFileName to \a destinationFileName.
89 *
90 * It behaves as QFile::rename() but handles .lnk files correctly on Windows.
91 */
92 bool OCSYNC_EXPORT rename(const QString &originFileName,
93 const QString &destinationFileName,
94 QString *errorString = NULL);
95
96 /**
97 * Rename the file \a originFileName to \a destinationFileName, and
98 * overwrite the destination if it already exists - without extra checks.
99 */
100 bool OCSYNC_EXPORT uncheckedRenameReplace(const QString &originFileName,
101 const QString &destinationFileName,
102 QString *errorString);
103
104 /**
105 * Removes a file.
106 *
107 * Equivalent to QFile::remove(), except on Windows, where it will also
108 * successfully remove read-only files.
109 */
110 bool OCSYNC_EXPORT remove(const QString &fileName, QString *errorString = 0);
111
112 /**
113 * Move the specified file or folder to the trash. (Only implemented on linux)
114 */
115 bool OCSYNC_EXPORT moveToTrash(const QString &filename, QString *errorString);
116
117 /**
118 * Replacement for QFile::open(ReadOnly) followed by a seek().
119 * This version sets a more permissive sharing mode on Windows.
120 *
121 * Warning: The resulting file may have an empty fileName and be unsuitable for use
122 * with QFileInfo! Calling seek() on the QFile with >32bit signed values will fail!
123 */
124 bool OCSYNC_EXPORT openAndSeekFileSharedRead(QFile *file, QString *error, qint64 seek);
125
126#ifdef Q_OS_WIN
127 /**
128 * Returns the file system used at the given path.
129 */
130 QString fileSystemForPath(const QString &path);
131#endif
132
133 QByteArray OCSYNC_EXPORT calcMd5(const QString &fileName);
134 QByteArray OCSYNC_EXPORT calcSha1(const QString &fileName);
135#ifdef ZLIB_FOUND
136 QByteArray OCSYNC_EXPORT calcAdler32(const QString &fileName);
137#endif
138
139 /**
140 * Returns true when a file is locked. (Windows only)
141 */
142 bool OCSYNC_EXPORT isFileLocked(const QString &fileName);
143
144 /**
145 * Returns whether the file is a shortcut file (ends with .lnk)
146 */
147 bool OCSYNC_EXPORT isLnkFile(const QString &filename);
148
149 /**
150 * Returns whether the file is a junction (windows only)
151 */
152 bool OCSYNC_EXPORT isJunction(const QString &filename);
153
154 /*
155 * This function takes a path and converts it to a UNC representation of the
156 * string. That means that it prepends a \\?\ (unless already UNC) and converts
157 * all slashes to backslashes.
158 *
159 * Note the following:
160 * - The string must be absolute.
161 * - it needs to contain a drive character to be a valid UNC
162 * - A conversion is only done if the path len is larger than 245. Otherwise
163 * the windows API functions work with the normal "unixoid" representation too.
164 */
165 template<typename S>
166 S pathtoUNC(const S &str)
167 {
168 int len = 0;
169 S longStr;
170
171 len = str.length();
172 longStr.reserve(len+4);
173
174 // prepend \\?\ and convert '/' => '\' to support long names
175 if( str[0] == '/' || str[0] == '\\' ) {
176 // Don't prepend if already UNC
177 if( !(len > 1 && (str[1] == '/' || str[1] == '\\')) ) {
178 longStr.append("\\\\?");
179 }
180 } else {
181 longStr.append("\\\\?\\"); // prepend string by this four magic chars.
182 }
183 longStr += str;
184
185 /* replace all occurences of / with the windows native \ */
186
187 for (auto it = longStr.begin(); it != longStr.end(); ++it) {
188 if(*it == '/') {
189 *it = '\\';
190 }
191 }
192 return longStr;
193 }
194}
195
196/** @} */
197}
198