/*
mtalkf -- full rate mtalk, using /dev/audio
sd = Scott Doty, scott@cs.santarosa.edu
Sun Mar 27 02:41:07 PST 1994
Extremely alpha -- use at your own risk -- don't blame me
or these guys:
*/

/* Copyright (C) 1993 Free Software Association of Germany

   The following is only valid, if you use this outside the Federal
   Republic of Germany.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   If you don't have a a copy of the GNU General Public License
   write to the Free Software Foundation, Inc., 675 Mass Ave, 
   Cambridge, MA 02139, USA.

   (C)opyright 1993,1994 FREE SOFTWARE ASSOCIATION OF GERMANY

   ----------------------------------------------------------------

   Fuer die Nutzung dieses Quell-Codes innerhalb der Bundesrepublik
   Deutschland gilt:

   Dieses Programm ist freie Software und kann unter den Bedingungen
   der Deutschen Free Software Lizenz weitergeben und/oder modifiziert
   werden.

   Wir haben dieses Programm in der Hoffnung entwickelt, dass es
   sich als nuetzlich erweist. Wir uebernehmen jedoch *KEINERLEI*
   Garantien auf die Funktion oder Verwendbarkeit dieses Programms.
   Der Anwender nutzt dieses Programm * AUF EIGENES RISIKO *

   Diesem Programm sollte eine Kopie der Deutschen Free Software Lizenz
   (DFSL) beigefuegt sein. Falls nicht, kann eine Kopie von uns angefordert
   werden: Free Software Association of Germany, Heimatring 19,
   60596 Frankfurt (info@elara.fsag..de), Telefon: ++49 - 69 - 6312083

   (C)opyright 1993,1994 FREE SOFTWARE ASSOCIATION OF GERMANY */


#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/soundcard.h>
#include <linux/time.h>
#include <time.h>
#include "mtalk.h"

#define AUDIO "/dev/audio"
#define TCP_PORT_MTALK	5105

int audio;
int VERBOSE = 1;
/* unsigned char sndbuff[100000]; *//*we'll use the read buffer*/
static unsigned char mb[SIZE_MB]; /* sd: that outta clear the rug. */

int s_b = 0;

#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
#endif

struct sockaddr_in	tcp_srv_addr;
struct sockaddr_in	myctladdr;
struct sockaddr_in	data_addr;
struct servent		tcp_serv_info;
struct hostent		tcp_host_info;

char current_ip[100];
char host[100];
int great_errno; 

#ifndef lint
static	char copyright[] =
"@(#) Copyright (c) 1993, 1994 Free Software Association of Germany.\n";
#endif

#ifndef lint
static char sccsid[] = "@(#) mtalk  Version 0.90f Fri 25 Mar 1994 15:37\n";
#endif 
    
#ifndef FD_SETSIZE
/* Forward compatability */
#define FD_SET(n, p)    ((p)->fds_bits[0] |= (1<<(n)))
#define FD_CLR(n, p)    ((p)->fds_bits[0] &= ~(1<<(n)))
#define FD_ISSET(n, p)  ((p)->fds_bits[0] & (1<<(n)))
#define FD_ZERO(p)      ((p)->fds_bits[0] = 0)
#endif


main(int argc, char **argv)
{

	strcpy(host,argv[1]); 

	while (1)	{
		printf("Listening: Hit [RETURN] to start your message for %s\n",host);	
		getchar();
		audio = open(AUDIO,O_RDONLY);
		send_sound();
		close(audio);
		}
}
	

send_sound()
{
	int m_b = 0;
	int a;
	int b,h;
	fd_set readfds;
	struct timeval timeout;
	char c;
 
	timeout.tv_usec = 10;
	timeout.tv_sec = 0;
 
	if (VERBOSE == 1)
		printf("mtalk: starting record\n");
	
	s_b = 0;
	printf("Recording: Hit [RETURN] to stop\n");	
	while (1)   {

		FD_ZERO(&readfds);
		FD_SET(0,&readfds);

		a = select(1,&readfds,(fd_set*)0,(fd_set *)0, &timeout);

		if (a > 0)	{
			if (VERBOSE == 1)
				printf("mtalk: ending record\n");
			read(0,&c,1);
			compress_buffer(mb,m_b); /* sd: not really compressed */
			return(0);
			}

		a = read(audio,&mb[m_b],1024);
		if (a <= 0)
			break; 
		m_b += a;
		}
}

compress_buffer(unsigned char *bu,int cnt)
{
FILE * fhd = NULL;
	int a,hd;
	char out[512];
	unsigned char la,by;
	char ccnt[8];
	int c = 0;

	la = 0x80;
/* should use memcpy(), but I was in a hurry.  sd */


	if (VERBOSE == 1)
		printf("mtalk: connecting to %s\n",host);
	hd = gl_tcp_open(host,NULL,TCP_PORT_MTALK);
	if (hd < 0)	{
		printf("mtalk: Unable to connect to %s\n",host);
		exit(0);
		}
	if (VERBOSE == 1)
		printf("mtalk: sending data\n");
	read_line(hd);
	sprintf(out,"%d\n",cnt);
	write(hd,out,strlen(out));
	read_line(hd);
	slow_write(hd,bu,cnt);
	sprintf(out,"0000\n");
	write(hd,out,strlen(out));
	close(hd);
	return (0); 
}

gl_tcp_open(host, service,port)
char *host;
char *service;
int port;
{
	struct in_addr adress;
	unsigned long ip_addr;
	int len;
	int fd, resvport;
	unsigned long inaddr;
	struct servent *sp;
	struct hostent *hp;

	bzero(( char *) &tcp_srv_addr, sizeof(tcp_srv_addr));
	tcp_srv_addr.sin_family = AF_INET;

	if (service != NULL)	{
		if (( sp = getservbyname(service,"tcp")) == NULL)	{
			return (-1);
			}
		tcp_serv_info = *sp;
		if (port > 0)
			tcp_srv_addr.sin_port = htons(port);
		else
			tcp_srv_addr.sin_port = sp->s_port;
		} 
	else	{
		if (port <= 0)	{
			great_errno = 101;
			return (-2);
			}
		tcp_srv_addr.sin_port = htons(port);
		}

	if ((inaddr = inet_addr(host)) != INADDR_NONE)	{
		bcopy((char *) &inaddr, (char *) &tcp_srv_addr.sin_addr,
			sizeof(inaddr));
		bcopy((char *) &inaddr, (char *) &adress.s_addr,
			sizeof(inaddr));
		tcp_host_info.h_name = NULL;
		}
	else	{
		if (( hp = gethostbyname(host)) == NULL)	{
			great_errno = 102;
			return (-3);	
			}
		tcp_host_info = *hp;
		bcopy(hp->h_addr, (char *) &tcp_srv_addr.sin_addr,
			hp->h_length);
		bcopy(hp->h_addr, (char *) &adress.s_addr,
			hp->h_length);
		}


        strcpy(current_ip,inet_ntoa(adress));

	if (port >= 0)	{
		if ((fd = socket(AF_INET, SOCK_STREAM,0)) < 0)	{
			great_errno = 108;
			return (-4);
			}
		}
	else if (port < 0)	{
		resvport = IPPORT_RESERVED -1;
		if (( fd = rresvport(&resvport) < 0))	{
			great_errno = 108;
			return (-5);
			}
		}
	alarm(60);
	if (connect(fd, (struct sockaddr *) &tcp_srv_addr,
		sizeof(tcp_srv_addr)) < 0)	{
		close(fd);
		great_errno = 107;
		alarm(0);
		return (-6);
		}

	len = sizeof (myctladdr);
	if (getsockname(fd, (struct sockaddr *)&myctladdr, &len) < 0) {
		perror("ftp: getsockname");
		alarm(0);
		close(fd);
		return(-7);
		}
	alarm(0);
	return (fd);
}


slow_write(int hd,char *s,int sz)
{
        int pos;
        int a;
        int written = 0;
        int tz;
        
        pos = 0;
        tz = sz;  


        while (1)       {
                a = write(hd,&s[pos],tz);
                if (a < 0)	
                        return (-1);
                pos +=a;
                tz -= a;
#ifdef DEBUG
                printf("slow_write: written <%d> towrite <%d>\n",pos,tz);
#endif
                if (pos >= sz)
                        return (pos);
                }

}

read_line(hd)
{
	char c;
	char bu[100];
	int a;

	a = 0;

	while (1)	{ 
		if (read(hd,&c,1)!= 1)
			break; 
		if (c == 10)
			break;
		bu[a++] = c;
		}
	bu[a] = 0;
	printf("<%s>\n",bu);
}

