| 
									
										
										
										
											2007-11-07 01:08:31 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Asterisk EAGI -> TCP/IP proxy | 
					
						
							|  |  |  |  * 	by Danijel Korzinek (devil_slayer _at_ hotmail.com) | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This simple C application allows you to control asterisk thru one TCP/IP | 
					
						
							|  |  |  |  * socket and listen to the conversation thru another socket. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Great for ASR or wizzard-of-oz telephony systems! | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * HOWTO: | 
					
						
							|  |  |  |  * 	The program is compiled using the following command: | 
					
						
							|  |  |  |  * 		gcc eagi_proxy.c -o eagi_proxy -lpthread | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 	In the dialplan, you can add something like this to the main context: | 
					
						
							|  |  |  |  * 		exten => s,1,Answer | 
					
						
							|  |  |  |  * 		exten => s,n,EAGI(/path/to/eagi_proxy) | 
					
						
							|  |  |  |  * 		exten => s,n,Hangup | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 	To test the program you can use the netcat utility: | 
					
						
							|  |  |  |  * 		(http://netcat.sourceforge.net/)
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 		-in one console run: | 
					
						
							|  |  |  |  * 			nc -vv -l -p 8418 > /path/to/file.raw | 
					
						
							|  |  |  |  * 		-in another run: | 
					
						
							|  |  |  |  * 			nc -vv -l -p 8417 | 
					
						
							|  |  |  |  * 		-you can use any file for the signal or even /dev/null | 
					
						
							|  |  |  |  * 		-you can change the port numbers in the sourcecode below | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 	Once you make the call, both programs will accept the incoming | 
					
						
							|  |  |  |  * 	connection. The program on port 8417 will print out the enviornemnt | 
					
						
							|  |  |  |  * 	(unless the appropriate define below is commented) and you can write | 
					
						
							|  |  |  |  * 	any AGI command there (http://www.voip-info.org/wiki-Asterisk+AGI),
 | 
					
						
							|  |  |  |  * 	e.g.: | 
					
						
							|  |  |  |  * 		GET DATA /path/to/gsm/file 10000 4 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 	Finally, you can open the RAW file in any sound editor. The format is: | 
					
						
							|  |  |  |  * 		RAW little-endian 8kHz 16bit | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <unistd.h>
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <netinet/in.h>
 | 
					
						
							|  |  |  | #include <netinet/tcp.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <time.h>
 | 
					
						
							|  |  |  | #include <sys/types.h>
 | 
					
						
							|  |  |  | #include <sys/stat.h>
 | 
					
						
							|  |  |  | #include <sys/socket.h>
 | 
					
						
							|  |  |  | #include <sys/time.h>
 | 
					
						
							|  |  |  | #include <arpa/inet.h>
 | 
					
						
							|  |  |  | #include <netdb.h>
 | 
					
						
							|  |  |  | #include <fcntl.h>
 | 
					
						
							|  |  |  | #include <errno.h>
 | 
					
						
							|  |  |  | #include <ctype.h>
 | 
					
						
							|  |  |  | #include <pthread.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* DEFINES */ | 
					
						
							|  |  |  | #define SIGNAL_PORT 8418
 | 
					
						
							|  |  |  | #define COMMAND_PORT 8417
 | 
					
						
							|  |  |  | #define SEND_ENVIORNMENT /*send the enviornment thru the socket*/
 | 
					
						
							|  |  |  | /************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define BUFSIZE 1024
 | 
					
						
							|  |  |  | char buf[BUFSIZE]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define WINSIZE 400 /* 25 ms @ 8 kHz and 16bit */
 | 
					
						
							|  |  |  | char window[WINSIZE]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define WINBUF_NUM 2400 /* number of WINSIZE windows = 1 minute */
 | 
					
						
							|  |  |  | char* winbuf; | 
					
						
							|  |  |  | char *end, *bs, *be; | 
					
						
							| 
									
										
										
										
											2017-12-22 09:23:22 -05:00
										 |  |  | /* winbuf - start of buffer
 | 
					
						
							|  |  |  |  * end - end of buffer | 
					
						
							| 
									
										
										
										
											2007-11-07 01:08:31 +00:00
										 |  |  |  * bs - start of data | 
					
						
							| 
									
										
										
										
											2017-12-22 09:23:22 -05:00
										 |  |  |  * be - end of data | 
					
						
							| 
									
										
										
										
											2007-11-07 01:08:31 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int command_desc; /* command transfer descriptor */ | 
					
						
							|  |  |  | int speech_desc; /* speech signal descrriptor */ | 
					
						
							|  |  |  | char connected=1; /* connection state */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int connect_to_host(char* host, int port); /* connect to a given host (name or IP) and given port number in nonblocking mode returning socket descriptor*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void read_full(int file, char* buffer, int num); /* read EXACTLY "num" ammount of bytes from "file" descriptor to "buffer"*/ | 
					
						
							|  |  |  | int read_some(int file, char* buffer, int size); /* read AT MOST "size" ammount of bytes */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void write_buf(int file, char* buffer, int num); /* write "num" ammount of bytes to "file" descriptor and buffer the surplus if the write would block */ | 
					
						
							|  |  |  | int write_amap(int file, char* buffer, int num); /*write AT MOST "num" ammount of bytes and return ammount that was written*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void setnonblocking(int desc); /*sets the socket non-blocking; for polling */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void finalize(); /* this function is run at exit */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | pthread_mutex_t command_mutex;/* command socket mutex */ | 
					
						
							|  |  |  | pthread_t stdin_thread,signal_thread; | 
					
						
							|  |  |  | void* readStdin(void* ptr); | 
					
						
							|  |  |  | void* readSignal(void* ptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* The program creates 3 threads:
 | 
					
						
							|  |  |  |  * 1) Main thread - reads commands from the socket and sends them to asterisk | 
					
						
							|  |  |  |  * 2) stdin_thread - reads asterisk output and sends it to the command socket | 
					
						
							|  |  |  |  * 3) signal_thread - reads the sound from asterisk and sends it to the signal socket | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int main() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int ret; | 
					
						
							| 
									
										
										
										
											2017-12-22 09:23:22 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-07 01:08:31 +00:00
										 |  |  | 	atexit(finalize); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	setlinebuf(stdin); | 
					
						
							|  |  |  | 	setlinebuf(stdout); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	winbuf=(char*)malloc(WINSIZE*WINBUF_NUM); | 
					
						
							|  |  |  | 	end=winbuf+WINSIZE*WINBUF_NUM; | 
					
						
							|  |  |  | 	bs=be=winbuf; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	speech_desc=connect_to_host("localhost",SIGNAL_PORT); | 
					
						
							| 
									
										
										
										
											2017-12-22 09:23:22 -05:00
										 |  |  | 	if(speech_desc<0) | 
					
						
							| 
									
										
										
										
											2007-11-07 01:08:31 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		perror("signal socket"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	command_desc=connect_to_host("localhost",COMMAND_PORT); | 
					
						
							| 
									
										
										
										
											2017-12-22 09:23:22 -05:00
										 |  |  | 	if(command_desc<0) | 
					
						
							| 
									
										
										
										
											2007-11-07 01:08:31 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		perror("command socket"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pthread_mutex_init(&command_mutex,NULL); | 
					
						
							|  |  |  | 	pthread_create(&stdin_thread,NULL,readStdin,NULL); | 
					
						
							|  |  |  | 	pthread_create(&signal_thread,NULL,readSignal,NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(connected) | 
					
						
							| 
									
										
										
										
											2017-12-22 09:23:22 -05:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2007-11-07 01:08:31 +00:00
										 |  |  | 		pthread_mutex_lock(&command_mutex); | 
					
						
							|  |  |  | 		ret=read_some(command_desc,buf,BUFSIZE); | 
					
						
							|  |  |  | 		pthread_mutex_unlock(&command_mutex); | 
					
						
							|  |  |  | 		if(ret>0) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			buf[ret]=0; | 
					
						
							| 
									
										
										
										
											2017-12-22 09:23:22 -05:00
										 |  |  | 			printf("%s",buf); | 
					
						
							| 
									
										
										
										
											2007-11-07 01:08:31 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void finalize() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	close(command_desc); | 
					
						
							|  |  |  | 	close(speech_desc); | 
					
						
							| 
									
										
										
										
											2017-12-22 09:23:22 -05:00
										 |  |  | 	free(winbuf); | 
					
						
							| 
									
										
										
										
											2007-11-07 01:08:31 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void* readStdin(void* ptr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	while(1)/*read enviornment*/ | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		fgets(buf,BUFSIZE,stdin); | 
					
						
							|  |  |  | 		#ifdef SEND_ENVIORNMENT
 | 
					
						
							|  |  |  | 			pthread_mutex_lock(&command_mutex); | 
					
						
							|  |  |  | 			write_buf(command_desc,buf,strlen(buf)); | 
					
						
							|  |  |  | 			pthread_mutex_unlock(&command_mutex); | 
					
						
							|  |  |  | 		#endif
 | 
					
						
							| 
									
										
										
										
											2017-12-22 09:23:22 -05:00
										 |  |  | 		if(feof(stdin) || buf[0]=='\n') | 
					
						
							| 
									
										
										
										
											2007-11-07 01:08:31 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(connected) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		fgets(buf,BUFSIZE,stdin); | 
					
						
							|  |  |  | 		pthread_mutex_lock(&command_mutex); | 
					
						
							|  |  |  | 		write_buf(command_desc,buf,strlen(buf)); | 
					
						
							|  |  |  | 		pthread_mutex_unlock(&command_mutex); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pthread_exit(NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void* readSignal(void* ptr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	while(connected) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		read_full(3,window,WINSIZE); | 
					
						
							|  |  |  | 		write_buf(speech_desc,window,WINSIZE); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pthread_exit(NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void read_full(int file, char* buffer, int num) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int count,pos=0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(num) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		count=read(file,buffer+pos,num); | 
					
						
							|  |  |  | 		if(count==0 || (count<0 && errno!=EAGAIN)) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			connected=0; | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		num-=count; | 
					
						
							|  |  |  | 		pos+=count; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int connect_to_host(char* name, int port) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int address; | 
					
						
							|  |  |  | 	struct hostent* host_entity; | 
					
						
							|  |  |  | 	int res,desc; | 
					
						
							|  |  |  | 	int opts; | 
					
						
							|  |  |  | 	struct sockaddr_in host; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-22 09:23:22 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* get address */ | 
					
						
							| 
									
										
										
										
											2007-11-07 01:08:31 +00:00
										 |  |  | 	if(!strcmp(name,"localhost")) | 
					
						
							|  |  |  | 		address=htonl(2130706433); /*127.0.0.1*/ | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		address=inet_addr(name); /* check if it's an IP that's written in the string */ | 
					
						
							|  |  |  | 		if(address==(in_addr_t)-1) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			host_entity = gethostbyname(name); /* search for the host under this name */ | 
					
						
							| 
									
										
										
										
											2017-12-22 09:23:22 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-07 01:08:31 +00:00
										 |  |  | 			if(!host_entity) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				fprintf(stderr,"EAGI proxy: Wrong address!\n"); /* can't find anything*/ | 
					
						
							|  |  |  | 				return -1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			address=*((int*)host_entity->h_addr); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	desc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); | 
					
						
							|  |  |  | 	if(desc<0) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		fprintf(stderr,"EAGI proxy: Cannot create socket!\n"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memset((void*)&host,0,sizeof(struct sockaddr_in)); | 
					
						
							| 
									
										
										
										
											2017-12-22 09:23:22 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-07 01:08:31 +00:00
										 |  |  | 	host.sin_family=AF_INET; | 
					
						
							|  |  |  | 	host.sin_port=htons(port); | 
					
						
							|  |  |  | 	host.sin_addr.s_addr=address; | 
					
						
							| 
									
										
										
										
											2017-12-22 09:23:22 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-07 01:08:31 +00:00
										 |  |  | 	res=connect(desc,(struct sockaddr*)&host,sizeof(host)); | 
					
						
							|  |  |  | 	if(res<0) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		fprintf(stderr,"EAGI proxy: Cannot connect!\n"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* set to non-blocking mode */ | 
					
						
							|  |  |  | 	opts = fcntl(desc,F_GETFL); | 
					
						
							|  |  |  | 	if (opts < 0) { | 
					
						
							|  |  |  | 		perror("fcntl(F_GETFL)"); | 
					
						
							|  |  |  | 		exit(EXIT_FAILURE); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	opts = (opts | O_NONBLOCK); | 
					
						
							|  |  |  | 	if (fcntl(desc,F_SETFL,opts) < 0) { | 
					
						
							|  |  |  | 		perror("fcntl(F_SETFL)"); | 
					
						
							|  |  |  | 		exit(EXIT_FAILURE); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return desc; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int read_some(int desc, char* buffer, int size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned char c; | 
					
						
							|  |  |  | 	int res,i=0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for(;;) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		res=read(desc,&c,1); | 
					
						
							|  |  |  | 		if(res<1) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if(errno!=EAGAIN) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				perror("Error reading"); | 
					
						
							|  |  |  | 				connected=0; | 
					
						
							| 
									
										
										
										
											2017-12-22 09:23:22 -05:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2007-11-07 01:08:31 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-12-22 09:23:22 -05:00
										 |  |  | 		if(res==0) | 
					
						
							| 
									
										
										
										
											2007-11-07 01:08:31 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			connected=0; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-12-22 09:23:22 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-07 01:08:31 +00:00
										 |  |  | 		buffer[i]=c; | 
					
						
							|  |  |  | 		i++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return i; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* This is a tricky function! */ | 
					
						
							|  |  |  | void write_buf(int desc, char* buf, int size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*NOTE: AMAP -> as much as possible */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(be!=bs)/* if data left in buffer */ | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if(be>bs)/* if buffer not split */ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			ret=write_amap(desc,bs,be-bs);/* write AMAP */ | 
					
						
							|  |  |  | 			bs+=ret;/* shift the start of the buffer */ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else/* if buffer is split */ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			ret=write_amap(desc,bs,end-bs);/* write higher part first */ | 
					
						
							|  |  |  | 			if(ret==end-bs)/* if wrote whole of the higher part */ | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				ret=write_amap(desc,winbuf,be-winbuf);/* write lower part */ | 
					
						
							|  |  |  | 				bs=winbuf+ret;/* shift start to new position */ | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else bs+=ret;/* if not wrote whole of higher part, only shift start */ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(be==bs)/* if buffer is empty now */ | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		ret=write_amap(desc,buf,size);/* write AMAP of the new data */ | 
					
						
							|  |  |  | 		buf+=ret;/* shift start of new data */ | 
					
						
							|  |  |  | 		size-=ret;/* lower size of new data */ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(size)/* if new data still remains unsent */ | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if(be>=bs)/* if data not split */ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if(size>end-be)/* if new data size doesn't fit higher end */ | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				size-=end-be;/* reduce new data size by the higher end size */ | 
					
						
							|  |  |  | 				memcpy(be,buf,end-be);/* copy to higher end */ | 
					
						
							|  |  |  | 				be=winbuf;/* shift end to begining of buffer */ | 
					
						
							|  |  |  | 				buf+=end-be;/* shift start of new data */ | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else/* if new data fits the higher end */ | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				memcpy(be,buf,size);/* copy to higher end */ | 
					
						
							|  |  |  | 				be+=size;/* shift end by size */ | 
					
						
							|  |  |  | 				if(be>=end)/* if end goes beyond the buffer */ | 
					
						
							|  |  |  | 					be=winbuf;/* restart */ | 
					
						
							|  |  |  | 				size=0;/* everything copied */ | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(size)/* if new data still remains */ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if(size>=bs-be)/* if new data doesn't fit between end and start */ | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				fprintf(stderr,"Buffer overflow!\n"); | 
					
						
							|  |  |  | 				size=bs-be-1;/* reduce the size that we can copy */ | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(size)/* if we can copy anything */ | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				memcpy(be,buf,size);/* copy the new data between end and start */ | 
					
						
							|  |  |  | 				be+=size;/* shift end by size */ | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int write_amap(int desc, char* buf, int size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 	ret=write(desc,buf,size); | 
					
						
							|  |  |  | 	if(ret<0) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2017-12-22 09:23:22 -05:00
										 |  |  | 		if(errno!=EAGAIN) | 
					
						
							| 
									
										
										
										
											2007-11-07 01:08:31 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			perror("Error writing"); | 
					
						
							|  |  |  | 			connected=0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if(ret==0) | 
					
						
							|  |  |  | 		connected=0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void setnonblocking(int desc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int opts; | 
					
						
							| 
									
										
										
										
											2017-12-22 09:23:22 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-07 01:08:31 +00:00
										 |  |  | 	opts = fcntl(desc,F_GETFL); | 
					
						
							|  |  |  | 	if(opts < 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		perror("fcntl(F_GETFL)"); | 
					
						
							|  |  |  | 		exit(-1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	opts = (opts | O_NONBLOCK ); | 
					
						
							|  |  |  | 	if(fcntl(desc,F_SETFL,opts) < 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		perror("fcntl(F_SETFL)"); | 
					
						
							|  |  |  | 		exit(-1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |