forked from meganz/sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnode.h
More file actions
412 lines (297 loc) · 10.6 KB
/
node.h
File metadata and controls
412 lines (297 loc) · 10.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
/**
* @file mega/node.h
* @brief Classes for accessing local and remote nodes
*
* (c) 2013-2014 by Mega Limited, Auckland, New Zealand
*
* This file is part of the MEGA SDK - Client Access Engine.
*
* Applications using the MEGA API must present a valid application key
* and comply with the the rules set forth in the Terms of Service.
*
* The MEGA SDK is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* @copyright Simplified (2-clause) BSD License.
*
* You should have received a copy of the license along with this
* program.
*/
#ifndef MEGA_NODE_H
#define MEGA_NODE_H 1
#include "filefingerprint.h"
#include "file.h"
#include "attrmap.h"
namespace mega {
struct LocalPathPtrCmp
{
bool operator()(const LocalPath* a, const LocalPath* b) const
{
return *a < *b;
}
};
typedef map<const LocalPath*, LocalNode*, LocalPathPtrCmp> localnode_map;
typedef map<const string*, Node*, StringCmp> remotenode_map;
struct MEGA_API NodeCore
{
// node's own handle
handle nodehandle = UNDEF;
// parent node handle (in a Node context, temporary placeholder until parent is set)
handle parenthandle = UNDEF;
// node type
nodetype_t type = TYPE_UNKNOWN;
// node attributes
std::unique_ptr<string> attrstring;
};
// new node for putnodes()
struct MEGA_API NewNode : public NodeCore
{
static const int OLDUPLOADTOKENLEN = 27;
static const int UPLOADTOKENLEN = 36;
string nodekey;
newnodesource_t source = NEW_NODE;
handle ovhandle = UNDEF;
handle uploadhandle = UNDEF;
byte uploadtoken[UPLOADTOKENLEN]{};
handle syncid = UNDEF;
#ifdef ENABLE_SYNC
crossref_ptr<LocalNode, NewNode> localnode; // non-owning
#endif
std::unique_ptr<string> fileattributes;
bool added = false;
};
struct MEGA_API PublicLink
{
handle ph;
m_time_t cts;
m_time_t ets;
bool takendown;
PublicLink(handle ph, m_time_t cts, m_time_t ets, bool takendown);
PublicLink(PublicLink *plink);
bool isExpired();
};
// Container storing FileFingerprint* (Node* in practice) ordered by fingerprint.
struct Fingerprints
{
// maps FileFingerprints to node
using fingerprint_set = std::multiset<FileFingerprint*, FileFingerprintCmp>;
using iterator = fingerprint_set::iterator;
void newnode(Node* n);
void add(Node* n);
void remove(Node* n);
void clear();
m_off_t getSumSizes();
Node* nodebyfingerprint(FileFingerprint* fingerprint);
node_vector *nodesbyfingerprint(FileFingerprint* fingerprint);
private:
fingerprint_set mFingerprints;
m_off_t mSumSizes = 0;
};
// filesystem node
struct MEGA_API Node : public NodeCore, FileFingerprint
{
MegaClient* client = nullptr;
// supplies the nodekey (which is private to ensure we track changes to it)
const string& nodekey() const;
// Also returns the key but does not assert that the key has been applied. Only use it where we don't need the node to be readable.
const string& nodekeyUnchecked() const;
// check if the key is present and is the correct size for this node
bool keyApplied() const;
// change parent node association
bool setparent(Node*);
// follow the parent links all the way to the top
Node* firstancestor();
// copy JSON-delimited string
static void copystring(string*, const char*);
// try to resolve node key string
bool applykey();
// set up nodekey in a static SymmCipher
SymmCipher* nodecipher();
// decrypt attribute string and set fileattrs
void setattr();
// display name (UTF-8)
const char* displayname() const;
// display path from its root in the cloud (UTF-8)
string displaypath() const;
// node attributes
AttrMap attrs;
// owner
handle owner = mega::UNDEF;
// actual time this node was created (cannot be set by user)
m_time_t ctime = 0;
// file attributes
string fileattrstring;
// check presence of file attribute
int hasfileattribute(fatype) const;
static int hasfileattribute(const string *fileattrstring, fatype);
// decrypt node attribute string
static byte* decryptattr(SymmCipher*, const char*, size_t);
// parse node attributes from an incoming buffer, this function must be called after call decryptattr
static void parseattr(byte*, AttrMap&, m_off_t, m_time_t&, string&, string&, FileFingerprint&);
// inbound share
Share* inshare = nullptr;
// outbound shares by user
share_map* outshares = nullptr;
// outbound pending shares
share_map* pendingshares = nullptr;
// incoming/outgoing share key
SymmCipher* sharekey = nullptr;
// app-private pointer
void* appdata = nullptr;
bool foreignkey = false;
struct
{
bool removed : 1;
bool attrs : 1;
bool owner : 1;
bool ctime : 1;
bool fileattrstring : 1;
bool inshare : 1;
bool outshares : 1;
bool pendingshares : 1;
bool parent : 1;
bool publiclink : 1;
bool newnode : 1;
} changed;
void setkey(const byte* = NULL);
void setkeyfromjson(const char*);
void setfingerprint();
void faspec(string*);
NodeCounter subnodeCounts() const;
// parent
Node* parent = nullptr;
// children
node_list children;
// own position in parent's children
node_list::iterator child_it;
// own position in fingerprint set (only valid for file nodes)
Fingerprints::iterator fingerprint_it;
#ifdef ENABLE_SYNC
// related synced item or NULL
LocalNode* localnode = nullptr;
// active sync get
struct SyncFileGet* syncget = nullptr;
// state of removal to //bin / SyncDebris
syncdel_t syncdeleted = SYNCDEL_NONE;
// location in the todebris node_set
node_set::iterator todebris_it;
// location in the tounlink node_set
// FIXME: merge todebris / tounlink
node_set::iterator tounlink_it;
#endif
// source tag
int tag = 0;
// check if node is below this node
bool isbelow(Node*) const;
// handle of public link for the node
PublicLink* plink = nullptr;
void setpubliclink(handle, m_time_t, m_time_t, bool);
bool serialize(string*) override;
static Node* unserialize(MegaClient*, const string*, node_vector*);
Node(MegaClient*, vector<Node*>*, handle, handle, nodetype_t, m_off_t, handle, const char*, m_time_t);
~Node();
private:
// full folder/file key, symmetrically or asymmetrically encrypted
// node crypto keys (raw or cooked -
// cooked if size() == FOLDERNODEKEYLENGTH or FILEFOLDERNODEKEYLENGTH)
string nodekeydata;
};
inline const string& Node::nodekey() const
{
assert(keyApplied() || type == ROOTNODE || type == INCOMINGNODE || type == RUBBISHNODE);
return nodekeydata;
}
inline const string& Node::nodekeyUnchecked() const
{
return nodekeydata;
}
inline bool Node::keyApplied() const
{
return nodekeydata.size() == size_t((type == FILENODE) ? FILENODEKEYLENGTH : FOLDERNODEKEYLENGTH);
}
#ifdef ENABLE_SYNC
struct MEGA_API LocalNode : public File
{
class Sync* sync = nullptr;
// parent linkage
LocalNode* parent = nullptr;
// stored to rebuild tree after serialization => this must not be a pointer to parent->dbid
int32_t parent_dbid = 0;
// whether this node can be synced to the remote tree
bool mSyncable = true;
// whether this node knew its shortname (otherwise it was loaded from an old db)
bool slocalname_in_db = false;
// children by name
localnode_map children;
// for botched filesystems with legacy secondary ("short") names
// Filesystem notifications could arrive with long or short names, and we need to recognise which LocalNode corresponds.
std::unique_ptr<LocalPath> slocalname; // null means either the entry has no shortname or it's the same as the (normal) longname
localnode_map schildren;
// local filesystem node ID (inode...) for rename/move detection
handle fsid = mega::UNDEF;
handlelocalnode_map::iterator fsid_it{};
// related cloud node, if any
Node* node = nullptr;
// related pending node creation or NULL
crossref_ptr<NewNode, LocalNode> newnode;
// FILENODE or FOLDERNODE
nodetype_t type = TYPE_UNKNOWN;
// detection of deleted filesystem records
int scanseqno = 0;
// number of iterations since last seen
int notseen = 0;
// global sync reference
handle syncid = mega::UNDEF;
struct
{
// was actively deleted
bool deleted : 1;
// has been created remotely
bool created : 1;
// an issue has been reported
bool reported : 1;
// checked for missing attributes
bool checked : 1;
};
// current subtree sync state: current and displayed
treestate_t ts = TREESTATE_NONE;
treestate_t dts = TREESTATE_NONE;
// update sync state all the way to the root node
void treestate(treestate_t = TREESTATE_NONE);
// check the current state (only useful for folders)
treestate_t checkstate();
// timer to delay upload start
dstime nagleds = 0;
void bumpnagleds();
// if delage > 0, own iterator inside MegaClient::localsyncnotseen
localnode_set::iterator notseen_it{};
// build full local path to this node
void getlocalpath(LocalPath&, bool sdisable = false, const std::string* localseparator = nullptr) const;
LocalPath getLocalPath(bool sdisable = false) const;
string localnodedisplaypath(FileSystemAccess& fsa) const;
// return child node by name
LocalNode* childbyname(LocalPath*);
#ifdef USE_INOTIFY
// node-specific DirNotify tag
handle dirnotifytag = mega::UNDEF;
#endif
void prepare() override;
void completed(Transfer*, LocalNode*) override;
void setnode(Node*);
void setnotseen(int);
// set fsid - assume that an existing assignment of the same fsid is no longer current and revoke.
// fsidnodes is a map from fsid to LocalNode, keeping track of all fs ids.
void setfsid(handle newfsid, handlelocalnode_map& fsidnodes);
void setnameparent(LocalNode*, LocalPath* newlocalpath, std::unique_ptr<LocalPath>);
LocalNode();
void init(Sync*, nodetype_t, LocalNode*, LocalPath&, std::unique_ptr<LocalPath>);
bool serialize(string*) override;
static LocalNode* unserialize( Sync* sync, const string* sData );
~LocalNode();
};
template <> inline NewNode*& crossref_other_ptr_ref<LocalNode, NewNode>(LocalNode* p) { return p->newnode.ptr; }
template <> inline LocalNode*& crossref_other_ptr_ref<NewNode, LocalNode>(NewNode* p) { return p->localnode.ptr; }
#endif
} // namespace
#endif