summaryrefslogblamecommitdiffstats
path: root/src/main.c
blob: c14af388f6096e65b2a95f35f3a88b01e0d575b7 (plain) (tree)
1
2
3
4
5
6
7
8
9
10


                   




                     

                     
                          
                












                                      

                                   










                                                                                  
                        
                                                                                          

                                                                    
                                                                                 


                                                                                   
                      




                                                                                                                              
                      


                                                                           
                               
                               

































                                                                                                                      

                                 
                   

                                                                                                
                        




                                                                                                   
                        



                                                                                                                              
                        



                               
                      
          



                              




                                                                                                
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <error.h>
#include <fcntl.h>
#include <signal.h>
#include <poll.h>
#include <sys/time.h>
#define S0(x) (x ? x : "")
#include <dht.c>
int samomor = 0;
int periodično = 0;
void handler (int s) {
	switch (s) {
		case SIGINT:
		case SIGTERM:
			samomor++;
			break;
		case SIGALRM:
			periodično++;
			break;
	}
}
int main (int argc, char ** argv) {
	int r = 0;
	struct dht * dht = NULL;
	struct sigaction sigact = {
		.sa_handler = handler,
		.sa_flags = SA_RESTART
	};
	if (sigaction(SIGALRM, &sigact, NULL) == -1)
		error_at_line(1, errno, __FILE__, __LINE__, "sigaction(SIGALRM)");
	if (sigaction(SIGINT, &sigact, NULL) == -1)
		error_at_line(2, errno, __FILE__, __LINE__, "sigaction(SIGINT)");
	if (sigaction(SIGTERM, &sigact, NULL) == -1)
		error_at_line(3, errno, __FILE__, __LINE__, "sigaction(SIGTERM)");
	if (argc != 1+1)
		error_at_line(4, 0, __FILE__, __LINE__, "%s configfile.ben", S0(argv[0]));
	int cf = open(argv[1], O_RDWR | O_CLOEXEC | O_CREAT, 00664);
	if (cf == -1)
		error_at_line(5, errno, __FILE__, __LINE__, "open(%s)", argv[1]);
	struct stat statbuf;
	if (fstat(cf, &statbuf) == -1) {
		error_at_line(0, errno, __FILE__, __LINE__, "fstat(cf, &statbuf)");
		r = 6;
		goto r;
	}
	char * cfr = NULL;
	if (statbuf.st_size && !(cfr = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, cf, 0))) {
		error_at_line(0, errno, __FILE__, __LINE__, "mmap(NULL, %ld, PROT_READ, MAP_SHARED, cf, 0)", statbuf.st_size);
		r = 7;
		goto r;
	}
	struct bencoding * config = bdecode(cfr, statbuf.st_size, replace);
	dht = dht_init(config);
	free_bencoding(config);
	struct torrent * torrent = calloc(1, sizeof *torrent);
	memcpy(torrent->hash, "\xdd\x82\x55\xec\xdc\x7c\xa5\x5f\xb0\xbb\xf8\x13\x23\xd8\x70\x62\xdb\x1f\x6d\x1c", 20);
	torrent->type = announce | peers;
	add_torrent(dht, torrent);
	work(dht);
	struct pollfd pollfd = {
		.fd = dht->socket,
		.events = POLLIN
	};
	struct itimerval itimerval = {
		.it_interval = {
			.tv_sec = 13*60
		}
	};
	setitimer(ITIMER_REAL, &itimerval, NULL);
w:
	while (poll(&pollfd, 1, -1) == 1) {
		work(dht);
	}
	if (errno == EINTR) {
		if (periodično) {
			periodično = 0;
			work(dht);
			goto w;
		}
		if (!samomor) {
			error_at_line(0, errno, __FILE__, __LINE__, "poll");
			r = 108;
		}
	} else {
		error_at_line(0, errno, __FILE__,  __LINE__, "poll");
		r = 109;
		goto r;
	}
	config = persistent(dht);
	dht_free(dht);
	dht = NULL;
	if (cfr && munmap(cfr, statbuf.st_size) == -1) {
		error_at_line(0, errno, __FILE__, __LINE__, "munmap(cf, %ld)", statbuf.st_size);
		r = 110;
		goto r;
	}
	cfr = NULL;
	if (ftruncate(cf, (statbuf.st_size = bencode_length(config))) == -1) {
		error_at_line(0, errno, __FILE__, __LINE__, "ftruncate(cf, %ld)", statbuf.st_size);
		r = 111;
		goto r;
	}
	if (!(cfr = mmap(NULL, statbuf.st_size, PROT_WRITE, MAP_SHARED, cf, 0))) {
		error_at_line(0, errno, __FILE__, __LINE__, "mmap(NULL, %ld, PROT_READ, MAP_SHARED, cf, 0)", statbuf.st_size);
		r = 112;
		goto r;
	}
	bencode(cfr, config);
	free_bencoding(config);
	config = NULL;
	r:
	if (dht) {
		dht_free(dht);
		dht = NULL;
	}
	if (cfr && munmap(cfr, statbuf.st_size) == -1)
		error_at_line(0, errno, __FILE__, __LINE__, "munmap(cf, %ld)", statbuf.st_size);
	if (close(cf) == -1)
		error_at_line(0, errno, __FILE__, __LINE__, "close(cf)");
	return r;
}