1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 #ifndef SEAF_FILE_MGR_H 4 #define SEAF_FILE_MGR_H 5 6 #include <glib.h> 7 8 #include "seafile-object.h" 9 10 #include "obj-store.h" 11 12 #include "cdc/cdc.h" 13 #include "../common/seafile-crypt.h" 14 15 #define CURRENT_DIR_OBJ_VERSION 1 16 #define CURRENT_SEAFILE_OBJ_VERSION 1 17 18 typedef struct _SeafFSManager SeafFSManager; 19 typedef struct _SeafFSObject SeafFSObject; 20 typedef struct _Seafile Seafile; 21 typedef struct _SeafDir SeafDir; 22 typedef struct _SeafDirent SeafDirent; 23 24 typedef enum { 25 SEAF_METADATA_TYPE_INVALID, 26 SEAF_METADATA_TYPE_FILE, 27 SEAF_METADATA_TYPE_LINK, 28 SEAF_METADATA_TYPE_DIR, 29 } SeafMetadataType; 30 31 /* Common to seafile and seafdir objects. */ 32 struct _SeafFSObject { 33 int type; 34 }; 35 36 struct _Seafile { 37 SeafFSObject object; 38 int version; 39 char file_id[41]; 40 guint64 file_size; 41 guint32 n_blocks; 42 char **blk_sha1s; 43 int ref_count; 44 }; 45 46 typedef struct SearchResult { 47 char *path; 48 gint64 size; 49 gint64 mtime; 50 gboolean is_dir; 51 } SearchResult; 52 53 void 54 seafile_ref (Seafile *seafile); 55 56 void 57 seafile_unref (Seafile *seafile); 58 59 int 60 seafile_save (SeafFSManager *fs_mgr, 61 const char *repo_id, 62 int version, 63 Seafile *file); 64 65 #define SEAF_DIR_NAME_LEN 256 66 67 struct _SeafDirent { 68 int version; 69 guint32 mode; 70 char id[41]; 71 guint32 name_len; 72 char *name; 73 74 /* attributes for version > 0 */ 75 gint64 mtime; 76 char *modifier; /* for files only */ 77 gint64 size; /* for files only */ 78 }; 79 80 struct _SeafDir { 81 SeafFSObject object; 82 int version; 83 char dir_id[41]; 84 GList *entries; 85 86 /* data in on-disk format. */ 87 void *ondisk; 88 int ondisk_size; 89 }; 90 91 SeafDir * 92 seaf_dir_new (const char *id, GList *entries, int version); 93 94 void 95 seaf_dir_free (SeafDir *dir); 96 97 SeafDir * 98 seaf_dir_from_data (const char *dir_id, uint8_t *data, int len, 99 gboolean is_json); 100 101 void * 102 seaf_dir_to_data (SeafDir *dir, int *len); 103 104 int 105 seaf_dir_save (SeafFSManager *fs_mgr, 106 const char *repo_id, 107 int version, 108 SeafDir *dir); 109 110 SeafDirent * 111 seaf_dirent_new (int version, const char *sha1, int mode, const char *name, 112 gint64 mtime, const char *modifier, gint64 size); 113 114 void 115 seaf_dirent_free (SeafDirent *dent); 116 117 SeafDirent * 118 seaf_dirent_dup (SeafDirent *dent); 119 120 int 121 seaf_metadata_type_from_data (const char *obj_id, 122 uint8_t *data, int len, gboolean is_json); 123 124 /* Parse an fs object without knowing its type. */ 125 SeafFSObject * 126 seaf_fs_object_from_data (const char *obj_id, 127 uint8_t *data, int len, 128 gboolean is_json); 129 130 void 131 seaf_fs_object_free (SeafFSObject *obj); 132 133 typedef struct { 134 /* TODO: GHashTable may be inefficient when we have large number of IDs. */ 135 GHashTable *block_hash; 136 GPtrArray *block_ids; 137 uint32_t n_blocks; 138 uint32_t n_valid_blocks; 139 } BlockList; 140 141 BlockList * 142 block_list_new (); 143 144 void 145 block_list_free (BlockList *bl); 146 147 void 148 block_list_insert (BlockList *bl, const char *block_id); 149 150 /* Return a blocklist containing block ids which are in @bl1 but 151 * not in @bl2. 152 */ 153 BlockList * 154 block_list_difference (BlockList *bl1, BlockList *bl2); 155 156 struct _SeafileSession; 157 158 typedef struct _SeafFSManagerPriv SeafFSManagerPriv; 159 160 struct _SeafFSManager { 161 struct _SeafileSession *seaf; 162 163 struct SeafObjStore *obj_store; 164 165 SeafFSManagerPriv *priv; 166 }; 167 168 SeafFSManager * 169 seaf_fs_manager_new (struct _SeafileSession *seaf, 170 const char *seaf_dir); 171 172 int 173 seaf_fs_manager_init (SeafFSManager *mgr); 174 175 #ifndef SEAFILE_SERVER 176 177 int 178 seaf_fs_manager_checkout_file (SeafFSManager *mgr, 179 const char *repo_id, 180 int version, 181 const char *file_id, 182 const char *file_path, 183 guint32 mode, 184 guint64 mtime, 185 struct SeafileCrypt *crypt, 186 const char *in_repo_path, 187 const char *conflict_head_id, 188 gboolean force_conflict, 189 gboolean *conflicted, 190 const char *email); 191 192 #endif /* not SEAFILE_SERVER */ 193 194 /** 195 * Check in blocks and create seafile/symlink object. 196 * Returns sha1 id for the seafile/symlink object in @sha1 parameter. 197 */ 198 int 199 seaf_fs_manager_index_file_blocks (SeafFSManager *mgr, 200 const char *repo_id, 201 int version, 202 GList *paths, 203 GList *blockids, 204 unsigned char sha1[], 205 gint64 file_size); 206 207 int 208 seaf_fs_manager_index_raw_blocks (SeafFSManager *mgr, 209 const char *repo_id, 210 int version, 211 GList *paths, 212 GList *blockids); 213 214 int 215 seaf_fs_manager_index_existed_file_blocks (SeafFSManager *mgr, 216 const char *repo_id, 217 int version, 218 GList *blockids, 219 unsigned char sha1[], 220 gint64 file_size); 221 int 222 seaf_fs_manager_index_blocks (SeafFSManager *mgr, 223 const char *repo_id, 224 int version, 225 const char *file_path, 226 unsigned char sha1[], 227 gint64 *size, 228 SeafileCrypt *crypt, 229 gboolean write_data, 230 gboolean use_cdc, 231 gint64 *indexed); 232 233 Seafile * 234 seaf_fs_manager_get_seafile (SeafFSManager *mgr, 235 const char *repo_id, 236 int version, 237 const char *file_id); 238 239 SeafDir * 240 seaf_fs_manager_get_seafdir (SeafFSManager *mgr, 241 const char *repo_id, 242 int version, 243 const char *dir_id); 244 245 /* Make sure entries in the returned dir is sorted in descending order. 246 */ 247 SeafDir * 248 seaf_fs_manager_get_seafdir_sorted (SeafFSManager *mgr, 249 const char *repo_id, 250 int version, 251 const char *dir_id); 252 253 SeafDir * 254 seaf_fs_manager_get_seafdir_sorted_by_path (SeafFSManager *mgr, 255 const char *repo_id, 256 int version, 257 const char *root_id, 258 const char *path); 259 260 int 261 seaf_fs_manager_populate_blocklist (SeafFSManager *mgr, 262 const char *repo_id, 263 int version, 264 const char *root_id, 265 BlockList *bl); 266 267 /* 268 * For dir object, set *stop to TRUE to stop traversing the subtree. 269 */ 270 typedef gboolean (*TraverseFSTreeCallback) (SeafFSManager *mgr, 271 const char *repo_id, 272 int version, 273 const char *obj_id, 274 int type, 275 void *user_data, 276 gboolean *stop); 277 278 int 279 seaf_fs_manager_traverse_tree (SeafFSManager *mgr, 280 const char *repo_id, 281 int version, 282 const char *root_id, 283 TraverseFSTreeCallback callback, 284 void *user_data, 285 gboolean skip_errors); 286 287 typedef gboolean (*TraverseFSPathCallback) (SeafFSManager *mgr, 288 const char *path, 289 SeafDirent *dent, 290 void *user_data, 291 gboolean *stop); 292 293 int 294 seaf_fs_manager_traverse_path (SeafFSManager *mgr, 295 const char *repo_id, 296 int version, 297 const char *root_id, 298 const char *dir_path, 299 TraverseFSPathCallback callback, 300 void *user_data); 301 302 gboolean 303 seaf_fs_manager_object_exists (SeafFSManager *mgr, 304 const char *repo_id, 305 int version, 306 const char *id); 307 308 void 309 seaf_fs_manager_delete_object (SeafFSManager *mgr, 310 const char *repo_id, 311 int version, 312 const char *id); 313 314 gint64 315 seaf_fs_manager_get_file_size (SeafFSManager *mgr, 316 const char *repo_id, 317 int version, 318 const char *file_id); 319 320 gint64 321 seaf_fs_manager_get_fs_size (SeafFSManager *mgr, 322 const char *repo_id, 323 int version, 324 const char *root_id); 325 326 #ifndef SEAFILE_SERVER 327 int 328 seafile_write_chunk (const char *repo_id, 329 int version, 330 CDCDescriptor *chunk, 331 SeafileCrypt *crypt, 332 uint8_t *checksum, 333 gboolean write_data); 334 int 335 seafile_check_write_chunk (CDCDescriptor *chunk, 336 uint8_t *sha1, 337 gboolean write_data); 338 #endif /* SEAFILE_SERVER */ 339 340 uint32_t 341 calculate_chunk_size (uint64_t total_size); 342 343 int 344 seaf_fs_manager_count_fs_files (SeafFSManager *mgr, 345 const char *repo_id, 346 int version, 347 const char *root_id); 348 349 SeafDir * 350 seaf_fs_manager_get_seafdir_by_path(SeafFSManager *mgr, 351 const char *repo_id, 352 int version, 353 const char *root_id, 354 const char *path, 355 GError **error); 356 char * 357 seaf_fs_manager_get_seafile_id_by_path (SeafFSManager *mgr, 358 const char *repo_id, 359 int version, 360 const char *root_id, 361 const char *path, 362 GError **error); 363 364 char * 365 seaf_fs_manager_path_to_obj_id (SeafFSManager *mgr, 366 const char *repo_id, 367 int version, 368 const char *root_id, 369 const char *path, 370 guint32 *mode, 371 GError **error); 372 373 char * 374 seaf_fs_manager_get_seafdir_id_by_path (SeafFSManager *mgr, 375 const char *repo_id, 376 int version, 377 const char *root_id, 378 const char *path, 379 GError **error); 380 381 SeafDirent * 382 seaf_fs_manager_get_dirent_by_path (SeafFSManager *mgr, 383 const char *repo_id, 384 int version, 385 const char *root_id, 386 const char *path, 387 GError **error); 388 389 /* Check object integrity. */ 390 391 gboolean 392 seaf_fs_manager_verify_seafdir (SeafFSManager *mgr, 393 const char *repo_id, 394 int version, 395 const char *dir_id, 396 gboolean verify_id, 397 gboolean *io_error); 398 399 gboolean 400 seaf_fs_manager_verify_seafile (SeafFSManager *mgr, 401 const char *repo_id, 402 int version, 403 const char *file_id, 404 gboolean verify_id, 405 gboolean *io_error); 406 407 gboolean 408 seaf_fs_manager_verify_object (SeafFSManager *mgr, 409 const char *repo_id, 410 int version, 411 const char *obj_id, 412 gboolean verify_id, 413 gboolean *io_error); 414 415 int 416 dir_version_from_repo_version (int repo_version); 417 418 int 419 seafile_version_from_repo_version (int repo_version); 420 421 struct _CDCFileDescriptor; 422 void 423 seaf_fs_manager_calculate_seafile_id_json (int repo_version, 424 struct _CDCFileDescriptor *cdc, 425 guint8 *file_id_sha1); 426 427 int 428 seaf_fs_manager_remove_store (SeafFSManager *mgr, 429 const char *store_id); 430 431 GObject * 432 seaf_fs_manager_get_file_count_info_by_path (SeafFSManager *mgr, 433 const char *repo_id, 434 int version, 435 const char *root_id, 436 const char *path, 437 GError **error); 438 439 GList * 440 seaf_fs_manager_search_files (SeafFSManager *mgr, 441 const char *repo_id, 442 const char *str); 443 444 #endif 445