games@tekred.TEK.COM (05/31/88)
Submitted by: Jiang-Hsing Chu <jchu@mimsy.umd.edu> Comp.sources.games: Volume 4, Issue 20 Archive-name: bridge/Part02 [Oops! Forgot to mention in Part01 that this does look BSD specific. I don't know what it would take to get it running on SysV. -br] #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 2 (of 2)." # Contents: Makefile ctl.c ctl.h get_addrs.c get_names.c # invitebridge.README slave_talk.c talk.h talk_ctl.h # Wrapped by billr@saab on Tue May 31 09:13:31 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f Makefile -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"Makefile\" else echo shar: Extracting \"Makefile\" \(478 characters\) sed "s/^X//" >Makefile <<'END_OF_Makefile' X# Makefile for multi-player bridge X XOBJ1 = master_talk.o bridge.o get_names.o master_io.o msgs.o ctl.o init_disp.o get_addrs.o ctl_transact.o invite.o look_up.o X XOBJ2 = slave_talk.o get_names.o slave_io.o msgs.o ctl.o init_disp.o get_addrs.o ctl_transact.o invite.o look_up.o X Xall: invitebridge bridge X Xinvitebridge: $(OBJ1) X cc -O -o invitebridge $(OBJ1) -lcurses -ltermlib X Xbridge: $(OBJ2) X cc -O -o bridge $(OBJ2) -lcurses -ltermlib X Xclean: X -rm *.o bridge invitebridge END_OF_Makefile if test 478 -ne `wc -c <Makefile`; then echo shar: \"Makefile\" unpacked with wrong size! fi # end of overwriting check fi if test -f ctl.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"ctl.c\" else echo shar: Extracting \"ctl.c\" \(1868 characters\) sed "s/^X//" >ctl.c <<'END_OF_ctl.c' X#ifndef lint Xstatic char sccsid[] = "@(#)ctl.c 1.1 86/02/05 SMI"; /* from UCB 1.4 83/06/09 */ X#endif X X/* This file handles haggling with the various talk daemons to X get a socket to talk to. sockt is opened and connected in X the progress X */ X X#include "talk_ctl.h" X Xstruct sockaddr_in daemon_addr = { AF_INET }; Xstruct sockaddr_in ctl_addr = { AF_INET }; Xstruct sockaddr_in my_addr = { AF_INET }; X X /* inet addresses of the two machines */ Xstruct in_addr my_machine_addr; Xstruct in_addr his_machine_addr; X Xu_short daemon_port; /* port number of the talk daemon */ X Xint ctl_sockt; Xint sockt; Xint invitation_waiting = 0; X XCTL_MSG msg; X Xopen_sockt() X{ X int length; X X my_addr.sin_addr = my_machine_addr; X my_addr.sin_port = 0; X X sockt = socket(AF_INET, SOCK_STREAM, 0, 0); X X if (sockt <= 0) { X p_error("Bad socket"); X } X X if ( bind(sockt, &my_addr, sizeof(my_addr)) != 0) { X p_error("Binding local socket"); X } X X length = sizeof(my_addr); X X if (getsockname(sockt, &my_addr, &length) == -1) { X p_error("Bad address for socket"); X } X} X X /* open the ctl socket */ X Xopen_ctl() X{ X int length; X X ctl_addr.sin_port = 0; X ctl_addr.sin_addr = my_machine_addr; X X ctl_sockt = socket(AF_INET, SOCK_DGRAM, 0, 0); X X if (ctl_sockt <= 0) { X p_error("Bad socket"); X } X X if (bind(ctl_sockt, &ctl_addr, sizeof(ctl_addr), 0) != 0) { X p_error("Couldn't bind to control socket"); X } X X length = sizeof(ctl_addr); X if (getsockname(ctl_sockt, &ctl_addr, &length) == -1) { X p_error("Bad address for ctl socket"); X } X} X X/* print_addr is a debug print routine */ X Xprint_addr(addr) Xstruct sockaddr_in addr; X{ X int i; X X printf("addr = %x, port = %o, family = %o zero = ", X addr.sin_addr, addr.sin_port, addr.sin_family); X X for (i = 0; i<8;i++) { X printf("%o ", (int)addr.sin_zero[i]); X } X putchar('\n'); X} END_OF_ctl.c if test 1868 -ne `wc -c <ctl.c`; then echo shar: \"ctl.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f ctl.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"ctl.h\" else echo shar: Extracting \"ctl.h\" \(1170 characters\) sed "s/^X//" >ctl.h <<'END_OF_ctl.h' X/* @(#)ctl.h 1.1 86/02/05 SMI; from UCB 1.4 83/03/28 */ X X/* ctl.h describes the structure that talk and talkd pass back X and forth X */ X X#include <sys/types.h> X#include <sys/socket.h> X#include <netinet/in.h> X#include <netdb.h> X X#define NAME_SIZE 9 X#define TTY_SIZE 16 X#define HOST_NAME_LENGTH 256 X X#define MAX_LIFE 60 /* maximum time an invitation is saved by the X talk daemons */ X#define RING_WAIT 30 /* time to wait before refreshing invitation X should be 10's of seconds less than MAX_LIFE */ X X /* the values for type */ X X#define LEAVE_INVITE 0 X#define LOOK_UP 1 X#define DELETE 2 X#define ANNOUNCE 3 X X /* the values for answer */ X X#define SUCCESS 0 X#define NOT_HERE 1 X#define FAILED 2 X#define MACHINE_UNKNOWN 3 X#define PERMISSION_DENIED 4 X#define UNKNOWN_REQUEST 5 X Xtypedef struct ctl_response CTL_RESPONSE; X Xstruct ctl_response { X char type; X char answer; X int id_num; X struct sockaddr_in addr; X}; X Xtypedef struct ctl_msg CTL_MSG; X Xstruct ctl_msg { X char type; X char l_name[NAME_SIZE]; X char r_name[NAME_SIZE]; X int id_num; X int pid; X char r_tty[TTY_SIZE]; X struct sockaddr_in addr; X struct sockaddr_in ctl_addr; X}; END_OF_ctl.h if test 1170 -ne `wc -c <ctl.h`; then echo shar: \"ctl.h\" unpacked with wrong size! fi # end of overwriting check fi if test -f get_addrs.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"get_addrs.c\" else echo shar: Extracting \"get_addrs.c\" \(1678 characters\) sed "s/^X//" >get_addrs.c <<'END_OF_get_addrs.c' X#ifndef lint Xstatic char sccsid[] = "@(#)get_addrs.c 1.1 86/02/05 SMI"; /* from UCB 1.5 83/04/01 */ X#endif X X#include "talk_ctl.h" X Xstruct hostent *gethostbyname(); Xstruct servent *getservbyname(); X Xget_addrs(my_machine_name, his_machine_name) Xchar *my_machine_name; Xchar *his_machine_name; X{ X struct hostent *hp; X struct servent *sp; X X msg.pid = getpid(); X X /* look up the address of the local host */ X X hp = gethostbyname(my_machine_name); X X if (hp == (struct hostent *) 0) { X printf("This machine doesn't exist. Boy, am I confused!\n"); X exit(-1); X } X X if (hp->h_addrtype != AF_INET) { X printf("Protocal mix up with local machine address\n"); X exit(-1); X } X X bcopy(hp->h_addr, (char *)&my_machine_addr, hp->h_length); X X /* if he is on the same machine, then simply copy */ X X if ( bcmp((char *)&his_machine_name, (char *)&my_machine_name, X sizeof(his_machine_name)) == 0) { X bcopy((char *)&my_machine_addr, (char *)&his_machine_addr, X sizeof(his_machine_name)); X } else { X X /* look up the address of the recipient's machine */ X X hp = gethostbyname(his_machine_name); X X if (hp == (struct hostent *) 0 ) { X printf("%s is an unknown host\n", his_machine_name); X exit(-1); X } X X if (hp->h_addrtype != AF_INET) { X printf("Protocol mix up with remote machine address\n"); X exit(-1); X } X X bcopy(hp->h_addr, (char *) &his_machine_addr, hp->h_length); X } X X /* find the daemon portal */ X X#ifdef NTALK X sp = getservbyname("ntalk", "udp"); X#else X sp = getservbyname("talk", "udp"); X#endif X X if (strcmp(sp->s_proto, "udp") != 0) { X printf("Protocol mix up with talk daemon\n"); X exit(-1); X } X X daemon_port = sp->s_port; X} END_OF_get_addrs.c if test 1678 -ne `wc -c <get_addrs.c`; then echo shar: \"get_addrs.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f get_names.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"get_names.c\" else echo shar: Extracting \"get_names.c\" \(2077 characters\) sed "s/^X//" >get_names.c <<'END_OF_get_names.c' X#ifndef lint Xstatic char sccsid[] = "@(#)get_names.c 1.1 86/02/05 SMI"; /* from UCB 1.2 83/03/26 */ X#endif X X#include "talk.h" X#include "ctl.h" X Xchar *getlogin(), *ttyname(), *rindex(); X Xextern CTL_MSG msg; X X/* X * Determine the local and remote user, tty, and machines X */ X Xstruct hostent *gethostbyname(); X Xget_names(argc, argv) Xint argc; Xchar *argv[]; X{ X char hostname[HOST_NAME_LENGTH]; X char *his_name; X char *my_name; X char *my_machine_name; X char *his_machine_name; X char *my_tty; X char *his_tty; X char *ptr; X int name_length; X X if (argc < 2 ) { X printf("Usage: talk user [ttyname]\n"); X exit(-1); X } X if ( !isatty(0) ) { X printf("Standard input must be a tty, not a pipe or a file\n"); X exit(-1); X } X X my_name = getlogin(); X if (my_name == NULL) { X printf("You don't exist. Go away.\n"); X exit(-1); X } X X name_length = HOST_NAME_LENGTH; X gethostname(hostname, &name_length); X my_machine_name = hostname; X X my_tty = rindex(ttyname(0), '/') + 1; X X /* check for, and strip out, the machine name X of the target */ X X for (ptr = argv[1]; *ptr != '\0' && X *ptr != '@' && X *ptr != ':' && X *ptr != '!' && X *ptr != '.' ; ptr++) { X } X X if (*ptr == '\0') { X X /* this is a local to local talk */ X X his_name = argv[1]; X his_machine_name = my_machine_name; X X } else { X X if (*ptr == '@') { X /* user@host */ X his_name = argv[1]; X his_machine_name = ptr + 1; X } else { X /* host.user or host!user or host:user */ X his_name = ptr + 1; X his_machine_name = argv[1]; X } X *ptr = '\0'; X } X X X if (argc > 2) { X his_tty = argv[2]; /* tty name is arg 2 */ X } else { X his_tty = ""; X } X X get_addrs(my_machine_name, his_machine_name); X X /* Load these useful values into the standard message header */ X X msg.id_num = 0; X X strncpy(msg.l_name, my_name, NAME_SIZE); X msg.l_name[NAME_SIZE - 1] = '\0'; X X strncpy(msg.r_name, his_name, NAME_SIZE); X msg.r_name[NAME_SIZE - 1] = '\0'; X X strncpy(msg.r_tty, his_tty, TTY_SIZE); X msg.r_tty[TTY_SIZE - 1] = '\0'; X} END_OF_get_names.c if test 2077 -ne `wc -c <get_names.c`; then echo shar: \"get_names.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f invitebridge.README -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"invitebridge.README\" else echo shar: Extracting \"invitebridge.README\" \(1688 characters\) sed "s/^X//" >invitebridge.README <<'END_OF_invitebridge.README' X"invitebridge" is the brain of the whole system. The system looks like this: X X ---------- X |player1@| X |machine1| X ---------- X | bridge@ X | machine1 X | X ---------------------------------------- X | | | X | ---------- | | bridge@ ---------- X | |player4@| invitebridge@ | machine2 |player2@| X | |machine4|---- machine4 -------|------------|machine2| X | ---------- | | --------- X ---------------------------------------- X | bridge@ X | machine3 X | X ---------- X |player3@| X |machine3| X ---------- X XTo play the bridge game via compute communication, the central site needs Xthe "invitebridge" program and the remote sites need "bridge" program. XThe game is started by issuing the following command: X invitebridge player1@machine1 player2@machine2 player@machine3 X XIn the given example, the player1 will be the North, the player2 will be Xthe East, and the player3 will be the South. You, player4, are always Xthe West. X XThe game record will be stored in "bridge.log" in your working directory. XThe guide of bidding, playing,.. can be found in "bridge.README" which Xis part of this package. END_OF_invitebridge.README if test 1688 -ne `wc -c <invitebridge.README`; then echo shar: \"invitebridge.README\" unpacked with wrong size! fi # end of overwriting check fi if test -f slave_talk.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"slave_talk.c\" else echo shar: Extracting \"slave_talk.c\" \(264 characters\) sed "s/^X//" >slave_talk.c <<'END_OF_slave_talk.c' X X#include "talk.h" X X Xxwin_t comwin[19]; Xchar *current_state; X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X get_names(argc, argv); X X open_ctl(); X open_sockt(); X start_msgs(); X X if ( !check_local() ) { X invite_remote(); X } X end_msgs(); X X init_disp(); X X talk(); X} END_OF_slave_talk.c if test 264 -ne `wc -c <slave_talk.c`; then echo shar: \"slave_talk.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f talk.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"talk.h\" else echo shar: Extracting \"talk.h\" \(656 characters\) sed "s/^X//" >talk.h <<'END_OF_talk.h' X/* @(#)talk.h 1.1 86/02/05 SMI; from UCB 1.2 83/04/23 */ X X#include <curses.h> X#include <utmp.h> X X#define forever for(;;) X X#define BUF_SIZE 512 X#define PUT 1 X#define GET 2 X#define TYPE buf.type X#define WN buf.wn X#define ROW buf.row X#define COL buf.col X#define STR buf.string X XFILE *popen(); Xint quit(), sleeper(); X Xextern int sockt; Xextern int curses_initialized; Xextern int invitation_waiting; X Xextern char *current_state; Xextern int current_line; X Xtypedef struct xwin { X WINDOW *x_win; X int x_nlines; X int x_ncols; X int x_line; X int x_col; X} xwin_t; X Xextern xwin_t comwin[19]; X Xtypedef struct { X char type, wn, row, col; X char string[40]; X} BMSG; END_OF_talk.h if test 656 -ne `wc -c <talk.h`; then echo shar: \"talk.h\" unpacked with wrong size! fi # end of overwriting check fi if test -f talk_ctl.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"talk_ctl.h\" else echo shar: Extracting \"talk_ctl.h\" \(395 characters\) sed "s/^X//" >talk_ctl.h <<'END_OF_talk_ctl.h' X/* @(#)talk_ctl.h 1.1 86/02/05 SMI; from UCB 1.1 83/03/26 */ X X#include "ctl.h" X#include "talk.h" X#include <errno.h> X Xextern int errno; X Xextern struct sockaddr_in daemon_addr; Xextern struct sockaddr_in ctl_addr; Xextern struct sockaddr_in my_addr; Xextern struct in_addr my_machine_addr; Xextern struct in_addr his_machine_addr; Xextern u_short daemon_port; Xextern int ctl_sockt; Xextern CTL_MSG msg; END_OF_talk_ctl.h if test 395 -ne `wc -c <talk_ctl.h`; then echo shar: \"talk_ctl.h\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 2 \(of 2\). cp /dev/null ark2isdone MISSING="" for I in 1 2 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked both archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0