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