Freeciv-3.1: /fast/freeciv/nightly/S3_1/server/scripting/script_fcdb.c Source File

Freeciv-3.1

Loading...
Searching...
No Matches
script_fcdb.c
Go to the documentation of this file.
1/*****************************************************************************
2 Freeciv - Copyright (C) 2005 - The Freeciv Project
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12*****************************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <stdarg.h>
19#include <stdlib.h>
20#include <time.h>
21
22/* dependencies/lua */
23#include "lua.h"
24#include "lualib.h"
25
26/* dependencies/tolua */
27#include "tolua.h"
28
29/* dependencies/luasql */
30#ifdef HAVE_FCDB_MYSQL
31#include "ls_mysql.h"
32#endif
33#ifdef HAVE_FCDB_ODBC
34#include "ls_odbc.h"
35#endif
36#ifdef HAVE_FCDB_POSTGRES
37#include "ls_postgres.h"
38#endif
39#ifdef HAVE_FCDB_SQLITE3
40#include "ls_sqlite3.h"
41#endif
42
43/* utility */
44#include "log.h"
45#include "md5.h"
46#include "registry.h"
47#include "string_vector.h"
48
49/* common/scriptcore */
50#include "luascript.h"
51#include "luascript_types.h"
52#include "tolua_common_a_gen.h"
53#include "tolua_common_z_gen.h"
54#include "tolua_game_gen.h"
55
56/* server */
57#include "console.h"
58#include "stdinhand.h"
59
60/* server/scripting */
61#ifdef HAVE_FCDB
62#include <tolua_fcdb_gen.h> /* <> so looked from the build directory first. */
63#endif /* HAVE_FCDB */
64
65#include "script_fcdb.h"
66
67#ifdef HAVE_FCDB
68
69#define SCRIPT_FCDB_LUA_FILE "database.lua"
70
71static void script_fcdb_functions_define(void);
72static bool script_fcdb_functions_check(const char *fcdb_luafile);
73
74static void script_fcdb_cmd_reply(struct fc_lua *lfcl, enum log_level level,
75 const char *format, ...)
76 fc__attribute((__format__ (__printf__, 3, 4)));
77
78/**********************************************************************/
81static struct fc_lua *fcl = NULL;
82
83/**********************************************************************/
109static void script_fcdb_functions_define(void)
110{
111 luascript_func_add(fcl, "database_init", TRUE, 0, 0);
112 luascript_func_add(fcl, "database_free", TRUE, 0, 0);
113
114 luascript_func_add(fcl, "user_exists", TRUE, 1, 1, API_TYPE_CONNECTION,
115 API_TYPE_BOOL);
116 luascript_func_add(fcl, "user_verify", TRUE, 2, 1, API_TYPE_CONNECTION,
117 API_TYPE_STRING, API_TYPE_BOOL);
118 luascript_func_add(fcl, "user_save", FALSE, 2, 0, API_TYPE_CONNECTION,
119 API_TYPE_STRING);
120 luascript_func_add(fcl, "user_log", TRUE, 2, 0, API_TYPE_CONNECTION,
121 API_TYPE_BOOL);
122 luascript_func_add(fcl, "user_delegate_to", FALSE, 3, 1,
123 API_TYPE_CONNECTION, API_TYPE_PLAYER, API_TYPE_STRING,
124 API_TYPE_BOOL);
125 luascript_func_add(fcl, "user_take", FALSE, 4, 1, API_TYPE_CONNECTION,
126 API_TYPE_CONNECTION, API_TYPE_PLAYER, API_TYPE_BOOL,
127 API_TYPE_BOOL);
128}
129
130/**********************************************************************/
133static bool script_fcdb_functions_check(const char *fcdb_luafile)
134{
135 bool ret = TRUE;
136 struct strvec *missing_func_required = strvec_new();
137 struct strvec *missing_func_optional = strvec_new();
138
139 if (!luascript_func_check(fcl, missing_func_required,
140 missing_func_optional)) {
141 strvec_iterate(missing_func_required, func_name) {
142 log_error("Database script '%s' does not define the required function "
143 "'%s'.", fcdb_luafile, func_name);
144 ret = FALSE;
145 } strvec_iterate_end;
146 strvec_iterate(missing_func_optional, func_name) {
147 log_verbose("Database script '%s' does not define the optional "
148 "function '%s'.", fcdb_luafile, func_name);
149 } strvec_iterate_end;
150 }
151
152 strvec_destroy(missing_func_required);
153 strvec_destroy(missing_func_optional);
154
155 return ret;
156}
157
158/**********************************************************************/
161static void script_fcdb_cmd_reply(struct fc_lua *lfcl, enum log_level level,
162 const char *format, ...)
163{
164 va_list args;
165 enum rfc_status rfc_status = C_OK;
166 char buf[1024];
167
168 va_start(args, format);
169 fc_vsnprintf(buf, sizeof(buf), format, args);
170 va_end(args);
171
172 switch (level) {
173 case LOG_FATAL:
174 /* Special case - will quit the server. */
175 log_fatal("%s", buf);
176 break;
177 case LOG_ERROR:
178 case LOG_WARN:
179 rfc_status = C_WARNING;
180 break;
181 case LOG_NORMAL:
182 rfc_status = C_COMMENT;
183 break;
184 case LOG_VERBOSE:
185 rfc_status = C_LOG_BASE;
186 break;
187 case LOG_DEBUG:
188 rfc_status = C_DEBUG;
189 break;
190 }
191
192 cmd_reply(CMD_FCDB, lfcl->caller, rfc_status, "%s", buf);
193}
194
195/**********************************************************************/
198static int md5sum(lua_State *L)
199{
200 int n = lua_gettop(L);
201 char sum[MD5_HEX_BYTES + 1];
202 const char *plaintext;
203 size_t len;
204
205 if (n != 1 || lua_type(L, -1) != LUA_TSTRING) {
206 lua_pushliteral(L, "invalid argument");
207 lua_error(L);
208 }
209
210 plaintext = lua_tolstring(L, -1, &len);
211 create_md5sum((unsigned char*)plaintext, len, sum);
212
213 lua_pushstring(L, sum);
214 return 1;
215}
216#endif /* HAVE_FCDB */
217
218/**********************************************************************/
222 bool script_fcdb_init(const char *fcdb_luafile)
223{
224#ifdef HAVE_FCDB
225 if (fcl != NULL) {
226 fc_assert_ret_val(fcl->state != NULL, FALSE);
227
228 return TRUE;
229 }
230
231 if (!fcdb_luafile) {
232 /* Use default freeciv database lua file. */
233 fcdb_luafile = FC_CONF_PATH "/" SCRIPT_FCDB_LUA_FILE;
234 }
235
236 fcl = luascript_new(NULL, FALSE);
237 if (fcl == NULL) {
238 log_error("Error loading the Freeciv database lua definition.");
239 return FALSE;
240 }
241
242 tolua_common_a_open(fcl->state);
243 tolua_game_open(fcl->state);
244
245#ifdef MESON_BUILD
246 /* Tolua adds 'tolua_' prefix to _open() function names,
247 * and we can't pass it a basename where the original
248 * 'tolua_' has been stripped when generating from meson. */
249 tolua_tolua_fcdb_open(fcl->state);
250#else /* MESON_BUILD */
251 tolua_fcdb_open(fcl->state);
252#endif /* MESON_BUILD */
253 lua_register(fcl->state, "md5sum", md5sum);
254#ifdef HAVE_FCDB_MYSQL
255 luaL_requiref(fcl->state, "ls_mysql", luaopen_luasql_mysql, 1);
256 lua_pop(fcl->state, 1);
257#endif
258#ifdef HAVE_FCDB_ODBC
259 luaL_requiref(fcl->state, "ls_odbc", luaopen_luasql_odbc, 1);
260 lua_pop(fcl->state, 1);
261#endif
262#ifdef HAVE_FCDB_POSTGRES
263 luaL_requiref(fcl->state, "ls_postgres", luaopen_luasql_postgres, 1);
264 lua_pop(fcl->state, 1);
265#endif
266#ifdef HAVE_FCDB_SQLITE3
267 luaL_requiref(fcl->state, "ls_sqlite3", luaopen_luasql_sqlite3, 1);
268 lua_pop(fcl->state, 1);
269#endif
270 tolua_common_z_open(fcl->state);
271
272 luascript_func_init(fcl);
273
274 /* Define the prototypes for the needed lua functions. */
275 script_fcdb_functions_define();
276
277 if (luascript_do_file(fcl, fcdb_luafile)
278 || !script_fcdb_functions_check(fcdb_luafile)) {
279 log_error("Error loading the Freeciv database lua script '%s'.",
280 fcdb_luafile);
281 script_fcdb_free();
282 return FALSE;
283 }
284
285 if (!script_fcdb_call("database_init")) {
286 log_error("Error connecting to the database");
287 script_fcdb_free();
288 return FALSE;
289 }
290#endif /* HAVE_FCDB */
291
292 return TRUE;
293}
294
295/**********************************************************************/
301 bool script_fcdb_call(const char *func_name, ...)
302{
303 bool success = TRUE;
304#ifdef HAVE_FCDB
305
306 va_list args;
307 va_start(args, func_name);
308
309 success = luascript_func_call_valist(fcl, func_name, args);
310 va_end(args);
311#endif /* HAVE_FCDB */
312
313 return success;
314}
315
316/**********************************************************************/
319 void script_fcdb_free(void)
320{
321#ifdef HAVE_FCDB
322 if (!script_fcdb_call("database_free", 0)) {
323 log_error("Error closing the database connection. Continuing anyway...");
324 }
325
326 if (fcl) {
327 /* luascript_func_free() is called by luascript_destroy(). */
328 luascript_destroy(fcl);
329 fcl = NULL;
330 }
331#endif /* HAVE_FCDB */
332}
333
334/**********************************************************************/
338 bool script_fcdb_do_string(struct connection *caller, const char *str)
339{
340#ifdef HAVE_FCDB
341 int status;
342 struct connection *save_caller;
343 luascript_log_func_t save_output_fct;
344
345 /* Set a log callback function which allows to send the results of the
346 * command to the clients. */
347 save_caller = fcl->caller;
348 save_output_fct = fcl->output_fct;
349 fcl->output_fct = script_fcdb_cmd_reply;
350 fcl->caller = caller;
351
352 status = luascript_do_string(fcl, str, "cmd");
353
354 /* Reset the changes. */
355 fcl->caller = save_caller;
356 fcl->output_fct = save_output_fct;
357
358 return (status == 0);
359#else
360 return TRUE;
361#endif /* HAVE_FCDB */
362}
str
#define str
Definition astring.c:76
n
#define n
Definition astring.c:77
CMD_FCDB
@ CMD_FCDB
Definition commands.h:97
console.h
rfc_status
rfc_status
Definition console.h:35
C_DEBUG
@ C_DEBUG
Definition console.h:39
C_OK
@ C_OK
Definition console.h:41
C_LOG_BASE
@ C_LOG_BASE
Definition console.h:40
C_COMMENT
@ C_COMMENT
Definition console.h:37
C_WARNING
@ C_WARNING
Definition console.h:50
log.h
log_verbose
#define log_verbose(message,...)
Definition log.h:109
fc_assert_ret_val
#define fc_assert_ret_val(condition, val)
Definition log.h:194
log_fatal
#define log_fatal(message,...)
Definition log.h:100
log_level
log_level
Definition log.h:28
LOG_ERROR
@ LOG_ERROR
Definition log.h:30
LOG_DEBUG
@ LOG_DEBUG
Definition log.h:34
LOG_NORMAL
@ LOG_NORMAL
Definition log.h:32
LOG_FATAL
@ LOG_FATAL
Definition log.h:29
LOG_VERBOSE
@ LOG_VERBOSE
Definition log.h:33
LOG_WARN
@ LOG_WARN
Definition log.h:31
log_error
#define log_error(message,...)
Definition log.h:103
luascript_do_string
int luascript_do_string(struct fc_lua *fcl, const char *str, const char *name)
Definition luascript.c:617
luascript_do_file
int luascript_do_file(struct fc_lua *fcl, const char *filename)
Definition luascript.c:637
luascript_new
struct fc_lua * luascript_new(luascript_log_func_t output_fct, bool secured_environment)
Definition luascript.c:332
luascript_destroy
void luascript_destroy(struct fc_lua *fcl)
Definition luascript.c:386
luascript.h
luascript_log_func_t
void(* luascript_log_func_t)(struct fc_lua *fcl, enum log_level level, const char *format,...) fc__attribute((__format__(__printf__
Definition luascript.h:39
luascript_func_call_valist
bool luascript_func_call_valist(struct fc_lua *fcl, const char *func_name, va_list args)
Definition luascript_func.c:220
luascript_func_check
bool luascript_func_check(struct fc_lua *fcl, struct strvec *missing_func_required, struct strvec *missing_func_optional)
Definition luascript_func.c:94
luascript_func_init
void luascript_func_init(struct fc_lua *fcl)
Definition luascript_func.c:203
luascript_func_add
void luascript_func_add(struct fc_lua *fcl, const char *func_name, bool required, int nargs, int nreturns,...)
Definition luascript_func.c:178
luascript_types.h
create_md5sum
void create_md5sum(const unsigned char *input, int len, char output[MD5_HEX_BYTES+1])
Definition md5.c:335
md5.h
MD5_HEX_BYTES
#define MD5_HEX_BYTES
Definition md5.h:21
len
int len
Definition packhand.c:125
registry.h
script_fcdb_free
void script_fcdb_free(void)
Definition script_fcdb.c:319
script_fcdb_do_string
bool script_fcdb_do_string(struct connection *caller, const char *str)
Definition script_fcdb.c:338
script_fcdb_call
bool script_fcdb_call(const char *func_name,...)
Definition script_fcdb.c:301
script_fcdb_init
bool script_fcdb_init(const char *fcdb_luafile)
Definition script_fcdb.c:222
script_fcdb.h
level
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:183
cmd_reply
void cmd_reply(enum command_id cmd, struct connection *caller, enum rfc_status rfc_status, const char *format,...)
Definition stdinhand.c:418
stdinhand.h
strvec_destroy
void strvec_destroy(struct strvec *psv)
Definition string_vector.c:71
strvec_new
struct strvec * strvec_new(void)
Definition string_vector.c:58
string_vector.h
strvec_iterate
#define strvec_iterate(psv, str)
Definition string_vector.h:61
strvec_iterate_end
#define strvec_iterate_end
Definition string_vector.h:68
connection
Definition connection.h:141
connection::status
enum auth_status status
Definition connection.h:222
fc_lua
Definition luascript.h:44
fc_lua::caller
struct connection * caller
Definition luascript.h:49
strvec
Definition string_vector.c:29
fc_vsnprintf
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
Definition support.c:896
fc__attribute
#define fc__attribute(x)
Definition support.h:89
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
tolua_common_a_open
TOLUA_API int tolua_common_a_open(lua_State *tolua_S)
Definition tolua_common_a_gen.c:717
tolua_common_a_gen.h
tolua_common_z_open
TOLUA_API int tolua_common_z_open(lua_State *tolua_S)
Definition tolua_common_z_gen.c:141
tolua_common_z_gen.h
tolua_fcdb_open
TOLUA_API int tolua_fcdb_open(lua_State *tolua_S)
Definition tolua_fcdb_gen.c:166
tolua_fcdb_gen.h
tolua_game_open
TOLUA_API int tolua_game_open(lua_State *tolua_S)
Definition tolua_game_gen.c:5144
tolua_game_gen.h