[alt.sources] vtalk, voice talk for Sparcs

emv@math.lsa.umich.edu (Edward Vielmetti) (03/02/90)

Found this while rummaging around in Japan.

Some high bits are set, so it might be somewhat garbled, and I can't
read Japanese no matter whatever the encoding is -- translation
welcomed.

I used port 2314 on duby.math.lsa.umich.edu to install this, everything
compiled but I don't know if it works.

--Ed
Edward Vielmetti, U of Michigan Math dept.


From: kamei@cs1.cs.oki.co.jp (Masako Kamei)
Newsgroups: fj.sources
Subject: vtalk for SPARCstation1
Date: 25 Jan 90 02:08:52 GMT
Distribution: fj
Organization: Oki Electric Industry Co.,Ltd. Warabi, Saitama, Japan.

!!$O$8$a$^$7$F!"2-EE5$$N550f$G$9!#

!!SUN SPARCstation1MQ$Nvtalk!JVoice TALK!K%3%^%s%I$G$9!#%M%C%H%o!<%/
$G$D$J$,$C$F$$$k!"#2Bf$NSUN SPARCstation1$K%^%$%/$r$D$1$k$H!"EEOC$N
$h$&$K$*OC$7$,$G$-$^$9!#$G$-$l$P!"%X%C%I%;%C%H$N$[$&$,<~0O$K%R%s%7%e%/
$r$+$o$:$K:Q$`$+$b$7$l$^$;$s!#$G$b!"$I$A$i$K$7$F$bFMA3%3%s%T%e!<%?$K
8~$+$C$FC}$j$@$9$H!"3'$,!I$I$&$7$?$s$@$m$&!"$3$N?M!#!I$H!"Gr$$L\$G8+
$^$9!#!J$3$s$J$3$H$r=q$/$H!"C/$b;H$C$F$/$l$J$$$+$b$7$l$J$$...!K

!!$H$K$+$/!"0lEY;H$C$F$_$F$/$@$5$$!#;H$$J}$K$D$$$F$O!"README$K=q$$$F
$"$j$^$9!#$40U8+!"$4MWK>!"$*BT$A$7$F$*$j$^$9!#


      *      *  	 				2-EE5$9)6H
  *      _  *    *					
   *    /_|    *   					550f!!2m;R
       (^_^)  *
   *  (     )   *   

			
------------------------------- CUT HERE ------------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	Makefile
#	README
#	audio.c
#	netwk.c
#	netwk.h
#	vtalk.c
#	vtalk.h
#	vtalkd.c
# This archive created: Thu Jan 25 10:41:37 JST 1990
export PATH; PATH=/bin:/usr/bin:/usr/ucb
if test -f Makefile
then
	echo "shar: will not over-write existing file 'Makefile'"
else
echo 'x - Makefile'
sed 's/^X//' << '\SHAR_EOF' > Makefile
X# 
X#   Copyright (c) 1989 Oki Electric Industry Co., Ltd.
X#
X#   This file is part of vtalk.
X#
X#   Permission to use, copy, modify and distribute this program without
X#   fee is grtanted,  provided that  the above  copyright notice appear
X#   in all copies.
X#
X#
X
XDEST	      = .
X
X#EXTHDRS	      = 
X
X#CFLAGS	      = -g -DDEBUG
X#CFLAGS	      = -g
XCFLAGS	      = -O
X
XHDRS	      = netwk.h		\
X		vtalk.h
X
XLDFLAGS	      = 
X
XLIBS	      = 
X
XWLIBS	      =
X
XLINKER	      = cc
X
XMAKEFILE      = Makefile
X
XOBJS	      = vtalk.o		\
X		netwk.o 	\
X		audio.o		
X
XDOBJS	      = vtalkd.o
X
XPRINT	      = pr
X
XPROGRAM	      = vtalk		\
X		vtalkd
X
XSRCS	      = vtalk.c		\
X		netwk.c		\
X		audio.c
X
XDSRCS         = vtalkd.c
X
Xall:		$(PROGRAM)
X
Xvtalk:		$(OBJS) $(LIBS) $(HDRS)
X		@echo -n "Loading vtalk ... "
X		@$(LINKER) $(LDFLAGS) $(OBJS) $(LIBS) -o vtalk
X		@echo "done"
X
Xvtalkd:		$(DOBJS) $(LIBS) $(HDRS)
X		@echo -n "Loading vtalkd ... "
X		@$(LINKER) $(LDFLAGS) $(DOBJS) $(LIBS) -o vtalkd
X		@echo "done"
X
Xclean:;		@rm -f $(OBJS) $(DOBJS)
X
Xdepend:;	@mkmf -f $(MAKEFILE) PROGRAM=$(PROGRAM) DEST=$(DEST)
X
Xindex:;		@ctags -wx $(HDRS) $(SRCS)
X
Xinstall:	$(PROGRAM)
X		@echo Installing $(PROGRAM) in $(DEST)
X		@install -s $(PROGRAM) $(DEST)
X
Xprint:;		@$(PRINT) $(HDRS) $(SRCS)
X
Xprogram:        $(PROGRAM)
X
Xtags:           $(HDRS) $(SRCS); @ctags $(HDRS) $(SRCS)
X
Xupdate:		$(DEST)/$(PROGRAM)
X
Xlint:;		lint $(SRCS)
X###
\SHAR_EOF
if test `wc -c < Makefile` -ne 1376
then
	echo "shar: 'Makefile' was damaged during transit (should have been 1376 bytes)"
fi
fi
if test -f README
then
	echo "shar: will not over-write existing file 'README'"
else
echo 'x - README'
sed 's/^X//' << '\SHAR_EOF' > README
X--------------------------
X#v#t#a#l#k%$%s%9%H!<%k<j=g
X--------------------------
X	1. #m#a#k#e$9$k!#
X		#2$D$N<B9T7A<0%U%!%$%k!"vtalk!"vtalkd$,:n@.$5$l$k!#
X
X	2. vtalk $r/usr/local/bin$K0\$9!#
X		% mv vtalk /usr/local/bin
X
X	3. vtalkd $r/usr/local/lib$K0\$9!#
X		% mv vtalkd /usr/local/lib
X
X
X------------------
X#v#t#a#l#k;HMQJ}K!
X------------------
X	
X vtalk $O!"SUN SPARCstation1 MQ$Nvoice talk%3%^%s%I$G$9!#vtalk%3%^%s%I$r
X;HMQ$9$k$K$O!"M=$avtalk%G!<%b%s$rN)$A>e$2$F$*$/I,MW$,$"$j$^$9!#0J2<$K!"
X
X	#1!%vtalk %3%^%s%I(vtalk)
X	#2!%vtalk %G!<%b%s(vtalkd)
X
X$N=g$G@bL@$7$^$9!#
X
X
X#1!%vtalk %3%^%s%I
X
XL>A0	vtalk -	voice talk to another user on SUN SPARCstation1
X
X7A<0!!!!vtalk [username@hostname]
X
X5!G=!!!!%^%7%s4V!JSUN SPARCstation1)$G"$*OC"$r$9$k!"talk%3%^%s%I$NvoiceHG!#
X
X;HMQ>r7o
X!J%O!<%I!K
X	1.#2Bf0J>eSUN SPARCstation1$,$"$k!#
X	2.3F%^%7%s$K%^%$%/$,<hIU$i$l$F$$$k!#
X
X!J%=%U%H!K
X	1./etc/services $K!""vtalk"$H$$$&%5!<%S%9$,tcp$GDj5A$5$l$F$$$k!#
X	Nc!Kvtalk           xxx/tcp
X	(xxx $O!"%7%9%F%`$G6u$$$F$$$kE,Ev$J%]!<%HHV9f$r;XDj$9$k!#!K
X
X	2.3F%^%7%s$G vtalkd(vtalk%G!<%b%s!K$,5/F0$5$l$F$$$k!#
X
X;HMQJ}K!
X!R8F$SB&!S
X	% vtalk Aj<j$NL>A0!wAj<j$N%^%7%sL>
X
X	Aj<j$N%^%7%s$G0J2<$N%a%C%;!<%8$,I=<($5$l$k!#
X
X	Message from VtalkDaemon at <time>...
X	vtalk:connection requested by 8F$SB&$NL>A0!w8F$SB&$N%^%7%sL>
X	vtalk:respond with: vtalk
X
X!R<u$1B&!S
X	% vtalk
X	(Cm0U :$3$3$G$O!"8F$SB&$NL>A0!w8F$SB&$N%^%7%sL>$r;XDj$7$J$$!#)
X
X
X#2!%vtalk %G!<%b%s
X
XL>A0	vtalkd - voice talk daemon
X
X7A<0	vtalkd
X
X5!G=	vtalk(voice talk)%3%^%s%I$r%5%]!<%H$9$k!"%G!<%b%s%W%m%0%i%`!#
X
X
X;HMQ>r7o
X	/etc/services $K!""vtalk"$H$$$&%5!<%S%9$,tcp$GDj5A$5$l$F$$$k!#
X
X;HMQJ}K!
X	%9!<%Q!<%f!<%6$K$J$j!"%P%C%/%0%i%&%s%I$GN)$A>e$2$k(rc.local
X	%U%!%$%kEy$G!K
X
X	# vtalkd &
X
X
\SHAR_EOF
if test `wc -c < README` -ne 2101
then
	echo "shar: 'README' was damaged during transit (should have been 2101 bytes)"
fi
fi
if test -f audio.c
then
	echo "shar: will not over-write existing file 'audio.c'"
else
echo 'x - audio.c'
sed 's/^X//' << '\SHAR_EOF' > audio.c
X/* 
X *   Copyright (c) 1989 Oki Electric Industry Co., Ltd.
X *
X *   This file is part of vtalk.
X *
X *   Permission to use, copy, modify and distribute this program without
X *   fee is grtanted,  provided that  the above  copyright notice appear
X *   in all copies.
X *
X */
X/*
X *  audio.c    audio control routine for vtalk
X *
X *  vtalk is a command for 
X *  Voice TALK with the user on another machine.
X *
X */
X
X#include <stdio.h>
X#include <sys/ioctl.h>            /* for audio */
X#include <sbusdev/audioreg.h>
X#include <sun/audioio.h>
X
Xint fd_audio;
X
X
Xdevice_open()
X{
X	struct audio_ioctl audioreg;
X	
X	if((fd_audio = open("/dev/audio", 2)) < 0){
X		fprintf(stderr,"vtalk: can't open /dev/audio\n");
X		exit(1);
X	}
X
X	/* set MMR1 register */
X	audioreg.control = AUDIO_MAP_MMR1;
X	audioreg.data[0] = AUDIO_MMR1_BITS_LOAD_GX |
X	  AUDIO_MMR1_BITS_LOAD_GR | AUDIO_MMR1_BITS_LOAD_GER;
X	if (ioctl(fd_audio,AUDIOSETREG,&audioreg) < 0) {
X		perror("vtalk: set MMR1 register");
X	}
X	
X	/* set MMR2 register                      *
X         * send the output to the builtin speaker */
X	audioreg.control = AUDIO_MAP_MMR2;
X	if (ioctl(fd_audio,AUDIOGETREG,&audioreg) < 0) {
X		perror("vtalk: set MMR2 register");
X	}
X	audioreg.data[0] |= AUDIO_MMR2_BITS_LS;
X	if (ioctl(fd_audio,AUDIOSETREG,&audioreg) < 0) {
X		perror("vtalk: set MMR2 register");
X	}
X	
X	return(fd_audio);
X}
X
X
Xvoid
Xset_volume()
X{
X	struct	audio_ioctl	audioreg;
X
X	/* register GR set 5db for play volume */
X	audioreg.control = AUDIO_MAP_GR;
X	audioreg.data[0] = 0x3b;
X	audioreg.data[1] = 0x11;
X	if (ioctl(fd_audio,AUDIOSETREG,&audioreg) < 0) {
X		perror("vtalk: set GR register");
X	}
X	
X	/* register GER set 5db for play volume */
X	audioreg.control = AUDIO_MAP_GER;
X	audioreg.data[0] = 0x31;
X	audioreg.data[1] = 0xdd;
X	if (ioctl(fd_audio,AUDIOSETREG,&audioreg) < 0) {
X		perror("vtalk: set GER register");
X	}
X	
X	/* register GX set 11db for record volume */
X	audioreg.control = AUDIO_MAP_GX;
X	audioreg.data[0] = 0x13;
X	audioreg.data[1] = 0x00;
X	if (ioctl(fd_audio,AUDIOSETREG,&audioreg) < 0) {
X		perror("vtalk: set GX register");
X	}
X}
X
X
X
X
\SHAR_EOF
if test `wc -c < audio.c` -ne 2069
then
	echo "shar: 'audio.c' was damaged during transit (should have been 2069 bytes)"
fi
fi
if test -f netwk.c
then
	echo "shar: will not over-write existing file 'netwk.c'"
else
echo 'x - netwk.c'
sed 's/^X//' << '\SHAR_EOF' > netwk.c
X/* 
X *   Copyright (c) 1989 Oki Electric Industry Co., Ltd.
X *
X *   This file is part of vtalk.
X *
X *   Permission to use, copy, modify and distribute this program without
X *   fee is grtanted,  provided that  the above  copyright notice appear
X *   in all copies.
X *
X */
X/*
X *  netwk.c    network control routine for vtalk
X *
X *  vtalk is a command for 
X *  Voice TALK with the user on another machine.
X *  
X */
X
X#include <errno.h>
X#include <stdio.h>
X#include <string.h>
X#include <netdb.h>
X#include <sys/file.h>
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <netinet/in.h>
X#include <sys/param.h>
X#include <sys/time.h>
X#include "netwk.h"
X
X
X/* #define BUFFER_SIZE	256    */
X#define BUFFER_SIZE	64    /* record */
X#define INT sizeof(int)
X
X
Xstruct daemon_msg msg;
X
Xstruct in_addr machine_addr; /* inet address */
Xint machine_addrtype;
Xint dsockt;        /* socket for daemon */
Xint vsockt;        /* socket for voice talk */
X
X
Xvoid
X  check_args(argc, argv, flag)
Xint argc;
Xchar **argv;
Xint *flag;
X{
X	char *my_name;
X	char his_name[256];
X	char *my_host;
X	char *his_host;
X	char host[MAXHOSTNAMELEN];
X	struct in_addr my_host_addr;
X	struct in_addr his_host_addr;
X	int his_host_addrtype;
X	int my_host_addrtype;
X	struct hostent *hp;
X	char *ap, *np;
X	char *getlogin();
X	
X	/* my name */
X	if ((my_name = getlogin()) == NULL) {
X		fprintf(stderr,"%s: you don't exist\n", argv[0]);
X		exit(1);
X	}
X	strcpy(msg.caller_name, my_name);
X	
X	/* my host name */
X	gethostname(host, sizeof (host));
X	my_host = host;
X	strcpy(msg.caller_host_name, host);
X	
X	if(argc == 1){		/* receiver */
X		
X	/* my host address */
X		if ((hp = gethostbyname(my_host))== (struct hostent *) 0) {
X			fprintf(stderr,
X				"%s: %s can't recognize network address.\n",
X				argv[0], my_host);
X			exit(1);
X		}
X		bcopy(hp->h_addr, (char *)&my_host_addr,
X		      hp->h_length);
X		my_host_addrtype = hp->h_addrtype;
X		*flag = 0;
X		machine_addr = my_host_addr;
X		machine_addrtype = my_host_addrtype;
X		
X		
X	}else {                 /* caller */
X		
X	/* his name & his host name */
X		ap = argv[1];
X		np = his_name;
X		while(*ap != '\0'){
X			*np = *ap;
X			if (*ap == '@') {
X				*np = '\0';
X				his_host = ++ap;
X				break;
X			} ap++;np++;
X		}
X		if(*ap == '\0') {
X			fprintf(stderr,"Usage: vtalk user@machine\n");
X			exit(1);
X		}
X		strcpy(msg.receiver_name, his_name);
X		
X	/* his host addrs */
X		if ((hp = gethostbyname(his_host)) == (struct hostent *) 0) {
X			fprintf(stderr,
X				"%s: %s can't recognize network address.\n",
X				argv[0], his_host);
X			exit(1);
X		}
X		bcopy(hp->h_addr, (char *) &his_host_addr, 
X		      hp->h_length);
X		his_host_addrtype = hp->h_addrtype;
X		
X		machine_addrtype = his_host_addrtype;
X		machine_addr = his_host_addr;
X		*flag = 1;       /* caller */
X		msg.sin.sin_addr = my_host_addr;
X	}
X	
X}
X
X
Xvoid
X  open_dsocket()
X{
X	struct sockaddr_in daemon; /* daemon sockname */
X	struct servent* sp;        /* server entry */
X	
X#ifdef DEBUG
X	fprintf(stderr,"vtalk:open_dsocket\n");
X#endif DEBUG
X	
X	/* vtalk server entry */
X	if((sp = getservbyname("vtalk","tcp")) == NULL){
X		fprintf(stderr,
X			"vtalk: undefined server entry\n");
X		exit(1);
X	}
X	bzero((char *)&daemon, sizeof(daemon));
X	daemon.sin_port = sp->s_port;
X	daemon.sin_addr = machine_addr;
X	daemon.sin_family = machine_addrtype;
X	
X	/* SOCKET for server */
X	if((dsockt = socket(AF_INET, SOCK_STREAM, 0)) < 0){
X		perror("vtalk: can't create socket");
X		exit(1);
X	}
X	
X	/* CONNECT to server */
X	if(connect(dsockt, (struct sockaddr *)&daemon, sizeof(daemon))
X	   < 0){
X		perror("vtalk: binding local socket");
X		exit(1);
X	}
X	
X}
X
X
Xcall_vtalkd(caller)
X     int caller;
X{
X	
X#ifdef DEBUG
X	fprintf(stderr,"vtalk:call vtalk daemon\n");
X#endif DEBUG
X	
X	/* WRITE msg to server */
X	msg.flag = caller;
X	if(write(dsockt, (char*)&msg, sizeof(struct daemon_msg)) !=
X	   sizeof(struct daemon_msg)){
X		perror("vtalk: lost the connection with daemon");
X		exit(1);
X	}
X
X	/* READ msg from server */
X	if(read(dsockt, (char*)&msg, sizeof(struct daemon_msg)) !=
X	   sizeof(struct daemon_msg)){
X		perror("vtalk: lost the connection with daemon");
X		exit(1);
X	}
X	
X	/* CLOSE daemon socket */
X	if(close(dsockt)){
X		perror("vtalk: can't close socket\n");
X	}
X
X	return(msg.status);
X}
X
X
X
Xvoid
X  call()
X{
X	struct sockaddr_in sin;
X	int sd;  
X
X#ifdef DEBUG 
X	fprintf(stderr,"vtalk:open vtalk socket\n");
X#endif DEBUG
X	
X	/* SOCKET for vtalk */
X	if((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
X		perror("vtalk: can't create socket");
X		exit(1);
X	}
X
X	/* BIND socket to given port no */
X	bzero((char *)&sin, sizeof(sin));
X	sin.sin_port = msg.sin.sin_port; 
X
X#ifdef DEBUG
X	fprintf(stderr,"vtalk:sin=%d %d %d \n",sin.sin_port,
X		sin.sin_addr,sin.sin_family);
X#endif DEBUG
X	
X	if(bind(sd, (struct sockaddr*)&sin, sizeof(sin))
X	   < 0){
X
X#ifdef DEBUG
X		fprintf(stderr,"vtalk:bind:errno = %d\n",errno);
X#endif DEBUG
X		
X		perror("vtalk: binding local socket");
X		exit(1);
X	}
X	
X	/* LISTEN */
X	listen(sd, 5);
X	
X#ifdef DEBUG
X	fprintf(stderr,"vtalk:caller:listen\n");
X#endif
X
X	/* waiting until ACCEPT */ 
X	while((vsockt = accept(sd, 0, 0)) < 0){
X		if(errno == EINTR)
X		  continue;
X		perror("vtalk: can't accept");
X	}
X
X#ifdef DEBUG
X	fprintf(stderr,"vtalk:caller:accepted\n");
X#endif
X	/* CLOSE old sockt */
X	close(sd);
X	
X}
X
X
Xvoid
X  response()
X{
X	struct sockaddr_in sin;
X
X#ifdef DEBUG 
X	fprintf(stderr,"vtalk:open vtalk socket\n");
X#endif DEBUG
X	
X	/* SOCKET for vtalk */
X	if((vsockt = socket(AF_INET, SOCK_STREAM, 0)) < 0){
X		perror("vtalk: can't create socket");
X		exit(1);
X	}
X
X	/* CONNECT to waiting caller */
X	sin.sin_family = msg.sin.sin_family;
X	sin.sin_port = msg.sin.sin_port;
X	sin.sin_addr = msg.sin.sin_addr;
X	if(connect(vsockt, (struct sockaddr*)&sin, 
X		   sizeof(sin)) < 0){
X		perror("vtalk: can't connect");
X		exit(1);
X	}	
X
X#ifdef DEBUG
X	fprintf(stderr,"vtalk:receiver:connected\n");
X#endif
X}
X
X
Xvoid
X  vtalk(audio_fd, caller)
Xint audio_fd;
Xint caller;
X{
X	int read_size;
X	char audio_buffer[BUFFER_SIZE];
X	char sockt_buffer[BUFFER_SIZE];
X	
X	read_size = BUFFER_SIZE;
X	if(caller){
X		while(1) {
X			read(vsockt, &sockt_buffer[0], read_size);
X			write(audio_fd, &sockt_buffer[0], read_size);
X			read(audio_fd, &audio_buffer[0], read_size);
X			write(vsockt, &audio_buffer[0], read_size);
X		}
X        }else{
X		while(1){
X			read(audio_fd, &audio_buffer[0], read_size);
X			write(vsockt, &audio_buffer[0], read_size);
X			read(vsockt, &sockt_buffer[0], read_size);
X			write(audio_fd, &sockt_buffer[0], read_size);
X		}
X        }
X}
X
X
Xstatic char *messages[] = {
X	"",
X	"Receiver is not existing",
X	"Receiver machine is too confused to vtalk",
X	"Receiver machine cannot recognize us",
X	"Receiver is refusing messages",
X	"Anyone is not waiting for you",
X};
X#define NANSWERS  (sizeof(messages) /sizeof (messages[0]))
X
X
Xoutput_err(status)
X     int status;
X{
X	if(status < NANSWERS)
X	  fprintf(stderr,"[%s]\n",messages[status]);
X	
X}
X
\SHAR_EOF
if test `wc -c < netwk.c` -ne 6791
then
	echo "shar: 'netwk.c' was damaged during transit (should have been 6791 bytes)"
fi
fi
if test -f netwk.h
then
	echo "shar: will not over-write existing file 'netwk.h'"
else
echo 'x - netwk.h'
sed 's/^X//' << '\SHAR_EOF' > netwk.h
X/* 
X *   Copyright (c) 1989 Oki Electric Industry Co., Ltd.
X *
X *   This file is part of vtalk.
X *
X *   Permission to use, copy, modify and distribute this program without
X *   fee is grtanted,  provided that  the above  copyright notice appear
X *   in all copies.
X *
X */
X
X#include "vtalk.h"
X
Xstruct daemon_msg {
X	int flag;            /* caller ? receiver flag */
X	int status;          /* is caller exist */
X	struct sockaddr_in sin;
X	char      caller_host_name[NAME_LEN];
X	char      caller_name[NAME_LEN]; 
X	char      receiver_name[NAME_LEN];
X
X};
\SHAR_EOF
if test `wc -c < netwk.h` -ne 547
then
	echo "shar: 'netwk.h' was damaged during transit (should have been 547 bytes)"
fi
fi
if test -f vtalk.c
then
	echo "shar: will not over-write existing file 'vtalk.c'"
else
echo 'x - vtalk.c'
sed 's/^X//' << '\SHAR_EOF' > vtalk.c
X/* 
X *   Copyright (c) 1989 Oki Electric Industry Co., Ltd.
X *
X *   This file is part of vtalk.
X *
X *   Permission to use, copy, modify and distribute this program without
X *   fee is grtanted,  provided that  the above  copyright notice appear
X *   in all copies.
X *
X */
X/*
X *  vtalk.c    main routione for vtalk
X *
X *  vtalk is a command for 
X *  Voice TALK with the user on another machine.
X *  
X */
X
X#include "vtalk.h"
X
Xmain(argc, argv)
Xint  argc;
Xchar *argv[];
X{
X	int caller;        /* caller ? receiver flag */
X	int audio_fd;
X	int status;
X
X	void check_args(), open_dsocket(), open_socket();
X	void call(), response(), vtalk();
X
X	check_args(argc, argv, &caller);
X	open_dsocket();
X	if((status= call_vtalkd(caller)) != SUCCESS){
X		/* not exit or not response or not waiting */
X		output_err(status);
X		exit(1);
X	}
X	if(caller)
X	  call();
X	else response();
X	audio_fd = device_open();
X	set_volume();
X
X	vtalk(audio_fd, caller);
X}
X
X
\SHAR_EOF
if test `wc -c < vtalk.c` -ne 929
then
	echo "shar: 'vtalk.c' was damaged during transit (should have been 929 bytes)"
fi
fi
if test -f vtalk.h
then
	echo "shar: will not over-write existing file 'vtalk.h'"
else
echo 'x - vtalk.h'
sed 's/^X//' << '\SHAR_EOF' > vtalk.h
X/* 
X *   Copyright (c) 1989 Oki Electric Industry Co., Ltd.
X *
X *   This file is part of vtalk.
X *
X *   Permission to use, copy, modify and distribute this program without
X *   fee is grtanted,  provided that  the above  copyright notice appear
X *   in all copies.
X *
X */
X
X#define MAX_QUEUE 10
X#define NAME_LEN 64
X
X/* server -> client msg.status */
X#define SUCCESS 0  
X#define NOEXIST 1  
X#define FAILED  2  
X#define UNKNOWN 3  
X#define PERMISSION_DENIED 4 
X#define NOWAIT 5 
\SHAR_EOF
if test `wc -c < vtalk.h` -ne 476
then
	echo "shar: 'vtalk.h' was damaged during transit (should have been 476 bytes)"
fi
fi
if test -f vtalkd.c
then
	echo "shar: will not over-write existing file 'vtalkd.c'"
else
echo 'x - vtalkd.c'
sed 's/^X//' << '\SHAR_EOF' > vtalkd.c
X/* 
X *   Copyright (c) 1989 Oki Electric Industry Co., Ltd.
X *
X *   This file is part of vtalkd.
X *
X *   Permission to use, copy, modify and distribute this program without
X *   fee is grtanted,  provided that  the above  copyright notice appear
X *   in all copies.
X *
X */
X/*
X *  vtalkd.c    main routine for vtalkd
X *
X *  vtalkd is a daemon for 
X *  Voice TALK with the user on another machine.
X *  
X */
X
X#include <errno.h>
X#include <stdio.h>
X#include <netdb.h>
X#include <sys/file.h>
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <sys/stat.h>
X#include <netinet/in.h>
X#include <utmp.h>
X#include <syslog.h>
X#include <sys/time.h>
X#include <signal.h>
X#include "netwk.h"
X
X
Xstruct sockaddr_in caller_queue[MAX_QUEUE];
Xint current_caller = 0;
Xint sockt;
Xint daemon_sockt;
X
Xmain(argc, argv)
X     int argc;
X     char *argv[];
X{
X	
X	struct daemon_msg msg;
X	char ftty[20];
X	void open_dsocket();
X	int die();
X	
X	/* super user ? */
X	if(getuid()){
X		fprintf(stderr,
X			"%s: getuid: not super user\n", argv[0]);
X		exit(1);
X	}
X	
X	openlog("vtalkd", LOG_PID, LOG_DAEMON);
X	
X	/*  daemon  */
X	open_dsocket();
X	
X	/* signal handler */
X	signal(SIGINT, die);
X	signal(SIGQUIT, die);
X	signal(SIGTERM, die);
X	
X	/* waiting for caller */
X	while(1){
X		receive_msg(&msg);
X		if(msg.flag){
X			if((msg.status = check_user(msg.receiver_name,
X						    ftty))== SUCCESS){
X				if((msg.status = open_socket(&msg))
X				   == SUCCESS)
X				  msg.status = announce(&msg, ftty);
X			}
X		} else	msg.status = check_caller(&msg.sin);
X		
X		return_msg(&msg); 
X		close(sockt);
X	}
X}
X
X
Xvoid
X  open_dsocket()
X{
X	struct sockaddr_in sin;
X	struct servent* sp;
X	
X	/* GETSERVBYNAME for vtalk */
X	if((sp = getservbyname("vtalk","tcp")) == NULL){
X		syslog(LOG_ERR, "getservbyname: %m");
X		exit(1);
X	}
X	
X	/* get port */
X	bzero((char *)&sin, sizeof(sin));
X	sin.sin_port = sp->s_port;
X	
X	/* SOCKET for server */
X	if((daemon_sockt = socket(AF_INET, SOCK_STREAM, 0)) < 0){
X		syslog(LOG_ERR, "socket: %m");
X		exit(1);
X	}
X
X	/* BIND to daemon port */
X	if(bind(daemon_sockt, (struct sockaddr*)&sin, sizeof(sin)) 
X	   < 0){
X		syslog(LOG_ERR, "bind: %m");
X		exit(1);
X	}
X	
X	/* LISTEN */
X	listen(daemon_sockt, 5);
X	
X}
X
X
Xreceive_msg(msg)
X     struct daemon_msg *msg;
X{
X	
X	/* waiting until ACCEPT msg */
X	while((sockt = accept(daemon_sockt, (struct sockaddr*)0,
X			      (int *)0)) < 0){
X		if(errno == EINTR)
X		  continue;
X		syslog(LOG_WARNING, "accept: %m");
X#ifdef DEBUG
X		fprintf(stderr,"errno = %d\n",errno);
X#endif DEBUG
X	}
X	
X	/* READ msg from client */
X	if(read(sockt, (char*)msg, sizeof(struct daemon_msg)) !=
X	   sizeof(struct daemon_msg)){
X		syslog(LOG_WARNING, "read: %m");
X		return(FAILED);
X	}
X	return(SUCCESS);
X}
X
X
Xcheck_user(name, ftty)
X     char *name;
X     char *ftty;
X{
X	struct utmp ubuf;
X	int status;
X	FILE *fp;
X	struct stat sbuf;
X	
X	/* open utmp file */
X	if ((fp = fopen("/etc/utmp", "r")) == NULL) {
X		perror("vtalk: can't open /etc/utmp");
X		return (FAILED);
X	}
X
X	/* check user existing */
X	status = NOEXIST;
X	strcpy(ftty, "/dev/");
X	while(fread((char*)&ubuf, sizeof ubuf, 1, fp) == 1)
X	  if(strncmp(ubuf.ut_name, name, sizeof(ubuf.ut_name)) == 0) {
X		  status = PERMISSION_DENIED;
X		  strcpy(ftty+5, ubuf.ut_line);
X		  if(stat(ftty, &sbuf) == 0) {
X			  if(!(sbuf.st_mode & 020))
X			    continue;
X#ifdef DEBUG 
X			  fprintf(stderr,"ftty: %s\n", ftty);
X#endif DEBUG
X			  status = SUCCESS;
X			  break;
X		  }
X	  }
X	fclose(fp);
X	return (status);
X}
X
X
Xopen_socket(msg)
X     struct daemon_msg *msg;
X{
X	struct sockaddr_in sin; /* address for caller */
X	int sd;                 /* socket discriptor */
X	int port;               /* port number for vtalk */
X	struct hostent *hp;
X	
X	/* SOCKET for caller & receiver */
X	if((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
X		syslog(LOG_ERR,"socket: %m");
X		close(daemon_sockt);
X		exit(1);
X	}
X	
X	/* BIND to port(>=5000) */
X	bzero((char *)&sin, sizeof(sin));
X	sin.sin_family = AF_INET;
X	sin.sin_addr.s_addr = htonl(INADDR_ANY);
X	port = IPPORT_USERRESERVED - 1;
X	do{
X		port++;
X		sin.sin_port = htons(port);
X	}while(bind(sd, (struct sockaddr*)&sin, sizeof(sin))!=0);
X	
X	/* return port number to client */
X	msg->sin.sin_port = htons(port);
X	
X	/* save request to caller_queue */
X	hp = gethostbyname(msg->caller_host_name);
X	if (hp == (struct hostent *) 0) {
X		return(UNKNOWN);
X	}
X	bcopy(hp->h_addr, (char *) &sin.sin_addr, hp->h_length);
X	caller_queue[current_caller].sin_port = htons(port);
X	caller_queue[current_caller].sin_addr = sin.sin_addr;
X	caller_queue[current_caller].sin_family = hp->h_addrtype;
X	current_caller++;
X	
X	/* CLOSE socket */
X	close(sd);
X	return(SUCCESS);
X}
X
X
Xannounce(msg, ftty)
X     struct daemon_msg *msg;
X     char *ftty;
X{
X	struct timeval tval;
X	struct timezone tzone;
X	struct tm *localtime();
X	struct tm *time;
X	FILE *fp;
X	
X	/* test ftty F_OK? */
X	if(access(ftty, 0) != 0)
X	  return(FAILED);
X	if((fp = fopen(ftty, "w")) == NULL)
X	  return(PERMISSION_DENIED);
X
X	/* get time */
X	gettimeofday(&tval, &tzone);
X	time = localtime(&tval.tv_sec);
X	
X	/* display message */
X	fprintf(fp,"\n");
X	fprintf(fp,"\007");
X	fprintf(fp,"Vtalk: message from vtalkdaemon at %d:%02d ...\n",
X		time->tm_hour, time->tm_min);
X	fprintf(fp,"Vtalk: connection requested by %s@%s.\n",
X		msg->caller_name, msg->caller_host_name);
X	fprintf(fp,"Vtalk: respond with: vtalk\n");
X	fflush(fp);
X
X	fclose(fp);
X	return(SUCCESS);
X}
X
X
Xcheck_caller(sin)
X     struct sockaddr_in *sin;
X{
X	if(current_caller == 0)
X	  return(NOWAIT);
X	else{
X		sin->sin_port = caller_queue[0].sin_port;
X		sin->sin_addr = caller_queue[0].sin_addr;
X		sin->sin_family = caller_queue[0].sin_family;
X		current_caller--;
X		return(SUCCESS);
X	}
X	
X}
X
X
Xreturn_msg(msg)
X     struct daemon_msg *msg;
X{
X	int x;
X	
X	/* WRITE msg to client */
X	x = write(sockt, (char*)msg, sizeof(struct daemon_msg));
X	if(x != sizeof(struct daemon_msg)){
X		syslog(LOG_WARNING, "write: %m");
X		return(FAILED);
X	}
X	return(SUCCESS);
X	
X}
X
X
Xdie(sig)
X     int sig;
X{
X	close(daemon_sockt);
X	exit(sig != 0);
X}
\SHAR_EOF
if test `wc -c < vtalkd.c` -ne 5910
then
	echo "shar: 'vtalkd.c' was damaged during transit (should have been 5910 bytes)"
fi
fi
	echo "End of part 1/1"
exit 0