Pārlūkot izejas kodu

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

amount we have in the info file.
master
Richard Nyberg pirms 18 gadiem
vecāks
revīzija
7ae55cac4d
3 mainītis faili ar 100 papildinājumiem un 38 dzēšanām
  1. +93
    -34
      btpd/tlib.c
  2. +5
    -3
      btpd/tlib.h
  3. +2
    -1
      btpd/torrent.c

+ 93
- 34
btpd/tlib.c Parādīt failu

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

if ((errno = read_whole_file((void **)&p, &size, path)) != 0) {
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)) {
btpd_log(BTPD_L_ERROR, "bad info file '%s'.\n", path);
return ;
return;
}

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

static void
save_info(struct tlib *tl, const char *path)
save_info(struct tlib *tl)
{
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);
if ((fp = fopen(wpath, "w")) == NULL)
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,
(int)strlen(tl->name), tl->name);
#if 0
fprintf(fp, "11:time activei%lde10:time addedi%lde", tl->t_active,
tl->t_added);
fprintf(fp, "14:total downloadi%llde12:total uploadi%lldee", tl->tot_down,
tl->tot_up);
#else
fprintf(fp, "e");
#endif
if (old != NULL) {
dct_subst_save(fp, old, iob.buf);
free(old);
} else
dct_subst_save(fp, "de", iob.buf);
buf_free(&iob);
if (ferror(fp) || fclose(fp) != 0)
btpd_err("failed to write '%s'.\n", wpath);
if (rename(wpath, path) != 0)
@@ -138,6 +194,17 @@ save_info(struct tlib *tl, const char *path)
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
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)
{
struct tlib *tl = tlib_create(hash);
#if 0
struct timeval tv;
#endif
char relpath[RELPATH_SIZE], file[PATH_MAX];
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)
btpd_err("out of memory.\n");

tl->content_size = mi_total_length(mi);
tl->name = name;
tl->dir = strdup(content);
if (tl->name == NULL || tl->dir == NULL)
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);
if (mkdir(file, 0777) != 0)
btpd_err("failed to create dir '%s' (%s).\n", file, strerror(errno));
snprintf(file, PATH_MAX, "torrents/%s/torrent", relpath);
write_torrent(mi, mi_size, file);
snprintf(file, PATH_MAX, "torrents/%s/info", relpath);
save_info(tl, file);
save_info(tl);
return tl;
}



+ 5
- 3
btpd/tlib.h Parādīt failu

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

char *name;
char *dir;
#if 0
unsigned long long tot_up, tot_down;
long t_added, t_active;
#endif
off_t content_size, content_have;
HTBL_ENTRY(nchain);
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);
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_num(unsigned num);
unsigned tlib_count(void);


+ 2
- 1
btpd/torrent.c Parādīt failu

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


Notiek ielāde…
Atcelt
Saglabāt