1 | /* |
2 | * libcsync -- a library to sync a directory with another |
3 | * |
4 | * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org> |
5 | * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com> |
6 | * |
7 | * This library is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU Lesser General Public |
9 | * License as published by the Free Software Foundation; either |
10 | * version 2.1 of the License, or (at your option) any later version. |
11 | * |
12 | * This library is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | * Lesser General Public License for more details. |
16 | * |
17 | * You should have received a copy of the GNU Lesser General Public |
18 | * License along with this library; if not, write to the Free Software |
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | */ |
21 | |
22 | /** |
23 | * @file csync.h |
24 | * |
25 | * @brief Application developer interface for csync. |
26 | * |
27 | * @defgroup csyncPublicAPI csync public API |
28 | * |
29 | * @{ |
30 | */ |
31 | |
32 | #ifndef _CSYNC_H |
33 | #define _CSYNC_H |
34 | |
35 | #include "std/c_private.h" |
36 | #include "ocsynclib.h" |
37 | |
38 | #include <sys/stat.h> |
39 | #include <stdbool.h> |
40 | #include <stdint.h> |
41 | #include <sys/types.h> |
42 | #include <config_csync.h> |
43 | #include <functional> |
44 | #include <memory> |
45 | #include <QByteArray> |
46 | #include "common/remotepermissions.h" |
47 | |
48 | namespace OCC { |
49 | class SyncJournalFileRecord; |
50 | } |
51 | |
52 | #if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && !defined(Q_CC_CLANG) && (__GNUC__ * 100 + __GNUC_MINOR__ < 408) |
53 | // openSuse 12.3 didn't like enum bitfields. |
54 | #define BITFIELD(size) |
55 | #elif defined(Q_CC_MSVC) |
56 | // MSVC stores enum and bool as signed, so we need to add a bit for the sign |
57 | #define BITFIELD(size) :(size+1) |
58 | #else |
59 | #define BITFIELD(size) :size |
60 | #endif |
61 | |
62 | enum csync_status_codes_e { |
63 | CSYNC_STATUS_OK = 0, |
64 | |
65 | CSYNC_STATUS_ERROR = 1024, /* don't use this code, |
66 | */ |
67 | CSYNC_STATUS_UNSUCCESSFUL, /* Unspecific problem happend */ |
68 | CSYNC_STATUS_STATEDB_LOAD_ERROR, /* Statedb can not be loaded. */ |
69 | CSYNC_STATUS_UPDATE_ERROR, /* general update or discovery error */ |
70 | CSYNC_STATUS_TIMEOUT, /* UNUSED */ |
71 | CSYNC_STATUS_HTTP_ERROR, /* UNUSED */ |
72 | CSYNC_STATUS_PERMISSION_DENIED, /* */ |
73 | CSYNC_STATUS_NOT_FOUND, |
74 | CSYNC_STATUS_FILE_EXISTS, |
75 | CSYNC_STATUS_OUT_OF_SPACE, |
76 | CSYNC_STATUS_SERVICE_UNAVAILABLE, |
77 | CSYNC_STATUS_STORAGE_UNAVAILABLE, |
78 | CSYNC_STATUS_FILE_SIZE_ERROR, |
79 | CSYNC_STATUS_OPENDIR_ERROR, |
80 | CSYNC_STATUS_READDIR_ERROR, |
81 | CSYNC_STATUS_OPEN_ERROR, |
82 | CSYNC_STATUS_ABORTED, |
83 | /* Codes for file individual status: */ |
84 | CSYNC_STATUS_INDIVIDUAL_IS_SYMLINK, |
85 | CSYNC_STATUS_INDIVIDUAL_IGNORE_LIST, |
86 | CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS, |
87 | CSYNC_STATUS_INDIVIDUAL_TRAILING_SPACE, |
88 | CSYNC_STATUS_INDIVIDUAL_EXCLUDE_LONG_FILENAME, |
89 | CSYNC_STATUS_INDIVIDUAL_EXCLUDE_HIDDEN, |
90 | CSYNC_STATUS_INVALID_CHARACTERS, |
91 | CSYNC_STATUS_INDIVIDUAL_STAT_FAILED, |
92 | CSYNC_STATUS_FORBIDDEN, |
93 | CSYNC_STATUS_INDIVIDUAL_TOO_DEEP, |
94 | CSYNC_STATUS_INDIVIDUAL_IS_CONFLICT_FILE, |
95 | CSYNC_STATUS_INDIVIDUAL_CANNOT_ENCODE |
96 | }; |
97 | |
98 | typedef enum csync_status_codes_e CSYNC_STATUS; |
99 | |
100 | #ifndef likely |
101 | # define likely(x) (x) |
102 | #endif |
103 | #ifndef unlikely |
104 | # define unlikely(x) (x) |
105 | #endif |
106 | |
107 | #define CSYNC_STATUS_IS_OK(x) (likely((x) == CSYNC_STATUS_OK)) |
108 | #define CSYNC_STATUS_IS_ERR(x) (unlikely((x) >= CSYNC_STATUS_ERROR)) |
109 | #define CSYNC_STATUS_IS_EQUAL(x, y) ((x) == (y)) |
110 | |
111 | /** |
112 | * Instruction enum. In the file traversal structure, it describes |
113 | * the csync state of a file. |
114 | */ |
115 | enum csync_instructions_e { |
116 | CSYNC_INSTRUCTION_NONE = 0x00000000, /* Nothing to do (UPDATE|RECONCILE) */ |
117 | CSYNC_INSTRUCTION_EVAL = 0x00000001, /* There was changed compared to the DB (UPDATE) */ |
118 | CSYNC_INSTRUCTION_REMOVE = 0x00000002, /* The file need to be removed (RECONCILE) */ |
119 | CSYNC_INSTRUCTION_RENAME = 0x00000004, /* The file need to be renamed (RECONCILE) */ |
120 | CSYNC_INSTRUCTION_EVAL_RENAME = 0x00000800, /* The file is new, it is the destination of a rename (UPDATE) */ |
121 | CSYNC_INSTRUCTION_NEW = 0x00000008, /* The file is new compared to the db (UPDATE) */ |
122 | CSYNC_INSTRUCTION_CONFLICT = 0x00000010, /* The file need to be downloaded because it is a conflict (RECONCILE) */ |
123 | CSYNC_INSTRUCTION_IGNORE = 0x00000020, /* The file is ignored (UPDATE|RECONCILE) */ |
124 | CSYNC_INSTRUCTION_SYNC = 0x00000040, /* The file need to be pushed to the other remote (RECONCILE) */ |
125 | CSYNC_INSTRUCTION_STAT_ERROR = 0x00000080, |
126 | CSYNC_INSTRUCTION_ERROR = 0x00000100, |
127 | CSYNC_INSTRUCTION_TYPE_CHANGE = 0x00000200, /* Like NEW, but deletes the old entity first (RECONCILE) |
128 | Used when the type of something changes from directory to file |
129 | or back. */ |
130 | CSYNC_INSTRUCTION_UPDATE_METADATA = 0x00000400, /* If the etag has been updated and need to be writen to the db, |
131 | but without any propagation (UPDATE|RECONCILE) */ |
132 | }; |
133 | |
134 | // This enum is used with BITFIELD(3) and BITFIELD(4) in several places. |
135 | // Also, this value is stored in the database, so beware of value changes. |
136 | enum ItemType { |
137 | ItemTypeFile = 0, |
138 | ItemTypeSoftLink = 1, |
139 | ItemTypeDirectory = 2, |
140 | ItemTypeSkip = 3, |
141 | ItemTypeVirtualFile = 4, |
142 | ItemTypeVirtualFileDownload = 5 |
143 | }; |
144 | |
145 | |
146 | #define FILE_ID_BUF_SIZE 36 |
147 | |
148 | // currently specified at https://github.com/owncloud/core/issues/8322 are 9 to 10 |
149 | #define REMOTE_PERM_BUF_SIZE 15 |
150 | |
151 | typedef struct csync_file_stat_s csync_file_stat_t; |
152 | |
153 | struct OCSYNC_EXPORT csync_file_stat_s { |
154 | time_t modtime; |
155 | int64_t size; |
156 | uint64_t inode; |
157 | |
158 | OCC::RemotePermissions remotePerm; |
159 | ItemType type BITFIELD(4); |
160 | bool child_modified BITFIELD(1); |
161 | bool has_ignored_files BITFIELD(1); // Specify that a directory, or child directory contains ignored files. |
162 | bool is_hidden BITFIELD(1); // Not saved in the DB, only used during discovery for local files. |
163 | |
164 | QByteArray path; |
165 | QByteArray rename_path; |
166 | QByteArray etag; |
167 | QByteArray file_id; |
168 | QByteArray directDownloadUrl; |
169 | QByteArray directDownloadCookies; |
170 | QByteArray original_path; // only set if locale conversion fails |
171 | |
172 | // In the local tree, this can hold a checksum and its type if it is |
173 | // computed during discovery for some reason. |
174 | // In the remote tree, this will have the server checksum, if available. |
175 | // In both cases, the format is "SHA1:baff". |
176 | QByteArray ; |
177 | |
178 | CSYNC_STATUS error_status; |
179 | |
180 | enum csync_instructions_e instruction; /* u32 */ |
181 | |
182 | csync_file_stat_s() |
183 | : modtime(0) |
184 | , size(0) |
185 | , inode(0) |
186 | , type(ItemTypeSkip) |
187 | , child_modified(false) |
188 | , has_ignored_files(false) |
189 | , is_hidden(false) |
190 | , error_status(CSYNC_STATUS_OK) |
191 | , instruction(CSYNC_INSTRUCTION_NONE) |
192 | { } |
193 | |
194 | static std::unique_ptr<csync_file_stat_t> fromSyncJournalFileRecord(const OCC::SyncJournalFileRecord &rec); |
195 | }; |
196 | |
197 | /** |
198 | * csync handle |
199 | */ |
200 | typedef struct csync_s CSYNC; |
201 | |
202 | typedef int (*csync_auth_callback) (const char *prompt, char *buf, size_t len, |
203 | int echo, int verify, void *userdata); |
204 | |
205 | typedef void (*csync_update_callback) (bool local, |
206 | const char *dirUrl, |
207 | void *userdata); |
208 | |
209 | typedef void csync_vio_handle_t; |
210 | typedef csync_vio_handle_t* (*csync_vio_opendir_hook) (const char *url, |
211 | void *userdata); |
212 | typedef std::unique_ptr<csync_file_stat_t> (*csync_vio_readdir_hook) (csync_vio_handle_t *dhhandle, |
213 | void *userdata); |
214 | typedef void (*csync_vio_closedir_hook) (csync_vio_handle_t *dhhandle, |
215 | void *userdata); |
216 | |
217 | /* Compute the checksum of the given \a checksumTypeId for \a path. */ |
218 | typedef QByteArray (*csync_checksum_hook)( |
219 | const QByteArray &path, const QByteArray &, void *userdata); |
220 | |
221 | /** |
222 | * @brief Update detection |
223 | * |
224 | * @param ctx The context to run the update detection on. |
225 | * |
226 | * @return 0 on success, less than 0 if an error occurred. |
227 | */ |
228 | int OCSYNC_EXPORT csync_update(CSYNC *ctx); |
229 | |
230 | /** |
231 | * @brief Reconciliation |
232 | * |
233 | * @param ctx The context to run the reconciliation on. |
234 | * |
235 | * @return 0 on success, less than 0 if an error occurred. |
236 | */ |
237 | int OCSYNC_EXPORT csync_reconcile(CSYNC *ctx); |
238 | |
239 | /** |
240 | * @brief Get the userdata saved in the context. |
241 | * |
242 | * @param ctx The csync context. |
243 | * |
244 | * @return The userdata saved in the context, NULL if an error |
245 | * occurred. |
246 | */ |
247 | void *csync_get_userdata(CSYNC *ctx); |
248 | |
249 | /** |
250 | * @brief Save userdata to the context which is passed to the auth |
251 | * callback function. |
252 | * |
253 | * @param ctx The csync context. |
254 | * |
255 | * @param userdata The userdata to be stored in the context. |
256 | * |
257 | * @return 0 on success, less than 0 if an error occurred. |
258 | */ |
259 | int OCSYNC_EXPORT csync_set_userdata(CSYNC *ctx, void *userdata); |
260 | |
261 | /** |
262 | * @brief Get the authentication callback set. |
263 | * |
264 | * @param ctx The csync context. |
265 | * |
266 | * @return The authentication callback set or NULL if an error |
267 | * occurred. |
268 | */ |
269 | csync_auth_callback OCSYNC_EXPORT csync_get_auth_callback(CSYNC *ctx); |
270 | |
271 | /** |
272 | * @brief Set the authentication callback. |
273 | * |
274 | * @param ctx The csync context. |
275 | * |
276 | * @param cb The authentication callback. |
277 | * |
278 | * @return 0 on success, less than 0 if an error occurred. |
279 | */ |
280 | int OCSYNC_EXPORT csync_set_auth_callback(CSYNC *ctx, csync_auth_callback cb); |
281 | |
282 | /* Used for special modes or debugging */ |
283 | CSYNC_STATUS OCSYNC_EXPORT csync_get_status(CSYNC *ctx); |
284 | |
285 | /* Used for special modes or debugging */ |
286 | int OCSYNC_EXPORT csync_set_status(CSYNC *ctx, int status); |
287 | |
288 | using csync_treewalk_visit_func = std::function<int(csync_file_stat_t *cur, csync_file_stat_t *other)>; |
289 | |
290 | /** |
291 | * @brief Walk the local file tree and call a visitor function for each file. |
292 | * |
293 | * @param ctx The csync context. |
294 | * @param visitor A callback function to handle the file info. |
295 | * |
296 | * @return 0 on success, less than 0 if an error occurred. |
297 | */ |
298 | int OCSYNC_EXPORT csync_walk_local_tree(CSYNC *ctx, const csync_treewalk_visit_func &visitor); |
299 | |
300 | /** |
301 | * @brief Walk the remote file tree and call a visitor function for each file. |
302 | * |
303 | * @param ctx The csync context. |
304 | * @param visitor A callback function to handle the file info. |
305 | * |
306 | * @return 0 on success, less than 0 if an error occurred. |
307 | */ |
308 | int OCSYNC_EXPORT csync_walk_remote_tree(CSYNC *ctx, const csync_treewalk_visit_func &visitor); |
309 | |
310 | /** |
311 | * @brief Aborts the current sync run as soon as possible. Can be called from another thread. |
312 | * |
313 | * @param ctx The csync context. |
314 | */ |
315 | void OCSYNC_EXPORT csync_request_abort(CSYNC *ctx); |
316 | |
317 | /** |
318 | * @brief Clears the abort flag. Can be called from another thread. |
319 | * |
320 | * @param ctx The csync context. |
321 | */ |
322 | void OCSYNC_EXPORT csync_resume(CSYNC *ctx); |
323 | |
324 | /** |
325 | * @brief Checks for the abort flag, to be used from the modules. |
326 | * |
327 | * @param ctx The csync context. |
328 | */ |
329 | int OCSYNC_EXPORT csync_abort_requested(CSYNC *ctx); |
330 | |
331 | time_t OCSYNC_EXPORT oc_httpdate_parse( const char *date ); |
332 | |
333 | /** |
334 | * }@ |
335 | */ |
336 | #endif /* _CSYNC_H */ |
337 | /* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */ |
338 | |