vtalk, voice talk for Sparcs
Edward Vielmetti
emv at math.lsa.umich.edu
Fri Mar 2 16:09:52 AEST 1990
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 at 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 at .$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 at 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 at 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 at 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
More information about the Alt.sources
mailing list