summaryrefslogtreecommitdiff
path: root/gnu/packages
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/packages')
-rw-r--r--gnu/packages/games.scm134
-rw-r--r--gnu/packages/patches/bsd-games-2.17-64bit.patch43
-rw-r--r--gnu/packages/patches/bsd-games-add-configure-config.patch22
-rw-r--r--gnu/packages/patches/bsd-games-add-wrapper.patch251
-rw-r--r--gnu/packages/patches/bsd-games-bad-ntohl-cast.patch22
-rw-r--r--gnu/packages/patches/bsd-games-dont-install-empty-files.patch87
-rw-r--r--gnu/packages/patches/bsd-games-gamescreen.h.patch14
-rw-r--r--gnu/packages/patches/bsd-games-getline.patch194
-rw-r--r--gnu/packages/patches/bsd-games-null-check.patch24
-rw-r--r--gnu/packages/patches/bsd-games-number.c-and-test.patch183
-rw-r--r--gnu/packages/patches/bsd-games-prevent-name-collisions.patch13
-rw-r--r--gnu/packages/patches/bsd-games-stdio.h.patch14
12 files changed, 1001 insertions, 0 deletions
diff --git a/gnu/packages/games.scm b/gnu/packages/games.scm
index 5f906d0a4e..eb29f2a8e5 100644
--- a/gnu/packages/games.scm
+++ b/gnu/packages/games.scm
@@ -116,6 +116,7 @@
#:use-module (gnu packages gl)
#:use-module (gnu packages glib)
#:use-module (gnu packages gnome)
+ #:use-module (gnu packages gnu-doc)
#:use-module (gnu packages gnupg)
#:use-module (gnu packages gnuzilla)
#:use-module (gnu packages gperf)
@@ -589,6 +590,139 @@ possible, while battling many vicious aliens.")
license:lgpl2.1+
license:bsd-2))))
+(define-public bsd-games
+ (package
+ (name "bsd-games")
+ (version "2.17.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri "https://ibiblio.org/pub/linux/games/bsd-games-2.17.tar.gz")
+ (sha256
+ (base32 "0q7zdyyfvn15y0w4g54kq3gza89h61py727m8slmw73cxx594vq6"))
+ (patches
+ (search-patches
+ ;; thanks Arch, and Debian
+ "bsd-games-2.17-64bit.patch"
+ "bsd-games-bad-ntohl-cast.patch"
+ "bsd-games-gamescreen.h.patch"
+ "bsd-games-getline.patch"
+ "bsd-games-null-check.patch"
+ "bsd-games-number.c-and-test.patch"
+ "bsd-games-stdio.h.patch"
+ "bsd-games-prevent-name-collisions.patch"
+ ;; Guix customizations
+ "bsd-games-add-configure-config.patch"
+ "bsd-games-dont-install-empty-files.patch"
+ "bsd-games-add-wrapper.patch"))))
+ (build-system gnu-build-system)
+ (native-inputs
+ `(("flex" ,flex)
+ ("bison" ,bison)))
+ (inputs
+ `(("curses" ,ncurses)
+ ("pager" ,less)
+ ("miscfiles" ,miscfiles)
+ ("openssl" ,openssl))) ;used only by 'factor'
+ (arguments
+ `(#:phases
+ (modify-phases %standard-phases
+ (replace 'configure
+ (lambda* (#:key outputs inputs #:allow-other-keys)
+ (let* ((out (assoc-ref outputs "out"))
+ (bin (string-append out "/bin"))
+ (doc (string-append out "/share/doc/bsd-games-" ,version))
+ (man (string-append out "/share/man"))
+ (word-list (string-append (assoc-ref inputs "miscfiles")
+ "/share/web2"))
+ (static-data (string-append out "/share/games/bsd-games"))
+ ;; Not a "./" because of substitute* in 'patch-install
+ ;; below. The .// allow us not to mess with the games'
+ ;; code any further: we just use a wrapper script that
+ ;; cd's to a BSD_GAMES_DIR. :]
+ (save-files ".//"))
+ (substitute* "configure"
+ (("/usr/share/man") man)
+ (("/usr/share/doc/bsd-games") doc)
+ (("/usr/share/[^\n/]*") static-data)
+ (("/var/games") save-files)
+ (("/usr/bin/less") (which "less"))
+ (("(/usr/bin|/usr/games)") bin))
+ (substitute* "config.params" (("WORD_LIST") word-list))
+ (substitute* "wrapper" (("STATIC_DATA") static-data))
+ (invoke "./configure"))
+ #t))
+ (add-before 'install 'patch-install
+ ;; Some games need a writable directory containing pre-maded files.
+ ;; The files get installed to the Store. Then the wrapper kicks in.
+ (lambda* (#:key outputs #:allow-other-keys)
+ (let* ((out (assoc-ref outputs "out"))
+ (static-data (string-append out "/share/games/bsd-games"))
+ (save-files ".//"))
+ (substitute* "Makeconfig" ((save-files) static-data)))
+ #t))
+ (add-after 'install 'install-documents
+ (lambda* (#:key outputs #:allow-other-keys)
+ (let* ((out (assoc-ref outputs "out"))
+ (doc (string-append out "/share/doc/bsd-games-" ,version)))
+ (rename-file "phantasia/COPYRIGHT" "phantasia-COPYRIGHT")
+ (for-each
+ (lambda(file) (install-file file doc))
+ '("AUTHORS" "BUGS" "README" "SECURITY" "THANKS"
+ "phantasia-COPYRIGHT")))
+ #t)))))
+ (home-page "https://github.com/vattam/BSDGames")
+ (synopsis "Collection of the old text-based games and amusements")
+ (description
+ "These are the BSD games. See the fortune-mod package for fortunes.
+
+Action: atc (keep the airplanes safe), hack (explore the dangerous Dungeon),
+hunt (kill the others for the Pair of Boots, multi-player only), robots (avoid
+the evil robots), sail (game of naval warfare with wooden ships), snake (steal
+the $$ from the cave, anger the snake, and get out alive), tetris (game of
+lining up the falling bricks of different shapes), and worm (eat, grow big,
+and neither bite your tail, nor ram the wall).
+
+Amusements: banner (prints a large banner), bcd & morse & ppt (print a punch
+card, or paper tape, or Morse codes), caesar & rot13 (ciphers and deciphers
+the input), factor (factorizes a number), number (translates numbers into
+text), pig (translates from English to Pig Latin), pom (should print the
+Moon's phase), primes (generates primes), rain & worms (plays an screen-saver
+in terminal), random (prints randomly choosen lines from files, or returns a
+random exit-code), and wtf (explains what do some acronyms mean).
+
+Board: backgammon (lead the men out of board faster than the friend do),
+boggle (find the words in the square of letters), dab (game of dots and
+boxes), gomoku (game of five in a row), hangman (guess a word before man is
+hanged), and monop (game of monopoly, hot-seat only). Also the card-games:
+canfield, cribbage, fish (juniors game), and mille.
+
+Quests: adventure (search for treasures with the help of wizard),
+battlestar (explore the world around, starting from dying spaceship),
+phantasia (role-play as an rogue), trek (hunt the Klingons, and save the
+Federation), and wump (hunt the big smelly Wumpus in a dark cave).
+
+Quizes: arithmetic, and quiz.")
+ ;; "Auxiliary and data files, distributed with the games in NetBSD, but
+ ;; not bearing copyright notices, probably fall under the terms of the UCB
+ ;; or NetBSD copyrights and licences. The file "fortune/Notes" contains a
+ ;; warning in regard to the fortune databases."
+ (license (list
+ ;; Most games. Files: countmail/countmail.6, dab/dab.6,
+ ;; lib/strlcpy.c, wargames/wargames.6
+ license:bsd-3
+ ;; dab and hunt. Files: adventure/extern.h,
+ ;; backgammon/backgammon/backlocal.h, caesar/rot13.in,
+ ;; countmail/countmail, dm/utmpentry.c, dm/utmpentry.h,
+ ;; hack/extern.h, robots/auto.c, sail/display.h,
+ ;; sail/restart.h, wargames/wargames
+ license:bsd-4
+ ;; wtf (the game)
+ license:public-domain
+ ;; phantasia (all but phantasia/pathnames.h.in, which is bsd-3)
+ (license:fsf-free "file:///phantasia/COPYRIGHT")))))
+
+
(define-public bzflag
(package
(name "bzflag")
diff --git a/gnu/packages/patches/bsd-games-2.17-64bit.patch b/gnu/packages/patches/bsd-games-2.17-64bit.patch
new file mode 100644
index 0000000000..e286c1c531
--- /dev/null
+++ b/gnu/packages/patches/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/gnu/packages/patches/bsd-games-add-configure-config.patch b/gnu/packages/patches/bsd-games-add-configure-config.patch
new file mode 100644
index 0000000000..d8636addb6
--- /dev/null
+++ b/gnu/packages/patches/bsd-games-add-configure-config.patch
@@ -0,0 +1,22 @@
+Remove a few 'setenv's from the definition.
+
+diff -Naur bsd-games-2.17/config.params bsd-games-patch/config.params
+--- bsd-games-2.17/config.params 1970-01-01 07:00:00.000000000 +0700
++++ bsd-games-patch/config.params 2020-04-22 20:49:40.809695248 +0700
+@@ -0,0 +1,16 @@
++bsd_games_cfg_do_chown=n
++bsd_games_cfg_non_interactive=y
++
++# Fix some man-pages: cfscores, morse, ppt, rot13, snscore, teachgammon.
++bsd_games_cfg_use_dot_so=syml
++
++# Don't build some games:
++# Countmail require some BSD-package called `from`.
++# DM is a toy to restrict access to bsd-games.
++# Fortune seems to be already packaged (fortune-mod).
++# Wargames isn't convenient as a game launcher.
++bsd_games_cfg_no_build_dirs="countmail dm fortune wargames"
++
++# Those are substitute*'d with GNU miscfiles.
++bsd_games_cfg_hangman_wordsfile=WORD_LIST
++bsd_games_cfg_dictionary_src=WORD_LIST
diff --git a/gnu/packages/patches/bsd-games-add-wrapper.patch b/gnu/packages/patches/bsd-games-add-wrapper.patch
new file mode 100644
index 0000000000..ad3b1a9860
--- /dev/null
+++ b/gnu/packages/patches/bsd-games-add-wrapper.patch
@@ -0,0 +1,251 @@
+As we cannot install outside the Store, and those games do not create the
+needed writable files on their own, we need a wrapper script.
+
+diff -Naur bsd-games-2.17/atc/Makefrag bsd-games-patch/atc/Makefrag
+--- bsd-games-2.17/atc/Makefrag 1970-01-01 07:00:00.000000000 +0700
++++ bsd-games-patch/atc/Makefrag 2020-04-23 20:24:04.446176222 +0700
+@@ -47,7 +47,8 @@
+ mv atc/lex.yy.c $@
+
+ atc_install: atc_all
+- $(INSTALL_SCORE_GAME) atc/atc $(INSTALL_PREFIX)$(GAMESDIR)/atc
++ $(INSTALL_SCORE_GAME) wrapper $(INSTALL_PREFIX)$(GAMESDIR)/atc
++ $(INSTALL_SCORE_GAME) atc/atc $(INSTALL_PREFIX)$(GAMESDIR)/.atc-real
+ $(HIDE_GAME) atc
+ $(INSTALL_SCORE_FILE) $(ATC_SCOREFILE)
+ $(INSTALL_MANUAL) atc/atc.6
+diff -Naur bsd-games-2.17/battlestar/Makefrag bsd-games-patch/battlestar/Makefrag
+--- bsd-games-2.17/battlestar/Makefrag 1970-01-01 07:00:00.000000000 +0700
++++ bsd-games-patch/battlestar/Makefrag 2020-04-23 20:24:04.482175771 +0700
+@@ -32,7 +32,8 @@
+ battlestar_all: battlestar/battlestar battlestar/battlestar.6
+
+ battlestar_install: battlestar_all
+- $(INSTALL_SCORE_GAME) battlestar/battlestar $(INSTALL_PREFIX)$(GAMESDIR)/battlestar
++ $(INSTALL_SCORE_GAME) wrapper $(INSTALL_PREFIX)$(GAMESDIR)/battlestar
++ $(INSTALL_SCORE_GAME) battlestar/battlestar $(INSTALL_PREFIX)$(GAMESDIR)/.battlestar-real
+ $(HIDE_GAME) battlestar
+ $(INSTALL_MANUAL) battlestar/battlestar.6
+ $(INSTALL_SCORE_FILE) $(BATTLESTAR_SCOREFILE)
+diff -Naur bsd-games-2.17/canfield/canfield/Makefrag bsd-games-patch/canfield/canfield/Makefrag
+--- bsd-games-2.17/canfield/canfield/Makefrag 1970-01-01 07:00:00.000000000 +0700
++++ bsd-games-patch/canfield/canfield/Makefrag 2020-04-23 20:24:04.522175270 +0700
+@@ -31,7 +31,8 @@
+ canfield_canfield_all: canfield/canfield/canfield canfield/canfield/canfield.6
+
+ canfield_canfield_install: canfield_canfield_all
+- $(INSTALL_SCORE_GAME) canfield/canfield/canfield $(INSTALL_PREFIX)$(GAMESDIR)/canfield
++ $(INSTALL_SCORE_GAME) wrapper $(INSTALL_PREFIX)$(GAMESDIR)/canfield
++ $(INSTALL_SCORE_GAME) canfield/canfield/canfield $(INSTALL_PREFIX)$(GAMESDIR)/.canfield-real
+ $(HIDE_GAME) canfield
+ $(INSTALL_MANUAL) canfield/canfield/canfield.6
+ $(INSTALL_SCORE_FILE) $(CANFIELD_SCOREFILE)
+diff -ur bsd-games-2.17.orig/canfield/cfscores/Makefrag bsd-games-2.17/canfield/cfscores/Makefrag
+--- bsd-games-2.17.orig/canfield/cfscores/Makefrag 1970-01-01 07:00:01.000000000 +0700
++++ bsd-games-2.17/canfield/cfscores/Makefrag 2020-08-06 12:20:10.592076477 +0700
+@@ -32,6 +32,7 @@
+ canfield_cfscores_all: canfield/cfscores/cfscores
+
+ canfield_cfscores_install: canfield_cfscores_all
+- $(INSTALL_BINARY) canfield/cfscores/cfscores $(INSTALL_PREFIX)$(GAMESDIR)/cfscores
++ $(INSTALL_BINARY) wrapper $(INSTALL_PREFIX)$(GAMESDIR)/cfscores
++ $(INSTALL_BINARY) canfield/cfscores/cfscores $(INSTALL_PREFIX)$(GAMESDIR)/.cfscores-real
+ $(HIDE_GAME) cfscores
+ $(INSTALL_MANUAL) canfield.6 cfscores.6
+diff -Naur bsd-games-2.17/cribbage/Makefrag bsd-games-patch/cribbage/Makefrag
+--- bsd-games-2.17/cribbage/Makefrag 1970-01-01 07:00:00.000000000 +0700
++++ bsd-games-patch/cribbage/Makefrag 2020-04-23 20:24:04.534175120 +0700
+@@ -31,7 +31,8 @@
+ cribbage_all: cribbage/cribbage cribbage/cribbage.n cribbage/cribbage.6
+
+ cribbage_install: cribbage_all
+- $(INSTALL_SCORE_GAME) cribbage/cribbage $(INSTALL_PREFIX)$(GAMESDIR)/cribbage
++ $(INSTALL_SCORE_GAME) wrapper $(INSTALL_PREFIX)$(GAMESDIR)/cribbage
++ $(INSTALL_SCORE_GAME) cribbage/cribbage $(INSTALL_PREFIX)$(GAMESDIR)/.cribbage-real
+ $(HIDE_GAME) cribbage
+ $(INSTALL_DATA) cribbage/cribbage.n $(INSTALL_PREFIX)$(CRIBBAGE_INSTRFILE)
+ $(INSTALL_SCORE_FILE) $(CRIBBAGE_SCOREFILE)
+diff -Naur bsd-games-2.17/hack/Makefrag bsd-games-patch/hack/Makefrag
+--- bsd-games-2.17/hack/Makefrag 1970-01-01 07:00:00.000000000 +0700
++++ bsd-games-patch/hack/Makefrag 2020-04-23 20:24:04.590174419 +0700
+@@ -53,7 +53,8 @@
+ hack/hack.zap.d hack/rnd.d: hack/hack.onames.h
+
+ hack_install: hack_all
+- $(INSTALL_SCORE_GAME) hack/hack $(INSTALL_PREFIX)$(GAMESDIR)/hack
++ $(INSTALL_SCORE_GAME) wrapper $(INSTALL_PREFIX)$(GAMESDIR)/hack
++ $(INSTALL_SCORE_GAME) hack/hack $(INSTALL_PREFIX)$(GAMESDIR)/.hack-real
+ $(HIDE_GAME) hack
+ $(INSTALL_HACK_DIR) $(INSTALL_PREFIX)$(HACK_DIR)
+ set -e; for f in data help hh rumors; do $(INSTALL_DATA) hack/$$f $(INSTALL_PREFIX)$(HACK_DIR)/$$f; done
+diff -Naur bsd-games-2.17/phantasia/Makefrag bsd-games-patch/phantasia/Makefrag
+--- bsd-games-2.17/phantasia/Makefrag 1970-01-01 07:00:00.000000000 +0700
++++ bsd-games-patch/phantasia/Makefrag 2020-04-23 20:24:04.650173667 +0700
+@@ -38,7 +38,8 @@
+ touch phantasia/scorefiles.stamp
+
+ phantasia_install: phantasia_all
+- $(INSTALL_SCORE_GAME) phantasia/phantasia $(INSTALL_PREFIX)$(GAMESDIR)/phantasia
++ $(INSTALL_SCORE_GAME) wrapper $(INSTALL_PREFIX)$(GAMESDIR)/phantasia
++ $(INSTALL_SCORE_GAME) phantasia/phantasia $(INSTALL_PREFIX)$(GAMESDIR)/.phantasia-real
+ $(HIDE_GAME) phantasia
+ (set -e; for f in $(phantasia_VFILES1); do \
+ cp phantasia/$$f $(INSTALL_PREFIX)$(PHANTASIA_DIR)/$$f; \
+diff -Naur bsd-games-2.17/robots/Makefrag bsd-games-patch/robots/Makefrag
+--- bsd-games-2.17/robots/Makefrag 1970-01-01 07:00:00.000000000 +0700
++++ bsd-games-patch/robots/Makefrag 2020-04-23 20:24:04.702173016 +0700
+@@ -32,7 +32,8 @@
+ robots_all: robots/robots robots/robots.6
+
+ robots_install: robots_all
+- $(INSTALL_SCORE_GAME) robots/robots $(INSTALL_PREFIX)$(GAMESDIR)/robots
++ $(INSTALL_SCORE_GAME) wrapper $(INSTALL_PREFIX)$(GAMESDIR)/robots
++ $(INSTALL_SCORE_GAME) robots/robots $(INSTALL_PREFIX)$(GAMESDIR)/.robots-real
+ $(HIDE_GAME) robots
+ $(INSTALL_SCORE_FILE) $(ROBOTS_SCOREFILE)
+ $(INSTALL_MANUAL) robots/robots.6
+diff -Naur bsd-games-2.17/sail/Makefrag bsd-games-patch/sail/Makefrag
+--- bsd-games-2.17/sail/Makefrag 1970-01-01 07:00:00.000000000 +0700
++++ bsd-games-patch/sail/Makefrag 2020-04-23 20:24:04.710172917 +0700
+@@ -31,7 +31,8 @@
+ sail_all: sail/sail sail/sail.6
+
+ sail_install: sail_all
+- $(INSTALL_SCORE_GAME) sail/sail $(INSTALL_PREFIX)$(GAMESDIR)/sail
++ $(INSTALL_SCORE_GAME) wrapper $(INSTALL_PREFIX)$(GAMESDIR)/sail
++ $(INSTALL_SCORE_GAME) sail/sail $(INSTALL_PREFIX)$(GAMESDIR)/.sail-real
+ $(HIDE_GAME) sail
+ $(INSTALL_SCORE_FILE) $(SAIL_SCOREFILE)
+ $(INSTALL_SAIL_DIR) $(INSTALL_PREFIX)$(SAIL_DIR)
+diff -Naur bsd-games-2.17/snake/snake/Makefrag bsd-games-patch/snake/snake/Makefrag
+--- bsd-games-2.17/snake/snake/Makefrag 1970-01-01 07:00:00.000000000 +0700
++++ bsd-games-patch/snake/snake/Makefrag 2020-04-23 20:24:04.722172766 +0700
+@@ -31,7 +31,8 @@
+ snake_snake_all: snake/snake/snake snake/snake/snake.6
+
+ snake_snake_install: snake_snake_all
+- $(INSTALL_SCORE_GAME) snake/snake/snake $(INSTALL_PREFIX)$(GAMESDIR)/snake
++ $(INSTALL_SCORE_GAME) wrapper $(INSTALL_PREFIX)$(GAMESDIR)/snake
++ $(INSTALL_SCORE_GAME) snake/snake/snake $(INSTALL_PREFIX)$(GAMESDIR)/.snake-real
+ $(HIDE_GAME) snake
+ $(INSTALL_SCORE_FILE) $(SNAKE_SCOREFILE)
+ $(INSTALL_SCORE_FILE) $(SNAKE_RAWSCOREFILE)
+--- bsd-games-2.17.orig/snake/snscore/Makefrag 1970-01-01 07:00:01.000000000 +0700
++++ bsd-games-2.17/snake/snscore/Makefrag 2020-08-06 12:33:09.636089394 +0700
+@@ -32,6 +32,7 @@
+ snake_snscore_all: snake/snscore/snscore
+
+ snake_snscore_install: snake_snscore_all
+- $(INSTALL_BINARY) snake/snscore/snscore $(INSTALL_PREFIX)$(GAMESDIR)/snscore
++ $(INSTALL_BINARY) wrapper $(INSTALL_PREFIX)$(GAMESDIR)/snscore
++ $(INSTALL_BINARY) snake/snscore/snscore $(INSTALL_PREFIX)$(GAMESDIR)/.snscore-real
+ $(HIDE_GAME) snscore
+ $(INSTALL_MANUAL) snake.6 snscore.6
+diff -Naur bsd-games-2.17/tetris/Makefrag bsd-games-patch/tetris/Makefrag
+--- bsd-games-2.17/tetris/Makefrag 1970-01-01 07:00:00.000000000 +0700
++++ bsd-games-patch/tetris/Makefrag 2020-04-23 20:24:04.734172616 +0700
+@@ -32,7 +32,8 @@
+ tetris_all: tetris/tetris tetris/tetris.6
+
+ tetris_install: tetris_all
+- $(INSTALL_SCORE_GAME) tetris/tetris $(INSTALL_PREFIX)$(GAMESDIR)/tetris-bsd
++ $(INSTALL_SCORE_GAME) wrapper $(INSTALL_PREFIX)$(GAMESDIR)/tetris-bsd
++ $(INSTALL_SCORE_GAME) tetris/tetris $(INSTALL_PREFIX)$(GAMESDIR)/.tetris-bsd-real
+ $(HIDE_GAME) tetris-bsd
+ $(INSTALL_SCORE_FILE) $(TETRIS_SCOREFILE)
+ ln -f tetris/tetris.6 tetris/tetris-bsd.6
+diff -Naur bsd-games-2.17/wrapper bsd-games-patch/wrapper
+--- bsd-games-2.17/wrapper 1970-01-01 07:00:00.000000000 +0700
++++ bsd-games-patch/wrapper 2020-04-23 20:24:37.153766719 +0700
+@@ -0,0 +1,91 @@
++#!/bin/sh
++# This file works around limitations of our read-only Store.
++
++set -e
++
++check_empty_files () {
++ # those start empty
++ for f in ${@}
++ do
++ if [[ ! -f ${f} ]]
++ then
++ touch ${f}
++ echo "$(pwd)/${f} RESTORED"
++ fi
++ done
++}
++check_data_files () {
++ # those start with some initial data
++ for f in ${@}
++ do
++ if [[ ! -f ${f} ]]
++ then
++ cp STATIC_DATA/${game}/${f} ${f}
++ chmod u+w ${f}
++ echo "$(pwd)/${f} RESTORED"
++ fi
++ done
++}
++visit_dir () {
++ mkdir -p ${1}
++ cd ${1}
++}
++exit_with_variable_error () {
++ variables="${1}${2:+ or ${2}}"
++ echo "Guix: Please set up the ${variables} variable."
++ echo "Examples:"
++ echo " export ${1}=/var/multiplayer"
++ echo " export ${2:-${1}}=~/.local/share/bsd-games"
++ echo "You can place this in ~/.bashrc or a similar file for Your shell."
++ echo "For multiplayer this directory should be writable for all players."
++ exit 1
++}
++
++game=$(basename $0)
++if [[ ${game} == "hack" ]]
++then
++ if [[ -n ${HACKDIR} ]]; then visit_dir "${HACKDIR}"
++ elif [[ -n ${BSD_GAMES_DIR} ]]; then visit_dir "${BSD_GAMES_DIR}/hack"
++ else exit_with_variable_error "HACKDIR" "BSD_GAMES_DIR"
++ fi
++else
++ if [[ -n ${BSD_GAMES_DIR} ]]; then visit_dir "${BSD_GAMES_DIR}"
++ else exit_with_variable_error "BSD_GAMES_DIR"
++ fi
++fi
++
++case ${game} in
++ ### Games with score-files
++ atc)
++ check_empty_files "atc_score";;
++ battlestar)
++ check_empty_files "battlestar.log";;
++ canfield)
++ check_empty_files "cfscores";;
++ cribbage)
++ check_empty_files "criblog";;
++ robots)
++ check_empty_files "robots_roll";;
++ snake)
++ check_empty_files "snakerawscores" "snake.log";;
++ tetris)
++ check_empty_files "tetris-bsd.scores";;
++ ### Games with saved state
++ hack)
++ check_empty_files "record" "perm"
++ check_data_files "data" "help" "hh" "rumors"
++ visit_dir "save"
++ cd ../../;;
++ phantasia)
++ visit_dir "phantasia"
++ check_empty_files "characs" "gold" "lastdead"\
++ "mess" "motd" "scoreboard" "void"
++ check_data_files "monsters"
++ cd ../;;
++ sail)
++ visit_dir "sail"
++ check_empty_files "log" "syncfile"
++ cd ../;;
++esac
++
++exec .${game}-real ${@}
diff --git a/gnu/packages/patches/bsd-games-bad-ntohl-cast.patch b/gnu/packages/patches/bsd-games-bad-ntohl-cast.patch
new file mode 100644
index 0000000000..caadfa5054
--- /dev/null
+++ b/gnu/packages/patches/bsd-games-bad-ntohl-cast.patch
@@ -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/gnu/packages/patches/bsd-games-dont-install-empty-files.patch b/gnu/packages/patches/bsd-games-dont-install-empty-files.patch
new file mode 100644
index 0000000000..4ee0578177
--- /dev/null
+++ b/gnu/packages/patches/bsd-games-dont-install-empty-files.patch
@@ -0,0 +1,87 @@
+Those games rely on user to provide the files to write scores in.
+Those score-files are initially empty. Anyway, the Store is read-only.
+So we do not install those empty files.
+
+diff -Naur bsd-games-2.17/install-score.in bsd-games-patch/install-score.in
+--- bsd-games-2.17/install-score.in 1970-01-01 07:00:00.000000000 +0700
++++ bsd-games-patch/install-score.in 2020-04-22 21:41:47.810544804 +0700
+@@ -1,45 +0,0 @@
+-# install-score.in - install a score file
+-#
+-# Copyright (c) 1997, 1998, 1999 Joseph Samuel Myers.
+-# All rights reserved.
+-#
+-# Redistribution and use in source and binary forms, with or without
+-# modification, are permitted provided that the following conditions
+-# are met:
+-# 1. Redistributions of source code must retain the above copyright
+-# notice, this list of conditions and the following disclaimer.
+-# 2. Redistributions in binary form must reproduce the above copyright
+-# notice, this list of conditions and the following disclaimer in the
+-# documentation and/or other materials provided with the distribution.
+-# 3. The name of the author may not be used to endorse or promote products
+-# derived from this software without specific prior written permission.
+-#
+-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+-# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+-# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+-# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+-# SUCH DAMAGE.
+-
+-set -e
+-
+-if [ "$1" = "-p" ]; then
+- scorefile="@install_prefix@$2"
+- perms=@vardata_perms_priv@
+-else
+- scorefile="@install_prefix@$1"
+- perms=@vardata_perms@
+-fi
+-
+-mkdir -p "$(dirname "$scorefile")"
+-
+-test -e "$scorefile" || touch "$scorefile"
+-if [ @do_chown@ = y ]; then
+- chown @vardata_owner@:@vardata_group@ "$scorefile"
+-fi
+-chmod "$perms" "$scorefile"
+diff -Naur bsd-games-2.17/phantasia/Makefrag bsd-games-patch/phantasia/Makefrag
+--- bsd-games-2.17/phantasia/Makefrag 1970-01-01 07:00:00.000000000 +0700
++++ bsd-games-patch/phantasia/Makefrag 2020-04-22 21:26:00.162409464 +0700
+@@ -27,9 +27,8 @@
+ # SUCH DAMAGE.
+
+ phantasia_DIRS := $(GAMESDIR) $(MAN6DIR) $(PHANTASIA_DIR)
+-phantasia_VFILES1 := gold lastdead mess monsters motd void
+-phantasia_VFILES2 := scoreboard characs
+-phantasia_CLEANFILES := $(phantasia_VFILES1) $(phantasia_VFILES2) scorefiles.stamp
++phantasia_VFILES1 := monsters
++phantasia_CLEANFILES := $(phantasia_VFILES1) scorefiles.stamp
+
+ phantasia_all: phantasia/phantasia phantasia/phantasia.6 phantasia/scorefiles.stamp
+
+@@ -43,9 +42,4 @@
+ (set -e; for f in $(phantasia_VFILES1); do \
+ cp phantasia/$$f $(INSTALL_PREFIX)$(PHANTASIA_DIR)/$$f; \
+ $(INSTALL_SCORE_FILE) $(PHANTASIA_DIR)/$$f; done)
+- (set -e; for f in $(phantasia_VFILES2); do \
+- if [ ! -e $(PHANTASIA_DIR)/$$f ]; then \
+- cp phantasia/$$f $(INSTALL_PREFIX)$(PHANTASIA_DIR)/$$f; fi; done; \
+- $(INSTALL_SCORE_FILE) $(PHANTASIA_DIR)/scoreboard; \
+- $(INSTALL_SCORE_FILE) -p $(PHANTASIA_DIR)/characs)
+ $(INSTALL_MANUAL) phantasia/phantasia.6
+diff -Naur bsd-games-2.17/sail/Makefrag bsd-games-patch/sail/Makefrag
+--- bsd-games-2.17/sail/Makefrag 1970-01-01 07:00:00.000000000 +0700
++++ bsd-games-patch/sail/Makefrag 2020-04-22 21:26:48.701801676 +0700
+@@ -34,5 +34,4 @@
+ $(INSTALL_SCORE_GAME) sail/sail $(INSTALL_PREFIX)$(GAMESDIR)/sail
+ $(HIDE_GAME) sail
+ $(INSTALL_SCORE_FILE) $(SAIL_SCOREFILE)
+- $(INSTALL_SAIL_DIR) $(INSTALL_PREFIX)$(SAIL_DIR)
+ $(INSTALL_MANUAL) sail/sail.6
diff --git a/gnu/packages/patches/bsd-games-gamescreen.h.patch b/gnu/packages/patches/bsd-games-gamescreen.h.patch
new file mode 100644
index 0000000000..d3c6b4ae50
--- /dev/null
+++ b/gnu/packages/patches/bsd-games-gamescreen.h.patch
@@ -0,0 +1,14 @@
+--- 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/gnu/packages/patches/bsd-games-getline.patch b/gnu/packages/patches/bsd-games-getline.patch
new file mode 100644
index 0000000000..d7c0b4034d
--- /dev/null
+++ b/gnu/packages/patches/bsd-games-getline.patch
@@ -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/gnu/packages/patches/bsd-games-null-check.patch b/gnu/packages/patches/bsd-games-null-check.patch
new file mode 100644
index 0000000000..ba977c95bf
--- /dev/null
+++ b/gnu/packages/patches/bsd-games-null-check.patch
@@ -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/gnu/packages/patches/bsd-games-number.c-and-test.patch b/gnu/packages/patches/bsd-games-number.c-and-test.patch
new file mode 100644
index 0000000000..1cf5ba2822
--- /dev/null
+++ b/gnu/packages/patches/bsd-games-number.c-and-test.patch
@@ -0,0 +1,183 @@
+Arch's patch, and a fix for the "number" game's test.
+--- 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 -Naur bsd-games-2.17/tests/number.-0.1 bsd-games-patch/tests/number.-0.1
+--- bsd-games-2.17/tests/number.-0.1 1970-01-01 07:00:00.000000000 +0700
++++ bsd-games-patch/tests/number.-0.1 2020-04-17 15:14:27.831098084 +0700
+@@ -1,3 +1,3 @@
+ minus
+ one.
+-tenths.
++tenth.
+diff -Naur bsd-games-2.17/tests/number.-0.2 bsd-games-patch/tests/number.-0.2
+--- bsd-games-2.17/tests/number.-0.2 1970-01-01 07:00:00.000000000 +0700
++++ bsd-games-patch/tests/number.-0.2 2020-04-17 15:20:48.162336279 +0700
+@@ -0,0 +1,3 @@
++minus
++two.
++tenths.
+diff -Naur bsd-games-2.17/tests/number.test bsd-games-patch/tests/number.test
+--- bsd-games-2.17/tests/number.test 1970-01-01 07:00:00.000000000 +0700
++++ bsd-games-patch/tests/number.test 2020-04-17 15:20:22.774654155 +0700
+@@ -36,6 +36,8 @@
+ testno 1
+ number/number -- -0.1 >test.out 2>&1 || failtest
+ compare test.out tests/number.-0.1
++number/number -- -0.2 >test.out 2>&1 || failtest
++compare test.out tests/number.-0.2
+ rm -f test.out
+
+ testno 2
diff --git a/gnu/packages/patches/bsd-games-prevent-name-collisions.patch b/gnu/packages/patches/bsd-games-prevent-name-collisions.patch
new file mode 100644
index 0000000000..855ce59131
--- /dev/null
+++ b/gnu/packages/patches/bsd-games-prevent-name-collisions.patch
@@ -0,0 +1,13 @@
+There is already a "fish" shell.
+diff -ur bsd-games-2.17.orig/fish/Makefrag bsd-games-2.17/fish/Makefrag
+--- bsd-games-2.17.orig/fish/Makefrag 1970-01-01 07:00:01.000000000 +0700
++++ bsd-games-2.17/fish/Makefrag 2020-08-06 19:18:43.204492847 +0700
+@@ -31,7 +31,7 @@
+ fish_all: fish/fish fish/fish.instr fish/fish.6
+
+ fish_install: fish_all
+- $(INSTALL_BINARY) fish/fish $(INSTALL_PREFIX)$(GAMESDIR)/fish
++ $(INSTALL_BINARY) fish/fish $(INSTALL_PREFIX)$(GAMESDIR)/fish-game
+ $(HIDE_GAME) fish
+ $(INSTALL_DATA) fish/fish.instr $(INSTALL_PREFIX)$(FISH_INSTRFILE)
+ $(INSTALL_MANUAL) fish/fish.6
diff --git a/gnu/packages/patches/bsd-games-stdio.h.patch b/gnu/packages/patches/bsd-games-stdio.h.patch
new file mode 100644
index 0000000000..1c3a402042
--- /dev/null
+++ b/gnu/packages/patches/bsd-games-stdio.h.patch
@@ -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