Exemplo n.º 1
0
struct mi_file *
mi_files(const char *p)
{
    struct mi_file *fi;
    const char *info = benc_dget_dct(p, "info");
    const char *files = benc_dget_lst(info, "files");
    if (files != NULL) {
        int i = 0;
        unsigned nfiles = benc_nelems(files);
        const char *fdct = benc_first(files);
        if ((fi = calloc(nfiles, sizeof(*fi))) == NULL)
            return NULL;
        for (fdct = benc_first(files); fdct != NULL; fdct = benc_next(fdct)) {
            fi[i].length = benc_dget_int(fdct, "length");
            fi[i].path = mi_filepath(benc_dget_lst(fdct, "path"));
            if (fi[i].path == NULL) {
                mi_free_files(nfiles, fi);
                return NULL;
            }
            i++;
        }
    } else {
        if ((fi = calloc(1, sizeof(*fi))) == NULL)
            return NULL;
        fi[0].length = benc_dget_int(info, "length");
        fi[0].path = benc_dget_str(info, "name", NULL);
        if (fi[0].path == NULL) {
            free(fi);
            return NULL;
        }
    }
    return fi;
}
Exemplo n.º 2
0
static void
maybe_connect_to(struct torrent *tp, const char *pinfo)
{
    const char *pid;
    char *ip;
    int port;
    size_t len;

    if ((pid = benc_dget_mem(pinfo, "peer id", &len)) == NULL || len != 20)
        return;

    if (bcmp(btpd_get_peer_id(), pid, 20) == 0)
        return;

    if (net_torrent_has_peer(tp->net, pid))
        return;

    if ((ip = benc_dget_str(pinfo, "ip", NULL)) == NULL)
        return;

    port = benc_dget_int(pinfo, "port");
    peer_create_out(tp->net, pid, ip, port);

    if (ip != NULL)
        free(ip);
}
Exemplo n.º 3
0
static int
cmd_add(struct cli *cli, int argc, const char *args)
{
    if (argc != 1 || !benc_isdct(args))
        return IPC_COMMERR;

    struct tlib *tl;
    size_t mi_size = 0, csize = 0;
    const char *mi, *cp;
    char content[PATH_MAX];
    uint8_t hash[20];

    if ((mi = benc_dget_mem(args, "torrent", &mi_size)) == NULL)
        return IPC_COMMERR;

    if (!mi_test(mi, mi_size))
        return write_code_buffer(cli, IPC_EBADT);

    if ((cp = benc_dget_mem(args, "content", &csize)) == NULL ||
            csize >= PATH_MAX || csize == 0)
        return write_code_buffer(cli, IPC_EBADCDIR);

    if (cp[0] != '/')
        return write_code_buffer(cli, IPC_EBADCDIR);
    bcopy(cp, content, csize);
    content[csize] = '\0';

    tl = tlib_by_hash(mi_info_hash(mi, hash));
    if (tl != NULL && !torrent_haunting(tl))
        return write_code_buffer(cli, IPC_ETENTEXIST);
    if (tl != NULL) {
        tl = tlib_readd(tl, hash, mi, mi_size, content,
            benc_dget_str(args, "name", NULL),
            benc_dget_str(args, "label", NULL));
    } else {
        tl = tlib_add(hash, mi, mi_size, content,
            benc_dget_str(args, "name", NULL),
            benc_dget_str(args, "label", NULL));
    }
    return write_add_buffer(cli, tl->num);
}
Exemplo n.º 4
0
struct mi_announce *
mi_announce(const char *p)
{
    int ti, ui;
    const char *alst, *ulst, *url;
    struct mi_announce *res;

    if ((res = calloc(1, sizeof(*res))) == NULL)
        return NULL;

    if ((alst = benc_dget_lst(p, "announce-list")) != NULL) {
        res->ntiers = benc_nelems(alst);
        if ((res->tiers = calloc(res->ntiers, sizeof(*res->tiers))) == NULL)
            goto error;
        ti = 0; ulst = benc_first(alst);
        while (ulst != NULL) {
            res->tiers[ti].nurls = benc_nelems(ulst);
            res->tiers[ti].urls =
                calloc(res->tiers[ti].nurls, sizeof(*res->tiers[ti].urls));
            if (res->tiers[ti].urls == NULL)
                goto error;

            ui = 0; url = benc_first(ulst);
            while (url != NULL) {
                if ((res->tiers[ti].urls[ui] =
                        benc_str(url, NULL, NULL)) == NULL)
                    goto error;
                ui++; url = benc_next(url);
            }

            ti++; ulst = benc_next(ulst);
        }
    } else {
        res->ntiers = 1;
        if ((res->tiers = calloc(1, sizeof(*res->tiers))) == NULL)
            goto error;
        res->tiers[0].nurls = 1;
        if ((res->tiers[0].urls =
                calloc(1, sizeof(*res->tiers[0].urls))) == NULL)
            goto error;
        if ((res->tiers[0].urls[0] =
                benc_dget_str(p, "announce", NULL)) == NULL)
            goto error;
    }
    mi_shuffle_announce(res);
    return res;

error:
    if (res != NULL)
        mi_free_announce(res);
    return NULL;
}
Exemplo n.º 5
0
Arquivo: add.c Projeto: AchillesA/btpd
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);
    }
}
Exemplo n.º 6
0
char *
mi_name(const char *p)
{
    return benc_dget_str(benc_dget_dct(p, "info"), "name", NULL);
}