Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package bs for openSUSE:Factory checked in 
at 2026-10-21 21:02:30
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/bs (Old)
 and      /work/SRC/openSUSE:Factory/.bs.new.2252680 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "bs"

Wed Oct 21 21:02:30 2026 rev:4 rq:1386896 version:2.15

Changes:
--------
--- /work/SRC/openSUSE:Factory/bs/bs.changes    2025-03-12 15:27:34.975128358 
+0100
+++ /work/SRC/openSUSE:Factory/.bs.new.2252680/bs.changes       2026-10-21 
21:03:38.638544883 +0200
@@ -1,0 +2,21 @@
+Sun Oct 18 09:20:28 UTC 2026 - Martin Pluskal <[email protected]>
+
+- Update to 2.15:
+  * 2.14: fix stack buffer overflow on long usernames: the
+    login name is now truncated into a LOGIN_NAME_MAX buffer
+    instead of strcpy into a 40-byte array
+  * 2.15: upstream packaging fixes: install honors
+    PREFIX/BINDIR/MANDIR, man page is built from source with
+    asciidoctor instead of shipping a prebuilt one
+  * Fully spellchecked manual page and assorted
+    undefined-behavior fixes (curses/mouse handling, character
+    classification, computer-AI state reset on new game)
+- Add bs-fix-install-paths.patch: install the binary into BINDIR
+  instead of MANDIR and honor DESTDIR in uninstall
+- Add bs-fix-gcc15-errors.patch: fix -Wincompatible-pointer-types
+  errors with GCC 14 and later
+- Spec cleanup: drop Group tag; add missing gcc, make and
+  rubygem(asciidoctor) BuildRequires; pass PREFIX at install time
+  and build with optflags; README renamed to README.adoc upstream
+
+-------------------------------------------------------------------

Old:
----
  bs-2.13.tar.gz

New:
----
  bs-2.15.tar.gz
  bs-fix-gcc15-errors.patch
  bs-fix-install-paths.patch

----------(New B)----------
  New:  instead of MANDIR and honor DESTDIR in uninstall
- Add bs-fix-gcc15-errors.patch: fix -Wincompatible-pointer-types
  errors with GCC 14 and later
  New:    classification, computer-AI state reset on new game)
- Add bs-fix-install-paths.patch: install the binary into BINDIR
  instead of MANDIR and honor DESTDIR in uninstall
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ bs.spec ++++++
--- /var/tmp/diff_new_pack.hghUF6/_old  2026-10-21 21:03:39.383576510 +0200
+++ /var/tmp/diff_new_pack.hghUF6/_new  2026-10-21 21:03:39.384576553 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package bs
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
 # Copyright (c) 2025 Andreas Stieger <[email protected]>
 #
 # All modifications and additions to the file contributed by third parties
@@ -18,16 +18,21 @@
 
 
 Name:           bs
-Version:        2.13
+Version:        2.15
 Release:        0
 Summary:        Battleships solitaire game with a color interface
 License:        BSD-2-Clause
-Group:          Amusements/Games/Strategy/Turn Based
 URL:            http://www.catb.org/~esr/bs/
 Source0:        http://www.catb.org/~esr/%{name}/%{name}-%{version}.tar.gz
+Patch0:         bs-fix-install-paths.patch
+Patch1:         bs-fix-gcc15-errors.patch
+BuildRequires:  %{rubygem asciidoctor}
+BuildRequires:  gcc
 BuildRequires:  hicolor-icon-theme
-BuildRequires:  ncurses-devel
+BuildRequires:  make
+BuildRequires:  pkgconfig
 BuildRequires:  update-desktop-files
+BuildRequires:  pkgconfig(ncurses)
 
 %description
 The classic game of Battleships against the computer. Uses character-cell
@@ -38,15 +43,15 @@
 %autosetup -p1
 
 %build
-%make_build
+%make_build CFLAGS="%{optflags}"
 
 %install
-%make_install
+%make_install PREFIX=%{_prefix}
 %suse_update_desktop_file %{name}
 
 %files
 %license COPYING
-%doc NEWS.adoc README
+%doc NEWS.adoc README.adoc
 %{_bindir}/%{name}
 %{_mandir}/man6/%{name}.6%{?ext_man}
 %{_datadir}/appdata/

++++++ bs-2.13.tar.gz -> bs-2.15.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bs-2.13/Makefile new/bs-2.15/Makefile
--- old/bs-2.13/Makefile        2024-02-13 19:21:24.000000000 +0100
+++ new/bs-2.15/Makefile        2026-03-27 11:43:30.000000000 +0100
@@ -3,15 +3,14 @@
 # SPDX-License-Identifier: BSD-2-Clause
 # SPDX-FileCopyrightText: (C) Eric S. Raymond <[email protected]>
 
-VERSION=$(shell sed -n <NEWS.adoc '/::/s/^\([0-9][^:]*\).*/\1/p' | head -1)
+PREFIX      ?= /usr/local
+BINDIR      ?= $(PREFIX)/bin
+DATADIR     ?= $(PREFIX)/share
+MANDIR      ?= $(DATADIR)/man
 
-CC = gcc
+VERSION=$(shell sed -n <NEWS.adoc '/::/s/^\([0-9][^:]*\).*/\1/p' | head -1)
 
-# DESTDIR support
-DESTDIR = 
-
-bs: bs.c
-       $(CC) $(CFLAGS) -DVERSION='"$(VERSION)"' -o bs bs.c -lncurses
+# Rules
 
 # Note: to suppress the footers with timestamps being generated in HTML,
 # we use "-a nofooter".
@@ -24,35 +23,56 @@
 .adoc.html:
        asciidoctor -D. -a nofooter -a webfonts! $<
 
+.PHONY: add clean reflow cppcheck spellcheck
+.PHONY: install uninstall version dist release refresh
+
+# Build
+
+bs: bs.c
+       $(CC) $(CFLAGS) -DVERSION='"$(VERSION)"' -o bs bs.c -lncurses
+
 clean:
        rm -f bs bs.6 bs*.tar.gz bs*.rpm *~ *.html
 
+# Validate
+
 reflow:
        @clang-format --style="{IndentWidth: 8, UseTab: ForIndentation}" -i 
$$(find . -name "*.[ch]")
 
 cppcheck:
-       cppcheck --quiet --template gcc --enable=all 
--suppress=missingIncludeSystem bs.c
+       @cppcheck --quiet --template=gcc --enable=all --suppress=checkersReport 
--suppress=missingIncludeSystem --suppress=redundantContinue 
--suppress=knownConditionTrueFalse bs.c
+
+spellcheck:
+       @spellcheck bs.adoc
+
+# Install/uninstall
 
 # Note: does not install desktop file.
 install: bs.6 uninstall
-       install -m 0755 -d $(DESTDIR)/usr/bin
-       install -m 0755 -d $(DESTDIR)/usr/share/man/man6
+       install -m 0755 -d $(DESTDIR)$(BINDIR)
+       install -m 0755 -d $(DESTDIR)$(MANDIR)/man6
        install -m 0755 -d $(DESTDIR)//usr/share/applications/
        install -m 0755 -d $(DESTDIR)/usr/share/icons/hicolor/32x32/apps/
        install -m 0755 -d $(DESTDIR)/usr/share/appdata
-       install -m 0755 bs $(DESTDIR)/usr/bin/
-       install -m 0644 bs.6 $(DESTDIR)/usr/share/man/man6/
+       install -m 0755 bs $(DESTDIR)$(MANDIR)/
+       install -m 0644 bs.6 $(DESTDIR)$(MANDIR)/man6/
        install -m 0644 bs.desktop $(DESTDIR)/usr/share/applications/
        install -m 0644 battleship.png 
$(DESTDIR)/usr/share/icons/hicolor/32x32/apps/
        install -m 0644 bs.adoc $(DESTDIR)/usr/share/appdata/
 
 uninstall:
-       rm -f /usr/bin/bs /usr/share/man/man6/bs.6
+       rm -f $(BINDIR)/bs /usr/share/man/man6/bs.6
+
+# Export
 
-SOURCES = README COPYING NEWS.adoc control bs.c Makefile bs.adoc 
battleship.png bs.desktop
+SOURCES = README.adoc COPYING NEWS.adoc control bs.c Makefile bs.adoc 
battleship.png bs.desktop
 
-bs-$(VERSION).tar.gz: $(SOURCES) bs.6
-       tar --transform='s:^:bs-$(VERSION)/:' --show-transformed-names -cvzf 
bs-$(VERSION).tar.gz $(SOURCES) bs.6
+bs-$(VERSION).tar.gz: $(SOURCES)
+       mkdir bs-$(VERSION)
+       cp -r $(SOURCES) bs-$(VERSION)
+       tar -czf bs-$(VERSION).tar.gz bs-$(VERSION)
+       rm -fr bs-$(VERSION)
+       ls -l bs-$(VERSION).tar.gz
 
 dist: bs-$(VERSION).tar.gz
 
@@ -62,3 +82,4 @@
 refresh: bs.html
        shipper -N -w version=$(VERSION) | sh -e -x
 
+# end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bs-2.13/NEWS.adoc new/bs-2.15/NEWS.adoc
--- old/bs-2.13/NEWS.adoc       2024-02-13 19:21:24.000000000 +0100
+++ new/bs-2.15/NEWS.adoc       2026-03-27 11:43:30.000000000 +0100
@@ -1,5 +1,13 @@
 = bs project news =
 
+2.15: 2026-03-27::
+  Packaging fixes.
+
+2.14: 2026-02-06::
+  Fully spellchecked manual page
+  Prevent buffer overflow on long usernames.
+  Various small changes to avoid undefined behavior.
+
 2.13: 2024-02-13::
   Code cleanup - remove pre-SuSv2 cruft.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bs-2.13/README new/bs-2.15/README
--- old/bs-2.13/README  2024-02-13 19:21:24.000000000 +0100
+++ new/bs-2.15/README  1970-01-01 01:00:00.000000000 +0100
@@ -1,38 +0,0 @@
-                               BS 2.0
-
-Battleships is an intrinsically silly game, but I couldn't resist fixing this
-sucker. It now has a purely visual interface (you place ships and call for
-shots by moving the cursor around the board using the standard yuhjklbn keys).
-
-The default game now disallows placement of ships so that they touch. A new
--c option is available to force the older behavior.
-
-I also removed the `seemiss' option (now always on) and `ask' (which is only
-useful for cheating). And I ifdefed out the ditsy opening screen; if you want
-it back, compile with -DPENGUIN. One strike against featureitis...
-
-This was probably a waste of a day or so. But what the hack -- rewriting the
-strategy robot as an FSM was fun, and maybe the interface will set a good
-example for the next guy.
-
-<*** FLAME ON ***>
-
-People who write curses games that require you to enter #@!!#$! coordinates
-rather than doing the natural pick-and-place with cursor motions should be
-stuffed in suits and condemned to write COBOL for the rest of their days...
-
-<*** FLAME OFF ***>
-
-O.K., I feel better now that I've got that off my chest...
-
-November 1993: I've added function key support, and ANSI/POSIXized the code.
-
-December 2012: This is ancient code now, mainly interesting as a
-historical document of what primitive computer games looked like in
-the 1980s - it dates from 1986, I rewrote it in 1989.  The PNG icon in
-the distribution is much later; thanks to Tor Gjerde who seems to have
-built it for use with FVWM.
-
-                                       Eric S. Raymond
-                                       [email protected]
-                               (WWW: http://www.catb.org/~esr/)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bs-2.13/README.adoc new/bs-2.15/README.adoc
--- old/bs-2.13/README.adoc     1970-01-01 01:00:00.000000000 +0100
+++ new/bs-2.15/README.adoc     2026-03-27 11:43:30.000000000 +0100
@@ -0,0 +1,39 @@
+                               BS 2.0
+
+Battleships is an intrinsically silly game, but I couldn't resist fixing this
+sucker. It now has a purely visual interface (you place ships and call for
+shots by moving the cursor around the board using the standard yuhjklbn keys).
+
+The default game now disallows placement of ships so that they touch. A new
+-c option is available to force the older behavior.
+
+I also removed the `seemiss' option (now always on) and `ask' (which is only
+useful for cheating). And I ifdefed out the ditsy opening screen; if you want
+it back, compile with -DPENGUIN. One strike against featureitis...
+
+This was probably a waste of a day or so. But what the hack -- rewriting the
+strategy robot as an FSM was fun, and maybe the interface will set a good
+example for the next guy.
+
+*** FLAME ON ***
+
+People who write curses games that require you to enter #@!!#$! coordinates
+rather than doing the natural pick-and-place with cursor motions should be
+stuffed in suits and condemned to write COBOL for the rest of their days...
+
+*** FLAME OFF ***
+
+O.K., I feel better now that I've got that off my chest...
+
+November 1993: I've added function key support, and ANSI/POSIXized the code.
+
+December 2012: This is ancient code now, mainly interesting as a
+historical document of what primitive computer games looked like in
+the 1980s - it dates from 1986, I rewrote it in 1989.  The PNG icon in
+the distribution is much later; thanks to Tor Gjerde who seems to have
+built it for use with FVWM.
+
+This code is commonly packaged as "battleships".
+
+image:https://repology.org/badge/vertical-allrepos/battleships.svg[Repology
+package status]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bs-2.13/bs.6 new/bs-2.15/bs.6
--- old/bs-2.13/bs.6    2024-02-13 19:06:06.000000000 +0100
+++ new/bs-2.15/bs.6    1970-01-01 01:00:00.000000000 +0100
@@ -1,95 +0,0 @@
-'\" t
-.\"     Title: bluemoon
-.\"    Author: [see the "AUTHOR(S)" section]
-.\" Generator: Asciidoctor 2.0.16
-.\"      Date: 2024-02-13
-.\"    Manual: \ \&
-.\"    Source: \ \&
-.\"  Language: English
-.\"
-.TH "BS" "6" "2024-02-13" "\ \&" "\ \&"
-.ie \n(.g .ds Aq \(aq
-.el       .ds Aq '
-.ss \n[.ss] 0
-.nh
-.ad l
-.de URL
-\fI\\$2\fP <\\$1>\\$3
-..
-.als MTO URL
-.if \n[.g] \{\
-.  mso www.tmac
-.  am URL
-.    ad l
-.  .
-.  am MTO
-.    ad l
-.  .
-.  LINKSTYLE blue R < >
-.\}
-.SH "NAME"
-bs \- the Battleships game
-.SH "SYNOPSIS"
-.sp
-\fBbs\fP [\-b | \-s ]  [ \-c ] [\-v]
-.SH "DESCRIPTION"
-.sp
-This program allows you to play the familiar Battleships game
-against the computer on a 10x10 board. The interface is visual and
-largely self\-explanatory; you place your ships and pick your shots by
-moving the cursor around the board with the rogue/hack motion keys
-hjklyubn. Your arrow keys will also work.
-.sp
-Note that when selecting a ship to place, you must type the
-capital letter (these are, after all, capital ships). During ship
-placement, the "r" command may be used to ignore the current position
-and randomly place your currently selected ship. The "R" command will
-place all remaining ships randomly. The ^L command (form feed, ASCII
-12) will force a screen redraw).
-.sp
-The command\-line arguments control game modes.
-.sp
-\-b
-.RS 4
-selects a `blitz\*(Aq variant
-.RE
-.sp
-\-s
-.RS 4
-selects a `salvo\*(Aq variant
-.RE
-.sp
-\-c
-.RS 4
-permits ships to be placed adjacently
-.RE
-.sp
-\-v reports the program version
-.sp
-The "blitz" variant allows a side to shoot for as long as it continues to
-score hits.
-.sp
-The "salvo" game allows a player one shot per turn for each of
-his/her ships still afloat.  This puts a premium scoring hits early
-and knocking out some ships and also makes much harder the situation
-where you face a superior force with only your PT\-boat.
-.sp
-Normally, ships must be separated by at least one square of open
-water. The \-c option disables this check and allows them to
-close\-pack.
-.sp
-The algorithm the computer uses once it has found a ship to sink
-is provably optimal.  The dispersion criterion for the random\-fire
-algorithm may not be.
-.SH "AUTHORS"
-.sp
-Originally written by one Bruce Holloway in 1986. Salvo mode added by
-Chuck A.  DeGaul (cbosgd!cad). Visual user interface, "closepack"
-option, code rewrite and manual page by Eric S. Raymond
-\c
-.MTO "esr\(atsnark.thyrsus.com" "" ""
-August 1989.  Keypad support and ANSI/POSIX
-conformance, November \*(Aq93. See \c
-.URL "http://www.catb.org/~esr/"; "" ""
-for updates,
-also other software and resources by ESR.
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bs-2.13/bs.adoc new/bs-2.15/bs.adoc
--- old/bs-2.13/bs.adoc 2024-02-13 18:25:59.000000000 +0100
+++ new/bs-2.15/bs.adoc 2026-03-27 11:43:30.000000000 +0100
@@ -1,4 +1,5 @@
-= bluemoon(6) =
+// spellcheck: add bs hjklyubn DeGaul cbosgd closepack POSIX
+= bs(6) =
 :doctype: manpage
 // SPDX-FileCopyrightText: (C) Eric S. Raymond <[email protected]>
 // SPDX-License-Identifier: BSD-2-Clause
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bs-2.13/bs.c new/bs-2.15/bs.c
--- old/bs-2.13/bs.c    2024-02-13 19:21:24.000000000 +0100
+++ new/bs-2.15/bs.c    2026-03-27 11:43:30.000000000 +0100
@@ -11,6 +11,7 @@
 #include <ctype.h>
 #include <curses.h>
 #include <signal.h>
+#include <limits.h>
 #include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
@@ -82,7 +83,7 @@
 static const char destroy[] = "Destroyer";
 static const char ptboat[] = "PT Boat";
 
-static char name[40];
+static char name[LOGIN_NAME_MAX + 1];
 static const char dftname[] = "stranger";
 
 /* direction constants */
@@ -112,6 +113,7 @@
 } ship_t;
 
 static bool checkplace(int b, ship_t *ss, int vis);
+static void reset_ai_state(void);
 
 static ship_t plyship[SHIPTYPES] = {
     {carrier, 0, 'A', 5}, {battle, 0, 'B', 4}, {destroy, 0, 'D', 3},
@@ -124,8 +126,8 @@
 };
 
 /* "Hits" board, and main board. */
-static char hits[2][BWIDTH][BDEPTH];
-static char board[2][BWIDTH][BDEPTH];
+static char unsigned hits[2][BWIDTH][BDEPTH];
+static char unsigned board[2][BWIDTH][BDEPTH];
 
 static int turn;                   /* 0=player, 1=computer */
 static int plywon = 0, cpuwon = 0; /* How many games has each won? */
@@ -134,6 +136,26 @@
 
 #define PR (void)addstr
 
+/* computer AI state (reset each game) */
+#define S_MISS 0
+#define S_HIT 1
+#define S_SUNK -1
+
+#define POSSIBLE(x, y) (ONBOARD(x, y) && !hits[COMPUTER][x][y])
+#define RANDOM_FIRE 0
+#define RANDOM_HIT 1
+#define HUNT_DIRECT 2
+#define FIRST_PASS 3
+#define REVERSE_JUMP 4
+#define SECOND_PASS 5
+
+static int rf_turncount;
+static int rf_srchstep = BEGINSTEP;
+static int rf_huntoffs;
+static int cpu_next = RANDOM_FIRE;
+static bool cpu_used[4];
+static ship_t cpu_ts;
+
 static void uninitgame(int sig GCC_UNUSED)
 /* end the game, either normally or due to signal */
 {
@@ -171,23 +193,24 @@
 }
 
 static void intro(void) {
-       char *tmpname;
+       const char *tmpname;
 
        srand((unsigned)(time(0L) +
                         getpid())); /* Kick the random number generator */
 
        (void)signal(SIGINT, uninitgame);
-       (void)signal(SIGINT, uninitgame);
+       (void)signal(SIGHUP, uninitgame);
+       (void)signal(SIGTERM, uninitgame);
        (void)signal(SIGABRT, uninitgame); /* for assert(3) */
        if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) {
                (void)signal(SIGQUIT, uninitgame);
        }
 
        if ((tmpname = getlogin()) != 0) {
-               (void)strcpy(name, tmpname);
-               name[0] = toupper(name[0]);
+               (void)snprintf(name, sizeof(name), "%s", tmpname);
+               name[0] = toupper((unsigned char)name[0]);
        } else {
-               (void)strcpy(name, dftname);
+               (void)snprintf(name, sizeof(name), "%s", dftname);
        }
 
        (void)initscr();
@@ -238,6 +261,15 @@
 #endif /* NCURSES_MOUSE_VERSION*/
 }
 
+static void reset_ai_state(void) {
+       rf_turncount = 0;
+       rf_srchstep = BEGINSTEP;
+       rf_huntoffs = 0;
+       cpu_next = RANDOM_FIRE;
+       memset(cpu_used, 0, sizeof(cpu_used));
+       memset(&cpu_ts, 0, sizeof(cpu_ts));
+}
+
 /* VARARGS1 */
 static void prompt(int n, NCURSES_CONST char *f, const char *s) {
        /* print a message at the prompt line */
@@ -276,11 +308,18 @@
 
 static void randomplace(int b, ship_t *ss) {
        /* generate a valid random ship placement into px,py */
-
        do {
+               int maxx, maxy;
+
                ss->dir = rnd(2) ? E : S;
-               ss->x = rnd(BWIDTH - (ss->dir == E ? ss->length : 0));
-               ss->y = rnd(BDEPTH - (ss->dir == S ? ss->length : 0));
+               maxx = BWIDTH - (ss->dir == E ? ss->length : 0);
+               maxy = BDEPTH - (ss->dir == S ? ss->length : 0);
+               if (maxx < 0 || maxy < 0) {
+                       error("Ship is too large for the board");
+                       exit(EXIT_FAILURE);
+               }
+               ss->x = rnd(maxx + 1);
+               ss->y = rnd(maxy + 1);
        } while (!checkplace(b, ss, false));
 }
 
@@ -293,8 +332,9 @@
        (void)move(PROMPTLINE + 2, 0);
        announceopts();
 
-       memset(board, 0, sizeof(char) * BWIDTH * BDEPTH * 2);
-       memset(hits, 0, sizeof(char) * BWIDTH * BDEPTH * 2);
+       memset(board, 0, sizeof(board));
+       memset(hits, 0, sizeof(hits));
+       reset_ai_state();
        for (i = 0; i < SHIPTYPES; i++) {
                ss = cpuship + i;
 
@@ -397,7 +437,10 @@
                /* get a command letter */
                prompt(1, "Type one of [%s] to pick a ship.", docked + 1);
                do {
-                       c = toupper(getcoord(PLAYER));
+                       c = getcoord(PLAYER);
+                       if (c >= 0 && c <= UCHAR_MAX) {
+                               c = toupper((unsigned char)c);
+                       }
                } while (!strchr(docked, c));
 
                if (c == 'R') {
@@ -417,7 +460,7 @@
 
                do {
                        c = getch();
-               } while (!strchr("hjklrR", c) || c == FF);
+               } while (!strchr("hjklrR", c) && c != FF);
 
                if (c == FF) {
                        (void)clearok(stdscr, true);
@@ -594,12 +637,24 @@
                case KEY_MOUSE: {
                        MEVENT myevent;
 
-                       getmouse(&myevent);
+                       if (getmouse(&myevent) != OK) {
+                               continue;
+                       }
                        if (atcpu && myevent.y >= CY(0) &&
-                           myevent.y <= CY(BDEPTH) && myevent.x >= CX(0) &&
-                           myevent.x <= CX(BDEPTH)) {
+                           myevent.y <= CY(BDEPTH - 1) && myevent.x >= CX(0) &&
+                           myevent.x <= CX(BWIDTH - 1)) {
                                curx = CXINV(myevent.x);
                                cury = CYINV(myevent.y);
+                               if (curx < 0) {
+                                       curx = 0;
+                               } else if (curx >= BWIDTH) {
+                                       curx = BWIDTH - 1;
+                               }
+                               if (cury < 0) {
+                                       cury = 0;
+                               } else if (cury >= BDEPTH) {
+                                       cury = BDEPTH - 1;
+                               }
                                return (' ');
                        } else {
                                beep();
@@ -653,7 +708,7 @@
        return (collide);
 }
 
-static bool checkplace(int b, ship_t *ss, int vis) {
+static bool checkplace(int b, const ship_t *ss, int vis) {
        int l, xend, yend;
 
        /* first, check for board edges */
@@ -888,8 +943,8 @@
        (void)refresh();
        for (;;) {
                int ch = getch();
-               if (islower(ch)) {
-                       ch = toupper(ch);
+               if (ch >= 0 && ch <= UCHAR_MAX && islower((unsigned char)ch)) {
+                       ch = toupper((unsigned char)ch);
                }
                if (ch == CTRLC) {
                        uninitgame(0);
@@ -908,15 +963,12 @@
 static void randomfire(int *px, int *py) {
        /* random-fire routine -- implements simple diagonal-striping strategy
         */
-       static int turncount = 0;
-       static int srchstep = BEGINSTEP;
-       static int huntoffs; /* Offset on search strategy */
        int ypossible[BWIDTH * BDEPTH], xpossible[BWIDTH * BDEPTH], nposs;
        int ypreferred[BWIDTH * BDEPTH], xpreferred[BWIDTH * BDEPTH], npref;
        int x, y, i;
 
-       if (turncount++ == 0) {
-               huntoffs = rnd(srchstep);
+       if (rf_turncount++ == 0) {
+               rf_huntoffs = rnd(rf_srchstep);
        }
 
        /* first, list all possible moves */
@@ -927,8 +979,8 @@
                                xpossible[nposs] = x;
                                ypossible[nposs] = y;
                                nposs++;
-                               if (((x + huntoffs) % srchstep) !=
-                                   (y % srchstep)) {
+                               if (((x + rf_huntoffs) % rf_srchstep) !=
+                                   (y % rf_srchstep)) {
                                        xpreferred[npref] = x;
                                        ypreferred[npref] = y;
                                        npref++;
@@ -948,8 +1000,8 @@
                *px = xpossible[i];
                *py = ypossible[i];
 
-               if (srchstep > 1) {
-                       --srchstep;
+               if (rf_srchstep > 1) {
+                       --rf_srchstep;
                }
        } else {
                error("No moves possible?? Help!");
@@ -958,10 +1010,6 @@
        }
 }
 
-#define S_MISS 0
-#define S_HIT 1
-#define S_SUNK -1
-
 static int cpufire(int x, int y) {
        /* fire away at given location */
        bool hit, sunk;
@@ -991,7 +1039,10 @@
        attrset(0);
 #endif /* A_COLOR */
 
-       return ((hit ? (sunk ? S_SUNK : S_HIT) : S_MISS) ? true : false);
+       if (!hit) {
+               return S_MISS;
+       }
+       return sunk ? S_SUNK : S_HIT;
 }
 
 /*
@@ -1000,117 +1051,111 @@
  * between computer turns.
  */
 static bool cputurn(void) {
-#define POSSIBLE(x, y) (ONBOARD(x, y) && !hits[COMPUTER][x][y])
-#define RANDOM_FIRE 0
-#define RANDOM_HIT 1
-#define HUNT_DIRECT 2
-#define FIRST_PASS 3
-#define REVERSE_JUMP 4
-#define SECOND_PASS 5
-       static int next = RANDOM_FIRE;
-       static bool used[4];
-       static ship_t ts;
        int navail, x, y, d, n;
        int hit = S_MISS;
 
-       switch (next) {
+       switch (cpu_next) {
        case RANDOM_FIRE: /* last shot was random and missed */
        refire:
                randomfire(&x, &y);
                if (!(hit = cpufire(x, y))) {
-                       next = RANDOM_FIRE;
+                       cpu_next = RANDOM_FIRE;
                } else {
-                       ts.x = x;
-                       ts.y = y;
-                       ts.hits = 1;
-                       next = (hit == S_SUNK) ? RANDOM_FIRE : RANDOM_HIT;
+                       cpu_ts.x = x;
+                       cpu_ts.y = y;
+                       cpu_ts.hits = 1;
+                       cpu_next = (hit == S_SUNK) ? RANDOM_FIRE : RANDOM_HIT;
                }
                break;
 
        case RANDOM_HIT: /* last shot was random and hit */
-               used[E / 2] = used[S / 2] = used[W / 2] = used[N / 2] = false;
+               cpu_used[E / 2] = cpu_used[S / 2] = cpu_used[W / 2] =
+                   cpu_used[N / 2] = false;
                /* FALLTHROUGH */
 
        case HUNT_DIRECT: /* last shot hit, we're looking for ship's long axis
                           */
                for (d = navail = 0; d < 4; d++) {
-                       x = ts.x + xincr[d * 2];
-                       y = ts.y + yincr[d * 2];
-                       if (!used[d] && POSSIBLE(x, y)) {
+                       x = cpu_ts.x + xincr[d * 2];
+                       y = cpu_ts.y + yincr[d * 2];
+                       if (!cpu_used[d] && POSSIBLE(x, y)) {
                                navail++;
                        } else {
-                               used[d] = true;
+                               cpu_used[d] = true;
                        }
                }
                if (navail == 0) /* no valid places for shots adjacent... */ {
                        goto refire; /* ...so we must random-fire */
                } else {
-                       for (d = 0, n = rnd(navail) + 1; n; n--) {
-                               while (used[d]) {
-                                       d++;
+                               for (d = 0, n = rnd(navail); d < 4; d++) {
+                                       if (cpu_used[d]) {
+                                               continue;
+                                       }
+                                       if (n-- == 0) {
+                                               break;
                                }
                        }
 
-                       assert(d <= 4);
+                       assert(d < 4);
 
-                       used[d] = false;
-                       x = ts.x + xincr[d * 2];
-                       y = ts.y + yincr[d * 2];
+                       cpu_used[d] = false;
+                       x = cpu_ts.x + xincr[d * 2];
+                       y = cpu_ts.y + yincr[d * 2];
 
                        assert(POSSIBLE(x, y));
 
                        if (!(hit = cpufire(x, y))) {
-                               next = HUNT_DIRECT;
+                               cpu_next = HUNT_DIRECT;
                        } else {
-                               ts.x = x;
-                               ts.y = y;
-                               ts.dir = d * 2;
-                               ts.hits++;
-                               next =
+                               cpu_ts.x = x;
+                               cpu_ts.y = y;
+                               cpu_ts.dir = d * 2;
+                               cpu_ts.hits++;
+                               cpu_next =
                                    (hit == S_SUNK) ? RANDOM_FIRE : FIRST_PASS;
                        }
                }
                break;
 
        case FIRST_PASS: /* we have a start and a direction now */
-               x = ts.x + xincr[ts.dir];
-               y = ts.y + yincr[ts.dir];
+               x = cpu_ts.x + xincr[cpu_ts.dir];
+               y = cpu_ts.y + yincr[cpu_ts.dir];
                if (POSSIBLE(x, y) && (hit = cpufire(x, y))) {
-                       ts.x = x;
-                       ts.y = y;
-                       ts.hits++;
-                       next = (hit == S_SUNK) ? RANDOM_FIRE : FIRST_PASS;
+                       cpu_ts.x = x;
+                       cpu_ts.y = y;
+                       cpu_ts.hits++;
+                       cpu_next = (hit == S_SUNK) ? RANDOM_FIRE : FIRST_PASS;
                } else {
-                       next = REVERSE_JUMP;
+                       cpu_next = REVERSE_JUMP;
                }
                break;
 
        case REVERSE_JUMP: /* nail down the ship's other end */
-               d = ts.dir + 4;
-               x = ts.x + ts.hits * xincr[d];
-               y = ts.y + ts.hits * yincr[d];
+               d = cpu_ts.dir + 4;
+               x = cpu_ts.x + cpu_ts.hits * xincr[d];
+               y = cpu_ts.y + cpu_ts.hits * yincr[d];
                if (POSSIBLE(x, y) && (hit = cpufire(x, y))) {
-                       ts.x = x;
-                       ts.y = y;
-                       ts.dir = d;
-                       ts.hits++;
-                       next = (hit == S_SUNK) ? RANDOM_FIRE : SECOND_PASS;
+                       cpu_ts.x = x;
+                       cpu_ts.y = y;
+                       cpu_ts.dir = d;
+                       cpu_ts.hits++;
+                       cpu_next = (hit == S_SUNK) ? RANDOM_FIRE : SECOND_PASS;
                } else {
-                       next = RANDOM_FIRE;
+                       cpu_next = RANDOM_FIRE;
                }
                break;
 
        case SECOND_PASS: /* kill squares not caught on first pass */
-               x = ts.x + xincr[ts.dir];
-               y = ts.y + yincr[ts.dir];
+               x = cpu_ts.x + xincr[cpu_ts.dir];
+               y = cpu_ts.y + yincr[cpu_ts.dir];
                if (POSSIBLE(x, y) && (hit = cpufire(x, y))) {
-                       ts.x = x;
-                       ts.y = y;
-                       ts.hits++;
-                       next = (hit == S_SUNK) ? RANDOM_FIRE : SECOND_PASS;
+                       cpu_ts.x = x;
+                       cpu_ts.y = y;
+                       cpu_ts.hits++;
+                       cpu_next = (hit == S_SUNK) ? RANDOM_FIRE : SECOND_PASS;
                        break;
                } else {
-                       next = RANDOM_FIRE;
+                       cpu_next = RANDOM_FIRE;
                }
                break;
        }
@@ -1126,7 +1171,7 @@
 
 #ifdef DEBUG
        (void)mvprintw(PROMPTLINE + 2, 0, "New state %d, x=%d, y=%d, d=%d",
-                      next, x, y, d);
+                      cpu_next, x, y, d);
 #endif /* DEBUG */
        return ((hit) ? true : false);
 }
@@ -1165,7 +1210,7 @@
        return (sgetc("YN") == 'Y');
 }
 
-static void do_options(int c, char *op[]) {
+static void do_options(int c, const char *op[]) {
        if (c > 1) {
                register int i;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bs-2.13/control new/bs-2.15/control
--- old/bs-2.13/control 2024-02-01 17:47:40.000000000 +0100
+++ new/bs-2.15/control 2026-03-27 11:43:30.000000000 +0100
@@ -12,6 +12,8 @@
 
 Homepage: http://www.catb.org/~esr/bs
 
+XBS-Packaged-AsL battleships
+
 XBS-HTML-Target: index.html
 
 XBS-Repository-URL: https://gitlab.com/esr/bs
@@ -23,3 +25,5 @@
 #XBS-Project-Tags: Games/Entertainment
 
 XBS-VC-Tag-Template: %(version)s
+
+XBS-Validate: make spellcheck

++++++ bs-fix-gcc15-errors.patch ++++++
Fix build with GCC 14+ (incompatible-pointer-types is an error):
match the checkplace forward declaration to its const-qualified
definition, and take plain char * in do_options (called with argv).

Index: bs-2.15/bs.c
===================================================================
--- bs-2.15.orig/bs.c
+++ bs-2.15/bs.c
@@ -112,7 +112,7 @@
        bool placed;       /* has it been placed on the board? */
 } ship_t;

-static bool checkplace(int b, ship_t *ss, int vis);
+static bool checkplace(int b, const ship_t *ss, int vis);
 static void reset_ai_state(void);

 static ship_t plyship[SHIPTYPES] = {
@@ -1210,7 +1210,7 @@
        return (sgetc("YN") == 'Y');
 }

-static void do_options(int c, const char *op[]) {
+static void do_options(int c, char *op[]) {
        if (c > 1) {
                register int i;


++++++ bs-fix-install-paths.patch ++++++
Fix install locations in the 2.15 Makefile: the binary was installed
into MANDIR instead of BINDIR, and uninstall ignored DESTDIR.

Index: bs-2.15/Makefile
===================================================================
--- bs-2.15.orig/Makefile
+++ bs-2.15/Makefile
@@ -53,9 +53,9 @@ install: bs.6 uninstall
        install -m 0755 -d $(DESTDIR)/usr/share/icons/hicolor/32x32/apps/
        install -m 0755 -d $(DESTDIR)/usr/share/appdata
-       install -m 0755 bs $(DESTDIR)$(MANDIR)/
+       install -m 0755 bs $(DESTDIR)$(BINDIR)/
        install -m 0644 bs.6 $(DESTDIR)$(MANDIR)/man6/
        install -m 0644 bs.desktop $(DESTDIR)/usr/share/applications/
        install -m 0644 battleship.png 
$(DESTDIR)/usr/share/icons/hicolor/32x32/apps/
        install -m 0644 bs.adoc $(DESTDIR)/usr/share/appdata/

 uninstall:
-       rm -f $(BINDIR)/bs /usr/share/man/man6/bs.6
+       rm -f $(DESTDIR)$(BINDIR)/bs $(DESTDIR)/usr/share/man/man6/bs.6

 # Export

Reply via email to