-
Notifications
You must be signed in to change notification settings - Fork 59
/
add.c
129 lines (121 loc) · 3.44 KB
/
add.c
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
#include "btcli.h"
void
usage_add(void)
{
printf(
"Add torrents to btpd.\n"
"\n"
"Usage: add [-n name] [-T] [-N] -d dir file(s)\n"
"\n"
"Arguments:\n"
"file\n"
"\tThe torrent file to add.\n"
"\n"
"Options:\n"
"-d dir\n"
"\tUse the dir for content.\n"
"\n"
"-n name\n"
"\tSet the name displayed for this torrent.\n"
"\n"
"-l label\n"
"\tSet the label to associate with torrent.\n"
"\n"
"--nostart, -N\n"
"\tDon't activate the torrent after adding it.\n"
"\n"
"--topdir, -T\n"
"\tAppend the torrent top directory (if any) to the content path.\n"
"\n"
);
exit(1);
}
static struct option add_opts [] = {
{ "help", no_argument, NULL, 'H' },
{ "nostart", no_argument, NULL, 'N'},
{ "topdir", no_argument, NULL, 'T'},
{NULL, 0, NULL, 0}
};
void
cmd_add(int argc, char **argv)
{
int ch, topdir = 0, start = 1, nfile, nloaded = 0;
size_t dirlen = 0, labellen = 0;
char *dir = NULL, *name = NULL, *glabel = NULL, *label;
while ((ch = getopt_long(argc, argv, "NTd:l:n:", add_opts, NULL)) != -1) {
switch (ch) {
case 'N':
start = 0;
break;
case 'T':
topdir = 1;
break;
case 'd':
dir = optarg;
if ((dirlen = strlen(dir)) == 0)
diemsg("bad option value for -d.\n");
break;
case 'l':
glabel = optarg;
if ((labellen = strlen(dir)) == 0)
diemsg("bad option value for -l.\n");
break;
case 'n':
name = optarg;
break;
default:
usage_add();
}
}
argc -= optind;
argv += optind;
if (argc < 1 || dir == NULL)
usage_add();
btpd_connect();
char *mi;
size_t mi_size;
enum ipc_err code;
char dpath[PATH_MAX];
struct iobuf iob;
for (nfile = 0; nfile < argc; nfile++) {
if ((mi = mi_load(argv[nfile], &mi_size)) == NULL) {
fprintf(stderr, "error loading '%s' (%s).\n", argv[nfile], strerror(errno));
continue;
}
iob = iobuf_init(PATH_MAX);
iobuf_write(&iob, dir, dirlen);
if (topdir && !mi_simple(mi)) {
size_t tdlen;
const char *td =
benc_dget_mem(benc_dget_dct(mi, "info"), "name", &tdlen);
iobuf_swrite(&iob, "/");
iobuf_write(&iob, td, tdlen);
}
iobuf_swrite(&iob, "\0");
if ((errno = make_abs_path(iob.buf, dpath)) != 0) {
fprintf(stderr, "make_abs_path '%s' failed (%s).\n", dpath, strerror(errno));
iobuf_free(&iob);
continue;
}
if(NULL == glabel)
label = benc_dget_str(mi, "announce", NULL);
else
label = glabel;
code = btpd_add(ipc, mi, mi_size, dpath, name, label);
if ((code == IPC_OK) && start) {
struct ipc_torrent tspec;
tspec.by_hash = 1;
mi_info_hash(mi, tspec.u.hash);
code = btpd_start(ipc, &tspec);
}
if (code != IPC_OK) {
fprintf(stderr, "command failed for '%s' (%s).\n", argv[nfile], ipc_strerror(code));
} else {
nloaded++;
}
iobuf_free(&iob);
}
if (nloaded != nfile) {
diemsg("error loaded %d of %d files.\n", nloaded, nfile);
}
}