Hi Theo, hope you are doing well! I did the changes as you instructed and now since the snscore() is so tiny we might just as well incorporate it into snake.c. There's not need for a separate file just for a function with a few lines.
Index: Makefile =================================================================== RCS file: /cvs/src/games/snake/Makefile,v retrieving revision 1.10 diff -u -p -u -r1.10 Makefile --- Makefile 24 Nov 2015 03:10:10 -0000 1.10 +++ Makefile 25 Nov 2015 17:47:37 -0000 @@ -2,13 +2,9 @@ # @(#)Makefile 8.1 (Berkeley) 5/31/93 PROG= snake -SRCS= snake.c snscore.c +SRCS= snake.c MAN= snake.6 DPADD= ${LIBM} ${LIBCURSES} LDADD= -lm -lcurses - -beforeinstall: - ${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} -m 664 /dev/null \ - ${DESTDIR}/var/games/snakerawscores .include <bsd.prog.mk> Index: snake.c =================================================================== RCS file: /cvs/src/games/snake/snake.c,v retrieving revision 1.16 diff -u -p -u -r1.16 snake.c --- snake.c 16 Nov 2014 04:49:49 -0000 1.16 +++ snake.c 25 Nov 2015 17:47:47 -0000 @@ -47,8 +47,8 @@ #include <curses.h> #include <err.h> #include <fcntl.h> +#include <limits.h> #include <math.h> -#include <pwd.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> @@ -57,8 +57,6 @@ #include <time.h> #include <unistd.h> -#include "pathnames.h" - #ifdef DEBUG #define cashvalue (loot-penalty)/25 #else @@ -96,8 +94,10 @@ int moves; int fast = 1; int rawscores; +char scorepath[PATH_MAX]; #ifdef LOGGING FILE *logfile; +char logpath[PATH_MAX]; #endif int lcnt, ccnt; /* user's idea of screen size */ @@ -134,18 +134,21 @@ main(int argc, char *argv[]) { int ch, i; struct sigaction sa; - gid_t gid; - /* don't create the score file if it doesn't exist. */ - rawscores = open(_PATH_RAWSCORES, O_RDWR, 0664); + if (pledge("stdio rpath wpath cpath tty", NULL) == -1) + err(1, "pledge"); + + if (!getenv("HOME")) + return; + snprintf(scorepath, sizeof(scorepath), "%s/%s", getenv("HOME"), + ".snakerawscores"); + rawscores = open(scorepath, O_RDWR | O_CREAT, 0644); #ifdef LOGGING - logfile = fopen(_PATH_LOGFILE, "a"); + snprintf(logpath, sizeof(logpath), "%s/%s", getenv("HOME"), + ".snake.log"); + logfile = fopen(logpath, "a"); #endif - /* revoke privs */ - gid = getgid(); - setresgid(gid, gid, gid); - while ((ch = getopt(argc, argv, "hl:stw:")) != -1) switch ((char)ch) { case 'w': /* width */ @@ -495,7 +498,6 @@ post(int iscore, int flag) { short score = iscore; short oldbest = 0; - uid_t uid = getuid(); /* I want to printf() the scores for terms that clear on endwin(), * but this routine also gets called with flag == 0 to see if @@ -504,22 +506,21 @@ post(int iscore, int flag) */ if (rawscores == -1) { if (flag) - warnx("Can't open score file %s", _PATH_RAWSCORES); + warnx("Can't open score file %s", scorepath); return(1); } /* Figure out what happened in the past */ - lseek(rawscores, uid * sizeof(short), SEEK_SET); + lseek(rawscores, 0, SEEK_SET); read(rawscores, &oldbest, sizeof(short)); if (!flag) return (score > oldbest ? 1 : 0); /* Update this jokers best */ if (score > oldbest) { - lseek(rawscores, uid * sizeof(short), SEEK_SET); + lseek(rawscores, 0, SEEK_SET); write(rawscores, &score, sizeof(short)); printf("\nYou bettered your previous best of $%d\n", oldbest); - } else - printf("\nYour best to date is $%d\n", oldbest); + } fsync(rawscores); /* See if we have a new champ */ @@ -922,6 +923,31 @@ void length(int num) { printf("You made %d moves.\n", num); +} + +void +snscore(int fd, int topn) +{ + short score; + char *name; + + if (fd < 0) { + fd = open(scorepath, O_RDONLY, 0); + if (fd < 0) + errx(1, "Couldn't open raw scorefile"); + } + + lseek(fd, 0, SEEK_SET); + /* read(fd, &whoallbest, sizeof(uid_t)); + * read(fd, &allbest, sizeof(short)); SCOREFILE FORMAT CHANGE + */ + if (read(fd, &score, sizeof(short)) == 0) + errx(1, "Raw scorefile is empty"); + + name = getlogin(); + + printf("%sSnake scores to date:\n", topn > 0 ? "Top " : ""); + printf("$%d\t%s\n", score, name); } #ifdef LOGGING Index: snscore.c =================================================================== RCS file: /cvs/src/games/snake/snscore.c,v retrieving revision 1.11 diff -u -p -u -r1.11 snscore.c --- snscore.c 18 Nov 2014 20:51:00 -0000 1.11 +++ snscore.c 25 Nov 2015 17:48:24 -0000 @@ -1,115 +0,0 @@ -/* $OpenBSD: snscore.c,v 1.11 2014/11/18 20:51:00 krw Exp $ */ -/* $NetBSD: snscore.c,v 1.5 1995/04/24 12:25:43 cgd Exp $ */ - -/* - * Copyright (c) 1980, 1993 - * The Regents of the University of California. 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. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. - */ - -#include <sys/types.h> -#include <err.h> -#include <fcntl.h> -#include <pwd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include "pathnames.h" - -#define MAXPLAYERS 256 - -struct player { - uid_t uids; - short scores; - char *name; -} players[MAXPLAYERS], temp; - -void -snscore(int fd, int topn) -{ - uid_t uid; - short score; - int noplayers; - int i, j, notsorted; - char *q; - struct passwd *p; - - if (fd < 0) { - fd = open(_PATH_RAWSCORES, O_RDONLY, 0); - if (fd < 0) - errx(1, "Couldn't open raw scorefile"); - } - - lseek(fd, 0, SEEK_SET); - printf("%sSnake scores to date:\n", topn > 0 ? "Top " : ""); - /* read(fd, &whoallbest, sizeof(uid_t)); - * read(fd, &allbest, sizeof(short)); SCOREFILE FORMAT CHANGE - */ - noplayers = 0; - for (uid = 0; ; uid++) { - if (read(fd, &score, sizeof(short)) == 0) - break; - if (score > 0) { - if (noplayers >= MAXPLAYERS) - errx(2, "Too many entries in scorefile!"); - players[noplayers].uids = uid; - players[noplayers].scores = score; - p = getpwuid(uid); - if (p == NULL) - continue; - q = p -> pw_name; - if ((players[noplayers].name = strdup(q)) == NULL) - err(1, "strdup"); - - noplayers++; - } - } - - /* bubble sort scores */ - for (notsorted = 1; notsorted; ) { - notsorted = 0; - for (i = 0; i < noplayers - 1; i++) - if (players[i].scores < players[i + 1].scores) { - temp = players[i]; - players[i] = players[i + 1]; - players[i + 1] = temp; - notsorted++; - } - } - - if ((topn > 0) && (topn < noplayers)) - noplayers = topn; - j = 1; - for (i = 0; i < noplayers; i++) { - printf("%d:\t$%d\t%s\n", j, players[i].scores, players[i].name); - if (i < noplayers - 1 && - players[i].scores > players[i + 1].scores) - j = i + 2; - } - if (noplayers == 0) - printf("None.\n"); -} Index: snake.6 =================================================================== RCS file: /cvs/src/games/snake/snake.6,v retrieving revision 1.11 diff -u -p -u -r1.11 snake.6 --- snake.6 13 Nov 2009 21:50:12 -0000 1.11 +++ snake.6 25 Nov 2015 17:48:30 -0000 @@ -115,10 +115,10 @@ To see who wastes time playing snake, ru .Nm snake .Fl s . .Sh FILES -.Bl -tag -width /var/games/snakerawscores -compact -.It Pa /var/games/snakerawscores +.Bl -tag -width $HOME/.snakerawscores -compact +.It Pa $HOME/.snakerawscores database of personal bests -.\".It Pa /var/games/snake.log +.\".It Pa $HOME/.snake.log .\"log of games played .El .Sh BUGS Index: pathnames.h =================================================================== RCS file: /cvs/src/games/snake/pathnames.h,v retrieving revision 1.2 diff -u -p -u -r1.2 pathnames.h --- pathnames.h 3 Jun 2003 03:01:41 -0000 1.2 +++ pathnames.h 25 Nov 2015 17:48:36 -0000 @@ -1,38 +0,0 @@ -/* $OpenBSD: pathnames.h,v 1.2 2003/06/03 03:01:41 millert Exp $ */ -/* $NetBSD: pathnames.h,v 1.3 1995/04/22 08:34:33 cgd Exp $ */ - -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. 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. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. - * - * @(#)pathnames.h 8.1 (Berkeley) 5/31/93 - */ - -#define _PATH_RAWSCORES "/var/games/snakerawscores" -#ifdef LOGGING -#define _PATH_LOGFILE "/var/games/snake.log" -#endif On 17:05 Wed 25 Nov , Theo Buehler wrote: > On Wed, Nov 25, 2015 at 03:28:55PM +0000, Ricardo Mestre wrote: > > First open(2) operation must be changed to O_RDWR|O_CREAT since the file is > > no > > longer copied to the location like it was in Makefile and now needs to be > > created if it doesn't exist. > > I agree with that. > > > Remove one else when exiting the game stating "your best" since it will show > > right afterwards the top score and since there will only be 1 record there's > > no point in showing the same value twice. > > > > Remove a couple of loops to show the top score since now there's only 1 > > record > > to be displayed. > > If you're not going to maintain a list of high scores of the user, you > could still simplify snscore() further: The score file will just > contain the user's score as a short, so you could get the user name > using getlogin(2) instead of doing getuid() getpwuid(), etc. > Keeping the struct player also seems unnecessary. > > > As a bonus it's also pledged since the beginning with "stdio rpath wpath > > cpath > > tty" due to having to read/write/create the score file and to perform > > windows > > operations with curses(3). > > The pledge is correct. > > > Question! Should the LOGGING facility be kept? At least it's commented out > > in > > the manpage, although I change the log file path there anyway. > > I have no opinion on that. >