]> git.cameronkatri.com Git - bsdgames-darwin.git/blobdiff - atc/log.c
Bump date for previous. Remove superfluous .Pp.
[bsdgames-darwin.git] / atc / log.c
index e9ea4309aa535b600dd7eb3e64979e8d1645713f..5f5d9bfecb4b6104cfa69c7c3c0da2e44d2f24cb 100644 (file)
--- a/atc/log.c
+++ b/atc/log.c
@@ -1,6 +1,8 @@
+/*     $NetBSD: log.c,v 1.12 2003/08/07 09:36:54 agc Exp $     */
+
 /*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * Ed James.
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
  *
  * For more info on this and all of my stuff, mail edjames@berkeley.edu.
  */
 
+#include <sys/cdefs.h>
 #ifndef lint
-/*static char sccsid[] = "from: @(#)log.c      5.7 (Berkeley) 10/30/90";*/
-static char rcsid[] = "$Id: log.c,v 1.2 1993/08/01 18:57:06 mycroft Exp $";
-#endif not lint
+#if 0
+static char sccsid[] = "@(#)log.c      8.1 (Berkeley) 5/31/93";
+#else
+__RCSID("$NetBSD: log.c,v 1.12 2003/08/07 09:36:54 agc Exp $");
+#endif
+#endif /* not lint */
 
 #include "include.h"
 #include "pathnames.h"
 
-compar(a, b)
-       SCORE   *a, *b;
+static FILE *score_fp;
+
+int
+compar(va, vb)
+       const void *va, *vb;
 {
+       const SCORE     *a, *b;
+
+       a = (const SCORE *)va;
+       b = (const SCORE *)vb;
        if (b->planes == a->planes)
                return (b->time - a->time);
        else
@@ -70,8 +79,9 @@ compar(a, b)
 #define MIN(t)         (((t) % SECAHOUR) / SECAMIN)
 #define SEC(t)         ((t) % SECAMIN)
 
-char   *
+const char     *
 timestr(t)
+       int t;
 {
        static char     s[80];
 
@@ -89,44 +99,69 @@ timestr(t)
        return (s);
 }
 
-log_score(list_em)
+void
+open_score_file()
 {
-       register int    i, fd, num_scores = 0, good, changed = 0, found = 0;
-       struct passwd   *pw;
-       FILE            *fp;
-       char            *cp, *index(), *rindex();
-       SCORE           score[100], thisscore;
-#ifdef SYSV
-       struct utsname  name;
-#endif
+       mode_t old_mask;
+       int score_fd;
+       int flags;
 
-       umask(0);
-       fd = open(_PATH_SCORE, O_CREAT|O_RDWR, 0644);
-       if (fd < 0) {
-               perror(_PATH_SCORE);
-               return (-1);
+       old_mask = umask(0);
+       score_fd = open(_PATH_SCORE, O_CREAT|O_RDWR, 0664);
+       umask(old_mask);
+       if (score_fd < 0) {
+               warn("open %s", _PATH_SCORE);
+               return;
        }
+       if (score_fd < 3)
+               exit(1);
+       /* Set the close-on-exec flag.  If this fails for any reason, quit
+        * rather than leave the score file open to tampering.  */
+       flags = fcntl(score_fd, F_GETFD);
+       if (flags < 0)
+               err(1, "fcntl F_GETFD");
+       flags |= FD_CLOEXEC;
+       if (fcntl(score_fd, F_SETFD, flags) == -1)
+               err(1, "fcntl F_SETFD");
        /*
         * This is done to take advantage of stdio, while still 
         * allowing a O_CREAT during the open(2) of the log file.
         */
-       fp = fdopen(fd, "r+");
-       if (fp == NULL) {
-               perror(_PATH_SCORE);
+       score_fp = fdopen(score_fd, "r+");
+       if (score_fp == NULL) {
+               warn("fdopen %s", _PATH_SCORE);
+               return;
+       }
+}
+
+int
+log_score(list_em)
+       int list_em;
+{
+       int             i, num_scores = 0, good, changed = 0, found = 0;
+       struct passwd   *pw;
+       char            *cp;
+       SCORE           score[100], thisscore;
+       struct utsname  name;
+       long            offset;
+
+       if (score_fp == NULL) {
+               warnx("no score file available");
                return (-1);
        }
+
 #ifdef BSD
-       if (flock(fileno(fp), LOCK_EX) < 0)
+       if (flock(fileno(score_fp), LOCK_EX) < 0)
 #endif
 #ifdef SYSV
-       while (lockf(fileno(fp), F_LOCK, 1) < 0)
+       while (lockf(fileno(score_fp), F_LOCK, 1) < 0)
 #endif
        {
-               perror("flock");
+               warn("flock %s", _PATH_SCORE);
                return (-1);
        }
        for (;;) {
-               good = fscanf(fp, "%s %s %s %d %d %d",
+               good = fscanf(score_fp, SCORE_SCANF_FMT,
                        score[num_scores].name, 
                        score[num_scores].host, 
                        score[num_scores].game,
@@ -140,22 +175,15 @@ log_score(list_em)
                if ((pw = (struct passwd *) getpwuid(getuid())) == NULL) {
                        fprintf(stderr, 
                                "getpwuid failed for uid %d.  Who are you?\n",
-                               getuid());
+                               (int)getuid());
                        return (-1);
                }
                strcpy(thisscore.name, pw->pw_name);
-#ifdef BSD
-               if (gethostname(thisscore.host, sizeof (thisscore.host)) < 0) {
-                       perror("gethostname");
-                       return (-1);
-               }
-#endif
-#ifdef SYSV
                uname(&name);
-               strcpy(thisscore.host, name.sysname);
-#endif
+               strncpy(thisscore.host, name.nodename, sizeof(thisscore.host)-1);
+               thisscore.host[sizeof(thisscore.host) - 1] = '\0';
 
-               cp = rindex(file, '/');
+               cp = strrchr(file, '/');
                if (cp == NULL) {
                        fprintf(stderr, "log: where's the '/' in %s?\n", file);
                        return (-1);
@@ -187,19 +215,19 @@ log_score(list_em)
                                if (thisscore.time > score[i].time) {
                                        if (num_scores < NUM_SCORES)
                                                num_scores++;
-                                       bcopy(&score[i],
-                                               &score[num_scores - 1], 
-                                               sizeof (score[i]));
-                                       bcopy(&thisscore, &score[i],
-                                               sizeof (score[i]));
+                                       memcpy(&score[num_scores - 1],
+                                              &score[i],
+                                              sizeof (score[i]));
+                                       memcpy(&score[i], &thisscore,
+                                              sizeof (score[i]));
                                        changed++;
                                        break;
                                }
                        }
                }
                if (!found && !changed && num_scores < NUM_SCORES) {
-                       bcopy(&thisscore, &score[num_scores], 
-                               sizeof (score[num_scores]));
+                       memcpy(&score[num_scores], &thisscore,
+                              sizeof (score[num_scores]));
                        num_scores++;
                        changed++;
                }
@@ -210,12 +238,23 @@ log_score(list_em)
                        else
                                puts("You made the top players list!");
                        qsort(score, num_scores, sizeof (*score), compar);
-                       rewind(fp);
+                       rewind(score_fp);
                        for (i = 0; i < num_scores; i++)
-                               fprintf(fp, "%s %s %s %d %d %d\n",
+                               fprintf(score_fp, "%s %s %s %d %d %d\n",
                                        score[i].name, score[i].host, 
                                        score[i].game, score[i].planes,
                                        score[i].time, score[i].real_time);
+                       fflush(score_fp);
+                       if (ferror(score_fp))
+                               warn("error writing %s", _PATH_SCORE);
+                       /* It is just possible that updating an entry could
+                        * have reduced the length of the file, so we
+                        * truncate it.  The seeks are required for stream/fd
+                        * synchronisation by POSIX.1.  */
+                       offset = ftell(score_fp);
+                       lseek(fileno(score_fp), 0, SEEK_SET);
+                       ftruncate(fileno(score_fp), offset);
+                       rewind(score_fp);
                } else {
                        if (found)
                                puts("You didn't beat your previous score.");
@@ -225,17 +264,17 @@ log_score(list_em)
                putchar('\n');
        }
 #ifdef BSD
-       flock(fileno(fp), LOCK_UN);
+       flock(fileno(score_fp), LOCK_UN);
 #endif
 #ifdef SYSV
        /* lock will evaporate upon close */
 #endif
-       fclose(fp);
+       fclose(score_fp);
        printf("%2s:  %-8s  %-8s  %-18s  %4s  %9s  %4s\n", "#", "name", "host", 
                "game", "time", "real time", "planes safe");
        puts("-------------------------------------------------------------------------------");
        for (i = 0; i < num_scores; i++) {
-               cp = index(score[i].host, '.');
+               cp = strchr(score[i].host, '.');
                if (cp != NULL)
                        *cp = '\0';
                printf("%2d:  %-8s  %-8s  %-18s  %4d  %9s  %4d\n", i + 1,
@@ -246,3 +285,11 @@ log_score(list_em)
        putchar('\n');
        return (0);
 }
+
+void
+log_score_quit(dummy)
+       int dummy __attribute__((__unused__));
+{
+       (void)log_score(0);
+       exit(0);
+}