#include 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; }