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
emacs
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
1
Issues
1
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
emacs
emacs
Commits
a5d107f3
Commit
a5d107f3
authored
Feb 04, 2003
by
Richard M. Stallman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
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