#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#define SERVER_PORT 9999
#define LINE_SPEED 128
const unsigned int BFFER_LEN = LINE_SPEED / 8 * 100
int main( int argc, char* argv[] ){
printf( "Rebroadcastinf 128 kbps mp3 stream without metadata\n" );
if( argc != 5 ){
printf( "%s stream_ip /stream_path stream_port local_port\n\n", argv[0] );
return 1;
}
int listener, k;
struct sockaddr_in addr;
char buf[BFFER_LEN], ch;
if( ( listener = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
exit( 1 );
addr.sin_family = AF_INET;
int shfd_buf = shmget( IPC_PRIVATE, BFFER_LEN, IPC_CREAT | S_IRWXU | S_IRWXG | S_IRWXO );
if( shfd_buf == -1 )
return 1;
int shfd_blink = shmget( IPC_PRIVATE, 1, IPC_CREAT | S_IRWXU | S_IRWXG | S_IRWXO );
if( shfd_blink == -1 )
return 1;
switch( fork() ){ // === 1 ===
case -1: perror("fork");break;
case 0:
char* sh_buf = (char*) shmat( shfd_buf, 0, 0 );
if( sh_buf == (char*) -1 ){
perror("sh_buf w");
exit( 2 );
}
char* sh_blink = (char*) shmat( shfd_blink, 0, 0 );
if( sh_blink == (char*) -1 ){
perror("sh_blink w");
exit( 2 );
}
addr.sin_port = htons( atoi( argv[3] ) );
addr.sin_addr.s_addr = inet_addr( argv[1] );
if( connect( listener, (struct sockaddr *) &addr, sizeof( addr ) ) < 0 ){
printf( "%s:%s\n" , argv[1], argv[3] );
perror( "connect" );
exit( 2 );
}
strcpy( buf, "GET " );
strncat( buf, argv[2], strlen( argv[1] ) );
strcat( buf, " HTTP/1.0\nUser-Agent: WinampMPEG/5.53\nAccept: */*Icy-MetaData:0\nConnection: close\n\n" );
send( listener, buf, strlen( buf ), 0 );
while( recv( listener, &ch, 1, 0 ) > 0 ){
strncat( buf, &ch, 1 );
if( strlen( buf ) < BFFER_LEN )
continue;
strcpy( sh_buf, buf );
strcpy( sh_blink, strcmp( "1", sh_blink ) ? "1" : "0" );
buf[0] = '0';
printf( "op\n" );
sleep(1);
}
shmdt( sh_buf );
shmdt( sh_blink );
close( listener );
_exit( 0 );
} // === 1 ===
int sock;
addr.sin_port = htons( atoi( argv[4] ) );
addr.sin_addr.s_addr = INADDR_ANY;
if( bind( listener, (struct sockaddr *) &addr, sizeof( addr ) ) < 0 ){
perror("listener 2");
exit( 2 );
}
listen( listener, 5 );
signal(SIGCHLD, SIG_IGN);
printf( "------------\n" );
fflush( stdout );
char* sh_buf = (char*) shmat( shfd_buf, 0, SHM_RDONLY );
if( sh_buf == (char*) -1 )
return 1;
char* sh_blink = (char*) shmat( shfd_blink, 0, 0 );
if( sh_blink == (char*) -1 )
return 1;
char tmp;
while( 1 ){
sock = accept( listener, NULL, NULL );
if( sock < 0 ){
perror( "accept" );
exit( 3 );
}
switch( fork() ){
case 0:
close(listener);
printf( "user connected\n" );
strcpy( buf, "ICY 200 OK\nicy-name: First Radio Project\n\n" );
while( recv( sock, &ch, 1, 0 ) > 0 );
send( sock, buf, strlen( buf ), 0 );
while( 1 ){
while( !strncmp( &tmp, sh_blink, 1 ) );
strncpy( &tmp, sh_blink, 1 );
send( sock, sh_buf, BFFER_LEN, 0 );
}
shmdt( sh_buf );
close( sock );
_exit( 0 );
default:
close( sock );
}
}
close( listener );
return 0;
}