#include <sys/utsname.h>
void disconnection (struct torrent * t) {
fprintf(stderr, "disconnecting from peer ");
peer_print(stderr, t->dl);
fprintf(stderr, " nfds=%ld, pollfds=%zu\n", *t->dht->nfds, *t->dht->pollfds_size);
for (size_t i = 0; i < *t->dht->nfds; i++) {
if ((*t->dht->pollfds)[i].fd == t->socket) {
if (i != (*t->dht->nfds)--)
(*t->dht->pollfds)[i] = (*t->dht->pollfds)[*t->dht->nfds];
break;
}
}
if (t->dl->flags & goodmeta) {
char buf[128];
bin2hex(buf, t->hash, 20);
strcpy(buf+40, ".torrent");
FILE * f = fopen(buf, "w+b");
if (!f) {
L(user, t->dht, "fopen(%s, \"w+b\"): %s", buf, strerror(errno));
return;
}
char remote[INET6_ADDRSTRLEN + 64];
if (!inet_ntop(t->dl->addr.sin6_family, t->dl->addr.sin6_addr.s6_addr, remote, INET6_ADDRSTRLEN+7))
snprintf(remote, sizeof remote, "(inet_ntop: %s)", strerror(errno));
sprintf(remote+strlen(remote), "/%d", ntohs(t->dl->addr.sin6_port));
char createdby[1024];
char unam[512];
char * machinetext = unam;
struct utsname utsname;
if (uname(&utsname) == -1)
snprintf(unam, 512, "uname(&utsname) == -1, errno == %d (%s)", errno, strerror(errno));
else
snprintf(unam, 512, "%s %s %s %s %s"
#ifdef _GNU_SOURCE
" %s"
#endif
, utsname.sysname, utsname.nodename, utsname.release, utsname.version, utsname.machine
#ifdef _GNU_SOURCE
, utsname.domainname
#endif
);
if (getenv("CREATED_BY"))
machinetext = getenv("CREATED_BY");
snprintf(createdby, 1024, "http://ni.šijanec.eu/sijanec/travnik mailto:tk@sijanec.eu %s", machinetext);
fprintf(f, "d10:created by%zu:%s13:creation datei%lde8:encoding5:UTF-84:info", strlen(createdby), createdby, time(NULL));
fwrite(t->metadata, 1, t->size, f); // i don't expect any errors here
fprintf(f, "6:sourced2:ip%zu:%s", strlen(remote), remote);
if (t->software)
fprintf(f, "1:v%zu:%s", strlen(t->software), t->software);
fputs("ee", f);
if (fclose(f) == EOF)
L(user, t->dht, "fclose(%s): %s", buf, strerror(errno));
}
#ifdef DISCONNECTION_MIXIN_BOTTOM
DISCONNECTION_MIXIN_BOTTOM
#endif
}
void intentions (struct torrent * t) {
for (size_t i = 0; i < *t->dht->nfds; i++)
if ((*t->dht->pollfds)[i].fd == t->socket) {
(*t->dht->pollfds)[i].events &= ~(POLLIN | POLLOUT);
if (t->state & incoming)
(*t->dht->pollfds)[i].events |= POLLIN;
if (t->state & outgoing)
(*t->dht->pollfds)[i].events |= POLLOUT;
}
fprintf(stderr, "tcp intentions: ");
peer_print(stderr, t->dl);
fprintf(stderr, " nfds=%ld, pollfds=%zu%s%s\n", *t->dht->nfds, *t->dht->pollfds_size, (t->state & incoming) ? " reading" : "", (t->state & outgoing) ? " writing" : "");
}
void connection (struct dht * d, struct torrent * t) {
if (*d->pollfds_size <= *d->nfds)
*d->pollfds = reallocarray(*d->pollfds, (*d->pollfds_size *= 2), sizeof **d->pollfds);
(*d->pollfds)[*d->nfds].events = POLLIN | POLLOUT;
(*d->pollfds)[(*d->nfds)++].fd = t->socket;
fprintf(stderr, "attempting to connect to peer ");
peer_print(stderr, t->dl);
fprintf(stderr, " nfds=%ld, pollfds=%zu\n", *d->nfds, *d->pollfds_size);
t->disconnection = disconnection;
t->dht = d;
t->intentions = intentions;
}