4 * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 /* WSLUA_MODULE Utility Utility Functions */
33 #include <epan/stat_cmd_args.h>
35 WSLUA_API gboolean
wslua_optbool(lua_State
* L
, int n
, gboolean def
) {
38 if ( lua_isboolean(L
,n
) ) {
39 val
= lua_toboolean(L
,n
);
40 } else if ( lua_isnil(L
,n
) || lua_gettop(L
) < n
){
43 luaL_argerror(L
,n
,"must be a boolean");
50 WSLUA_API
const gchar
* lua_shiftstring(lua_State
* L
, int i
) {
51 const gchar
* p
= luaL_checkstring(L
, i
);
61 /* following is based on the luaL_setfuncs() from Lua 5.2, so we can use it in pre-5.2 */
62 WSLUA_API
void wslua_setfuncs(lua_State
*L
, const luaL_Reg
*l
, int nup
) {
63 luaL_checkstack(L
, nup
, "too many upvalues");
64 for (; l
->name
!= NULL
; l
++) { /* fill the table with given functions */
66 for (i
= 0; i
< nup
; i
++) /* copy upvalues to the top */
67 lua_pushvalue(L
, -nup
);
68 lua_pushcclosure(L
, l
->func
, nup
); /* closure with those upvalues */
69 lua_setfield(L
, -(nup
+ 2), l
->name
);
71 lua_pop(L
, nup
); /* remove upvalues */
74 WSLUA_FUNCTION
wslua_get_version(lua_State
* L
) { /* Get Wireshark version */
75 const gchar
* str
= VERSION
;
76 lua_pushstring(L
,str
);
77 WSLUA_RETURN(1); /* version string */
80 WSLUA_FUNCTION
wslua_format_date(lua_State
* LS
) { /* Formats an absolute timestamp into a human readable date */
81 #define WSLUA_ARG_format_date_TIMESTAMP 1 /* A timestamp value to convert. */
82 lua_Number timestamp
= luaL_checknumber(LS
,WSLUA_ARG_format_date_TIMESTAMP
);
86 then
.secs
= (guint32
)floor(timestamp
);
87 then
.nsecs
= (guint32
) ( (timestamp
-(double)(then
.secs
))*1000000000);
88 str
= abs_time_to_str(&then
, ABSOLUTE_TIME_LOCAL
, TRUE
);
89 lua_pushstring(LS
,str
);
91 WSLUA_RETURN(1); /* A string with the formated date */
94 WSLUA_FUNCTION
wslua_format_time(lua_State
* LS
) { /* Formats a relative timestamp in a human readable form */
95 #define WSLUA_ARG_format_time_TIMESTAMP 1 /* A timestamp value to convert */
96 lua_Number timestamp
= luaL_checknumber(LS
,WSLUA_ARG_format_time_TIMESTAMP
);
100 then
.secs
= (guint32
)floor(timestamp
);
101 then
.nsecs
= (guint32
) ( (timestamp
-(double)(then
.secs
))*1000000000);
102 str
= rel_time_to_str(&then
);
103 lua_pushstring(LS
,str
);
105 WSLUA_RETURN(1); /* A string with the formated time */
108 WSLUA_FUNCTION
wslua_report_failure(lua_State
* LS
) { /* Reports a failure to the user */
109 #define WSLUA_ARG_report_failure_TEXT 1 /* Message */
110 const gchar
* s
= luaL_checkstring(LS
,WSLUA_ARG_report_failure_TEXT
);
111 report_failure("%s",s
);
115 static int wslua_log(lua_State
* L
, GLogLevelFlags log_level
) {
116 GString
* str
= g_string_new("");
117 int n
= lua_gettop(L
); /* Number of arguments */
120 lua_getglobal(L
, "tostring");
121 for (i
=1; i
<=n
; i
++) {
123 lua_pushvalue(L
, -1); /* function to be called */
124 lua_pushvalue(L
, i
); /* value to print */
126 s
= lua_tostring(L
, -1); /* get result */
128 return luaL_error(L
, "`tostring' must return a string");
130 if (i
>1) g_string_append(str
,"\t");
131 g_string_append(str
,s
);
133 lua_pop(L
, 1); /* pop result */
136 g_log(LOG_DOMAIN_LUA
, log_level
, "%s\n", str
->str
);
137 g_string_free(str
,TRUE
);
142 WSLUA_FUNCTION
wslua_critical( lua_State
* L
) { /* Will add a log entry with critical severity*/
143 /* WSLUA_MOREARGS critical objects to be printed */
144 wslua_log(L
,G_LOG_LEVEL_CRITICAL
);
147 WSLUA_FUNCTION
wslua_warn( lua_State
* L
) { /* Will add a log entry with warn severity */
148 /* WSLUA_MOREARGS warn objects to be printed */
149 wslua_log(L
,G_LOG_LEVEL_WARNING
);
152 WSLUA_FUNCTION
wslua_message( lua_State
* L
) { /* Will add a log entry with message severity */
153 /* WSLUA_MOREARGS message objects to be printed */
154 wslua_log(L
,G_LOG_LEVEL_MESSAGE
);
157 WSLUA_FUNCTION
wslua_info( lua_State
* L
) { /* Will add a log entry with info severity */
158 /* WSLUA_MOREARGS info objects to be printed */
159 wslua_log(L
,G_LOG_LEVEL_INFO
);
162 WSLUA_FUNCTION
wslua_debug( lua_State
* L
) { /* Will add a log entry with debug severity */
163 /* WSLUA_MOREARGS debug objects to be printed */
164 wslua_log(L
,G_LOG_LEVEL_DEBUG
);
168 /* The returned filename is g_malloc()'d so the caller must free it */
169 /* except when NULL is returned if file doesn't exist */
170 static char* wslua_get_actual_filename(const char* fname
) {
171 char fname_clean
[256];
175 g_strlcpy(fname_clean
,fname
,255);
176 fname_clean
[255] = '\0';
178 for(f
= fname_clean
; *f
; f
++) {
181 *f
= *(G_DIR_SEPARATOR_S
);
188 if ( file_exists(fname_clean
) ) {
189 return g_strdup(fname_clean
);
192 filename
= get_persconffile_path(fname_clean
,FALSE
);
194 if ( file_exists(filename
) ) {
199 filename
= get_datafile_path(fname_clean
);
200 if ( file_exists(filename
) ) {
208 WSLUA_FUNCTION
wslua_loadfile(lua_State
* L
) {
209 /* Lua's loadfile() has been modified so that if a file does not exist
210 in the current directory it will look for it in wireshark's user and system directories */
211 #define WSLUA_ARG_loadfile_FILENAME 1 /* Name of the file to be loaded */
212 const char *given_fname
= luaL_checkstring(L
, WSLUA_ARG_loadfile_FILENAME
);
215 filename
= wslua_get_actual_filename(given_fname
);
217 if (!filename
) WSLUA_ARG_ERROR(loadfile
,FILENAME
,"file does not exist");
219 if (luaL_loadfile(L
, filename
) == 0) {
230 WSLUA_FUNCTION
wslua_dofile(lua_State
* L
) {
231 /* Lua's dofile() has been modified so that if a file does not exist
232 in the current directory it will look for it in wireshark's user and system directories */
233 #define WSLUA_ARG_dofile_FILENAME 1 /* Name of the file to be run */
234 const char *given_fname
= luaL_checkstring(L
, WSLUA_ARG_dofile_FILENAME
);
238 if (!given_fname
) WSLUA_ARG_ERROR(dofile
,FILENAME
,"must be a string");
240 filename
= wslua_get_actual_filename(given_fname
);
242 if (!filename
) WSLUA_ARG_ERROR(dofile
,FILENAME
,"file does not exist");
245 if (luaL_loadfile(L
, filename
) != 0) lua_error(L
);
247 lua_call(L
, 0, LUA_MULTRET
);
248 return lua_gettop(L
) - n
;
252 WSLUA_FUNCTION
wslua_persconffile_path(lua_State
* L
) {
253 #define WSLUA_OPTARG_persconffile_path_FILENAME 1 /* A filename */
254 const char *fname
= luaL_optstring(L
, WSLUA_OPTARG_persconffile_path_FILENAME
,"");
255 char* filename
= get_persconffile_path(fname
,FALSE
);
257 lua_pushstring(L
,filename
);
259 WSLUA_RETURN(1); /* The full pathname for a file in the personal configuration directory */
262 WSLUA_FUNCTION
wslua_datafile_path(lua_State
* L
) {
263 #define WSLUA_OPTARG_datafile_path_FILENAME 1 /* A filename */
264 const char *fname
= luaL_optstring(L
, WSLUA_OPTARG_datafile_path_FILENAME
,"");
265 char* filename
= get_datafile_path(fname
);
267 lua_pushstring(L
,filename
);
269 WSLUA_RETURN(1); /* The full pathname for a file in wireshark's configuration directory */
273 WSLUA_CLASS_DEFINE(Dir
,NOP
,NOP
); /* A Directory */
275 WSLUA_CONSTRUCTOR
Dir_open(lua_State
* L
) {
276 /* Usage: for filename in Dir.open(path) do ... end */
277 #define WSLUA_ARG_Dir_open_PATHNAME 1 /* The pathname of the directory */
278 #define WSLUA_OPTARG_Dir_open_EXTENSION 2 /* If given, only file with this extension will be returned */
280 const char* dirname
= luaL_checkstring(L
,WSLUA_ARG_Dir_open_PATHNAME
);
281 const char* extension
= luaL_optstring(L
,WSLUA_OPTARG_Dir_open_EXTENSION
,NULL
);
285 if (!dirname
) WSLUA_ARG_ERROR(Dir_open
,PATHNAME
,"must be a string");
287 dirname_clean
= wslua_get_actual_filename(dirname
);
288 if (!dirname_clean
) WSLUA_ARG_ERROR(Dir_open
,PATHNAME
,"directory does not exist");
290 if (!test_for_directory(dirname_clean
)) {
291 g_free(dirname_clean
);
292 WSLUA_ARG_ERROR(Dir_open
,PATHNAME
, "must be a directory");
295 dir
= (Dir
)g_malloc(sizeof(struct _wslua_dir
));
296 dir
->dir
= OPENDIR_OP(dirname_clean
);
297 g_free(dirname_clean
);
298 dir
->ext
= extension
? g_strdup(extension
) : NULL
;
299 dir
->dummy
= (GError
**)g_malloc(sizeof(GError
*));
300 *(dir
->dummy
) = NULL
;
302 if (dir
->dir
== NULL
) {
306 WSLUA_ARG_ERROR(Dir_open
,PATHNAME
,"could not open directory");
310 WSLUA_RETURN(1); /* the Dir object */
313 WSLUA_METAMETHOD
Dir__call(lua_State
* L
) {
314 /* At every invocation will return one file (nil when done) */
316 Dir dir
= checkDir(L
,1);
318 const gchar
* filename
;
322 luaL_argerror(L
,1,"must be a Dir");
330 if ( ! ( file
= DIRGETNEXT_OP(dir
->dir
) )) {
331 CLOSEDIR_OP(dir
->dir
);
338 filename
= GETFNAME_OP(file
);
339 lua_pushstring(L
,filename
);
344 filename
= GETFNAME_OP(file
);
346 /* XXX strstr returns ptr to first match,
347 this fails ext=".xxx" filename="aaa.xxxz.xxx" */
348 if ( ( ext
= strstr(filename
,dir
->ext
)) && g_str_equal(ext
,dir
->ext
) ) {
349 lua_pushstring(L
,filename
);
352 } while(( file
= DIRGETNEXT_OP(dir
->dir
) ));
354 CLOSEDIR_OP(dir
->dir
);
359 WSLUA_METHOD
Dir_close(lua_State
* L
) {
360 /* Closes the directory */
361 Dir dir
= checkDir(L
,1);
364 CLOSEDIR_OP(dir
->dir
);
371 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
372 static int Dir__gc(lua_State
* L
) {
373 Dir dir
= checkDir(L
,1);
376 CLOSEDIR_OP(dir
->dir
);
381 if (dir
->ext
) g_free(dir
->ext
);
388 static const luaL_Reg Dir_methods
[] = {
390 {"close", Dir_close
},
394 static const luaL_Reg Dir_meta
[] = {
395 {"__call", Dir__call
},
399 int Dir_register(lua_State
* L
) {
401 WSLUA_REGISTER_CLASS(Dir
);
407 typedef struct _statcmd_t
{
412 static int statcmd_init_cb_error_handler(lua_State
* L _U_
) {
416 static void statcmd_init(const char *opt_arg
, void* userdata
) {
417 statcmd_t
* sc
= (statcmd_t
*)userdata
;
418 lua_State
* L
= sc
->L
;
421 lua_pushcfunction(L
,statcmd_init_cb_error_handler
);
422 lua_rawgeti(L
, LUA_REGISTRYINDEX
, sc
->func_ref
);
424 lua_pushstring(L
,opt_arg
);
426 switch ( lua_pcall(L
,1,0,1) ) {
430 g_warning("Runtime error while calling statcmd callback");
433 g_warning("Memory alloc error while calling statcmd callback");
436 g_assert_not_reached();
442 WSLUA_FUNCTION
wslua_register_stat_cmd_arg(lua_State
* L
) {
443 /* Register a function to handle a -z option */
444 #define WSLUA_ARG_register_stat_cmd_arg_ARGUMENT 1 /* Argument */
445 #define WSLUA_OPTARG_register_stat_cmd_arg_ACTION 2 /* Action */
446 const char* arg
= luaL_checkstring(L
,WSLUA_ARG_register_stat_cmd_arg_ARGUMENT
);
447 statcmd_t
* sc
= (statcmd_t
*)g_malloc0(sizeof(statcmd_t
)); /* XXX leaked */
450 lua_pushvalue(L
, WSLUA_OPTARG_register_stat_cmd_arg_ACTION
);
451 sc
->func_ref
= luaL_ref(L
, LUA_REGISTRYINDEX
);
454 register_stat_cmd_arg(arg
, statcmd_init
, sc
);