updated docs
[rlserver.git] / stats.c
blob166bfc9bdcc87174f2e2ceb801f5099eb3e0bff0
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <libgen.h>
6 #include <time.h>
7 #include "util.h"
8 #include "log.h"
9 #include "server.h"
10 #include "games.h"
11 #include "sessions.h"
14 #define BUF_SIZE 1024
16 extern server_config config;
20 static void update_stat_file (const char *fn, const session_info *sess, time_t now)
22 FILE *f;
23 char buf[BUF_SIZE];
24 int stats[4] = {1, now - sess->game_stat.start_time, sess->game_stat.bytes_in, sess->game_stat.bytes_out};
25 int newfile = 0, n;
28 if (fn[0] == 0) return;
30 // make directory for it
31 strcpy (buf, fn);
32 make_dir (dirname(buf));
35 if ((f = fopen(fn, "r+")) == NULL)
37 write_log (LOG_ERROR, "creating stat file %s", fn);
39 newfile = 1;
40 if ((f = fopen(fn, "w")) == NULL)
42 write_log (LOG_ERROR, "error creating %s", fn);
43 return;
47 // lock file to block access from other threads
48 if (lockf(fileno(f), F_LOCK, 0) != 0)
50 write_log (LOG_ERROR, "error locking %s", fn);
51 fclose (f);
52 return;
55 // load old stats
56 if (!newfile)
58 int i;
60 for (i = 0; i < 4; i++)
62 if (fgets(buf, BUF_SIZE, f) == NULL)
64 write_log (LOG_ERROR, "error reading %s", fn);
65 fclose (f);
66 return;
69 stats[i] += atoi(buf);
72 fseek (f, SEEK_SET, 0);
75 // write updated data
76 n = sprintf(buf, "%d\n%d\n%d\n%d\n", stats[0], stats[1], stats[2], stats[3]);
77 if (fwrite(buf, n, 1, f) != 1) write_log (LOG_ERROR, "error writing %s", fn);
79 fclose (f);
84 static void append_log_file (const char *fn, const session_info *sess, time_t now)
86 FILE *f;
87 char buf[BUF_SIZE], tm[100];
88 struct tm tnow;
89 int n;
92 if (fn[0] == 0) return;
94 // make directory for it
95 strcpy (buf, fn);
96 make_dir (dirname(buf));
99 if ((f = fopen(fn, "a")) == NULL)
101 write_log (LOG_ERROR, "error opening %s");
102 return;
105 // lock file to block access from other threads
106 if (lockf(fileno(f), F_LOCK, 0) != 0)
108 write_log (LOG_ERROR, "error locking %s", fn);
109 fclose (f);
110 return;
113 // append session data
114 strftime (tm, 100, "%F %H:%M:%S", localtime_r(&now, &tnow));
115 n = sprintf(buf, "%s\t%s\t%d\t%d\t%d\n", tm, sess->user_name, (int)(now - sess->game_stat.start_time), sess->game_stat.bytes_in, sess->game_stat.bytes_out);
116 if (fwrite(buf, n, 1, f) != 1) write_log (LOG_ERROR, "error writing %s", fn);
118 fclose (f);
123 void update_stats (const game_info *game, const session_info *sess)
125 char fn[BUF_SIZE];
126 time_t now = time(NULL);
129 str_replace (fn, BUF_SIZE, config.game_stat_file, "$GAME$", game->id);
130 update_stat_file (fn, sess, now);
132 str_replace (fn, BUF_SIZE, config.game_log_file, "$GAME$", game->id);
133 append_log_file (fn, sess, now);