Merge pull request #13 from wdlkmpx/patch1
store files in $XDG_CONFIG_HOME/games
This commit is contained in:
commit
0f4151f689
@ -7,7 +7,7 @@ gtkballs_SOURCES = gtkballs.c gtkballs.h gfx.c gfx.h \
|
|||||||
path.c path.h preferences.c preferences.h \
|
path.c path.h preferences.c preferences.h \
|
||||||
scoreboard.c scoreboard.h themerc.c themerc.h \
|
scoreboard.c scoreboard.h themerc.c themerc.h \
|
||||||
gtkutils.c gtkutils.h mainmenu.c mainmenu.h \
|
gtkutils.c gtkutils.h mainmenu.c mainmenu.h \
|
||||||
rules.c rules.h about.c about.h child.c child.h \
|
rules.c rules.h about.c about.h \
|
||||||
theme.c theme.h savegame.c savegame.h \
|
theme.c theme.h savegame.c savegame.h \
|
||||||
savedialog.c savedialog.h halloffame.c halloffame.h \
|
savedialog.c savedialog.h halloffame.c halloffame.h \
|
||||||
inputname.c inputname.h rulesdialog.c rulesdialog.h \
|
inputname.c inputname.h rulesdialog.c rulesdialog.h \
|
||||||
|
147
src/child.c
147
src/child.c
@ -1,147 +0,0 @@
|
|||||||
/* child.c - spawn child, that works with extra privileges
|
|
||||||
* to be able to write scores.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2 of the License, or (at your option) any later version.
|
|
||||||
*/
|
|
||||||
#include <glib.h>
|
|
||||||
#include <sys/time.h> /* select() */
|
|
||||||
#include <sys/types.h> /* pid_t */
|
|
||||||
#include <sys/stat.h> /* open() */
|
|
||||||
#include <fcntl.h> /* fcntl() */
|
|
||||||
#include <signal.h> /* sigaction() */
|
|
||||||
#include <unistd.h> /* pipe() */
|
|
||||||
#include <string.h> /* strerror() */
|
|
||||||
#include <errno.h> /* errno */
|
|
||||||
#include <stdlib.h> /* exit() */
|
|
||||||
#include <sys/wait.h> /* waitpid() */
|
|
||||||
#include <stdio.h> /* printf() */
|
|
||||||
|
|
||||||
volatile sig_atomic_t _child_writer_alive = 0;
|
|
||||||
gboolean _child_writer_dead_warned = 0;
|
|
||||||
|
|
||||||
int child_writer_alive(void){
|
|
||||||
return _child_writer_alive;
|
|
||||||
}
|
|
||||||
|
|
||||||
int child_writer_dead_handler(void) {
|
|
||||||
if (_child_writer_alive == 0 && _child_writer_dead_warned == 0) {
|
|
||||||
_child_writer_dead_warned = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void child_process_score_writer(int chfd, gchar *score_file)
|
|
||||||
{
|
|
||||||
fd_set rfds;
|
|
||||||
int i;
|
|
||||||
int fd=-1;
|
|
||||||
gchar *buf;
|
|
||||||
size_t sz;
|
|
||||||
sigset_t sset;
|
|
||||||
struct flock lockinfo;
|
|
||||||
gchar *score_file_full = g_strconcat(LOCALSTATEDIR, score_file, NULL);
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
FD_ZERO(&rfds);
|
|
||||||
FD_SET(chfd, &rfds);
|
|
||||||
if (select(chfd + 1, &rfds, NULL, NULL, NULL) > 0)
|
|
||||||
{
|
|
||||||
if (read(chfd, &sz, sizeof(sz)) <= 0) {
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
/* block signals before writing, to prevent possible file corruption */
|
|
||||||
sigemptyset(&sset);
|
|
||||||
sigaddset(&sset, SIGHUP);
|
|
||||||
sigaddset(&sset, SIGINT);
|
|
||||||
sigaddset(&sset, SIGQUIT);
|
|
||||||
sigaddset(&sset, SIGTERM);
|
|
||||||
sigprocmask(SIG_BLOCK, &sset, NULL);
|
|
||||||
fd = open(score_file_full, O_WRONLY | O_TRUNC);
|
|
||||||
if (fd != -1) {
|
|
||||||
/* get write lock before writing scores */
|
|
||||||
lockinfo.l_whence = SEEK_SET;
|
|
||||||
lockinfo.l_start = 0;
|
|
||||||
lockinfo.l_len = 0;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
while (1) {
|
|
||||||
lockinfo.l_type=F_WRLCK;
|
|
||||||
if (!fcntl(fd, F_SETLK, &lockinfo)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (i >= 3) {
|
|
||||||
close(fd);
|
|
||||||
fd = -1;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (sz > 0) {
|
|
||||||
buf=g_malloc(sz);
|
|
||||||
read(chfd, buf, sz);
|
|
||||||
if (fd != -1) {
|
|
||||||
write(fd, buf, sz);
|
|
||||||
}
|
|
||||||
g_free(buf);
|
|
||||||
read(chfd, &sz, sizeof(sz));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fd != -1) {
|
|
||||||
close(fd);
|
|
||||||
} else {
|
|
||||||
/* FIXME: here should be some sort of error reporting to parent */
|
|
||||||
}
|
|
||||||
sigprocmask(SIG_UNBLOCK, &sset, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sigchld_handler(int param)
|
|
||||||
{
|
|
||||||
pid_t ret = waitpid(0, NULL, WNOHANG);
|
|
||||||
|
|
||||||
if (ret > 0) { /* score writer process killed by bastards! */
|
|
||||||
_child_writer_alive = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int child_setup(gchar *score_file)
|
|
||||||
{
|
|
||||||
pid_t pid;
|
|
||||||
struct sigaction sact;
|
|
||||||
int sfds[2];
|
|
||||||
|
|
||||||
/* set up SIGCHLD handler, so we can know if our score writer process
|
|
||||||
terminated while we run... */
|
|
||||||
sact.sa_handler = sigchld_handler;
|
|
||||||
sigemptyset(&sact.sa_mask);
|
|
||||||
sact.sa_flags = 0;
|
|
||||||
#ifdef SA_RESTART
|
|
||||||
sact.sa_flags |= SA_RESTART;
|
|
||||||
#endif
|
|
||||||
if (sigaction(SIGCHLD, &sact, NULL) < 0) {
|
|
||||||
printf("cannot setup SIGCHLD handler.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (pipe(sfds) == -1) {
|
|
||||||
printf("pipe() failed: %s\n", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
pid = fork();
|
|
||||||
if (pid == -1) {
|
|
||||||
printf("cannot fork: %s\n", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
} else if (pid == 0) {
|
|
||||||
close(sfds[1]);
|
|
||||||
child_process_score_writer(sfds[0], score_file);
|
|
||||||
}
|
|
||||||
close(sfds[0]);
|
|
||||||
_child_writer_alive = 1;
|
|
||||||
|
|
||||||
return sfds[1];
|
|
||||||
}
|
|
13
src/child.h
13
src/child.h
@ -1,13 +0,0 @@
|
|||||||
#ifndef __CHILD_H__
|
|
||||||
#define __CHILD_H__
|
|
||||||
|
|
||||||
/* spawn score writer process */
|
|
||||||
int child_setup(gchar *score_file);
|
|
||||||
|
|
||||||
/* check if child process alive or not */
|
|
||||||
int child_writer_alive(void);
|
|
||||||
|
|
||||||
/* check score writer process and display warning if not running */
|
|
||||||
int child_writer_dead_handler(void);
|
|
||||||
|
|
||||||
#endif
|
|
@ -16,12 +16,36 @@
|
|||||||
#include "prefs.h" /* preferences */
|
#include "prefs.h" /* preferences */
|
||||||
#include "scoreboard.h" /* read_score, score_setup */
|
#include "scoreboard.h" /* read_score, score_setup */
|
||||||
#include "gfx.h"
|
#include "gfx.h"
|
||||||
#include "child.h"
|
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
#include "inputname.h" /* input_name_dialog */
|
#include "inputname.h" /* input_name_dialog */
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "mainmenu.h"
|
#include "mainmenu.h"
|
||||||
#include "mainwin.h"
|
#include "mainwin.h"
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h> /* mkdir */
|
||||||
|
|
||||||
|
|
||||||
|
#define P_DIR "games"
|
||||||
|
char * get_config_dir_file (const char * file)
|
||||||
|
{
|
||||||
|
/* returns a path that must be freed with g_free */
|
||||||
|
char * config_home, * res;
|
||||||
|
#if __MINGW32__
|
||||||
|
config_home = getenv ("LOCALAPPDATA"); /* XP */
|
||||||
|
if (!config_home) {
|
||||||
|
config_home = getenv ("APPDATA");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
config_home = getenv ("XDG_CONFIG_HOME");
|
||||||
|
#endif
|
||||||
|
if (config_home) {
|
||||||
|
res = g_build_filename (config_home, P_DIR, file, NULL);
|
||||||
|
} else {
|
||||||
|
res = g_build_filename (g_get_home_dir(), ".config", P_DIR, file, NULL);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gint destroy_lines(gboolean count_score) {
|
gint destroy_lines(gboolean count_score) {
|
||||||
gint i = game_destroy_lines(count_score);
|
gint i = game_destroy_lines(count_score);
|
||||||
@ -113,6 +137,7 @@ void new_game(void)
|
|||||||
draw_board();
|
draw_board();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================================================================
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -120,7 +145,7 @@ int main(int argc, char **argv)
|
|||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct timezone tz;
|
struct timezone tz;
|
||||||
struct score_board scoreboard[10];
|
struct score_board scoreboard[10];
|
||||||
gchar *err, *mapfile;
|
gchar *err, *mapfile, * confdir;
|
||||||
|
|
||||||
/* setup all i18n stuff */
|
/* setup all i18n stuff */
|
||||||
#ifdef ENABLE_NLS
|
#ifdef ENABLE_NLS
|
||||||
@ -129,21 +154,21 @@ int main(int argc, char **argv)
|
|||||||
bind_textdomain_codeset(PACKAGE, "UTF8");
|
bind_textdomain_codeset(PACKAGE, "UTF8");
|
||||||
#endif /* ENABLE_NLS */
|
#endif /* ENABLE_NLS */
|
||||||
|
|
||||||
/* drop privileges after spawning child with extra privs */
|
|
||||||
if (score_setup() == -1)
|
|
||||||
return 1;
|
|
||||||
setregid(getgid(), getgid());
|
|
||||||
|
|
||||||
/* initialize random seed */
|
/* initialize random seed */
|
||||||
gettimeofday(&tv, &tz);
|
gettimeofday(&tv, &tz);
|
||||||
srand((unsigned int)tv.tv_usec);
|
srand((unsigned int)tv.tv_usec);
|
||||||
|
|
||||||
/* load user's preferences */
|
|
||||||
load_preferences();
|
|
||||||
|
|
||||||
/* initialize gtk */
|
/* initialize gtk */
|
||||||
gtk_init (&argc, &argv);
|
gtk_init (&argc, &argv);
|
||||||
|
|
||||||
|
/* Make sure confdir exists */
|
||||||
|
confdir = get_config_dir_file (NULL);
|
||||||
|
g_mkdir_with_parents (confdir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
||||||
|
g_free (confdir);
|
||||||
|
|
||||||
|
/* load user's preferences */
|
||||||
|
load_preferences();
|
||||||
|
|
||||||
/* load theme, fallback to default if specifed theme cannot be loaded */
|
/* load theme, fallback to default if specifed theme cannot be loaded */
|
||||||
if (!(i = load_theme(pref_get_theme_name()))) {
|
if (!(i = load_theme(pref_get_theme_name()))) {
|
||||||
if (strcmp(pref_get_theme_name(), pref_get_default_theme_name()) != 0) {
|
if (strcmp(pref_get_theme_name(), pref_get_default_theme_name()) != 0) {
|
||||||
@ -170,20 +195,18 @@ int main(int argc, char **argv)
|
|||||||
remake_board(-1, 1);
|
remake_board(-1, 1);
|
||||||
|
|
||||||
/* read and set scores */
|
/* read and set scores */
|
||||||
if (!read_score(scoreboard, NULL, NULL)) {
|
read_score (scoreboard, NULL, NULL);
|
||||||
ut_simple_message_box(_("Unable to read score.\n"));
|
|
||||||
}
|
|
||||||
mw_set_hi_score(scoreboard[0].score);
|
mw_set_hi_score(scoreboard[0].score);
|
||||||
mw_set_user_score(0);
|
mw_set_user_score(0);
|
||||||
|
|
||||||
mapfile = g_strconcat(getenv("HOME"), G_DIR_SEPARATOR_S, ".gtkballs",
|
mapfile = get_config_dir_file ("gtkballs-accel.map");
|
||||||
G_DIR_SEPARATOR_S, "accel.map", NULL);
|
|
||||||
gtk_accel_map_load (mapfile);
|
gtk_accel_map_load (mapfile);
|
||||||
|
|
||||||
/* enter main application loop */
|
/* enter main application loop */
|
||||||
gtk_main();
|
gtk_main();
|
||||||
|
|
||||||
gtk_accel_map_save (mapfile);
|
gtk_accel_map_save (mapfile);
|
||||||
|
g_free (mapfile);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ extern GtkWindow * main_window;
|
|||||||
# define N_(String) (String)
|
# define N_(String) (String)
|
||||||
#endif /* ENABLE_NLS */
|
#endif /* ENABLE_NLS */
|
||||||
|
|
||||||
|
char * get_config_dir_file (const char * file);
|
||||||
void new_game(void);
|
void new_game(void);
|
||||||
void new_turn(gint number, gboolean first);
|
void new_turn(gint number, gboolean first);
|
||||||
void undo_move(GtkWidget *widget, gpointer data);
|
void undo_move(GtkWidget *widget, gpointer data);
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#include "gtkutils.h"
|
#include "gtkutils.h"
|
||||||
#include "mainmenu.h" /* menu_* */
|
#include "mainmenu.h" /* menu_* */
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "child.h"
|
|
||||||
|
|
||||||
GtkWindow * main_window;
|
GtkWindow * main_window;
|
||||||
|
|
||||||
@ -78,12 +77,6 @@ gboolean _countdown_timer(gpointer data)
|
|||||||
GtkLabel *label = data;
|
GtkLabel *label = data;
|
||||||
gint trem;
|
gint trem;
|
||||||
|
|
||||||
if (child_writer_dead_handler()) {
|
|
||||||
ut_simple_message_box_with_title(_("Score writer process died unexpectedly. No scores will be writen!\n" \
|
|
||||||
"Save your game and restart programm.\n"),
|
|
||||||
_("Who Killed Bambi?"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!timer_is_running()) {
|
if (!timer_is_running()) {
|
||||||
gtk_label_set_text(label, _("Time is unlimited"));
|
gtk_label_set_text(label, _("Time is unlimited"));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
17
src/prefs.c
17
src/prefs.c
@ -15,7 +15,7 @@
|
|||||||
#include "gtkballs.h" /* for _() */
|
#include "gtkballs.h" /* for _() */
|
||||||
|
|
||||||
#define BUFFER_SIZE 1024
|
#define BUFFER_SIZE 1024
|
||||||
#define CONFIG_FILE_NAME ".gtkballsrc"
|
#define CONFIG_FILE_NAME "gtkballs.ini"
|
||||||
|
|
||||||
gint _show_next_colors = TRUE;
|
gint _show_next_colors = TRUE;
|
||||||
gint _show_path = TRUE;
|
gint _show_path = TRUE;
|
||||||
@ -112,17 +112,6 @@ void pref_set_theme_name(gchar *name) {
|
|||||||
_theme_name = g_strdup(name);
|
_theme_name = g_strdup(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
gchar *find_rc_file(void) {
|
|
||||||
gchar *rc_file = NULL;
|
|
||||||
|
|
||||||
if (getenv("HOME")) {
|
|
||||||
rc_file = g_strdup_printf("%s/%s", getenv ("HOME"), CONFIG_FILE_NAME);
|
|
||||||
} else { /* unable to find $HOME, assuming current directory */
|
|
||||||
rc_file = g_strdup(CONFIG_FILE_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc_file;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* converts string to TRUE/FALSE. "true", "yes" or "1" is TRUE, otherwise - FALSE */
|
/* converts string to TRUE/FALSE. "true", "yes" or "1" is TRUE, otherwise - FALSE */
|
||||||
gboolean pref_str_to_bool(gchar *val) {
|
gboolean pref_str_to_bool(gchar *val) {
|
||||||
@ -152,7 +141,7 @@ void load_preferences(void)
|
|||||||
if (!_theme_name) {
|
if (!_theme_name) {
|
||||||
_theme_name = g_strdup(_default_theme_name);
|
_theme_name = g_strdup(_default_theme_name);
|
||||||
}
|
}
|
||||||
rc_file = find_rc_file();
|
rc_file = get_config_dir_file (CONFIG_FILE_NAME);
|
||||||
if ((fp = fopen(rc_file, "r")))
|
if ((fp = fopen(rc_file, "r")))
|
||||||
{
|
{
|
||||||
while(fgets(buffer, BUFFER_SIZE, fp))
|
while(fgets(buffer, BUFFER_SIZE, fp))
|
||||||
@ -219,7 +208,7 @@ gchar *save_preferences (void)
|
|||||||
gchar *rc_file/*, *err*/;
|
gchar *rc_file/*, *err*/;
|
||||||
gchar *ret = NULL;
|
gchar *ret = NULL;
|
||||||
|
|
||||||
rc_file = find_rc_file();
|
rc_file = get_config_dir_file (CONFIG_FILE_NAME);
|
||||||
if ((fp = fopen(rc_file, "w"))) {
|
if ((fp = fopen(rc_file, "w"))) {
|
||||||
write_pref_string(fp, "show_hints", pref_bool_to_str(_show_next_colors));
|
write_pref_string(fp, "show_hints", pref_bool_to_str(_show_next_colors));
|
||||||
write_pref_string(fp, "show_path", pref_bool_to_str(_show_path));
|
write_pref_string(fp, "show_path", pref_bool_to_str(_show_path));
|
||||||
|
@ -16,19 +16,11 @@
|
|||||||
#include "gtkballs.h"
|
#include "gtkballs.h"
|
||||||
#include "scoreboard.h"
|
#include "scoreboard.h"
|
||||||
|
|
||||||
#include "child.h" /* child_writer_alive, child_setup */
|
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
|
|
||||||
|
#define SCORE_FILE "gtkballs-scores"
|
||||||
#define BUFFER_SIZE 1024
|
#define BUFFER_SIZE 1024
|
||||||
|
|
||||||
int _score_fd = -1;
|
|
||||||
|
|
||||||
gint score_setup(void)
|
|
||||||
{
|
|
||||||
_score_fd = child_setup(SCORE_FILE);
|
|
||||||
return _score_fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void free_score_board_full(struct score_board_full *bf, gint nbf)
|
void free_score_board_full(struct score_board_full *bf, gint nbf)
|
||||||
{
|
{
|
||||||
@ -44,10 +36,13 @@ void free_score_board_full(struct score_board_full *bf, gint nbf)
|
|||||||
gint write_score(struct score_board *b, struct score_board_full *bf, gint nbf)
|
gint write_score(struct score_board *b, struct score_board_full *bf, gint nbf)
|
||||||
{
|
{
|
||||||
gint i;
|
gint i;
|
||||||
gchar *buf, *tname, *tdate, *rules;
|
gchar *tname, *tdate, *rules;
|
||||||
size_t sz;
|
char * score_file = get_config_dir_file (SCORE_FILE);
|
||||||
|
FILE * fd;
|
||||||
|
|
||||||
if (child_writer_alive() == 0) {
|
fd = fopen (score_file, "w");
|
||||||
|
if (!fd) {
|
||||||
|
g_free (score_file);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,27 +58,19 @@ gint write_score(struct score_board *b, struct score_board_full *bf, gint nbf)
|
|||||||
tdate = g_strdup(_("Unknown"));
|
tdate = g_strdup(_("Unknown"));
|
||||||
}
|
}
|
||||||
rules = rules_get_as_str();
|
rules = rules_get_as_str();
|
||||||
buf = g_strdup_printf("%s\t%i\t%s\t%s\n", tname, b[i].score, tdate, rules);
|
fprintf (fd, "%s\t%i\t%s\t%s\n", tname, b[i].score, tdate, rules);
|
||||||
sz = strlen(buf);
|
|
||||||
write(_score_fd, &sz, sizeof(sz));
|
|
||||||
write(_score_fd, buf, strlen(buf));
|
|
||||||
g_free(rules);
|
g_free(rules);
|
||||||
g_free(tdate);
|
g_free(tdate);
|
||||||
g_free(tname);
|
g_free(tname);
|
||||||
g_free(buf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < nbf; i++) {
|
for (i = 0; i < nbf; i++) {
|
||||||
if (strlen(bf[i].name)) {
|
if (strlen(bf[i].name)) {
|
||||||
buf = g_strdup_printf("%s\t%i\t%s\t%s\n", bf[i].name, bf[i].score, bf[i].date, bf[i].rules);
|
fprintf (fd, "%s\t%i\t%s\t%s\n", bf[i].name, bf[i].score, bf[i].date, bf[i].rules);
|
||||||
sz = strlen(buf);
|
|
||||||
write(_score_fd, &sz, sizeof(sz));
|
|
||||||
write(_score_fd, buf, strlen(buf));
|
|
||||||
g_free(buf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sz = 0;
|
g_free (score_file);
|
||||||
write(_score_fd, &sz, sizeof(sz));
|
fclose (fd);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -104,24 +91,20 @@ gint read_score(struct score_board *b, struct score_board_full **bf, gint *nbf)
|
|||||||
gchar **str_val, *tstr, **tstr_val;
|
gchar **str_val, *tstr, **tstr_val;
|
||||||
gint valid, sc, fsc;
|
gint valid, sc, fsc;
|
||||||
gsize br, bw;
|
gsize br, bw;
|
||||||
struct flock lockinfo;
|
char * score_file = get_config_dir_file (SCORE_FILE);
|
||||||
|
|
||||||
gchar *g_rules = NULL;
|
gchar *g_rules = NULL;
|
||||||
|
|
||||||
memset(b, 0, sizeof(struct score_board) * 10);
|
memset(b, 0, sizeof(struct score_board) * 10);
|
||||||
|
|
||||||
if (!(fp = fopen(LOCALSTATEDIR SCORE_FILE, "r"))) {
|
if (!(fp = fopen(score_file, "r"))) {
|
||||||
return FALSE;
|
if (nbf) {
|
||||||
|
*nbf = 0;
|
||||||
|
}
|
||||||
|
g_free (score_file);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
|
||||||
lockinfo.l_whence = SEEK_SET;
|
|
||||||
lockinfo.l_start = 0;
|
|
||||||
lockinfo.l_len = 0;
|
|
||||||
lockinfo.l_type = F_WRLCK;
|
|
||||||
fcntl(fileno(fp), F_GETLK, &lockinfo);
|
|
||||||
} while (lockinfo.l_type != F_UNLCK);
|
|
||||||
|
|
||||||
sc = 0;
|
sc = 0;
|
||||||
fsc = 0;
|
fsc = 0;
|
||||||
while (fgets(buffer, BUFFER_SIZE, fp))
|
while (fgets(buffer, BUFFER_SIZE, fp))
|
||||||
@ -198,6 +181,8 @@ gint read_score(struct score_board *b, struct score_board_full **bf, gint *nbf)
|
|||||||
}
|
}
|
||||||
g_strfreev(str_val);
|
g_strfreev(str_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_free (score_file);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
qsort(b, 10, sizeof(struct score_board), score_sort);
|
qsort(b, 10, sizeof(struct score_board), score_sort);
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#ifndef __SCOREBOARD_H__
|
#ifndef __SCOREBOARD_H__
|
||||||
#define __SCOREBOARD_H__
|
#define __SCOREBOARD_H__
|
||||||
|
|
||||||
#define SCORE_FILE "/gtkballs-scores"
|
|
||||||
|
|
||||||
struct score_board {
|
struct score_board {
|
||||||
gchar name[30];
|
gchar name[30];
|
||||||
gint score;
|
gint score;
|
||||||
@ -16,8 +14,6 @@ struct score_board_full {
|
|||||||
gchar *rules;
|
gchar *rules;
|
||||||
};
|
};
|
||||||
|
|
||||||
gint score_setup(void);
|
|
||||||
|
|
||||||
void free_score_board_full(struct score_board_full *bf, gint nbf);
|
void free_score_board_full(struct score_board_full *bf, gint nbf);
|
||||||
gint write_score(struct score_board *, struct score_board_full *, gint);
|
gint write_score(struct score_board *, struct score_board_full *, gint);
|
||||||
gint read_score(struct score_board *, struct score_board_full **, gint *);
|
gint read_score(struct score_board *, struct score_board_full **, gint *);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user