summaryrefslogblamecommitdiffstats
path: root/src/main.c
blob: 70b4d3e46025590360bba05d2c5b615fe1e3e9b1 (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;
int sigusr1 = 0;
void handler (int s) {
	switch (s) {
		case SIGINT:
		case SIGTERM:
			samomor++;
			break;
		case SIGALRM:
			periodično++;
			break;
		case SIGUSR1:
			sigusr1++;
			break;
	}
}
void found_torrent (struct dht * d __attribute__((unused)), const unsigned char * h) {
	char buf[41];
	bin2hex(buf, h, 20);
	buf[40] = '\0';
	L(stdout, "magnet:?xt=urn:btih:%s", buf);
}
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 (sigaction(SIGUSR1, &sigact, NULL) == -1)
		error_at_line(4, errno, __FILE__, __LINE__, "sigaction(SIGUSR1)");
	sigset_t sigset;
	if (sigemptyset(&sigset) == -1)
		error_at_line(5, errno, __FILE__, __LINE__, "sigemptyset");
	if (sigaddset(&sigset, SIGUSR1) == -1)
		error_at_line(6, errno, __FILE__, __LINE__, "sigaddset(SIGUSR1)");
	if (sigaddset(&sigset, SIGALRM) == -1)
		error_at_line(7, errno, __FILE__, __LINE__, "sigaddset(SIGALRM)");
	if (sigprocmask(SIG_UNBLOCK, &sigset, NULL) == -1)
		error_at_line(8, errno, __FILE__, __LINE__, "sigprocmask");
	/* struct itimerval itimerval = {
		.it_interval = {
			.tv_sec = 60
		}
	};
	if (setitimer(ITIMER_REAL, &itimerval, NULL) == -1)
		error_at_line(9, errno, __FILE__, __LINE__, "setitimer"); */
	if (argc != 1+1)
		error_at_line(10, 0, __FILE__, __LINE__, "%s configfile.ben >> possible_torrents.L", S0(argv[0]));
	int cf = open(argv[1], O_RDWR | O_CLOEXEC | O_CREAT, 00664);
	if (cf == -1)
		error_at_line(11, 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 = 12;
		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 = 13;
		goto r;
	}
	struct bencoding * config = bdecode(cfr, statbuf.st_size, replace);
	dht = dht_init(config);
	dht->possible_torrent = found_torrent;
	free_bencoding(config);
	struct torrent * torrent = torrent_init();
	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);
	struct pollfd pollfd = {
		.fd = dht->socket,
		.events = POLLIN
	};
w:
	alarm(13*60);
	while (poll(&pollfd, 1, -1) == 1)
		work(dht);
	if (errno == EINTR) {
		if (sigusr1) {
			sigusr1 = 0;
			dht_print(stdout, dht);
			goto w;
		}
		if (periodično) {
			periodično = 0;
			work(dht);
			goto w;
		}
		if (!samomor) {
			error_at_line(0, errno, __FILE__, __LINE__, "poll");
			r = 114;
		}
	} else {
		error_at_line(0, errno, __FILE__,  __LINE__, "poll");
		r = 115;
		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 = 116;
		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 = 117;
		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 = 118;
		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)");
	L(stderr, "exiting cleanly with status %d\n", r);
	return r;
}