Finish building daemon, refresh peers, cli and gui
This commit is contained in:
parent
b6b7fcecd9
commit
baf7d64cab
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
||||
dist/
|
||||
package/
|
||||
|
@ -1,21 +1,75 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <threads.h>
|
||||
#include <stdatomic.h>
|
||||
|
||||
#include "states.h"
|
||||
#include "open_gui.h"
|
||||
#include "unix_sockets.h"
|
||||
#include "melon_vpn_sock.h"
|
||||
#include "melon_vpn_about.h"
|
||||
|
||||
#ifndef PROJ_VERSION
|
||||
#define PROJ_VERSION "unknown"
|
||||
#endif
|
||||
|
||||
States currentstate;
|
||||
char *currentpeers;
|
||||
bool currentisrestart;
|
||||
char *version = PROJ_VERSION;
|
||||
bool is_gui = false;
|
||||
thrd_t listenthr;
|
||||
atomic_bool listenserverready = false;
|
||||
|
||||
int send_to_daemon(char*, ssize_t);
|
||||
int refresh_vpn();
|
||||
int status_vpn();
|
||||
int peers_vpn();
|
||||
int start_vpn();
|
||||
int stop_vpn();
|
||||
int restart_conf_vpn(bool);
|
||||
|
||||
int start_client_receiver(void*);
|
||||
int listen_client_receiver(int);
|
||||
|
||||
void start_listen_thread();
|
||||
void wait_listen_thread();
|
||||
|
||||
void update_state(States state) {
|
||||
currentstate = state;
|
||||
}
|
||||
|
||||
bool incoming_state(char *state) {
|
||||
currentstate = enum_state(state);
|
||||
if(is_gui) {
|
||||
gui_trigger_state(currentstate);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool incoming_peers(char *peers) {
|
||||
currentpeers = peers;
|
||||
if(is_gui) {
|
||||
gui_trigger_peers(peers);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool incoming_isrestart(char *isrestart) {
|
||||
currentisrestart = strcmp(isrestart,"on")==0;
|
||||
if(is_gui) {
|
||||
gui_trigger_isrestart(currentisrestart);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int is_arg(int ac, char **argv, char *arg) {
|
||||
if (ac < 2) {
|
||||
return 0;
|
||||
@ -34,19 +88,23 @@ void display_version(bool is_debug) {
|
||||
}
|
||||
|
||||
void display_about(bool is_debug) {
|
||||
printf("Melon VPN\n");
|
||||
printf("%s\n", about_name);
|
||||
display_version(is_debug);
|
||||
printf("Copyright OnPointCoding\n");
|
||||
printf("https://software.onpointcoding.net\n");
|
||||
printf("OnPointCoding.net\n");
|
||||
printf("Author: MrMelon54\n");
|
||||
printf("Artist: MrMelon54\n");
|
||||
printf("%s\n", about_copyright);
|
||||
printf("%s\n", about_url);
|
||||
printf("%s\n", about_website);
|
||||
printf("Author: %s\n", about_author);
|
||||
printf("Artist: %s\n", about_artist);
|
||||
}
|
||||
|
||||
void display_help(bool is_debug) {
|
||||
printf("Melon VPN Help\n");
|
||||
printf("-h, --help Display this help message\n");
|
||||
printf("--about About this program\n");
|
||||
printf("connect, -c Connect to VPN\n");
|
||||
printf("disconnect, -d Disconnect from VPN\n");
|
||||
printf("restart <on/off>, Enable or disable restart mode\n");
|
||||
printf(" -r <on/off>\n");
|
||||
}
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
@ -70,10 +128,169 @@ int main (int argc, char **argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
start_listen_thread();
|
||||
|
||||
struct timespec *t = malloc(sizeof t);
|
||||
t->tv_nsec = 1000;
|
||||
while(!listenserverready) {
|
||||
thrd_sleep(t,NULL);
|
||||
}
|
||||
|
||||
if(is_arg(argc, argv, "--gui")) {
|
||||
open_gui(argc, argv, is_debug);
|
||||
is_gui = true;
|
||||
open_gui(argc, argv, is_debug, &start_vpn, &stop_vpn, &restart_conf_vpn, &refresh_vpn);
|
||||
is_gui = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(argc==2) {
|
||||
if(strcmp(argv[1],"status")==0 || strcmp(argv[1],"-s")==0) {
|
||||
status_vpn();
|
||||
} else if(strcmp(argv[1],"peers")==0 || strcmp(argv[1],"-p")==0) {
|
||||
peers_vpn();
|
||||
} else if(strcmp(argv[1],"connect")==0 || strcmp(argv[1],"-c")==0) {
|
||||
start_vpn();
|
||||
} else if(strcmp(argv[1],"disconnect")==0 || strcmp(argv[1],"-d")==0) {
|
||||
stop_vpn();
|
||||
}
|
||||
} else if(argc==3) {
|
||||
if(strcmp(argv[1],"restart")==0 || strcmp(argv[1],"-r")==0) {
|
||||
if(strcmp(argv[2],"enable")==0 || strcmp(argv[2],"on")==0) {
|
||||
restart_conf_vpn(true);
|
||||
} else if(strcmp(argv[2],"disable")==0 || strcmp(argv[2],"off")==0) {
|
||||
restart_conf_vpn(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void start_listen_thread() {
|
||||
thrd_create(&listenthr, start_client_receiver, NULL);
|
||||
}
|
||||
|
||||
void wait_listen_thread() {
|
||||
thrd_join(listenthr,NULL);
|
||||
}
|
||||
|
||||
int send_to_daemon(char *buf, ssize_t n) {
|
||||
int sfd = unix_socket_client_start(SV_DAEMON_SOCK_PATH);
|
||||
if(sfd==-1) {
|
||||
fprintf(stderr, "Make sure the daemon is running before trying to use it.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
write(sfd, buf, n);
|
||||
close(sfd);
|
||||
|
||||
fprintf(stderr, "Closed connection to socket\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int start_client_server() {
|
||||
int sfd = unix_socket_server_start(SV_CLIENT_SOCK_PATH);
|
||||
|
||||
listenserverready = true;
|
||||
|
||||
ssize_t numRead;
|
||||
int MAX_PEERS_LEN = 1000;
|
||||
char msg[MAX_PEERS_LEN];
|
||||
char buf[BUF_SIZE];
|
||||
int total = 0;
|
||||
|
||||
for(;;) {
|
||||
int cfd = accept(sfd, NULL, NULL);
|
||||
|
||||
strcpy(msg, "");
|
||||
strcpy(buf, "");
|
||||
total = 0;
|
||||
|
||||
while ((numRead = read(cfd, buf, BUF_SIZE)) > 0) {
|
||||
if(total > MAX_PEERS_LEN-1) break;
|
||||
total+=numRead;
|
||||
strcat(msg, buf);
|
||||
msg[MAX_PEERS_LEN-1]=0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Incoming request: %s\n",msg);
|
||||
|
||||
char *a = strtok(msg,"\1");
|
||||
if(strcmp(a,"client")==0) {
|
||||
char *b = strtok(NULL,"\1");
|
||||
if(strcmp(b,"status")==0) {
|
||||
char *c = strtok(NULL,"\1");
|
||||
if(incoming_state(c)) break;
|
||||
} else if(strcmp(b,"peers")==0) {
|
||||
char *c = strtok(NULL,"\1");
|
||||
if(incoming_peers(c)) break;
|
||||
} else if(strcmp(b,"isrestart")==0) {
|
||||
char *c = strtok(NULL,"\1");
|
||||
if(incoming_isrestart(c)) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int start_client_receiver(void *thr_data) {
|
||||
(void)thr_data;
|
||||
|
||||
start_client_server();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int status_vpn() {
|
||||
char *msg = "daemon\1status";
|
||||
send_to_daemon(msg, strlen(msg));
|
||||
wait_listen_thread();
|
||||
printf("Melon VPN status: %s\n", string_state(currentstate));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int peers_vpn() {
|
||||
char *msg = "daemon\1peers";
|
||||
send_to_daemon(msg, strlen(msg));
|
||||
wait_listen_thread();
|
||||
printf("Melon VPN peers:\n%s\n", currentpeers);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int start_vpn() {
|
||||
char *msg = "daemon\1connect";
|
||||
return send_to_daemon(msg, strlen(msg));
|
||||
}
|
||||
|
||||
int stop_vpn() {
|
||||
char *msg = "daemon\1disconnect";
|
||||
return send_to_daemon(msg, strlen(msg));
|
||||
}
|
||||
|
||||
int refresh_vpn() {
|
||||
char *msg = "daemon\1status";
|
||||
int a=send_to_daemon(msg, strlen(msg));
|
||||
|
||||
char *msg2 = "daemon\1peers";
|
||||
int b=send_to_daemon(msg2, strlen(msg2));
|
||||
|
||||
char *msg3 = "daemon\1isrestart";
|
||||
int c=send_to_daemon(msg3, strlen(msg3));
|
||||
|
||||
return a+b+c;
|
||||
}
|
||||
|
||||
int restart_conf_vpn(bool enable) {
|
||||
char *msgprefix = "daemon\1restart\1";
|
||||
int prefixlen = strlen(msgprefix);
|
||||
int msglen = prefixlen + (enable ? 2 : 3);
|
||||
|
||||
char msg[msglen+1];
|
||||
strcpy(msg, msgprefix);
|
||||
msg[prefixlen] = 0;
|
||||
|
||||
strcat(msg, enable ? "on" : "off");
|
||||
msg[msglen] = 0;
|
||||
|
||||
return send_to_daemon(msg, msglen+1);
|
||||
}
|
||||
|
@ -4,10 +4,12 @@
|
||||
#include "magic_code.h"
|
||||
#include "open_gui.h"
|
||||
|
||||
int open_gui(int argc, char **argv, bool is_debug) {
|
||||
void *lib_handle;
|
||||
bool gui_trigger_safe = false;
|
||||
|
||||
int open_gui(int argc, char **argv, bool is_debug, int (*start_vpn)(), int (*stop_vpn)(), int (*restart_conf_vpn)(bool), int (*refresh_vpn)()) {
|
||||
void (*fn)(int*, int*);
|
||||
int (*gui)(int, char**);
|
||||
int (*gui)(int argc, char** argv, bool is_debug, int (*start_vpn)(), int (*stop_vpn)(), int (*restart_conf_vpn)(bool), int (*refresh_vpn)());
|
||||
int a = 0;
|
||||
int b = 0;
|
||||
char *error;
|
||||
@ -30,6 +32,7 @@ int open_gui(int argc, char **argv, bool is_debug) {
|
||||
fprintf(stderr, "The function 'get_magic_code' couldn't be found\n");
|
||||
fprintf(stderr, "Check the package 'melonvpngui' is installed correctly\n");
|
||||
fprintf(stderr, "%s\n", error);
|
||||
dlclose(lib_handle);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -42,16 +45,72 @@ int open_gui(int argc, char **argv, bool is_debug) {
|
||||
fprintf(stderr, "The function 'run_gui' couldn't be found\n");
|
||||
fprintf(stderr, "Check the package 'melonvpngui' is installed correctly\n");
|
||||
fprintf(stderr, "%s\n", error);
|
||||
dlclose(lib_handle);
|
||||
return 1;
|
||||
}
|
||||
|
||||
gui_trigger_safe = true;
|
||||
|
||||
int fake_argc = 1;
|
||||
char *fake_argv[1] = {0};
|
||||
fake_argv[0] = argv[0];
|
||||
|
||||
(*gui)(fake_argc,fake_argv);
|
||||
(*gui)(fake_argc, fake_argv, is_debug, start_vpn, stop_vpn, restart_conf_vpn, refresh_vpn);
|
||||
}
|
||||
|
||||
gui_trigger_safe = false;
|
||||
|
||||
dlclose(lib_handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gui_trigger_state(States state) {
|
||||
if(!gui_trigger_safe) return 100;
|
||||
|
||||
char *error;
|
||||
void (*trigger)(States);
|
||||
trigger = dlsym(lib_handle, "mod_trigger_state");
|
||||
|
||||
if((error = dlerror()) != NULL) {
|
||||
fprintf(stderr, "Failed to run 'mod_trigger_state'\n");
|
||||
fprintf(stderr, "%s\n", error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
(*trigger)(state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gui_trigger_isrestart(bool isrestart) {
|
||||
if(!gui_trigger_safe) return 100;
|
||||
|
||||
char *error;
|
||||
void (*trigger)(bool);
|
||||
trigger = dlsym(lib_handle, "mod_trigger_isrestart");
|
||||
|
||||
if((error = dlerror()) != NULL) {
|
||||
fprintf(stderr, "Failed to run 'mod_trigger_isrestart'\n");
|
||||
fprintf(stderr, "%s\n", error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
(*trigger)(isrestart);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gui_trigger_peers(char *peers) {
|
||||
if(!gui_trigger_safe) return 100;
|
||||
|
||||
char *error;
|
||||
void (*trigger)(char*);
|
||||
trigger = dlsym(lib_handle, "mod_trigger_peers");
|
||||
|
||||
if((error = dlerror()) != NULL) {
|
||||
fprintf(stderr, "Failed to run 'mod_trigger_peers'\n");
|
||||
fprintf(stderr, "%s\n", error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
(*trigger)(peers);
|
||||
return 0;
|
||||
}
|
||||
|
@ -5,13 +5,16 @@
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <threads.h>
|
||||
#include <stdatomic.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "states.h"
|
||||
#include "unix_sockets.h"
|
||||
#include "melon_vpn_sock.h"
|
||||
#include "config_file.h"
|
||||
#include "popen2.h"
|
||||
|
||||
#define vpnconfig "/etc/melonvpn/client.cfg"
|
||||
#define daemonconfig "/etc/melonvpn/daemon.cfg"
|
||||
@ -20,20 +23,27 @@ char *vpnserver = "";
|
||||
char *devicename = "unknown";
|
||||
bool restartvpn = false;
|
||||
|
||||
char *storedpeers;
|
||||
pid_t vpn_process = -1;
|
||||
States currentstate;
|
||||
|
||||
int start_daemon_server(void*);
|
||||
int start_peers_server(void*);
|
||||
void send_to_client(char*, ssize_t);
|
||||
|
||||
static volatile int keepRunning = 1;
|
||||
atomic_bool daemonthrbusy = false;
|
||||
atomic_bool peersthrbusy = false;
|
||||
int start_vpn_process();
|
||||
void stop_vpn_process();
|
||||
|
||||
thrd_t daemonthr;
|
||||
thrd_t peersthr;
|
||||
|
||||
void read_vpn_config();
|
||||
void read_daemon_config();
|
||||
void write_daemon_config();
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
currentstate = DISCONNECTED;
|
||||
|
||||
printf("Reading config files...\n");
|
||||
read_vpn_config();
|
||||
read_daemon_config();
|
||||
@ -42,6 +52,25 @@ int main(int argc, char **argv) {
|
||||
printf("Device name: %s\n", devicename);
|
||||
printf("Restart VPN: %s\n", restartvpn ? "true" : "false");
|
||||
|
||||
printf("Create folder for sockets\n");
|
||||
|
||||
// why check stat first its slower?
|
||||
char sock_wrapper_path[100] = SV_WRAPPER_SOCK_PATH;
|
||||
umask(0);
|
||||
|
||||
// Try removing sockets
|
||||
unlink(SV_CLIENT_SOCK_PATH);
|
||||
unlink(SV_DAEMON_SOCK_PATH);
|
||||
unlink(SV_RPEERS_SOCK_PATH);
|
||||
|
||||
// Remove wrapping directory and make a new one
|
||||
rmdir(sock_wrapper_path);
|
||||
int mkdirout = mkdir(sock_wrapper_path, 0777); // user: rw, group: rw, everyone: w
|
||||
if(mkdirout!=0) {
|
||||
fprintf(stderr, "Failed to create directory for sockets (%d)\n",mkdirout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
thrd_create(&daemonthr, start_daemon_server, NULL);
|
||||
thrd_create(&peersthr, start_peers_server, NULL);
|
||||
|
||||
@ -50,18 +79,66 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
void incoming_request(char *request) {
|
||||
char *a;
|
||||
char *b;
|
||||
a=strtok(request,(char*)1);
|
||||
b=strtok(NULL,"");
|
||||
fprintf(stderr,a);
|
||||
fprintf(stderr,b);
|
||||
fprintf(stderr, "Incoming request: %s\n",request);
|
||||
char *a = strtok(request, "\1");
|
||||
|
||||
if(strcmp(a,"daemon")==0) {
|
||||
char *b = strtok(NULL, "\1");
|
||||
|
||||
if(strcmp(b,"status")==0) {
|
||||
send_vpn_status();
|
||||
} else if(strcmp(b,"connect")==0) {
|
||||
if(start_vpn_process()==0) {
|
||||
currentstate = CONNECTED;
|
||||
} else {
|
||||
currentstate = DISCONNECTED;
|
||||
}
|
||||
send_vpn_status();
|
||||
} else if(strcmp(b,"disconnect")==0) {
|
||||
stop_vpn_process();
|
||||
currentstate = DISCONNECTED;
|
||||
send_vpn_status();
|
||||
} else if(strcmp(b,"isrestart")==0) {
|
||||
send_is_restart_status();
|
||||
} else if(strcmp(b,"restart")==0) {
|
||||
char *c = strtok(NULL, "\1");
|
||||
restartvpn=strcmp(c,"on")==0;
|
||||
write_daemon_config();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void incoming_peers(char *peers) {
|
||||
char *a;
|
||||
char *b;
|
||||
fprintf(stderr,peers);
|
||||
storedpeers = peers;
|
||||
send_to_client(peers, strlen(peers));
|
||||
}
|
||||
|
||||
void send_vpn_status() {
|
||||
char *msgprefix = "client\1status\1";
|
||||
int prefixl = strlen(msgprefix);
|
||||
char *msgsuffix = string_state(currentstate);
|
||||
int suffixl = strlen(msgsuffix);
|
||||
int total = prefixl+suffixl;
|
||||
char msg[total+1];
|
||||
strcpy(msg, msgprefix);
|
||||
msg[prefixl] = 0;
|
||||
strcat(msg, msgsuffix);
|
||||
msg[total] = 0;
|
||||
send_to_client(msg, total+1);
|
||||
}
|
||||
|
||||
void send_is_restart_status() {
|
||||
char *msgprefix = "client\1isrestart\1";
|
||||
int prefixl = strlen(msgprefix);
|
||||
char *msgsuffix = restartvpn ? "on" : "off";
|
||||
int suffixl = strlen(msgsuffix);
|
||||
int total = prefixl+suffixl;
|
||||
char msg[total+1];
|
||||
strcpy(msg, msgprefix);
|
||||
msg[prefixl]=0;
|
||||
strcat(msg, msgsuffix);
|
||||
msg[total]=0;
|
||||
send_to_client(msg, total+1);
|
||||
}
|
||||
|
||||
void read_vpn_config() {
|
||||
@ -111,41 +188,65 @@ void write_daemon_config() {
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
int start_vpn_process() {
|
||||
fprintf(stderr, "ready to start: %d\n", vpn_process);
|
||||
if(vpn_process != -1) return;
|
||||
|
||||
// Command line arguments for simple-vpn
|
||||
char* const command[] = {"simple-vpn", "client", vpnconfig, NULL};
|
||||
|
||||
fprintf(stderr, "Attempting to start simple-vpn.\n");
|
||||
|
||||
int a;
|
||||
int b;
|
||||
pid_t pp = popen2(command, &a, &b);
|
||||
if(pp < 0){
|
||||
fprintf(stderr, "Could not start simple-vpn.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
vpn_process = pp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void stop_vpn_process() {
|
||||
if(vpn_process < 0) return;
|
||||
fprintf(stderr, "Stopping simple-vpn (%d)\n", vpn_process);
|
||||
|
||||
kill(vpn_process, SIGTERM);
|
||||
waitpid(vpn_process,NULL,0);
|
||||
vpn_process = -1;
|
||||
}
|
||||
|
||||
int start_daemon_server(void *thr_data) {
|
||||
(void)thr_data;
|
||||
|
||||
// Just too lazy to keep all this shit here...
|
||||
// functions are better
|
||||
int sfd = unix_socket_server_start(SV_DAEMON_SOCK_PATH);
|
||||
|
||||
ssize_t numRead;
|
||||
char buf[BUF_SIZE];
|
||||
int MAX_PEERS_LEN = 1000;
|
||||
int total = 0;
|
||||
char msg[MAX_PEERS_LEN];
|
||||
|
||||
// Client connections are handled iteratively
|
||||
for(;;) {
|
||||
int cfd = accept(sfd, NULL, NULL);
|
||||
|
||||
// Read at most BUF_SIZE bytes from the socket into buf.
|
||||
total = 0;
|
||||
strcpy(msg, "");
|
||||
strcpy(buf, "");
|
||||
|
||||
while ((numRead = read(cfd, buf, BUF_SIZE)) > 0) {
|
||||
// Then, write those bytes from buf into STDOUT.
|
||||
if(total > MAX_PEERS_LEN-1) break;
|
||||
total+=numRead;
|
||||
|
||||
incoming_request(buf);
|
||||
|
||||
if (write(STDOUT_FILENO, buf, numRead) != numRead) {
|
||||
fprintf(stderr,"Partial/failed write");
|
||||
return 0;
|
||||
}
|
||||
// Append buf to msg then clear buf
|
||||
strcat(msg, buf);
|
||||
strcpy(buf, "");
|
||||
msg[total]=0;
|
||||
}
|
||||
|
||||
if (numRead == -1) {
|
||||
fprintf(stderr,"Failed to read");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (close(cfd) == -1) {
|
||||
fprintf(stderr,"Failed to close");
|
||||
return 0;
|
||||
}
|
||||
incoming_request(msg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -157,25 +258,39 @@ int start_peers_server(void *thr_data) {
|
||||
int sfd = unix_socket_server_start(SV_RPEERS_SOCK_PATH);
|
||||
|
||||
ssize_t numRead;
|
||||
int MAX_PEERS_LEN = 1000;
|
||||
char msg[MAX_PEERS_LEN];
|
||||
char buf[BUF_SIZE];
|
||||
int total = 0;
|
||||
|
||||
for(;;) {
|
||||
int cfd = accept(sfd, NULL, NULL);
|
||||
|
||||
int MAX_PEERS_LEN = 1000;
|
||||
int total = 0;
|
||||
char peers[MAX_PEERS_LEN];
|
||||
strcpy(peers, "");
|
||||
strcpy(msg, "");
|
||||
strcpy(buf, "");
|
||||
total = 0;
|
||||
|
||||
while ((numRead = read(cfd, buf, BUF_SIZE)) > 0) {
|
||||
if(total > MAX_PEERS_LEN-1) break;
|
||||
total+=numRead;
|
||||
strcat(peers, buf);
|
||||
peers[MAX_PEERS_LEN-1]=0;
|
||||
strcat(msg, buf);
|
||||
msg[MAX_PEERS_LEN-1]=0;
|
||||
}
|
||||
|
||||
incoming_peers(buf);
|
||||
incoming_peers(msg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void send_to_client(char *buf, ssize_t n) {
|
||||
int sfd = unix_socket_client_start(SV_CLIENT_SOCK_PATH);
|
||||
if(sfd==-1) {
|
||||
return;
|
||||
}
|
||||
|
||||
write(sfd, buf, n);
|
||||
close(sfd);
|
||||
|
||||
fprintf(stderr, "Closed connection to socket\n");
|
||||
}
|
||||
|
36
src/impl/daemon/popen2.c
Normal file
36
src/impl/daemon/popen2.c
Normal file
@ -0,0 +1,36 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define READ 0
|
||||
#define WRITE 1
|
||||
|
||||
// omg thanks
|
||||
// https://stackoverflow.com/a/12788169/10719432
|
||||
pid_t popen2(char* const *command, int *infp, int *outfp) {
|
||||
int p_stdin[2], p_stdout[2];
|
||||
pid_t pid;
|
||||
|
||||
if (pipe(p_stdin) != 0 || pipe(p_stdout) != 0) return -1;
|
||||
|
||||
pid = fork();
|
||||
|
||||
if (pid < 0) return pid;
|
||||
else if (pid == 0) {
|
||||
close(p_stdin[WRITE]);
|
||||
dup2(p_stdin[READ], READ);
|
||||
close(p_stdout[READ]);
|
||||
dup2(p_stdout[WRITE], WRITE);
|
||||
|
||||
execvp(command[0], command);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (infp == NULL) close(p_stdin[WRITE]);
|
||||
else *infp = p_stdin[WRITE];
|
||||
|
||||
if (outfp == NULL) close(p_stdout[READ]);
|
||||
else *outfp = p_stdout[READ];
|
||||
|
||||
return pid;
|
||||
}
|
@ -1,16 +1,39 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <libappindicator/app-indicator.h>
|
||||
#include <stdbool.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <pango-1.0/pango/pango-font.h>
|
||||
|
||||
#include "states.h"
|
||||
#include "statusicon.h"
|
||||
#include "magic_code.h"
|
||||
#include "melon_vpn_about.h"
|
||||
|
||||
GtkApplication *app;
|
||||
GdkPixbuf *appicon;
|
||||
char *statusiconoff;
|
||||
char *statusiconon;
|
||||
States currentstate;
|
||||
char *currentpeers;
|
||||
bool restarttoggle = false;
|
||||
bool cli_is_debug = false;
|
||||
|
||||
// Window shit
|
||||
GtkWidget *window;
|
||||
GtkWidget *box;
|
||||
GtkWidget *button;
|
||||
GtkWidget *button2;
|
||||
GtkWidget *button3;
|
||||
GtkWidget *button4;
|
||||
GtkWidget *statustxt;
|
||||
|
||||
// Callback functions for the code in the CLI
|
||||
int (*cli_start_vpn)();
|
||||
int (*cli_stop_vpn)();
|
||||
int (*cli_refresh_vpn)();
|
||||
int (*cli_restart_conf_vpn)(bool);
|
||||
|
||||
void update_state(States state) {
|
||||
currentstate = state;
|
||||
@ -25,25 +48,41 @@ void update_state(States state) {
|
||||
|
||||
void open_about(GtkApplication* app) {
|
||||
GtkWidget *about = gtk_about_dialog_new();
|
||||
gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(about),"Melon VPN");
|
||||
gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(about),about_name);
|
||||
gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about),"v1.0.0");
|
||||
gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(about),"Copyright OnPointCoding");
|
||||
gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(about),about_copyright);
|
||||
gtk_about_dialog_set_license_type(GTK_ABOUT_DIALOG(about),GTK_LICENSE_UNKNOWN);
|
||||
gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(about),"https://software.onpointcoding.net");
|
||||
gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(about),"OnPointCoding.net");
|
||||
gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(about),about_url);
|
||||
gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(about),about_website);
|
||||
gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(about),appicon);
|
||||
|
||||
const char *authors[2] = {"MrMelon54",NULL};
|
||||
const char *authors[2] = {about_author,NULL};
|
||||
gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(about),authors);
|
||||
|
||||
const char *artists[2] = {"MrMelon54",NULL};
|
||||
const char *artists[2] = {about_artist,NULL};
|
||||
gtk_about_dialog_set_artists(GTK_ABOUT_DIALOG(about),artists);
|
||||
|
||||
gtk_widget_show_all(about);
|
||||
}
|
||||
|
||||
void open_paint_btn(GtkButton *button) {
|
||||
update_state((currentstate + 1) % 3);
|
||||
void open_start_btn(GtkButton *button) {
|
||||
(*cli_start_vpn)();
|
||||
}
|
||||
|
||||
void open_stop_btn(GtkButton *button) {
|
||||
(*cli_stop_vpn)();
|
||||
}
|
||||
|
||||
void open_restart_toggle_btn(GtkButton *button) {
|
||||
restarttoggle = !restarttoggle;
|
||||
(*cli_restart_conf_vpn)(restarttoggle);
|
||||
update_restart_toggle_btn_label();
|
||||
}
|
||||
|
||||
void update_restart_toggle_btn_label() {
|
||||
char restartbtnlabel[] = "Restart [ ]";
|
||||
if(restarttoggle) restartbtnlabel[9] = '#';
|
||||
gtk_button_set_label(GTK_BUTTON(button3), restartbtnlabel);
|
||||
}
|
||||
|
||||
void open_about_btn(GtkButton *button) {
|
||||
@ -51,14 +90,9 @@ void open_about_btn(GtkButton *button) {
|
||||
}
|
||||
|
||||
void activate(GtkApplication* app) {
|
||||
GtkWidget *window;
|
||||
GtkWidget *box;
|
||||
GtkWidget *button;
|
||||
GtkWidget *button2;
|
||||
|
||||
window = gtk_application_window_new(app);
|
||||
gtk_window_set_title(GTK_WINDOW(window),"Melon VPN");
|
||||
gtk_window_set_default_size(GTK_WINDOW(window),400,400);
|
||||
gtk_window_set_default_size(GTK_WINDOW(window),300,300);
|
||||
|
||||
// Setup status icon now window is available
|
||||
status_icon_create(window,statusiconoff,statusiconon);
|
||||
@ -66,19 +100,41 @@ void activate(GtkApplication* app) {
|
||||
|
||||
gtk_container_set_border_width(GTK_CONTAINER(window),8);
|
||||
|
||||
button = gtk_button_new_with_label("Start");
|
||||
g_signal_connect(button,"clicked",G_CALLBACK(open_paint_btn),NULL);
|
||||
PangoFontDescription *font = pango_font_description_new();
|
||||
pango_font_description_set_family(font,"Monospace");
|
||||
|
||||
button2 = gtk_button_new_with_label("About");
|
||||
g_signal_connect(button2,"clicked",G_CALLBACK(open_about_btn),NULL);
|
||||
button = gtk_button_new_with_label("Start");
|
||||
gtk_widget_modify_font(GTK_WIDGET(button), font);
|
||||
g_signal_connect(button,"clicked",G_CALLBACK(open_start_btn),NULL);
|
||||
|
||||
button2 = gtk_button_new_with_label("Stop");
|
||||
gtk_widget_modify_font(GTK_WIDGET(button2), font);
|
||||
g_signal_connect(button2,"clicked",G_CALLBACK(open_stop_btn),NULL);
|
||||
|
||||
button3 = gtk_button_new_with_label("Restart [ ]");
|
||||
gtk_widget_modify_font(GTK_WIDGET(button3), font);
|
||||
g_signal_connect(button3,"clicked",G_CALLBACK(open_restart_toggle_btn),NULL);
|
||||
|
||||
button4 = gtk_button_new_with_label("About");
|
||||
gtk_widget_modify_font(GTK_WIDGET(button4), font);
|
||||
g_signal_connect(button4,"clicked",G_CALLBACK(open_about_btn),NULL);
|
||||
|
||||
statustxt = gtk_label_new("");
|
||||
gtk_widget_modify_font(GTK_WIDGET(statustxt), font);
|
||||
|
||||
box = gtk_fixed_new();
|
||||
|
||||
gtk_container_add(GTK_CONTAINER(window),box);
|
||||
gtk_fixed_put(GTK_FIXED(box),button,5,5);
|
||||
gtk_fixed_put(GTK_FIXED(box),button2,100,60);
|
||||
gtk_fixed_put(GTK_FIXED(box),button,10,40);
|
||||
gtk_fixed_put(GTK_FIXED(box),button2,100,40);
|
||||
gtk_fixed_put(GTK_FIXED(box),button3,190,40);
|
||||
gtk_fixed_put(GTK_FIXED(box),button4,190,5);
|
||||
gtk_fixed_put(GTK_FIXED(box),statustxt,10,10);
|
||||
|
||||
gtk_widget_show_all(window);
|
||||
|
||||
// Refresh data when loading the GUI
|
||||
(*cli_refresh_vpn)();
|
||||
}
|
||||
|
||||
void get_magic_code(int *a, int *b) {
|
||||
@ -86,39 +142,69 @@ void get_magic_code(int *a, int *b) {
|
||||
*b = MAGIC_CODE_B;
|
||||
}
|
||||
|
||||
int run_gui(int argc, char **argv) {
|
||||
int run_gui(int argc, char **argv, bool is_debug, int (*start_vpn)(), int (*stop_vpn)(), int (*restart_conf_vpn)(bool), int (*refresh_vpn)()) {
|
||||
int status;
|
||||
|
||||
cli_is_debug = is_debug;
|
||||
cli_start_vpn = start_vpn;
|
||||
cli_stop_vpn = stop_vpn;
|
||||
cli_refresh_vpn = refresh_vpn;
|
||||
cli_restart_conf_vpn = restart_conf_vpn;
|
||||
|
||||
statusiconoff = "";
|
||||
statusiconon = "";
|
||||
|
||||
char cwd[PATH_MAX];
|
||||
if (getcwd(cwd, sizeof(cwd)) == NULL) {
|
||||
fprintf(stderr, "Failed to get current directory\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cwdlen = strlen(cwd);
|
||||
|
||||
char officonname[] = "/statusmelonoff.png";
|
||||
int officonl = cwdlen+strlen(officonname)+1;
|
||||
char officonpath[officonl];
|
||||
strcpy(officonpath, cwd);
|
||||
officonpath[cwdlen] = 0;
|
||||
strcat(officonpath, officonname);
|
||||
officonpath[officonl-1] = 0;
|
||||
|
||||
char oniconname[] = "/statusmelonon.png";
|
||||
int oniconl = cwdlen+strlen(oniconname)+1;
|
||||
char oniconpath[oniconl];
|
||||
strcpy(oniconpath, cwd);
|
||||
oniconpath[cwdlen] = 0;
|
||||
strcat(oniconpath, oniconname);
|
||||
oniconpath[oniconl-1] = 0;
|
||||
|
||||
if(access("melonvpn.png",R_OK) == 0) {
|
||||
appicon = gdk_pixbuf_new_from_file("melonvpn.png",NULL);
|
||||
} else if(access("/usr/lib/melonvpn/melonvpn.png",R_OK) == 0) {
|
||||
appicon = gdk_pixbuf_new_from_file("/usr/lib/melonvpn/melonvpn.png",NULL);
|
||||
}
|
||||
|
||||
if(access("/usr/lib/melonvpn/statusmelonoff.png",R_OK) == 0) {
|
||||
if(access(officonpath,R_OK) == 0) {
|
||||
statusiconoff = officonpath;
|
||||
} else if(access("/usr/lib/melonvpn/statusmelonoff.png",R_OK) == 0) {
|
||||
statusiconoff = "/usr/lib/melonvpn/statusmelonoff.png";
|
||||
} else {
|
||||
fprintf(stderr,"WARN: Unable to find statusmelonoff.png\n");
|
||||
}
|
||||
|
||||
if(access("/usr/lib/melonvpn/statusmelonon.png",R_OK) == 0) {
|
||||
if(access(oniconpath,R_OK) == 0) {
|
||||
statusiconon = oniconpath;
|
||||
} else if(access("/usr/lib/melonvpn/statusmelonon.png",R_OK) == 0) {
|
||||
statusiconon = "/usr/lib/melonvpn/statusmelonon.png";
|
||||
} else {
|
||||
fprintf(stderr,"WARN: Unable to find statusmelonon.png\n");
|
||||
}
|
||||
|
||||
if(appicon == NULL) {
|
||||
fprintf(stderr,"ERROR: Failed to load program logo\n");
|
||||
return 1;
|
||||
}
|
||||
if(statusiconoff == NULL) {
|
||||
if(strcmp(statusiconoff,"")==0) {
|
||||
fprintf(stderr,"ERROR: Failed to load status off icon\n");
|
||||
return 1;
|
||||
}
|
||||
if(statusiconon == NULL) {
|
||||
if(strcmp(statusiconon,"")==0) {
|
||||
fprintf(stderr,"ERROR: Failed to load status on icon\n");
|
||||
return 1;
|
||||
}
|
||||
@ -132,3 +218,21 @@ int run_gui(int argc, char **argv) {
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void mod_trigger_state(States state) {
|
||||
currentstate = state;
|
||||
|
||||
char *statelbl = string_state_upper(state);
|
||||
fprintf(stderr, "hi: %s\n", statelbl);
|
||||
|
||||
gtk_label_set_text(GTK_LABEL(statustxt), statelbl);
|
||||
}
|
||||
|
||||
void mod_trigger_peers(char *peers) {
|
||||
strcpy(currentpeers, peers);
|
||||
}
|
||||
|
||||
void mod_trigger_isrestart(bool isrestart) {
|
||||
restarttoggle = isrestart;
|
||||
update_restart_toggle_btn_label();
|
||||
}
|
||||
|
@ -86,8 +86,7 @@ void send_to_daemon(char *buf, ssize_t n) {
|
||||
}
|
||||
|
||||
write(sfd, buf, n);
|
||||
close(sfd);
|
||||
|
||||
// Closes our socket; server sees EOF.
|
||||
exit(EXIT_SUCCESS);
|
||||
fprintf(stderr, "Closed connection to socket");
|
||||
}
|
||||
|
24
src/impl/shared/states.c
Normal file
24
src/impl/shared/states.c
Normal file
@ -0,0 +1,24 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "states.h"
|
||||
|
||||
char *string_state(States state) {
|
||||
if(state == CONNECTED) return "connected";
|
||||
else if(state == DISCONNECTED) return "disconnected";
|
||||
else if(state == RESTARTING) return "restarting";
|
||||
else return "unknown";
|
||||
}
|
||||
|
||||
char *string_state_upper(States state) {
|
||||
if(state == CONNECTED) return "Connected";
|
||||
else if(state == DISCONNECTED) return "Disconnected";
|
||||
else if(state == RESTARTING) return "Restarting";
|
||||
else return "Unknown";
|
||||
}
|
||||
|
||||
States enum_state(char *state) {
|
||||
if(strcmp(state,"connected")==0) return CONNECTED;
|
||||
else if(strcmp(state,"disconnected")==0) return DISCONNECTED;
|
||||
else if(strcmp(state,"restarting")==0) return RESTARTING;
|
||||
else return UNKNOWN;
|
||||
}
|
@ -14,7 +14,7 @@ int unix_socket_client_start(char *sock_path) {
|
||||
|
||||
// Make sure socket's file descriptor is legit.
|
||||
if (sfd == -1) {
|
||||
fprintf(stderr,"ERROR: socket is not legit");
|
||||
fprintf(stderr,"ERROR: socket is not legit\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ int unix_socket_client_start(char *sock_path) {
|
||||
// Connects the active socket referred to be sfd to the listening socket
|
||||
// whose address is specified by addr.
|
||||
if (connect(sfd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)) == -1) {
|
||||
fprintf(stderr,"Failed to connect");
|
||||
fprintf(stderr,"Failed to connect\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -15,20 +15,20 @@ int unix_socket_server_start(char *sock_path) {
|
||||
|
||||
// Make sure socket's file descriptor is legit.
|
||||
if (sfd == -1) {
|
||||
fprintf(stderr,"ERROR: socket is not legit");
|
||||
fprintf(stderr,"ERROR: socket is not legit\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Make sure the address we're planning to use isn't too long.
|
||||
if (strlen(sock_path) > sizeof(addr.sun_path) - 1) {
|
||||
fprintf(stderr,"Server socket path too long: %s",sock_path);
|
||||
fprintf(stderr,"Server socket path too long: %s\n",sock_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Delete any file that already exists at the address. Make sure the deletion
|
||||
// succeeds. If the error is just that the file/directory doesn't exist, it's fine.
|
||||
if (remove(sock_path) == -1 && errno != ENOENT) {
|
||||
fprintf(stderr,"remove-%s",sock_path);
|
||||
fprintf(stderr,"remove-%s\n",sock_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ int unix_socket_server_start(char *sock_path) {
|
||||
// Bind the socket to the address. Note that we're binding the server socket
|
||||
// to a well-known address so that clients know where to connect.
|
||||
if (bind(sfd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)) == -1) {
|
||||
fprintf(stderr,"Failed to bind");
|
||||
fprintf(stderr,"Failed to bind\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ int unix_socket_server_start(char *sock_path) {
|
||||
// listen cannot be called on a connected socket (a socket on which a connect()
|
||||
// has been succesfully performed or a socket returned by a call to accept()).
|
||||
if (listen(sfd, BACKLOG) == -1) {
|
||||
fprintf(stderr,"Failed to listen");
|
||||
fprintf(stderr,"Failed to listen\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
8
src/intf/melon_vpn_about.h
Normal file
8
src/intf/melon_vpn_about.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#define about_name "Melon VPN"
|
||||
#define about_copyright "Copyright OnPointCoding"
|
||||
#define about_url "https://software.onpointcoding.net/melonvpn"
|
||||
#define about_website "OnPointCoding.net"
|
||||
#define about_author "MrMelon54"
|
||||
#define about_artist "MrMelon54"
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#define SV_DAEMON_SOCK_PATH "/tmp/melonvpndaemon.sock"
|
||||
#define SV_RPEERS_SOCK_PATH "/tmp/melonvpnrefreshpeers.sock"
|
||||
#define SV_CLIENT_SOCK_PATH "/tmp/melonvpn.sock"
|
||||
#define SV_WRAPPER_SOCK_PATH "/run/melonvpn"
|
||||
#define SV_DAEMON_SOCK_PATH "/run/melonvpn/melonvpndaemon.sock"
|
||||
#define SV_RPEERS_SOCK_PATH "/run/melonvpn/melonvpnrefreshpeers.sock"
|
||||
#define SV_CLIENT_SOCK_PATH "/run/melonvpn/melonvpnclient.sock"
|
||||
|
@ -1,4 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
int open_gui(int argc, char **argv, bool is_debug);
|
||||
#include "states.h"
|
||||
|
||||
int open_gui(int argc, char **argv, bool is_debug, int (*start_vpn)(), int (*stop_vpn)(), int (*restart_conf_vpn)(bool), int (*refresh_vpn)());
|
||||
|
||||
int gui_trigger_state(States state);
|
||||
int gui_trigger_peers(char *peers);
|
||||
int gui_trigger_isrestart(bool isrestart);
|
||||
|
5
src/intf/popen2.h
Normal file
5
src/intf/popen2.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
pid_t popen2(char* const *command, int *infp, int *outfp);
|
@ -1,7 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
typedef enum {
|
||||
UNKNOWN,
|
||||
CONNECTED,
|
||||
DISCONNECTED,
|
||||
RESTARTING
|
||||
} States;
|
||||
|
||||
char *string_state(States state);
|
||||
|
||||
char *string_state_upper(States state);
|
||||
|
||||
States enum_state(char *state);
|
||||
|
Loading…
Reference in New Issue
Block a user