20
20
#include "internals.h"
22
struct module_context *active_context = NULL;
23
#include <libxml/xmlmemory.h>
24
#include <libxml/parser.h>
26
#define BACKTRACE_STACK_SIZE 64
28
#ifdef HAVE_EXECINFO_H
32
#define add_log_domain(domain) g_log_set_handler (domain, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, log_handler, NULL);
24
35
char my_hostname[MAXHOSTNAMELEN+2];
25
char output_debug = 0;
36
xmlNodePtr xmlNode_networks, xmlNode_plugins;
38
xmlDocPtr configuration;
39
char *configuration_file;
41
FILE *f_logfile = NULL;
43
GList *plugins = NULL;
27
45
void signal_crash(int sig)
31
/* If we crashed in the middle of a module, unload that module */
32
unload_module(active_context);
34
/* Bug in the core. Just loop until someone runs gdb on us */
47
#ifdef HAVE_BACKTRACE_SYMBOLS
48
void *backtrace_stack[BACKTRACE_STACK_SIZE];
49
size_t backtrace_size;
50
char **backtrace_strings;
52
g_critical("Received SIGSEGV!\n");
54
#ifdef HAVE_BACKTRACE_SYMBOLS
55
/* get the backtrace (stack frames) */
56
backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
57
backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
59
g_critical ("BACKTRACE: %d stack frames:\n", backtrace_size);
61
if (backtrace_strings) {
64
for (i = 0; i < backtrace_size; i++)
65
g_critical(" #%u %s", i, backtrace_strings[i]);
67
free(backtrace_strings);
72
g_error("Ctrlproxy core has segfaulted, exiting...\n");
75
void log_handler(const gchar *log_domain, GLogLevelFlags flags, const gchar *message, gpointer user_data) {
77
fprintf(f_logfile, "%s\n", message);
85
struct network *n = (struct network *)gl->data;
89
if(debugfd)fclose(debugfd);
39
92
void signal_quit(int sig)
94
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, "Received signal %d, quitting...\n", sig);
99
gboolean unload_plugin(struct plugin *p)
101
plugin_fini_function f;
103
/* Run exit function if present */
104
if(g_module_symbol(p->module, "fini_plugin", (gpointer *)&f)) {
106
g_warning("Unable to unload plugin '%s': still in use?\n", p->name);
110
g_warning("No symbol 'fini_plugin' in plugin '%s'. Module does not support unloading, so no unload will be attempted\n", p->name);
114
g_module_close(p->module);
116
/* Remove autoload from this plugins' element */
117
xmlUnsetProp(p->xmlConf, "autoload");
121
gboolean plugin_loaded(char *name)
125
struct plugin *p = (struct plugin *)gl->data;
126
if(!strcmp(p->name, name)) return TRUE;
132
gboolean load_plugin(xmlNodePtr cur)
139
plugin_init_function f = NULL;
141
mod_name = xmlGetProp(cur, "file");
143
g_warning("No filename specified for plugin");
147
/* Determine correct modules directory */
148
if(getenv("MODULESDIR"))modulesdir = getenv("MODULESDIR");
149
else modulesdir = MODULESDIR;
151
if(mod_name[0] == '/')path_name = g_strdup(mod_name);
152
else path_name = g_module_build_path(modulesdir, mod_name);
155
m = g_module_open(path_name, 0);
157
g_warning("Unable to open module %s(%s), ignoring\n", path_name, g_module_error());
162
if(!g_module_symbol(m, "init_plugin", (gpointer *)&f)) {
163
g_warning("Can't find symbol 'init_plugin' in module %s\n", path_name);
171
p = malloc(sizeof(struct plugin));
172
p->name = strdup(mod_name);
177
g_warning("Running initialization function for plugin '%s' failed.\n", mod_name);
183
plugins = g_list_append(plugins, p);
185
xmlSetProp(cur, "autoload", "1");
190
void save_configuration()
192
xmlSaveFile(configuration_file, configuration);
195
void signal_save(int sig)
197
save_configuration();
200
void readConfig(char *file) {
203
configuration = xmlParseFile(file);
204
g_assert(configuration);
206
cur = xmlDocGetRootElement(configuration);
209
g_assert(!strcmp(cur->name, "ctrlproxy"));
211
cur = cur->xmlChildrenNode;
213
if(xmlIsBlankNode(cur) || !strcmp(cur->name, "comment")) {
218
if(!strcmp(cur->name, "plugins")) {
219
xmlNode_plugins = cur;
220
} else if(!strcmp(cur->name, "networks")) {
221
xmlNode_networks = cur;
46
228
int main(int argc, const char *argv[])
52
char *nick, *port, *host, *pass, *mods, *modsdup;
232
char *logfile = NULL, *rcfile = NULL;
58
char *rcfile_default, *rcfile;
60
236
struct poptOption options[] = {
62
{"rc-file", 'r', POPT_ARG_STRING, &rcfile, 0, "Use alternative ctrlproxyrc file", "RCFILE"},
63
{"daemon", 'D', POPT_ARG_VAL, &daemon, 1, "Run in the background (as a daemon)"},
238
{"debug", 'd', POPT_ARG_STRING, NULL, 'd', "Write irc traffic to specified file", "FILE" },
239
{"daemon", 'D', POPT_ARG_VAL, &isdaemon, 1, "Run in the background (as a daemon)"},
240
{"log", 'l', POPT_ARG_STRING, &logfile, 0, "Log messages to specified file", "FILE"},
241
{"rc-file", 'r', POPT_ARG_STRING, &rcfile, 0, "Use configuration file from specified location", "FILE"},
64
242
{"version", 'v', POPT_ARG_NONE, NULL, 'v', "Show version information"},
65
{"debug", 'd', POPT_ARG_VAL, &output_debug, 1, "Output debug information"},
69
248
signal(SIGINT, signal_quit);
70
249
signal(SIGTERM, signal_quit);
71
250
signal(SIGPIPE, SIG_IGN);
72
251
signal(SIGHUP, SIG_IGN);
73
252
signal(SIGSEGV, signal_crash);
75
asprintf(&rcfile_default, "%s/.ctrlproxyrc", getenv("HOME")?getenv("HOME"):"");
76
rcfile = rcfile_default;
253
signal(SIGUSR1, signal_save);
255
replicate_function = default_replicate_function;
256
g_hook_list_init(&data_hook, sizeof(GHook));
258
loop = g_main_new(FALSE);
78
261
pc = poptGetContext(argv[0], argc, argv, options, 0);
80
263
while((c = poptGetNextOpt(pc)) >= 0) {
267
const char *fname = poptGetOptArg(pc);
268
if(!strcmp(fname, "-")) { debugfd = stdout; break; }
269
debugfd = fopen(fname, "w+");
83
printf("ctrlproxy %s\n", CTRLPROXY_VERSION);
84
printf("(c) 2002 Jelmer Vernooij <jelmer@nl.linux.org>\n");
273
printf("ctrlproxy %s\n", PACKAGE_VERSION);
274
printf("(c) 2002-2003 Jelmer Vernooij <jelmer@nl.linux.org>\n");
90
280
if(gethostname(my_hostname, MAXHOSTNAMELEN) != 0) {
91
fprintf(stderr, "Can't figure out hostname of local host!\n");
95
if(SLang_init_slang() == -1) {
96
fprintf(stderr, "Unable to initialize S-Lang\n");
100
if(SLang_load_file(rcfile) == -1) {
101
fprintf(stderr, "Unable to load %s!\n", rcfile);
105
sections = enum_sections();
107
for(i = 0; sections[i]; i++) {
109
nick = get_conf(t, "nick");
110
if(!nick)nick = getenv("USER");
111
port = get_conf(t, "port");
112
if(!port)port = "6667";
113
host = get_conf(t, "host");
115
fprintf(stderr, "No host specified for %s !\n", t);
118
pass = get_conf(t, "password");
120
s = connect_to_server(host, atoi(port), nick, pass);
125
/* Do autojoin stuff */
126
autojoin = get_conf(t, "autojoin");
127
if(autojoin)server_send(s, NULL, "JOIN", autojoin, NULL);
130
mods = get_conf(t, "modules");
132
modsdup = strdup(mods);
136
while((tmp = strchr(mods, ' ')) || (tmp = strchr(mods, '\0'))) {
137
if(*tmp == '\0')final = 1;
140
load_module(s, mods);
281
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "Can't figure out hostname of local host!\n");
286
f_logfile = fopen(logfile, "a+");
287
if(!f_logfile) g_warning("Can't open logfile %s!", logfile);
290
add_log_domain("GLib");
291
add_log_domain("ctrlproxy");
293
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Logfile opened");
150
298
signal(SIGTTOU, SIG_IGN);