1 
2 /*
3     xskat - a card game for 1 to 3 players.
4     Copyright (C) 2004  Gunter Gerhardt
5 
6     This program is free software; you can redistribute it freely.
7     Use it at your own risk; there is NO WARRANTY.
8 
9     Redistribution of modified versions is permitted
10     provided that the following conditions are met:
11     1. All copyright & permission notices are preserved.
12     2.a) Only changes required for packaging or porting are made.
13       or
14     2.b) It is clearly stated who last changed the program.
15          The program is renamed or
16          the version number is of the form x.y.z,
17          where x.y is the version of the original program
18          and z is an arbitrary suffix.
19 */
20 
21 #define IRC_C
22 
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <signal.h>
28 #include <fcntl.h>
29 #include <sys/types.h>
30 #include "defs.h"
31 #include "skat.h"
32 #include "xio.h"
33 #include "xdial.h"
34 #include "text.h"
35 #include "irc.h"
36 
irc_log(s,in)37 VOID irc_log(s,in)
38 char *s;
39 int in;
40 {
41   static FILE *f;
42   static int ini,nl;
43 
44   if (!irc_logfile) return;
45   if (!ini) {
46     f=strcmp(irc_logfile,"-")?fopen(irc_logfile,irc_logappend?"a":"w"):stdout;
47     if (!f) {
48       fprintf(stderr,"Can't write file %s\n",irc_logfile);
49       irc_logfile=0;
50       return;
51     }
52     ini=nl=1;
53   }
54   if (nl) {
55     fputs(in?"<-":"->",f);
56     nl=0;
57   }
58   fprintf(f,"%s",s);
59   if (strchr(s,'\n')) {
60     nl=1;
61     fflush(f);
62   }
63 }
64 
irc_out(s)65 VOID irc_out(s)
66 char *s;
67 {
68   write(irc_o,s,strlen(s));
69   irc_log(s,0);
70 }
71 
irc_print(s)72 VOID irc_print(s)
73 char *s;
74 {
75   unsigned char c;
76 
77   while ((c=*s++)) {
78     if (c>=' ' || c=='\b' || c=='\t' || c=='\n' || c=='\r') {
79       while (fputc(c,stderr)==EOF);
80     }
81   }
82   fflush(stderr);
83 }
84 
irc_printnl(s)85 VOID irc_printnl(s)
86 char *s;
87 {
88   irc_print(s);
89   irc_print("\n");
90 }
91 
irc_getline()92 char *irc_getline()
93 {
94   static char buf[1024];
95   static int siz,rst;
96   static ssize_t cnt;
97   char *ptr;
98 
99   ptr=buf;
100   if (rst) {
101     while (cnt--) *ptr++=buf[++siz];
102     cnt=siz=ptr-buf;
103     rst=0;
104     ptr=buf;
105   }
106   if (cnt<=0) {
107     ptr=buf+siz;
108     cnt=read(irc_i,ptr,sizeof(buf)-siz);
109   }
110   if (cnt>0) {
111     while (cnt && *ptr!='\n') cnt--,ptr++;
112     siz=ptr-buf;
113     if (cnt) {
114       cnt--;
115       *ptr=0;
116       rst=1;
117       if (*buf!=':' || !(ptr=strchr(buf,' ')) || strncmp(ptr+1,"322",3)) {
118 	irc_log(buf,1);
119 	irc_log("\n",1);
120       }
121       return buf;
122     }
123     if (siz==sizeof(buf)) {
124       cnt=siz=0;
125     }
126   }
127   return 0;
128 }
129 
irc_xinput(s,l)130 int irc_xinput(s,l)
131 char *s;
132 int l;
133 {
134   s[l]=0;
135   switch (s[0]) {
136   case '\r':
137     if (!irc_inplen) return 0;
138     s[0]='\n';
139     break;
140   case '\b':case 127:
141     if (irc_inplen) {
142       strcpy(s,"\b \b");
143     }
144     else {
145       s[0]=l=0;
146     }
147     break;
148   case ' ':
149   case '\t':
150     if (!irc_inplen) return 0;
151     break;
152   case 0x1B:
153     return 0;
154   }
155   irc_print(s);
156   if (s[0]=='\n') {
157     irc_inpbuf[irc_inplen]=0;
158     irc_talk(irc_inpbuf);
159     irc_inplen=0;
160   }
161   else if (s[0]=='\b') {
162     irc_inplen--;
163   }
164   else if (irc_inplen+l<sizeof(irc_inpbuf)){
165     strcpy(irc_inpbuf+irc_inplen,s);
166     irc_inplen+=l;
167   }
168   else {
169     irc_inplen=0;
170   }
171   return 1;
172 }
173 
irc_match(cmd,s)174 int irc_match(cmd,s)
175 char *cmd;
176 char **s;
177 {
178   int len;
179 
180   len=strlen(cmd);
181   if (!strncmp(*s,cmd,len)) {
182     *s+=len;
183     return 1;
184   }
185   return 0;
186 }
187 
irc_sendnick(s)188 VOID irc_sendnick(s)
189 char *s;
190 {
191   irc_out("nick ");
192   irc_out(s);
193   irc_out("\n");
194 }
195 
irc_pr_ss(s1,s2)196 VOID irc_pr_ss(s1,s2)
197 char *s1,*s2;
198 {
199   irc_print(s1);
200   irc_print(" : ");
201   irc_printnl(s2);
202 }
203 
irc_pr_bs(s)204 VOID irc_pr_bs(s)
205 char *s;
206 {
207   irc_print(" ");
208   irc_printnl(s);
209 }
210 
irc_pr_sd(s,d)211 VOID irc_pr_sd(s,d)
212 char *s;
213 int d;
214 {
215   char buf[20];
216 
217   sprintf(buf,"%d",d);
218   irc_print(s);
219   irc_print(" : ");
220   irc_printnl(buf);
221 }
222 
irc_pr_ramsch(val)223 VOID irc_pr_ramsch(val)
224 int val;
225 {
226   irc_pr_ss(textarr[TX_RAMSCH_SPIELEN].t[lang[0]],
227 	    textarr[val==2?TX_IMMER:TX_NEIN-val].t[lang[0]]);
228 }
229 
irc_pr_sramsch(val)230 VOID irc_pr_sramsch(val)
231 int val;
232 {
233   irc_pr_ss(textarr[TX_SCHIEBERAMSCH].t[lang[0]],
234 	    textarr[TX_NEIN-val].t[lang[0]]);
235 }
236 
irc_pr_rskatloser(val)237 VOID irc_pr_rskatloser(val)
238 int val;
239 {
240   irc_pr_ss(textarr[TX_SKAT_GEHT_AN].t[lang[0]],
241 	    textarr[val?TX_VERLIERER:TX_LETZTEN_STICH].t[lang[0]]);
242 }
243 
irc_pr_kontra(val)244 VOID irc_pr_kontra(val)
245 int val;
246 {
247   irc_pr_ss(textarr[TX_KONTRA_SAGEN].t[lang[0]],
248 	    textarr[val==2?TX_AB18:TX_NEIN-val].t[lang[0]]);
249 }
250 
irc_pr_bock(val)251 VOID irc_pr_bock(val)
252 int val;
253 {
254   irc_pr_ss(textarr[TX_BOCK_RUNDEN].t[lang[0]],
255 	    textarr[val==2?TX_UND_RAMSCH:TX_NEIN-val].t[lang[0]]);
256 }
257 
irc_pr_resumebock(val)258 VOID irc_pr_resumebock(val)
259 int val;
260 {
261   irc_pr_ss(textarr[TX_FORTSETZEN].t[lang[0]],
262 	    textarr[TX_NEIN-val].t[lang[0]]);
263 }
264 
irc_pr_spitze(val)265 VOID irc_pr_spitze(val)
266 int val;
267 {
268   irc_pr_ss(textarr[TX_SPITZE].t[lang[0]],
269 	    textarr[val==2?TX_PLUS2:TX_NEIN-val].t[lang[0]]);
270 }
271 
irc_pr_revolution(val)272 VOID irc_pr_revolution(val)
273 int val;
274 {
275   irc_pr_ss(textarr[TX_REVOLUTION].t[lang[0]],
276 	    textarr[TX_NEIN-val].t[lang[0]]);
277 }
278 
irc_pr_klopfen(val)279 VOID irc_pr_klopfen(val)
280 int val;
281 {
282   irc_pr_ss(textarr[TX_KLOPFEN].t[lang[0]],
283 	    textarr[TX_NEIN-val].t[lang[0]]);
284 }
285 
irc_pr_schenken(val)286 VOID irc_pr_schenken(val)
287 int val;
288 {
289   irc_pr_ss(textarr[TX_SCHENKEN].t[lang[0]],
290 	    textarr[TX_NEIN-val].t[lang[0]]);
291 }
292 
irc_pr_oldrules(val)293 VOID irc_pr_oldrules(val)
294 int val;
295 {
296   irc_pr_ss(textarr[TX_ALTE_REGELN].t[lang[0]],
297 	    textarr[TX_NEIN-val].t[lang[0]]);
298 }
299 
irc_pr_bockevents(val)300 VOID irc_pr_bockevents(val)
301 int val;
302 {
303   irc_print(textarr[TX_BOCK_EREIGNISSE_T].t[lang[0]]+1);
304   irc_printnl(":");
305   if (val&BOCK_BEI_60) {
306     irc_pr_bs(textarr[TX_VERLOREN_MIT_60].t[lang[0]]);
307   }
308   if (val&BOCK_BEI_GRANDHAND) {
309     irc_pr_bs(textarr[TX_GRAND_HAND_GEWONNEN].t[lang[0]]);
310   }
311   if (val&BOCK_BEI_KONTRA) {
312     irc_pr_bs(textarr[TX_ERFOLGREICHER_KONTRA].t[lang[0]]);
313   }
314   if (val&BOCK_BEI_RE) {
315     irc_pr_bs(textarr[TX_KONTRA_RE_ANGESAGT].t[lang[0]]);
316   }
317   if (val&BOCK_BEI_NNN) {
318     irc_pr_bs(textarr[TX_NNN_IN_SPIELLISTE].t[lang[0]]);
319   }
320   if (val&BOCK_BEI_N00) {
321     irc_pr_bs(textarr[TX_N00_IN_SPIELLISTE].t[lang[0]]);
322   }
323   if (val&BOCK_BEI_72) {
324     irc_pr_bs(textarr[TX_SPIELWERT_72].t[lang[0]]);
325   }
326   if (val&BOCK_BEI_96) {
327     irc_pr_bs(textarr[TX_SPIELWERT_96].t[lang[0]]);
328   }
329 }
330 
irc_pr_alist(val)331 VOID irc_pr_alist(val)
332 int val;
333 {
334   irc_pr_ss(textarr[TX_SPIELLISTE].t[lang[0]],
335 	    textarr[val==2?TX_TURNIER:val?TX_ALTERNATIV:TX_NORMAL].t[lang[0]]);
336 }
337 
irc_pr_start(val)338 VOID irc_pr_start(val)
339 int val;
340 {
341   irc_pr_sd(textarr[TX_GEBER].t[lang[0]],right(val)?right(val):3);
342 }
343 
irc_pr_s1(val)344 VOID irc_pr_s1(val)
345 int val;
346 {
347   irc_pr_sd(textarr[TX_SPIELSTAERKE].t[lang[0]],val);
348 }
349 
irc_showrules(aplayramsch,aplaysramsch,aplaykontra,aplaybock,aresumebock,aspitzezaehlt,arevolution,aklopfen,aschenken,abockevents,ageber,aalist,astrateg,aoldrules,arskatloser)350 VOID irc_showrules(aplayramsch,aplaysramsch,aplaykontra,aplaybock,
351 		   aresumebock,aspitzezaehlt,arevolution,aklopfen,
352 		   aschenken,abockevents,ageber,aalist,astrateg,
353 		   aoldrules,arskatloser)
354 int aplayramsch,aplaysramsch,aplaykontra,aplaybock;
355 int aresumebock,aspitzezaehlt,arevolution,aklopfen;
356 int aschenken,abockevents,ageber,aalist,astrateg;
357 int aoldrules,arskatloser;
358 {
359   int f=1;
360 
361   if (aplayramsch) {
362     f=0;
363     irc_pr_ramsch(aplayramsch);
364     irc_pr_sramsch(aplaysramsch);
365     irc_pr_rskatloser(arskatloser);
366   }
367   if (aplaykontra) {
368     f=0;
369     irc_pr_kontra(aplaykontra);
370   }
371   if (aplaybock && (abockevents&(2*BOCK_BEI_LAST-1))) {
372     f=0;
373     irc_pr_bock(aplaybock);
374     irc_pr_resumebock(aresumebock);
375     irc_pr_bockevents(abockevents);
376   }
377   if (aspitzezaehlt) {
378     f=0;
379     irc_pr_spitze(aspitzezaehlt);
380   }
381   if (arevolution) {
382     f=0;
383     irc_pr_revolution(arevolution);
384   }
385   if (aklopfen) {
386     f=0;
387     irc_pr_klopfen(aklopfen);
388   }
389   if (aschenken) {
390     f=0;
391     irc_pr_schenken(aschenken);
392   }
393   if (aoldrules) {
394     f=0;
395     irc_pr_oldrules(aoldrules);
396   }
397   if (f) {
398     irc_printnl(textarr[TX_OFFIZIELLE_REGELN].t[lang[0]]);
399   }
400   irc_pr_alist(aalist);
401   irc_pr_start(ageber);
402   irc_pr_s1(astrateg);
403 }
404 
irc_sendrules()405 VOID irc_sendrules()
406 {
407   char buf[1024];
408 
409   sprintf(buf,"notice %s :/rules %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
410 	  irc_channel,
411 	  playramsch,playsramsch,playkontra,playbock,
412 	  resumebock,spitzezaehlt,revolution,klopfen,
413 	  schenken,bockevents,geber,alist[0],strateg[0],oldrules,rskatloser);
414   irc_out(buf);
415 }
416 
irc_incidx(idx,sn)417 VOID irc_incidx(idx,sn)
418 int *idx,sn;
419 {
420   if (++idx[sn]>=100) idx[sn]=0;
421 }
422 
irc_sync(q)423 VOID irc_sync(q)
424 char *q;
425 {
426   int idx[3],n=0;
427 
428   sscanf(q,"%d,%d,%d\n",&idx[0],&idx[1],&idx[2]);
429   while (idx[irc_pos]!=irc_histidx[irc_pos]) {
430     irc_out("notice ");
431     irc_out(irc_channel);
432     irc_out(irc_history[irc_pos][idx[irc_pos]]);
433     irc_incidx(idx,irc_pos);
434     if (++n>3) {
435       n=0;
436       sleep(3);
437     }
438   }
439 }
440 
irc_sendsync(f)441 VOID irc_sendsync(f)
442 int f;
443 {
444   char buf[1024];
445 
446   sprintf(buf,"notice %s :/sync%s %d,%d,%d\n",
447 	  irc_channel,
448 	  f?"":"ed",irc_histidx[0],irc_histidx[1],irc_histidx[2]);
449   irc_out(buf);
450   irc_tick=ticker;
451 }
452 
irc_checksync()453 VOID irc_checksync()
454 {
455   if (irc_state==IRC_PLAYING &&
456       ticker-irc_tick>(30+5*irc_pos)*1000 &&
457       !lost[0] && !lost[1] && !lost[2]) {
458     irc_sendsync(1);
459   }
460 }
461 
irc_alarm()462 VOID irc_alarm()
463 {
464   if (irc_bell) {
465     XBell(dpy[0],100);
466     XFlush(dpy[0]);
467   }
468 }
469 
irc_talk(msg)470 VOID irc_talk(msg)
471 char *msg;
472 {
473   static int ini,len;
474   static char buf[1024],channel[1024],nick[IRC_NICK_LEN+1];
475   int i,c;
476   char *p,plb[80];
477 
478   irc_checksync();
479   irc_checkhist();
480   if (!ini) {
481     if (fcntl(fileno(stdin),F_SETFL,
482 	      fcntl(fileno(stdin),F_GETFL)|O_NONBLOCK)<0) {
483       fprintf(stderr,"Fcntl stdin failed\n");
484       exitus(1);
485     }
486     ini=1;
487   }
488   while (msg || (c=getchar())!=EOF) {
489     if (msg) {
490       len=strlen(msg);
491       c='\n';
492       p=msg;
493     }
494     else p=buf;
495     if (len>=sizeof(buf)) len=0;
496     if (c=='\n') {
497       if (len) {
498 	buf[len]=0;
499 	if (irc_match("/join ",&p)) {
500 	  irc_out("privmsg ");
501 	  irc_out(irc_channel);
502 	  irc_out(" :--> ");
503 	  irc_out(p);
504 	  irc_out("\n");
505 	  irc_out("part ");
506 	  irc_out(irc_channel);
507 	  irc_out("\n");
508 	  strcpy(channel,p);
509 	  irc_channel=channel;
510 	  irc_out("join ");
511 	  irc_out(irc_channel);
512 	  irc_out("\n");
513 	}
514 	else if (irc_match("/who",&p)) {
515 	  irc_out("who ");
516 	  irc_out(irc_channel);
517 	  irc_out("\n");
518 	}
519 	else if (irc_match("/list",&p)) {
520 	  if (*p==' ') {
521 	    strncpy(irc_substr,p+1,sizeof(irc_substr)-1);
522 	  }
523 	  else {
524 	    strcpy(irc_substr,"xskat");
525 	  }
526 	  irc_out("list\n");
527 	}
528 	else if (irc_match("/sync",&p)) {
529 	  irc_sendsync(1);
530 	}
531 	else if (irc_match("/bell",&p)) {
532 	  irc_bell^=1;
533 	  irc_alarm();
534 	}
535 	else if (irc_match("/nick",&p)) {
536 	  if (*p++==' ') {
537 	    strncpy(nick,p,IRC_NICK_LEN);
538 	    nick[IRC_NICK_LEN]=0;
539 	    irc_sendnick(nick);
540 	  }
541 	  else {
542 	    irc_printnl(irc_nick);
543 	  }
544 	}
545 	else if (irc_match("/pos ",&p)) {
546 	  if (irc_state==IRC_TALK) {
547 	    irc_pos=atoi(p);
548 	    irc_pos--;
549 	    if (irc_pos<0 || irc_pos>2) irc_pos=-1;
550 	    irc_pr_sd(textarr[TX_POSITION].t[lang[0]],irc_pos+1);
551 	  }
552 	}
553 	else if (irc_match("/ramsch ",&p)) {
554 	  if (irc_state==IRC_TALK) {
555 	    playramsch=atoi(p);
556 	    if (playramsch<0) playramsch=0;
557 	    else if (playramsch>2) playramsch=2;
558 	    irc_pr_ramsch(playramsch);
559 	  }
560 	}
561 	else if (irc_match("/sramsch ",&p)) {
562 	  if (irc_state==IRC_TALK) {
563 	    playsramsch=istrue(p);
564 	    irc_pr_sramsch(playsramsch);
565 	  }
566 	}
567 	else if (irc_match("/skattoloser ",&p)) {
568 	  if (irc_state==IRC_TALK) {
569 	    rskatloser=istrue(p);
570 	    irc_pr_rskatloser(rskatloser);
571 	  }
572 	}
573 	else if (irc_match("/kontra ",&p)) {
574 	  if (irc_state==IRC_TALK) {
575 	    playkontra=atoi(p);
576 	    if (playkontra<0) playkontra=0;
577 	    else if (playkontra>2) playkontra=2;
578 	    irc_pr_kontra(playkontra);
579 	  }
580 	}
581 	else if (irc_match("/bock ",&p)) {
582 	  if (irc_state==IRC_TALK) {
583 	    playbock=atoi(p);
584 	    if (playbock<0) playbock=0;
585 	    else if (playbock>2) playbock=2;
586 	    irc_pr_bock(playbock);
587 	  }
588 	}
589 	else if (irc_match("/resumebock ",&p)) {
590 	  if (irc_state==IRC_TALK) {
591 	    resumebock=istrue(p);
592 	    irc_pr_resumebock(resumebock);
593 	  }
594 	}
595 	else if (irc_match("/spitze ",&p)) {
596 	  if (irc_state==IRC_TALK) {
597 	    spitzezaehlt=atoi(p);
598 	    if (spitzezaehlt<0) spitzezaehlt=0;
599 	    else if (spitzezaehlt>2) spitzezaehlt=2;
600 	    irc_pr_spitze(spitzezaehlt);
601 	  }
602 	}
603 	else if (irc_match("/revolution ",&p)) {
604 	  if (irc_state==IRC_TALK) {
605 	    revolution=istrue(p);
606 	    irc_pr_revolution(revolution);
607 	  }
608 	}
609 	else if (irc_match("/klopfen ",&p)) {
610 	  if (irc_state==IRC_TALK) {
611 	    klopfen=istrue(p);
612 	    irc_pr_klopfen(klopfen);
613 	  }
614 	}
615 	else if (irc_match("/schenken ",&p)) {
616 	  if (irc_state==IRC_TALK) {
617 	    schenken=istrue(p);
618 	    irc_pr_schenken(schenken);
619 	  }
620 	}
621 	else if (irc_match("/oldrules ",&p)) {
622 	  if (irc_state==IRC_TALK) {
623 	    oldrules=istrue(p);
624 	    irc_pr_oldrules(oldrules);
625 	  }
626 	}
627 	else if (irc_match("/bockevents ",&p)) {
628 	  if (irc_state==IRC_TALK) {
629 	    bockevents=atoi(p);
630 	    irc_pr_bockevents(bockevents);
631 	  }
632 	}
633 	else if (irc_match("/alist ",&p)) {
634 	  if (irc_state==IRC_TALK) {
635 	    alist[0]=istrue(p);
636 	    irc_pr_alist(alist[0]);
637 	  }
638 	}
639 	else if (irc_match("/tlist ",&p)) {
640 	  if (irc_state==IRC_TALK) {
641 	    alist[0]=istrue(p)?2:0;
642 	    irc_pr_alist(alist[0]);
643 	  }
644 	}
645 	else if (irc_match("/start ",&p)) {
646 	  if (irc_state==IRC_TALK) {
647 	    geber=atoi(p);
648 	    if (geber<1 || geber>3) geber=0;
649 	    else geber=left(geber);
650 	    irc_pr_start(geber);
651 	  }
652 	}
653 	else if (irc_match("/s1 ",&p)) {
654 	  if (irc_state==IRC_TALK) {
655 	    strateg[0]=atoi(p);
656 	    if (strateg[0]<-4) strateg[0]=-4;
657 	    else if (strateg[0]>0) strateg[0]=0;
658 	    irc_pr_s1(strateg[0]);
659 	  }
660 	}
661 	else if (irc_match("/default",&p)) {
662 	  if (irc_state==IRC_TALK) {
663 	    playramsch=playsramsch=playkontra=playbock=resumebock=0;
664 	    spitzezaehlt=revolution=klopfen=schenken=bockevents=oldrules=0;
665 	    rskatloser=0;
666 	    irc_printnl(textarr[TX_OFFIZIELLE_REGELN].t[lang[0]]);
667 	  }
668 	}
669 	else if (irc_match("/rules",&p)) {
670 	  if (irc_state==IRC_TALK) {
671 	    irc_showrules(playramsch,playsramsch,playkontra,playbock,
672 			  resumebock,spitzezaehlt,revolution,klopfen,
673 			  schenken,bockevents,geber,alist[0],strateg[0],
674 			  oldrules,rskatloser);
675 	    irc_sendrules();
676 	  }
677 	}
678 	else if (irc_match("/go",&p)) {
679 	  if (irc_state==IRC_TALK || irc_state==IRC_SERVER) {
680 	    if (!strcmp(irc_channel,"#xskat")) {
681 	      irc_printnl(textarr[TX_NICHT_HIER].t[lang[0]]);
682 	    }
683 	    else {
684 	      irc_clients=0;
685 	      irc_2player=*p=='2';
686 	      irc_out("notice ");
687 	      irc_out(irc_channel);
688 	      irc_out(" :/server ");
689 	      irc_out(textarr[TX_XSKAT].t[lang[0]]);
690 	      irc_out("\n");
691 	      sprintf(plb,textarr[TX_WARTEN_AUF_SPIELER_N].t[lang[0]],2);
692 	      irc_printnl(plb);
693 	      irc_state=IRC_SERVER;
694 	    }
695 	  }
696 	}
697 	else if (irc_match("/quote ",&p)) {
698 	  irc_out(p);
699 	  irc_out("\n");
700 	}
701 	else if (irc_match("/help",&p)) {
702 	  for (i=TX_IRC_HELP01;i<=TX_IRC_HELPXX;i++) {
703 	    irc_printnl(textarr[i].t[lang[0]]);
704 	  }
705 	}
706 	else if (irc_match("/quit",&p)) {
707 	  exitus(1);
708 	}
709 	else if (*p=='/') {
710 	  irc_printnl(textarr[TX_UNBEKANNTES_KOMMANDO].t[lang[0]]);
711 	}
712 	else {
713 	  if (!strcmp(p,"go") || !strcmp(p,"go2")) {
714 	    sprintf(plb,textarr[TX_SOLLTE_DAS_GO_X_SEIN].t[lang[0]],p+2);
715 	    irc_printnl(plb);
716 	  }
717 	  else {
718 	    irc_out("privmsg ");
719 	    irc_out(irc_channel);
720 	    irc_out(" :");
721 	    irc_out(p);
722 	    irc_out("\n");
723 	  }
724 	}
725 	len=0;
726       }
727     }
728     else {
729       buf[len++]=c;
730     }
731     msg=0;
732   }
733 }
734 
irc_copyname(t,f)735 char *irc_copyname(t,f)
736 char *t,*f;
737 {
738   char *p;
739 
740   p=strchr(f,'~');
741   *p=0;
742   strcpy(t,f);
743   return p+1;
744 }
745 
irc_senderok(s)746 int irc_senderok(s)
747 char *s;
748 {
749   switch (irc_pos) {
750   case 0:return !strcmp(irc_conf[1].nick,s)?2:
751     !irc_2player && !strcmp(irc_conf[2].nick,s)?3:0;
752   case 1:return !strcmp(irc_conf[0].nick,s)?1:
753     !irc_2player && !strcmp(irc_conf[2].nick,s)?3:0;
754   default:return !strcmp(irc_conf[0].nick,s)?1:
755     !strcmp(irc_conf[1].nick,s)?2:0;
756   }
757 }
758 
irc_histsave(sn,s)759 VOID irc_histsave(sn,s)
760 int sn;
761 char *s;
762 {
763   irc_out(s);
764   s=strchr(strchr(s,' ')+1,' ');
765   if (irc_history[sn][irc_histidx[sn]]) {
766     free(irc_history[sn][irc_histidx[sn]]);
767   }
768   if (!(irc_history[sn][irc_histidx[sn]]=(char *)malloc(strlen(s)+1))) {
769     nomem();
770   }
771   strcpy(irc_history[sn][irc_histidx[sn]],s);
772   irc_incidx(irc_histidx,sn);
773 }
774 
irc_sendbtev(sn,bt)775 VOID irc_sendbtev(sn,bt)
776 int sn,bt;
777 {
778   char buf[1024];
779 
780   sprintf(buf,"notice %s :/cmd%02dbt %d\n",
781 	  irc_channel,irc_histidx[sn],bt);
782   irc_histsave(sn,buf);
783 }
784 
irc_sendxyev(sn,x,y,opt)785 VOID irc_sendxyev(sn,x,y,opt)
786 int sn,x,y,opt;
787 {
788   char buf[1024];
789 
790   sprintf(buf,"notice %s :/cmd%02dxy %d,%d,%d\n",
791 	  irc_channel,irc_histidx[sn],x,y,opt);
792   irc_histsave(sn,buf);
793 }
794 
irc_sendsort(sn)795 VOID irc_sendsort(sn)
796 int sn;
797 {
798   char buf[1024];
799 
800   sprintf(buf,"notice %s :/cmd%02dso %d,%d,%d\n",
801 	  irc_channel,irc_histidx[sn],
802 	  sort1[sn],sort2[sn],alternate[sn]);
803   irc_histsave(sn,buf);
804 }
805 
irc_sendschenken(sn)806 VOID irc_sendschenken(sn)
807 int sn;
808 {
809   char buf[1024];
810 
811   sprintf(buf,"notice %s :/cmd%02dsc\n",
812 	  irc_channel,irc_histidx[sn]);
813   irc_histsave(sn,buf);
814 }
815 
irc_sendloeschen(sn)816 VOID irc_sendloeschen(sn)
817 int sn;
818 {
819   char buf[1024];
820 
821   sprintf(buf,"notice %s :/cmd%02dcl\n",
822 	  irc_channel,irc_histidx[sn]);
823   irc_histsave(sn,buf);
824 }
825 
irc_addcmd(sn,idx,p)826 VOID irc_addcmd(sn,idx,p)
827 int sn,idx;
828 char *p;
829 {
830   if (irc_history[sn][idx]) free(irc_history[sn][idx]);
831   else irc_histcnt[sn]++;
832   if (!(irc_history[sn][idx]=(char *)malloc(strlen(p)+1))) nomem();
833   strcpy(irc_history[sn][idx],p);
834 }
835 
irc_getcmd(sn,fh,q)836 int irc_getcmd(sn,fh,q)
837 int sn,fh;
838 char *q;
839 {
840   int idx,bt,x,y,opt,s1,s2,a,ok;
841   char *p=q;
842 
843   ok=0;
844   sscanf(q,"%d",&idx);
845   q+=2;
846   if (idx!=irc_histidx[sn]) {
847     if (irc_histidx[sn]-idx+(idx>irc_histidx[sn]?100:0)>50) {
848       if (!irc_histcnt[sn]) irc_sendsync(1);
849       else irc_addcmd(sn,idx,p);
850     }
851     return ok;
852   }
853   if (irc_match("bt ",&q)) {
854     sscanf(q,"%d\n",&bt);
855     if (actdial[sn]) {
856       irc_incidx(irc_histidx,sn);
857       hndl_btevent(sn,bt);
858       ok=1;
859     }
860   }
861   else if (irc_match("xy ",&q)) {
862     sscanf(q,"%d,%d,%d\n",&x,&y,&opt);
863     if (hndl_button(sn,x,y,opt,0)) {
864       irc_incidx(irc_histidx,sn);
865       ok=1;
866     }
867   }
868   else if (irc_match("so ",&q)) {
869     sscanf(q,"%d,%d,%d\n",&s1,&s2,&a);
870     irc_incidx(irc_histidx,sn);
871     ok=1;
872     sort1[sn]=s1;
873     sort2[sn]=s2;
874     alternate[sn]=a;
875     initscr(sn,1);
876   }
877   else if (irc_match("sc",&q)) {
878     irc_incidx(irc_histidx,sn);
879     ok=1;
880     di_schenken(sn);
881   }
882   else if (irc_match("cl",&q)) {
883     irc_incidx(irc_histidx,sn);
884     ok=1;
885     setsum(1);
886     save_list();
887   }
888   if (!ok && !fh) irc_addcmd(sn,idx,p);
889   return ok;
890 }
891 
irc_checkhist()892 VOID irc_checkhist()
893 {
894   int ok,sn,idx;
895 
896   do {
897     ok=0;
898     for (sn=0;sn<numsp;sn++) {
899       if (sn==irc_pos) continue;
900       if (irc_history[sn][idx=irc_histidx[sn]]) {
901 	if (irc_getcmd(sn,1,irc_history[sn][idx])) {
902 	  free(irc_history[sn][idx]);
903 	  irc_history[sn][idx]=0;
904 	  irc_histcnt[sn]--;
905 	  ok=1;
906 	}
907       }
908     }
909   } while (ok);
910 }
911 
irc_getrules(q)912 VOID irc_getrules(q)
913 char *q;
914 {
915   int aplayramsch,aplaysramsch,aplaykontra,aplaybock;
916   int aresumebock,aspitzezaehlt,arevolution,aklopfen;
917   int aschenken,abockevents,ageber,aalist,astrateg;
918   int aoldrules,arskatloser;
919 
920   sscanf(q,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
921 	 &aplayramsch,&aplaysramsch,&aplaykontra,&aplaybock,
922 	 &aresumebock,&aspitzezaehlt,&arevolution,&aklopfen,
923 	 &aschenken,&abockevents,&ageber,&aalist,&astrateg,
924 	 &aoldrules,&arskatloser);
925   irc_showrules(aplayramsch,aplaysramsch,aplaykontra,aplaybock,
926 		aresumebock,aspitzezaehlt,arevolution,aklopfen,
927 		aschenken,abockevents,ageber,aalist,astrateg,
928 		aoldrules,arskatloser);
929 }
930 
irc_getserverconf(q)931 VOID irc_getserverconf(q)
932 char *q;
933 {
934   static int i,f;
935   char plb[80];
936   int ln;
937 
938   if (irc_match("1 ",&q)) {
939     q=irc_copyname(irc_conf[i].nick,q);
940     q=irc_copyname(spnames[i][0][0],q);
941     q=irc_copyname(spnames[i][1][0],q);
942     for (ln=1;ln<NUM_LANG;ln++) {
943       strcpy(spnames[i][0][ln],spnames[i][0][0]);
944       strcpy(spnames[i][1][ln],spnames[i][1][0]);
945     }
946     if (!i) {
947       strcpy(usrname[0],spnames[0][0][0]);
948       strcpy(usrname[1],spnames[0][1][0]);
949     }
950     sscanf(q,"%d,%d,%d,%d,%d,%d\n",
951 	   &sort1[i],&alternate[i],&desk[i].large,&alist[i],
952 	   &nimmstich[i][0],&abkuerz[i]);
953     calc_desk(i);
954     if (!strcmp(irc_conf[i].nick,irc_nick)) {
955       irc_pos=i;
956       f=1;
957     }
958     else if (nimmstich[i][0]<101) {
959       nimmstich[i][0]=0;
960     }
961     numsp=++i;
962     irc_2player=numsp==2;
963   }
964   else if (f && irc_match("2 ",&q)) {
965     sscanf(q,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%ld,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
966 	   &playramsch,&playsramsch,&playkontra,&playbock,&resumebock,
967 	   &spitzezaehlt,&revolution,&klopfen,&schenken,
968 	   &bockevents,&geber,&alist[0],&strateg[0],&oldrules,&rskatloser,
969 	   &savseed,&bockspiele,&bockinc,&ramschspiele,
970 	   &sum[0][0],&sum[0][1],&sum[0][2],
971 	   &sum[1][0],&sum[1][1],&sum[1][2],
972 	   &sum[2][0],&sum[2][1],&sum[2][2],
973 	   &cgewoverl[0][0],&cgewoverl[1][0],&cgewoverl[2][0],
974 	   &cgewoverl[0][1],&cgewoverl[1][1],&cgewoverl[2][1]);
975     savseed-=11;
976     setrnd(&seed[0],savseed);
977     setsum(0);
978     if (!irc_2player) {
979       sprintf(plb,textarr[TX_VERBUNDEN_MIT_SPIELER_N].t[lang[0]],3);
980       irc_printnl(plb);
981     }
982     irc_state=IRC_PLAYING;
983   }
984   else i=0;
985 }
986 
irc_putserverconf()987 VOID irc_putserverconf()
988 {
989   char buf[1024];
990   int i;
991 
992   for (i=0;i<2+!irc_2player;i++) {
993     sprintf(buf,"notice %s :/svconf1 %s~%s~%s~%d,%d,%d,%d,%d,%d\n",
994 	    irc_channel,
995 	    irc_conf[i].nick,spnames[i][0][0],spnames[i][1][0],
996 	    irc_conf[i].sort1,irc_conf[i].alternate,irc_conf[i].large,
997 	    alist[0],irc_conf[i].nimmstich,irc_conf[i].abkuerz);
998     irc_out(buf);
999   }
1000   sprintf(buf,"notice %s :/svconf2 %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%ld,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
1001 	  irc_channel,
1002 	  playramsch,playsramsch,playkontra,playbock,resumebock,
1003 	  spitzezaehlt,revolution,klopfen,schenken,
1004 	  bockevents,geber,alist[0],strateg[0],oldrules,rskatloser,
1005 	  savseed+11,bockspiele,bockinc,ramschspiele,
1006 	  sum[0][0],sum[0][1],sum[0][2],
1007 	  sum[1][0],sum[1][1],sum[1][2],
1008 	  sum[2][0],sum[2][1],sum[2][2],
1009 	  cgewoverl[0][0],cgewoverl[1][0],cgewoverl[2][0],
1010 	  cgewoverl[0][1],cgewoverl[1][1],cgewoverl[2][1]);
1011   irc_out(buf);
1012   irc_state=IRC_PLAYING;
1013 }
1014 
irc_putclientconf()1015 VOID irc_putclientconf()
1016 {
1017   char buf[1024];
1018 
1019   sprintf(buf,"notice %s :/clconf %s~%s~%d,%d,%d,%d,%d,%d\n",
1020 	  irc_channel,
1021 	  spnames[0][0][0],spnames[0][1][0],
1022 	  sort1[0],alternate[0],desk[0].large,
1023 	  nimmstich[0][0],irc_pos,abkuerz[0]);
1024   irc_out(buf);
1025 }
1026 
irc_setpos()1027 VOID irc_setpos()
1028 {
1029   int i,j,p[3];
1030 
1031   for (i=0;i<3;i++) {
1032     p[i]=-1;
1033     for (j=0;j<numsp;j++) {
1034       if (irc_conf[j].pos==i) {
1035 	if (i==2 && numsp==2) {
1036 	  irc_conf[j].pos=-1;
1037 	}
1038 	else {
1039 	  p[i]=j++;
1040 	  for (;j<numsp;j++) {
1041 	    if (irc_conf[j].pos==i) irc_conf[j].pos=-1;
1042 	  }
1043 	}
1044       }
1045     }
1046   }
1047   for (i=j=0;i<3;i++) {
1048     if (p[i]==-1) {
1049       for (;j<numsp;j++) {
1050 	if (irc_conf[j].pos==-1) {
1051 	  irc_conf[j].pos=i;
1052 	  break;
1053 	}
1054       }
1055     }
1056   }
1057 }
1058 
irc_getclientconf(s,q)1059 VOID irc_getclientconf(s,q)
1060 char *s,*q;
1061 {
1062   int i,ln;
1063   char plb[80];
1064 
1065   i=irc_clients;
1066   strcpy(irc_conf[i].nick,s);
1067   q=irc_copyname(irc_conf[i].spnames[0],q);
1068   q=irc_copyname(irc_conf[i].spnames[1],q);
1069   sscanf(q,"%d,%d,%d,%d,%d,%d\n",
1070 	 &irc_conf[i].sort1,&irc_conf[i].alternate,
1071 	 &irc_conf[i].large,&irc_conf[i].nimmstich,
1072 	 &irc_conf[i].pos,&irc_conf[i].abkuerz);
1073   irc_clients=++i;
1074   sprintf(plb,textarr[TX_VERBUNDEN_MIT_SPIELER_N].t[lang[0]],i+1);
1075   irc_printnl(plb);
1076   if (!irc_2player && i<2) {
1077     sprintf(plb,textarr[TX_WARTEN_AUF_SPIELER_N].t[lang[0]],i+2);
1078     irc_printnl(plb);
1079   }
1080   if (i==1+!irc_2player) {
1081     numsp=i+1;
1082     irc_conf[i].pos=irc_pos;
1083     irc_setpos();
1084     irc_pos=irc_conf[i].pos;
1085     for (i=2;i>=0;i--) {
1086       if (irc_conf[0].pos==i) irc_conf[i]=irc_conf[0];
1087       else if (!irc_2player && irc_conf[1].pos==i) irc_conf[i]=irc_conf[1];
1088     }
1089     i=irc_pos;
1090     strcpy(irc_conf[i].nick,irc_nick);
1091     irc_conf[i].sort1=sort1[0];
1092     irc_conf[i].alternate=alternate[0];
1093     irc_conf[i].large=desk[0].large;
1094     irc_conf[i].nimmstich=nimmstich[0][0];
1095     irc_conf[i].abkuerz=abkuerz[0];
1096     strcpy(irc_conf[i].spnames[0],spnames[0][0][0]);
1097     strcpy(irc_conf[i].spnames[1],spnames[0][1][0]);
1098     for (i=0;i<numsp;i++) {
1099       sort1[i]=irc_conf[i].sort1;
1100       alternate[i]=irc_conf[i].alternate;
1101       desk[i].large=irc_conf[i].large;
1102       alist[i]=alist[0];
1103       nimmstich[i][0]=i!=irc_pos && irc_conf[i].nimmstich<101
1104 	?0:irc_conf[i].nimmstich;
1105       abkuerz[i]=irc_conf[i].abkuerz;
1106       for (ln=0;ln<NUM_LANG;ln++) {
1107 	strcpy(spnames[i][0][ln],irc_conf[i].spnames[0]);
1108 	strcpy(spnames[i][1][ln],irc_conf[i].spnames[1]);
1109       }
1110       calc_desk(i);
1111     }
1112     irc_putserverconf();
1113   }
1114 }
1115 
irc_changenick(send)1116 VOID irc_changenick(send)
1117 int send;
1118 {
1119   static char nick[IRC_NICK_LEN+1];
1120   static long rseed;
1121   static int ini;
1122 
1123   if (!ini) {
1124     rseed=seed[0];
1125     ini=1;
1126   }
1127   sprintf(nick,"xskat%04d",rndval(&rseed,8191));
1128   if (send) irc_sendnick(nick);
1129   if (!send || irc_state==IRC_OFFLINE) irc_nick=nick;
1130 }
1131 
irc_checknick()1132 VOID irc_checknick()
1133 {
1134   if (!strlen(irc_nick)) {
1135     irc_changenick(0);
1136   }
1137 }
1138 
irc_nickchanged(oldnick,newnick)1139 VOID irc_nickchanged(oldnick,newnick)
1140 char *oldnick,*newnick;
1141 {
1142   static char nick[IRC_NICK_LEN+1];
1143   int i;
1144 
1145   if (*newnick==':') newnick++;
1146   if (!strcmp(oldnick,irc_nick)) {
1147     strncpy(nick,newnick,IRC_NICK_LEN);
1148     nick[IRC_NICK_LEN]=0;
1149     irc_nick=nick;
1150   }
1151   if (irc_state==IRC_PLAYING) {
1152     for (i=0;i<numsp;i++) {
1153       if (!strcmp(oldnick,irc_conf[i].nick)) {
1154 	strncpy(irc_conf[i].nick,newnick,IRC_NICK_LEN);
1155 	irc_conf[i].nick[IRC_NICK_LEN]=0;
1156       }
1157     }
1158   }
1159 }
1160 
irc_msg(nick,q)1161 VOID irc_msg(nick,q)
1162 char *nick,*q;
1163 {
1164   int i,sn;
1165   char nam[20];
1166 
1167   irc_alarm();
1168   if (irc_inplen) {
1169     for (i=0;i<irc_inplen;i++) {
1170       irc_print("\b \b");
1171     }
1172   }
1173   irc_print("<");
1174   irc_print(nick);
1175   if (irc_state==IRC_PLAYING && (sn=irc_senderok(nick))) {
1176     prspnam(nam,sn-1,lang[sn-1]);
1177     if (strcmp(nick,nam)) {
1178       irc_print("/");
1179       irc_print(nam);
1180     }
1181   }
1182   irc_print("> ");
1183   irc_printnl(q);
1184   if (irc_inplen) {
1185     irc_inpbuf[irc_inplen]=0;
1186     irc_print(irc_inpbuf);
1187   }
1188 }
1189 
irc_parse(s)1190 VOID irc_parse(s)
1191 char *s;
1192 {
1193   char *p,*q,nick[IRC_NICK_LEN+1];
1194   char plb[80];
1195   int i,sn,nickerr,colon;
1196   static int ini;
1197   static char mynick[IRC_NICK_LEN+1];
1198 
1199   nickerr=0;
1200   colon=*s==':';
1201   if (colon) {
1202     s++;
1203     strncpy(nick,s,IRC_NICK_LEN);
1204     nick[IRC_NICK_LEN]=0;
1205     for (i=0,p=s;i<IRC_NICK_LEN && *p && *p!=' ' && *p!='!';i++,p++);
1206     nick[*p=='!'?p++-s:0]=0;
1207     p=strchr(p,' ');
1208     if (p) {
1209       p++;
1210       if ((q=strchr(p,' ')) &&
1211 	  (q=strchr(q+1,' ')) &&
1212 	  (q=strchr(q+1,':'))) q++;
1213       if (q && irc_match("NOTICE",&p)) {
1214 	if (irc_match("/server ",&q)) {
1215 	  if (irc_state==IRC_SERVER) {
1216 	    irc_printnl(textarr[TX_NUR_EINER_SOLLTE_GO_SAGEN].t[lang[0]]);
1217 	    irc_out("notice ");
1218 	    irc_out(irc_channel);
1219 	    irc_out(" :/noserver\n");
1220 	    irc_state=IRC_TALK;
1221 	  }
1222 	  else if (irc_state==IRC_TALK) {
1223 	    irc_out("notice ");
1224 	    irc_out(irc_channel);
1225 	    irc_out(" :/client ");
1226 	    irc_out(textarr[TX_XSKAT].t[lang[0]]);
1227 	    irc_out("\n");
1228 	    if (!irc_match(textarr[TX_XSKAT].t[lang[0]],&q)) {
1229 	      irc_pr_ss(textarr[TX_VERSCHIEDENE_VERSIONEN].t[lang[0]],q);
1230 	    }
1231 	    else {
1232 	      sprintf(plb,textarr[TX_VERBUNDEN_MIT_SPIELER_N].t[lang[0]],2);
1233 	      irc_printnl(plb);
1234 	      irc_putclientconf();
1235 	    }
1236 	  }
1237 	}
1238 	else if (irc_match("/noserver",&q)) {
1239 	  if (irc_state==IRC_SERVER) {
1240 	    irc_printnl(textarr[TX_NUR_EINER_SOLLTE_GO_SAGEN].t[lang[0]]);
1241 	    irc_state=IRC_TALK;
1242 	  }
1243 	}
1244 	else if (irc_match("/client ",&q)) {
1245 	  if (irc_state==IRC_SERVER) {
1246 	    if (!irc_match(textarr[TX_XSKAT].t[lang[0]],&q)) {
1247 	      irc_pr_ss(textarr[TX_VERSCHIEDENE_VERSIONEN].t[lang[0]],q);
1248 	      irc_state=IRC_TALK;
1249 	    }
1250 	  }
1251 	}
1252 	else if (irc_match("/clconf ",&q)) {
1253 	  if (irc_state==IRC_SERVER) {
1254 	    irc_getclientconf(nick,q);
1255 	  }
1256 	}
1257 	else if (irc_match("/svconf",&q)) {
1258 	  if (irc_state==IRC_TALK || irc_state==IRC_SERVER) {
1259 	    irc_state=IRC_TALK;
1260 	    irc_getserverconf(q);
1261 	  }
1262 	}
1263 	else if (irc_match("/cmd",&q)) {
1264 	  irc_tick=ticker;
1265 	  if (irc_state==IRC_PLAYING && (sn=irc_senderok(nick))) {
1266 	    irc_getcmd(sn-1,0,q);
1267 	  }
1268 	}
1269 	else if (irc_match("/sync",&q)) {
1270 	  if (irc_state==IRC_PLAYING && irc_senderok(nick)) {
1271 	    if (!irc_match("ed",&q)) {
1272 	      irc_sendsync(0);
1273 	    }
1274 	    irc_sync(q);
1275 	  }
1276 	}
1277 	else if (irc_match("/rules",&q)) {
1278 	  if (irc_state==IRC_TALK) {
1279 	    irc_print("<");
1280 	    irc_print(nick);
1281 	    irc_printnl(">");
1282 	    irc_getrules(q);
1283 	  }
1284 	}
1285 	else {
1286 	  irc_msg(nick,q);
1287 	}
1288       }
1289       else if (q && irc_match("PRIVMSG",&p)) {
1290 	irc_msg(nick,q);
1291       }
1292       else if (irc_match("JOIN",&p)) {
1293 	if (!strncmp(irc_nick,nick,9) && !ini) {
1294 	  strcpy(mynick,nick);
1295 	  irc_nick=mynick;
1296 	  irc_out("mode ");
1297 	  irc_out(irc_nick);
1298 	  irc_out(" +i\n");
1299 	  for (i=TX_IRC_INTRO1;i<=TX_IRC_INTROX;i++) {
1300 	    irc_printnl(textarr[i].t[lang[0]]);
1301 	  }
1302 	  ini=1;
1303 	}
1304 	else {
1305 	  irc_alarm();
1306 	  irc_printnl(s);
1307 	}
1308       }
1309       else if (irc_match("NICK ",&p)) {
1310 	irc_printnl(s);
1311 	irc_nickchanged(nick,p);
1312       }
1313       else if (irc_match("QUIT",&p)) {
1314 	if (irc_state==IRC_PLAYING && (sn=irc_senderok(nick)) &&
1315 	    !lost[0] && !lost[1] && !lost[2]) {
1316 	  lost[sn-1]=1;
1317 	  finish(sn-1,0);
1318 	}
1319       }
1320       else if (irc_match("432",&p) || irc_match("433",&p)) {
1321 	nickerr=1;
1322 	irc_printnl(s);
1323 	if (irc_state==IRC_OFFLINE) irc_changenick(1);
1324       }
1325       else if (irc_match("322",&p)) {
1326 	if ((p=strchr(p+1,' ')) &&
1327 	    (!irc_substr[0] ||
1328 	     strstr(p,irc_substr))) {
1329 	  p++;
1330 	  if (*p==':') p++;
1331 	  irc_printnl(p);
1332 	  irc_log(s-1,1);
1333 	  irc_log("\n",1);
1334 	}
1335       }
1336       else if (*p>='0' && *p<='9') {
1337 	if ((p=strchr(p,' ')) &&
1338 	    (p=strchr(p+1,' '))) {
1339 	  p++;
1340 	  if (*p==':') p++;
1341 	  irc_printnl(p);
1342 	}
1343       }
1344       else {
1345 	irc_printnl(s);
1346       }
1347     }
1348     else {
1349       irc_printnl(s);
1350     }
1351   }
1352   else if (irc_match("PING",&s)) {
1353     p=strchr(s,':');
1354     if (p) {
1355       irc_out("PONG ");
1356       irc_out(p+1);
1357       irc_out("\n");
1358     }
1359   }
1360   else if (p=s,irc_match("Connection closed",&s)) {
1361     irc_printnl(p);
1362     exitus(1);
1363   }
1364   else {
1365     irc_printnl(s);
1366   }
1367   if (irc_state==IRC_OFFLINE && colon && !nickerr) {
1368     irc_out("join ");
1369     irc_out(irc_channel);
1370     irc_out("\n");
1371     irc_state=IRC_TALK;
1372   }
1373 }
1374 
irc_connect()1375 VOID irc_connect()
1376 {
1377   int pipe1fd[2];
1378   int pipe2fd[2];
1379   char buf[20];
1380 
1381 #ifdef SIGTSTP
1382   signal(SIGTSTP,SIG_IGN);
1383 #endif
1384   pipe(pipe1fd);
1385   pipe(pipe2fd);
1386   if (fcntl(pipe1fd[0],F_SETFL,
1387 	    fcntl(pipe1fd[0],F_GETFL)|O_NONBLOCK)<0) {
1388     fprintf(stderr,"Fcntl pipe failed\n");
1389     exitus(1);
1390   }
1391   if ((irc_telnetpid=fork())<0) {
1392     fprintf(stderr,"Fork failed\n");
1393     exitus(1);
1394   }
1395   if (!irc_telnetpid) {
1396     if (dup2(pipe2fd[0],fileno(stdin))<0 ||
1397 	dup2(pipe1fd[1],fileno(stdout))<0 ||
1398 	dup2(fileno(stdout),fileno(stderr))<0) {
1399       fprintf(stderr,"Dup failed\n");
1400       exitus(1);
1401     }
1402     close(pipe1fd[0]);
1403     close(pipe1fd[1]);
1404     close(pipe2fd[0]);
1405     close(pipe2fd[1]);
1406     sprintf(buf,"%d",irc_port);
1407     execlp(irc_telnet,irc_telnet,irc_hostname,buf,NULL);
1408     fprintf(stderr,"Exec '%s' failed\n",irc_telnet);
1409     exitus(1);
1410   }
1411   close(pipe1fd[1]);
1412   close(pipe2fd[0]);
1413   irc_i=pipe1fd[0];
1414   irc_o=pipe2fd[1];
1415 }
1416 
irc_init()1417 VOID irc_init()
1418 {
1419   char *l;
1420 
1421   irc_state=IRC_OFFLINE;
1422   xinitplayers();
1423   irc_connect();
1424   irc_checknick();
1425   irc_print("*** ");
1426   irc_print(textarr[TX_XSKAT].t[lang[0]]);
1427   irc_printnl(" ***");
1428   irc_printnl(textarr[TX_README_IRC].t[lang[0]]);
1429   irc_print("Login ");
1430   irc_print(irc_user);
1431   irc_print(",");
1432   irc_print(irc_nick);
1433   irc_print(",");
1434   irc_printnl(irc_realname);
1435   irc_out("user ");
1436   irc_out(irc_user);
1437   irc_out(" xskat xskat :");
1438   irc_out(irc_realname);
1439   irc_out("\n");
1440   irc_sendnick(irc_nick);
1441   for (;;) {
1442     while ((l=irc_getline())) {
1443       irc_parse(l);
1444       if (irc_state==IRC_PLAYING) {
1445 	irc_tick=ticker;
1446 	return;
1447       }
1448     }
1449     irc_talk((char *)0);
1450     waitt(100,0);
1451   }
1452 }
1453