瀏覽代碼

Save the total amount down- and uploaded and cache the torrent size and the

amount we have in the info file.
master
Richard Nyberg 18 年之前
父節點
當前提交
7ae55cac4d
共有 3 個文件被更改,包括 100 次插入38 次删除
  1. +93
    -34
      btpd/tlib.c
  2. +5
    -3
      btpd/tlib.h
  3. +2
    -1
      btpd/torrent.c

+ 93
- 34
btpd/tlib.c 查看文件

@@ -70,15 +70,52 @@ tlib_del(struct tlib *tl)
return 0; return 0;
} }


static void
dct_subst_save(FILE *fp, const char *dct1, const char *dct2)
{
fprintf(fp, "d");
const char *k1 = benc_first(dct1), *k2 = benc_first(dct2);
const char *val, *str, *rest;
size_t len;

while (k1 != NULL && k2 != NULL) {
int test = benc_strcmp(k1, k2);
if (test < 0) {
str = benc_mem(k1, &len, &val);
fprintf(fp, "%d:%.*s", (int)len, (int)len, str);
fwrite(val, 1, benc_length(val), fp);
k1 = benc_next(val);
} else {
str = benc_mem(k2, &len, &val);
fprintf(fp, "%d:%.*s", (int)len, (int)len, str);
fwrite(val, 1, benc_length(val), fp);
k2 = benc_next(val);
if (test == 0)
k1 = benc_next(benc_next(k1));
}
}
rest = k1 != NULL ? k1 : k2;
while (rest != NULL) {
str = benc_mem(rest, &len, &val);
fprintf(fp, "%d:%.*s", (int)len, (int)len, str);
fwrite(val, 1, benc_length(val), fp);
rest = benc_next(val);
}
fprintf(fp, "e");
}

static int static int
valid_info(char *buf, size_t len) valid_info(char *buf, size_t len)
{ {
size_t slen; size_t slen;
const char *info;
if (benc_validate(buf, len) != 0) if (benc_validate(buf, len) != 0)
return 0; return 0;
if (benc_dget_mem(buf, "name", &slen) == NULL || slen == 0) if ((info = benc_dget_dct(buf, "info")) == NULL)
return 0;
if (benc_dget_mem(info, "name", &slen) == NULL || slen == 0)
return 0; return 0;
if ((benc_dget_mem(buf, "dir", &slen) == NULL || if ((benc_dget_mem(info, "dir", &slen) == NULL ||
(slen == 0 || slen >= PATH_MAX))) (slen == 0 || slen >= PATH_MAX)))
return 0; return 0;
return 1; return 1;
@@ -89,6 +126,7 @@ load_info(struct tlib *tl, const char *path)
{ {
size_t size = 1 << 14; size_t size = 1 << 14;
char buf[size], *p = buf; char buf[size], *p = buf;
const char *info;


if ((errno = read_whole_file((void **)&p, &size, path)) != 0) { if ((errno = read_whole_file((void **)&p, &size, path)) != 0) {
btpd_log(BTPD_L_ERROR, "couldn't load '%s' (%s).\n", path, btpd_log(BTPD_L_ERROR, "couldn't load '%s' (%s).\n", path,
@@ -98,39 +136,57 @@ load_info(struct tlib *tl, const char *path)


if (!valid_info(buf, size)) { if (!valid_info(buf, size)) {
btpd_log(BTPD_L_ERROR, "bad info file '%s'.\n", path); btpd_log(BTPD_L_ERROR, "bad info file '%s'.\n", path);
return ; return;
} }


tl->name = benc_dget_str(buf, "name", NULL); info = benc_dget_dct(buf, "info");
tl->dir = benc_dget_str(buf, "dir", NULL); tl->name = benc_dget_str(info, "name", NULL);
#if 0 tl->dir = benc_dget_str(info, "dir", NULL);
tl->t_added = benc_dget_int(buf, "time added"); tl->tot_up = benc_dget_int(info, "total upload");
tl->t_active = benc_dget_int(buf, "time active"); tl->tot_down = benc_dget_int(info, "total download");
tl->tot_up = benc_dget_int(buf, "total upload"); tl->content_size = benc_dget_int(info, "content size");
tl->tot_down = benc_dget_int(buf, "total download"); tl->content_have = benc_dget_int(info, "content have");
#endif
if (tl->name == NULL || tl->dir == NULL) if (tl->name == NULL || tl->dir == NULL)
btpd_err("out of memory.\n"); btpd_err("Out of memory.\n");
} }


static void static void
save_info(struct tlib *tl, const char *path) save_info(struct tlib *tl)
{ {
FILE *fp; FILE *fp;
char wpath[PATH_MAX]; char relpath[SHAHEXSIZE], path[PATH_MAX], wpath[PATH_MAX];
char *old = NULL;
size_t size = 1 << 14;
struct io_buffer iob = buf_init(1 << 10);

buf_print(&iob,
"d4:infod"
"12:content havei%llde12:content sizei%llde"
"3:dir%d:%s4:name%d:%s"
"14:total downloadi%llde12:total uploadi%llde"
"ee",
tl->content_have, tl->content_size,
(int)strlen(tl->dir), tl->dir, (int)strlen(tl->name), tl->name,
tl->tot_down, tl->tot_up);
if (iob.error)
btpd_err("Out of memory.\n");

if ((errno = read_whole_file((void **)&old, &size, path)) != 0
&& errno != ENOENT)
btpd_log(BTPD_L_ERROR, "couldn't load '%s' (%s).\n", path,
strerror(errno));

bin2hex(tl->hash, relpath, 20);
snprintf(path, PATH_MAX, "torrents/%s/info", relpath);
snprintf(wpath, PATH_MAX, "%s.write", path); snprintf(wpath, PATH_MAX, "%s.write", path);
if ((fp = fopen(wpath, "w")) == NULL) if ((fp = fopen(wpath, "w")) == NULL)
btpd_err("failed to open '%s' (%s).\n", wpath, strerror(errno)); btpd_err("failed to open '%s' (%s).\n", wpath, strerror(errno));
fprintf(fp, "d3:dir%d:%s4:name%d:%s", (int)strlen(tl->dir), tl->dir, if (old != NULL) {
(int)strlen(tl->name), tl->name); dct_subst_save(fp, old, iob.buf);
#if 0 free(old);
fprintf(fp, "11:time activei%lde10:time addedi%lde", tl->t_active, } else
tl->t_added); dct_subst_save(fp, "de", iob.buf);
fprintf(fp, "14:total downloadi%llde12:total uploadi%lldee", tl->tot_down, buf_free(&iob);
tl->tot_up);
#else
fprintf(fp, "e");
#endif
if (ferror(fp) || fclose(fp) != 0) if (ferror(fp) || fclose(fp) != 0)
btpd_err("failed to write '%s'.\n", wpath); btpd_err("failed to write '%s'.\n", wpath);
if (rename(wpath, path) != 0) if (rename(wpath, path) != 0)
@@ -138,6 +194,17 @@ save_info(struct tlib *tl, const char *path)
strerror(errno)); strerror(errno));
} }


void
tlib_update_info(struct tlib *tl)
{
assert(tl->tp != NULL);
tl->tot_down += tl->tp->net->downloaded;
tl->tot_up += tl->tp->net->uploaded;
tl->content_have = cm_content(tl->tp);
tl->content_size = tl->tp->total_length;
save_info(tl);
}

static void static void
write_torrent(const char *mi, size_t mi_size, const char *path) write_torrent(const char *mi, size_t mi_size, const char *path)
{ {
@@ -160,9 +227,6 @@ tlib_add(const uint8_t *hash, const char *mi, size_t mi_size,
const char *content, char *name) const char *content, char *name)
{ {
struct tlib *tl = tlib_create(hash); struct tlib *tl = tlib_create(hash);
#if 0
struct timeval tv;
#endif
char relpath[RELPATH_SIZE], file[PATH_MAX]; char relpath[RELPATH_SIZE], file[PATH_MAX];
bin2hex(hash, relpath, 20); bin2hex(hash, relpath, 20);


@@ -170,23 +234,18 @@ tlib_add(const uint8_t *hash, const char *mi, size_t mi_size,
if ((name = mi_name(mi)) == NULL) if ((name = mi_name(mi)) == NULL)
btpd_err("out of memory.\n"); btpd_err("out of memory.\n");


tl->content_size = mi_total_length(mi);
tl->name = name; tl->name = name;
tl->dir = strdup(content); tl->dir = strdup(content);
if (tl->name == NULL || tl->dir == NULL) if (tl->name == NULL || tl->dir == NULL)
btpd_err("out of memory.\n"); btpd_err("out of memory.\n");


#if 0
gettimeofday(&tv, NULL);
tl->t_added = tv.tv_sec;
#endif

snprintf(file, PATH_MAX, "torrents/%s", relpath); snprintf(file, PATH_MAX, "torrents/%s", relpath);
if (mkdir(file, 0777) != 0) if (mkdir(file, 0777) != 0)
btpd_err("failed to create dir '%s' (%s).\n", file, strerror(errno)); btpd_err("failed to create dir '%s' (%s).\n", file, strerror(errno));
snprintf(file, PATH_MAX, "torrents/%s/torrent", relpath); snprintf(file, PATH_MAX, "torrents/%s/torrent", relpath);
write_torrent(mi, mi_size, file); write_torrent(mi, mi_size, file);
snprintf(file, PATH_MAX, "torrents/%s/info", relpath); save_info(tl);
save_info(tl, file);
return tl; return tl;
} }




+ 5
- 3
btpd/tlib.h 查看文件

@@ -8,10 +8,10 @@ struct tlib {


char *name; char *name;
char *dir; char *dir;
#if 0
unsigned long long tot_up, tot_down; unsigned long long tot_up, tot_down;
long t_added, t_active; off_t content_size, content_have;
#endif
HTBL_ENTRY(nchain); HTBL_ENTRY(nchain);
HTBL_ENTRY(hchain); HTBL_ENTRY(hchain);
}; };
@@ -23,6 +23,8 @@ struct tlib *tlib_add(const uint8_t *hash, const char *mi, size_t mi_size,
const char *content, char *name); const char *content, char *name);
int tlib_del(struct tlib *tl); int tlib_del(struct tlib *tl);


void tlib_update_info(struct tlib *tl);

struct tlib *tlib_by_hash(const uint8_t *hash); struct tlib *tlib_by_hash(const uint8_t *hash);
struct tlib *tlib_by_num(unsigned num); struct tlib *tlib_by_num(unsigned num);
unsigned tlib_count(void); unsigned tlib_count(void);


+ 2
- 1
btpd/torrent.c 查看文件

@@ -171,8 +171,9 @@ torrent_stop(struct torrent *tp)
{ {
int tra, cma; int tra, cma;
switch (tp->state) { switch (tp->state) {
case T_STARTING:
case T_ACTIVE: case T_ACTIVE:
tlib_update_info(tp->tl);
case T_STARTING:
tp->state = T_STOPPING; tp->state = T_STOPPING;
if (net_active(tp)) if (net_active(tp))
net_stop(tp); net_stop(tp);


||||||
x
 
000:0
Loading…
取消
儲存