<commit_before>#include "types.h"
#include "xmpp.h"
#include "ui.h"
#include <glib.h>
#include <glib/gstdio.h>
#include <glib/gprintf.h>
#include <string.h>
#include <stdlib.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>

/* Here we are doing command parsing, either these typed at runtime,
 * or these supplied in a gtkabberrc file. This is also the home of
 * some configuration variables, keeping connection parameters as well
 * as various things of which user can decide */

/* functions */
void config_cleanup(void);
void config_init(void);
void config_reload(void);
static int fun_print(lua_State *);
static int fun_sendmsg(lua_State *);
static int fun_sendstatus(lua_State *);
static int getbool(const gchar *);
static int getint(const gchar *);
static gchar *getstr(const gchar *);
Option get_settings(Settings);
static void init_settings(void);
static void loadactions(void);
static void loadfile(void);
static void loadlib(void);
void lua_msg_callback(const gchar *, const gchar *);
void lua_post_connect(void);
void lua_pres_callback(const gchar *, const gchar *, const gchar *);
/*************/

/* vars */
lua_State *lua;
Option settings[NUM_SETTINGS];
GArray *actions;
/********/

void
config_cleanup(void)
{
	int i;
	/* cleaning strings in settings[] */
	for(i=0; i != USE_SSL; i++) {
		g_free(settings[i].s);
	}
	lua_close(lua);
	for(i=0; i < (int)actions->len; i++) {
		g_free(g_array_index(actions, gchar *, i));
	}
	g_array_free(actions, TRUE);
}

void
config_init(void) 
{
	/* This one opens rc file, reads its contents and passes the lines
	 * to commands_exec() */	
	init_settings();
	loadfile();
	loadlib();
	actions = g_array_new(FALSE, FALSE, sizeof(gchar *));
	loadactions();
} /* config_parse_rcfile */

void config_reload(void)
{
	config_cleanup();
	config_init();
} /* config_reload */

static int
fun_print(lua_State *l)
{
	const gchar *txt;
	txt = lua_tostring(l, 1);
	if(txt)
		ui_status_print(txt);
	return 0;
} /* fun_sendmsg */

static int
fun_sendmsg(lua_State *l)
{
	const gchar *to, *body;
	to = lua_tostring(l, 1);
	body = lua_tostring(l, 2);
	xmpp_send_message(to, body);
	return 0;
} /* fun_sendmsg */

static int
fun_sendstatus(lua_State *l)
{
	const gchar *to, *type;
	XmppStatus st;
	to = lua_tostring(l, 1);
	type = lua_tostring(l, 2);
	if(type[0] == 'o') st = STATUS_ONLINE;
	else if(type[0] == 'f') st = STATUS_FFC;
	else if(type[0] == 'a') st = STATUS_AWAY;
	else if(type[0] == 'x') st = STATUS_XA;
	else if(type[0] == 'd') st = STATUS_DND;
	else st = STATUS_OFFLINE;
	ui_status_print("Sending status '%s' to %s\n", xmpp_status_readable(st),
	                (to) ? to : "the server");
	xmpp_send_status(to, st);
	return 0;
} /* fun_sendstatus */

static int
getbool(const gchar *o)
{
	/* getbool returns -1 is the option is not set */
	int ret;
	lua_getglobal(lua, o);
	if(!lua_isboolean(lua, 1))
		ret = -1;
	else
		ret = lua_toboolean(lua, 1);
	lua_remove(lua, 1);
	return ret;
} /* getbool */

static int
getint(const gchar *o)
{
	int ret;
	lua_getglobal(lua, o);
	ret = (int)lua_tonumber(lua, 1);
	lua_remove(lua, 1);
	return ret;
} /* getint */

static gchar *
getstr(const gchar *o)
{
	gchar *ret;
	lua_getglobal(lua, o);
	ret = g_strdup(lua_tostring(lua, 1));
	lua_remove(lua, 1);
	return ret;
} /* getstr */

Option
get_settings(Settings s)
{
	return settings[s];
} /* get_settings */

static void
init_settings(void)
{
	/* strings go NULL, ints go 0 */
	int i;
	for(i = 0; i != USE_SSL; i++) {
		settings[i].s = NULL;
	}
	for(i = USE_SSL; i != NUM_SETTINGS; i++) {
		settings[i].i = 0;
	}
} /* init_settings */

static void
loadactions(void)
{
	GString *index = g_string_new(NULL);
	int i;
	lua_getglobal(lua, "actions");
	if(!lua_istable(lua, -1)) {
		lua_pop(lua, 1);
		return;
	}
	for (i=1; ; i++) {
		gchar *name;
		g_string_printf(index, "%d\n", i);
		lua_pushstring(lua, index->str);
		lua_gettable(lua, -2);
		if(lua_isnil(lua, -1))
			break;
		if(!lua_istable(lua, -1)) {
			ui_status_print("Lua error: actions[%s] not an array\n", index);
			lua_pop(lua, 1);
			continue;
		}

		lua_pushstring(lua, "name");
		lua_gettable(lua, -2);
		if(!lua_isstring(lua, -1)) {
			ui_status_print("Lua error: actions[%s].name not a string\n", index);
			lua_pop(lua, 1);
			continue;
		}
		name = g_strdup(lua_tostring(lua, -1));
		lua_pop(lua, 1);
		g_array_append_val(actions, name);
	}
	lua_pop(lua, 1); /* popping out "actions" array */
	g_string_free(index, TRUE);
} /* loadactions */

static void
loadfile(void)
{
	char *atpos, *path;
	lua = lua_open();
	luaL_openlibs(lua);
	path = g_strdup_printf("%s/.config/gtkabber.lua", g_getenv("HOME"));
	/* load the file and run it */
	if(luaL_loadfile(lua, path) || lua_pcall(lua, 0, 0, 0)) {<commit_msg>Stack-leak fixed<commit_after>#include "types.h"
#include "xmpp.h"
#include "ui.h"
#include <glib.h>
#include <glib/gstdio.h>
#include <glib/gprintf.h>
#include <string.h>
#include <stdlib.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>

/* Here we are doing command parsing, either these typed at runtime,
 * or these supplied in a gtkabberrc file. This is also the home of
 * some configuration variables, keeping connection parameters as well
 * as various things of which user can decide */

/* functions */
void config_cleanup(void);
void config_init(void);
void config_reload(void);
static int fun_print(lua_State *);
static int fun_sendmsg(lua_State *);
static int fun_sendstatus(lua_State *);
static int getbool(const gchar *);
static int getint(const gchar *);
static gchar *getstr(const gchar *);
Option get_settings(Settings);
static void init_settings(void);
static void loadactions(void);
static void loadfile(void);
static void loadlib(void);
void lua_msg_callback(const gchar *, const gchar *);
void lua_post_connect(void);
void lua_pres_callback(const gchar *, const gchar *, const gchar *);
/*************/

/* vars */
lua_State *lua;
Option settings[NUM_SETTINGS];
GArray *actions;
/********/

void
config_cleanup(void)
{
	int i;
	/* cleaning strings in settings[] */
	for(i=0; i != USE_SSL; i++) {
		g_free(settings[i].s);
	}
	lua_close(lua);
	for(i=0; i < (int)actions->len; i++) {
		g_free(g_array_index(actions, gchar *, i));
	}
	g_array_free(actions, TRUE);
}

void
config_init(void) 
{
	/* This one opens rc file, reads its contents and passes the lines
	 * to commands_exec() */	
	init_settings();
	loadfile();
	loadlib();
	actions = g_array_new(FALSE, FALSE, sizeof(gchar *));
	loadactions();
} /* config_parse_rcfile */

void config_reload(void)
{
	config_cleanup();
	config_init();
} /* config_reload */

static int
fun_print(lua_State *l)
{
	const gchar *txt;
	txt = lua_tostring(l, 1);
	if(txt)
		ui_status_print(txt);
	return 0;
} /* fun_sendmsg */

static int
fun_sendmsg(lua_State *l)
{
	const gchar *to, *body;
	to = lua_tostring(l, 1);
	body = lua_tostring(l, 2);
	xmpp_send_message(to, body);
	return 0;
} /* fun_sendmsg */

static int
fun_sendstatus(lua_State *l)
{
	const gchar *to, *type;
	XmppStatus st;
	to = lua_tostring(l, 1);
	type = lua_tostring(l, 2);
	if(type[0] == 'o') st = STATUS_ONLINE;
	else if(type[0] == 'f') st = STATUS_FFC;
	else if(type[0] == 'a') st = STATUS_AWAY;
	else if(type[0] == 'x') st = STATUS_XA;
	else if(type[0] == 'd') st = STATUS_DND;
	else st = STATUS_OFFLINE;
	ui_status_print("Sending status '%s' to %s\n", xmpp_status_readable(st),
	                (to) ? to : "the server");
	xmpp_send_status(to, st);
	return 0;
} /* fun_sendstatus */

static int
getbool(const gchar *o)
{
	/* getbool returns -1 is the option is not set */
	int ret;
	lua_getglobal(lua, o);
	if(!lua_isboolean(lua, 1))
		ret = -1;
	else
		ret = lua_toboolean(lua, 1);
	lua_remove(lua, 1);
	return ret;
} /* getbool */

static int
getint(const gchar *o)
{
	int ret;
	lua_getglobal(lua, o);
	ret = (int)lua_tonumber(lua, 1);
	lua_remove(lua, 1);
	return ret;
} /* getint */

static gchar *
getstr(const gchar *o)
{
	gchar *ret;
	lua_getglobal(lua, o);
	ret = g_strdup(lua_tostring(lua, 1));
	lua_remove(lua, 1);
	return ret;
} /* getstr */

Option
get_settings(Settings s)
{
	return settings[s];
} /* get_settings */

static void
init_settings(void)
{
	/* strings go NULL, ints go 0 */
	int i;
	for(i = 0; i != USE_SSL; i++) {
		settings[i].s = NULL;
	}
	for(i = USE_SSL; i != NUM_SETTINGS; i++) {
		settings[i].i = 0;
	}
} /* init_settings */

static void
loadactions(void)
{
	GString *index = g_string_new(NULL);
	int i;
	lua_getglobal(lua, "actions");
	if(!lua_istable(lua, -1)) {
		lua_pop(lua, 1);
		return;
	}
	for (i=1; ; i++) {
		gchar *name;
		g_string_printf(index, "%d\n", i);
		lua_pushstring(lua, index->str);
		lua_gettable(lua, -2);
		if(lua_isnil(lua, -1)) {
			lua_pop(lua, 1);
			break;
		}
		if(!lua_istable(lua, -1)) {
			ui_status_print("Lua error: actions[%s] not an array\n", index);
			lua_pop(lua, 1);
			continue;
		}

		lua_pushstring(lua, "name");
		lua_gettable(lua, -2);
		if(!lua_isstring(lua, -1)) {
			ui_status_print("Lua error: actions[%s].name not a string\n", index);
			lua_pop(lua, 1);
			continue;
		}
		name = g_strdup(lua_tostring(lua, -1));
		lua_pop(lua, 1);
		g_array_append_val(actions, name);
	}
	lua_pop(lua, 1); /* popping out "actions" array */
	g_string_free(index, TRUE);
} /* loadactions */

static void
loadfile(void)
{
	char *atpos, *path;
	lua = lua_open();
	luaL_openlibs(lua);
	path = g_strdup_printf("%s/.config/gtkabber.lua", g_getenv("HOME"));
	/* load the file and run it */
	if(luaL_loadfile(lua, path) || lua_pcall(lua, 0, 0, 0)) {
{'fraction_non_alphanumeric': 0.16650828845950796, 'fraction_numerical': 0.009185936015204309, 'mean_word_length': 4.412571428571429, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6220587', 'n_tokens_mistral': 3995, 'n_tokens_neox': 3800, 'n_words': 933}