started when btpd starts. The new '--empty-start' option turns this off.master
@@ -1,5 +1,6 @@ | |||||
bin_PROGRAMS=btpd | bin_PROGRAMS=btpd | ||||
btpd_SOURCES=\ | btpd_SOURCES=\ | ||||
active.c active.h\ | |||||
btpd.c btpd.h\ | btpd.c btpd.h\ | ||||
cli_if.c content.c content.h\ | cli_if.c content.c content.h\ | ||||
download.c download_subr.c download.h\ | download.c download_subr.c download.h\ | ||||
@@ -0,0 +1,101 @@ | |||||
#include <sys/types.h> | |||||
#include <sys/stat.h> | |||||
#include <string.h> | |||||
#include <unistd.h> | |||||
#include "btpd.h" | |||||
void | |||||
active_add(const uint8_t *hash) | |||||
{ | |||||
FILE *fp; | |||||
if ((fp = fopen("active", "a")) == NULL) { | |||||
btpd_log(BTPD_L_ERROR, "couldn't open file 'active' (%s).\n", | |||||
strerror(errno)); | |||||
return; | |||||
} | |||||
fwrite(hash, 20, 1, fp); | |||||
fclose(fp); | |||||
} | |||||
static void | |||||
active_del_pos(FILE *fp, long pos, off_t *size) | |||||
{ | |||||
uint8_t ehash[20]; | |||||
fseek(fp, -20, SEEK_END); | |||||
fread(ehash, 20, 1, fp); | |||||
fseek(fp, pos, SEEK_SET); | |||||
fwrite(ehash, 20, 1, fp); | |||||
fflush(fp); | |||||
*size -= 20; | |||||
ftruncate(fileno(fp), *size); | |||||
} | |||||
void | |||||
active_del(const uint8_t *hash) | |||||
{ | |||||
FILE *fp; | |||||
long pos; | |||||
struct stat sb; | |||||
uint8_t buf[20]; | |||||
if ((fp = fopen("active", "r+")) == NULL) { | |||||
btpd_log(BTPD_L_ERROR, "couldn't open file 'active' (%s).\n", | |||||
strerror(errno)); | |||||
return; | |||||
} | |||||
if (fstat(fileno(fp), &sb) != 0) { | |||||
btpd_log(BTPD_L_ERROR, "couldn't stat file 'active' (%s).\n", | |||||
strerror(errno)); | |||||
goto close; | |||||
} | |||||
pos = 0; | |||||
while (fread(buf, 20, 1, fp) == 1) { | |||||
if (bcmp(buf, hash, 20) == 0) { | |||||
active_del_pos(fp, pos, &sb.st_size); | |||||
break; | |||||
} | |||||
pos += 20; | |||||
} | |||||
close: | |||||
fclose(fp); | |||||
} | |||||
void | |||||
active_start(void) | |||||
{ | |||||
FILE *fp; | |||||
long pos; | |||||
struct stat sb; | |||||
uint8_t hash[20]; | |||||
if ((fp = fopen("active", "r+")) == NULL) | |||||
return; | |||||
if (fstat(fileno(fp), &sb) != 0) { | |||||
btpd_log(BTPD_L_ERROR, "Couldn't stat file 'active' (%s).\n", | |||||
strerror(errno)); | |||||
goto close; | |||||
} | |||||
pos = 0; | |||||
while (fread(hash, sizeof(hash), 1, fp) == 1) { | |||||
if (torrent_get(hash) == NULL) | |||||
if (torrent_start(hash) != 0) { | |||||
active_del_pos(fp, pos, &sb.st_size); | |||||
fseek(fp, pos, SEEK_SET); | |||||
} | |||||
pos += 20; | |||||
} | |||||
close: | |||||
fclose(fp); | |||||
} | |||||
void | |||||
active_clear(void) | |||||
{ | |||||
unlink("active"); | |||||
} |
@@ -0,0 +1,9 @@ | |||||
#ifndef BTPD_ACTIVE_H | |||||
#define BTPD_ACTIVE_H | |||||
void active_add(const uint8_t *hash); | |||||
void active_del(const uint8_t *hash); | |||||
void active_clear(void); | |||||
void active_start(void); | |||||
#endif |
@@ -28,6 +28,7 @@ | |||||
#include "btpd.h" | #include "btpd.h" | ||||
#include "http.h" | #include "http.h" | ||||
#include "active.h" | |||||
static uint8_t m_peer_id[20]; | static uint8_t m_peer_id[20]; | ||||
static struct event m_sigint; | static struct event m_sigint; | ||||
@@ -209,4 +210,9 @@ btpd_init(void) | |||||
btpd_ev_add(&m_sigterm, NULL); | btpd_ev_add(&m_sigterm, NULL); | ||||
evtimer_set(&m_heartbeat, heartbeat_cb, NULL); | evtimer_set(&m_heartbeat, heartbeat_cb, NULL); | ||||
btpd_ev_add(&m_heartbeat, (& (struct timeval) { 1, 0 })); | btpd_ev_add(&m_heartbeat, (& (struct timeval) { 1, 0 })); | ||||
if (!empty_start) | |||||
active_start(); | |||||
else | |||||
active_clear(); | |||||
} | } |
@@ -12,6 +12,7 @@ | |||||
#include <unistd.h> | #include <unistd.h> | ||||
#include "btpd.h" | #include "btpd.h" | ||||
#include "active.h" | |||||
#include "tracker_req.h" | #include "tracker_req.h" | ||||
struct cli { | struct cli { | ||||
@@ -121,8 +122,12 @@ cmd_add(struct cli *cli, int argc, const char *args) | |||||
code = IPC_ERROR; | code = IPC_ERROR; | ||||
goto out; | goto out; | ||||
} | } | ||||
if (torrent_start(hash) != 0) | |||||
if (torrent_start(hash) != 0) { | |||||
code = IPC_ERROR; | code = IPC_ERROR; | ||||
goto out; | |||||
} | |||||
active_add(hash); | |||||
out: | out: | ||||
if (content != NULL) | if (content != NULL) | ||||
@@ -149,8 +154,10 @@ cmd_del(struct cli *cli, int argc, const char *args) | |||||
// Stopping a torrent may trigger exit so we need to reply before. | // Stopping a torrent may trigger exit so we need to reply before. | ||||
int ret = write_code_buffer(cli, IPC_OK); | int ret = write_code_buffer(cli, IPC_OK); | ||||
struct torrent *tp = torrent_get(hash); | struct torrent *tp = torrent_get(hash); | ||||
if (tp != NULL) | |||||
if (tp != NULL) { | |||||
torrent_stop(tp); | torrent_stop(tp); | ||||
active_del(hash); | |||||
} | |||||
return ret; | return ret; | ||||
} | } | ||||
@@ -96,6 +96,9 @@ usage(void) | |||||
"-d dir\n" | "-d dir\n" | ||||
"\tThe directory in which to run btpd. Default is '$HOME/.btpd'.\n" | "\tThe directory in which to run btpd. Default is '$HOME/.btpd'.\n" | ||||
"\n" | "\n" | ||||
"--empty-start\n" | |||||
"\tStart btpd without any active torrents.\n" | |||||
"\n" | |||||
"--help\n" | "--help\n" | ||||
"\tShow this text.\n" | "\tShow this text.\n" | ||||
"\n" | "\n" | ||||
@@ -144,6 +147,7 @@ static struct option longopts[] = { | |||||
{ "no-daemon", no_argument, &longval, 6 }, | { "no-daemon", no_argument, &longval, 6 }, | ||||
{ "logfile", required_argument, &longval, 7 }, | { "logfile", required_argument, &longval, 7 }, | ||||
{ "ipcprot", required_argument, &longval, 8 }, | { "ipcprot", required_argument, &longval, 8 }, | ||||
{ "empty-start", no_argument, &longval, 9 }, | |||||
{ "help", no_argument, &longval, 128 }, | { "help", no_argument, &longval, 128 }, | ||||
{ NULL, 0, NULL, 0 } | { NULL, 0, NULL, 0 } | ||||
}; | }; | ||||
@@ -192,6 +196,9 @@ main(int argc, char **argv) | |||||
case 8: | case 8: | ||||
ipcprot = strtol(optarg, NULL, 8); | ipcprot = strtol(optarg, NULL, 8); | ||||
break; | break; | ||||
case 9: | |||||
empty_start = 1; | |||||
break; | |||||
default: | default: | ||||
usage(); | usage(); | ||||
} | } | ||||
@@ -13,3 +13,4 @@ unsigned net_bw_limit_out; | |||||
int net_port = 6881; | int net_port = 6881; | ||||
off_t cm_alloc_size = 2048 * 1024; | off_t cm_alloc_size = 2048 * 1024; | ||||
int ipcprot = 0600; | int ipcprot = 0600; | ||||
int empty_start = 0; |
@@ -10,5 +10,6 @@ extern unsigned net_bw_limit_out; | |||||
extern int net_port; | extern int net_port; | ||||
extern off_t cm_alloc_size; | extern off_t cm_alloc_size; | ||||
extern int ipcprot; | extern int ipcprot; | ||||
extern int empty_start; | |||||
#endif | #endif |