1 /** 2 * @file mega/sync.h 3 * @brief Class for synchronizing local and remote trees 4 * 5 * (c) 2013-2014 by Mega Limited, Auckland, New Zealand 6 * 7 * This file is part of the MEGA SDK - Client Access Engine. 8 * 9 * Applications using the MEGA API must present a valid application key 10 * and comply with the the rules set forth in the Terms of Service. 11 * 12 * The MEGA SDK 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. 15 * 16 * @copyright Simplified (2-clause) BSD License. 17 * 18 * You should have received a copy of the license along with this 19 * program. 20 */ 21 22 #ifndef MEGA_SYNC_H 23 #define MEGA_SYNC_H 1 24 25 #ifdef ENABLE_SYNC 26 #include "megaclient.h" 27 28 namespace mega { 29 30 // Searching from the back, this function compares path1 and path2 character by character and 31 // returns the number of consecutive character matches (excluding separators) but only including whole node names. 32 // It's assumed that the paths are normalized (e.g. not contain ..) and separated with the given `localseparator`. 33 // `accumulated` is a buffer that is used to avoid constant reallocations. 34 int computeReversePathMatchScore(string& accumulated, const LocalPath& path1, const LocalPath& path2, const FileSystemAccess&); 35 36 // Recursively iterates through the filesystem tree starting at the sync root and assigns 37 // fs IDs to those local nodes that match the fingerprint retrieved from disk. 38 bool assignFilesystemIds(Sync& sync, MegaApp& app, FileSystemAccess& fsaccess, handlelocalnode_map& fsidnodes, 39 LocalPath& localdebris); 40 41 // A collection of sync configs backed by a database table 42 class MEGA_API SyncConfigBag 43 { 44 public: 45 SyncConfigBag(DbAccess& dbaccess, FileSystemAccess& fsaccess, PrnGen& rng, const std::string& id); 46 47 MEGA_DISABLE_COPY_MOVE(SyncConfigBag) 48 49 // Adds a new sync config or updates if exists already 50 void insert(const SyncConfig& syncConfig); 51 52 // Removes a sync config at the given local path 53 void remove(const std::string& localPath); 54 55 // Returns the sync config at the given local path 56 const SyncConfig* get(const std::string& localPath) const; 57 58 // Removes all sync configs 59 void clear(); 60 61 // Returns all current sync configs 62 std::vector<SyncConfig> all() const; 63 64 private: 65 std::unique_ptr<DbTable> mTable; // table for caching the sync configs 66 std::map<std::string, SyncConfig> mSyncConfigs; // map of local paths to sync configs 67 }; 68 69 class MEGA_API Sync 70 { 71 public: 72 73 // returns the sync config 74 const SyncConfig& getConfig() const; 75 76 // sets whether this sync is resumable (default is true) 77 void setResumable(bool isResumable); 78 79 void* appData = nullptr; 80 81 MegaClient* client = nullptr; 82 83 // sync-wide directory notification provider 84 std::unique_ptr<DirNotify> dirnotify; 85 86 // root of local filesystem tree, holding the sync's root folder. Never null except briefly in the destructor (to ensure efficient db usage) 87 unique_ptr<LocalNode> localroot; 88 89 FileSystemType mFilesystemType = FS_UNKNOWN; 90 91 // Path used to normalize sync locaroot name when using prefix /System/Volumes/Data needed by fsevents, due to notification paths 92 // are served with such prefix from macOS catalina + 93 #ifdef __APPLE__ 94 string mFsEventsPath; 95 #endif 96 // current state 97 syncstate_t state = SYNC_INITIALSCAN; 98 99 // are we conducting a full tree scan? (during initialization and if event notification failed) 100 bool fullscan = true; 101 102 // syncing to an inbound share? 103 bool inshare = false; 104 105 // deletion queue 106 set<uint32_t> deleteq; 107 108 // insertion/update queue 109 localnode_set insertq; 110 111 // adds an entry to the delete queue - removes it from insertq 112 void statecachedel(LocalNode*); 113 114 // adds an entry to the insert queue - removes it from deleteq 115 void statecacheadd(LocalNode*); 116 117 // recursively add children 118 void addstatecachechildren(uint32_t, idlocalnode_map*, LocalPath&, LocalNode*, int); 119 120 // Caches all synchronized LocalNode 121 void cachenodes(); 122 123 // change state, signal to application 124 void changestate(syncstate_t); 125 126 // skip duplicates and self-caused 127 bool checkValidNotification(int q, Notification& notification); 128 129 // process and remove one directory notification queue item from *notify 130 dstime procscanq(int); 131 132 // recursively look for vanished child nodes and delete them 133 void deletemissing(LocalNode*); 134 135 // scan specific path 136 LocalNode* checkpath(LocalNode*, LocalPath*, string* const, dstime*, bool wejustcreatedthisfolder, DirAccess* iteratingDir); 137 138 m_off_t localbytes = 0; 139 unsigned localnodes[2]{}; 140 141 // look up LocalNode relative to localroot 142 LocalNode* localnodebypath(LocalNode*, const LocalPath&, LocalNode** = NULL, string* = NULL); 143 144 // Assigns fs IDs to those local nodes that match the fingerprint retrieved from disk. 145 // The fs IDs of unmatched nodes are invalidated. 146 bool assignfsids(); 147 148 // scan items in specified path and add as children of the specified 149 // LocalNode 150 bool scan(LocalPath*, FileAccess*); 151 152 // own position in session sync list 153 sync_list::iterator sync_it{}; 154 155 // rescan sequence number (incremented when a full rescan or a new 156 // notification batch starts) 157 int scanseqno = 0; 158 159 // notified nodes originating from this sync bear this tag 160 int tag = 0; 161 162 // debris path component relative to the base path 163 string debris; 164 LocalPath localdebris; 165 166 // permanent lock on the debris/tmp folder 167 std::unique_ptr<FileAccess> tmpfa; 168 169 // state cache table 170 DbTable* statecachetable = nullptr; 171 172 // move file or folder to localdebris 173 bool movetolocaldebris(LocalPath& localpath); 174 175 // original filesystem fingerprint 176 fsfp_t fsfp = 0; 177 178 // does the filesystem have stable IDs? (FAT does not) 179 bool fsstableids = false; 180 181 // Error that causes a cancellation 182 error errorcode = API_OK; 183 184 // true if the sync hasn't loaded cached LocalNodes yet 185 bool initializing = true; 186 187 // true if the local synced folder is a network folder 188 bool isnetwork = false; 189 190 // values related to possible files being updated 191 m_off_t updatedfilesize = ~0; 192 m_time_t updatedfilets = 0; 193 m_time_t updatedfileinitialts = 0; 194 195 Sync(MegaClient*, SyncConfig, const char*, string*, Node*, bool, int, void*); 196 ~Sync(); 197 198 static const int SCANNING_DELAY_DS; 199 static const int EXTRA_SCANNING_DELAY_DS; 200 static const int FILE_UPDATE_DELAY_DS; 201 static const int FILE_UPDATE_MAX_DELAY_SECS; 202 static const dstime RECENT_VERSION_INTERVAL_SECS; 203 204 protected : 205 bool readstatecache(); 206 207 private: 208 std::string mLocalPath; 209 }; 210 } // namespace 211 212 #endif 213 #endif 214