annotate highscore.c @ 4:aec74ae4d6e5 version-2

Fix the logic checking whether a generated board is playable
author Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
date Fri, 24 Oct 2014 17:12:12 +0200
parents a9a7ad180c3b
children 4f6bf50dbc4a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
1 /*
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
2 * Copyright (C) 2014 Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
3 *
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
4 * Permission is hereby granted, free of charge, to any person obtaining
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
5 * a copy of this software and associated documentation files (the
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
6 * "Software"), to deal in the Software without restriction, including
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
7 * without limitation the rights to use, copy, modify, merge, publish,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
8 * distribute, sublicense, and/or sell copies of the Software, and to
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
9 * permit persons to whom the Software is furnished to do so, subject to
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
10 * the following conditions:
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
11 *
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
12 * The above copyright notice and this permission notice shall be included
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
13 * in all copies or substantial portions of the Software.
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
14 *
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
22 */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
23
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
24 #define _XOPEN_SOURCE 600
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
25
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
26 #include <stdlib.h>
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
27 #include <pwd.h>
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
28 #include <unistd.h>
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
29 #include <stdio.h>
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
30 #include <string.h>
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
31 #include <inttypes.h>
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
32 #include <sys/stat.h>
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
33 #include <curses.h> /* for ERR, OK */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
34
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
35 #include "highscore.h"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
36 #include "compat.h"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
37 #include "util.h"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
38
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
39 #define HIGHSCORE_FILENAME ".rantaiwarna_hiscore"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
40 #define HIGHSCORE_TMP_TMPL ".rantaiwarna_hiscoreXXXXXX"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
41
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
42 static struct highscore_entry *
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
43 highscore_entry_new(int16_t width, int16_t height, int16_t colors,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
44 int32_t score, time_t time)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
45 {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
46 struct highscore_entry *entry;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
47
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
48 entry = rantaiwarna_malloc(sizeof (struct highscore_entry));
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
49 entry->next = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
50 entry->width = width;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
51 entry->height = height;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
52 entry->colors = colors;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
53 entry->score = score;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
54 localtime_r(&time, &entry->time);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
55
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
56 return (entry);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
57 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
58
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
59 void
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
60 highscore_entry_free(struct highscore_entry *entry)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
61 {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
62 free(entry);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
63 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
64
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
65 void
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
66 highscore_free(struct highscore_entry *highscore)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
67 {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
68 struct highscore_entry *next_entry = highscore;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
69 struct highscore_entry *entry = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
70
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
71 while (next_entry != NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
72 entry = next_entry;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
73 next_entry = entry->next;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
74 highscore_entry_free(entry);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
75 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
76 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
77
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
78 void
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
79 highscore_update(struct highscore_entry **highscorep, int16_t width,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
80 int16_t height, int16_t colors, int32_t score, time_t time)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
81 {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
82 struct highscore_entry *new_entry;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
83 struct highscore_entry *entry = *highscorep;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
84 int n = 0;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
85
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
86 if ((entry == NULL) || (entry->score < score)) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
87 /*
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
88 * if there are no entries or the current score is greater than
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
89 * the first entry, prepend a new entry
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
90 */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
91 new_entry = highscore_entry_new(width, height, colors, score,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
92 time);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
93 new_entry->next = entry;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
94 *highscorep = new_entry;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
95 n++;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
96 } else {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
97 /*
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
98 * if the current score is higher than the score of one of the
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
99 * top ten entries, insert a new entry
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
100 */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
101 for (n = 0; (entry->next != NULL) && (entry->next->score >
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
102 score) && (n < 10); entry = entry->next, n++);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
103 new_entry = highscore_entry_new(width, height, colors, score,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
104 time);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
105 new_entry->next = entry->next;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
106 entry->next = new_entry;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
107 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
108 if (entry != NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
109 /* trim any entries outside the top ten */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
110 while ((entry->next != NULL) && (n < 10)) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
111 entry = entry->next;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
112 n++;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
113 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
114 highscore_free(entry->next);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
115 entry->next = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
116 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
117 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
118
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
119 int
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
120 highscore_load(struct highscore_entry **highscorep, int16_t ref_height,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
121 int16_t ref_width, int16_t ref_colors)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
122 {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
123 int error = ERR;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
124 struct highscore_entry *highscore = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
125 char *home_dir;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
126 struct passwd *pw;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
127 int n;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
128 char *highscore_filename = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
129 FILE *fp = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
130 char *scan_fmt = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
131 int16_t width;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
132 int16_t height;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
133 int16_t colors;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
134 int32_t score;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
135 char timestr[4 + 1 + 2 + 1 + 2 + 1]; /* holds %Y-%m-%d */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
136 struct tm tm;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
137 time_t time;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
138
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
139 home_dir = getenv("HOME");
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
140 if (home_dir == NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
141 pw = getpwuid(getuid());
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
142 if (pw != NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
143 home_dir = pw->pw_dir;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
144 } else {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
145 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
146 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
147 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
148
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
149 n = snprintf(NULL, 0, "%s/%s", home_dir, HIGHSCORE_FILENAME);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
150 if (n < 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
151 rantaiwarna_err(1, NULL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
152 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
153 highscore_filename = rantaiwarna_malloc((size_t)n + 1);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
154 if (snprintf(highscore_filename, (size_t)n + 1,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
155 "%s/%s", home_dir, HIGHSCORE_FILENAME) != n) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
156 rantaiwarna_err(1, NULL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
157 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
158
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
159 n = snprintf(NULL, 0, "%%" SCNd16 "%%" SCNd16 "%%" SCNd16 "%%" SCNd32
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
160 "%%%lus", sizeof (timestr) - 1);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
161 if (n < 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
162 rantaiwarna_err(1, NULL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
163 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
164 scan_fmt = rantaiwarna_malloc((size_t)n + 1);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
165 if (snprintf(scan_fmt, (size_t)n + 1, "%%" SCNd16 "%%" SCNd16 "%%"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
166 SCNd16 "%%" SCNd32 "%%%lus", sizeof (timestr) - 1) != n) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
167 rantaiwarna_err(1, NULL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
168 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
169
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
170 fp = fopen(highscore_filename, "r");
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
171 if (fp == NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
172 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
173 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
174 while ((n = fscanf(fp, scan_fmt, &width, &height, &colors, &score,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
175 timestr)) != EOF) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
176 if ((n == 5) && ((width == ref_width) &&
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
177 (height == ref_height) && (colors == ref_colors))) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
178 memset(&tm, 0, sizeof (struct tm));
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
179 time = (time_t)0;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
180 if (strptime(timestr, "%Y-%m-%d", &tm) != NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
181 time = mktime(&tm);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
182 if (time == (time_t)-1) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
183 time = (time_t)0;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
184 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
185 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
186 highscore_update(&highscore, width, height, colors,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
187 score, time);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
188 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
189 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
190 if (ferror(fp) != 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
191 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
192 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
193
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
194 error = OK;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
195
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
196 out:
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
197 if (fp != NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
198 fclose(fp);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
199 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
200
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
201 free(scan_fmt);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
202 free(highscore_filename);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
203
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
204 if (error == ERR) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
205 highscore_free(highscore);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
206 } else {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
207 highscore_free(*highscorep);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
208 *highscorep = highscore;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
209 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
210
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
211 return (error);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
212 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
213
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
214 int
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
215 highscore_save(struct highscore_entry *highscore, int16_t ref_height,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
216 int16_t ref_width, int16_t ref_colors)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
217 {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
218 int error = ERR;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
219 char *scan_fmt = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
220 char *home_dir;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
221 struct passwd *pw;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
222 int n;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
223 char *highscore_filename = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
224 char *tmp_filename = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
225 mode_t old_mode;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
226 FILE *fp_in = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
227 int fd_out = -1;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
228 FILE *fp_out = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
229 int16_t width;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
230 int16_t height;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
231 int16_t colors;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
232 int32_t score;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
233 char timestr[4 + 1 + 2 + 1 + 2 + 1]; /* holds %Y-%m-%d */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
234 struct highscore_entry *entry;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
235
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
236 /*
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
237 * file format:
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
238 * entries consisting of five fields, entries and fields separated by
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
239 * whitespace
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
240 *
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
241 * fields:
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
242 * width (int16_t)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
243 * height (int16_t)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
244 * colors (int16_t)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
245 * score (int32_t)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
246 * time string (YYYY-MM-DD)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
247 */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
248 if (highscore == NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
249 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
250 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
251
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
252 n = snprintf(NULL, 0, "%%" SCNd16 "%%" SCNd16 "%%" SCNd16 "%%" SCNd32
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
253 "%%%lus", sizeof (timestr) - 1);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
254 if (n < 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
255 rantaiwarna_err(1, NULL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
256 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
257 scan_fmt = rantaiwarna_malloc((size_t)n + 1);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
258 if (snprintf(scan_fmt, (size_t)n + 1, "%%" SCNd16 "%%" SCNd16 "%%"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
259 SCNd16 "%%" SCNd32 "%%%lus", sizeof (timestr) - 1) != n) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
260 rantaiwarna_err(1, NULL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
261 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
262
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
263 home_dir = getenv("HOME");
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
264 if (home_dir == NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
265 pw = getpwuid(getuid());
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
266 if (pw != NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
267 home_dir = pw->pw_dir;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
268 } else {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
269 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
270 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
271 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
272
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
273 n = snprintf(NULL, 0, "%s/%s", home_dir, HIGHSCORE_FILENAME);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
274 if (n < 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
275 rantaiwarna_err(1, NULL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
276 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
277 highscore_filename = rantaiwarna_malloc((size_t)n + 1);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
278 if (snprintf(highscore_filename, (size_t)n + 1, "%s/%s", home_dir,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
279 HIGHSCORE_FILENAME) != n) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
280 rantaiwarna_err(1, NULL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
281 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
282
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
283 n = snprintf(NULL, 0, "%s/%s", home_dir, HIGHSCORE_TMP_TMPL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
284 if (n < 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
285 rantaiwarna_err(1, NULL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
286 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
287 tmp_filename = rantaiwarna_malloc((size_t)n + 1);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
288 if (snprintf(tmp_filename, (size_t)n + 1, "%s/%s", home_dir,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
289 HIGHSCORE_TMP_TMPL) != n) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
290 rantaiwarna_err(1, NULL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
291 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
292
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
293 old_mode = umask(077);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
294 fd_out = mkstemp(tmp_filename);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
295 umask(old_mode);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
296 if (fd_out == -1) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
297 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
298 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
299
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
300 fp_out = fdopen(fd_out, "w");
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
301 if (fp_out == NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
302 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
303 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
304 /*
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
305 * preserve entries which do not match the current combination of width,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
306 * height, and colors
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
307 */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
308 fp_in = fopen(highscore_filename, "r");
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
309 if (fp_in != NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
310 while ((n = fscanf(fp_in, scan_fmt, &width, &height, &colors,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
311 &score, timestr)) != EOF) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
312 if ((n == 5) && ((width != ref_width) ||
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
313 (height != ref_height) || (colors != ref_colors))) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
314 if (fprintf(fp_out, "%" PRId16 " %" PRId16 " %"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
315 PRId16 " %" PRId32 " %s\n", width, height,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
316 colors, score, timestr) < 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
317 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
318 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
319 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
320 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
321 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
322 /*
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
323 * append entries for the current combination of width, height, and
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
324 * colors
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
325 */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
326 for (entry = highscore; entry != NULL; entry = entry->next) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
327 if (strftime(timestr, sizeof (timestr), "%Y-%m-%d",
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
328 &entry->time) == 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
329 snprintf(timestr, sizeof (timestr) - 1, "1970-01-01");
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
330 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
331 n = snprintf(NULL, 0, "%" PRId16 " %" PRId16 " %" PRId16 " %"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
332 PRId32 " %s\n", entry->width, entry->height, entry->colors,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
333 entry->score, timestr);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
334 if (n < 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
335 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
336 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
337 if (fprintf(fp_out, "%" PRId16 " %" PRId16 " %" PRId16 " %"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
338 PRId32 " %s\n", entry->width, entry->height,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
339 entry->colors, entry->score, timestr) != n) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
340 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
341 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
342 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
343 if (fflush(fp_out) == EOF) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
344 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
345 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
346 if (fsync(fd_out) == -1) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
347 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
348 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
349
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
350 error = OK;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
351
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
352 out:
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
353 if (fp_in != NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
354 fclose(fp_in);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
355 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
356
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
357 if (fp_out != NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
358 fclose(fp_out);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
359 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
360
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
361 if (fd_out != -1) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
362 close(fd_out);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
363 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
364
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
365 if (error == ERR) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
366 if (tmp_filename != NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
367 unlink(tmp_filename);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
368 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
369 } else {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
370 if (rename(tmp_filename, highscore_filename) == -1) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
371 unlink(tmp_filename);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
372 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
373 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
374
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
375 free(highscore_filename);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
376 free(tmp_filename);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
377 free(scan_fmt);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
378
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
379 return (error);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
380 }