annotate highscore.c @ 10:4f6bf50dbc4a default tip

Detect the OS and configure build flags and libraries automatically
author Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
date Tue, 13 Sep 2016 18:19:44 +0200
parents a9a7ad180c3b
children
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 #include <stdlib.h>
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
25 #include <pwd.h>
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
26 #include <unistd.h>
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
27 #include <stdio.h>
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
28 #include <string.h>
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
29 #include <inttypes.h>
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
30 #include <sys/stat.h>
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
31 #include <curses.h> /* for ERR, OK */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
32
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
33 #include "highscore.h"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
34 #include "compat.h"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
35 #include "util.h"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
36
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
37 #define HIGHSCORE_FILENAME ".rantaiwarna_hiscore"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
38 #define HIGHSCORE_TMP_TMPL ".rantaiwarna_hiscoreXXXXXX"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
39
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
40 static struct highscore_entry *
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
41 highscore_entry_new(int16_t width, int16_t height, int16_t colors,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
42 int32_t score, time_t time)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
43 {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
44 struct highscore_entry *entry;
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 entry = rantaiwarna_malloc(sizeof (struct highscore_entry));
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
47 entry->next = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
48 entry->width = width;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
49 entry->height = height;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
50 entry->colors = colors;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
51 entry->score = score;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
52 localtime_r(&time, &entry->time);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
53
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
54 return (entry);
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
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
57 void
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
58 highscore_entry_free(struct highscore_entry *entry)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
59 {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
60 free(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
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
63 void
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
64 highscore_free(struct highscore_entry *highscore)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
65 {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
66 struct highscore_entry *next_entry = highscore;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
67 struct highscore_entry *entry = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
68
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
69 while (next_entry != NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
70 entry = next_entry;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
71 next_entry = entry->next;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
72 highscore_entry_free(entry);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
73 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
74 }
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 void
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
77 highscore_update(struct highscore_entry **highscorep, int16_t width,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
78 int16_t height, int16_t colors, int32_t score, time_t time)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
79 {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
80 struct highscore_entry *new_entry;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
81 struct highscore_entry *entry = *highscorep;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
82 int n = 0;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
83
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
84 if ((entry == NULL) || (entry->score < score)) {
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 there are no entries or the current score is greater than
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
87 * the first entry, prepend a new entry
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
88 */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
89 new_entry = highscore_entry_new(width, height, colors, score,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
90 time);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
91 new_entry->next = entry;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
92 *highscorep = new_entry;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
93 n++;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
94 } else {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
95 /*
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
96 * 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
97 * top ten entries, insert a new entry
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
98 */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
99 for (n = 0; (entry->next != NULL) && (entry->next->score >
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
100 score) && (n < 10); entry = entry->next, n++);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
101 new_entry = highscore_entry_new(width, height, colors, score,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
102 time);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
103 new_entry->next = entry->next;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
104 entry->next = new_entry;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
105 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
106 if (entry != NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
107 /* trim any entries outside the top ten */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
108 while ((entry->next != NULL) && (n < 10)) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
109 entry = entry->next;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
110 n++;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
111 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
112 highscore_free(entry->next);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
113 entry->next = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
114 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
115 }
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 int
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
118 highscore_load(struct highscore_entry **highscorep, int16_t ref_height,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
119 int16_t ref_width, int16_t ref_colors)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
120 {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
121 int error = ERR;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
122 struct highscore_entry *highscore = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
123 char *home_dir;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
124 struct passwd *pw;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
125 int n;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
126 char *highscore_filename = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
127 FILE *fp = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
128 char *scan_fmt = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
129 int16_t width;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
130 int16_t height;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
131 int16_t colors;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
132 int32_t score;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
133 char timestr[4 + 1 + 2 + 1 + 2 + 1]; /* holds %Y-%m-%d */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
134 struct tm tm;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
135 time_t time;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
136
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
137 home_dir = getenv("HOME");
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
138 if (home_dir == NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
139 pw = getpwuid(getuid());
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
140 if (pw != NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
141 home_dir = pw->pw_dir;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
142 } else {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
143 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
144 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
145 }
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 n = snprintf(NULL, 0, "%s/%s", home_dir, HIGHSCORE_FILENAME);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
148 if (n < 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
149 rantaiwarna_err(1, NULL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
150 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
151 highscore_filename = rantaiwarna_malloc((size_t)n + 1);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
152 if (snprintf(highscore_filename, (size_t)n + 1,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
153 "%s/%s", home_dir, HIGHSCORE_FILENAME) != n) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
154 rantaiwarna_err(1, NULL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
155 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
156
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
157 n = snprintf(NULL, 0, "%%" SCNd16 "%%" SCNd16 "%%" SCNd16 "%%" SCNd32
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
158 "%%%lus", sizeof (timestr) - 1);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
159 if (n < 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
160 rantaiwarna_err(1, NULL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
161 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
162 scan_fmt = rantaiwarna_malloc((size_t)n + 1);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
163 if (snprintf(scan_fmt, (size_t)n + 1, "%%" SCNd16 "%%" SCNd16 "%%"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
164 SCNd16 "%%" SCNd32 "%%%lus", sizeof (timestr) - 1) != n) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
165 rantaiwarna_err(1, NULL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
166 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
167
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
168 fp = fopen(highscore_filename, "r");
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
169 if (fp == NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
170 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
171 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
172 while ((n = fscanf(fp, scan_fmt, &width, &height, &colors, &score,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
173 timestr)) != EOF) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
174 if ((n == 5) && ((width == ref_width) &&
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
175 (height == ref_height) && (colors == ref_colors))) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
176 memset(&tm, 0, sizeof (struct tm));
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
177 time = (time_t)0;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
178 if (strptime(timestr, "%Y-%m-%d", &tm) != NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
179 time = mktime(&tm);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
180 if (time == (time_t)-1) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
181 time = (time_t)0;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
182 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
183 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
184 highscore_update(&highscore, width, height, colors,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
185 score, time);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
186 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
187 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
188 if (ferror(fp) != 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
189 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
190 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
191
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
192 error = OK;
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 out:
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
195 if (fp != NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
196 fclose(fp);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
197 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
198
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
199 free(scan_fmt);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
200 free(highscore_filename);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
201
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
202 if (error == ERR) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
203 highscore_free(highscore);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
204 } else {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
205 highscore_free(*highscorep);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
206 *highscorep = highscore;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
207 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
208
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
209 return (error);
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
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
212 int
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
213 highscore_save(struct highscore_entry *highscore, int16_t ref_height,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
214 int16_t ref_width, int16_t ref_colors)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
215 {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
216 int error = ERR;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
217 char *scan_fmt = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
218 char *home_dir;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
219 struct passwd *pw;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
220 int n;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
221 char *highscore_filename = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
222 char *tmp_filename = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
223 mode_t old_mode;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
224 FILE *fp_in = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
225 int fd_out = -1;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
226 FILE *fp_out = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
227 int16_t width;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
228 int16_t height;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
229 int16_t colors;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
230 int32_t score;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
231 char timestr[4 + 1 + 2 + 1 + 2 + 1]; /* holds %Y-%m-%d */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
232 struct highscore_entry *entry;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
233
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
234 /*
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
235 * file format:
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
236 * entries consisting of five fields, entries and fields separated by
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
237 * whitespace
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
238 *
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
239 * fields:
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
240 * width (int16_t)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
241 * height (int16_t)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
242 * colors (int16_t)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
243 * score (int32_t)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
244 * time string (YYYY-MM-DD)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
245 */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
246 if (highscore == NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
247 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
248 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
249
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
250 n = snprintf(NULL, 0, "%%" SCNd16 "%%" SCNd16 "%%" SCNd16 "%%" SCNd32
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
251 "%%%lus", sizeof (timestr) - 1);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
252 if (n < 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
253 rantaiwarna_err(1, NULL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
254 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
255 scan_fmt = rantaiwarna_malloc((size_t)n + 1);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
256 if (snprintf(scan_fmt, (size_t)n + 1, "%%" SCNd16 "%%" SCNd16 "%%"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
257 SCNd16 "%%" SCNd32 "%%%lus", sizeof (timestr) - 1) != n) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
258 rantaiwarna_err(1, NULL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
259 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
260
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
261 home_dir = getenv("HOME");
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
262 if (home_dir == NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
263 pw = getpwuid(getuid());
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
264 if (pw != NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
265 home_dir = pw->pw_dir;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
266 } else {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
267 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
268 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
269 }
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 n = snprintf(NULL, 0, "%s/%s", home_dir, HIGHSCORE_FILENAME);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
272 if (n < 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
273 rantaiwarna_err(1, NULL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
274 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
275 highscore_filename = rantaiwarna_malloc((size_t)n + 1);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
276 if (snprintf(highscore_filename, (size_t)n + 1, "%s/%s", home_dir,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
277 HIGHSCORE_FILENAME) != n) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
278 rantaiwarna_err(1, NULL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
279 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
280
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
281 n = snprintf(NULL, 0, "%s/%s", home_dir, HIGHSCORE_TMP_TMPL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
282 if (n < 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
283 rantaiwarna_err(1, NULL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
284 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
285 tmp_filename = rantaiwarna_malloc((size_t)n + 1);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
286 if (snprintf(tmp_filename, (size_t)n + 1, "%s/%s", home_dir,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
287 HIGHSCORE_TMP_TMPL) != n) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
288 rantaiwarna_err(1, NULL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
289 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
290
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
291 old_mode = umask(077);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
292 fd_out = mkstemp(tmp_filename);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
293 umask(old_mode);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
294 if (fd_out == -1) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
295 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
296 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
297
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
298 fp_out = fdopen(fd_out, "w");
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
299 if (fp_out == NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
300 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
301 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
302 /*
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
303 * preserve entries which do not match the current combination of width,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
304 * height, and colors
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
305 */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
306 fp_in = fopen(highscore_filename, "r");
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
307 if (fp_in != NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
308 while ((n = fscanf(fp_in, scan_fmt, &width, &height, &colors,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
309 &score, timestr)) != EOF) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
310 if ((n == 5) && ((width != ref_width) ||
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
311 (height != ref_height) || (colors != ref_colors))) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
312 if (fprintf(fp_out, "%" PRId16 " %" PRId16 " %"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
313 PRId16 " %" PRId32 " %s\n", width, height,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
314 colors, score, timestr) < 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
315 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
316 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
317 }
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 * append entries for the current combination of width, height, and
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
322 * colors
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
323 */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
324 for (entry = highscore; entry != NULL; entry = entry->next) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
325 if (strftime(timestr, sizeof (timestr), "%Y-%m-%d",
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
326 &entry->time) == 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
327 snprintf(timestr, sizeof (timestr) - 1, "1970-01-01");
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
328 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
329 n = snprintf(NULL, 0, "%" PRId16 " %" PRId16 " %" PRId16 " %"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
330 PRId32 " %s\n", entry->width, entry->height, entry->colors,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
331 entry->score, timestr);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
332 if (n < 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
333 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
334 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
335 if (fprintf(fp_out, "%" PRId16 " %" PRId16 " %" PRId16 " %"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
336 PRId32 " %s\n", entry->width, entry->height,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
337 entry->colors, entry->score, timestr) != n) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
338 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
339 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
340 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
341 if (fflush(fp_out) == EOF) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
342 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
343 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
344 if (fsync(fd_out) == -1) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
345 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
346 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
347
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
348 error = OK;
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 out:
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
351 if (fp_in != NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
352 fclose(fp_in);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
353 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
354
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
355 if (fp_out != NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
356 fclose(fp_out);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
357 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
358
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
359 if (fd_out != -1) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
360 close(fd_out);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
361 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
362
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
363 if (error == ERR) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
364 if (tmp_filename != NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
365 unlink(tmp_filename);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
366 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
367 } else {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
368 if (rename(tmp_filename, highscore_filename) == -1) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
369 unlink(tmp_filename);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
370 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
371 }
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 free(highscore_filename);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
374 free(tmp_filename);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
375 free(scan_fmt);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
376
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
377 return (error);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
378 }