示例#1
0
文件: metainfo.c 项目: AchillesA/btpd
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;
}
示例#2
0
文件: metainfo.c 项目: AchillesA/btpd
int
mi_test(const char *p, size_t size)
{
    const char *info;
    const char *alst;
    const char *pieces;
    const char *files;
    const char *fdct;
    const char *name;
    size_t slen, npieces;
    off_t length = 0, piece_length;

    if (benc_validate(p, size) != 0 || !benc_isdct(p))
        return 0;

    if ((alst = benc_dget_any(p, "announce-list")) != NULL) {
        if (!benc_islst(alst))
            return 0;
        if (!mi_test_announce_list(alst))
            return 0;
    } else if (benc_dget_mem(p, "announce", NULL) == NULL)
        return 0;

    if ((info = benc_dget_dct(p, "info")) == NULL)
        return 0;
    if ((name = benc_dget_mem(info, "name", &slen)) != NULL)
        if (!mi_test_path(name, slen))
            return 0;
    if ((piece_length = benc_dget_int(info, "piece length")) <= 0)
        return 0;
    if ((pieces = benc_dget_mem(info, "pieces", &slen)) == NULL ||
            slen % 20 != 0)
        return 0;
    npieces = slen / 20;
    if ((length = benc_dget_int(info, "length")) != 0) {
        if (length < 0 || benc_dget_any(info, "files") != NULL)
            return 0;
    } else {
        if ((files = benc_dget_lst(info, "files")) == NULL)
            return 0;
        if (!mi_test_files(files))
            return 0;
        fdct = benc_first(files);
        while (fdct != NULL) {
            length += benc_dget_int(fdct, "length");
            fdct = benc_next(fdct);
        }
    }
    if (length < (npieces - 1) * piece_length ||
            length > npieces * piece_length)
        return 0;
    return 1;
}
示例#3
0
文件: metainfo.c 项目: AchillesA/btpd
static int
mi_test_files(const char *files)
{
    int fcount = 0;
    const char *fdct = benc_first(files);
    while (fdct != NULL) {
        const char *plst;
        const char *path;
        int pcount = 0;
        if (!benc_isdct(fdct))
            return 0;
        if (benc_dget_int(fdct, "length") < 0)
            return 0;
        if ((plst = benc_dget_lst(fdct, "path")) == NULL)
            return 0;
        path = benc_first(plst);
        while (path != NULL) {
            size_t plen;
            const char *pstr = benc_mem(path, &plen, &path);
            if (pstr == NULL || !mi_test_path(pstr, plen))
                return 0;
            pcount++;
        }
        if (pcount == 0)
            return 0;
        fcount++;
        fdct = benc_next(fdct);
    }
    return fcount > 0 ? 1 : 0;
}
示例#4
0
文件: metainfo.c 项目: AchillesA/btpd
off_t
mi_total_length(const char *p)
{
    const char *info = benc_dget_dct(p, "info");
    const char *files = benc_dget_lst(info, "files");
    if (files != NULL) {
        off_t length = 0;
        const char *fdct = benc_first(files);
        while (fdct != NULL) {
            length += benc_dget_int(fdct, "length");
            fdct = benc_next(fdct);
        }
        return length;
    } else
        return benc_dget_int(info, "length");
}
示例#5
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);
}
示例#6
0
文件: metainfo.c 项目: AchillesA/btpd
off_t
mi_piece_length(const char *p)
{
    return benc_dget_int(benc_dget_dct(p, "info"), "piece length");
}