Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
emacs
emacs
Commits
a5d107f3
Commit
a5d107f3
authored
Feb 04, 2003
by
Richard M. Stallman
Browse files
Whitespace changes.
parent
22b94eeb
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
122 additions
and
125 deletions
+122
-125
lib-src/update-game-score.c
lib-src/update-game-score.c
+122
-125
No files found.
lib-src/update-game-score.c
View file @
a5d107f3
...
...
@@ -69,22 +69,20 @@ extern int optind, opterr;
#endif
int
usage
(
err
)
usage
(
err
)
int
err
;
{
fprintf
(
stdout
,
"Usage: update-game-score [-m MAX ] [ -r ] game/scorefile SCORE DATA
\n
"
);
fprintf
(
stdout
,
" update-game-score -h
\n
"
);
fprintf
(
stdout
,
" -h
\t\t
Display this help.
\n
"
);
fprintf
(
stdout
,
" -m MAX
\t\t
Limit the maximum number of scores to MAX.
\n
"
);
fprintf
(
stdout
,
" -r
\t\t
Sort the scores in increasing order.
\n
"
);
fprintf
(
stdout
,
" -d DIR
\t\t
Store scores in DIR (only if not setuid).
\n
"
);
exit
(
err
);
fprintf
(
stdout
,
"Usage: update-game-score [-m MAX ] [ -r ] game/scorefile SCORE DATA
\n
"
);
fprintf
(
stdout
,
" update-game-score -h
\n
"
);
fprintf
(
stdout
,
" -h
\t\t
Display this help.
\n
"
);
fprintf
(
stdout
,
" -m MAX
\t\t
Limit the maximum number of scores to MAX.
\n
"
);
fprintf
(
stdout
,
" -r
\t\t
Sort the scores in increasing order.
\n
"
);
fprintf
(
stdout
,
" -d DIR
\t\t
Store scores in DIR (only if not setuid).
\n
"
);
exit
(
err
);
}
int
lock_file
P_
((
const
char
*
filename
,
void
**
state
));
int
unlock_file
P_
((
const
char
*
filename
,
void
*
state
));
int
lock_file
P_
((
const
char
*
filename
,
void
**
state
));
int
unlock_file
P_
((
const
char
*
filename
,
void
*
state
));
struct
score_entry
{
...
...
@@ -93,77 +91,75 @@ struct score_entry
char
*
data
;
};
int
read_scores
P_
((
const
char
*
filename
,
struct
score_entry
**
scores
,
int
*
count
));
int
push_score
P_
((
struct
score_entry
**
scores
,
int
*
count
,
int
newscore
,
char
*
username
,
char
*
newdata
));
void
sort_scores
P_
((
struct
score_entry
*
scores
,
int
count
,
int
reverse
));
int
write_scores
P_
((
const
char
*
filename
,
const
struct
score_entry
*
scores
,
int
count
));
int
read_scores
P_
((
const
char
*
filename
,
struct
score_entry
**
scores
,
int
*
count
));
int
push_score
P_
((
struct
score_entry
**
scores
,
int
*
count
,
int
newscore
,
char
*
username
,
char
*
newdata
));
void
sort_scores
P_
((
struct
score_entry
*
scores
,
int
count
,
int
reverse
));
int
write_scores
P_
((
const
char
*
filename
,
const
struct
score_entry
*
scores
,
int
count
));
void
lose
P_
((
const
char
*
msg
))
NO_RETURN
;
void
lose
P_
((
const
char
*
msg
))
NO_RETURN
;
void
lose
(
msg
)
void
lose
(
msg
)
const
char
*
msg
;
{
fprintf
(
stderr
,
"%s
\n
"
,
msg
);
exit
(
1
);
fprintf
(
stderr
,
"%s
\n
"
,
msg
);
exit
(
1
);
}
void
lose_syserr
P_
((
const
char
*
msg
))
NO_RETURN
;
void
lose_syserr
P_
((
const
char
*
msg
))
NO_RETURN
;
void
lose_syserr
(
msg
)
void
lose_syserr
(
msg
)
const
char
*
msg
;
{
fprintf
(
stderr
,
"%s: %s
\n
"
,
msg
,
strerror
(
errno
));
exit
(
1
);
fprintf
(
stderr
,
"%s: %s
\n
"
,
msg
,
strerror
(
errno
));
exit
(
1
);
}
char
*
get_user_id
P_
((
void
))
{
char
*
name
;
struct
passwd
*
buf
=
getpwuid
(
getuid
());
struct
passwd
*
buf
=
getpwuid
(
getuid
());
if
(
!
buf
)
{
int
count
=
1
;
int
uid
=
(
int
)
getuid
();
int
uid
=
(
int
)
getuid
();
int
tuid
=
uid
;
while
(
tuid
/=
10
)
count
++
;
name
=
malloc
(
count
+
1
);
name
=
malloc
(
count
+
1
);
if
(
!
name
)
return
NULL
;
sprintf
(
name
,
"%d"
,
uid
);
sprintf
(
name
,
"%d"
,
uid
);
return
name
;
}
return
buf
->
pw_name
;
}
char
*
get_prefix
(
running_suid
,
user_prefix
)
get_prefix
(
running_suid
,
user_prefix
)
int
running_suid
;
char
*
user_prefix
;
{
if
(
!
running_suid
&&
user_prefix
==
NULL
)
lose
(
"Not using a shared game directory, and no prefix given."
);
lose
(
"Not using a shared game directory, and no prefix given."
);
if
(
running_suid
)
{
#ifdef HAVE_SHARED_GAME_DIR
return
HAVE_SHARED_GAME_DIR
;
#else
lose
(
"This program was compiled without HAVE_SHARED_GAME_DIR,
\n
and should not be suid."
);
lose
(
"This program was compiled without HAVE_SHARED_GAME_DIR,
\n
and should not be suid."
);
#endif
}
return
user_prefix
;
}
int
main
(
argc
,
argv
)
main
(
argc
,
argv
)
int
argc
;
char
**
argv
;
{
...
...
@@ -175,13 +171,13 @@ main(argc, argv)
int
newscore
,
scorecount
,
reverse
=
0
,
max
=
MAX_SCORES
;
char
*
newdata
;
srand
(
time
(
0
));
srand
(
time
(
0
));
while
((
c
=
getopt
(
argc
,
argv
,
"hrm:d:"
))
!=
-
1
)
while
((
c
=
getopt
(
argc
,
argv
,
"hrm:d:"
))
!=
-
1
)
switch
(
c
)
{
case
'h'
:
usage
(
0
);
usage
(
0
);
break
;
case
'd'
:
user_prefix
=
optarg
;
...
...
@@ -190,48 +186,48 @@ main(argc, argv)
reverse
=
1
;
break
;
case
'm'
:
max
=
atoi
(
optarg
);
max
=
atoi
(
optarg
);
if
(
max
>
MAX_SCORES
)
max
=
MAX_SCORES
;
break
;
default:
usage
(
1
);
usage
(
1
);
}
if
(
optind
+
3
!=
argc
)
usage
(
1
);
usage
(
1
);
running_suid
=
(
getuid
()
!=
geteuid
());
running_suid
=
(
getuid
()
!=
geteuid
());
prefix
=
get_prefix
(
running_suid
,
user_prefix
);
prefix
=
get_prefix
(
running_suid
,
user_prefix
);
scorefile
=
malloc
(
strlen
(
prefix
)
+
strlen
(
argv
[
optind
])
+
2
);
scorefile
=
malloc
(
strlen
(
prefix
)
+
strlen
(
argv
[
optind
])
+
2
);
if
(
!
scorefile
)
lose_syserr
(
"Couldn't allocate score file"
);
lose_syserr
(
"Couldn't allocate score file"
);
strcpy
(
scorefile
,
prefix
);
strcat
(
scorefile
,
"/"
);
strcat
(
scorefile
,
argv
[
optind
]);
newscore
=
atoi
(
argv
[
optind
+
1
]);
strcpy
(
scorefile
,
prefix
);
strcat
(
scorefile
,
"/"
);
strcat
(
scorefile
,
argv
[
optind
]);
newscore
=
atoi
(
argv
[
optind
+
1
]);
newdata
=
argv
[
optind
+
2
];
if
(
strlen
(
newdata
)
>
MAX_DATA_LEN
)
if
(
strlen
(
newdata
)
>
MAX_DATA_LEN
)
newdata
[
MAX_DATA_LEN
]
=
'\0'
;
if
((
user_id
=
get_user_id
())
==
NULL
)
lose_syserr
(
"Couldn't determine user id"
);
if
((
user_id
=
get_user_id
())
==
NULL
)
lose_syserr
(
"Couldn't determine user id"
);
if
(
stat
(
scorefile
,
&
buf
)
<
0
)
lose_syserr
(
"Failed to access scores file"
);
if
(
stat
(
scorefile
,
&
buf
)
<
0
)
lose_syserr
(
"Failed to access scores file"
);
if
(
lock_file
(
scorefile
,
&
lockstate
)
<
0
)
lose_syserr
(
"Failed to lock scores file"
);
if
(
lock_file
(
scorefile
,
&
lockstate
)
<
0
)
lose_syserr
(
"Failed to lock scores file"
);
if
(
read_scores
(
scorefile
,
&
scores
,
&
scorecount
)
<
0
)
if
(
read_scores
(
scorefile
,
&
scores
,
&
scorecount
)
<
0
)
{
unlock_file
(
scorefile
,
lockstate
);
lose_syserr
(
"Failed to read scores file"
);
unlock_file
(
scorefile
,
lockstate
);
lose_syserr
(
"Failed to read scores file"
);
}
push_score
(
&
scores
,
&
scorecount
,
newscore
,
user_id
,
newdata
);
push_score
(
&
scores
,
&
scorecount
,
newscore
,
user_id
,
newdata
);
/* Limit the number of scores. If we're using reverse sorting, then
we should increment the beginning of the array, to skip over the
*smallest* scores. Otherwise, we just decrement the number of
...
...
@@ -240,58 +236,58 @@ main(argc, argv)
scorecount
-=
(
scorecount
-
MAX_SCORES
);
if
(
reverse
)
scores
+=
(
scorecount
-
MAX_SCORES
);
sort_scores
(
scores
,
scorecount
,
reverse
);
if
(
write_scores
(
scorefile
,
scores
,
scorecount
)
<
0
)
sort_scores
(
scores
,
scorecount
,
reverse
);
if
(
write_scores
(
scorefile
,
scores
,
scorecount
)
<
0
)
{
unlock_file
(
scorefile
,
lockstate
);
lose_syserr
(
"Failed to write scores file"
);
unlock_file
(
scorefile
,
lockstate
);
lose_syserr
(
"Failed to write scores file"
);
}
unlock_file
(
scorefile
,
lockstate
);
exit
(
0
);
unlock_file
(
scorefile
,
lockstate
);
exit
(
0
);
}
int
read_score
(
f
,
score
)
read_score
(
f
,
score
)
FILE
*
f
;
struct
score_entry
*
score
;
{
int
c
;
if
(
feof
(
f
))
if
(
feof
(
f
))
return
1
;
while
((
c
=
getc
(
f
))
!=
EOF
&&
isdigit
(
c
))
while
((
c
=
getc
(
f
))
!=
EOF
&&
isdigit
(
c
))
{
score
->
score
*=
10
;
score
->
score
+=
(
c
-
48
);
}
while
((
c
=
getc
(
f
))
!=
EOF
&&
isspace
(
c
))
while
((
c
=
getc
(
f
))
!=
EOF
&&
isspace
(
c
))
;
if
(
c
==
EOF
)
return
-
1
;
ungetc
(
c
,
f
);
ungetc
(
c
,
f
);
#ifdef HAVE_GETDELIM
{
size_t
count
=
0
;
if
(
getdelim
(
&
score
->
username
,
&
count
,
' '
,
f
)
<
1
if
(
getdelim
(
&
score
->
username
,
&
count
,
' '
,
f
)
<
1
||
score
->
username
==
NULL
)
return
-
1
;
/* Trim the space */
score
->
username
[
strlen
(
score
->
username
)
-
1
]
=
'\0'
;
score
->
username
[
strlen
(
score
->
username
)
-
1
]
=
'\0'
;
}
#else
{
int
unameread
=
0
;
int
unamelen
=
30
;
char
*
username
=
malloc
(
unamelen
);
char
*
username
=
malloc
(
unamelen
);
if
(
!
username
)
return
-
1
;
while
((
c
=
getc
(
f
))
!=
EOF
&&
!
isspace
(
c
))
while
((
c
=
getc
(
f
))
!=
EOF
&&
!
isspace
(
c
))
{
if
(
unameread
>=
unamelen
-
1
)
if
(
!
(
username
=
realloc
(
username
,
unamelen
*=
2
)))
if
(
!
(
username
=
realloc
(
username
,
unamelen
*=
2
)))
return
-
1
;
username
[
unameread
]
=
c
;
unameread
++
;
...
...
@@ -307,23 +303,23 @@ read_score(f, score)
errno
=
0
;
{
size_t
len
;
if
(
getline
(
&
score
->
data
,
&
len
,
f
)
<
0
)
if
(
getline
(
&
score
->
data
,
&
len
,
f
)
<
0
)
return
-
1
;
score
->
data
[
strlen
(
score
->
data
)
-
1
]
=
'\0'
;
score
->
data
[
strlen
(
score
->
data
)
-
1
]
=
'\0'
;
}
#else
{
int
cur
=
0
;
int
len
=
16
;
char
*
buf
=
malloc
(
len
);
char
*
buf
=
malloc
(
len
);
if
(
!
buf
)
return
-
1
;
while
((
c
=
getc
(
f
))
!=
EOF
while
((
c
=
getc
(
f
))
!=
EOF
&&
c
!=
'\n'
)
{
if
(
cur
>=
len
-
1
)
{
if
(
!
(
buf
=
realloc
(
buf
,
len
*=
2
)))
if
(
!
(
buf
=
realloc
(
buf
,
len
*=
2
)))
return
-
1
;
}
buf
[
cur
]
=
c
;
...
...
@@ -337,22 +333,22 @@ read_score(f, score)
}
int
read_scores
(
filename
,
scores
,
count
)
read_scores
(
filename
,
scores
,
count
)
const
char
*
filename
;
struct
score_entry
**
scores
;
int
*
count
;
{
int
readval
,
scorecount
,
cursize
;
struct
score_entry
*
ret
;
FILE
*
f
=
fopen
(
filename
,
"r"
);
FILE
*
f
=
fopen
(
filename
,
"r"
);
if
(
!
f
)
return
-
1
;
scorecount
=
0
;
cursize
=
16
;
ret
=
malloc
(
sizeof
(
struct
score_entry
)
*
cursize
);
ret
=
malloc
(
sizeof
(
struct
score_entry
)
*
cursize
);
if
(
!
ret
)
return
-
1
;
while
((
readval
=
read_score
(
f
,
&
ret
[
scorecount
]))
==
0
)
while
((
readval
=
read_score
(
f
,
&
ret
[
scorecount
]))
==
0
)
{
/* We encoutered an error */
if
(
readval
<
0
)
...
...
@@ -360,7 +356,7 @@ read_scores(filename, scores, count)
scorecount
++
;
if
(
scorecount
>=
cursize
)
{
ret
=
realloc
(
ret
,
cursize
*=
2
);
ret
=
realloc
(
ret
,
cursize
*=
2
);
if
(
!
ret
)
return
-
1
;
}
...
...
@@ -371,7 +367,7 @@ read_scores(filename, scores, count)
}
int
score_compare
(
a
,
b
)
score_compare
(
a
,
b
)
const
void
*
a
;
const
void
*
b
;
{
...
...
@@ -381,7 +377,7 @@ score_compare(a, b)
}
int
score_compare_reverse
(
a
,
b
)
score_compare_reverse
(
a
,
b
)
const
void
*
a
;
const
void
*
b
;
{
...
...
@@ -391,14 +387,15 @@ score_compare_reverse(a, b)
}
int
push_score
(
scores
,
count
,
newscore
,
username
,
newdata
)
push_score
(
scores
,
count
,
newscore
,
username
,
newdata
)
struct
score_entry
**
scores
;
int
*
count
;
int
newscore
;
char
*
username
;
char
*
newdata
;
{
struct
score_entry
*
newscores
=
realloc
(
*
scores
,
sizeof
(
struct
score_entry
)
*
((
*
count
)
+
1
));
struct
score_entry
*
newscores
=
realloc
(
*
scores
,
sizeof
(
struct
score_entry
)
*
((
*
count
)
+
1
));
if
(
!
newscores
)
return
-
1
;
newscores
[
*
count
].
score
=
newscore
;
...
...
@@ -410,49 +407,49 @@ push_score(scores, count, newscore, username, newdata)
}
void
sort_scores
(
scores
,
count
,
reverse
)
sort_scores
(
scores
,
count
,
reverse
)
struct
score_entry
*
scores
;
int
count
;
int
reverse
;
{
qsort
(
scores
,
count
,
sizeof
(
struct
score_entry
),
qsort
(
scores
,
count
,
sizeof
(
struct
score_entry
),
reverse
?
score_compare_reverse
:
score_compare
);
}
int
write_scores
(
filename
,
scores
,
count
)
write_scores
(
filename
,
scores
,
count
)
const
char
*
filename
;
const
struct
score_entry
*
scores
;
int
count
;
{
FILE
*
f
;
int
i
;
char
*
tempfile
=
malloc
(
strlen
(
filename
)
+
strlen
(
".tempXXXXXX"
)
+
1
);
char
*
tempfile
=
malloc
(
strlen
(
filename
)
+
strlen
(
".tempXXXXXX"
)
+
1
);
if
(
!
tempfile
)
return
-
1
;
strcpy
(
tempfile
,
filename
);
strcat
(
tempfile
,
".tempXXXXXX"
);
strcpy
(
tempfile
,
filename
);
strcat
(
tempfile
,
".tempXXXXXX"
);
#ifdef HAVE_MKSTEMP
if
(
mkstemp
(
tempfile
)
<
0
if
(
mkstemp
(
tempfile
)
<
0
#else
if
(
mktemp
(
tempfile
)
!=
tempfile
if
(
mktemp
(
tempfile
)
!=
tempfile
#endif
||
!
(
f
=
fopen
(
tempfile
,
"w"
)))
||
!
(
f
=
fopen
(
tempfile
,
"w"
)))
return
-
1
;
for
(
i
=
0
;
i
<
count
;
i
++
)
if
(
fprintf
(
f
,
"%ld %s %s
\n
"
,
scores
[
i
].
score
,
scores
[
i
].
username
,
if
(
fprintf
(
f
,
"%ld %s %s
\n
"
,
scores
[
i
].
score
,
scores
[
i
].
username
,
scores
[
i
].
data
)
<
0
)
return
-
1
;
fclose
(
f
);
if
(
rename
(
tempfile
,
filename
)
<
0
)
fclose
(
f
);
if
(
rename
(
tempfile
,
filename
)
<
0
)
return
-
1
;
if
(
chmod
(
filename
,
0644
)
<
0
)
if
(
chmod
(
filename
,
0644
)
<
0
)
return
-
1
;
return
0
;
}
int
lock_file
(
filename
,
state
)
lock_file
(
filename
,
state
)
const
char
*
filename
;
void
**
state
;
{
...
...
@@ -460,19 +457,19 @@ lock_file(filename, state)
struct
stat
buf
;
int
attempts
=
0
;
char
*
lockext
=
".lockfile"
;
char
*
lockpath
=
malloc
(
strlen
(
filename
)
+
strlen
(
lockext
)
+
60
);
char
*
lockpath
=
malloc
(
strlen
(
filename
)
+
strlen
(
lockext
)
+
60
);
if
(
!
lockpath
)
return
-
1
;
strcpy
(
lockpath
,
filename
);
strcat
(
lockpath
,
lockext
);
strcpy
(
lockpath
,
filename
);
strcat
(
lockpath
,
lockext
);
*
state
=
lockpath
;
trylock:
attempts
++
;
/* If the lock is over an hour old, delete it. */
if
(
stat
(
lockpath
,
&
buf
)
==
0
&&
(
difftime
(
buf
.
st_ctime
,
time
(
NULL
)
>
60
*
60
)))
unlink
(
lockpath
);
if
((
fd
=
open
(
lockpath
,
O_CREAT
|
O_EXCL
,
0600
))
<
0
)
if
(
stat
(
lockpath
,
&
buf
)
==
0
&&
(
difftime
(
buf
.
st_ctime
,
time
(
NULL
)
>
60
*
60
)))
unlink
(
lockpath
);
if
((
fd
=
open
(
lockpath
,
O_CREAT
|
O_EXCL
,
0600
))
<
0
)
{
if
(
errno
==
EEXIST
)
{
...
...
@@ -480,28 +477,28 @@ lock_file(filename, state)
lose some scores. */
if
(
attempts
>
MAX_ATTEMPTS
)
{
unlink
(
lockpath
);
unlink
(
lockpath
);
attempts
=
0
;
}
sleep
((
rand
()
%
2
)
+
1
);
sleep
((
rand
()
%
2
)
+
1
);
goto
trylock
;
}
else
return
-
1
;
}
close
(
fd
);
close
(
fd
);
return
0
;
}
int
unlock_file
(
filename
,
state
)
unlock_file
(
filename
,
state
)
const
char
*
filename
;
void
*
state
;
{
char
*
lockpath
=
(
char
*
)
state
;
int
ret
=
unlink
(
lockpath
);
int
ret
=
unlink
(
lockpath
);
int
saved_errno
=
errno
;
free
(
lockpath
);
free
(
lockpath
);
errno
=
saved_errno
;
return
ret
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment