1 /**
2  * @file src/megacmdshellcommunications.h
3  * @brief MEGAcmd: Communications module to connect to server
4  *
5  * (c) 2013 by Mega Limited, Auckland, New Zealand
6  *
7  * This file is part of the MEGAcmd.
8  *
9  * MEGAcmd is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * @copyright Simplified (2-clause) BSD License.
14  *
15  * You should have received a copy of the license along with this
16  * program.
17  *
18  * This file is also distributed under the terms of the GNU General
19  * Public License, see http://www.gnu.org/copyleft/gpl.txt for details.
20  */
21 
22 #ifndef MEGACMDSHELLCOMMUNICATIONS_H
23 #define MEGACMDSHELLCOMMUNICATIONS_H
24 
25 #include "../megacmdcommonutils.h"
26 
27 #include <string>
28 #include <iostream>
29 #include <mutex>
30 
31 #ifdef _WIN32
32 #include <WinSock2.h>
33 #include <Shlwapi.h> //PathAppend
34 #else
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <unistd.h>
38 #include <arpa/inet.h>
39 #include <sys/un.h>
40 #endif
41 
42 #if defined(_WIN32) && !defined(WINDOWS_PHONE) && !defined(USE_CPPTHREAD)
43 #include "mega/thread/win32thread.h"
44 class MegaThread : public ::mega::Win32Thread {};
45 #elif defined(USE_CPPTHREAD)
46 #include "mega/thread/cppthread.h"
47 class MegaThread : public ::mega::CppThread {};
48 #else
49 #include "mega/thread/posixthread.h"
50 class MegaThread : public ::mega::PosixThread {};
51 #endif
52 
53 #ifdef _WIN32
54 #else
55 typedef int SOCKET;
56 #endif
57 
58 #ifdef _WIN32
59 #include <windows.h>
60 #define ERRNO WSAGetLastError()
61 #else
62 #define ERRNO errno
63 #endif
64 
65 #ifndef SOCKET_ERROR
66 #define SOCKET_ERROR -1
67 #endif
68 
69 #ifdef __MACH__
70 #define MSG_NOSIGNAL 0
71 #elif _WIN32
72 #define MSG_NOSIGNAL 0
73 #endif
74 
75 #define MEGACMDINITIALPORTNUMBER 12300
76 namespace megacmd {
77 
78 enum
79 {
80     MCMD_OK = 0,              ///< Everything OK
81 
82     MCMD_EARGS = -51,         ///< Wrong arguments
83     MCMD_INVALIDEMAIL = -52,  ///< Invalid email
84     MCMD_NOTFOUND = -53,      ///< Resource not found
85     MCMD_INVALIDSTATE = -54,  ///< Invalid state
86     MCMD_INVALIDTYPE = -55,   ///< Invalid type
87     MCMD_NOTPERMITTED = -56,  ///< Operation not allowed
88     MCMD_NOTLOGGEDIN = -57,   ///< Needs loging in
89     MCMD_NOFETCH = -58,       ///< Nodes not fetched
90     MCMD_EUNEXPECTED = -59,   ///< Unexpected failure
91 
92     MCMD_REQCONFIRM = -60,     ///< Confirmation required
93     MCMD_REQSTRING = -61,     ///< String required
94     MCMD_PARTIALOUT = -62,     ///< Partial output provided
95 
96 #if defined(_WIN32) || defined(__APPLE__)
97     MCMD_REQRESTART = -71,     ///< Restart required
98 #endif
99 };
100 
101 enum confirmresponse
102 {
103     MCMDCONFIRM_NO=0,
104     MCMDCONFIRM_YES,
105     MCMDCONFIRM_ALL,
106     MCMDCONFIRM_NONE
107 };
108 
109 typedef struct structListenStateChanges{
110     int receiveSocket;
111     void (*statechangehandle)(std::string);
112 } sListenStateChanges;
113 
114 class MegaCmdShellCommunications
115 {
116 public:
117     MegaCmdShellCommunications();
118     virtual ~MegaCmdShellCommunications();
119 
120     static std::mutex megaCmdStdoutputing;
121     virtual int executeCommand(std::string command, std::string (*readresponse)(const char *) = NULL, OUTSTREAMTYPE &output = COUT, bool interactiveshell = true, std::wstring = L"");
122     virtual int executeCommandW(std::wstring command, std::string (*readresponse)(const char *) = NULL, OUTSTREAMTYPE &output = COUT, bool interactiveshell = true);
123 
124     virtual int registerForStateChanges(bool interactive, void (*statechangehandle)(std::string) = NULL, bool initiateServer = true);
125 
126     virtual void setResponseConfirmation(bool confirmation);
127 
128     static bool serverinitiatedfromshell;
129     static bool registerAgainRequired;
130     int readconfirmationloop(const char *question, std::string (*readresponse)(const char *));
131     static bool updating;
132 
133 private:
134     static SOCKET newsockfd;
135     static bool socketValid(SOCKET socket);
136     static void closeSocket(SOCKET socket);
137 
138     static void *listenToStateChangesEntry(void *slsc);
139     static int listenToStateChanges(int receiveSocket, void (*statechangehandle)(std::string) = NULL);
140 
141 
142     static bool confirmResponse;
143 
144     static bool stopListener;
145     static MegaThread *listenerThread;
146 
147 #ifdef _WIN32
148 static SOCKET createSocket(int number = 0, bool initializeserver = true, bool net = true);
149 #else
150 static SOCKET createSocket(int number = 0, bool initializeserver = true, bool net = false);
151 #endif
152 
153 
154 };
155 
156 }//end namespace
157 #endif // MEGACMDSHELLCOMMUNICATIONS_H
158