Another thing as well, maybe char *name for getlogin(2) could/should be declared as char name[LOGIN_NAME_MAX]?
On 25/11/2015 18:00, Ricardo Mestre wrote: > 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. >>