Mercurial > emacs
annotate lib-src/update-game-score.c @ 68498:528aecb860cf
Revision: emacs@sv.gnu.org/emacs--devo--0--patch-30
Creator: Michael Olson <mwolson@gnu.org>
Merge from erc--main--0
2006-01-30 Michael Olson <mwolson@gnu.org>
* erc-stamp.el (erc-timestamp-right-align-by-pixel): New option
that determines whether to use pixel values to align right
timestamps. The default is not to do so, since it only works with
Emacs22 on X, and even then some people have trouble.
(erc-insert-aligned): Use `erc-timestamp-right-align-by-pixel'.
author | Miles Bader <miles@gnu.org> |
---|---|
date | Tue, 31 Jan 2006 00:24:36 +0000 |
parents | 6358e3c6075c |
children | 3661e9b3c48f 2d92f5c9d6ae |
rev | line source |
---|---|
44184 | 1 /* update-game-score.c --- Update a score file |
64769
6358e3c6075c
Update years in copyright notice; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
64083
diff
changeset
|
2 Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. |
44184 | 3 |
4 This file is part of GNU Emacs. | |
5 | |
6 GNU Emacs is free software; you can redistribute it and/or modify | |
7 it under the terms of the GNU General Public License as published by | |
8 the Free Software Foundation; either version 2, or (at your option) | |
9 any later version. | |
10 | |
11 GNU Emacs is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 GNU General Public License for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with GNU Emacs; see the file COPYING. If not, write to | |
64083 | 18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
19 Boston, MA 02110-1301, USA. */ | |
44184 | 20 |
21 /* This program is allows a game to securely and atomically update a | |
44481
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
22 score file. It should be installed setuid, owned by an appropriate |
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
23 user like `games'. |
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
24 |
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
25 Alternatively, it can be compiled without HAVE_SHARED_GAME_DIR |
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
26 defined, and in that case it will store scores in the user's home |
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
27 directory (it should NOT be setuid). |
44184 | 28 |
29 Created 2002/03/22, by Colin Walters <walters@debian.org> | |
30 */ | |
31 | |
44639
44995332ed1b
Move config.h before the other headers, to prevent compiler warnings
Eli Zaretskii <eliz@gnu.org>
parents:
44576
diff
changeset
|
32 #include <config.h> |
44995332ed1b
Move config.h before the other headers, to prevent compiler warnings
Eli Zaretskii <eliz@gnu.org>
parents:
44576
diff
changeset
|
33 |
48422
2346caa2a66a
Include unistd.h, string.h, stdlib.h,
Dave Love <fx@gnu.org>
parents:
46774
diff
changeset
|
34 #ifdef HAVE_UNISTD_H |
44184 | 35 #include <unistd.h> |
48422
2346caa2a66a
Include unistd.h, string.h, stdlib.h,
Dave Love <fx@gnu.org>
parents:
46774
diff
changeset
|
36 #endif |
44184 | 37 #include <errno.h> |
48422
2346caa2a66a
Include unistd.h, string.h, stdlib.h,
Dave Love <fx@gnu.org>
parents:
46774
diff
changeset
|
38 #ifdef HAVE_STRING_H |
44184 | 39 #include <string.h> |
48422
2346caa2a66a
Include unistd.h, string.h, stdlib.h,
Dave Love <fx@gnu.org>
parents:
46774
diff
changeset
|
40 #endif |
2346caa2a66a
Include unistd.h, string.h, stdlib.h,
Dave Love <fx@gnu.org>
parents:
46774
diff
changeset
|
41 #ifdef HAVE_STDLIB_H |
44184 | 42 #include <stdlib.h> |
48422
2346caa2a66a
Include unistd.h, string.h, stdlib.h,
Dave Love <fx@gnu.org>
parents:
46774
diff
changeset
|
43 #endif |
44184 | 44 #include <stdio.h> |
45 #include <time.h> | |
44402
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
46 #include <pwd.h> |
44184 | 47 #include <ctype.h> |
48422
2346caa2a66a
Include unistd.h, string.h, stdlib.h,
Dave Love <fx@gnu.org>
parents:
46774
diff
changeset
|
48 #ifdef HAVE_FCNTL_H |
44184 | 49 #include <fcntl.h> |
48422
2346caa2a66a
Include unistd.h, string.h, stdlib.h,
Dave Love <fx@gnu.org>
parents:
46774
diff
changeset
|
50 #endif |
2346caa2a66a
Include unistd.h, string.h, stdlib.h,
Dave Love <fx@gnu.org>
parents:
46774
diff
changeset
|
51 #ifdef STDC_HEADERS |
44481
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
52 #include <stdarg.h> |
48422
2346caa2a66a
Include unistd.h, string.h, stdlib.h,
Dave Love <fx@gnu.org>
parents:
46774
diff
changeset
|
53 #endif |
44184 | 54 #include <sys/stat.h> |
55 | |
48422
2346caa2a66a
Include unistd.h, string.h, stdlib.h,
Dave Love <fx@gnu.org>
parents:
46774
diff
changeset
|
56 /* Needed for SunOS4, for instance. */ |
2346caa2a66a
Include unistd.h, string.h, stdlib.h,
Dave Love <fx@gnu.org>
parents:
46774
diff
changeset
|
57 extern char *optarg; |
2346caa2a66a
Include unistd.h, string.h, stdlib.h,
Dave Love <fx@gnu.org>
parents:
46774
diff
changeset
|
58 extern int optind, opterr; |
2346caa2a66a
Include unistd.h, string.h, stdlib.h,
Dave Love <fx@gnu.org>
parents:
46774
diff
changeset
|
59 |
44184 | 60 #define MAX_ATTEMPTS 5 |
44481
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
61 #define MAX_SCORES 200 |
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
62 #define MAX_DATA_LEN 1024 |
44419
16b3622178f9
update-game-score.c (SCORE_FILE_PREFIX): Don't hardcode.
Colin Walters <walters@gnu.org>
parents:
44404
diff
changeset
|
63 |
46774
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
64 /* Declare the prototype for a general external function. */ |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
65 #if defined (PROTOTYPES) || defined (WINDOWSNT) |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
66 #define P_(proto) proto |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
67 #else |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
68 #define P_(proto) () |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
69 #endif |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
70 |
51146
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
71 #ifndef HAVE_DIFFTIME |
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
72 /* OK on POSIX (time_t is arithmetic type) modulo overflow in subtraction. */ |
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
73 #define difftime(t1, t0) (double)((t1) - (t0)) |
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
74 #endif |
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
75 |
44184 | 76 int |
49594 | 77 usage (err) |
46774
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
78 int err; |
44184 | 79 { |
49594 | 80 fprintf (stdout, "Usage: update-game-score [-m MAX ] [ -r ] game/scorefile SCORE DATA\n"); |
81 fprintf (stdout, " update-game-score -h\n"); | |
82 fprintf (stdout, " -h\t\tDisplay this help.\n"); | |
83 fprintf (stdout, " -m MAX\t\tLimit the maximum number of scores to MAX.\n"); | |
84 fprintf (stdout, " -r\t\tSort the scores in increasing order.\n"); | |
85 fprintf (stdout, " -d DIR\t\tStore scores in DIR (only if not setuid).\n"); | |
86 exit (err); | |
44184 | 87 } |
88 | |
49594 | 89 int lock_file P_ ((const char *filename, void **state)); |
90 int unlock_file P_ ((const char *filename, void *state)); | |
44184 | 91 |
92 struct score_entry | |
93 { | |
94 long score; | |
44402
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
95 char *username; |
44184 | 96 char *data; |
97 }; | |
98 | |
49594 | 99 int read_scores P_ ((const char *filename, struct score_entry **scores, |
100 int *count)); | |
101 int push_score P_ ((struct score_entry **scores, int *count, | |
102 int newscore, char *username, char *newdata)); | |
103 void sort_scores P_ ((struct score_entry *scores, int count, int reverse)); | |
104 int write_scores P_ ((const char *filename, const struct score_entry *scores, | |
105 int count)); | |
106 | |
107 void lose P_ ((const char *msg)) NO_RETURN; | |
108 | |
44184 | 109 void |
49594 | 110 lose (msg) |
46774
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
111 const char *msg; |
44481
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
112 { |
49594 | 113 fprintf (stderr, "%s\n", msg); |
55442
a47704955f8d
Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
52401
diff
changeset
|
114 exit (EXIT_FAILURE); |
46774
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
115 } |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
116 |
49594 | 117 void lose_syserr P_ ((const char *msg)) NO_RETURN; |
46774
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
118 |
51146
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
119 /* Taken from sysdep.c. */ |
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
120 #ifndef HAVE_STRERROR |
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
121 #ifndef WINDOWSNT |
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
122 char * |
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
123 strerror (errnum) |
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
124 int errnum; |
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
125 { |
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
126 extern char *sys_errlist[]; |
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
127 extern int sys_nerr; |
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
128 |
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
129 if (errnum >= 0 && errnum < sys_nerr) |
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
130 return sys_errlist[errnum]; |
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
131 return (char *) "Unknown error"; |
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
132 } |
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
133 #endif /* not WINDOWSNT */ |
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
134 #endif /* ! HAVE_STRERROR */ |
f20c52ac1b8d
(difftime) [!HAVE_DIFFTIME]: Define.
Dave Love <fx@gnu.org>
parents:
50718
diff
changeset
|
135 |
49594 | 136 void |
137 lose_syserr (msg) | |
46774
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
138 const char *msg; |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
139 { |
49594 | 140 fprintf (stderr, "%s: %s\n", msg, strerror (errno)); |
55442
a47704955f8d
Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
52401
diff
changeset
|
141 exit (EXIT_FAILURE); |
44481
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
142 } |
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
143 |
44987
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
144 char * |
48422
2346caa2a66a
Include unistd.h, string.h, stdlib.h,
Dave Love <fx@gnu.org>
parents:
46774
diff
changeset
|
145 get_user_id P_ ((void)) |
44987
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
146 { |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
147 char *name; |
49594 | 148 struct passwd *buf = getpwuid (getuid ()); |
44987
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
149 if (!buf) |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
150 { |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
151 int count = 1; |
49594 | 152 int uid = (int) getuid (); |
44987
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
153 int tuid = uid; |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
154 while (tuid /= 10) |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
155 count++; |
49594 | 156 name = malloc (count+1); |
44987
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
157 if (!name) |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
158 return NULL; |
49594 | 159 sprintf (name, "%d", uid); |
44987
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
160 return name; |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
161 } |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
162 return buf->pw_name; |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
163 } |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
164 |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
165 char * |
49594 | 166 get_prefix (running_suid, user_prefix) |
46774
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
167 int running_suid; |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
168 char *user_prefix; |
44987
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
169 { |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
170 if (!running_suid && user_prefix == NULL) |
49594 | 171 lose ("Not using a shared game directory, and no prefix given."); |
44987
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
172 if (running_suid) |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
173 { |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
174 #ifdef HAVE_SHARED_GAME_DIR |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
175 return HAVE_SHARED_GAME_DIR; |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
176 #else |
49594 | 177 lose ("This program was compiled without HAVE_SHARED_GAME_DIR,\n and should not be suid."); |
44987
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
178 #endif |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
179 } |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
180 return user_prefix; |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
181 } |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
182 |
44184 | 183 int |
49594 | 184 main (argc, argv) |
46774
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
185 int argc; |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
186 char **argv; |
44184 | 187 { |
44987
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
188 int c, running_suid; |
44184 | 189 void *lockstate; |
44987
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
190 char *user_id, *scorefile, *prefix, *user_prefix = NULL; |
44184 | 191 struct stat buf; |
192 struct score_entry *scores; | |
44481
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
193 int newscore, scorecount, reverse = 0, max = MAX_SCORES; |
44184 | 194 char *newdata; |
195 | |
49594 | 196 srand (time (0)); |
44184 | 197 |
49594 | 198 while ((c = getopt (argc, argv, "hrm:d:")) != -1) |
44184 | 199 switch (c) |
200 { | |
201 case 'h': | |
55442
a47704955f8d
Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
52401
diff
changeset
|
202 usage (EXIT_SUCCESS); |
44184 | 203 break; |
44987
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
204 case 'd': |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
205 user_prefix = optarg; |
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
206 break; |
44184 | 207 case 'r': |
208 reverse = 1; | |
209 break; | |
210 case 'm': | |
49594 | 211 max = atoi (optarg); |
44481
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
212 if (max > MAX_SCORES) |
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
213 max = MAX_SCORES; |
44184 | 214 break; |
215 default: | |
55442
a47704955f8d
Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
52401
diff
changeset
|
216 usage (EXIT_FAILURE); |
44184 | 217 } |
218 | |
219 if (optind+3 != argc) | |
55442
a47704955f8d
Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
52401
diff
changeset
|
220 usage (EXIT_FAILURE); |
44419
16b3622178f9
update-game-score.c (SCORE_FILE_PREFIX): Don't hardcode.
Colin Walters <walters@gnu.org>
parents:
44404
diff
changeset
|
221 |
49594 | 222 running_suid = (getuid () != geteuid ()); |
44419
16b3622178f9
update-game-score.c (SCORE_FILE_PREFIX): Don't hardcode.
Colin Walters <walters@gnu.org>
parents:
44404
diff
changeset
|
223 |
49594 | 224 prefix = get_prefix (running_suid, user_prefix); |
44481
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
225 |
49594 | 226 scorefile = malloc (strlen (prefix) + strlen (argv[optind]) + 2); |
44184 | 227 if (!scorefile) |
49594 | 228 lose_syserr ("Couldn't allocate score file"); |
44481
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
229 |
49594 | 230 strcpy (scorefile, prefix); |
231 strcat (scorefile, "/"); | |
232 strcat (scorefile, argv[optind]); | |
233 newscore = atoi (argv[optind+1]); | |
44184 | 234 newdata = argv[optind+2]; |
49594 | 235 if (strlen (newdata) > MAX_DATA_LEN) |
44481
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
236 newdata[MAX_DATA_LEN] = '\0'; |
44987
cc0ab9acdc46
(SCORE_FILE_PREFIX): Delete.
Colin Walters <walters@gnu.org>
parents:
44789
diff
changeset
|
237 |
49595
ca4fb31aae14
(push_score, read_scores): Cast values of malloc and realloc.
Richard M. Stallman <rms@gnu.org>
parents:
49594
diff
changeset
|
238 user_id = get_user_id (); |
ca4fb31aae14
(push_score, read_scores): Cast values of malloc and realloc.
Richard M. Stallman <rms@gnu.org>
parents:
49594
diff
changeset
|
239 if (user_id == NULL) |
49594 | 240 lose_syserr ("Couldn't determine user id"); |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
49595
diff
changeset
|
241 |
49594 | 242 if (stat (scorefile, &buf) < 0) |
243 lose_syserr ("Failed to access scores file"); | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
49595
diff
changeset
|
244 |
49594 | 245 if (lock_file (scorefile, &lockstate) < 0) |
246 lose_syserr ("Failed to lock scores file"); | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
49595
diff
changeset
|
247 |
49594 | 248 if (read_scores (scorefile, &scores, &scorecount) < 0) |
44184 | 249 { |
49594 | 250 unlock_file (scorefile, lockstate); |
251 lose_syserr ("Failed to read scores file"); | |
44184 | 252 } |
49594 | 253 push_score (&scores, &scorecount, newscore, user_id, newdata); |
44481
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
254 /* Limit the number of scores. If we're using reverse sorting, then |
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
255 we should increment the beginning of the array, to skip over the |
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
256 *smallest* scores. Otherwise, we just decrement the number of |
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
257 scores, since the smallest will be at the end. */ |
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
258 if (scorecount > MAX_SCORES) |
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
259 scorecount -= (scorecount - MAX_SCORES); |
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
260 if (reverse) |
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
261 scores += (scorecount - MAX_SCORES); |
49594 | 262 sort_scores (scores, scorecount, reverse); |
263 if (write_scores (scorefile, scores, scorecount) < 0) | |
44184 | 264 { |
49594 | 265 unlock_file (scorefile, lockstate); |
266 lose_syserr ("Failed to write scores file"); | |
44184 | 267 } |
49594 | 268 unlock_file (scorefile, lockstate); |
55442
a47704955f8d
Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
52401
diff
changeset
|
269 exit (EXIT_SUCCESS); |
44184 | 270 } |
271 | |
272 int | |
49594 | 273 read_score (f, score) |
46774
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
274 FILE *f; |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
275 struct score_entry *score; |
44184 | 276 { |
277 int c; | |
49594 | 278 if (feof (f)) |
44184 | 279 return 1; |
49594 | 280 while ((c = getc (f)) != EOF |
281 && isdigit (c)) | |
44402
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
282 { |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
283 score->score *= 10; |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
284 score->score += (c-48); |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
285 } |
49594 | 286 while ((c = getc (f)) != EOF |
287 && isspace (c)) | |
44402
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
288 ; |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
289 if (c == EOF) |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
290 return -1; |
49594 | 291 ungetc (c, f); |
44402
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
292 #ifdef HAVE_GETDELIM |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
293 { |
44566
7a0ad319b38f
(read_score): Fix type of second parameter
Andreas Schwab <schwab@suse.de>
parents:
44481
diff
changeset
|
294 size_t count = 0; |
49594 | 295 if (getdelim (&score->username, &count, ' ', f) < 1 |
44402
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
296 || score->username == NULL) |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
297 return -1; |
44789
d095e59dc01d
(read_score) [HAVE_GETDELIM]: Trim trailing space.
Colin Walters <walters@gnu.org>
parents:
44639
diff
changeset
|
298 /* Trim the space */ |
49594 | 299 score->username[strlen (score->username)-1] = '\0'; |
44184 | 300 } |
44402
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
301 #else |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
302 { |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
303 int unameread = 0; |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
304 int unamelen = 30; |
49594 | 305 char *username = malloc (unamelen); |
44404
21e4d76a9e8a
Actually make previous changes work (oops).
Colin Walters <walters@gnu.org>
parents:
44402
diff
changeset
|
306 if (!username) |
21e4d76a9e8a
Actually make previous changes work (oops).
Colin Walters <walters@gnu.org>
parents:
44402
diff
changeset
|
307 return -1; |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
49595
diff
changeset
|
308 |
49594 | 309 while ((c = getc (f)) != EOF |
310 && !isspace (c)) | |
44402
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
311 { |
44481
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
312 if (unameread >= unamelen-1) |
49594 | 313 if (!(username = realloc (username, unamelen *= 2))) |
44481
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
314 return -1; |
44402
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
315 username[unameread] = c; |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
316 unameread++; |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
317 } |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
49595
diff
changeset
|
318 if (c == EOF) |
44404
21e4d76a9e8a
Actually make previous changes work (oops).
Colin Walters <walters@gnu.org>
parents:
44402
diff
changeset
|
319 return -1; |
21e4d76a9e8a
Actually make previous changes work (oops).
Colin Walters <walters@gnu.org>
parents:
44402
diff
changeset
|
320 username[unameread] = '\0'; |
44402
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
321 score->username = username; |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
322 } |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
323 #endif |
44184 | 324 #ifdef HAVE_GETLINE |
325 score->data = NULL; | |
44566
7a0ad319b38f
(read_score): Fix type of second parameter
Andreas Schwab <schwab@suse.de>
parents:
44481
diff
changeset
|
326 errno = 0; |
44184 | 327 { |
44566
7a0ad319b38f
(read_score): Fix type of second parameter
Andreas Schwab <schwab@suse.de>
parents:
44481
diff
changeset
|
328 size_t len; |
49594 | 329 if (getline (&score->data, &len, f) < 0) |
44184 | 330 return -1; |
49594 | 331 score->data[strlen (score->data)-1] = '\0'; |
44184 | 332 } |
333 #else | |
44402
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
334 { |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
335 int cur = 0; |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
336 int len = 16; |
49594 | 337 char *buf = malloc (len); |
44402
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
338 if (!buf) |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
339 return -1; |
49594 | 340 while ((c = getc (f)) != EOF |
44404
21e4d76a9e8a
Actually make previous changes work (oops).
Colin Walters <walters@gnu.org>
parents:
44402
diff
changeset
|
341 && c != '\n') |
44402
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
342 { |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
343 if (cur >= len-1) |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
344 { |
49594 | 345 if (!(buf = realloc (buf, len *= 2))) |
44402
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
346 return -1; |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
347 } |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
348 buf[cur] = c; |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
349 cur++; |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
350 } |
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
351 score->data = buf; |
44419
16b3622178f9
update-game-score.c (SCORE_FILE_PREFIX): Don't hardcode.
Colin Walters <walters@gnu.org>
parents:
44404
diff
changeset
|
352 score->data[cur] = '\0'; |
44402
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
353 } |
44184 | 354 #endif |
355 return 0; | |
356 } | |
357 | |
358 int | |
49594 | 359 read_scores (filename, scores, count) |
46774
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
360 const char *filename; |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
361 struct score_entry **scores; |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
362 int *count; |
44184 | 363 { |
364 int readval, scorecount, cursize; | |
365 struct score_entry *ret; | |
49594 | 366 FILE *f = fopen (filename, "r"); |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
49595
diff
changeset
|
367 if (!f) |
44184 | 368 return -1; |
369 scorecount = 0; | |
370 cursize = 16; | |
49595
ca4fb31aae14
(push_score, read_scores): Cast values of malloc and realloc.
Richard M. Stallman <rms@gnu.org>
parents:
49594
diff
changeset
|
371 ret = (struct score_entry *) malloc (sizeof (struct score_entry) * cursize); |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
49595
diff
changeset
|
372 if (!ret) |
44184 | 373 return -1; |
49594 | 374 while ((readval = read_score (f, &ret[scorecount])) == 0) |
44184 | 375 { |
376 /* We encoutered an error */ | |
377 if (readval < 0) | |
378 return -1; | |
379 scorecount++; | |
380 if (scorecount >= cursize) | |
381 { | |
50718
240f333f936c
(read_scores): Fix corruption of score files.
Juanma Barranquero <lekktu@gmail.com>
parents:
49600
diff
changeset
|
382 cursize *= 2; |
240f333f936c
(read_scores): Fix corruption of score files.
Juanma Barranquero <lekktu@gmail.com>
parents:
49600
diff
changeset
|
383 ret = (struct score_entry *) |
240f333f936c
(read_scores): Fix corruption of score files.
Juanma Barranquero <lekktu@gmail.com>
parents:
49600
diff
changeset
|
384 realloc (ret, (sizeof (struct score_entry) * cursize)); |
44184 | 385 if (!ret) |
386 return -1; | |
387 } | |
388 } | |
389 *count = scorecount; | |
390 *scores = ret; | |
391 return 0; | |
392 } | |
393 | |
394 int | |
49594 | 395 score_compare (a, b) |
46774
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
396 const void *a; |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
397 const void *b; |
44184 | 398 { |
399 const struct score_entry *sa = (const struct score_entry *) a; | |
400 const struct score_entry *sb = (const struct score_entry *) b; | |
401 return (sb->score > sa->score) - (sb->score < sa->score); | |
402 } | |
403 | |
404 int | |
49594 | 405 score_compare_reverse (a, b) |
46774
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
406 const void *a; |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
407 const void *b; |
44184 | 408 { |
409 const struct score_entry *sa = (const struct score_entry *) a; | |
410 const struct score_entry *sb = (const struct score_entry *) b; | |
411 return (sa->score > sb->score) - (sa->score < sb->score); | |
412 } | |
413 | |
414 int | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
49595
diff
changeset
|
415 push_score (scores, count, newscore, username, newdata) |
46774
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
416 struct score_entry **scores; |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
417 int *count; int newscore; |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
418 char *username; |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
419 char *newdata; |
44184 | 420 { |
49594 | 421 struct score_entry *newscores |
49595
ca4fb31aae14
(push_score, read_scores): Cast values of malloc and realloc.
Richard M. Stallman <rms@gnu.org>
parents:
49594
diff
changeset
|
422 = (struct score_entry *) realloc (*scores, |
ca4fb31aae14
(push_score, read_scores): Cast values of malloc and realloc.
Richard M. Stallman <rms@gnu.org>
parents:
49594
diff
changeset
|
423 sizeof (struct score_entry) * ((*count) + 1)); |
44184 | 424 if (!newscores) |
425 return -1; | |
426 newscores[*count].score = newscore; | |
44402
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
427 newscores[*count].username = username; |
44184 | 428 newscores[*count].data = newdata; |
429 (*count) += 1; | |
430 *scores = newscores; | |
431 return 0; | |
432 } | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
49595
diff
changeset
|
433 |
44184 | 434 void |
49594 | 435 sort_scores (scores, count, reverse) |
46774
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
436 struct score_entry *scores; |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
437 int count; |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
49595
diff
changeset
|
438 int reverse; |
44184 | 439 { |
49594 | 440 qsort (scores, count, sizeof (struct score_entry), |
44184 | 441 reverse ? score_compare_reverse : score_compare); |
442 } | |
443 | |
444 int | |
49594 | 445 write_scores (filename, scores, count) |
46774
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
446 const char *filename; |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
447 const struct score_entry * scores; |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
49595
diff
changeset
|
448 int count; |
44184 | 449 { |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
49595
diff
changeset
|
450 FILE *f; |
44184 | 451 int i; |
49594 | 452 char *tempfile = malloc (strlen (filename) + strlen (".tempXXXXXX") + 1); |
44184 | 453 if (!tempfile) |
454 return -1; | |
49594 | 455 strcpy (tempfile, filename); |
456 strcat (tempfile, ".tempXXXXXX"); | |
44481
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
457 #ifdef HAVE_MKSTEMP |
49594 | 458 if (mkstemp (tempfile) < 0 |
44481
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
459 #else |
49594 | 460 if (mktemp (tempfile) != tempfile |
44481
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
461 #endif |
49594 | 462 || !(f = fopen (tempfile, "w"))) |
44184 | 463 return -1; |
464 for (i = 0; i < count; i++) | |
49594 | 465 if (fprintf (f, "%ld %s %s\n", scores[i].score, scores[i].username, |
44402
968fd5ccea65
(toplevel): Include pwd.h.
Colin Walters <walters@gnu.org>
parents:
44184
diff
changeset
|
466 scores[i].data) < 0) |
44184 | 467 return -1; |
49594 | 468 fclose (f); |
469 if (rename (tempfile, filename) < 0) | |
44481
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
470 return -1; |
49594 | 471 if (chmod (filename, 0644) < 0) |
44481
a0dc261f564a
(toplevel): Include stdarg.h.
Colin Walters <walters@gnu.org>
parents:
44419
diff
changeset
|
472 return -1; |
44184 | 473 return 0; |
474 } | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
49595
diff
changeset
|
475 |
44184 | 476 int |
49594 | 477 lock_file (filename, state) |
46774
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
478 const char *filename; |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
479 void **state; |
44184 | 480 { |
481 int fd; | |
44576
90866353c7bd
(lock_file): If the lock file is older than an hour, delete it. Reset
Colin Walters <walters@gnu.org>
parents:
44566
diff
changeset
|
482 struct stat buf; |
44184 | 483 int attempts = 0; |
484 char *lockext = ".lockfile"; | |
49594 | 485 char *lockpath = malloc (strlen (filename) + strlen (lockext) + 60); |
44184 | 486 if (!lockpath) |
487 return -1; | |
49594 | 488 strcpy (lockpath, filename); |
489 strcat (lockpath, lockext); | |
44184 | 490 *state = lockpath; |
491 trylock: | |
492 attempts++; | |
44576
90866353c7bd
(lock_file): If the lock file is older than an hour, delete it. Reset
Colin Walters <walters@gnu.org>
parents:
44566
diff
changeset
|
493 /* If the lock is over an hour old, delete it. */ |
49594 | 494 if (stat (lockpath, &buf) == 0 |
495 && (difftime (buf.st_ctime, time (NULL) > 60*60))) | |
496 unlink (lockpath); | |
49595
ca4fb31aae14
(push_score, read_scores): Cast values of malloc and realloc.
Richard M. Stallman <rms@gnu.org>
parents:
49594
diff
changeset
|
497 fd = open (lockpath, O_CREAT | O_EXCL, 0600); |
ca4fb31aae14
(push_score, read_scores): Cast values of malloc and realloc.
Richard M. Stallman <rms@gnu.org>
parents:
49594
diff
changeset
|
498 if (fd < 0) |
44184 | 499 { |
500 if (errno == EEXIST) | |
501 { | |
502 /* Break the lock; we won't corrupt the file, but we might | |
503 lose some scores. */ | |
504 if (attempts > MAX_ATTEMPTS) | |
44576
90866353c7bd
(lock_file): If the lock file is older than an hour, delete it. Reset
Colin Walters <walters@gnu.org>
parents:
44566
diff
changeset
|
505 { |
49594 | 506 unlink (lockpath); |
44576
90866353c7bd
(lock_file): If the lock file is older than an hour, delete it. Reset
Colin Walters <walters@gnu.org>
parents:
44566
diff
changeset
|
507 attempts = 0; |
90866353c7bd
(lock_file): If the lock file is older than an hour, delete it. Reset
Colin Walters <walters@gnu.org>
parents:
44566
diff
changeset
|
508 } |
49594 | 509 sleep ((rand () % 2)+1); |
44184 | 510 goto trylock; |
511 } | |
512 else | |
513 return -1; | |
514 } | |
49594 | 515 close (fd); |
44184 | 516 return 0; |
517 } | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
49595
diff
changeset
|
518 |
44184 | 519 int |
49594 | 520 unlock_file (filename, state) |
46774
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
521 const char *filename; |
7411dc9e5008
(P_): New macro. Use it for all prototypes.
Colin Walters <walters@gnu.org>
parents:
44987
diff
changeset
|
522 void *state; |
44184 | 523 { |
524 char *lockpath = (char *) state; | |
49594 | 525 int ret = unlink (lockpath); |
44184 | 526 int saved_errno = errno; |
49594 | 527 free (lockpath); |
44184 | 528 errno = saved_errno; |
529 return ret; | |
530 } | |
52401 | 531 |
532 /* arch-tag: 2bf5c52e-4beb-463a-954e-c58b9c64736b | |
533 (do not change this comment) */ | |
55442
a47704955f8d
Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
52401
diff
changeset
|
534 |
a47704955f8d
Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
52401
diff
changeset
|
535 /* update-game-score.c ends here */ |