#include "queries.h"
#include "nicklist.h"
+#include "perl-core.h"
#include "perl-common.h"
typedef struct {
return func;
}
+static int magic_free_object(pTHX_ SV *sv, MAGIC *mg)
+{
+ sv_setiv(sv, 0);
+ return 0;
+}
+
+static MGVTBL vtbl_free_object =
+{
+ NULL, NULL, NULL, NULL, magic_free_object
+};
+
+static SV *create_sv_ptr(void *object)
+{
+ SV *sv;
+
+ sv = newSViv((IV)object);
+
+ sv_magic(sv, NULL, '~', NULL, 0);
+
+ SvMAGIC(sv)->mg_private = 0x1551; /* HF */
+ SvMAGIC(sv)->mg_virtual = &vtbl_free_object;
+
+ return sv;
+}
+
SV *irssi_bless_iobject(int type, int chat_type, void *object)
{
PERL_OBJECT_REC *rec;
GINT_TO_POINTER(type | (chat_type << 16)));
if (rec == NULL) {
/* unknown iobject */
- return newSViv(GPOINTER_TO_INT(object));
+ return create_sv_ptr(object);
}
stash = gv_stashpv(rec->stash, 1);
hv = newHV();
- hv_store(hv, "_irssi", 6, newSViv(GPOINTER_TO_INT(object)), 0);
+ hv_store(hv, "_irssi", 6, create_sv_ptr(object), 0);
rec->fill_func(hv, object);
return sv_bless(newRV_noinc((SV*)hv), stash);
}
fill_func = g_hash_table_lookup(plain_stashes, stash);
hv = newHV();
- hv_store(hv, "_irssi", 6, newSViv(GPOINTER_TO_INT(object)), 0);
+ hv_store(hv, "_irssi", 6, create_sv_ptr(object), 0);
if (fill_func != NULL)
fill_func(hv, object);
return sv_bless(newRV_noinc((SV*)hv), gv_stashpv((char *)stash, 1));
{
SV **sv;
HV *hv;
+ void *p;
hv = hvref(o);
if (hv == NULL)
sv = hv_fetch(hv, "_irssi", 6, 0);
if (sv == NULL)
- croak("variable is damaged");
- return GINT_TO_POINTER(SvIV(*sv));
+ croak("variable is damaged");
+ p = GINT_TO_POINTER(SvIV(*sv));
+ return p;
}
void irssi_add_object(int type, int chat_type, const char *stash,
return ret;
}
-void irssi_callXS(void (*subaddr)(CV* cv), CV *cv, SV **mark)
+void irssi_callXS(void (*subaddr)(pTHX_ CV* cv), CV *cv, SV **mark)
{
dSP;
PUSHMARK(mark);
- (*subaddr)(cv);
+ (*subaddr)(aTHX_ cv);
PUTBACK;
}
hv_store(hv, "type", 4, new_pv(type), 0);
hv_store(hv, "chat_type", 9, new_pv(chat_type), 0);
+ hv_store(hv, "tag", 3, new_pv(conn->tag), 0);
hv_store(hv, "address", 7, new_pv(conn->address), 0);
hv_store(hv, "port", 4, newSViv(conn->port), 0);
hv_store(hv, "chatnet", 7, new_pv(conn->chatnet), 0);
hv_store(hv, "wanted_nick", 11, new_pv(conn->nick), 0);
hv_store(hv, "username", 8, new_pv(conn->username), 0);
hv_store(hv, "realname", 8, new_pv(conn->realname), 0);
+
+ hv_store(hv, "reconnection", 12, newSViv(conn->reconnection), 0);
+ hv_store(hv, "no_autojoin_channels", 20, newSViv(conn->no_autojoin_channels), 0);
+ hv_store(hv, "unix_socket", 11, newSViv(conn->unix_socket), 0);
+ hv_store(hv, "use_ssl", 7, newSViv(conn->use_ssl), 0);
+ hv_store(hv, "no_connect", 10, newSViv(conn->no_connect), 0);
}
void perl_server_fill_hash(HV *hv, SERVER_REC *server)
hv_store(hv, "connection_lost", 15, newSViv(server->connection_lost), 0);
stash = gv_stashpv("Irssi::Rawlog", 0);
- hv_store(hv, "rawlog", 6, sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(server->rawlog))), stash), 0);
+ hv_store(hv, "rawlog", 6, sv_bless(newRV_noinc(newSViv((IV)server->rawlog)), stash), 0);
hv_store(hv, "version", 7, new_pv(server->version), 0);
hv_store(hv, "away_reason", 11, new_pv(server->away_reason), 0);
if (item->server != NULL) {
hv_store(hv, "server", 6, iobject_bless(item->server), 0);
}
- hv_store(hv, "name", 4, new_pv(item->name), 0);
+ hv_store(hv, "visible_name", 12, new_pv(item->visible_name), 0);
hv_store(hv, "createtime", 10, newSViv(item->createtime), 0);
- hv_store(hv, "data_level", 8, newSViv(item->data_level), 0);
- hv_store(hv, "hilight_color", 10, new_pv(item->hilight_color), 0);
+ hv_store(hv, "data_level", 10, newSViv(item->data_level), 0);
+ hv_store(hv, "hilight_color", 13, new_pv(item->hilight_color), 0);
}
void perl_channel_fill_hash(HV *hv, CHANNEL_REC *channel)
perl_window_item_fill_hash(hv, (WI_ITEM_REC *) channel);
+ if (channel->ownnick != NULL)
+ hv_store(hv, "ownnick", 7, iobject_bless(channel->ownnick), 0);
+
+ hv_store(hv, "name", 4, new_pv(channel->name), 0);
hv_store(hv, "topic", 5, new_pv(channel->topic), 0);
hv_store(hv, "topic_by", 8, new_pv(channel->topic_by), 0);
hv_store(hv, "topic_time", 10, newSViv(channel->topic_time), 0);
perl_window_item_fill_hash(hv, (WI_ITEM_REC *) query);
+ hv_store(hv, "name", 4, new_pv(query->name), 0);
+ hv_store(hv, "last_unread_msg", 15, newSViv(query->last_unread_msg), 0);
hv_store(hv, "address", 7, new_pv(query->address), 0);
hv_store(hv, "server_tag", 10, new_pv(query->server_tag), 0);
hv_store(hv, "unwanted", 8, newSViv(query->unwanted), 0);
hv_store(hv, "op", 2, newSViv(nick->op), 0);
hv_store(hv, "halfop", 6, newSViv(nick->halfop), 0);
hv_store(hv, "voice", 5, newSViv(nick->voice), 0);
+ hv_store(hv, "other", 5, newSViv(nick->other), 0);
hv_store(hv, "last_check", 10, newSViv(nick->last_check), 0);
hv_store(hv, "send_massjoin", 13, newSViv(nick->send_massjoin), 0);
hv_store(hv, "mask", 4, new_pv(ignore->mask), 0);
hv_store(hv, "servertag", 9, new_pv(ignore->servertag), 0);
av = newAV();
- for (tmp = ignore->channels; *tmp != NULL; tmp++) {
- av_push(av, new_pv(*tmp));
+ if (ignore->channels != NULL) {
+ for (tmp = ignore->channels; *tmp != NULL; tmp++) {
+ av_push(av, new_pv(*tmp));
+ }
}
hv_store(hv, "channels", 8, newRV_noinc((SV*)av), 0);
hv_store(hv, "pattern", 7, new_pv(ignore->pattern), 0);
hv_store(hv, "level", 5, newSViv(ignore->level), 0);
- hv_store(hv, "exception", 6, newSViv(ignore->exception), 0);
+ hv_store(hv, "exception", 9, newSViv(ignore->exception), 0);
hv_store(hv, "regexp", 6, newSViv(ignore->regexp), 0);
hv_store(hv, "fullword", 8, newSViv(ignore->fullword), 0);
}
hv_store(hv, "next_connect", 12, newSViv(reconnect->next_connect), 0);
}
+static void perl_script_fill_hash(HV *hv, PERL_SCRIPT_REC *script)
+{
+ hv_store(hv, "name", 4, new_pv(script->name), 0);
+ hv_store(hv, "package", 7, new_pv(script->package), 0);
+ hv_store(hv, "path", 4, new_pv(script->path), 0);
+ hv_store(hv, "data", 4, new_pv(script->data), 0);
+}
+
+static void remove_newlines(char *str)
+{
+ char *writing = str;
+
+ for (;*str;str++)
+ if (*str != '\n' && *str != '\r')
+ *(writing++) = *str;
+ *writing = '\0';
+}
+
void perl_command(const char *cmd, SERVER_REC *server, WI_ITEM_REC *item)
{
const char *cmdchars;
sendcmd = g_strdup_printf("%c%s", *cmdchars, cmd);
}
+ /* remove \r and \n from commands,
+ to make it harder to introduce a security bug in a script */
+ if(strpbrk(sendcmd, "\r\n")) {
+ if (sendcmd == cmd)
+ sendcmd = strdup(cmd);
+ remove_newlines(sendcmd);
+ }
+
signal_emit("send command", 3, sendcmd, server, item);
if (sendcmd != cmd) g_free(sendcmd);
}
chat_type = chat_protocol_lookup(rec->name);
g_return_if_fail(chat_type >= 0);
+#if GLIB_MAJOR_VERSION < 2
name = g_strdup(rec->name);
g_strdown(name+1);
+#else
+ name = g_ascii_strdown(rec->name,-1);
+ *name = *(rec->name);
+#endif
/* window items: channel, query */
type = module_get_uniq_id_str("WINDOW ITEM TYPE", "CHANNEL");
static void perl_unregister_protocol(CHAT_PROTOCOL_REC *rec)
{
- GSList *item;
+ GSList *item;
+ void *data;
item = gslist_find_icase_string(use_protocols, rec->name);
if (item != NULL) {
- g_free(item->data);
- use_protocols =
- g_slist_remove(use_protocols, item->data);
+ data = item->data;
+ use_protocols = g_slist_remove(use_protocols, data);
+ g_free(data);
}
g_hash_table_foreach_remove(iobject_stashes,
(GHRFunc) free_iobject_proto,
{ "Irssi::Logitem", (PERL_OBJECT_FUNC) perl_log_item_fill_hash },
{ "Irssi::Rawlog", (PERL_OBJECT_FUNC) perl_rawlog_fill_hash },
{ "Irssi::Reconnect", (PERL_OBJECT_FUNC) perl_reconnect_fill_hash },
+ { "Irssi::Script", (PERL_OBJECT_FUNC) perl_script_fill_hash },
{ NULL, NULL }
};