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); } }
static int cmd_tget(struct cli *cli, int argc, const char *args) { if (argc != 1 || !benc_isdct(args)) return IPC_COMMERR; size_t nkeys; const char *keys, *p; enum ipc_tval *opts; struct iobuf iob; if ((keys = benc_dget_lst(args, "keys")) == NULL) return IPC_COMMERR; nkeys = benc_nelems(keys); opts = btpd_calloc(nkeys, sizeof(*opts)); p = benc_first(keys); for (int i = 0; i < nkeys; i++) opts[i] = benc_int(p, &p); iob = iobuf_init(1 << 15); iobuf_swrite(&iob, "d4:codei0e6:resultl"); p = benc_dget_any(args, "from"); if (benc_isint(p)) { enum ipc_twc from = benc_int(p, NULL); struct htbl_iter it; struct tlib *tl; for (tl = tlib_iter_first(&it); tl != NULL; tl = tlib_iter_next(&it)) { if (!torrent_haunting(tl) && ( from == IPC_TWC_ALL || (!torrent_active(tl) && from == IPC_TWC_INACTIVE) || (torrent_active(tl) && from == IPC_TWC_ACTIVE))) { iobuf_swrite(&iob, "l"); for (int k = 0; k < nkeys; k++) write_ans(&iob, tl, opts[k]); iobuf_swrite(&iob, "e"); } } } else if (benc_islst(p)) { for (p = benc_first(p); p != NULL; p = benc_next(p)) { struct tlib *tl = NULL; if (benc_isint(p)) tl = tlib_by_num(benc_int(p, NULL)); else if (benc_isstr(p) && benc_strlen(p) == 20) tl = tlib_by_hash(benc_mem(p, NULL, NULL)); else { iobuf_free(&iob); free(opts); return IPC_COMMERR; } if (tl != NULL && !torrent_haunting(tl)) { iobuf_swrite(&iob, "l"); for (int i = 0; i < nkeys; i++) write_ans(&iob, tl, opts[i]); iobuf_swrite(&iob, "e"); } else iobuf_print(&iob, "i%de", IPC_ENOTENT); } } iobuf_swrite(&iob, "ee"); free(opts); return write_buffer(cli, &iob); }