summaryrefslogtreecommitdiff
path: root/community/bsd-games
diff options
context:
space:
mode:
authorroot <root@rshg054.dnsready.net>2013-07-19 01:10:32 -0700
committerroot <root@rshg054.dnsready.net>2013-07-19 01:10:32 -0700
commit8fbc0076a4827ddc6af92e0b9daa4c4c31450808 (patch)
tree03fd0e2921ebd53228d9a93e32ed3976b636cbea /community/bsd-games
parente445a313723389ba9ee1fded025c567dae5b21ea (diff)
Fri Jul 19 01:09:18 PDT 2013
Diffstat (limited to 'community/bsd-games')
-rw-r--r--community/bsd-games/PKGBUILD104
-rw-r--r--community/bsd-games/bad-ntohl-cast.diff22
-rw-r--r--community/bsd-games/bsd-games-2.17-64bit.patch43
-rw-r--r--community/bsd-games/bsd-games.install11
-rw-r--r--community/bsd-games/config.params15
-rw-r--r--community/bsd-games/gamescreen.h.diff15
-rw-r--r--community/bsd-games/getline.diff194
-rw-r--r--community/bsd-games/null-check.diff24
-rw-r--r--community/bsd-games/number.c.diff156
-rw-r--r--community/bsd-games/stdio.h.diff14
10 files changed, 598 insertions, 0 deletions
diff --git a/community/bsd-games/PKGBUILD b/community/bsd-games/PKGBUILD
new file mode 100644
index 000000000..1b4ac12da
--- /dev/null
+++ b/community/bsd-games/PKGBUILD
@@ -0,0 +1,104 @@
+# $Id: PKGBUILD 90951 2013-05-16 09:13:23Z lcarlier $
+# Maintainer: Chris Brannon <cmbrannon79@gmail.com>
+# Contributor: Abhishek Dasgupta <abhidg@gmail.com>
+# Contributor: SmackleFunky <smacklefunky@optusnet.com.au>
+
+pkgname=bsd-games
+pkgver=2.17
+pkgrel=14
+pkgdesc="A linux port for a collection of BSD command line games."
+url="ftp://ftp.ibiblio.org/pub/Linux/games/"
+arch=('i686' 'x86_64')
+install=$pkgname.install
+license=('BSD')
+depends=(gcc-libs words sh)
+makedepends=('flex' 'bison' 'm4')
+source=(ftp://ftp.ibiblio.org/pub/Linux/games/$pkgname-$pkgver.tar.gz
+ config.params stdio.h.diff gamescreen.h.diff getline.diff
+ number.c.diff bsd-games-2.17-64bit.patch
+ bad-ntohl-cast.diff null-check.diff)
+md5sums=('238a38a3a017ca9b216fc42bde405639'
+ '2ea80281ee9993a9ee47323e78349a2a'
+ '784f68c796b9e099ac008aecef1af998'
+ '9c0fa6e2345bd0a7945c9a41d5ba68aa'
+ '5356bd6999ae53dd27cb2a0f837a3e70'
+ '47249a90f38ccb4dd07625b245bbc728'
+ '257813b76a41c8b2c02701571c804227'
+ '3d21a9dad2e603ddf3842972e4ff85a1'
+ 'a43ca0b4b9ebc4eec26372c52014ac0a')
+
+prepare() {
+ cd "${srcdir}/$pkgname-$pkgver"
+
+ [ "$CARCH" = "x86_64" ] && patch -p1 < "$srcdir/bsd-games-2.17-64bit.patch"
+ cp "${srcdir}/config.params" .
+
+ # Several games use their own internal functions named getline. All
+ # are different, and none is the getline from glibc. So we need a patch
+ # in order to compile. Each internal getline function is prefixed
+ # with the name of the game. -- Chris Brannon
+ patch -p1 -i "${srcdir}/getline.diff"
+
+ patch -p1 -i "${srcdir}/stdio.h.diff"
+ patch -p1 -i "${srcdir}/gamescreen.h.diff"
+
+# Incorporated some fixes from Debian
+ patch -p1 -i "${srcdir}/number.c.diff"
+# ntohl returns uint32_t, not unsigned long:
+ patch -p1 -i "${srcdir}/bad-ntohl-cast.diff"
+# And add a NULL pointer check to the "hunt" program, fixing a segfault.
+ patch -p1 -i "${srcdir}/null-check.diff"
+
+ sed -i "s/FISH/GO-FISH/g; s/\.Nm fish/\.Nm go-fish/g" fish/fish.6
+ sed -i "s/tenths/tenth/g" tests/number.-0.1
+ sed -i "s/Elegy{ Written in a Country Church{-| }Yard:/Elegy{ Written in a Country Church{-| }Yard}:/g" \
+ quiz/datfiles/poetry
+ sed -i "s/\.tI friend/\.It friend/g" hunt/hunt/hunt.6.in
+ sed -i "s/it\'s initial/its initial/g" backgammon/teachgammon/ttext1.c
+ sed -i "s/two player\'s/two players/g" backgammon/teachgammon/ttext2.c
+ sed -i "s/\.I range/\.It range/g" arithmetic/arithmetic.6
+ sed -i "s/game were the/game where the/g" gomoku/gomoku.6
+
+ # The wargames script expects binaries in /usr/games, and this
+ # path is hard-coded.
+ # Prior to release 2.17-10 of the ArchLinux package, wargames was
+ # broken, since binaries are in /usr/bin instead.
+ sed -i -e 's|/usr/games|/usr/bin|g' wargames/wargames
+}
+
+build() {
+ cd "${srcdir}/$pkgname-$pkgver"
+
+ ./configure
+ make
+}
+
+package() {
+ cd "${srcdir}/$pkgname-$pkgver"
+ sed -i "s%PKGDIR%$pkgdir%g" hide-game install-man install-score Makeconfig subst.sed
+ make install
+ # This make install command does install to $pkgdir, because of the
+ # change to config.params in the build function.
+
+# Fix permissions
+ rmdir "${pkgdir}/tmp"
+ install -dm755 "${pkgdir}/usr/share/bsdgames/data/hack/save"
+ chown -R root:games "${pkgdir}/var/lib/bsdgames"
+ chmod 664 "${pkgdir}"/var/lib/bsdgames/*
+ chmod 664 "${pkgdir}"/var/lib/bsdgames/{hack,phantasia}/*
+ chmod 775 "${pkgdir}"/var/lib/bsdgames/{hack,phantasia}
+
+# Remove conflict with xscreensaver and fish
+ mv "${pkgdir}/usr/bin/fish" "${pkgdir}/usr/bin/go-fish"
+ mv "${pkgdir}/usr/share/man/man6/fish.6.gz" "${pkgdir}/usr/share/man/man6/go-fish.6.gz"
+ mv "${pkgdir}/usr/share/man/man6/worm.6.gz" \
+ "${pkgdir}/usr/share/man/man6/worm-game.6.gz"
+
+# Install documentation and license
+ install -dm755 "$pkgdir/usr/share/doc/bsd-games"
+ install -m644 AUTHORS NEWS BUGS ChangeLog "$pkgdir/usr/share/doc/$pkgname" \
+
+ rm "${pkgdir}/usr/share/doc/trek.me"
+ install -D -m644 COPYING "${pkgdir}/usr/share/licenses/$pkgname/COPYING"
+}
+
diff --git a/community/bsd-games/bad-ntohl-cast.diff b/community/bsd-games/bad-ntohl-cast.diff
new file mode 100644
index 000000000..f783813e9
--- /dev/null
+++ b/community/bsd-games/bad-ntohl-cast.diff
@@ -0,0 +1,22 @@
+diff --git a/hunt/hunt/playit.c b/hunt/hunt/playit.c
+index 9acf86e..881a4e7 100644
+--- a/hunt/hunt/playit.c
++++ b/hunt/hunt/playit.c
+@@ -114,7 +114,7 @@ playit()
+ bad_con();
+ /* NOTREACHED */
+ }
+- if (ntohl(version) != (unsigned long)HUNT_VERSION) {
++ if (ntohl(version) != (uint32_t)HUNT_VERSION) {
+ bad_ver();
+ /* NOTREACHED */
+ }
+@@ -649,7 +649,7 @@ do_message()
+ bad_con();
+ /* NOTREACHED */
+ }
+- if (ntohl(version) != (unsigned long)HUNT_VERSION) {
++ if (ntohl(version) != (uint32_t)HUNT_VERSION) {
+ bad_ver();
+ /* NOTREACHED */
+ }
diff --git a/community/bsd-games/bsd-games-2.17-64bit.patch b/community/bsd-games/bsd-games-2.17-64bit.patch
new file mode 100644
index 000000000..a56ea8454
--- /dev/null
+++ b/community/bsd-games/bsd-games-2.17-64bit.patch
@@ -0,0 +1,43 @@
+David Leverton writes about adventure/crc.c:
+
+The 'adventure' game from the games-misc/bsd-games-2.13 package crashes
+when saving the game on AMD64 (and probably other 64-bit systems, but I
+haven't checked). Find attached to fix this.
+
+http://bugs.gentoo.org/show_bug.cgi?id=77032
+
+
+About utmpentry.c:
+
+the utmpx structure defines the ut_tv member a little differently on
+64bit hosts so that a 32bit and 64bit structure can be shared. So the
+ut_tv is a custom 32bit structure rather than the native 64bit timeval
+structure. Work around is to assign the submembers instead.
+
+http://bugs.gentoo.org/show_bug.cgi?id=102667
+
+--- bsd-games/adventure/crc.c
++++ bsd-games/adventure/crc.c
+@@ -134,7 +134,8 @@
+ if (step >= sizeof(crctab) / sizeof(crctab[0]))
+ step = 0;
+ }
+- crcval = (crcval << 8) ^ crctab[i];
++ /* Mask to 32 bits. */
++ crcval = ((crcval << 8) ^ crctab[i]) & 0xffffffff;
+ }
+- return crcval & 0xffffffff; /* Mask to 32 bits. */
++ return crcval;
+ }
+--- bsd-games/dm/utmpentry.c
++++ bsd-games/dm/utmpentry.c
+@@ -291,7 +291,8 @@
+ e->line[sizeof(e->line) - 1] = '\0';
+ (void)strncpy(e->host, up->ut_host, sizeof(up->ut_host));
+ e->name[sizeof(e->host) - 1] = '\0';
+- e->tv = up->ut_tv;
++ e->tv.tv_sec = up->ut_tv.tv_sec;
++ e->tv.tv_usec = up->ut_tv.tv_usec;
+ adjust_size(e);
+ }
+ #endif
diff --git a/community/bsd-games/bsd-games.install b/community/bsd-games/bsd-games.install
new file mode 100644
index 000000000..453a6ded7
--- /dev/null
+++ b/community/bsd-games/bsd-games.install
@@ -0,0 +1,11 @@
+MSG="You need to be in the games group to use the score files."
+
+post_install() {
+ echo $MSG
+}
+
+post_upgrade() {
+ if [ $(vercmp 2.17-8 $2) -ge 0 ]; then
+ echo $MSG
+ fi
+}
diff --git a/community/bsd-games/config.params b/community/bsd-games/config.params
new file mode 100644
index 000000000..f061d8f26
--- /dev/null
+++ b/community/bsd-games/config.params
@@ -0,0 +1,15 @@
+bsd_games_cfg_non_interactive=y
+bsd_games_cfg_install_prefix=PKGDIR
+bsd_games_cfg_no_build_dirs='banner fortune wtf factor monop'
+bsd_games_cfg_gamesdir=/usr/bin
+bsd_games_cfg_sbindir=/usr/bin
+bsd_games_cfg_man6dir=/usr/share/man/man6
+bsd_games_cfg_man5dir=/usr/share/man/man5
+bsd_games_cfg_man8dir=/usr/share/man/man8
+bsd_games_cfg_docdir=/usr/share/doc
+bsd_games_cfg_sharedir=/usr/share/bsdgames
+bsd_games_cfg_varlibdir=/var/lib/bsdgames
+bsd_games_cfg_do_chown=n
+bsd_games_cfg_sail_dir=/tmp
+bsd_games_cfg_sail_dir_perms=0777
+bsd_games_cfg_hack_dir_perms=0777
diff --git a/community/bsd-games/gamescreen.h.diff b/community/bsd-games/gamescreen.h.diff
new file mode 100644
index 000000000..f74ebcb4b
--- /dev/null
+++ b/community/bsd-games/gamescreen.h.diff
@@ -0,0 +1,15 @@
+--- a/dab/gamescreen.h 2004-01-02 23:34:51.000000000 +0530
++++ b/dab/gamescreen.h 2008-07-31 23:45:19.000000000 +0530
+@@ -70,9 +70,9 @@
+ virtual void redraw(void) = 0; // Refresh
+ virtual int getinput(void) = 0; // Get user input
+ virtual void bell(void) = 0; // Beep
+- virtual void score(size_t p, const PLAYER& p) = 0; // Post current score
+- virtual void games(size_t p, const PLAYER& p) = 0; // Post games won
+- virtual void total(size_t p, const PLAYER& p) = 0; // Post total score
++ virtual void score(size_t, const PLAYER&) = 0; // Post current score
++ virtual void games(size_t, const PLAYER&) = 0; // Post games won
++ virtual void total(size_t, const PLAYER&) = 0; // Post total score
+ virtual void ties(const PLAYER& p) = 0; // Post tie games
+ };
+
diff --git a/community/bsd-games/getline.diff b/community/bsd-games/getline.diff
new file mode 100644
index 000000000..99a663847
--- /dev/null
+++ b/community/bsd-games/getline.diff
@@ -0,0 +1,194 @@
+diff -Naur bsd-games-2.17/boggle/boggle/bog.c bsd-games-2.17.1/boggle/boggle/bog.c
+--- bsd-games-2.17/boggle/boggle/bog.c 2004-12-07 07:34:21.000000000 -0600
++++ bsd-games-2.17.1/boggle/boggle/bog.c 2010-05-22 10:51:23.000000000 -0500
+@@ -336,7 +336,7 @@
+ }
+
+ while (1) {
+- if (getline(buf) == NULL) {
++ if (boggle_getline(buf) == NULL) {
+ if (feof(stdin))
+ clearerr(stdin);
+ break;
+diff -Naur bsd-games-2.17/boggle/boggle/extern.h bsd-games-2.17.1/boggle/boggle/extern.h
+--- bsd-games-2.17/boggle/boggle/extern.h 2004-01-27 14:52:07.000000000 -0600
++++ bsd-games-2.17.1/boggle/boggle/extern.h 2010-05-22 10:51:23.000000000 -0500
+@@ -43,7 +43,7 @@
+ long dictseek(FILE *, long, int);
+ void findword(void);
+ void flushin(FILE *);
+-char *getline(char *);
++char *boggle_getline(char *);
+ void getword(char *);
+ int help(void);
+ int inputch(void);
+diff -Naur bsd-games-2.17/boggle/boggle/mach.c bsd-games-2.17.1/boggle/boggle/mach.c
+--- bsd-games-2.17/boggle/boggle/mach.c 2004-12-07 07:34:21.000000000 -0600
++++ bsd-games-2.17.1/boggle/boggle/mach.c 2010-05-22 10:51:23.000000000 -0500
+@@ -168,7 +168,7 @@
+ * - doesn't accept words longer than MAXWORDLEN or containing caps
+ */
+ char *
+-getline(q)
++boggle_getline(q)
+ char *q;
+ {
+ int ch, done;
+diff -Naur bsd-games-2.17/cribbage/cribbage.h bsd-games-2.17.1/cribbage/cribbage.h
+--- bsd-games-2.17/cribbage/cribbage.h 2004-02-08 16:29:14.000000000 -0600
++++ bsd-games-2.17.1/cribbage/cribbage.h 2010-05-22 10:51:23.000000000 -0500
+@@ -77,7 +77,7 @@
+ int fifteens(const CARD [], int);
+ void game(void);
+ void gamescore(void);
+-char *getline(void);
++char *cribbage_getline(void);
+ int getuchar(void);
+ int incard(CARD *);
+ int infrom(const CARD [], int, const char *);
+diff -Naur bsd-games-2.17/cribbage/crib.c bsd-games-2.17.1/cribbage/crib.c
+--- bsd-games-2.17/cribbage/crib.c 2004-01-27 14:52:07.000000000 -0600
++++ bsd-games-2.17.1/cribbage/crib.c 2010-05-22 10:51:23.000000000 -0500
+@@ -221,7 +221,7 @@
+ if (!rflag) { /* player cuts deck */
+ msg(quiet ? "Cut for crib? " :
+ "Cut to see whose crib it is -- low card wins? ");
+- getline();
++ cribbage_getline();
+ }
+ i = (rand() >> 4) % CARDS; /* random cut */
+ do { /* comp cuts deck */
+@@ -397,7 +397,7 @@
+ if (!rflag) { /* random cut */
+ msg(quiet ? "Cut the deck? " :
+ "How many cards down do you wish to cut the deck? ");
+- getline();
++ cribbage_getline();
+ }
+ i = (rand() >> 4) % (CARDS - pos);
+ turnover = deck[i + pos];
+diff -Naur bsd-games-2.17/cribbage/io.c bsd-games-2.17.1/cribbage/io.c
+--- bsd-games-2.17/cribbage/io.c 2004-12-07 07:34:21.000000000 -0600
++++ bsd-games-2.17.1/cribbage/io.c 2010-05-22 10:51:23.000000000 -0500
+@@ -245,7 +245,7 @@
+
+ retval = FALSE;
+ rnk = sut = EMPTY;
+- if (!(line = getline()))
++ if (!(line = cribbage_getline()))
+ goto gotit;
+ p = p1 = line;
+ while (*p1 != ' ' && *p1 != '\0')
+@@ -346,7 +346,7 @@
+
+ for (sum = 0;;) {
+ msg(prompt);
+- if (!(p = getline()) || *p == '\0') {
++ if (!(p = cribbage_getline()) || *p == '\0') {
+ msg(quiet ? "Not a number" :
+ "That doesn't look like a number");
+ continue;
+@@ -528,12 +528,12 @@
+ }
+
+ /*
+- * getline:
++ * cribbage_getline:
+ * Reads the next line up to '\n' or EOF. Multiple spaces are
+ * compressed to one space; a space is inserted before a ','
+ */
+ char *
+-getline()
++cribbage_getline()
+ {
+ char *sp;
+ int c, oy, ox;
+diff -Naur bsd-games-2.17/gomoku/bdisp.c bsd-games-2.17.1/gomoku/bdisp.c
+--- bsd-games-2.17/gomoku/bdisp.c 2003-12-16 20:47:37.000000000 -0600
++++ bsd-games-2.17.1/gomoku/bdisp.c 2010-05-22 10:51:23.000000000 -0500
+@@ -241,7 +241,7 @@
+ }
+
+ int
+-getline(buf, size)
++gomoku_getline(buf, size)
+ char *buf;
+ int size;
+ {
+diff -Naur bsd-games-2.17/gomoku/gomoku.h bsd-games-2.17.1/gomoku/gomoku.h
+--- bsd-games-2.17/gomoku/gomoku.h 2004-01-27 14:52:07.000000000 -0600
++++ bsd-games-2.17.1/gomoku/gomoku.h 2010-05-22 10:51:23.000000000 -0500
+@@ -263,7 +263,7 @@
+
+ void bdinit(struct spotstr *);
+ void init_overlap(void);
+-int getline(char *, int);
++int gomoku_getline(char *, int);
+ void ask(const char *);
+ void dislog(const char *);
+ void bdump(FILE *);
+diff -Naur bsd-games-2.17/gomoku/main.c bsd-games-2.17.1/gomoku/main.c
+--- bsd-games-2.17/gomoku/main.c 2004-01-27 14:52:07.000000000 -0600
++++ bsd-games-2.17.1/gomoku/main.c 2010-05-22 10:51:23.000000000 -0500
+@@ -155,7 +155,7 @@
+ if (inputfp == NULL && test == 0) {
+ for (;;) {
+ ask("black or white? ");
+- getline(buf, sizeof(buf));
++ gomoku_getline(buf, sizeof(buf));
+ if (buf[0] == 'b' || buf[0] == 'B') {
+ color = BLACK;
+ break;
+@@ -172,7 +172,7 @@
+ }
+ } else {
+ setbuf(stdout, 0);
+- getline(buf, sizeof(buf));
++ gomoku_getline(buf, sizeof(buf));
+ if (strcmp(buf, "black") == 0)
+ color = BLACK;
+ else if (strcmp(buf, "white") == 0)
+@@ -244,7 +244,7 @@
+ getinput:
+ if (interactive)
+ ask("move? ");
+- if (!getline(buf, sizeof(buf))) {
++ if (!gomoku_getline(buf, sizeof(buf))) {
+ curmove = RESIGN;
+ break;
+ }
+@@ -256,7 +256,7 @@
+ FILE *fp;
+
+ ask("save file name? ");
+- (void)getline(buf, sizeof(buf));
++ (void)gomoku_getline(buf, sizeof(buf));
+ if ((fp = fopen(buf, "w")) == NULL) {
+ glog("cannot create save file");
+ goto getinput;
+@@ -309,14 +309,14 @@
+ if (i != RESIGN) {
+ replay:
+ ask("replay? ");
+- if (getline(buf, sizeof(buf)) &&
++ if (gomoku_getline(buf, sizeof(buf)) &&
+ (buf[0] == 'y' || buf[0] == 'Y'))
+ goto again;
+ if (strcmp(buf, "save") == 0) {
+ FILE *fp;
+
+ ask("save file name? ");
+- (void)getline(buf, sizeof(buf));
++ (void)gomoku_getline(buf, sizeof(buf));
+ if ((fp = fopen(buf, "w")) == NULL) {
+ glog("cannot create save file");
+ goto replay;
+@@ -367,7 +367,7 @@
+ quit();
+ top:
+ ask("cmd? ");
+- if (!getline(fmtbuf, sizeof(fmtbuf)))
++ if (!gomoku_getline(fmtbuf, sizeof(fmtbuf)))
+ quit();
+ switch (*fmtbuf) {
+ case '\0':
diff --git a/community/bsd-games/null-check.diff b/community/bsd-games/null-check.diff
new file mode 100644
index 000000000..048ed93f4
--- /dev/null
+++ b/community/bsd-games/null-check.diff
@@ -0,0 +1,24 @@
+diff --git a/hunt/hunt/hunt.c b/hunt/hunt/hunt.c
+index 11f4c44..28321bc 100644
+--- a/hunt/hunt/hunt.c
++++ b/hunt/hunt/hunt.c
+@@ -394,7 +394,8 @@ broadcast_vec(s, vector)
+
+ vec_cnt = 0;
+ for (ip = ifp; ip; ip = ip->ifa_next)
+- if ((ip->ifa_addr->sa_family == AF_INET) &&
++ if (ip->ifa_addr &&
++ (ip->ifa_addr->sa_family == AF_INET) &&
+ (ip->ifa_flags & IFF_BROADCAST))
+ vec_cnt++;
+
+@@ -405,7 +406,8 @@ broadcast_vec(s, vector)
+
+ vec_cnt = 0;
+ for (ip = ifp; ip; ip = ip->ifa_next)
+- if ((ip->ifa_addr->sa_family == AF_INET) &&
++ if (ip->ifa_addr &&
++ (ip->ifa_addr->sa_family == AF_INET) &&
+ (ip->ifa_flags & IFF_BROADCAST))
+ memcpy(&(*vector)[vec_cnt++], ip->ifa_broadaddr,
+ sizeof(struct sockaddr_in));
diff --git a/community/bsd-games/number.c.diff b/community/bsd-games/number.c.diff
new file mode 100644
index 000000000..1acbeff30
--- /dev/null
+++ b/community/bsd-games/number.c.diff
@@ -0,0 +1,156 @@
+--- bsdgames-2.17.orig/number/number.c
++++ bsdgames-2.17/number/number.c
+@@ -78,9 +78,9 @@
+
+ void convert(char *);
+ int main(int, char *[]);
+-int number(const char *, int);
+-void pfract(int);
+-int unit(int, const char *);
++int number(const char *, int, int *);
++void pfract(int, int);
++int unit(int, const char *, int *);
+ void usage(void) __attribute__((__noreturn__));
+
+ int lflag;
+@@ -131,7 +131,7 @@
+ convert(line)
+ char *line;
+ {
+- int flen, len, rval;
++ int flen, len, rval, singular;
+ char *p, *fraction;
+
+ flen = 0;
+@@ -174,7 +174,7 @@
+ --len;
+ }
+
+- rval = len > 0 ? unit(len, line) : 0;
++ rval = len > 0 ? unit(len, line, &singular) : 0;
+ if (fraction != NULL && flen != 0)
+ for (p = fraction; *p != '\0'; ++p)
+ if (*p != '0') {
+@@ -182,10 +182,10 @@
+ (void)printf("%sand%s",
+ lflag ? " " : "",
+ lflag ? " " : "\n");
+- if (unit(flen, fraction)) {
++ if (unit(flen, fraction, &singular)) {
+ if (lflag)
+ (void)printf(" ");
+- pfract(flen);
++ pfract(flen, singular);
+ rval = 1;
+ }
+ break;
+@@ -197,9 +197,10 @@
+ }
+
+ int
+-unit(len, p)
++unit(len, p, singular)
+ int len;
+ const char *p;
++ int *singular;
+ {
+ int off, rval;
+
+@@ -208,7 +209,7 @@
+ if (len % 3) {
+ off = len % 3;
+ len -= off;
+- if (number(p, off)) {
++ if (number(p, off, singular)) {
+ rval = 1;
+ (void)printf(" %s%s",
+ name3[len / 3], lflag ? " " : ".\n");
+@@ -217,14 +218,16 @@
+ }
+ for (; len > 3; p += 3) {
+ len -= 3;
+- if (number(p, 3)) {
++ if (number(p, 3, singular)) {
+ rval = 1;
+ (void)printf(" %s%s",
+ name3[len / 3], lflag ? " " : ".\n");
+ }
+ }
+ }
+- if (number(p, len)) {
++ if (number(p, len, singular)) {
++ if (rval)
++ *singular = 0;
+ if (!lflag)
+ (void)printf(".\n");
+ rval = 1;
+@@ -233,17 +236,20 @@
+ }
+
+ int
+-number(p, len)
++number(p, len, singular)
+ const char *p;
+ int len;
++ int *singular;
+ {
+ int val, rval;
+
+ rval = 0;
++ *singular = 1;
+ switch (len) {
+ case 3:
+ if (*p != '0') {
+ rval = 1;
++ *singular = 0;
+ (void)printf("%s hundred", name1[*p - '0']);
+ }
+ ++p;
+@@ -262,33 +268,42 @@
+ }
+ rval = 1;
+ }
++ if (val != 1)
++ *singular = 0;
+ break;
+ case 1:
+ if (*p != '0') {
+ rval = 1;
+ (void)printf("%s", name1[*p - '0']);
+ }
++ if (*p != '1')
++ *singular = 0;
+ }
+ return (rval);
+ }
+
+ void
+-pfract(len)
++pfract(len, singular)
+ int len;
++ int singular;
+ {
+ static const char *const pref[] = { "", "ten-", "hundred-" };
+
+ switch(len) {
+ case 1:
+- (void)printf("tenths.\n");
++ (void)printf("tenth");
+ break;
+ case 2:
+- (void)printf("hundredths.\n");
++ (void)printf("hundredth");
+ break;
+ default:
+- (void)printf("%s%sths.\n", pref[len % 3], name3[len / 3]);
++ (void)printf("%s%sth", pref[len % 3], name3[len / 3]);
+ break;
+ }
++ if (!singular) {
++ printf("s");
++ }
++ printf(".\n");
+ }
+
+ void
+
diff --git a/community/bsd-games/stdio.h.diff b/community/bsd-games/stdio.h.diff
new file mode 100644
index 000000000..786fa54c4
--- /dev/null
+++ b/community/bsd-games/stdio.h.diff
@@ -0,0 +1,14 @@
+diff -ru a/include/stdio.h b/include/stdio.h
+--- a/include/stdio.h 2000-08-04 10:24:39.000000000 +1000
++++ b/include/stdio.h 2005-06-18 14:26:35.000000000 +1000
+@@ -34,6 +34,10 @@
+ #include <bsd-games.h>
+ #include_next <stdio.h>
+
++__BEGIN_DECLS
++
+ #ifndef HAVE_fgetln
+ extern char *fgetln(FILE *stream, size_t *len);
+ #endif
++
++__END_DECLS