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
48namespace OCC {
49class 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
62enum 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
98typedef 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 */
115enum 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.
136enum 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
151typedef struct csync_file_stat_s csync_file_stat_t;
152
153struct 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 checksumHeader;
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 */
200typedef struct csync_s CSYNC;
201
202typedef int (*csync_auth_callback) (const char *prompt, char *buf, size_t len,
203 int echo, int verify, void *userdata);
204
205typedef void (*csync_update_callback) (bool local,
206 const char *dirUrl,
207 void *userdata);
208
209typedef void csync_vio_handle_t;
210typedef csync_vio_handle_t* (*csync_vio_opendir_hook) (const char *url,
211 void *userdata);
212typedef std::unique_ptr<csync_file_stat_t> (*csync_vio_readdir_hook) (csync_vio_handle_t *dhhandle,
213 void *userdata);
214typedef 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. */
218typedef QByteArray (*csync_checksum_hook)(
219 const QByteArray &path, const QByteArray &otherChecksumHeader, 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 */
228int 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 */
237int 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 */
247void *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 */
259int 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 */
269csync_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 */
280int OCSYNC_EXPORT csync_set_auth_callback(CSYNC *ctx, csync_auth_callback cb);
281
282/* Used for special modes or debugging */
283CSYNC_STATUS OCSYNC_EXPORT csync_get_status(CSYNC *ctx);
284
285/* Used for special modes or debugging */
286int OCSYNC_EXPORT csync_set_status(CSYNC *ctx, int status);
287
288using 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 */
298int 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 */
308int 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 */
315void 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 */
322void 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 */
329int OCSYNC_EXPORT csync_abort_requested(CSYNC *ctx);
330
331time_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