1 /**
2 * @file mega/types.h
3 * @brief Mega SDK types and includes
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_TYPES_H
23 #define MEGA_TYPES_H 1
24
25 #ifdef _MSC_VER
26 #if MEGA_LINKED_AS_SHARED_LIBRARY
27 #define MEGA_API __declspec(dllimport)
28 #elif MEGA_CREATE_SHARED_LIBRARY
29 #define MEGA_API __declspec(dllexport)
30 #endif
31 #endif
32
33 #ifndef MEGA_API
34 #define MEGA_API
35 #endif
36
37 // it needs to be reviewed that serialization/unserialization is not relying on this
38 typedef char __static_check_01__[sizeof(bool) == sizeof(char) ? 1 : -1];
39 // if your build fails here, please contact MEGA developers
40
41 // platform-specific includes and defines
42 #ifdef _WIN32
43 #include "mega/win32/megasys.h"
44 #else
45 #include "mega/posix/megasys.h"
46 #endif
47
48 #ifdef USE_CRYPTOPP
49 #include <cryptopp/config.h> // so we can test CRYPTO_VERSION below
50 #endif
51
52 // signed 64-bit generic offset
53 typedef int64_t m_off_t;
54
55 // opaque filesystem fingerprint
56 typedef uint64_t fsfp_t;
57
58 namespace mega {
59 // within ::mega namespace, byte is unsigned char (avoids ambiguity when std::byte from c++17 and perhaps other defined ::byte are available)
60 #if defined(USE_CRYPTOPP) && (CRYPTOPP_VERSION >= 600) && ((__cplusplus >= 201103L) || (__RPCNDR_H_VERSION__ == 500))
61 using byte = CryptoPP::byte;
62 #elif __RPCNDR_H_VERSION__ != 500
63 typedef unsigned char byte;
64 #endif
65 }
66
67 #ifdef USE_CRYPTOPP
68 #include "mega/crypto/cryptopp.h"
69 #else
70 #include "megacrypto.h"
71 #endif
72
73 #include "mega/crypto/sodium.h"
74
75 #include <memory>
76 #include <string>
77 #include <chrono>
78
79 namespace mega {
80
81 // import these select types into the namespace directly, to avoid adding std::byte from c++17
82 using std::string;
83 using std::map;
84 using std::set;
85 using std::list;
86 using std::vector;
87 using std::pair;
88 using std::multimap;
89 using std::deque;
90 using std::multiset;
91 using std::queue;
92 using std::streambuf;
93 using std::tuple;
94 using std::ostringstream;
95 using std::unique_ptr;
96
97 // forward declaration
98 struct AttrMap;
99 class BackoffTimer;
100 class Command;
101 class CommandPubKeyRequest;
102 struct DirectRead;
103 struct DirectReadNode;
104 struct DirectReadSlot;
105 struct FileAccess;
106 struct FileAttributeFetch;
107 struct FileAttributeFetchChannel;
108 struct FileFingerprint;
109 struct FileFingerprintCmp;
110 struct HttpReq;
111 struct GenericHttpReq;
112 struct HttpReqCommandPutFA;
113 struct LocalNode;
114 class MegaClient;
115 struct NewNode;
116 struct Node;
117 struct NodeCore;
118 class PubKeyAction;
119 class Request;
120 struct Transfer;
121 class TreeProc;
122 class LocalTreeProc;
123 struct User;
124 struct Waiter;
125 struct Proxy;
126 struct PendingContactRequest;
127 class TransferList;
128 struct Achievement;
129 namespace UserAlert
130 {
131 struct Base;
132 }
133 class AuthRing;
134
135 #define EOO 0
136
137 // Our own version of time_t which we can be sure is 64 bit.
138 // Utils.h has functions m_time() and so on corresponding to time() which help us to use this type and avoid arithmetic overflow when working with time_t on systems where it's 32-bit
139 typedef int64_t m_time_t;
140
141 // monotonously increasing time in deciseconds
142 typedef uint32_t dstime;
143
144 #define NEVER (~(dstime)0)
145 #define EVER(ds) ((ds+1))
146
147 #define STRINGIFY(x) # x
148 #define TOSTRING(x) STRINGIFY(x)
149
150 // HttpReq states
151 typedef enum { REQ_READY, REQ_PREPARED, REQ_ENCRYPTING, REQ_DECRYPTING, REQ_DECRYPTED, REQ_INFLIGHT, REQ_SUCCESS, REQ_FAILURE, REQ_DONE, REQ_ASYNCIO } reqstatus_t;
152
153 typedef enum { USER_HANDLE, NODE_HANDLE } targettype_t;
154
155 typedef enum { METHOD_POST, METHOD_GET, METHOD_NONE} httpmethod_t;
156
157 typedef enum { REQ_BINARY, REQ_JSON } contenttype_t;
158
159 // new node source types
160 typedef enum { NEW_NODE, NEW_PUBLIC, NEW_UPLOAD } newnodesource_t;
161
162 // file chunk MAC
163 struct ChunkMAC
164 {
ChunkMACChunkMAC165 ChunkMAC() : offset(0), finished(false) { }
166
167 byte mac[SymmCipher::BLOCKSIZE];
168 unsigned int offset;
169 bool finished;
170 };
171
172 class chunkmac_map;
173
174 /**
175 * @brief Declaration of API error codes.
176 */
177 typedef enum ErrorCodes
178 {
179 API_OK = 0, ///< Everything OK.
180 API_EINTERNAL = -1, ///< Internal error.
181 API_EARGS = -2, ///< Bad arguments.
182 API_EAGAIN = -3, ///< Request failed, retry with exponential backoff.
183 DAEMON_EFAILED = -4, ///< If returned from the daemon: EFAILED
184 API_ERATELIMIT = -4, ///< If returned from the API: Too many requests, slow down.
185 API_EFAILED = -5, ///< Request failed permanently. This one is only produced by the API, only per command (not batch level)
186 API_ETOOMANY = -6, ///< Too many requests for this resource.
187 API_ERANGE = -7, ///< Resource access out of range.
188 API_EEXPIRED = -8, ///< Resource expired.
189 API_ENOENT = -9, ///< Resource does not exist.
190 API_ECIRCULAR = -10, ///< Circular linkage.
191 API_EACCESS = -11, ///< Access denied.
192 API_EEXIST = -12, ///< Resource already exists.
193 API_EINCOMPLETE = -13, ///< Request incomplete.
194 API_EKEY = -14, ///< Cryptographic error.
195 API_ESID = -15, ///< Bad session ID.
196 API_EBLOCKED = -16, ///< Resource administratively blocked.
197 API_EOVERQUOTA = -17, ///< Quota exceeded.
198 API_ETEMPUNAVAIL = -18, ///< Resource temporarily not available.
199 API_ETOOMANYCONNECTIONS = -19, ///< Too many connections on this resource.
200 API_EWRITE = -20, ///< File could not be written to (or failed post-write integrity check)
201 API_EREAD = -21, ///< File could not be read from (or changed unexpectedly during reading)
202 API_EAPPKEY = -22, ///< Invalid or missing application key.
203 API_ESSL = -23, ///< SSL verification failed
204 API_EGOINGOVERQUOTA = -24, ///< Not enough quota
205 API_EMFAREQUIRED = -26, ///< Multi-factor authentication required
206 API_EMASTERONLY = -27, ///< Access denied for sub-users (only for business accounts)
207 API_EBUSINESSPASTDUE = -28, ///< Business account expired
208 API_EPAYWALL = -29, ///< Over Disk Quota Paywall
209 } error;
210
211 class Error
212 {
213 public:
214 typedef enum
215 {
216 USER_ETD_UNKNOWN = -1,
217 USER_ETD_SUSPENSION = 7, // represents an ETD/ToS 'severe' suspension level
218 } UserErrorCode;
219
220 typedef enum
221 {
222 LINK_UNKNOWN = -1,
223 LINK_UNDELETED = 0, // Link is undeleted
224 LINK_DELETED_DOWN = 1, // Link is deleted or down
225 LINK_DOWN_ETD = 2, // Link is down due to an ETD specifically
226 } LinkErrorCode;
227
228 Error(error err = API_EINTERNAL)
mError(err)229 : mError(err)
230 { }
231
setErrorCode(error err)232 void setErrorCode(error err)
233 {
234 mError = err;
235 }
236
setUserStatus(int64_t u)237 void setUserStatus(int64_t u) { mUserStatus = u; }
setLinkStatus(int64_t l)238 void setLinkStatus(int64_t l) { mLinkStatus = l; }
hasExtraInfo()239 bool hasExtraInfo() const { return mUserStatus != USER_ETD_UNKNOWN || mLinkStatus != LINK_UNKNOWN; }
getUserStatus()240 int64_t getUserStatus() const { return mUserStatus; }
getLinkStatus()241 int64_t getLinkStatus() const { return mLinkStatus; }
error()242 operator error() const { return mError; }
243
244 private:
245 error mError = API_EINTERNAL;
246 int64_t mUserStatus = USER_ETD_UNKNOWN;
247 int64_t mLinkStatus = LINK_UNKNOWN;
248 };
249
250 // returned by loggedin()
251 typedef enum { NOTLOGGEDIN, EPHEMERALACCOUNT, CONFIRMEDACCOUNT, FULLACCOUNT } sessiontype_t;
252
253 // node/user handles are 8-11 base64 characters, case sensitive, and thus fit
254 // in a 64-bit int
255 typedef uint64_t handle;
256
257 // (can use unordered_set if available)
258 typedef set<handle> handle_set;
259
260 // file attribute type
261 typedef uint16_t fatype;
262
263 // list of files
264 typedef list<struct File*> file_list;
265
266 // node types:
267 // FILE - regular file nodes
268 // FOLDER - regular folder nodes
269 // ROOT - the cloud drive root node
270 // INCOMING - inbox
271 // RUBBISH - rubbish bin
272 typedef enum { TYPE_UNKNOWN = -1, FILENODE = 0, FOLDERNODE, ROOTNODE, INCOMINGNODE, RUBBISHNODE } nodetype_t;
273
274 // node type key lengths
275 const int FILENODEKEYLENGTH = 32;
276 const int FOLDERNODEKEYLENGTH = 16;
277
278 typedef list<class Sync*> sync_list;
279
280 // persistent resource cache storage
281 class Cacheable
282 {
283 public:
284 virtual ~Cacheable() = default;
285
286 virtual bool serialize(string*) = 0;
287
288 uint32_t dbid = 0;
289 bool notified = false;
290 };
291
292 // numeric representation of string (up to 8 chars)
293 typedef uint64_t nameid;
294
295 // access levels:
296 // RDONLY - cannot add, rename or delete
297 // RDWR - cannot rename or delete
298 // FULL - all operations that do not require ownership permitted
299 // OWNER - node is in caller's ROOT, INCOMING or RUBBISH trees
300 typedef enum { ACCESS_UNKNOWN = -1, RDONLY = 0, RDWR, FULL, OWNER, OWNERPRELOGIN } accesslevel_t;
301
302 // operations for outgoing pending contacts
303 typedef enum { OPCA_ADD = 0, OPCA_DELETE, OPCA_REMIND} opcactions_t;
304 // operations for incoming pending contacts
305 typedef enum { IPCA_ACCEPT = 0, IPCA_DENY, IPCA_IGNORE} ipcactions_t;
306
307
308 typedef vector<struct Node*> node_vector;
309
310 // contact visibility:
311 // HIDDEN - not shown
312 // VISIBLE - shown
313 typedef enum { VISIBILITY_UNKNOWN = -1, HIDDEN = 0, VISIBLE = 1, INACTIVE = 2, BLOCKED = 3 } visibility_t;
314
315 typedef enum { PUTNODES_APP, PUTNODES_SYNC, PUTNODES_SYNCDEBRIS } putsource_t;
316
317 // maps handle-index pairs to file attribute handle
318 typedef map<pair<handle, fatype>, pair<handle, int> > fa_map;
319
320 typedef enum { SYNC_FAILED = -2, SYNC_CANCELED = -1, SYNC_INITIALSCAN = 0, SYNC_ACTIVE } syncstate_t;
321
322 typedef enum { SYNCDEL_NONE, SYNCDEL_DELETED, SYNCDEL_INFLIGHT, SYNCDEL_BIN,
323 SYNCDEL_DEBRIS, SYNCDEL_DEBRISDAY, SYNCDEL_FAILED } syncdel_t;
324
325 typedef vector<LocalNode*> localnode_vector;
326
327 typedef map<handle, LocalNode*> handlelocalnode_map;
328
329 typedef set<LocalNode*> localnode_set;
330
331 typedef multimap<int32_t, LocalNode*> idlocalnode_map;
332
333 typedef set<Node*> node_set;
334
335 // enumerates a node's children
336 // FIXME: switch to forward_list once C++11 becomes more widely available
337 typedef list<Node*> node_list;
338
339 // undefined node handle
340 const handle UNDEF = ~(handle)0;
341
342 #define ISUNDEF(h) (!((h) + 1))
343
344 typedef list<struct TransferSlot*> transferslot_list;
345
346 // FIXME: use forward_list instad (C++11)
347 typedef list<HttpReqCommandPutFA*> putfa_list;
348
349 // map a FileFingerprint to the transfer for that FileFingerprint
350 typedef map<FileFingerprint*, Transfer*, FileFingerprintCmp> transfer_map;
351
352 template <class T, class E>
353 class deque_with_lazy_bulk_erase
354 {
355 // This is a wrapper class for deque. Erasing an element from the middle of a deque is not cheap since all the subsequent elements need to be shuffled back.
356 // This wrapper intercepts the erase() calls for single items, and instead marks each one as 'erased'.
357 // The supplied template class E contains the normal deque entry T, plus a flag or similar to mark an entry erased.
358 // Any other operation on the deque performs all the gathered erases in a single std::remove_if for efficiency.
359 // This makes an enormous difference when cancelling 100k transfers in MEGAsync's transfers window for example.
360 deque<E> mDeque;
361 bool mErasing = false;
362
363 public:
364
365 typedef typename deque<E>::iterator iterator;
366
erase(iterator i)367 void erase(iterator i)
368 {
369 assert(i != mDeque.end());
370 i->erase();
371 mErasing = true;
372 }
373
applyErase()374 void applyErase()
375 {
376 if (mErasing)
377 {
378 auto newEnd = std::remove_if(mDeque.begin(), mDeque.end(), [](const E& e) { return e.isErased(); } );
379 mDeque.erase(newEnd, mDeque.end());
380 mErasing = false;
381 }
382 }
383
size()384 size_t size() { applyErase(); return mDeque.size(); }
empty()385 size_t empty() { applyErase(); return mDeque.empty(); }
clear()386 void clear() { mDeque.clear(); }
387 iterator begin(bool canHandleErasedElements = false) { if (!canHandleErasedElements) applyErase(); return mDeque.begin(); }
388 iterator end(bool canHandleErasedElements = false) { if (!canHandleErasedElements) applyErase(); return mDeque.end(); }
push_front(T t)389 void push_front(T t) { applyErase(); mDeque.push_front(E(t)); }
push_back(T t)390 void push_back(T t) { applyErase(); mDeque.push_back(E(t)); }
insert(iterator i,T t)391 void insert(iterator i, T t) { applyErase(); mDeque.insert(i, E(t)); }
392 T& operator[](size_t n) { applyErase(); return mDeque[n]; }
393
394 };
395
396 // map a request tag with pending dbids of transfers and files
397 typedef map<int, vector<uint32_t> > pendingdbid_map;
398
399 // map a request tag with a pending dns request
400 typedef map<int, GenericHttpReq*> pendinghttp_map;
401
402 // map an upload handle to the corresponding transer
403 typedef map<handle, Transfer*> handletransfer_map;
404
405 // maps node handles to Node pointers
406 typedef map<handle, Node*> node_map;
407
408 struct NodeCounter
409 {
410 m_off_t storage = 0;
411 m_off_t versionStorage = 0;
412 size_t files = 0;
413 size_t folders = 0;
414 size_t versions = 0;
415 void operator += (const NodeCounter&);
416 void operator -= (const NodeCounter&);
417 };
418
419 typedef std::map<handle, NodeCounter> NodeCounterMap;
420
421 // maps node handles to Share pointers
422 typedef map<handle, struct Share*> share_map;
423
424 // maps node handles NewShare pointers
425 typedef list<struct NewShare*> newshare_list;
426
427 // generic handle vector
428 typedef vector<handle> handle_vector;
429
430 // pairs of node handles
431 typedef set<pair<handle, handle> > handlepair_set;
432
433 // node and user vectors
434 typedef vector<struct User*> user_vector;
435 typedef vector<UserAlert::Base*> useralert_vector;
436 typedef vector<struct PendingContactRequest*> pcr_vector;
437
438 // actual user data (indexed by userid)
439 typedef map<int, User> user_map;
440
441 // maps user handles to userids
442 typedef map<handle, int> uh_map;
443
444 // maps lowercase user e-mail addresses to userids
445 typedef map<string, int> um_map;
446
447 // file attribute fetch map
448 typedef map<handle, FileAttributeFetch*> faf_map;
449
450 // file attribute fetch channel map
451 typedef map<int, FileAttributeFetchChannel*> fafc_map;
452
453 // transfer type
454 typedef enum { GET = 0, PUT, API, NONE } direction_t;
455 typedef enum { LARGEFILE = 0, SMALLFILE } filesizetype_t;
456
457 struct StringCmp
458 {
operatorStringCmp459 bool operator()(const string* a, const string* b) const
460 {
461 return *a < *b;
462 }
463 };
464
465 typedef map<handle, DirectReadNode*> handledrn_map;
466 typedef multimap<dstime, DirectReadNode*> dsdrn_map;
467 typedef list<DirectRead*> dr_list;
468 typedef list<DirectReadSlot*> drs_list;
469
470 typedef enum { TREESTATE_NONE = 0, TREESTATE_SYNCED, TREESTATE_PENDING, TREESTATE_SYNCING } treestate_t;
471
472 typedef enum { TRANSFERSTATE_NONE = 0, TRANSFERSTATE_QUEUED, TRANSFERSTATE_ACTIVE, TRANSFERSTATE_PAUSED,
473 TRANSFERSTATE_RETRYING, TRANSFERSTATE_COMPLETING, TRANSFERSTATE_COMPLETED,
474 TRANSFERSTATE_CANCELLED, TRANSFERSTATE_FAILED } transferstate_t;
475
476
477 // FIXME: use forward_list instad (C++11)
478 typedef list<HttpReqCommandPutFA*> putfa_list;
479
480 typedef map<handle, PendingContactRequest*> handlepcr_map;
481
482 // Type-Value (for user attributes)
483 typedef vector<string> string_vector;
484 typedef map<string, string> string_map;
485 typedef string_map TLV_map;
486
487
488 // user attribute types
489 typedef enum {
490 ATTR_UNKNOWN = -1,
491 ATTR_AVATAR = 0, // public - char array - non-versioned
492 ATTR_FIRSTNAME = 1, // public - char array - non-versioned
493 ATTR_LASTNAME = 2, // public - char array - non-versioned
494 ATTR_AUTHRING = 3, // private - byte array
495 ATTR_LAST_INT = 4, // private - byte array
496 ATTR_ED25519_PUBK = 5, // public - byte array - versioned
497 ATTR_CU25519_PUBK = 6, // public - byte array - versioned
498 ATTR_KEYRING = 7, // private - byte array - versioned
499 ATTR_SIG_RSA_PUBK = 8, // public - byte array - versioned
500 ATTR_SIG_CU255_PUBK = 9, // public - byte array - versioned
501 ATTR_COUNTRY = 10, // public - char array - non-versioned
502 ATTR_BIRTHDAY = 11, // public - char array - non-versioned
503 ATTR_BIRTHMONTH = 12, // public - char array - non-versioned
504 ATTR_BIRTHYEAR = 13, // public - char array - non-versioned
505 ATTR_LANGUAGE = 14, // private, non-encrypted - char array in B64 - non-versioned
506 ATTR_PWD_REMINDER = 15, // private, non-encrypted - char array in B64 - non-versioned
507 ATTR_DISABLE_VERSIONS = 16, // private, non-encrypted - char array in B64 - non-versioned
508 ATTR_CONTACT_LINK_VERIFICATION = 17, // private, non-encrypted - char array in B64 - versioned
509 ATTR_RICH_PREVIEWS = 18, // private - byte array
510 ATTR_RUBBISH_TIME = 19, // private, non-encrypted - char array in B64 - non-versioned
511 ATTR_LAST_PSA = 20, // private - char array
512 ATTR_STORAGE_STATE = 21, // private - non-encrypted - char array in B64 - non-versioned
513 ATTR_GEOLOCATION = 22, // private - byte array - non-versioned
514 ATTR_CAMERA_UPLOADS_FOLDER = 23, // private - byte array - non-versioned
515 ATTR_MY_CHAT_FILES_FOLDER = 24, // private - byte array - non-versioned
516 ATTR_PUSH_SETTINGS = 25, // private - non-encripted - char array in B64 - non-versioned
517 ATTR_UNSHAREABLE_KEY = 26, // private - char array - versioned
518 ATTR_ALIAS = 27, // private - byte array - versioned
519 ATTR_AUTHRSA = 28, // private - byte array
520 ATTR_AUTHCU255 = 29, // private - byte array
521 ATTR_DEVICE_NAMES = 30, // private - byte array - versioned
522
523 } attr_t;
524 typedef map<attr_t, string> userattr_map;
525
526 typedef enum {
527
528 AES_CCM_12_16 = 0x00,
529 AES_CCM_10_16 = 0x01,
530 AES_CCM_10_08 = 0x02,
531 AES_GCM_12_16_BROKEN = 0x03, // Same as 0x00 (due to a legacy bug)
532 AES_GCM_10_08_BROKEN = 0x04, // Same as 0x02 (due to a legacy bug)
533 AES_GCM_12_16 = 0x10,
534 AES_GCM_10_08 = 0x11
535
536 } encryptionsetting_t;
537
538 typedef enum { AES_MODE_UNKNOWN, AES_MODE_CCM, AES_MODE_GCM } encryptionmode_t;
539
540 #ifdef ENABLE_CHAT
541 typedef enum { PRIV_UNKNOWN = -2, PRIV_RM = -1, PRIV_RO = 0, PRIV_STANDARD = 2, PRIV_MODERATOR = 3 } privilege_t;
542 typedef pair<handle, privilege_t> userpriv_pair;
543 typedef vector< userpriv_pair > userpriv_vector;
544 typedef map <handle, set <handle> > attachments_map;
545 struct TextChat : public Cacheable
546 {
547 enum {
548 FLAG_OFFSET_ARCHIVE = 0
549 };
550
551 handle id;
552 privilege_t priv;
553 int shard;
554 userpriv_vector *userpriv;
555 bool group;
556 string title; // byte array
557 string unifiedKey; // byte array
558 handle ou;
559 m_time_t ts; // creation time
560 attachments_map attachedNodes;
561 bool publicchat; // whether the chat is public or private
562
563 private: // use setter to modify these members
564 byte flags; // currently only used for "archive" flag at first bit
565
566 public:
567 int tag; // source tag, to identify own changes
568
569 TextChat();
570 ~TextChat();
571
572 bool serialize(string *d);
573 static TextChat* unserialize(class MegaClient *client, string *d);
574
575 void setTag(int tag);
576 int getTag();
577 void resetTag();
578
579 struct
580 {
581 bool attachments : 1;
582 bool flags : 1;
583 bool mode : 1;
584 } changed;
585
586 // return false if failed
587 bool setNodeUserAccess(handle h, handle uh, bool revoke = false);
588 bool setFlag(bool value, uint8_t offset = 0xFF);
589 bool setFlags(byte newFlags);
590 bool isFlagSet(uint8_t offset) const;
591 bool setMode(bool publicchat);
592
593 };
594 typedef vector<TextChat*> textchat_vector;
595 typedef map<handle, TextChat*> textchat_map;
596 #endif
597
598 typedef enum { RECOVER_WITH_MASTERKEY = 9, RECOVER_WITHOUT_MASTERKEY = 10, CANCEL_ACCOUNT = 21, CHANGE_EMAIL = 12 } recovery_t;
599
600 typedef enum { EMAIL_REMOVED = 0, EMAIL_PENDING_REMOVED = 1, EMAIL_PENDING_ADDED = 2, EMAIL_FULLY_ACCEPTED = 3 } emailstatus_t;
601
602 typedef enum { RETRY_NONE = 0, RETRY_CONNECTIVITY = 1, RETRY_SERVERS_BUSY = 2, RETRY_API_LOCK = 3, RETRY_RATE_LIMIT = 4, RETRY_LOCAL_LOCK = 5, RETRY_UNKNOWN = 6} retryreason_t;
603
604 typedef enum {
605 STORAGE_UNKNOWN = -9,
606 STORAGE_GREEN = 0, // there is storage is available
607 STORAGE_ORANGE = 1, // storage is almost full
608 STORAGE_RED = 2, // storage is full
609 STORAGE_CHANGE = 3, // the status of the storage might have changed
610 STORAGE_PAYWALL = 4, // storage is full and user didn't remedy despite of warnings
611 } storagestatus_t;
612
613
614 enum SmsVerificationState {
615 // These values (except unknown) are delivered from the servers
616 SMS_STATE_UNKNOWN = -1, // Flag was not received
617 SMS_STATE_NOT_ALLOWED = 0, // No SMS allowed
618 SMS_STATE_ONLY_UNBLOCK = 1, // Only unblock SMS allowed
619 SMS_STATE_FULL = 2 // Opt-in and unblock SMS allowed
620 };
621
622 typedef unsigned int achievement_class_id;
623 typedef map<achievement_class_id, Achievement> achievements_map;
624
625 struct recentaction
626 {
627 m_time_t time;
628 handle user;
629 handle parent;
630 bool updated;
631 bool media;
632 node_vector nodes;
633 };
634 typedef vector<recentaction> recentactions_vector;
635
636 typedef enum { BIZ_STATUS_UNKNOWN = -2, BIZ_STATUS_EXPIRED = -1, BIZ_STATUS_INACTIVE = 0, BIZ_STATUS_ACTIVE = 1, BIZ_STATUS_GRACE_PERIOD = 2 } BizStatus;
637 typedef enum { BIZ_MODE_UNKNOWN = -1, BIZ_MODE_SUBUSER = 0, BIZ_MODE_MASTER = 1 } BizMode;
638
639 typedef enum {
640 AUTH_METHOD_UNKNOWN = -1,
641 AUTH_METHOD_SEEN = 0,
642 AUTH_METHOD_FINGERPRINT = 1, // used only for AUTHRING_ED255
643 AUTH_METHOD_SIGNATURE = 2, // used only for signed keys (RSA and Cu25519)
644 } AuthMethod;
645
646 typedef std::map<attr_t, AuthRing> AuthRingsMap;
647
648 // inside 'mega' namespace, since use C++11 and can't rely on C++14 yet, provide make_unique for the most common case.
649 // This keeps our syntax small, while making sure the compiler ensures the object is deleted when no longer used.
650 // Sometimes there will be ambiguity about std::make_unique vs mega::make_unique if cpp files "use namespace std", in which case specify ::mega::.
651 // It's better that we use the same one in older and newer compilers so we detect any issues.
652 template<class T, class... constructorArgs>
make_unique(constructorArgs &&...args)653 unique_ptr<T> make_unique(constructorArgs&&... args)
654 {
655 return (unique_ptr<T>(new T(std::forward<constructorArgs>(args)...)));
656 }
657
658 //#define MEGA_MEASURE_CODE // uncomment this to track time spent in major subsystems, and log it every 2 minutes, with extra control from megacli
659
660 namespace CodeCounter
661 {
662 // Some classes that allow us to easily measure the number of times a block of code is called, and the sum of the time it takes.
663 // Only enabled if MEGA_MEASURE_CODE is turned on.
664 // Usage generally doesn't need to be protected by the macro as the classes and methods will be empty when not enabled.
665
666 using namespace std::chrono;
667
668 struct ScopeStats
669 {
670 #ifdef MEGA_MEASURE_CODE
671 uint64_t count = 0;
672 uint64_t starts = 0;
673 uint64_t finishes = 0;
674 high_resolution_clock::duration timeSpent{};
675 std::string name;
ScopeStatsScopeStats676 ScopeStats(std::string s) : name(std::move(s)) {}
677
678 inline string report(bool reset = false)
679 {
680 string s = " " + name + ": " + std::to_string(count) + " " + std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(timeSpent).count());
681 if (reset)
682 {
683 count = 0;
684 starts -= finishes;
685 finishes = 0;
686 timeSpent = high_resolution_clock::duration{};
687 }
688 return s;
689 }
690 #else
691 ScopeStats(std::string s) {}
692 #endif
693 };
694
695 struct DurationSum
696 {
697 #ifdef MEGA_MEASURE_CODE
698 high_resolution_clock::duration sum{ 0 };
699 high_resolution_clock::time_point deltaStart;
700 bool started = false;
701 inline void start(bool b = true) { if (b && !started) { deltaStart = high_resolution_clock::now(); started = true; } }
702 inline void stop(bool b = true) { if (b && started) { sum += high_resolution_clock::now() - deltaStart; started = false; } }
inprogressDurationSum703 inline bool inprogress() { return started; }
704 inline string report(bool reset = false)
705 {
706 string s = std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(sum).count());
707 if (reset) sum = high_resolution_clock::duration{ 0 };
708 return s;
709 }
710 #else
711 inline void start(bool = true) { }
712 inline void stop(bool = true) { }
713 #endif
714 };
715
716 struct ScopeTimer
717 {
718 #ifdef MEGA_MEASURE_CODE
719 ScopeStats& scope;
720 high_resolution_clock::time_point blockStart;
721
ScopeTimerScopeTimer722 ScopeTimer(ScopeStats& sm) : scope(sm), blockStart(high_resolution_clock::now())
723 {
724 ++scope.starts;
725 }
~ScopeTimerScopeTimer726 ~ScopeTimer()
727 {
728 ++scope.count;
729 ++scope.finishes;
730 scope.timeSpent += high_resolution_clock::now() - blockStart;
731 }
732 #else
733 ScopeTimer(ScopeStats& sm)
734 {
735 }
736 #endif
737 };
738 }
739
740 typedef enum {INVALID = -1, TWO_WAY = 0, UP_SYNC = 1, DOWN_SYNC = 2, CAMERA_UPLOAD = 3 } BackupType;
741
742 // Holds the config of a sync. Can be extended with future config options
743 class SyncConfig : public Cacheable
744 {
745 public:
746
747 enum Type
748 {
749 TYPE_UP = 0x01, // sync up from local to remote
750 TYPE_DOWN = 0x02, // sync down from remote to local
751 TYPE_TWOWAY = TYPE_UP | TYPE_DOWN, // Two-way sync
752 };
753
754 SyncConfig(std::string localPath,
755 const handle remoteNode,
756 const fsfp_t localFingerprint,
757 std::vector<std::string> regExps = {},
758 const Type syncType = TYPE_TWOWAY,
759 const bool syncDeletions = false,
760 const bool forceOverwrite = false);
761
762 // whether this sync is resumable
763 bool isResumable() const;
764
765 // sets whether this sync is resumable
766 void setResumable(bool active);
767
768 // returns the local path of the sync
769 const std::string& getLocalPath() const;
770
771 // returns the remote path of the sync
772 handle getRemoteNode() const;
773
774 // returns the local fingerprint
775 fsfp_t getLocalFingerprint() const;
776
777 // sets the local fingerprint
778 void setLocalFingerprint(fsfp_t fingerprint);
779
780 // returns the regular expressions
781 const std::vector<std::string>& getRegExps() const;
782
783 // returns the type of the sync
784 Type getType() const;
785
786 // whether this is an up-sync from local to remote
787 bool isUpSync() const;
788
789 // whether this is a down-sync from remote to local
790 bool isDownSync() const;
791
792 // whether deletions are synced
793 bool syncDeletions() const;
794
795 // whether changes are overwritten irregardless of file properties
796 bool forceOverwrite() const;
797
798 // serializes the object to a string
799 bool serialize(string* data) override;
800
801 // deserializes the string to a SyncConfig object. Returns null in case of failure
802 static std::unique_ptr<SyncConfig> unserialize(const std::string& data);
803
804 private:
805 friend bool operator==(const SyncConfig& lhs, const SyncConfig& rhs);
806
807 // Whether the sync is resumable
808 bool mResumable = true;
809
810 // the local path of the sync
811 std::string mLocalPath;
812
813 // the remote handle of the sync
814 handle mRemoteNode;
815
816 // the local fingerprint
817 fsfp_t mLocalFingerprint;
818
819 // list of regular expressions
820 std::vector<std::string> mRegExps;
821
822 // type of the sync, defaults to bidirectional
823 Type mSyncType;
824
825 // whether deletions are synced (only relevant for one-way-sync)
826 bool mSyncDeletions;
827
828 // whether changes are overwritten irregardless of file properties (only relevant for one-way-sync)
829 bool mForceOverwrite;
830
831 // need this to ensure serialization doesn't mutate state (Cacheable::serialize is non-const)
832 bool serialize(std::string& data) const;
833
834 // this is very handy for defining comparison operators
835 std::tuple<const bool&,
836 const std::string&,
837 const handle&,
838 const fsfp_t&,
839 const std::vector<std::string>&,
840 const Type&,
841 const bool&,
tie()842 const bool&> tie() const
843 {
844 return std::tie(mResumable,
845 mLocalPath,
846 mRemoteNode,
847 mLocalFingerprint,
848 mRegExps,
849 mSyncType,
850 mSyncDeletions,
851 mForceOverwrite);
852 }
853 };
854
855 bool operator==(const SyncConfig& lhs, const SyncConfig& rhs);
856
857
858 // cross reference pointers. For the case where two classes have pointers to each other, and they should
859 // either always be NULL or if one refers to the other, the other refers to the one.
860 // This class makes sure that the two pointers are always consistent, and also prevents copy/move (unless the pointers are NULL)
861 template<class TO, class FROM>
862 FROM*& crossref_other_ptr_ref(TO* s); // to be supplied for each pair of classes (to assign to the right member thereof) (gets around circular declarations)
863
864 template <class TO, class FROM>
865 class MEGA_API crossref_ptr
866 {
867 friend class crossref_ptr<FROM, TO>;
868
869 template<class A, class B>
870 friend B*& crossref_other_ptr_ref(A* s); // friend so that specialization can access `ptr`
871
872 TO* ptr = nullptr;
873
874 public:
875 crossref_ptr() = default;
876
~crossref_ptr()877 ~crossref_ptr()
878 {
879 reset();
880 }
881
crossref(TO * to,FROM * from)882 void crossref(TO* to, FROM* from)
883 {
884 assert(to && from);
885 assert(ptr == nullptr);
886 assert( !(crossref_other_ptr_ref<TO, FROM>(to)) );
887 ptr = to;
888 crossref_other_ptr_ref<TO, FROM>(ptr) = from;
889 }
890
reset()891 void reset()
892 {
893 if (ptr)
894 {
895 assert( !!(crossref_other_ptr_ref<TO, FROM>(ptr)) );
896 crossref_other_ptr_ref<TO, FROM>(ptr) = nullptr;
897 ptr = nullptr;
898 }
899 }
900
901 TO* operator->() const { return ptr; }
902 operator TO*() const { return ptr; }
903
904 // no copying
905 crossref_ptr(const crossref_ptr&) = delete;
906 void operator=(const crossref_ptr&) = delete;
907
908 // only allow move if the pointers are null (check at runtime with assert)
crossref_ptr(crossref_ptr && p)909 crossref_ptr(crossref_ptr&& p) { assert(!p.ptr); }
910 void operator=(crossref_ptr&& p) { assert(!p.ptr); ptr = p; }
911 };
912
913 } // namespace
914
915 #define MEGA_DISABLE_COPY(class_name) \
916 class_name(const class_name&) = delete; \
917 class_name& operator=(const class_name&) = delete;
918
919 #define MEGA_DISABLE_MOVE(class_name) \
920 class_name(class_name&&) = delete; \
921 class_name& operator=(class_name&&) = delete;
922
923 #define MEGA_DISABLE_COPY_MOVE(class_name) \
924 MEGA_DISABLE_COPY(class_name) \
925 MEGA_DISABLE_MOVE(class_name)
926
927 #define MEGA_DEFAULT_COPY(class_name) \
928 class_name(const class_name&) = default; \
929 class_name& operator=(const class_name&) = default;
930
931 #define MEGA_DEFAULT_MOVE(class_name) \
932 class_name(class_name&&) = default; \
933 class_name& operator=(class_name&&) = default;
934
935 #define MEGA_DEFAULT_COPY_MOVE(class_name) \
936 MEGA_DEFAULT_COPY(class_name) \
937 MEGA_DEFAULT_MOVE(class_name)
938
939 #endif
940