Procházet zdrojové kódy

Moved to ../misc.

master
Richard Nyberg před 18 roky
rodič
revize
28380064b7
2 změnil soubory, kde provedl 0 přidání a 405 odebrání
  1. +0
    -313
      cli/btpd_if.c
  2. +0
    -92
      cli/btpd_if.h

+ 0
- 313
cli/btpd_if.c Zobrazit soubor

@@ -1,313 +0,0 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#include <assert.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "benc.h"
#include "btpd_if.h"
#include "iobuf.h"
#include "subr.h"

struct ipc {
int sd;
};

static const char *errmsgs[] = {
#define ERRDEF(name, msg) msg,
#include "ipcdefs.h"
#undef ERRDEF
NULL
};

static const char *tval_names[] = {
#define TVDEF(val, type, name) name,
#include "ipcdefs.h"
#undef TVDEF
NULL
};

const char *
ipc_strerror(enum ipc_err err)
{
if (err < 0 || err >= IPC_ERRCOUNT)
return "unknown error";
return errmsgs[err];
}

const char *
tval_name(enum ipc_tval key)
{
if (key < 0 || key >= IPC_TVALCOUNT)
return "unknown key";
return tval_names[key];
}

int
ipc_open(const char *dir, struct ipc **out)
{
int sd = -1, err = 0;
size_t plen;
struct ipc *res;
struct sockaddr_un addr;

plen = sizeof(addr.sun_path);
if (snprintf(addr.sun_path, plen, "%s/sock", dir) >= plen)
return ENAMETOOLONG;
addr.sun_family = AF_UNIX;

if ((sd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
return errno;

if (connect(sd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
err = errno;
close(sd);
return err;
}

if ((res = malloc(sizeof(*res))) == NULL) {
close(sd);
return ENOMEM;
}

res->sd = sd;
*out = res;
return 0;
}

void
ipc_close(struct ipc *ipc)
{
close(ipc->sd);
free(ipc);
}

static enum ipc_err
ipc_response(struct ipc *ipc, char **out, uint32_t *len)
{
uint32_t size;
char *buf;

if (read_fully(ipc->sd, &size, sizeof(size)) != 0)
return IPC_COMMERR;
if (size == 0)
return IPC_COMMERR;
if ((buf = malloc(size)) == NULL)
return IPC_COMMERR;
if (read_fully(ipc->sd, buf, size) != 0) {
free(buf);
return IPC_COMMERR;
}
*out = buf;
*len = size;
return IPC_OK;
}

static enum ipc_err
ipc_req_res(struct ipc *ipc, const char *req, uint32_t qlen, char **res,
uint32_t *rlen)
{
assert(benc_validate(req, qlen) == 0);
if (write_fully(ipc->sd, &qlen, sizeof(qlen)) != 0)
return IPC_COMMERR;
if (write_fully(ipc->sd, req, qlen) != 0)
return IPC_COMMERR;
if (ipc_response(ipc, res, rlen) != 0)
return IPC_COMMERR;
if (benc_validate(*res, *rlen) != 0)
return IPC_COMMERR;
if (!benc_isdct(*res))
return IPC_COMMERR;
return IPC_OK;
}

static enum ipc_err
ipc_buf_req_res(struct ipc *ipc, struct io_buffer *iob, char **res,
uint32_t *rlen)
{
enum ipc_err err = ipc_req_res(ipc, iob->buf, iob->buf_off, res, rlen);
free(iob->buf);
return err;
}

static enum ipc_err
ipc_buf_req_code(struct ipc *ipc, struct io_buffer *iob)
{
enum ipc_err err;
char *res;
uint32_t rlen;

if ((err = ipc_buf_req_res(ipc, iob, &res, &rlen)) == 0) {
err = benc_dget_int(res, "code");
free(res);
}
return err;
}

enum ipc_err
btpd_die(struct ipc *ipc, int seconds)
{
struct io_buffer iob;
buf_init(&iob, 16);
if (seconds >= 0)
buf_print(&iob, "l3:diei%dee", seconds);
else
buf_swrite(&iob, "l3:diee");
return ipc_buf_req_code(ipc, &iob);
}

static enum ipc_err
tget_common(char *ans, enum ipc_tval *keys, size_t nkeys, tget_cb_t cb,
void *arg)
{
int err;
const char *res;
struct ipc_get_res cbres[IPC_TVALCOUNT];

if ((err = benc_dget_int(ans, "code")) != 0)
return err;

res = benc_dget_lst(ans, "result");
int obji = 0;
for (res = benc_first(res); res != NULL; res = benc_next(res)) {
if (benc_isint(res)) {
cb(obji, benc_int(res, NULL), NULL, arg);
obji++;
continue;
}
const char *t = benc_first(res);
const char *v = benc_next(t);
for (int j = 0; j < nkeys; j++) {
cbres[keys[j]].type = benc_int(t, NULL);
switch (cbres[keys[j]].type) {
case IPC_TYPE_ERR:
case IPC_TYPE_NUM:
cbres[keys[j]].v.num = benc_int(v, NULL);
break;
case IPC_TYPE_STR:
case IPC_TYPE_BIN:
cbres[keys[j]].v.str.p= benc_mem(v, &cbres[keys[j]].v.str.l,
NULL);
break;
}
t = benc_next(v);
if (t != NULL)
v = benc_next(t);
}
cb(obji, IPC_OK, cbres, arg);
obji++;
}

free(ans);
return IPC_OK;
}

enum ipc_err
btpd_tget(struct ipc *ipc, struct ipc_torrent *tps, size_t ntps,
enum ipc_tval *keys, size_t nkeys, tget_cb_t cb, void *arg)
{
char *res;
uint32_t rlen;
enum ipc_err err;
struct io_buffer iob;

if (nkeys == 0 || ntps == 0)
return IPC_COMMERR;

buf_init(&iob, 1 << 14);
buf_swrite(&iob, "l4:tgetd4:froml");
for (int i = 0; i < ntps; i++) {
if (tps[i].by_hash) {
buf_swrite(&iob, "20:");
buf_write(&iob, tps[i].u.hash, 20);
} else
buf_print(&iob, "i%ue", tps[i].u.num);
}
buf_swrite(&iob, "e4:keysl");
for (int k = 0; k < nkeys; k++)
buf_print(&iob, "i%de", keys[k]);
buf_swrite(&iob, "eee");

if ((err = ipc_buf_req_res(ipc, &iob, &res, &rlen)) == 0)
err = tget_common(res, keys, nkeys, cb, arg);
return err;
}

enum ipc_err
btpd_tget_wc(struct ipc *ipc, enum ipc_twc twc, enum ipc_tval *keys,
size_t nkeys, tget_cb_t cb, void *arg)
{
char *res;
uint32_t rlen;
struct io_buffer iob;
enum ipc_err err;

if (nkeys == 0)
return IPC_COMMERR;

buf_init(&iob, 1 << 14);
buf_print(&iob, "l4:tgetd4:fromi%de4:keysl", twc);
for (int i = 0; i < nkeys; i++)
buf_print(&iob, "i%de", keys[i]);
buf_swrite(&iob, "eee");

if ((err = ipc_buf_req_res(ipc, &iob, &res, &rlen)) == 0)
err = tget_common(res, keys, nkeys, cb, arg);
return err;
}

enum ipc_err
btpd_add(struct ipc *ipc, const char *mi, size_t mi_size, const char *content,
const char *name)
{
struct io_buffer iob;
buf_init(&iob, (1 << 10));
buf_print(&iob, "l3:addd7:content%d:%s", (int)strlen(content),
content);
if (name != NULL)
buf_print(&iob, "4:name%d:%s", (int)strlen(name), name);
buf_print(&iob, "7:torrent%lu:", (unsigned long)mi_size);
buf_write(&iob, mi, mi_size);
buf_swrite(&iob, "ee");
return ipc_buf_req_code(ipc, &iob);
}

static enum ipc_err
simple_treq(struct ipc *ipc, char *cmd, struct ipc_torrent *tp)
{
struct io_buffer iob;
buf_init(&iob, 32);
if (tp->by_hash) {
buf_print(&iob, "l%d:%s20:", (int)strlen(cmd), cmd);
buf_write(&iob, tp->u.hash, 20);
buf_swrite(&iob, "e");
} else
buf_print(&iob, "l%d:%si%uee", (int)strlen(cmd), cmd, tp->u.num);
return ipc_buf_req_code(ipc, &iob);
}

enum ipc_err
btpd_del(struct ipc *ipc, struct ipc_torrent *tp)
{
return simple_treq(ipc, "del", tp);
}

enum ipc_err
btpd_start(struct ipc *ipc, struct ipc_torrent *tp)
{
return simple_treq(ipc, "start", tp);
}

enum ipc_err
btpd_stop(struct ipc *ipc, struct ipc_torrent *tp)
{
return simple_treq(ipc, "stop", tp);
}

+ 0
- 92
cli/btpd_if.h Zobrazit soubor

@@ -1,92 +0,0 @@
#ifndef BTPD_IPC_H
#define BTPD_IPC_H

enum ipc_err {
#define ERRDEF(name, msg) IPC_##name,
#include "ipcdefs.h"
#undef ERRDEF
IPC_ERRCOUNT
};

enum ipc_type {
IPC_TYPE_ERR,
IPC_TYPE_BIN,
IPC_TYPE_NUM,
IPC_TYPE_STR
};

enum ipc_tval {
#define TVDEF(val, type, name) IPC_TVAL_##val,
#include "ipcdefs.h"
#undef TVDEF
IPC_TVALCOUNT
};

enum ipc_dval {
IPC_DVAL_MIN,
IPC_DVAL_MAX
};

enum ipc_twc {
IPC_TWC_ALL,
IPC_TWC_ACTIVE,
IPC_TWC_INACTIVE
};

enum ipc_tstate {
IPC_TSTATE_INACTIVE,
IPC_TSTATE_START,
IPC_TSTATE_STOP,
IPC_TSTATE_LEECH,
IPC_TSTATE_SEED
};

#ifndef DAEMON

struct ipc;

struct ipc_get_res {
enum ipc_type type;
union {
struct {
const char *p;
size_t l;
} str;
long long num;
} v;
};

struct ipc_torrent {
int by_hash;
union {
unsigned num;
uint8_t hash[20];
} u;
};

typedef void (*tget_cb_t)(int obji, enum ipc_err objerr,
struct ipc_get_res *res, void *arg);

//typedef void (*dget_cb_t)(struct ipc_get_res *res, size_t nres, void *arg);

int ipc_open(const char *dir, struct ipc **out);
void ipc_close(struct ipc *ipc);

const char *ipc_strerror(enum ipc_err err);

enum ipc_err btpd_add(struct ipc *ipc, const char *mi, size_t mi_size,
const char *content, const char *name);
enum ipc_err btpd_del(struct ipc *ipc, struct ipc_torrent *tp);
enum ipc_err btpd_start(struct ipc *ipc, struct ipc_torrent *tp);
enum ipc_err btpd_stop(struct ipc *ipc, struct ipc_torrent *tp);
enum ipc_err btpd_die(struct ipc *ipc, int seconds);
enum ipc_err btpd_get(struct ipc *ipc, enum ipc_dval *keys, size_t nkeys,
tget_cb_t cb, void *arg);
enum ipc_err btpd_tget(struct ipc *ipc, struct ipc_torrent *tps, size_t ntps,
enum ipc_tval *keys, size_t nkeys, tget_cb_t cb, void *arg);
enum ipc_err btpd_tget_wc(struct ipc *ipc, enum ipc_twc, enum ipc_tval *keys,
size_t nkeys, tget_cb_t cb, void *arg);

#endif

#endif

Načítá se…
Zrušit
Uložit