games@tekred.TEK.COM (05/31/88)
Submitted by: Jiang-Hsing Chu <jchu@mimsy.umd.edu> Comp.sources.games: Volume 4, Issue 19 Archive-name: bridge/Part01 [This is a program that allows four persons to play bridge at different places, different computers, via the computer communication. Now that you've practiced your bidding with v4i018, you can start playing. -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 1 (of 2)." # Contents: README MANIFEST bridge.README bridge.c ctl_transact.c # init_disp.c invite.c look_up.c master_io.c master_talk.c msgs.c # slave_io.c # Wrapped by billr@saab on Tue May 31 09:13:29 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f README -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"README\" else echo shar: Extracting \"README\" \(860 characters\) sed "s/^X//" >README <<'END_OF_README' XThis program provides communication between different machines so that people Xcan play bridge even they are on different machine. It is written by XShyan-Ming Yuan and Jiang-Hsing Chu at University of Maryland, College Park. XIt was tested on Vaxes and Sun 3/50 running BSD 4.2 and BSD 4.3. XSince we don't have the previlege to create a 'bridge daemon' as a normal user, Xwe decided to use 'talk daemon' instead. The underlying communication program Xis modified from the 'talk' program. You will have confusion in trying to Xconnect to the others, this is also explained in bridge.README. X XYou are free to use, copy, and modify these programs. You receive the program Xas it is. No warranty. No major update is expected. But bug report is Xwelcome. If you have a major modification, please send me a new copy. XThanks. Jiang-Hsing Chu. e-mail: jchu@mimsy END_OF_README if test 860 -ne `wc -c <README`; then echo shar: \"README\" unpacked with wrong size! fi # end of overwriting check fi if test -f MANIFEST -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"MANIFEST\" else echo shar: Extracting \"MANIFEST\" \(744 characters\) sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST' X File Name Archive # Description X----------------------------------------------------------- X MANIFEST 1 This shipping list X Makefile 2 X README 1 X bridge.README 1 X bridge.c 1 X ctl.c 2 X ctl.h 2 X ctl_transact.c 1 X get_addrs.c 2 X get_names.c 2 X init_disp.c 1 X invite.c 1 X invitebridge.README 2 X look_up.c 1 X master_io.c 1 X master_talk.c 1 X msgs.c 1 X slave_io.c 1 X slave_talk.c 2 X talk.h 2 X talk_ctl.h 2 END_OF_MANIFEST if test 744 -ne `wc -c <MANIFEST`; then echo shar: \"MANIFEST\" unpacked with wrong size! fi # end of overwriting check fi if test -f bridge.README -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"bridge.README\" else echo shar: Extracting \"bridge.README\" \(7255 characters\) sed "s/^X//" >bridge.README <<'END_OF_bridge.README' XBridge is the program stored in the local site so that the player can Xcommunicate with other remote players. To be able to use this program, Xyou must have a terminal supporting "curses". When you are invited to play Xthe game, a message will be shown on your screen indicating someone Xwants to talk to you as the talk program does and requests you to type X'talk xxx@yyy.zzz.edu'. At this moment, you should type 'bridge Xxxx@yyy.zzz.edu' to make the connection. It's obviously confusing because Xyou don't know the message is coming form some one who wants to talk to Xyou or form some one who wants to play bridge with you. Unfortunately, Xthis is what we have so far, we may be able to improve it later. XThe confusion can be avoided by presetting the time for playing bridge Xvia talk or mail in advance. You can assume that you are invited to Xplay bridge when talk Daemon shows the message around the preset time. X XSince we assume that all the users of 'bridge' are experienced computer Xusers and bridge players, there will not be any HELP information other Xthan those shown on the screen. Please read the followings carefully Xbefore you start to use the program. X X(1)General Guide: X 1. Always end your input with a carriage return. X 2. Input only when you are prompted to avoid mistakes. X 3. Some abbreviations are used: X N: No Trump, S: Spade, H: Heart, D: Diamond, C: Club, X X: Double, XX: Redouble, P: Pass, T: 10. X X(2)Bidding: X You will be prompted when it is your turn to bid. You will be prompted X again if your bid is illegal. To make a bid, type the rank(between 1 and 7) X followed by the suit(N,S,H,D,C); or type P, X, and XX for Pass, Double, X and Redouble respectively. Remember to end it with a carriage return. X Please note that a single carriage return means PASS. X The followings are legal INPUTs (not necessary legal bids): X 1H, 2N, 4C, X, XX, P,... X The followings are not legal inputs: X 5, S, 0D, 8C, .... X All the inputs are checked for the validity according to the rules of X bridge game. You are encouraged to report any illegal bid which is X accepted by the program. X X(3)Playing: X You will be prompted when it is your turn to play. You will be prompted X again if your play is illegal. To make a play, type the suit(S,H,D,C) X followed by the face value(2,3,...,9,T,J,Q,K,A) and end it with a carriage X return. There are three special features for playing: X 1. Following: X When you are not the first person to lead a card, you can simply input X the face value(2,3,...,T,J,Q,K,A) which means you are following the X same suit. For example, if your right hand side opponent leads S3, you X can type J instead of SJ when you want to play SJ. X 2. Don't Care: X When you have only one choice or you don't care which card is to be X played, you can simply type a carriage return. In such case, the porgram X will automatically play the card which is a legal play and has the lowest X rank. The cards are ranked as: SA>SK>...>S2>HA>...>C2. To avoid the X disaster caused by typing mistake, this function is disabled when you X are in the position to lead a card except the last round. X 3. Finish Quickly (claim): X The declarer, in his turn or dummy's turn to play, can claim the number X of tricks he can win to save time. To make the claim, the declarer X has to type in Fn, where n is a number between 0 and 13 which means X declarer is willing to finish the game with n MORE tricks. A single X "F" without any number followed means all the tricks left. This claim X is subject to the approval of the opponents. All the cards will be X shown on the opponents' screen to make their decision easier. If the X opponents don't agree to finish the game, the play is resume after X all extra cards are erased from the opponents' screen. X X(4)Scoring X The scoring system of our birdge program is rubber. To win the rubber X bonus, basically, you have to win two games before your opponents do. X Thus, you might need a different strategy in playing rubbers. For your X convenience, the scoring rule is also enclosed. Due to the limited space X on the screen, please note the following notation: X X N-S E-W X TRICK ... ... <-- number of tricks won by each side so far X SCORE ... ... <-- score below the line (see the attached scoring rule) X which doesn't exceed 100 points. X TOTAL ... ... <-- total score (including the score in SCORE entry) won X by each side so far X XIt is also important to know whether you and/or your opponents have won a game Xalready. To gain this information, you have to look at the upper left corner Xon the screen, i.e. the VUL field. It can be interpreted as: X X VUL. X X NONE <-- neither side has won a game X N-S <-- N-S has won a game, but E-W hasn't X E-W <-- E-W has won a game, but N-S hasn't X BOTH <-- both N-S and E-W have won a game X X(5) Conversation: X All your inputs are sent to the bridge program when you are in input X mode. However, if you are in conversation mode, all your inputs will X be sent to the screens of all other players (same as talk does, but it X is a multiway talk). The ESC key is used to switch back and forth X between input mode and conversation mode. You will be put in the input X mode at the beginning of the game. X X(6)Ending: X There is not a graceful way to end this program. It will run forever X unless you type a ctrl-C. X X============================================================================== XSCORING TABLE X XTrick Score (below the line) X XSpades of Hearts 30 per trick | If doubled: XDiamonds or Clubs 20 per trick | multiply by 2 XNotrump 40 for first trick | If redoubled: X 30 for each additional trick | multiply by 4 X XGame - 100 points or more below the line X XBonuses (above the line) X XRubber bonus: 500 if you win two games out of three X 700 if you win the only two games X X Not Vulnerable Vulnerable XSlam Bonus: Small Slam 500 750 X Grand Slam 1000 1500 X X/* NOT IMPLEMENTED XHonors: 4 trump honors in one hand 100 X 5 trump honors in one hand 150 X 4 aces in one hand at notrump 150 X*/ X XMaking Doubled (or redoubled) Contract: 50 points X X Not Vulnerable Vulnerable XOvertricks: Undoubled trick value trick value X Doubled 100 per trick 200 per trick X Redoubled 200 per trick 400 per trick X XPenalties (above the line) X X Undoubled Doubled X Not Vul. Vul. Not Vul. Vul. XDown 1 50 100 100 200 XDown 2 100 200 300 500 XDown 3 150 300 500 800 XDown 4 200 400 700 1100 XDown 5 250 500 900 1400 XDown 6 300 600 1100 1700 XDown 7 350 700 1300 2100 XDown 8 400 800 1500 2500 X . . . . . X . . . . . X . . . . . X XIf redoubled: multiply the doubled penalty by two. X X============================================================================= X END_OF_bridge.README if test 7255 -ne `wc -c <bridge.README`; then echo shar: \"bridge.README\" unpacked with wrong size! fi # end of overwriting check fi if test -f bridge.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"bridge.c\" else echo shar: Extracting \"bridge.c\" \(14041 characters\) sed "s/^X//" >bridge.c <<'END_OF_bridge.c' X#include <stdio.h> X X#define EQ == X#define NEQ != X#define NOT ! X#define AND && X#define OR || X#define TRUE 1 X#define FALSE 0 X X#define SIDE(i) ((i)%2) X#define NEXT(i) ((i+1)%4) X#define PARTNER(i) ((i+2)%4) X#define IC(i) (i+'0') X#define ALLp p=0;p<=3;++p X XFILE *f1; Xchar scr[16][80]; Xint r[4]={1,6,11,6},c[4]={18,32,18,4}; Xint hand= -1,decl,dummy,trump,dbl,ld,ldd,win[2],HBR,HBS,HBB,rs,ts[2]={0,0}; Xint vt[2]={0,0},part[2]={0,0}; Xint eofg,eofp,eofr=0; Xint card[52],C[4][52],NS[4][4],LS[4]; Xint TV[5]={20,20,30,30,30}; Xint VUL[2][16]={0,1,0,1,1,0,1,0,0,1,0,1,1,0,1,0, X 0,0,1,1,0,1,1,0,1,1,0,0,1,0,0,1}; Xchar CBR,CBS,CPR,CPS; Xextern char player[4][20]; Xchar str[80],inp[80],num[6]; Xchar FV[13]={'2','3','4','5','6','7','8','9','T','J','Q','K','A'}; Xchar SV[5]={'C','D','H','S','N'}; Xchar P[4]={'N','E','S','W'}; Xextern long seed; X Xinit() X{ int p,t; X X f1=fopen("bridge.log","w"); X for(ALLp){player[p][0]=P[p];player[p][1]=':';} X for(ALLp){ X str[1]='\0'; X str[0]=P[PARTNER(p)]; X rput(p,13,4,29,str); X str[0]=P[t=NEXT(p)]; X rput(p,13,8,20,str); X str[0]=P[PARTNER(t)]; X rput(p,13,8,38,str); X str[0]=P[p]; X rput(p,13,12,29,str); X rput(p,13,17,5,player[(p+2)%4]); X rput(p,13,17,25,player[(p+1)%4]); X rput(p,13,17,45,player[p]); X rput(p,13,17,65,player[(p+3)%4]); X } X srandom(seed); X} Xrinit() X{ int tvt,p,i,j; X char *d; X X for(i=0;i<16;i++){ X d=(char *)&scr[i][0]; X for(j=0;j<80;++j) *d++ =' '; X } X sput("Hand:",0,0);sput("Vul.:",1,0); X sput("Bid",0,51);sput("=N==E==S==W==",1,46); X sput("Play",0,66);sput("=N===E===S===W===",1,60); X sput("--------------",5,17); X sput("| N |",6,17); X sput("|W E|",7,17); X sput("| |",8,17); X sput("| S |",9,17); X sput("--------------",10,17); X sput("Result:",15,47); X itos((++hand)+1); X sput(num+3,0,6); X for(ALLp)rput(p,8,0,0,num+3); X X/* for duplicate bridge X sput("Score:",15,62); X tvt=VUL[0][hand%16]*2+VUL[1][hand%16]; X*/ X/* for rubber */ X tvt=vt[0]*2+vt[1]; X for(ALLp){ clearw(p,11); clearw(p,10);} X str[1]='\0'; X switch(tvt){ X case 0: for(ALLp)rput(p,8,1,0,"NONE");sput("NONE",1,6);break; X case 1: for(ALLp){ X rput(p,8,1,0,"E-W "); X str[0]=45+SIDE(p)*79; X rput(p,10,3,8,str); X } X sput("E-W",1,6); X break; X case 2: for(ALLp){ X rput(p,8,1,0,"N-S "); X str[0]=124-SIDE(p)*79; X rput(p,10,3,8,str); X } X sput("N-S",1,6); X break; X case 3: str[0]='+'; X for(ALLp){ X rput(p,8,1,0,"BOTH"); X rput(p,10,3,8,str); X } X sput("BOTH",1,6); X break; X } X for(ALLp){ X rput(p,9,0,0," 0"); X rput(p,9,0,6," 0"); X clearw(p,0);clearw(p,1);clearw(p,2);clearw(p,3); X clearw(p,4);clearw(p,5);clearw(p,6);clearw(p,7); X } X} Xpscr() X{ int i,j; X char *d; X X for(i=0;i<16;++i){ X d=(char *)&scr[i][0]; X for(j=0;j<80;++j)fprintf(f1,"%c",*d++); X fprintf(f1,"\n"); X } X fprintf(f1,"\n\n\n\n"); X fflush(f1); X} X Xsput(s,r,c) Xchar *s; Xint r,c; X{ char *d; X X d=(char *)&scr[r][c]; X while(*s) *d++ = *s++; X} Xdeal() X{ int i,j,rr,cc; X char *d; X X for(i=0;i<52;++i){ X card[i]=i; X for(j=0;j<4;++j)C[j][i]=0; X } X for(i=0;i<4;++i){ X LS[i]=0; X for(j=0;j<4;++j) NS[i][j]=0; X } X i=52; X while(i>1){ X j=random()%i--; X C[i/13][card[j]]=1; X NS[i/13][card[j]/13]++; X if(NS[i/13][card[j]/13]>LS[i/13]) LS[i/13]++; X card[j]=card[i]; X } X C[0][card[0]]=1; X NS[0][card[0]/13]++; X for(i=0;i<4;++i) printhand(i,i); X for(i=0;i<4;++i){ X rr=r[i]-1;cc=c[i]; if(i EQ 3) cc=cc+10-LS[i]; X for(j=51;j>=0;--j){ X if(j%13 EQ 12){ d=(char *)&scr[++rr][cc];*d++ =SV[j/13]; *d++ = ' ';} X if(C[i][j] EQ 1)*d++ = FV[j%13]; X } X } X} Xbid() X{ int i,j,p,rb,eofb,legalbid,NP,OB; X int PFBS[2][5]; X X for(ALLp){ X rput(p,10,2,0,"-----------"); X rput(p,10,4,6,"-----------"); X for(i=0;i<=3;++i) rput(p,10,i,11,"|"); X for(i=0;i<=3;++i) rput(p,10,i+3,5,"|"); X } X for(i=0;i<2;++i)for(j=0;j<5;++j)PFBS[i][j]= -1; X rb=HBR=NP=0; X eofb=eofg=FALSE; X HBS= -1; X for(i=OB=hand%4;NOT eofb;i=NEXT(i)){ X legalbid=FALSE; X do{ X if(readbid(i)<0)continue; X if(CBS EQ 6){ X if((dbl NEQ 1) OR (SIDE(i) NEQ SIDE(HBB)) OR (HBR<1))continue; X dbl=2;ldd=i; X } X if(CBS EQ 5){ X if((dbl NEQ 0) OR (SIDE(i) EQ SIDE(HBB)) OR (HBR<1))continue; X dbl=1;ld=i; X } X if(CBR<HBR)continue; X if(CBR>=HBR AND CBR<8){ X if ((CBR EQ HBR) AND (CBS<=HBS))continue; X dbl=0;HBR=CBR;HBS=CBS;HBB=i; X if(PFBS[SIDE(i)][CBS] EQ -1)PFBS[SIDE(i)][CBS]=i; X } X if(CBS EQ 7) NP++; else NP=0; X legalbid=TRUE; X }while(NOT legalbid); X if(NP EQ 4){eofb=eofg=TRUE;inp[0]=inp[1]='=';} X if((NP EQ 3) AND (HBR>0)) {eofb=TRUE;inp[0]=inp[1]='=';} X printbid(rb,i); X sput(inp,2+rb+(i<OB),47+3*(i%4)); X if(NEXT(i) EQ OB) rb++; X } X decl=PFBS[SIDE(HBB)][HBS]; X dummy=PARTNER(decl); X trump=HBS; X if(NOT eofg){ X strcpy(str,"CONTRACT: "); X str[10]=HBR+'0'; str[11]=SV[HBS]; str[12]='/'; str[13]=P[decl]; j=14; X if(dbl>0){str[j++]=' ';str[j++]='X';str[j++]='/';str[j++]=P[ld];} X if(dbl>1) X {str[j++]=' ';str[j++]='X';str[j++]='X';str[j++]='/';str[j++]=P[ldd];} X str[j]='\0'; X for(ALLp)rput(p,11,0,0,str); X sput(str+10,4+rb,47); X } X} Xplay() X{ int r,i,ss,legalplay,winner,FL,FPS,HPR,HPS,p; X X FL=NEXT(decl); X win[0]=win[1]=0; X for(r=1;r<=13;++r){ X i=FL; X do{ X legalplay=FALSE; X do{ X if(readplay(i EQ dummy ? decl : i,i)<0)continue; X if(CPS EQ 5){ X if(SIDE(i) NEQ SIDE(decl))continue; X if(CPR<0 OR CPR>13-win[0]-win[1])continue; X printhand(NEXT(decl),decl); X printhand(NEXT(decl),NEXT(dummy)); X printhand(NEXT(dummy),decl); X printhand(NEXT(dummy),NEXT(decl)); X strcpy(inp,"Declarer asks more tricks. Agree?"); X if(CPR>9) inp[14]='1'; X inp[15]=CPR%10+'0'; X rget((1<<NEXT(decl))|(1<<NEXT(dummy)),inp); X if(inp[0] NEQ 'Y'){ X clearw(NEXT(decl),0); X clearw(NEXT(decl),1); X clearw(NEXT(dummy),3); X clearw(NEXT(dummy),0); X continue; X } X printhand(decl,NEXT(decl)); X printhand(decl,NEXT(dummy)); X win[SIDE(decl)]+=CPR; X win[1-SIDE(decl)]=13-win[SIDE(decl)]; X itos(win[0]);for(ALLp)rput(p,9,0,0,num); X itos(win[1]);for(ALLp)rput(p,9,0,6,num); X for(ALLp){clearw(p,4);clearw(p,5);clearw(p,6);clearw(p,7);} X return; X } X if(i EQ FL){ X if(CPS EQ 4) continue; X if(CPS EQ 6){ X if (r < 13) continue; X else{ X for(ss=0;C[i][ss]<1;++ss); X inp[0]=SV[CPS=ss/13];inp[1]=FV[CPR=ss%13]; X } X } X if(NOT inhand(CPS,CPR,i))continue; X if(r EQ 1){ X for(ALLp) clearw(p,10); X for(p=NEXT(dummy);p NEQ dummy;p=NEXT(p))printhand(p,dummy); X printhand(dummy,decl); X } X winner=FL; X HPR=CPR; X FPS=HPS=CPS; X } X else{ X if(CPS EQ 6){ X for(ss=NS[i][FPS]?FPS*13:0;C[i][ss]<1;++ss); X inp[0]=SV[CPS=ss/13];inp[1]=FV[CPR=ss%13]; X } X if(CPS EQ 4) {CPS=FPS;inp[1]=inp[0];inp[0]=SV[FPS];} X if((CPS NEQ FPS) AND (NS[i][FPS] NEQ 0))continue; X if(NOT inhand(CPS,CPR,i))continue; X if(CPS EQ HPS){ X if(CPR>HPR){winner=i;HPR=CPR;} X } X else {if(CPS EQ trump){winner=i;HPR=CPR;HPS=CPS;}} X } X printplay(i); X printsuit(i,i,CPS); X sput(inp,1+r,61+4*i); X sput("!",1+r,63+4*FL); X if(i EQ dummy) X for(p=NEXT(dummy);p NEQ dummy;p=NEXT(p))printsuit(p,i,CPS); X if(i EQ decl) printsuit(dummy,decl,CPS); X legalplay=TRUE; X }while(NOT legalplay); X i=NEXT(i); X }while(i NEQ FL); X itos(++win[SIDE(FL=winner)]); X for(ALLp) rput(p,9,0,6*SIDE(FL),num); X sput("*",r+1,63+4*winner); X if(r<13){ X waitkey("Press return to pause."); X for(ALLp){clearw(p,4);clearw(p,5);clearw(p,6);clearw(p,7);} X } X } X} Xscore() X{ int vt,over,otv,winside; X X vt=VUL[winside=SIDE(decl)][hand%16]; X over=win[winside]-6-HBR; X otv=TV[HBS]; X if(dbl>0) otv=100*dbl*(vt+1); X if(over>=0){ X rs=HBR*TV[HBS]; X if(HBS EQ 4) rs+=10; X if(dbl NEQ 0) rs=rs*2*dbl; X if(rs>=100)rs+=(250+200*vt); X rs+=(50+over*otv); X if(dbl NEQ 0)rs+=50; X if(HBR EQ 6)rs+=500+250*vt; X if(HBR EQ 7)rs+=1000+500*vt; X } X else{ X if(dbl EQ 0)rs=50*over*(vt+1); X else rs=((200*over+100)+100*over*vt)*dbl; X } X if(rs<0){winside=1-winside;rs= -rs;} X ts[winside]+=rs; X printscore(winside); X itos(over);sput(num+3,15,55); X waitkey("Press return to pause."); X} Xrscore() X{ int over,otv,winside,p; X X winside=SIDE(decl); X over=win[winside]-6-HBR; X otv=TV[HBS]; X if(dbl>0) otv=100*dbl*(vt[winside]+1); X if(over>=0){ X rs=HBR*TV[HBS]; X if(HBS EQ 4) rs+=10; X if(dbl NEQ 0) rs=rs*2*dbl; X ts[winside]+=rs; X ts[winside]+=(over*otv); X if(dbl NEQ 0)ts[winside]+=50; X if(HBR EQ 6)ts[winside]+=500+250*vt[winside]; X if(HBR EQ 7)ts[winside]+=1000+500*vt[winside]; X part[winside]+=rs; X if(part[winside]>=100){ X if(vt[winside]){ X ts[winside]+=700-200*vt[1-winside]; vt[0]=vt[1]=0; X eofr=1; X } X else{vt[winside]+=1;} X part[0]=part[1]=0; for(ALLp)rput(p,9,1,0," 0 0"); X } X else{itos(part[winside]);for(ALLp)rput(p,9,1,6*winside,num);} X itos(ts[winside]);for(ALLp)rput(p,9,2,6*winside,num); X } X else{ X if(dbl EQ 0)rs=50*over*(vt[winside]+1); X else rs=((200*over+100)+100*over*vt[winside])*dbl; X ts[1-winside]-=rs; X itos(ts[1-winside]);for(ALLp)rput(p,9,2,6-6*winside,num); X } X itos(over);sput(num+3,15,55); X waitkey("Press return to pause."); X} Xreadbid(i) Xint i; X{ X strcpy(inp,"It's your turn to bid "); X rget(1<<i,inp); X inp[2]='\0'; X CBR=inp[0]-'0'; X if(CBR>0 AND CBR <8) return(CBS=lookup(inp[1],SV,5)); X CBR=8; X switch(inp[0]){ X case '\n': X case 'P': inp[0]=inp[1]='-';CBS=7;return(CBS); X case 'X': if(inp[1] EQ 'X'){CBS=6;return(CBS);} X else{inp[1]='\0';CBS=5;return(CBS);} X default: return(-1); X } X} Xreadplay(i,j) Xint i,j; X{ X if (j EQ dummy) strcpy(inp,"It's dummy's turn to play "); X else strcpy(inp,"It's your turn to play "); X rget(1<<i,inp); X if(inp[0] EQ 'F'){ X CPS=5;CPR=inp[1]-'0'; X if(inp[2]>='0' AND inp[2]<='9') CPR=CPR*10+inp[2]-'0'; X if(inp[1]=='\n') CPR=13-win[0]-win[1]; X return(0); X } X inp[2]='\0'; X if((CPR=lookup(inp[0],FV,13))>=0) {CPS=4;return(0);} X if(inp[0] EQ '\n'){CPS=6;return(0);} X CPS=lookup(inp[0],SV,4); X CPR=lookup(inp[1],FV,13); X if(CPS<0 OR CPR<0) return(-1); X else return(0); X} Xlookup(ch,t,i) Xint i; Xchar ch,*t; X X{ int j; X X for(j=i-1;j>=0;j--)if(ch EQ t[j]) return(j); X return(-1); X} Xinhand(s,r,i) Xint s,r,i; X X{ int j; X X j=s*13+r; X if(C[i][j] NEQ 1)return(FALSE); X C[i][j]=0; X NS[i][s]--; X return(TRUE); X} Xitos(i) Xint i; X X{ int j,f; X char t; X X if(i EQ 0) {num[0]=num[1]=num[2]=num[3]=' ';num[4]='0';num[5]=0;return;} X f=0;if(i<0){f=1;i= -i;} X num[0]='\0'; X for(j=1;j<=5;j++) X if(i>0){ X num[j]=i%10+'0'; X i/=10; X } X else{ if(f){num[j]='-';f=0;} else num[j]=' ';} X for(i=0;i<=2;++i){ X t=num[i]; X num[i]=num[5-i]; X num[5-i]=t; X } X} Xprinthand(p,h) Xint p,h; X X{ int s; X X for(s=0;s<4;++s)printsuit(p,h,s); X} Xprintsuit(p,h,s) Xint p,h,s; X X{ int i,j=2,offset=0; X str[0]=SV[s]; X str[1]=' '; X for(i=12;i>=0;--i)if(C[h][s*13+i] EQ 1)str[j++]=FV[i]; X str[j++]=' ';str[j]='\0'; X if((j=(6+h-p)%4) EQ 3) offset=11-LS[h]; X rput(p,j,3-s,offset,str); X} Xprintplay(h) Xint h; X X{ int p; X X for(ALLp) rput(p,(6+h-p)%4+4,0,0,inp); X} Xprintscore(winside) Xint winside; X X{ int p; X X itos(rs);for(ALLp){rput(p,9,1,6*winside,num);rput(p,9,1,6-6*winside," 0");} X sput(num,15,69); X itos(ts[winside]);for(ALLp)rput(p,9,2,6*winside,num); X} Xprintbid(rb,i) Xint rb,i; X{ int p; X X p=i; X rput(p,10,5+rb/4,6+3*(rb%4),inp); p=NEXT(p); X rput(p,10,3-rb%4,12+3*(rb/4),inp); p=NEXT(p); X rput(p,10,1-rb/4,9-3*(rb%4),inp); p=NEXT(p); X rput(p,10,3+rb%4,3-3*(rb/4),inp); p=NEXT(p); X} Xwaitkey(c) Xchar *c; X{ int p; X char t[40]; X do {strcpy(t,c);} X while(rwait((1<<decl)|(1<<NEXT(decl))|(1<<NEXT(dummy)),t,2)>0); X for(ALLp) clearw(p,12); X} Xclearw(p,wn) Xint p,wn; X X{ X str[0]='Z'; X str[1]='\0'; X rput(p,wn,0,0,str); X} X/* Xrput(p,w,r,c,s) Xint p,w,r,c; Xchar *s; X X{ printf("p=%d, w=%d, r=%d, c=%d, s=%s",p,w,r,c,s); X} Xrget(p,s) Xint p; Xchar *s; X{ scanf("%s",s); X} X*/ Xmore() X{ int p; X/* X if(NOT eofr) return; X strcpy(inp,"You like another rubber?"); X rwait(15,inp,5); X if(inp[0] NEQ 'Y'){for(ALLp)rput(p,0,0,0,"\\"); exit();} X for(ALLp)clearw(p,12); X eofr=0; X*/ X return; X} Xbridge() X{ int p; X X init(); X eofp=FALSE; X do{ X rinit(); X deal(); X bid(); X if(NOT eofg){ X play(); X rscore(); X } X else for(ALLp) clearw(p,10); X pscr(); X more(); X }while(NOT eofp); X} END_OF_bridge.c if test 14041 -ne `wc -c <bridge.c`; then echo shar: \"bridge.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f ctl_transact.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"ctl_transact.c\" else echo shar: Extracting \"ctl_transact.c\" \(2210 characters\) sed "s/^X//" >ctl_transact.c <<'END_OF_ctl_transact.c' X#ifndef lint Xstatic char sccsid[] = "@(#)ctl_transact.c 1.1 86/02/05 SMI"; /* from UCB */ X#endif X#include "talk_ctl.h" X#include <sys/time.h> X X#define CTL_WAIT 2 /* the amount of time to wait for a X response, in seconds */ X X X /* X * SOCKDGRAM is unreliable, so we must repeat messages if we have X * not recieved an acknowledgement within a reasonable amount X * of time X */ X Xctl_transact(target, msg, type, response) Xstruct in_addr target; XCTL_MSG msg; Xint type; XCTL_RESPONSE *response; X{ X struct sockaddr junk; X int read_mask; X int ctl_mask; X int nready; X int cc; X int junk_size; X struct timeval wait; X X wait.tv_sec = CTL_WAIT; X wait.tv_usec = 0; X X msg.type = type; X X daemon_addr.sin_addr = target; X daemon_addr.sin_port = daemon_port; X X ctl_mask = 1 << ctl_sockt; X X /* X * keep sending the message until a response of the right X * type is obtained X */ X do { X /* keep sending the message until a response is obtained */ X X do { X cc = sendto(ctl_sockt, (char *)&msg, sizeof(CTL_MSG), 0, X &daemon_addr, sizeof(daemon_addr)); X X if (cc != sizeof(CTL_MSG)) { X if (errno == EINTR) { X /* we are returning from an interupt */ X continue; X } else { X p_error("Error on write to talk daemon"); X } X } X X read_mask = ctl_mask; X X while ((nready = select(32, &read_mask, 0, 0, &wait)) < 0) { X if (errno == EINTR) { X /* we are returning from an interupt */ X continue; X } else { X p_error("Error on waiting for response from daemon"); X } X } X } while (nready == 0); X X /* keep reading while there are queued messages X (this is not necessary, it just saves extra X request/acknowledgements being sent) X */ X X do { X X junk_size = sizeof(junk); X cc = recvfrom(ctl_sockt, (char *) response, X sizeof(CTL_RESPONSE), 0, &junk, &junk_size ); X if (cc < 0) { X if (errno == EINTR) { X continue; X } X p_error("Error on read from talk daemon"); X } X X read_mask = ctl_mask; X X /* an immediate poll */ X X timerclear(&wait); X nready = select(32, &read_mask, 0, 0, &wait); X X } while ( nready > 0 && response->type != type); X X } while (response->type != type); X} END_OF_ctl_transact.c if test 2210 -ne `wc -c <ctl_transact.c`; then echo shar: \"ctl_transact.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f init_disp.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"init_disp.c\" else echo shar: Extracting \"init_disp.c\" \(6607 characters\) sed "s/^X//" >init_disp.c <<'END_OF_init_disp.c' X#ifndef lint Xstatic char sccsid[] = "@(#)init_disp.c 1.1 86/02/05 SMI"; /* from UCB 1.2 83/06/23 */ X#endif X X/* X * init_disp contains the initialization code for the display package, X * as well as the signal handling routines X */ X X#include "talk.h" X#include <signal.h> X Xextern int ID; Xint curses_initialized; X X/* X * set up curses, catch the appropriate signals, and build the X * various windows X */ X Xinit_disp() X{ int i, t; X X void sig_sent(); X X initscr(); X curses_initialized = 1; X X clear(); X refresh(); X X noecho(); X crmode(); X X signal(SIGINT, sig_sent); X signal(SIGPIPE, sig_sent); X X /* curses takes care of ^Z */ X X comwin[0].x_nlines = 4; X comwin[0].x_ncols = 15; X comwin[0].x_win = newwin(4, 15, 0, 22); X X comwin[1].x_nlines = 4; X comwin[1].x_ncols = 15; X comwin[1].x_win = newwin(4, 15, 6, 40); X X comwin[2].x_nlines = 4; X comwin[2].x_ncols = 15; X comwin[2].x_win = newwin(4, 15, 13, 22); X X comwin[3].x_nlines = 4; X comwin[3].x_ncols = 15; X comwin[3].x_win = newwin(4, 15, 6, 5); X X comwin[4].x_nlines = 1; X comwin[4].x_ncols = 2; X comwin[4].x_win = newwin(1, 2, 5, 28); X X comwin[5].x_nlines = 1; X comwin[5].x_ncols = 2; X comwin[5].x_win = newwin(1, 2, 8, 35); X X comwin[6].x_nlines = 1; X comwin[6].x_ncols = 2; X comwin[6].x_win = newwin(1, 2, 11, 28); X X comwin[7].x_nlines = 1; X comwin[7].x_ncols = 2; X comwin[7].x_win = newwin(1, 2, 8, 22); X X comwin[8].x_nlines = 2; X comwin[8].x_ncols = 4; X comwin[8].x_win = newwin(2, 4, 1, 7); X X comwin[9].x_nlines = 3; X comwin[9].x_ncols = 11; X comwin[9].x_win = newwin(3, 11, 5, 67); X X comwin[10].x_nlines = 7; X comwin[10].x_ncols = 17; X comwin[10].x_win = newwin(7, 17, 5, 21); X X comwin[11].x_nlines = 1; X comwin[11].x_ncols = 30; X comwin[11].x_win = newwin(1, 30, 1, 50); X comwin[12].x_nlines = 1; X comwin[12].x_ncols = 40; X comwin[12].x_win = newwin(1, 40, 16, 40); X X comwin[13].x_nlines = 24; X comwin[13].x_ncols = 80; X comwin[13].x_win = newwin(24, 80, 0, 0); X X comwin[14].x_nlines = 5; X comwin[14].x_ncols = 19; X comwin[14].x_win = newwin(5, 19, 18, 0); X X comwin[15].x_nlines = 5; X comwin[15].x_ncols = 19; X comwin[15].x_win = newwin(5, 19, 18, 20); X X comwin[16].x_nlines = 5; X comwin[16].x_ncols = 19; X comwin[16].x_win = newwin(5, 19, 18, 40); X X comwin[17].x_nlines = 5; X comwin[17].x_ncols = 19; X comwin[17].x_win = newwin(5, 19, 18, 60); X X comwin[18].x_nlines = 1; X comwin[18].x_ncols = 20; X comwin[18].x_win = newwin(1, 20, 16, 0); X for (i=0; i<19; i++){ X scrollok(comwin[i].x_win, FALSE); X wclear(comwin[i].x_win); X }; Xfor (i=14; i<18;++i) scrollok(comwin[i].x_win, TRUE); X wmove(comwin[13].x_win, 1, 1); X wprintw(comwin[13].x_win, "HAND:"); X wmove(comwin[13].x_win, 2, 1); X wprintw(comwin[13].x_win, "VUL.:"); X wmove(comwin[13].x_win, 4, 20); X wprintw(comwin[13].x_win, "-------------------"); X wmove(comwin[13].x_win, 5, 20); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 6, 20); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 7, 20); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 8, 20); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 9, 20); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 10, 20); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 11, 20); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 12, 20); X wprintw(comwin[13].x_win, "-------------------"); X wmove(comwin[13].x_win, 5, 38); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 6, 38); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 7, 38); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 8, 38); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 9, 38); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 10, 38); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 11, 38); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 3, 68); X wprintw(comwin[13].x_win, "N-S E-W"); X wmove(comwin[13].x_win, 4, 67); X wprintw(comwin[13].x_win, "----- -----"); X wmove(comwin[13].x_win, 5, 60); X wprintw(comwin[13].x_win, "TRICK: 0 0"); X wmove(comwin[13].x_win, 6, 60); X wprintw(comwin[13].x_win, "SCORE: 0 0"); X wmove(comwin[13].x_win, 7, 60); X wprintw(comwin[13].x_win, "TOTAL: 0 0"); X wmove(comwin[13].x_win, 9, 55); X wprintw(comwin[13].x_win, "ABBREVIATIONS --"); X wmove(comwin[13].x_win, 10, 57); X wprintw(comwin[13].x_win, "P:PASS N:NO TRUMP"); X wmove(comwin[13].x_win, 11, 57); X wprintw(comwin[13].x_win, "S:SPADE H:HEART"); X wmove(comwin[13].x_win, 12, 57); X wprintw(comwin[13].x_win, "D:DIAMOND C:CLUB,"); X wmove(comwin[13].x_win, 13, 57); X wprintw(comwin[13].x_win, "X:DOUBLE XX:REDOUBLE"); X wmove(comwin[13].x_win, 14, 57); X wprintw(comwin[13].x_win, "T:10 F#:Finish"); X wmove(comwin[13].x_win, 17,0); X wprintw(comwin[13].x_win, "--------------------------------------------------------------------------------"); X wmove(comwin[13].x_win, 18,19); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 18,39); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 18,59); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 19,19); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 19,39); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 19,59); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 20,19); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 20,39); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 20,59); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 21,19); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 21,39); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 21,59); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 22,19); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 22,39); X wprintw(comwin[13].x_win, "|"); X wmove(comwin[13].x_win, 22,59); X wprintw(comwin[13].x_win, "|"); X wrefresh(comwin[13].x_win); X X current_state = "No connection yet"; X} X Xvoid sig_sent() X{ X message("Connection closing. Exiting"); X quit(); X} X X/* X * All done talking...hang up the phone and reset terminal thingy's X */ X Xquit() X{ int i; X X if (curses_initialized) { X for (i=0; i<3; i++){ X wmove(comwin[i].x_win, comwin[i].x_nlines-1, 0); X wclrtoeol(comwin[i].x_win); X wrefresh(comwin[i].x_win); X }; X endwin(); X } X X if (invitation_waiting) { X send_delete(); X } X X exit(0); X} END_OF_init_disp.c if test 6607 -ne `wc -c <init_disp.c`; then echo shar: \"init_disp.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f invite.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"invite.c\" else echo shar: Extracting \"invite.c\" \(3759 characters\) sed "s/^X//" >invite.c <<'END_OF_invite.c' X#ifndef lint Xstatic char sccsid[] = "@(#)invite.c 1.1 86/02/05 SMI"; /* from UCB 1.7 83/07/06 */ X#endif X X#include "talk_ctl.h" X#include <sys/time.h> X#include <signal.h> X#include <setjmp.h> X X /* X * there wasn't an invitation waiting, so send a request containing X * our sockt address to the remote talk daemon so it can invite X * him X */ X Xint local_id, remote_id; /* the msg.id's for the invitations X on the local and remote machines. X These are used to delete the X invitations. */ Xvoid re_invite(); Xjmp_buf invitebuf; X Xinvite_remote() X{ X int nfd, read_mask, template, new_sockt; X struct itimerval itimer; X CTL_RESPONSE response; X X itimer.it_value.tv_sec = RING_WAIT; X itimer.it_value.tv_usec = 0; X itimer.it_interval = itimer.it_value; X X if (listen(sockt, 5) != 0) { X p_error("Error on attempt to listen for caller"); X } X X msg.addr = my_addr; X msg.id_num = -1; /* an impossible id_num */ X X invitation_waiting = 1; X X announce_invite(); X X /* X * shut off the automatic messages for a while, X * so we can use the interupt timer to resend the invitation X */ X X setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0); X message("Waiting for your party to respond"); X signal(SIGALRM, re_invite); X (void) setjmp(invitebuf); X X while ((new_sockt = accept(sockt, 0, 0)) < 0) { X if (errno != EINTR) { X p_error("Unable to connect with your party"); X } else { X /* we just returned from a interupt, keep trying */ X continue; X } X } X X close(sockt); X sockt = new_sockt; X X /* have the daemons delete the invitations now that we X have connected. X */ X X current_state = "Waiting for your party to respond"; X X msg.id_num = local_id; X ctl_transact(my_machine_addr, msg, DELETE, &response); X msg.id_num = remote_id; X ctl_transact(his_machine_addr, msg, DELETE, &response); X invitation_waiting = 0; X} X X /* routine called on interupt to re-invite the callee */ X Xvoid re_invite() X{ X message("Ringing your party again"); X current_line++; X /* force a re-announce */ X msg.id_num = remote_id + 1; X announce_invite(); X longjmp(invitebuf, 1); X} X X /* transmit the invitation and process the response */ X Xannounce_invite() X{ X CTL_RESPONSE response; X X current_state = "Trying to connect to your party's talk daemon"; X X ctl_transact(his_machine_addr, msg, ANNOUNCE, &response); X remote_id = response.id_num; X X if (response.answer != SUCCESS) { X X switch (response.answer) { X X case NOT_HERE : X message("Your party is not logged on"); X break; X X case MACHINE_UNKNOWN : X message("Target machine does not recognize us"); X break; X X case UNKNOWN_REQUEST : X message("Target machine can not handle remote talk"); X break; X X case FAILED : X message("Target machine is too confused to talk to us"); X break; X X case PERMISSION_DENIED : X message("Your party is refusing messages"); X break; X } X X quit(); X } X X /* leave the actual invitation on my talk daemon */ X X ctl_transact(my_machine_addr, msg, LEAVE_INVITE, &response); X local_id = response.id_num; X} X Xsend_delete() X{ X /* tell the daemon to remove your invitation */ X X msg.type = DELETE; X X /* this is just a extra clean up, so just send it X and don't wait for an answer */ X X msg.id_num = remote_id; X daemon_addr.sin_addr = his_machine_addr; X if (sendto(ctl_sockt, &msg, sizeof(CTL_MSG), 0, &daemon_addr, X sizeof(daemon_addr)) != sizeof(CTL_MSG)) { X perror("send_delete remote"); X } X X msg.id_num = local_id; X daemon_addr.sin_addr = my_machine_addr; X if (sendto(ctl_sockt, &msg, sizeof(CTL_MSG), 0, &daemon_addr, X sizeof(daemon_addr)) != sizeof(CTL_MSG)) { X perror("send_delete local"); X } X} END_OF_invite.c if test 3759 -ne `wc -c <invite.c`; then echo shar: \"invite.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f look_up.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"look_up.c\" else echo shar: Extracting \"look_up.c\" \(3343 characters\) sed "s/^X//" >look_up.c <<'END_OF_look_up.c' X#ifndef lint Xstatic char sccsid[] = "@(#)look_up.c 1.1 86/02/05 SMI"; /* from UCB 1.2 83/03/28 */ X#endif X X#include "talk_ctl.h" X X /* see if the local daemon has a invitation for us */ X XCTL_RESPONSE swapresponse(); X Xcheck_local() X{ X CTL_RESPONSE response; X X /* the rest of msg was set up in get_names */ X X msg.ctl_addr = ctl_addr; X X if (!look_for_invite(&response)) { X X /* we must be initiating a talk */ X X return(0); X } X X /* X * there was an invitation waiting for us, X * so connect with the other (hopefully waiting) party X */ X X current_state = "Waiting to connect with caller"; X X response = swapresponse(response); X while (connect(sockt, &response.addr, sizeof(response.addr)) != 0) { X if (errno == ECONNREFUSED) { X X /* the caller gave up, but his invitation somehow X * was not cleared. Clear it and initiate an X * invitation. (We know there are no newer invitations, X * the talkd works LIFO.) X */ X X ctl_transact(his_machine_addr, msg, DELETE, &response); X close(sockt); X open_sockt(); X return(0); X } else if (errno == EINTR) { X /* we have returned from an interupt handler */ X continue; X } else { X p_error("Unable to connect with initiator"); X } X } X X return(1); X} X X /* look for an invitation on 'machine' */ X Xlook_for_invite(response) XCTL_RESPONSE *response; X{ X struct in_addr machine_addr; X X current_state = "Checking for invitation on caller's machine"; X X ctl_transact(his_machine_addr, msg, LOOK_UP, response); X X /* the switch is for later options, such as multiple X invitations */ X X switch (response->answer) { X X case SUCCESS: X X msg.id_num = response->id_num; X return(1); X X default : X /* there wasn't an invitation waiting for us */ X return(0); X } X} X X/* X * heuristic to detect if need to reshuffle CTL_RESPONSE structure X */ X X#define swapshort(a) (((a << 8) | ((unsigned short) a >> 8)) & 0xffff) X#define swaplong(a) ((swapshort(a) << 16) | (swapshort(((unsigned)a >> 16)))) X X#ifdef sun Xstruct ctl_response_vax { X char type; X char answer; X short junk; X int id_num; X struct sockaddr_in addr; X}; X XCTL_RESPONSE Xswapresponse(rsp) X CTL_RESPONSE rsp; X{ X struct ctl_response_vax swaprsp; X X if (rsp.addr.sin_family != AF_INET) { X bcopy(&rsp, &swaprsp, sizeof(CTL_RESPONSE)); X swaprsp.addr.sin_family = swapshort(swaprsp.addr.sin_family); X if (swaprsp.addr.sin_family == AF_INET) { X rsp.addr = swaprsp.addr; X rsp.type = swaprsp.type; X rsp.answer = swaprsp.answer; X rsp.id_num = swaplong(swaprsp.id_num); X } X } X return rsp; X} X#endif X X#ifdef vax Xstruct ctl_response_sun { X char type; X char answer; X unsigned short id_num2; X unsigned short id_num1; X short sin_family; X short sin_port; X short sin_addr2; X short sin_addr1; X}; X XCTL_RESPONSE Xswapresponse(rsp) X CTL_RESPONSE rsp; X{ X struct ctl_response_sun swaprsp; X X if (rsp.addr.sin_family != AF_INET) { X bcopy(&rsp, &swaprsp, sizeof(struct ctl_response_sun)); X if (swaprsp.sin_family == swapshort(AF_INET)) { X rsp.type = swaprsp.type; X rsp.answer = swaprsp.answer; X rsp.id_num = swapshort(swaprsp.id_num1) X | (swapshort(swaprsp.id_num2) << 16); X rsp.addr.sin_family = swapshort(swaprsp.sin_family); X rsp.addr.sin_port = swaprsp.sin_port; X rsp.addr.sin_addr.s_addr = X swaprsp.sin_addr2 | (swaprsp.sin_addr1 << 16); X } X } X return rsp; X} X#endif END_OF_look_up.c if test 3343 -ne `wc -c <look_up.c`; then echo shar: \"look_up.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f master_io.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"master_io.c\" else echo shar: Extracting \"master_io.c\" \(4055 characters\) sed "s/^X//" >master_io.c <<'END_OF_master_io.c' X#ifndef lint Xstatic char sccsid[] = "@(#)io.c 1.1 86/02/05 SMI"; /* from UCB 1.3 83/07/06 */ X#endif X X/* this file contains the I/O handling and the exchange of X edit characters. This connection itself is established in X ctl.c X */ X X#include "talk.h" X#include <stdio.h> X#include <errno.h> X#include <sys/time.h> X X#define A_LONG_TIME 10000000 X#define STDIN_MASK (1<<fileno(stdin)) /* the bit mask for standard X input */ Xextern int errno; Xextern int INPORT, OUTPORT, OUTEND; X X/* X * The routine to do the actual talking X */ X Xtalk() X{ X register int read_template, sockt_mask, inportmask; X BMSG buf; X char string[10],ch; X int read_set, nb,flag,nbuf=sizeof buf; X struct timeval wait; X X current_line = 0; X X sockt_mask = (1<<sockt); X inportmask = (1<<INPORT); X X /* X * wait on both the other process (sockt_mask) and X * standard input ( STDIN_MASK ) X */ X X read_template = sockt_mask | inportmask; X X forever { X X read_set = read_template; X X wait.tv_sec = 100000; X wait.tv_usec = 0; X X select(32, &read_set, 0, 0, &wait); X X if ( read_set & sockt_mask ) { X X /* There is data on sockt */ X nb=read(sockt,&buf,nbuf); X if(nb==nbuf)write(OUTPORT, &buf, nbuf); X } X X if ( read_set & inportmask ) { X X /* we can't make the tty non_blocking, because X curses's output routines would screw up */ X nb=read(INPORT,&buf,nbuf); X if(nb==nbuf)write(sockt, &buf, nbuf); X } X } X} X Xextern int errno; Xextern int sys_nerr; Xextern char *sys_errlist[]; X X /* p_error prints the system error message on the standard location X on the screen and then exits. (i.e. a curses version of perror) X */ X Xp_error(string) Xchar *string; X{ X char *sys; X X sys = "Unknown error"; X if(errno < sys_nerr) { X sys = sys_errlist[errno]; X } X X X printf("[%s : %s (%d)]\n", string, sys, errno); X quit(); X} X X /* display string in the standard location */ X Xmessage(string) Xchar *string; X{ X} Xtalk1() X{ char ch,ins[2][40]; X static char *im[2]={"Conversation","Input "}; X int rtn, i, ityp,iwn,wn, row, col, readmask,read_template; X int inport_mask,read_set; X BMSG buf; X int ki[2],nb,nbuf=sizeof buf; X struct timeval wait; X X ityp=1;iwn=12;ki[0]=ki[1]=0; X wmove(comwin[18].x_win,0,0); X wprintw(comwin[18].x_win,"%s",im[ityp]); X wrefresh(comwin[18].x_win); X inport_mask=(1<<INPORT); X read_template=inport_mask | STDIN_MASK; X forever { X read_set=read_template; X wait.tv_sec=100000; X wait.tv_usec=0; X select(32,&read_set,0,0,&wait); X if(read_set&inport_mask){ X nb=read(INPORT,&buf,nbuf); X if(nb==nbuf){ X wn=WN;row=ROW;col=COL; X if(row<80) wmove(comwin[wn].x_win,row,col); X if(wn<14&&STR[0]=='\\'){ X TYPE=64;write(OUTPORT,&buf,nbuf); X endwin();exit();} X if(STR[0]=='Z'|wn==12) wclear(comwin[wn].x_win); X if(STR[0]!='Z') wprintw(comwin[wn].x_win,"%s",STR); X wrefresh(comwin[wn].x_win); X } X } X if(read_set&STDIN_MASK){ X read(0,&ch,1); X if(ityp==1&&ch=='\\') { X TYPE=64;write(OUTPORT,&buf,nbuf); X write(OUTEND,&ch,1);endwin();exit();} X if(ityp==1&&ch<='z'&&ch>='a') ch&=223; X switch(ch){ X case 27: ityp=1-ityp;iwn=28-iwn; X wmove(comwin[18].x_win,0,0); X wprintw(comwin[18].x_win,"%s",im[ityp]); X wrefresh(comwin[18].x_win); X break; X case '\b': if(ki[ityp]>0){ X ki[ityp]--; X waddch(comwin[iwn].x_win,ch); X wrefresh(comwin[iwn].x_win); X } X break; X default: ins[ityp][ki[ityp]++]=ch; X waddch(comwin[iwn].x_win,ch); X wrefresh(comwin[iwn].x_win); X X } X if(ki[ityp]>=comwin[iwn].x_ncols-1&&ch!='\n'){ X ch='\n';ins[ityp][ki[ityp]++]=ch; X waddch(comwin[iwn].x_win,ch); X wrefresh(comwin[iwn].x_win); X } X if(ch=='\n'){ X if(ityp){wclear(comwin[iwn].x_win); X wrefresh(comwin[iwn].x_win);} X TYPE=ityp;ins[ityp][ki[ityp]]='\0'; X ROW=81;ki[ityp]=0; X strcpy(STR,ins[ityp]); X write(OUTPORT,&buf,nbuf); X } X } X } X} X END_OF_master_io.c if test 4055 -ne `wc -c <master_io.c`; then echo shar: \"master_io.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f master_talk.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"master_talk.c\" else echo shar: Extracting \"master_talk.c\" \(4015 characters\) sed "s/^X//" >master_talk.c <<'END_OF_master_talk.c' X#include <errno.h> X#include <signal.h> X#include <stdio.h> X#include "talk.h" X#include <sys/time.h> X Xextern int errno; Xxwin_t comwin[19]; Xint inport[5], outport[5], pid[5]; Xint INPORT, OUTPORT, ID; Xint INEND,OUTEND; Xchar player[4][20]; Xchar *getlogin(),*cp; Xchar *current_state; Xlong seed; Xstruct timeval wait; Xint readmask; X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ int fides1[2], fides2[2],endpipe[2]; X int i,j, rtn, nb ,wp,read_set,read_template; X char ins[40],ch; X BMSG buf; X int nbuf=sizeof buf; X struct sgttyb tty; X struct ltchars ltc; X struct timeval wait; X int inmask[4], sinmask, readmask, readtmp,intyp; X char inp[40],*cp,tbuf[10]; X X time(&seed); X pipe(endpipe); X for (i=0; i<=4; i++){ X rtn = pipe(fides1); X if (rtn == -1){ X printf("Error in pipe1, errno = %d\n", errno); X exit(-1); X }; X X rtn = pipe(fides2); X if (rtn == -1){ X printf("Error in pipe2, errno = %d\n", errno); X exit(-1); X }; X X for (pid[i]=fork(); pid[i]<0;pid[i]=fork()); X if (pid[i] == 0){ X ID = i; X INPORT = fides1[0]; X OUTPORT = fides2[1]; X switch(i){ X case 4: INEND=endpipe[0]; X bridge(); X exit(); X case 3: OUTEND=endpipe[1]; X init_disp(); X talk1(); X exit(); X case 2: X case 1: X case 0: X comm(2, &argv[i]); X exit(); X } X }; X inport[i] = fides2[0]; X outport[i] = fides1[1]; X cp=(char *)player[i];cp+=2; X if(i==3)strncpy(cp, getlogin(), 6); X if (i<3){strncpy(cp, argv[i+1], 6); X do{ X rtn = read(inport[i], tbuf, 10); X }while(rtn <= 1); X } X }; X read_template=0; wp=0; ins[0]=ins[1]=ins[2]=0; X for(i=0;i<=4;++i){read_template|=(1<<inport[i]);} X forever{ X read_set=read_template; X wait.tv_sec=100000; X select(32,&read_set,0,0,&wait); X for(i=0;i<=3;++i){ X if(!(read_set&(1<<inport[i]))) continue; X nb=read(inport[i],&buf,nbuf); X if(nb==nbuf){ X if(TYPE==64)exit(); X if(TYPE){ X if(!(wp&(1<<i))) continue; X wp-=(1<<i); X for(j=0;j<=2;++j) ins[j]|=STR[j]; X } X else{ X for(j=0;j<=3;++j){ X WN=14+(j-i+6)%4; X if(i!=j){ X write(outport[j],&buf,sizeof buf); X } X } X } X } X } X if(read_set&(1<<inport[4])){ X nb=read(inport[4],&buf,nbuf); X if(nb==nbuf){ X intyp=TYPE; X for(i=0;i<=3;++i){ X if(TYPE&(1<<i)) write(outport[i],&buf,nbuf); X } X if(TYPE>15) wp=TYPE&15; else wp=0; X ins[0]=ins[1]=ins[2]=0; X } X } X if(intyp<32&&intyp>15 && wp ==0){ X strncpy(STR,ins,3); X write(outport[4],&buf,nbuf);intyp=0;} X if(intyp>31&&((intyp&15)^wp)){ X write(outport[4],&buf,nbuf);intyp=0;} X } X} X Xcomm(argc, argv) Xint argc; Xchar *argv[]; X{ char string[10]; X X get_names(argc, argv); X X X open_ctl(); X open_sockt(); X start_msgs(); X X if ( !check_local() ) { X invite_remote(); X } X X end_msgs(); X write(OUTPORT, string, 10); X X talk(); X} X X Xrsend(p, ww, rr, cc, s) Xint p, ww, rr, cc; Xchar *s; X{ BMSG buf; X int nbuf = sizeof buf, rtn; X char w, r, c; X X w = ww; r = rr; c = cc; X WN = w; ROW = r; COL = c; TYPE = p; strcpy(STR, s); X rtn = write(OUTPORT, &buf, nbuf); X if (rtn <= 0){ X printf("lost pipe write %d, %d", p, errno); X exit(); X }; X} X Xrput(p,w,r,c,s) Xint p,w,r,c; Xchar *s; X{ X rsend(1<<p,w,r,c,s); X} X Xrwait(p, s, t) Xint p; Xlong t; Xchar *s; X{ X char ch; X int readset=0,rtn; X struct timeval wait; X BMSG buf; X X if(t<100)p+=16; X rsend(p+16,12,0,0,s); X wait.tv_sec=0; X readset=(1<<INPORT); X while(select(32,&readset,0,0,&wait)>0){ X wait.tv_sec=0; X read(INPORT,&buf,sizeof buf); X readset=(1<<INPORT); X } X wait.tv_sec=t; X wait.tv_usec=0; X readset=(1<<INPORT)|(1<<INEND); X rtn=select(32,&readset,0,0,&wait); X if (rtn>0){ X if(readset&(1<<INEND)) exit(); X read(INPORT,&buf,sizeof buf); X strncpy(s,STR,3); X } X return(rtn); X} X Xrget(p, s) Xint p; Xchar *s; X{ X rwait(p,s,99999); X} END_OF_master_talk.c if test 4015 -ne `wc -c <master_talk.c`; then echo shar: \"master_talk.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f msgs.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"msgs.c\" else echo shar: Extracting \"msgs.c\" \(922 characters\) sed "s/^X//" >msgs.c <<'END_OF_msgs.c' X#ifndef lint Xstatic char sccsid[] = "@(#)msgs.c 1.1 86/02/05 SMI"; /* from UCB 1.4 83/07/06 */ X#endif X X/* X * a package to display what is happening every MSG_INTERVAL seconds X * if we are slow connecting. X */ X X#include <signal.h> X#include <stdio.h> X#include <sys/time.h> X#include "talk.h" X X#define MSG_INTERVAL 4 X#define LONG_TIME 100000 X Xchar *current_state; Xint current_line = 0; X Xstatic struct itimerval itimer; Xstatic struct timeval wait = { MSG_INTERVAL , 0}; Xstatic struct timeval undo = { LONG_TIME, 0}; X X Xdisp_msg() X{ X message(current_state); X} X Xstart_msgs() X{ X message(current_state); X signal(SIGALRM, disp_msg); X itimer.it_value = itimer.it_interval = wait; X setitimer(ITIMER_REAL, &itimer, (struct timerval *)0); X} X Xend_msgs() X{ X signal(SIGALRM, SIG_IGN); X timerclear(&itimer.it_value); X timerclear(&itimer.it_interval); X setitimer(ITIMER_REAL, &itimer, (struct timerval *)0); X} END_OF_msgs.c if test 922 -ne `wc -c <msgs.c`; then echo shar: \"msgs.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f slave_io.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"slave_io.c\" else echo shar: Extracting \"slave_io.c\" \(2340 characters\) sed "s/^X//" >slave_io.c <<'END_OF_slave_io.c' X#include "talk.h" X#include <stdio.h> X#include <errno.h> X#include <sys/time.h> X X#define A_LONG_TIME 10000000 X#define STDIN_MASK (1<<fileno(stdin)) /* the bit mask for standard X input */ Xextern int errno; X X/* X * The routine to do the actual talking X */ X X Xtalk() X{ char ch,ins[2][40]; X static char *im[2]={"Conversation","Input "}; X int rtn, i, ityp,iwn,wn, row, col, readmask,read_template; X int sockt_mask,read_set; X BMSG buf; X int ki[2],nb,nbuf=sizeof buf; X struct timeval wait; X X ityp=1;iwn=12;ki[0]=ki[1]=0; X wmove(comwin[18].x_win,0,0); X wprintw(comwin[18].x_win,"%s",im[ityp]); X wrefresh(comwin[18].x_win); X sockt_mask=(1<<sockt); X read_template=sockt_mask | STDIN_MASK; X forever { X read_set=read_template; X wait.tv_sec=100000; X wait.tv_usec=0; X select(32,&read_set,0,0,&wait); X if(read_set&sockt_mask){ X nb=read(sockt,&buf,nbuf); X if(nb==nbuf){ X wn=WN;row=ROW;col=COL; X if(row<80) wmove(comwin[wn].x_win,row,col); X if(wn<14&&STR[0]=='\\'){endwin();exit();} X if(STR[0]=='Z'|wn==12) wclear(comwin[wn].x_win); X if(STR[0]!='Z') wprintw(comwin[wn].x_win,"%s",STR); X wrefresh(comwin[wn].x_win); X } X } X if(read_set&STDIN_MASK){ X read(0,&ch,1); X if(ityp==1&&ch<='z'&&ch>='a') ch&=223; X switch(ch){ X case 27: ityp=1-ityp;iwn=28-iwn; X wmove(comwin[18].x_win,0,0); X wprintw(comwin[18].x_win,"%s",im[ityp]); X wrefresh(comwin[18].x_win); X break; X case '\b': if(ki[ityp]>0){ X ki[ityp]--; X waddch(comwin[iwn].x_win,ch); X wrefresh(comwin[iwn].x_win); X } X break; X default: ins[ityp][ki[ityp]++]=ch; X waddch(comwin[iwn].x_win,ch); X wrefresh(comwin[iwn].x_win); X X } X if(ki[ityp]>=comwin[iwn].x_ncols-1&&ch!='\n'){ X ch='\n';ins[ityp][ki[ityp]++]=ch; X waddch(comwin[iwn].x_win,ch); X wrefresh(comwin[iwn].x_win); X } X if(ch=='\n'){ X if(ityp){wclear(comwin[iwn].x_win); X wrefresh(comwin[iwn].x_win);} X TYPE=ityp;ins[ityp][ki[ityp]]='\0'; X ROW=81;ki[ityp]=0; X strcpy(STR,ins[ityp]); X write(sockt,&buf,nbuf); X } X } X } X} X X Xp_error(string) Xchar *string; X{ X char *sys; X X sys = "Unknown error"; X X X printf("[%s : %s (%d)]\n", string, sys, errno); X quit(); X} X X /* display string in the standard location */ X Xmessage(string) Xchar *string; X{ X} END_OF_slave_io.c if test 2340 -ne `wc -c <slave_io.c`; then echo shar: \"slave_io.c\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 1 \(of 2\). cp /dev/null ark1isdone 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