Subject: RE: [bug #40818] "Add bsd-games"

From: Vitaliy Shatrov <[email-masked]>
Date: Thu, 06 Aug 2020 16:04:53 +0000

That is a "final" version. All games are works, the wrapper script works, and no unnecessary changes
were introduced to the games' code in the end. They're configured to search in the current dir, and the
wrapper (a bash script) cares about the files that should be copied from the Store, and cd's to the
BSD_GAMES_DIR (and ask the User to set this variable if it's unset). It's also can use HACKDIR if the game
started is "hack".

Regards, Vitaliy. Sent with [ProtonMail](https://protonmail.com) Secure Email.

From a6af7beba9d9feb5fdebf9f429c53cdad91b48bd Mon Sep 17 00:00:00 2001
From: Vitaliy Shatrov <[email-masked]>
Date: Thu, 6 Aug 2020 22:15:22 +0700
Subject: [PATCH] gnu: Add bsd-games.

* gnu/packages/games.scm a new variable.

New patches, taken from Arch and Debian:
* gnu/packages/patches/bsd-games-2.17-64bit.patch
* gnu/packages/patches/bsd-games-bad-ntohl-cast.patch
* gnu/packages/patches/bsd-games-gamescreen.h.patch
* gnu/packages/patches/bsd-games-getline.patch
* gnu/packages/patches/bsd-games-null-check.patch
* gnu/packages/patches/bsd-games-number.c-and-test.patch
* gnu/packages/patches/bsd-games-prevent-name-collisions.patch
* gnu/packages/patches/bsd-games-stdio.h.patch

New patches with our customizations (configure-config built after Arch's):
* gnu/packages/patches/bsd-games-add-configure-config.patch
* gnu/packages/patches/bsd-games-add-wrapper.patch
* gnu/packages/patches/bsd-games-dont-install-empty-files.patch
---
 gnu/packages/games.scm                        | 135 ++++++++++
 .../patches/bsd-games-2.17-64bit.patch        |  43 +++
 .../bsd-games-add-configure-config.patch      |  22 ++
 .../patches/bsd-games-add-wrapper.patch       | 251 ++++++++++++++++++
 .../patches/bsd-games-bad-ntohl-cast.patch    |  22 ++
 .../bsd-games-dont-install-empty-files.patch  |  87 ++++++
 .../patches/bsd-games-gamescreen.h.patch      |  14 +
 gnu/packages/patches/bsd-games-getline.patch  | 194 ++++++++++++++
 .../patches/bsd-games-null-check.patch        |  24 ++
 .../patches/bsd-games-number.c-and-test.patch | 183 +++++++++++++
 .../bsd-games-prevent-name-collisions.patch   |  13 +
 gnu/packages/patches/bsd-games-stdio.h.patch  |  14 +
 12 files changed, 1002 insertions(+)
 create mode 100644 gnu/packages/patches/bsd-games-2.17-64bit.patch
 create mode 100644 gnu/packages/patches/bsd-games-add-configure-config.patch
 create mode 100644 gnu/packages/patches/bsd-games-add-wrapper.patch
 create mode 100644 gnu/packages/patches/bsd-games-bad-ntohl-cast.patch
 create mode 100644 gnu/packages/patches/bsd-games-dont-install-empty-files.patch
 create mode 100644 gnu/packages/patches/bsd-games-gamescreen.h.patch
 create mode 100644 gnu/packages/patches/bsd-games-getline.patch
 create mode 100644 gnu/packages/patches/bsd-games-null-check.patch
 create mode 100644 gnu/packages/patches/bsd-games-number.c-and-test.patch
 create mode 100644 gnu/packages/patches/bsd-games-prevent-name-collisions.patch
 create mode 100644 gnu/packages/patches/bsd-games-stdio.h.patch

diff --git a/gnu/packages/games.scm b/gnu/packages/games.scm
index 0f79f5eeba..bb87740b64 100644
--- a/gnu/packages/games.scm
+++ b/gnu/packages/games.scm
@@ -115,6 +115,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)
@@ -584,6 +585,140 @@ 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
+     "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..67e64157f3
--- /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
-- 
2.28.0