/*
ctrlproxy: A modular IRC proxy
- (c) 2003,2006 Jelmer Vernooij <jelmer@nl.linux.org>
+ (c) 2003-2007 Jelmer Vernooij <jelmer@nl.linux.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "ctrlproxy.h"
#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "nickserv.h"
#include "irc.h"
-struct nickserv_entry {
- const char *network;
- const char *nick;
- const char *pass;
-};
-static const char *nickserv_find_nick(struct network *n, char *nick)
+const char *nickserv_find_nick(struct network *n, const char *nick)
{
GList *gl;
for (gl = n->global->nickserv_nicks; gl; gl = gl->next) {
continue;
if (!e->network) return e->pass;
- if (!g_strcasecmp(e->network, n->name)) return e->pass;
+ if (!g_strcasecmp(e->network, n->info.name)) return e->pass;
}
return NULL;
}
-static const char *nickserv_nick(struct network *n)
+const char *nickserv_nick(struct network *n)
{
return "NickServ";
}
const char *nickserv_n = nickserv_nick(network);
char *raw;
raw = g_strdup_printf("IDENTIFY %s", pass);
- log_network(NULL, LOG_INFO, network, "Sending password for %s", nickserv_n);
+ log_network(LOG_INFO, network, "Sending password for %s", nickserv_n);
network_send_args(network, "PRIVMSG", nickserv_n, raw, NULL);
g_free(raw);
} else {
- log_network(NULL, LOG_INFO, network, "No password known for `%s'", nick);
+ log_network(LOG_INFO, network, "No password known for `%s'", nick);
}
}
for (gl = n->global->nickserv_nicks; gl; gl = gl->next) {
e = gl->data;
- if (e->network && !g_strcasecmp(e->network, n->name) &&
+ if (e->network && !g_strcasecmp(e->network, n->info.name) &&
!g_strcasecmp(e->nick, n->state->me.nick)) {
break;
}
if (!gl) {
e = g_new0(struct nickserv_entry, 1);
e->nick = g_strdup(n->state->me.nick);
- e->network = g_strdup(n->name);
+ e->network = g_strdup(n->info.name);
n->global->nickserv_nicks = g_list_prepend(n->global->nickserv_nicks, e);
}
if (e->pass == NULL ||
strcmp(e->pass, newpass) != 0) {
e->pass = g_strdup(newpass);
- log_network(NULL, LOG_INFO, n, "Caching password for nick %s", e->nick);
+ log_network(LOG_INFO, n, "Caching password for nick %s", e->nick);
}
g_free(newpass);
const char *nickserv_n = nickserv_nick(n);
char *raw;
- log_network(NULL, LOG_INFO, n, "Ghosting current user using '%s'", nickattempt);
+ log_network(LOG_INFO, n, "Ghosting current user using '%s'", nickattempt);
raw = g_strdup_printf("GHOST %s %s", nickattempt, pass);
network_send_args(n, "PRIVMSG", nickserv_n, raw, NULL);
return TRUE;
}
-
-gboolean nickserv_save(struct global *global, const char *dir)
+gboolean nickserv_write_file(GList *nicks, const char *filename)
{
- char *filename = g_build_filename(dir, "nickserv", NULL);
- GIOChannel *gio;
- GList *gl;
- GError *error = NULL;
+ GList *gl;
+ int fd;
- gio = g_io_channel_new_file(filename, "w", &error);
+ fd = open(filename, O_WRONLY | O_CREAT, 0600);
- if (!gio) {
- log_global(NULL, LOG_WARNING, "Unable to write nickserv file `%s': %s", filename, error->message);
- g_free(filename);
+ if (fd == -1) {
+ log_global(LOG_WARNING, "Unable to write nickserv file `%s': %s", filename, strerror(errno));
return FALSE;
}
- for (gl = global->nickserv_nicks; gl; gl = gl->next) {
+ for (gl = nicks; gl; gl = gl->next) {
struct nickserv_entry *n = gl->data;
char *line;
- gsize nr;
line = g_strdup_printf("%s\t%s\t%s\n", n->nick, n->pass, n->network?n->network:"*");
-
- g_io_channel_write_chars(gio, line, -1, &nr, NULL);
+ if (write(fd, line, strlen(line)) < 0) {
+ log_global(LOG_WARNING, "error writing line `%s': %s", line, strerror(errno));
+ g_free(line);
+ close(fd);
+ return FALSE;
+ }
g_free(line);
}
- g_io_channel_unref(gio);
- g_free(filename);
+ close(fd);
return TRUE;
}
-gboolean nickserv_load(struct global *global)
+gboolean nickserv_save(struct global *global, const char *dir)
+{
+ char *filename = g_build_filename(dir, "nickserv", NULL);
+ gboolean ret;
+
+ ret = nickserv_write_file(global->nickserv_nicks, filename);
+
+ g_free(filename);
+
+ return ret;
+}
+
+gboolean nickserv_read_file(const char *filename, GList **nicks)
{
- char *filename = g_build_filename(global->config->config_dir, "nickserv", NULL);
GIOChannel *gio;
char *ret;
gsize nr, term;
gio = g_io_channel_new_file(filename, "r", NULL);
- if (!gio) {
- g_free(filename);
+ if (gio == NULL) {
return FALSE;
}
e->network = parts[2];
}
- global->nickserv_nicks = g_list_append(global->nickserv_nicks, e);
+ *nicks = g_list_append(*nicks, e);
g_free(parts);
}
- g_free(filename);
-
g_io_channel_shutdown(gio, TRUE, NULL);
g_io_channel_unref(gio);
return TRUE;
}
+gboolean nickserv_load(struct global *global)
+{
+ gboolean ret;
+ char *filename = g_build_filename(global->config->config_dir, "nickserv",
+ NULL);
+ ret = nickserv_read_file(filename, &global->nickserv_nicks);
+ g_free(filename);
+
+ return TRUE;
+}
+
void init_nickserv(void)
{
add_server_filter("nickserv", log_data, NULL, 1);