1 #include "filezilla.h"
2 #include "storj_key_interface.h"
3 #include "Options.h"
4 #include "filezillaapp.h"
5 #include "inputdialog.h"
6
7 #include <libfilezilla/process.hpp>
8
CStorjKeyInterface(wxWindow * parent)9 CStorjKeyInterface::CStorjKeyInterface(wxWindow* parent)
10 : m_parent(parent)
11 {
12 }
13
~CStorjKeyInterface()14 CStorjKeyInterface::~CStorjKeyInterface()
15 {
16 }
17
18 namespace {
quote(std::wstring_view const & arg)19 std::wstring quote(std::wstring_view const& arg)
20 {
21 return L"\"" + fz::replaced_substrings(arg, L"\"", L"\"\"") + L"\"";
22 }
23 }
ValidateGrant(std::wstring const & grant,bool silent)24 std::tuple<bool, std::wstring> CStorjKeyInterface::ValidateGrant(std::wstring const& grant, bool silent)
25 {
26 if (grant.empty()) {
27 return {false, std::wstring()};
28 }
29 LoadProcess(silent);
30
31 if (!Send(L"validate grant " + quote(grant))) {
32 return {false, std::wstring()};
33 }
34
35 std::wstring reply;
36 ReplyCode code = GetReply(reply);
37 return {code == success, reply};
38 }
39
LoadProcess(bool silent)40 bool CStorjKeyInterface::LoadProcess(bool silent)
41 {
42 if (m_initialized) {
43 return m_process != 0;
44 }
45 m_initialized = true;
46
47 std::wstring executable = COptions::Get()->get_string(OPTION_FZSTORJ_EXECUTABLE);
48 size_t pos = executable.rfind(wxFileName::GetPathSeparator());
49 if (pos == std::wstring::npos) {
50 if (!silent) {
51 wxMessageBoxEx(_("fzstorj could not be started.\nPlease make sure this executable exists in the same directory as the main FileZilla executable."), _("Error starting program"), wxICON_EXCLAMATION);
52 }
53 return false;
54 }
55
56 executable = executable.substr(0, pos + 1) + L"fzstorj";
57 #ifdef FZ_WINDOWS
58 executable += L".exe";
59 #endif
60
61 m_process = std::make_unique<fz::process>();
62 if (!m_process->spawn(fz::to_native(executable))) {
63 m_process.reset();
64
65 if (!silent) {
66 wxMessageBoxEx(_("fzstorj could not be started.\nPlease make sure this executable exists in the same directory as the main FileZilla executable."), _("Error starting program"), wxICON_EXCLAMATION);
67 }
68 return false;
69 }
70
71 return true;
72 }
73
Send(std::wstring const & cmd)74 bool CStorjKeyInterface::Send(std::wstring const& cmd)
75 {
76 if (!m_process) {
77 return false;
78 }
79
80 std::string utf8 = fz::to_utf8(cmd) + "\n";
81 if (!m_process->write(utf8)) {
82 m_process.reset();
83
84 wxMessageBoxEx(_("Could not send command to fzstorj."), _("Command failed"), wxICON_EXCLAMATION);
85 return false;
86 }
87
88 return true;
89 }
90
GetReply(std::wstring & reply)91 CStorjKeyInterface::ReplyCode CStorjKeyInterface::GetReply(std::wstring & reply)
92 {
93 if (!m_process) {
94 return error;
95 }
96
97 char buffer[100];
98
99 std::string input;
100
101 for (;;) {
102 size_t pos = input.find_first_of("\r\n");
103 if (pos == std::string::npos) {
104 int read = m_process->read(buffer, 100);
105 if (read <= 0) {
106 wxMessageBoxEx(_("Could not get reply from fzstorj."), _("Command failed"), wxICON_EXCLAMATION);
107 m_process.reset();
108 return error;
109 }
110
111 input.append(buffer, read);
112 continue;
113 }
114
115 // Strip everything behind first linebreak.
116 if (!pos) {
117 input = input.substr(1);
118 continue;
119 }
120
121 char c = input[0];
122
123 reply = fz::to_wstring_from_utf8(input.substr(1, pos - 1));
124 input = input.substr(pos + 1);
125
126 if (c == '1') {
127 return success;
128 }
129 else if (c == '2') {
130 return error;
131 }
132 // Ignore others
133 }
134 }
135
ProcessFailed() const136 bool CStorjKeyInterface::ProcessFailed() const
137 {
138 return m_initialized && !m_process;
139 }
140