Finish building daemon, refresh peers, cli and gui

This commit is contained in:
Melon 2021-04-29 17:31:50 +01:00
parent b6b7fcecd9
commit baf7d64cab
15 changed files with 680 additions and 97 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
dist/
package/

View File

@ -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("-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);
}

View File

@ -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;
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;
}

View File

@ -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,27 +23,53 @@ 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();
printf("VPN server: %s\n", vpnserver);
printf("Device name: %s\n", devicename);
printf("Restart VPN: %s\n", restartvpn?"true":"false");
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 (;;) {
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
View 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;
}

View File

@ -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();
}

View File

@ -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
View 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;
}

View File

@ -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;
}

View File

@ -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;
}

View 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"

View File

@ -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"

View File

@ -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
View File

@ -0,0 +1,5 @@
#pragma once
#include <unistd.h>
pid_t popen2(char* const *command, int *infp, int *outfp);

View File

@ -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);