-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathConnectExpressVPN.cpp
More file actions
58 lines (44 loc) · 1.68 KB
/
ConnectExpressVPN.cpp
File metadata and controls
58 lines (44 loc) · 1.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/*
ConnectExpressVPN.cpp
Joel Goodman 2020
*/
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <memory>
#include <array>
int main()
{
constexpr const char* vpnConnectCommand = "expressvpn connect smart";
constexpr const char* vpnDisconnectCommand = "expressvpn disconnect";
constexpr const char* notConnectedSubStr = "Not connected"; /* This is a substring we check for to tell whether or not vpn is connected. */
constexpr const char* statusCommand = "expressvpn status";
constexpr size_t subStrLen = strlen(notConnectedSubStr);
/* Credit for the code below that gets command output belongs to gregpaton08 on SO (https://bit.ly/3iMTppU).
* I've been using this solution for years now and it always works perfectly. Thanks, Greg! */
std::array<char,subStrLen> buffer;
std::string result;
result.reserve(subStrLen);
std::unique_ptr<std::FILE,decltype(&pclose)> pipe(popen(statusCommand, "r"), pclose);
if(!pipe)
throw std::runtime_error("popen() failed!");
for(unsigned int i = 0 ; i < subStrLen ; ++i)
{
fgets(buffer.data(), subStrLen, pipe.get());
result += buffer.data();
}
const size_t pos = result.find(notConnectedSubStr);
const bool connected = (pos == std::string::npos);
if(connected)
{
std::system("notify-send -i face-cool \"VPN Connector\" \"Disconnecting ExpressVPN...\"");
std::system(vpnDisconnectCommand);
}
else
{
std::system("notify-send -i face-cool \"VPN Connector\" \"Connecting ExpressVPN...\"");
std::system(vpnConnectCommand);
}
return EXIT_SUCCESS;
}