Ecco il vecchio canuto gioco Hearts, scritto per i sistemi UNIX da Bob Ankeney negli anni '80, rivisto nel 1992 da Mike Yang, ed attualmente mantenuto da Jonathan Badger. Il suo predecessore era un ancor più vecchio programma Pascal di Don Backus della Oregon Software, poi aggiornato da Jeff Hemmerling. Originariamente pensato come client per più giocatori, funziona bene anche per un solo giocatore contro avversari gestiti dal computer. La grafica è bella, benché il gioco manchi di caratteristiche più sofisticate e i giocatori computerizzati non siano molto forti. Nonostante tutto, sembra essere il solo Hearts decente disponibile per macchine UNIX e Linux ancora oggi.
A causa della sua stirpe ed età, questo pacchetto è particolarmente difficile da compilare su di un sistema Linux. Richiede la soluzione di una lunga e sconcertante serie di puzzle. È un esercizio di pazienza e determinazione.
Prima di iniziare, accertatevi di avere le librerie motif
o
le lesstif
installate.
xmkmf
make
client.c: In function `read_card':
client.c:430: `_tty' undeclared (first use in this function)
client.c:430: (Each undeclared identifier is reported only once
client.c:430: for each function it appears in.)
client.c: In function `scan':
client.c:685: `_tty' undeclared (first use in this function)
make: *** [client.o] Error 1
Questi sono i colpevoli nel file client.c
:
#ifndef SYSV
(buf[2] != _tty.sg_erase) && (buf[2] != _tty.sg_kill)) {
#else
(buf[2] != CERASE) && (buf[2] != CKILL)) {
#endif
client.c
, aggiungiamo
#define SYSV
alla linea 39. Ciò bypasserà il riferimento a _tty.
make
client.c:41: sys/termio.h: No such file or directory
make: *** [client.o] Error 1
Il file include termio.h
è nella directory /usr/include
su di un sistema Linux, invece che nella /usr/include/sys
,
come era sulle vecchie macchine UNIX. Perciò, cambiamo la linea 41 di
client.c
da
#include <sys/termio.h>
a
#include <termio.h>
make
gcc -o hearts -g -L/usr/X11R6/lib client.o hearts.o select.o connect.o
sockio.o start_dist.o -lcurses -ltermlib
/usr/bin/ld: cannot open -ltermlib: No such file or directory
collect2: ld returned 1 exit status
make: *** [hearts] Error 1
Le moderne distribuzioni Linux usano il database terminfo e/o termcap, piuttosto che l'obsoleto termlib.
Editiamo il Makefile
.
Linea 655:
CURSES_LIBRARIES = -lcurses -ltermlib
cambiamola in:
CURSES_LIBRARIES = -lcurses -ltermcap
make
gcc -o xmhearts -g -L/usr/X11R6/lib xmclient.o hearts.o select.o
connect.o sockio.o start_dist.o gfx.o -lXm_s -lXt -lSM -lICE -lXext -lX11
-lPW
/usr/bin/ld: cannot open -lXm_s: No such file or directory
collect2: ld returned 1 exit status
La principale libreria lesstif è libXm
,
piuttosto che libXm_s
. Quindi, editiamo il Makefile
.
Nella linea 653:
XMLIB = -lXm_s $(XTOOLLIB) $(XLIB) -lPW
cambia in:
XMLIB = -lXm $(XTOOLLIB) $(XLIB) -lPW
make
gcc -o xmhearts -g -L/usr/X11R6/lib xmclient.o hearts.o select.o
connect.o sockio.o start_dist.o gfx.o -lXm -lXt -lSM -lICE -lXext -lX11 -lPW
/usr/bin/ld: cannot open -lPW: No such file or directory
collect2: ld returned 1 exit status
make: *** [xmhearts] Error 1
Raduniamo i soliti sospetti.
Non c'è nessuna libreria PW
. Editiamo il Makefile
.
Linea 653:
XMLIB = -lXm $(XTOOLLIB) $(XLIB) -lPW
cambia in:
XMLIB = -lXm $(XTOOLLIB) $(XLIB) -lPEX5
(La libreria PEX5
è quella più simile alla PW
.)
make
rm -f xmhearts
gcc -o xmhearts -g -L/usr/X11R6/lib xmclient.o hearts.o select.o
connect.o sockio.o start_dist.o gfx.o -lXm -lXt -lSM -lICE -lXext -lX11 -lPEX5
Il make
finalmente funziona (hurra!)
Installazione:
Come root,
[root@localhost hearts]# make install
install -c -s hearts /usr/X11R6/bin/hearts
install -c -s xmhearts /usr/X11R6/bin/xmhearts
install -c -s xawhearts /usr/X11R6/bin/xawhearts
install in . done
Esecuzione di prova:
rehash
(Stiamo eseguendo la shell tcsh
.)
xmhearts
localhost:~/% xmhearts
Can't invoke distributor!
Dal file README
nel pacchetto hearts
:
Put heartsd, hearts_dist, and hearts.instr in the HEARTSLIB
directory defined in local.h and make them world-accessible.
(Traducendo: Mettete Heartsd, hearts_dist, e hearts.instr nella
directory HEARTSLIB definita in local.h e rendeteli accessibili
a chiunque)
Dal file local.h
:
/* where the distributor, dealer and instructions live */
#define HEARTSLIB "/usr/local/lib/hearts"
Questo è un classico caso: RTFM (leggete il fottuto manuale).
Come root,
cd /usr/local/lib
mkdir hearts
cd !$
Copiamo i file di distributor
in questa directory.
cp /home/username/hearts/heartsd .
cp /home/username/hearts/hearts_dist .
cp /home/username/hearts/hearts.instr .
Lanciamo un'altra esecuzione di prova.
xmhearts
Qualche volta funziona, ma il più delle volte si pianta con un
messaggio dealer died!
.
Il "distributor" e il "dealer" esaminano le porte hardware. Dovremmo perciò sospettare che quei programmi abbiano bisogno dei privilegi di root.
Proviamo, come root,
chmod u+s /usr/local/lib/heartsd
chmod u+s /usr/local/lib/hearts_dist
(Osserviamo che, come discusso precedentemente, i binari suid possono creare dei buchi di sicurezza.)
xmhearts
Alla fine funziona!
Hearts è disponibile da
Sunsite.