1 #include "filezilla.h"
2 #include "clearprivatedata.h"
3 #include "commandqueue.h"
4 #include "local_recursive_operation.h"
5 #include "Mainfrm.h"
6 #include "Options.h"
7 #include "queue.h"
8 #include "quickconnectbar.h"
9 #include "recentserverlist.h"
10 #include "remote_recursive_operation.h"
11 #include "state.h"
12 
13 #include "../commonui/ipcmutex.h"
14 
15 #include <libfilezilla/file.hpp>
16 
BEGIN_EVENT_TABLE(CClearPrivateDataDialog,wxDialogEx)17 BEGIN_EVENT_TABLE(CClearPrivateDataDialog, wxDialogEx)
18 EVT_TIMER(wxID_ANY, CClearPrivateDataDialog::OnTimer)
19 END_EVENT_TABLE()
20 
21 CClearPrivateDataDialog::CClearPrivateDataDialog(CMainFrame* pMainFrame)
22 	: m_pMainFrame(pMainFrame)
23 {
24 }
25 
Run()26 void CClearPrivateDataDialog::Run()
27 {
28 	if (!Load(m_pMainFrame, _T("ID_CLEARPRIVATEDATA"))) {
29 		return;
30 	}
31 
32 	if (ShowModal() != wxID_OK) {
33 		return;
34 	}
35 
36 	wxCheckBox *pSitemanagerCheck = XRCCTRL(*this, "ID_CLEARSITEMANAGER", wxCheckBox);
37 	wxCheckBox *pQueueCheck = XRCCTRL(*this, "ID_CLEARQUEUE", wxCheckBox);
38 	if (pSitemanagerCheck->GetValue() && pQueueCheck->GetValue()) {
39 		int res = wxMessageBoxEx(_("Do you really want to delete all Site Manager entries and the transfer queue?"), _("Clear private data"), wxYES | wxNO | wxICON_QUESTION);
40 		if (res != wxYES) {
41 			return;
42 		}
43 	}
44 	else if (pQueueCheck->GetValue()) {
45 		int res = wxMessageBoxEx(_("Do you really want to delete the transfer queue?"), _("Clear private data"), wxYES | wxNO | wxICON_QUESTION);
46 		if (res != wxYES) {
47 			return;
48 		}
49 	}
50 	else if (pSitemanagerCheck->GetValue()) {
51 		int res = wxMessageBoxEx(_("Do you really want to delete all Site Manager entries?"), _("Clear private data"), wxYES | wxNO | wxICON_QUESTION);
52 		if (res != wxYES) {
53 			return;
54 		}
55 	}
56 
57 	wxCheckBox *pCheck = XRCCTRL(*this, "ID_CLEARQUICKCONNECT", wxCheckBox);
58 	if (pCheck && pCheck->GetValue()) {
59 		CRecentServerList::Clear();
60 		if (m_pMainFrame->GetQuickconnectBar()) {
61 			m_pMainFrame->GetQuickconnectBar()->ClearFields();
62 		}
63 	}
64 
65 	pCheck = XRCCTRL(*this, "ID_CLEARRECONNECT", wxCheckBox);
66 	if (pCheck && pCheck->GetValue()) {
67 		bool asked = false;
68 
69 		const std::vector<CState*> *states = CContextManager::Get()->GetAllStates();
70 
71 		for (std::vector<CState*>::const_iterator iter = states->begin(); iter != states->end(); ++iter) {
72 			CState* pState = *iter;
73 			if (pState->IsRemoteConnected() || !pState->IsRemoteIdle()) {
74 				if (!asked) {
75 					int res = wxMessageBoxEx(_("Reconnect information cannot be cleared while connected to a server.\nIf you continue, your connection will be disconnected."), _("Clear private data"), wxOK | wxCANCEL);
76 					if (res != wxOK) {
77 						return;
78 					}
79 					asked = true;
80 				}
81 
82 				pState->GetLocalRecursiveOperation()->StopRecursiveOperation();
83 				pState->GetRemoteRecursiveOperation()->StopRecursiveOperation();
84 				if (!pState->m_pCommandQueue->Cancel()) {
85 					m_timer.SetOwner(this);
86 					m_timer.Start(250, true);
87 				}
88 				else {
89 					pState->Disconnect();
90 				}
91 			}
92 		}
93 
94 		// Doesn't harm to do it now, but has to be repeated later just to be safe
95 		ClearReconnect();
96 	}
97 
98 	if (pSitemanagerCheck->GetValue()) {
99 		CInterProcessMutex sitemanagerMutex(MUTEX_SITEMANAGERGLOBAL, false);
100 		while (sitemanagerMutex.TryLock() == 0) {
101 			int res = wxMessageBoxEx(_("The Site Manager is opened in another instance of FileZilla 3.\nPlease close it or the data cannot be deleted."), _("Clear private data"), wxOK | wxCANCEL);
102 			if (res != wxYES) {
103 				return;
104 			}
105 		}
106 		CInterProcessMutex mutex(MUTEX_SITEMANAGER);
107 		RemoveXmlFile(L"sitemanager");
108 	}
109 
110 	if (pQueueCheck->GetValue()) {
111 		m_pMainFrame->GetQueue()->SetActive(false);
112 		m_pMainFrame->GetQueue()->RemoveAll();
113 	}
114 }
115 
OnTimer(wxTimerEvent &)116 void CClearPrivateDataDialog::OnTimer(wxTimerEvent&)
117 {
118 	const std::vector<CState*> *states = CContextManager::Get()->GetAllStates();
119 
120 	for (std::vector<CState*>::const_iterator iter = states->begin(); iter != states->end(); ++iter) {
121 		CState* pState = *iter;
122 
123 		if (pState->IsRemoteConnected() || !pState->IsRemoteIdle()) {
124 			if (!pState->m_pCommandQueue->Cancel()) {
125 				return;
126 			}
127 
128 			pState->Disconnect();
129 		}
130 
131 		if (pState->IsRemoteConnected() || !pState->IsRemoteIdle()) {
132 			return;
133 		}
134 	}
135 
136 	m_timer.Stop();
137 	ClearReconnect();
138 	Delete();
139 }
140 
Delete()141 void CClearPrivateDataDialog::Delete()
142 {
143 	if (m_timer.IsRunning()) {
144 		return;
145 	}
146 
147 	Destroy();
148 }
149 
ClearReconnect()150 bool CClearPrivateDataDialog::ClearReconnect()
151 {
152 	COptions::Get()->Cleanup();
153 	COptions::Get()->Save();
154 
155 	const std::vector<CState*> *states = CContextManager::Get()->GetAllStates();
156 	for (std::vector<CState*>::const_iterator iter = states->begin(); iter != states->end(); ++iter) {
157 		CState* pState = *iter;
158 		if (pState) {
159 			pState->SetLastSite(Site(), CServerPath());
160 		}
161 	}
162 
163 	return true;
164 }
165 
RemoveXmlFile(std::wstring const & name)166 void CClearPrivateDataDialog::RemoveXmlFile(std::wstring const& name)
167 {
168 	std::wstring const path = COptions::Get()->get_string(OPTION_DEFAULT_SETTINGSDIR);
169 	if (!name.empty() && !path.empty()) {
170 		fz::remove_file(fz::to_native(path + name + L".xml"));
171 		fz::remove_file(fz::to_native(path + name + L".xml~"));
172 	}
173 }
174