-
Notifications
You must be signed in to change notification settings - Fork 0
/
plugin_architecture_interface.cpp
134 lines (112 loc) · 2.94 KB
/
plugin_architecture_interface.cpp
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include "plugin_architecture_interface.h"
#include "event_c_api.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/time.h>
#include <exception>
#include <unistd.h>
#include "slave_thread.h"
#include "udsrf.h"
#include <signal.h>
#include <iostream>
#include <set>
#include "request.h"
#include <fstream>
#include <linux/capability.h>
extern "C" void die(const char* p_text);
extern "C" int vsf_sysutil_fork();
extern "C" void handle_slave_signal();
static int slave_socket_fast = 0;
static int slave_socket_slow = 0;
int slave_pid = -1;
struct sockaddr_un fast_un;
struct sockaddr_un slow_un;
void handle_unexpected_exception() {
handle_slave_signal();
die("Unexpected exception\n");
}
void handleSignal(int a) {
handle_slave_signal();
char erc[100];
sprintf(erc,"got a signal (%s) :(\n", strsignal(a));
die(erc);
}
C_COMPATIBLE_FUNCTION void vsf_plugin_architecture_start(struct vsf_session* p_sess) {
static bool started = false;
if (started)
{
return;
}
std::set_unexpected(handle_unexpected_exception);
fast_un.sun_family = PF_UNIX;
fast_un.sun_path[0] = 0;
slow_un.sun_family = PF_UNIX;
slow_un.sun_path[0] = 0;
srandom(time(0));
sprintf(fast_un.sun_path + 1, "vsftp_comm_fast%ld", random());
sprintf(slow_un.sun_path + 1, "vsftp_comm_slow%ld", random());
int slaveno;
// create slave
switch(slaveno = vsf_sysutil_fork()) {
case -1:
die("fork did not succeed");
break;
case 0:
{
pid_t parent_pid = getppid();
slave_thread_start(slow_un, fast_un); //should never return
printf("slave thread died\n");
if (parent_pid != 1)
{
kill(parent_pid, SIGUSR2);
}
printf("killing parent\n");
exit(0);
}
break;
default:
slave_pid = slaveno;
sleep(1);
for(int i = 0; i < 3; ++i) {
if(reconnect_after_fork()) {
printf("trying to connect to plugin arch thread\n");
sleep(1);
}
else {
printf("connect ok\n");
break;
}
}
if (slave_socket_fast == 0 || slave_socket_slow == 0)
{
die("connection to plugin architecture thread failed");
}
signal(SIGINT, handleSignal);
signal(SIGUSR2, handleSignal);
break;
}
}
C_COMPATIBLE_FUNCTION int plugin_architecture_get_slave_socket_fast() {
return slave_socket_fast;
}
C_COMPATIBLE_FUNCTION int plugin_architecture_get_slave_socket_slow() {
return slave_socket_slow;
}
C_COMPATIBLE_FUNCTION int reconnect_after_fork() {
slave_socket_fast = socket(PF_UNIX, SOCK_SEQPACKET, 0);
slave_socket_slow = socket(PF_UNIX, SOCK_SEQPACKET, 0);
if(connect(slave_socket_fast, (struct sockaddr*)&fast_un, sizeof(fast_un))){
goto failed;
}
if(connect(slave_socket_slow, (struct sockaddr*)&slow_un, sizeof(slow_un))){
goto failed;
}
return 0;
failed:
close(slave_socket_fast);
close(slave_socket_slow);
slave_socket_fast = 0;
slave_socket_slow = 0;
return -1;
}