539
544
xmlnode_insert_cdata(j->current, s, slen);
547
void cleanup_thread(void *arg)
549
struct pargs_r *argument = (struct pargs_r*)arg;
552
close(argument->fd_file);
553
close(argument->sock);
555
free(argument->hash);
557
free(argument->rfile);
562
void jabber_send_file(jconn j, const char *filename, long int size, struct send_file *file, void *rfile, void (*function)(void *file, long int bytes, long int size, int status, int conn_type), int start_port, int end_port) //returning ip address and port after binding
566
struct sockaddr_in addr;
569
int fd_file = open(filename, O_RDONLY);
573
sock = socket(AF_INET, SOCK_STREAM, 0);
580
addr.sin_family = AF_INET;
582
if( (start_port == 0) || (end_port == 0))
583
addr.sin_port = htons(0); //
585
addr.sin_port = htons(next_random(start_port,end_port)); //
587
struct sockaddr_in sa;
588
int sa_len = sizeof( sa );
589
getsockname( j->fd, (struct sockaddr *) &sa, &sa_len ); //geting address for bind
590
addr.sin_addr.s_addr = sa.sin_addr.s_addr;
592
// addr.sin_addr.s_addr = htonl(INADDR_ANY);
593
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval , sizeof(int)) < 0)
599
if ( (bind(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr)) ) < 0 )
603
if( errno == EADDRINUSE ) //select another port
604
addr.sin_port = htons(next_random(start_port, end_port)); //geting another random port
612
while(bind(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr)) < 0);
615
file->host = strdup(inet_ntoa(sa.sin_addr));
617
getsockname( sock, (struct sockaddr *) &sa, &sa_len );
618
file->port = (int) ntohs(sa.sin_port);
621
arg = (struct pargs_r *)calloc(1, sizeof(struct pargs_r));
626
arg->fd_file = fd_file;
631
arg->callback = function;
632
if (pthread_create(&file->thread, NULL, jabber_send_file_fd, (void *)arg ))
648
void *jabber_send_file_fd(void *arg)
651
struct pargs_r *argument;
654
struct sockaddr_in *addr;
656
argument = (struct pargs_r*)arg;
658
sock = argument->sock;
659
fd_file = argument->fd_file;
660
size = argument->size;
662
pthread_cleanup_push(cleanup_thread, argument);
663
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
666
char buff[SEND_BUF+1];
668
char sbuf[SEND_BUF+1];
671
int addr_size = sizeof( addr );
672
client = accept(sock, (struct sockaddr *) &addr, &addr_size);
676
n = recv(client, buff, SEND_BUF, 0);
677
if( strstr( buff, "GET /" ) )
679
snprintf( sbuf, SEND_BUF, "%d\r\n\r\n", size );
680
strncpy( buff, "HTTP/1.0 200 OK\r\nContent-Type: application/data\r\nContent-Length: ", SEND_BUF );
681
strncat( buff, sbuf, SEND_BUF );
682
int str_len = strlen( buff );
683
send( client, buff, str_len, 0);
684
while( ( n = read( fd_file, buff, SEND_BUF )) > 0 )
687
if( send( client, buff, n, 0) != n )
690
argument->callback(argument->rfile, counter, size, 0, 1);
697
if( counter == size )
698
argument->callback(argument->rfile, counter, size, 1, 1);
700
argument->callback(argument->rfile, counter, size, 2, 1);
702
pthread_cleanup_pop(1);
708
int next_random( int start_port, int end_port ) //generate random number between two digits
710
srand( time( NULL ) );
711
return (start_port + rand() % (end_port-start_port+1));
714
void jabber_get_file(jconn j, const char *filename, long int size, struct send_file *file, void *rfile, void (*function)(void *file, long int bytes, long int size, int status, int conn_type) ) //returning ip address and port after binding
718
struct sockaddr_in addr;
720
char *ip_addr = file->host;
721
char *sid_from_to = file->sid_from_to;
722
int port = file->port;
724
int fd_file = open(filename, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH );
728
sock = socket(AF_INET, SOCK_STREAM, 0);
735
struct hostent *host = gethostbyname(ip_addr);
736
bcopy(host->h_addr, &addr.sin_addr, host->h_length);
738
addr.sin_family = AF_INET;
739
addr.sin_port = htons( port );
742
if ( connect(sock, (struct sockaddr *) &addr, sizeof(addr) ) < 0 )
753
hash = shahash(sid_from_to);
756
arg = (struct pargs_r *)calloc(1, sizeof(struct pargs_r));
761
arg->fd_file = fd_file;
764
arg->hash = strdup( hash );
766
arg->url = file->url;
767
arg->callback = function;
768
if(file->transfer_type == 0)
770
if (pthread_create(&file->thread, NULL, jabber_recieve_file_fd, (void *)arg ))
780
if (pthread_create(&file->thread, NULL, jabber_recieve_file_fd_http, (void *)arg ))
797
void *jabber_recieve_file_fd(void *arg)
800
struct pargs_r *argument;
805
argument = (struct pargs_r*)arg;
807
sock = argument->sock;
808
fd_file = argument->fd_file;
809
size = argument->size;
810
hash = argument->hash;
811
pthread_cleanup_push(cleanup_thread, argument);
812
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
822
if( send( sock, buff, 3, 0 ) != 3 )
830
recv( sock, buff, SEND_BUF, 0 );
831
if( buff[0] != 0x05 || buff[1] != 0x00 )
839
//socks5 bytestream packet
845
strncpy( (char*)(buff + 5), hash, 40 );
849
if( send( sock, buff, 47, 0 ) != 47 )
856
recv( sock, buff, 47, 0 );
857
if( buff[0] != 0x05 || buff[3] != 0x03 )
870
bytes = recv( sock, buff, SEND_BUF, 0 );
875
write(fd_file, buff, bytes);
877
argument->callback(argument->rfile, counter, size, 0, 0);
881
if( counter == size )
882
argument->callback(argument->rfile, counter, size, 1, 0);
884
argument->callback(argument->rfile, counter, size, 2, 0);
886
pthread_cleanup_pop(1);
895
void *jabber_recieve_file_fd_http(void *arg)
898
struct pargs_r *argument;
903
argument = (struct pargs_r*)arg;
905
sock = argument->sock;
906
fd_file = argument->fd_file;
907
size = argument->size;
909
pthread_cleanup_push(cleanup_thread, argument);
910
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
914
snprintf( buff, SEND_BUF, "GET %s HTTP/1.0\r\n\r\n", url );
915
send( sock, buff, strlen(buff), 0 );
918
int but = recv( sock, buff, SEND_BUF, 0 );
919
if( strstr(buff, "200 OK" ) )
921
char *length = strstr( buff, "Content-Length:" );
922
sscanf( length, "Content-Length: %d", &size );
927
if(buff[i] == '\r' && buff[i+1] == '\n' && buff[i+2] == '\r' && buff[i+3] == '\n' )
938
write(fd_file, (buff+i), bytes);
943
bytes = recv( sock, buff, SEND_BUF, 0 );
948
write(fd_file, buff, bytes);
950
argument->callback(argument->rfile, counter, size, 0, 0);
954
if( counter == size )
955
argument->callback(argument->rfile, counter, size, 1, 0);
957
argument->callback(argument->rfile, counter, size, 2, 0);
960
pthread_cleanup_pop(1);