summaryrefslogtreecommitdiff
path: root/other/bootstrap_daemon
diff options
context:
space:
mode:
authormannol <eniz_vukovic@hotmail.com>2014-02-23 23:24:07 +0100
committermannol <eniz_vukovic@hotmail.com>2014-02-23 23:24:07 +0100
commitcf8a090cdeeb2630730203144001f1357b25ee01 (patch)
treeac52dcc5d043248cd719004d4eaffde64a65e3d3 /other/bootstrap_daemon
parent4888d916d037e371c88d39951f24f6ef4219c7cc (diff)
parentf219fb4ac1bf60eea3117df4aa8615cd07738a69 (diff)
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'other/bootstrap_daemon')
-rw-r--r--other/bootstrap_daemon/Makefile.inc27
-rw-r--r--other/bootstrap_daemon/README.md62
-rw-r--r--other/bootstrap_daemon/conf42
-rw-r--r--other/bootstrap_daemon/tox_bootstrap_daemon.c460
-rw-r--r--other/bootstrap_daemon/tox_bootstrap_daemon.sh110
5 files changed, 701 insertions, 0 deletions
diff --git a/other/bootstrap_daemon/Makefile.inc b/other/bootstrap_daemon/Makefile.inc
new file mode 100644
index 00000000..b75d935f
--- /dev/null
+++ b/other/bootstrap_daemon/Makefile.inc
@@ -0,0 +1,27 @@
1if BUILD_DHT_BOOTSTRAP_DAEMON
2
3noinst_PROGRAMS += tox_bootstrap_daemon
4
5tox_bootstrap_daemon_SOURCES = \
6 ../other/bootstrap_daemon/tox_bootstrap_daemon.c
7
8tox_bootstrap_daemon_CFLAGS = \
9 -I$(top_srcdir)/other/bootstrap_daemon \
10 $(LIBSODIUM_CFLAGS) \
11 $(NACL_CFLAGS) \
12 $(LIBCONFIG_CFLAGS)
13
14tox_bootstrap_daemon_LDADD = \
15 $(LIBSODIUM_LDFLAGS) \
16 $(NACL_LDFLAGS) \
17 libtoxcore.la \
18 $(LIBCONFIG_LIBS) \
19 $(LIBSODIUM_LIBS) \
20 $(NACL_LIBS)
21
22endif
23
24EXTRA_DIST += \
25 $(top_srcdir)/other/bootstrap_daemon/conf \
26 $(top_srcdir)/other/bootstrap_daemon/tox_bootstrap_daemon.sh
27 \ No newline at end of file
diff --git a/other/bootstrap_daemon/README.md b/other/bootstrap_daemon/README.md
new file mode 100644
index 00000000..53a25cdb
--- /dev/null
+++ b/other/bootstrap_daemon/README.md
@@ -0,0 +1,62 @@
1##Instructions for Debian
2
3The following commands are to be executed as root:
4
51. In `tox_bootstrap_daemon.sh` file change:
6 - `CFG` to where your config file (`conf`) will be; read rights required
7 - `DAEMON` to point to the executable
8 - `PIDFILE` to point to a pid file daemon would have rights to create
9
102. Go over everything in `conf`. Make sure `pid_file_path` matches `PIDFILE` from `tox_bootstrap_daemon.sh`
11
123. Execute:
13```
14mv tox_bootstrap_daemon.sh /etc/init.d/tox_bootstrap_daemon
15```
16*(note that we removed `.sh` ending)*
17
184. Give the right permissions to this file:
19```
20chmod 755 /etc/init.d/tox_bootstrap_daemon
21```
22
235. Execute:
24```
25update-rc.d tox_bootstrap_daemon defaults
26```
27
286. Start the service:
29```
30service tox_bootstrap_daemon start
31```
32
337. Verify that the service is running:
34```
35service tox_bootstrap_daemon status
36```
37
38--
39
40You can see daemon's log with
41```
42grep "tox_bootstrap_daemon" /var/log/syslog
43```
44
45**Note that system log is where you find your public key**
46
47--
48
49###Troubleshooting:
50
511. Check the log for errors with
52```
53grep "tox_bootstrap_daemon" /var/log/syslog
54```
55
562. Check that paths in the beginning of `/etc/init.d/tox_bootstrap_daemon` are valid
57
583. Make sure that `PIDFILE` from `/etc/init.d/tox_bootstrap_daemon` matches with the `pid_file_path` from `conf`
59
604. Make sure you have write permission to keys and pid files
61
625. Make sure you have read permission for config file \ No newline at end of file
diff --git a/other/bootstrap_daemon/conf b/other/bootstrap_daemon/conf
new file mode 100644
index 00000000..28e638c1
--- /dev/null
+++ b/other/bootstrap_daemon/conf
@@ -0,0 +1,42 @@
1// ProjectTox dht bootstrap node daemon configuration file.
2
3// Listening port.
4port = 33445
5
6// The key file is like a password, so keep it where no one can read it.
7// The daemon should have permission to read/write to it.
8// Remember to replace the provided example with your own path.
9keys_file_path = "/home/tom/.tox_bootstrap_daemon/keys"
10
11// The PID file written to by daemon.
12// Make sure that the user who runs the daemon has permissions to write to the
13// PID file.
14// Remember to replace the provided example with your own path.
15pid_file_path = "/home/tom/.tox_bootstrap_daemon/pid"
16
17// Enable IPv6.
18enable_ipv6 = false
19
20// Automatically bootstrap with nodes on local area network.
21enable_lan_discovery = true
22
23// Any number of nodes the daemon will bootstrap itself from.
24// Remember to replace the provided example with your own node list.
25// There is a maintained list of bootstrap nodes on Tox's wiki, if you need it.
26// You may leave the list empty or remove "bootstrap_nodes" complitely,
27// in both cases this will be interpreted as if you don't want to bootstrap
28// from anyone.
29bootstrap_nodes = (
30 { // Node 1
31 // Any ipv4 or ipv6, depending if `enable_ipv6` is set or not, and also
32 // any US-ASCII domain name.
33 address = "198.46.136.167"
34 port = 33445
35 public_key = "728925473812C7AAC482BE7250BCCAD0B8CB9F737BF3D42ABD34459C1768F854"
36 },
37 { // Node 2
38 address = "example.org"
39 port = 33445
40 public_key = "8CD5A9BF0A6CE358BA36F7A653F99FA6B258FF756E490F52C1F98CC420F78858"
41 }
42)
diff --git a/other/bootstrap_daemon/tox_bootstrap_daemon.c b/other/bootstrap_daemon/tox_bootstrap_daemon.c
new file mode 100644
index 00000000..66f6436d
--- /dev/null
+++ b/other/bootstrap_daemon/tox_bootstrap_daemon.c
@@ -0,0 +1,460 @@
1/* tox_bootstrap_daemon.c
2 *
3 * Tox DHT bootstrap node daemon.
4 *
5 * Copyright (C) 2014 Tox project All Rights Reserved.
6 *
7 * This file is part of Tox.
8 *
9 * Tox is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * Tox is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <unistd.h>
27#include <syslog.h>
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <libconfig.h>
32#include <arpa/inet.h>
33#include <string.h>
34
35#ifdef HAVE_CONFIG_H
36#include "config.h"
37#endif
38
39#include "../../toxcore/DHT.h"
40#include "../../toxcore/friend_requests.h"
41#include "../../toxcore/LAN_discovery.h"
42
43#include "../../testing/misc_tools.c"
44
45#define DAEMON_NAME "tox_bootstrap_daemon"
46
47#define SLEEP_TIME_MILLISECONDS 30
48#define sleep usleep(1000*SLEEP_TIME_MILLISECONDS)
49
50#define DEFAULT_PID_FILE_PATH ".tox_bootstrap_daemon.pid"
51#define DEFAULT_KEYS_FILE_PATH ".tox_bootstrap_daemon.keys"
52#define DEFAULT_PORT 33445
53#define DEFAULT_ENABLE_IPV6 0 // 1 - true, 0 - false
54#define DEFAULT_ENABLE_LAN_DISCOVERY 1 // 1 - true, 0 - false
55
56
57// Uses the already existing key or creates one if it didn't exist
58//
59// retirns 1 on success
60// 0 on failure - no keys were read or stored
61
62int manage_keys(DHT *dht, char *keys_file_path)
63{
64 const uint32_t KEYS_SIZE = crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
65 uint8_t keys[KEYS_SIZE];
66 FILE *keys_file;
67
68 // Check if file exits, proceed to open and load keys
69 keys_file = fopen(keys_file_path, "r");
70
71 if (keys_file != NULL) {
72 size_t read_size = fread(keys, sizeof(uint8_t), KEYS_SIZE, keys_file);
73
74 if (read_size != KEYS_SIZE) {
75 return 0;
76 }
77
78 load_keys(dht->c, keys);
79 } else {
80 // Otherwise save new keys
81 new_keys(dht->c);
82 save_keys(dht->c, keys);
83
84 keys_file = fopen(keys_file_path, "w");
85
86 size_t write_size = fwrite(keys, sizeof(uint8_t), KEYS_SIZE, keys_file);
87
88 if (write_size != KEYS_SIZE) {
89 return 0;
90 }
91 }
92
93 fclose(keys_file);
94
95 // We want our DHT public key to be the same as our internal one since this is a bootstrap node
96 memcpy(dht->self_public_key, dht->c->self_public_key, crypto_box_PUBLICKEYBYTES);
97 memcpy(dht->self_secret_key, dht->c->self_secret_key, crypto_box_SECRETKEYBYTES);
98
99 return 1;
100}
101
102// Gets general config options
103//
104// Important: you are responsible for freeing `pid_file_path` and `keys_file_path`
105//
106// returns 1 on success
107// 0 on failure, doesn't modify any data pointed by arguments
108
109int get_general_config(char *cfg_file_path, char **pid_file_path, char **keys_file_path, int *port, int *enable_ipv6,
110 int *enable_lan_discovery)
111{
112 config_t cfg;
113
114 const char *NAME_PORT = "port";
115 const char *NAME_PID_FILE_PATH = "pid_file_path";
116 const char *NAME_KEYS_FILE_PATH = "keys_file_path";
117 const char *NAME_ENABLE_IPV6 = "enable_ipv6";
118 const char *NAME_ENABLE_LAN_DISCOVERY = "enable_lan_discovery";
119
120 config_init(&cfg);
121
122 // Read the file. If there is an error, report it and exit.
123 if (config_read_file(&cfg, cfg_file_path) == CONFIG_FALSE) {
124 syslog(LOG_ERR, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg));
125 config_destroy(&cfg);
126 return 0;
127 }
128
129 // Get port
130 if (config_lookup_int(&cfg, NAME_PORT, port) == CONFIG_FALSE) {
131 syslog(LOG_WARNING, "No '%s' setting in configuration file.\n", NAME_PORT);
132 syslog(LOG_WARNING, "Using default '%s': %d\n", NAME_PORT, DEFAULT_PORT);
133 *port = DEFAULT_PORT;
134 }
135
136 // Get PID file location
137 const char *tmp_pid_file;
138
139 if (config_lookup_string(&cfg, NAME_PID_FILE_PATH, &tmp_pid_file) == CONFIG_FALSE) {
140 syslog(LOG_WARNING, "No '%s' setting in configuration file.\n", NAME_PID_FILE_PATH);
141 syslog(LOG_WARNING, "Using default '%s': %s\n", NAME_PID_FILE_PATH, DEFAULT_PID_FILE_PATH);
142 tmp_pid_file = DEFAULT_PID_FILE_PATH;
143 }
144
145 *pid_file_path = malloc(strlen(tmp_pid_file) + 1);
146 strcpy(*pid_file_path, tmp_pid_file);
147
148 // Get keys file location
149 const char *tmp_keys_file;
150
151 if (config_lookup_string(&cfg, NAME_KEYS_FILE_PATH, &tmp_keys_file) == CONFIG_FALSE) {
152 syslog(LOG_WARNING, "No '%s' setting in configuration file.\n", NAME_KEYS_FILE_PATH);
153 syslog(LOG_WARNING, "Using default '%s': %s\n", NAME_KEYS_FILE_PATH, DEFAULT_KEYS_FILE_PATH);
154 tmp_keys_file = DEFAULT_KEYS_FILE_PATH;
155 }
156
157 *keys_file_path = malloc(strlen(tmp_keys_file) + 1);
158 strcpy(*keys_file_path, tmp_keys_file);
159
160 // Get IPv6 option
161 if (config_lookup_bool(&cfg, NAME_ENABLE_IPV6, enable_ipv6) == CONFIG_FALSE) {
162 syslog(LOG_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_IPV6);
163 syslog(LOG_WARNING, "Using default '%s': %s\n", NAME_ENABLE_IPV6, DEFAULT_ENABLE_IPV6 ? "true" : "false");
164 *enable_ipv6 = DEFAULT_ENABLE_IPV6;
165 }
166
167 // Get LAN discovery option
168 if (config_lookup_bool(&cfg, NAME_ENABLE_LAN_DISCOVERY, enable_lan_discovery) == CONFIG_FALSE) {
169 syslog(LOG_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_LAN_DISCOVERY);
170 syslog(LOG_WARNING, "Using default '%s': %s\n", NAME_ENABLE_LAN_DISCOVERY,
171 DEFAULT_ENABLE_LAN_DISCOVERY ? "true" : "false");
172 *enable_lan_discovery = DEFAULT_ENABLE_LAN_DISCOVERY;
173 }
174
175 config_destroy(&cfg);
176
177 syslog(LOG_DEBUG, "Successfully read:\n");
178 syslog(LOG_DEBUG, "'%s': %s\n", NAME_PID_FILE_PATH, *pid_file_path);
179 syslog(LOG_DEBUG, "'%s': %s\n", NAME_KEYS_FILE_PATH, *keys_file_path);
180 syslog(LOG_DEBUG, "'%s': %d\n", NAME_PORT, *port);
181 syslog(LOG_DEBUG, "'%s': %s\n", NAME_ENABLE_IPV6, *enable_ipv6 ? "true" : "false");
182 syslog(LOG_DEBUG, "'%s': %s\n", NAME_ENABLE_LAN_DISCOVERY, *enable_lan_discovery ? "true" : "false");
183
184 return 1;
185}
186
187// Bootstraps nodes listed in the config file
188//
189// returns 1 on success, some or no bootstrap nodes were added
190// 0 on failure, a error accured while parsing config file
191
192int bootstrap_from_config(char *cfg_file_path, DHT *dht, int enable_ipv6)
193{
194 const char *NAME_BOOTSTRAP_NODES = "bootstrap_nodes";
195
196 const char *NAME_PUBLIC_KEY = "public_key";
197 const char *NAME_PORT = "port";
198 const char *NAME_ADDRESS = "address";
199
200 config_t cfg;
201
202 config_init(&cfg);
203
204 if (config_read_file(&cfg, cfg_file_path) == CONFIG_FALSE) {
205 syslog(LOG_ERR, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg));
206 config_destroy(&cfg);
207 return 0;
208 }
209
210 config_setting_t *node_list = config_lookup(&cfg, NAME_BOOTSTRAP_NODES);
211
212 if (node_list == NULL) {
213 syslog(LOG_WARNING, "No '%s' setting in the configuration file. Skipping bootstrapping.\n", NAME_BOOTSTRAP_NODES);
214 config_destroy(&cfg);
215 return 1;
216 }
217
218 if (config_setting_length(node_list) == 0) {
219 syslog(LOG_WARNING, "No bootstrap nodes found. Skipping bootstrapping.\n");
220 config_destroy(&cfg);
221 return 1;
222 }
223
224 int bs_port;
225 const char *bs_address;
226 const char *bs_public_key;
227
228 config_setting_t *node;
229
230 int i = 0;
231
232 while (config_setting_length(node_list)) {
233
234 node = config_setting_get_elem(node_list, 0);
235
236 if (node == NULL) {
237 config_destroy(&cfg);
238 return 0;
239 }
240
241 // Check that all settings are present
242 if (config_setting_lookup_string(node, NAME_PUBLIC_KEY, &bs_public_key) == CONFIG_FALSE) {
243 syslog(LOG_WARNING, "Bootstrap node #%d: Couldn't find '%s' setting. Skipping the node.\n", i, NAME_PUBLIC_KEY);
244 goto next;
245 }
246
247 if (config_setting_lookup_int(node, NAME_PORT, &bs_port) == CONFIG_FALSE) {
248 syslog(LOG_WARNING, "Bootstrap node #%d: Couldn't find '%s' setting. Skipping the node.\n", i, NAME_PORT);
249 goto next;
250 }
251
252 if (config_setting_lookup_string(node, NAME_ADDRESS, &bs_address) == CONFIG_FALSE) {
253 syslog(LOG_WARNING, "Bootstrap node #%d: Couldn't find '%s' setting. Skipping the node.\n", i, NAME_ADDRESS);
254 goto next;
255 }
256
257 // Process settings
258 if (strlen(bs_public_key) != 64) {
259 syslog(LOG_WARNING, "Bootstrap node #%d: Invalid '%s': %s. Skipping the node.\n", i, NAME_PUBLIC_KEY,
260 bs_public_key);
261 goto next;
262 }
263
264 // not (1 <= port <= 65535)
265 if (bs_port < 1 || bs_port > 65535) {
266 syslog(LOG_WARNING, "Bootstrap node #%d: Invalid '%s': %d. Skipping the node.\n", i, NAME_PORT, bs_port);
267 goto next;
268 }
269
270 uint8_t *bs_public_key_bin = hex_string_to_bin((char *)bs_public_key);
271 const int address_resolved = DHT_bootstrap_from_address(dht, bs_address, enable_ipv6, htons(bs_port),
272 bs_public_key_bin);
273 free(bs_public_key_bin);
274
275 if (!address_resolved) {
276 syslog(LOG_WARNING, "Bootstrap node #%d: Invalid '%s': %s. Skipping the node.\n", i, NAME_ADDRESS, bs_address);
277 goto next;
278 }
279
280 syslog(LOG_DEBUG, "Successfully added bootstrap node #%d: %s:%d %s\n", i, bs_address, bs_port, bs_public_key);
281
282next:
283 // config_setting_lookup_string() allocates string inside and doesn't allow us to free it
284 // so in order to reuse `bs_public_key` and `bs_address` we have to remove the element
285 // which will cause libconfig to free allocated strings
286 config_setting_remove_elem(node_list, 0);
287 i++;
288 }
289
290 config_destroy(&cfg);
291
292 return 1;
293}
294
295// Prints public key
296
297void print_public_key(uint8_t *public_key)
298{
299 char buffer[64 + 1];
300 int index = 0;
301
302 int i;
303
304 for (i = 0; i < 32; i++) {
305 if (public_key[i] < 16) {
306 index += sprintf(buffer + index, "0");
307 }
308
309 index += sprintf(buffer + index, "%hhX", public_key[i]);
310 }
311
312 syslog(LOG_INFO, "Public Key: %s\n", buffer);
313
314 return;
315}
316
317int main(int argc, char *argv[])
318{
319 openlog(DAEMON_NAME, LOG_NOWAIT | LOG_PID, LOG_DAEMON);
320
321 if (argc < 2) {
322 syslog(LOG_ERR, "Please specify a path to a configuration file as the first argument. Exiting.\n");
323 return 1;
324 }
325
326 char *cfg_file_path = argv[1];
327 char *pid_file_path, *keys_file_path;
328 int port;
329 int enable_ipv6;
330 int enable_lan_discovery;
331
332 if (get_general_config(cfg_file_path, &pid_file_path, &keys_file_path, &port, &enable_ipv6, &enable_lan_discovery)) {
333 syslog(LOG_DEBUG, "General config read successfully\n");
334 } else {
335 syslog(LOG_ERR, "Couldn't read config file: %s. Exiting.\n", cfg_file_path);
336 return 1;
337 }
338
339 // not (1 <= port <= 65535)
340 if (port < 1 || port > 65535) {
341 syslog(LOG_ERR, "Invalid port: %d, must be 1 <= port <= 65535. Exiting.\n", port);
342 return 1;
343 }
344
345 // Check if the PID file exists
346 if (fopen(pid_file_path, "r")) {
347 syslog(LOG_ERR, "Another instance of the daemon is already running, PID file %s exists. Exiting.\n", pid_file_path);
348 return 1;
349 }
350
351 IP ip;
352 ip_init(&ip, enable_ipv6);
353
354 DHT *dht = new_DHT(new_net_crypto(new_networking(ip, port)));
355
356 if (dht == NULL) {
357 syslog(LOG_ERR, "Couldn't initialize Tox DHT instance. Exiting.\n");
358 return 1;
359 }
360
361 Onion *onion = new_onion(dht);
362 Onion_Announce *onion_a = new_onion_announce(dht);
363
364 if (!(onion && onion_a)) {
365 syslog(LOG_ERR, "Couldn't initialize Tox Onion. Exiting.\n");
366 return 1;
367 }
368
369 if (enable_lan_discovery) {
370 LANdiscovery_init(dht);
371 }
372
373 if (manage_keys(dht, keys_file_path)) {
374 syslog(LOG_DEBUG, "Keys are managed successfully\n");
375 } else {
376 syslog(LOG_ERR, "Couldn't read/write: %s. Exiting.\n", keys_file_path);
377 return 1;
378 }
379
380 if (bootstrap_from_config(cfg_file_path, dht, enable_ipv6)) {
381 syslog(LOG_DEBUG, "List of bootstrap nodes read successfully\n");
382 } else {
383 syslog(LOG_ERR, "Couldn't read list of bootstrap nodes in %s. Exiting.\n", cfg_file_path);
384 return 1;
385 }
386
387 print_public_key(dht->c->self_public_key);
388
389 // Write the PID file
390 FILE *pidf = fopen(pid_file_path, "w");
391
392 if (pidf == NULL) {
393 syslog(LOG_ERR, "Can't open the PID file for writing: %s. Exiting.\n", pid_file_path);
394 return 1;
395 }
396
397 free(pid_file_path);
398 free(keys_file_path);
399
400 // Fork off from the parent process
401 pid_t pid = fork();
402
403 if (pid < 0) {
404 fclose(pidf);
405 syslog(LOG_ERR, "Forking failed. Exiting.\n");
406 return 1;
407 }
408
409 if (pid > 0) {
410 fprintf(pidf, "%d\n", pid);
411 fclose(pidf);
412 syslog(LOG_DEBUG, "Forked successfully: PID: %d.\n", pid);
413 return 0;
414 }
415
416 // Change the file mode mask
417 umask(0);
418
419 // Create a new SID for the child process
420 if (setsid() < 0) {
421 syslog(LOG_ERR, "SID creation failure. Exiting.\n");
422 return 1;
423 }
424
425 // Change the current working directory
426 if ((chdir("/")) < 0) {
427 syslog(LOG_ERR, "Couldn't change working directory to '/'. Exiting.\n");
428 return 1;
429 }
430
431 // Go quiet
432 close(STDOUT_FILENO);
433 close(STDIN_FILENO);
434 close(STDERR_FILENO);
435
436 uint64_t last_LANdiscovery = 0;
437 uint16_t htons_port = htons(port);
438
439 int waiting_for_dht_connection = 1;
440
441 while (1) {
442 do_DHT(dht);
443
444 if (enable_lan_discovery && is_timeout(last_LANdiscovery, LAN_DISCOVERY_INTERVAL)) {
445 send_LANdiscovery(htons_port, dht);
446 last_LANdiscovery = unix_time();
447 }
448
449 networking_poll(dht->net);
450
451 if (waiting_for_dht_connection && DHT_isconnected(dht)) {
452 syslog(LOG_DEBUG, "Connected to other bootstrap node successfully.\n");
453 waiting_for_dht_connection = 0;
454 }
455
456 sleep;
457 }
458
459 return 1;
460}
diff --git a/other/bootstrap_daemon/tox_bootstrap_daemon.sh b/other/bootstrap_daemon/tox_bootstrap_daemon.sh
new file mode 100644
index 00000000..83d9a119
--- /dev/null
+++ b/other/bootstrap_daemon/tox_bootstrap_daemon.sh
@@ -0,0 +1,110 @@
1#! /bin/sh
2### BEGIN INIT INFO
3# Provides: tox_bootstrap_daemon
4# Required-Start: $remote_fs $syslog
5# Required-Stop: $remote_fs $syslog
6# Default-Start: 2 3 4 5
7# Default-Stop: 0 1 6
8# Short-Description: Starts the Tox DHT bootstrapping server daemon
9# Description: Starts the Tox DHT bootstrapping server daemon
10### END INIT INFO
11
12# PATH should only include /usr/* if it runs after the mountnfs.sh script
13PATH=/sbin:/usr/sbin:/bin:/usr/bin
14DESC="Tox DHT bootstrap server daemon"
15NAME=tox_bootstrap_daemon
16# You may want to change USER if you are using it anywhere else
17USER=tom
18CFG=/home/$USER/.$NAME/conf
19DAEMON=/home/$USER/$NAME
20DAEMON_ARGS="$CFG"
21PIDFILE=/home/$USER/.$NAME/pid
22SCRIPTNAME=/etc/init.d/$NAME
23
24# Exit if the package is not installed
25[ -x "$DAEMON" ] || exit 0
26
27# Read configuration variable file if it is present
28#[ -r /etc/default/$NAME ] && . /etc/default/$NAME
29
30# Load the VERBOSE setting and other rcS variables
31. /lib/init/vars.sh
32
33# Define LSB log_* functions.
34# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
35# and status_of_proc is working.
36. /lib/lsb/init-functions
37
38#
39# Function that starts the daemon/service
40#
41do_start()
42{
43 start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
44 || return 1
45 start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
46 $DAEMON_ARGS \
47 || return 2
48 sleep 1
49}
50
51#
52# Function that stops the daemon/service
53#
54do_stop()
55{
56 start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --exec $DAEMON
57 RETVAL="$?"
58 [ "$RETVAL" = 2 ] && return 2
59
60 start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
61 [ "$?" = 2 ] && return 2
62 # Many daemons don't delete their pidfiles when they exit.
63 rm -f $PIDFILE
64 return "$RETVAL"
65}
66
67case "$1" in
68 start)
69 [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
70 do_start
71 case "$?" in
72 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
73 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
74 esac
75 ;;
76 stop)
77 [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
78 do_stop
79 case "$?" in
80 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
81 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
82 esac
83 ;;
84 status)
85 status_of_proc -p $PIDFILE "$DAEMON" "$NAME" && exit 0 || exit $?
86 ;;
87
88 restart) #|force-reload)
89 log_daemon_msg "Restarting $DESC" "$NAME"
90 do_stop
91 case "$?" in
92 0|1)
93 do_start
94 case "$?" in
95 0) log_end_msg 0 ;;
96 1) log_end_msg 1 ;; # Old process is still running
97 *) log_end_msg 1 ;; # Failed to start
98 esac
99 ;;
100 *)
101 # Failed to stop
102 log_end_msg 1
103 ;;
104 esac
105 ;;
106 *)
107 echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
108 exit 3
109 ;;
110esac