diff --git a/src/Makefile.am b/src/Makefile.am index d34b3df..6120ff6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,7 +7,7 @@ gtkballs_SOURCES = gtkballs.c gtkballs.h gfx.c gfx.h \ path.c path.h preferences.c preferences.h \ scoreboard.c scoreboard.h themerc.c themerc.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 \ savedialog.c savedialog.h halloffame.c halloffame.h \ inputname.c inputname.h rulesdialog.c rulesdialog.h \ diff --git a/src/child.c b/src/child.c deleted file mode 100644 index 8959210..0000000 --- a/src/child.c +++ /dev/null @@ -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 -#include /* select() */ -#include /* pid_t */ -#include /* open() */ -#include /* fcntl() */ -#include /* sigaction() */ -#include /* pipe() */ -#include /* strerror() */ -#include /* errno */ -#include /* exit() */ -#include /* waitpid() */ -#include /* 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]; -} diff --git a/src/child.h b/src/child.h deleted file mode 100644 index 8f9a29d..0000000 --- a/src/child.h +++ /dev/null @@ -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 diff --git a/src/gtkballs.c b/src/gtkballs.c index 99937ea..372614c 100644 --- a/src/gtkballs.c +++ b/src/gtkballs.c @@ -16,7 +16,6 @@ #include "prefs.h" /* preferences */ #include "scoreboard.h" /* read_score, score_setup */ #include "gfx.h" -#include "child.h" #include "theme.h" #include "inputname.h" /* input_name_dialog */ #include "game.h" @@ -155,11 +154,6 @@ int main(int argc, char **argv) bind_textdomain_codeset(PACKAGE, "UTF8"); #endif /* ENABLE_NLS */ - /* drop privileges after spawning child with extra privs */ - if (score_setup() == -1) - return 1; - setregid(getgid(), getgid()); - /* initialize random seed */ gettimeofday(&tv, &tz); srand((unsigned int)tv.tv_usec); @@ -201,9 +195,7 @@ int main(int argc, char **argv) remake_board(-1, 1); /* read and set scores */ - if (!read_score(scoreboard, NULL, NULL)) { - ut_simple_message_box(_("Unable to read score.\n")); - } + read_score (scoreboard, NULL, NULL); mw_set_hi_score(scoreboard[0].score); mw_set_user_score(0); diff --git a/src/mainwin.c b/src/mainwin.c index 268e3f5..86983b7 100644 --- a/src/mainwin.c +++ b/src/mainwin.c @@ -14,7 +14,6 @@ #include "gtkutils.h" #include "mainmenu.h" /* menu_* */ #include "game.h" -#include "child.h" GtkWindow * main_window; @@ -78,12 +77,6 @@ gboolean _countdown_timer(gpointer data) GtkLabel *label = data; 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()) { gtk_label_set_text(label, _("Time is unlimited")); return TRUE; diff --git a/src/scoreboard.c b/src/scoreboard.c index 571ca8e..688bc26 100644 --- a/src/scoreboard.c +++ b/src/scoreboard.c @@ -16,19 +16,11 @@ #include "gtkballs.h" #include "scoreboard.h" -#include "child.h" /* child_writer_alive, child_setup */ #include "game.h" +#define SCORE_FILE "gtkballs-scores" #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) { @@ -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 i; - gchar *buf, *tname, *tdate, *rules; - size_t sz; + gchar *tname, *tdate, *rules; + 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; } @@ -63,27 +58,19 @@ gint write_score(struct score_board *b, struct score_board_full *bf, gint nbf) tdate = g_strdup(_("Unknown")); } rules = rules_get_as_str(); - buf = g_strdup_printf("%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)); + fprintf (fd, "%s\t%i\t%s\t%s\n", tname, b[i].score, tdate, rules); g_free(rules); g_free(tdate); g_free(tname); - g_free(buf); } } for (i = 0; i < nbf; i++) { 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); - sz = strlen(buf); - write(_score_fd, &sz, sizeof(sz)); - write(_score_fd, buf, strlen(buf)); - g_free(buf); + fprintf (fd, "%s\t%i\t%s\t%s\n", bf[i].name, bf[i].score, bf[i].date, bf[i].rules); } } - sz = 0; - write(_score_fd, &sz, sizeof(sz)); + g_free (score_file); + fclose (fd); return TRUE; } @@ -104,24 +91,17 @@ gint read_score(struct score_board *b, struct score_board_full **bf, gint *nbf) gchar **str_val, *tstr, **tstr_val; gint valid, sc, fsc; gsize br, bw; - struct flock lockinfo; + char * score_file = get_config_dir_file (SCORE_FILE); gchar *g_rules = NULL; memset(b, 0, sizeof(struct score_board) * 10); - if (!(fp = fopen(LOCALSTATEDIR SCORE_FILE, "r"))) { - return FALSE; + if (!(fp = fopen(score_file, "r"))) { + 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; fsc = 0; while (fgets(buffer, BUFFER_SIZE, fp)) @@ -198,6 +178,8 @@ gint read_score(struct score_board *b, struct score_board_full **bf, gint *nbf) } g_strfreev(str_val); } + + g_free (score_file); fclose(fp); qsort(b, 10, sizeof(struct score_board), score_sort); diff --git a/src/scoreboard.h b/src/scoreboard.h index 328e526..788376b 100644 --- a/src/scoreboard.h +++ b/src/scoreboard.h @@ -1,8 +1,6 @@ #ifndef __SCOREBOARD_H__ #define __SCOREBOARD_H__ -#define SCORE_FILE "/gtkballs-scores" - struct score_board { gchar name[30]; gint score; @@ -16,8 +14,6 @@ struct score_board_full { gchar *rules; }; -gint score_setup(void); - void free_score_board_full(struct score_board_full *bf, gint nbf); gint write_score(struct score_board *, struct score_board_full *, gint); gint read_score(struct score_board *, struct score_board_full **, gint *);