Esempio n. 1
0
void
ipc_init(void)
{
    int sd;
    struct sockaddr_un addr;
    size_t psiz = sizeof(addr.sun_path);

    addr.sun_family = PF_UNIX;
    if (snprintf(addr.sun_path, psiz, "%s/sock", btpd_dir) >= psiz)
        btpd_err("'%s/sock' is too long.\n", btpd_dir);

    if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
        btpd_err("sock: %s\n", strerror(errno));
    if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
        if (errno == EADDRINUSE) {
            unlink(addr.sun_path);
            if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
                btpd_err("bind: %s\n", strerror(errno));
        } else
            btpd_err("bind: %s\n", strerror(errno));
    }

    if (chmod(addr.sun_path, ipcprot) == -1)
        btpd_err("chmod: %s (%s).\n", addr.sun_path, strerror(errno));
    listen(sd, 4);
    set_nonblocking(sd);

    btpd_ev_new(&m_cli_incoming, sd, EV_READ, client_connection_cb, NULL);
    m_listen_sd = sd;
}
Esempio n. 2
0
static void
nc_connect(struct nameconn *nc)
{
    struct addrinfo *ai;
    int err;

again:
    if ((ai = nc->ai_cur) == NULL) {
        nc_done(nc, -1);
        return;
    }

    if ((nc->sd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0)
        btpd_err("Failed to create socket (%s).\r\n", strerror(errno));

    set_nonblocking(nc->sd);

    err = connect(nc->sd, ai->ai_addr, ai->ai_addrlen);
    if (err == 0)
        nc_done(nc, 0);
    else if (err == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK)
        btpd_ev_new(&nc->write_ev, nc->sd, EV_WRITE, nc_write_cb, nc);
    else {
        closesocket(nc->sd);
        nc->ai_cur = ai->ai_next;
        goto again;
    }
}
Esempio n. 3
0
static void
http_cb(struct http_req *req, struct http_response *res, void *arg)
{
    struct httptr_req *treq = arg;
    struct tr_response tres = {0, NULL, -1 };
    switch (res->type) {
    case HTTP_T_ERR:
        tres.type = TR_RES_BAD;
        tr_result(treq->tr, &tres);
        httptr_free(treq);
        break;
    case HTTP_T_DATA:
        if (treq->buf.off + res->v.data.l > MAX_DOWNLOAD) {
            tres.type = TR_RES_BAD;
            tr_result(treq->tr, &tres);
            httptr_cancel(treq);
            break;
        }
        if (!iobuf_write(&treq->buf, res->v.data.p, res->v.data.l))
            btpd_err("Out of memory.\n");
        break;
    case HTTP_T_DONE:
        if (treq->event == TR_EV_STOPPED) {
            tres.type = TR_RES_OK;
            tr_result(treq->tr, &tres);
        } else {
            parse_reply(treq->tp, &tres, treq->buf.buf, treq->buf.off);
            tr_result(treq->tr, &tres);
        }
        httptr_free(treq);
        break;
    default:
        break;
    }
}
Esempio n. 4
0
void
client_connection_cb(int sd, short type, void *arg)
{
    int nsd;

    if ((nsd = accept(sd, NULL, NULL)) < 0) {
        if (errno == EWOULDBLOCK || errno == ECONNABORTED)
            return;
        else
            btpd_err("client accept: %s\n", strerror(errno));
    }

    if ((errno = set_blocking(nsd)) != 0)
        btpd_err("set_blocking: %s.\n", strerror(errno));

    struct cli *cli = btpd_calloc(1, sizeof(*cli));
    cli->sd = nsd;
    btpd_ev_new(&cli->read, cli->sd, EV_READ, cli_read_cb, cli);
}
Esempio n. 5
0
static int
write_buffer(struct cli *cli, struct iobuf *iob)
{
    int err = 0;
    if (!iob->error) {
        uint32_t len = iob->off;
        write_fully(cli->sd, &len, sizeof(len));
        err = write_fully(cli->sd, iob->buf, iob->off);
    } else
        btpd_err("Out of memory.\n");
    iobuf_free(iob);
    return err;
}
Esempio n. 6
0
static void
nc_write_cb(int sd, short type, void *arg)
{
    struct nameconn *nc = arg;
    int error;
    socklen_t errsiz = sizeof(int);
    if (getsockopt(nc->sd, SOL_SOCKET, SO_ERROR, &error, &errsiz) < 0)
        btpd_err("getsockopt error (%s).\r\n", strerror(errno));
    if (error == 0) {
        btpd_ev_del(&nc->write_ev);
        nc_done(nc, 0);
    } else {
        btpd_ev_del(&nc->write_ev);
        closesocket(nc->sd);
        nc->ai_cur = nc->ai_cur->ai_next;
        nc_connect(nc);
    }
}
Esempio n. 7
0
static int
cmd_start_all(struct cli *cli, int argc, const char *args)
{
    struct htbl_iter it;
    struct tlib *tl;
    enum ipc_err last_code, ret_code= IPC_OK;

    if (btpd_is_stopping())
        return write_code_buffer(cli, IPC_ESHUTDOWN);

    for (tl = tlib_iter_first(&it); tl != NULL; tl = tlib_iter_next(&it)) {
        if (torrent_startable(tl)) {
            if ((last_code = torrent_start(tl)) == IPC_OK) {
                active_add(tl->hash);
            } else {
                btpd_err("torrent_start(%d) failed.\n", tl->num);
                ret_code = last_code;
            }
        }
    }

    return write_code_buffer(cli, ret_code);
}