Next Previous Contents

12.第四个例子:Hearts

这是以个很久以前的老游戏, 是 Bob Ankeney 在 80 年代的时候为 UNIX 写的, Mike Yang 在 1992 年修正过。现在是 Jonathan Badger 在维护它。它最初是美国俄勒冈州软件的 Don Backus 用更古老的 Pascal 程序写的,最后是 Jeff Hemmerling 更新。最初作为多个玩家客户端一起参加,也可以作为单打模式和电脑对抗。它的画面非常精美,虽然这个游戏缺乏诡辩难度的特点,而且电脑玩家不是很厉害。 所有上述的,它似乎是过去 UNIX 和 Linux 机器一个古来、正规的游戏。


由于它的年龄和血统,这一个包特别地难以在一个 Linux 系统上构建。 它需要解决一个很长的一系列复杂的难题。它是耐心和决心的一种锻炼。

开始之前确定某个已经安装了必须的图形库

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

这个原因在 client.c 文件:

#ifndef SYSV
        (buf[2] != _tty.sg_erase) && (buf[2] != _tty.sg_kill)) {
 #else
        (buf[2] != CERASE) && (buf[2] != CKILL)) {
#endif

在 client.c ,增加

#define SYSV
在 39 行,是通过上述提到的 _tty.

make

client.c:41: sys/termio.h: No such file or directory
make: *** [client.o] Error 1

这个 include 文件 termio.h 在一个 Linux 系统的 /usr/include 目录。 应当在 /usr/include/sys 更适合,这个案例是一个很老的 UNIX 机器。因此修改 client.c 的 41 行

#include <sys/termio.h>
修改为
#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

现流行的 Linux 发行版使用 terminfo 和/或 termcap 数据库,比这个 termlib 更适合:

编辑 Makefile.

第 655 行:

CURSES_LIBRARIES = -lcurses -ltermlib

修改为

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
主要缺少
lesstif 函数库是libXm ,相当于 libXm_s 。因此编辑 Makefile

在 653 行:

XMLIB = -lXm_s $(XTOOLLIB) $(XLIB) -lPW
修改为
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

这个通常是不可信的.

这儿没有 PW 库文件。编辑 Makefile

第 653 行::

XMLIB = -lXm $(XTOOLLIB) $(XLIB) -lPW

修改为:

XMLIB = -lXm $(XTOOLLIB) $(XLIB) -lPEX5
(PEX5 库受到的影响最接近到 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       

最终运转正常 (万岁!)

安装:

切换为 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

测试运行:

rehash

(我们运行的是 tcsh shell.)

xmhearts

localhost:~/% xmhearts
Can't invoke distributor!

从源码包里阅读 README 文件:

     Put heartsd, hearts_dist, and hearts.instr in the HEARTSLIB
     directory defined in local.h and make them world-accessible.

在 local.h 文件的内容如下:

/* where the distributor, dealer and instructions live */

#define HEARTSLIB "/usr/local/lib/hearts"
这是
RTFM 的一流案例:

切换成 root

cd /usr/local/lib

mkdir hearts

cd !$

拷贝目标文件到这个目录

cp /home/username/hearts/heartsd .

cp /home/username/hearts/hearts_dist .

cp /home/username/hearts/hearts.instr .

用其他用户测试运行

xmhearts

它运转了一些时间,但大部分时候没有出现失败的消息。

这个"distributor" 和 "dealer" 扫描硬件端口,我们应该因此猜想那些程序需要 root 特权。

尝试一下,切换到 root

chmod u+s /usr/local/lib/heartsd

chmod u+s /usr/local/lib/hearts_dist

(注意这里,象先前的讨论,suid 二进制可能会导致安全漏洞。)

xmhearts

它最终工作正常!

HeartsSunsite 可以下载得到。


Next Previous Contents