Yo.
gtk1-stable
v0_59_9
2003-03-01, Sean Egan
* Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> * 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 * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * This was taken almost exactly from X-Chat. The power of the GPL. * Translated from X-Chat to Gaim by Eric Warmenhoven. * Originally by Erik Scrafford <eriks@chilisoft.com>. * X-Chat Copyright (C) 1998 Peter Zelezny. #ifndef _SEM_SEMUN_UNDEFINED /* perl module support */ extern void xs_init _((void)); extern void boot_DynaLoader _((CV * cv)); /* perl is so wacky */ char *shutdowncallback; /* bleh */ struct _perl_event_handlers { struct _perl_timeout_handlers { static GList *perl_list = NULL; /* should probably extern this at some point */ static GList *perl_timeout_handlers = NULL; static GList *perl_event_handlers = NULL; static PerlInterpreter *my_perl = NULL; XS(XS_GAIM_register); /* set up hooks for script */ XS(XS_GAIM_get_info); /* version, last to attempt signon, protocol */ XS(XS_GAIM_print); /* lemme figure this one out... */ XS(XS_GAIM_write_to_conv); /* write into conversation window */ XS(XS_GAIM_buddy_list); /* all buddies */ XS(XS_GAIM_online_list); /* online buddies */ XS(XS_GAIM_command); /* send command to server */ XS(XS_GAIM_user_info); /* given name, return struct buddy members */ XS(XS_GAIM_print_to_conv); /* send message to someone */ XS(XS_GAIM_print_to_chat); /* send message to chat room */ XS(XS_GAIM_serv_send_im); /* send message to someone (but do not display) */ XS(XS_GAIM_add_event_handler); /* when servers talk */ XS(XS_GAIM_add_timeout_handler); /* figure it out */ XS(XS_GAIM_play_sound); /*play a sound*/ newXS ("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); static char *escape_quotes(char *buf) static char *tmp_buf = NULL; tmp_buf = g_malloc(strlen(buf) * 2 + 1); for (i = buf, j = tmp_buf; *i; i++, j++) { if (*i == '\'' || *i == '\\') static SV *execute_perl(char *function, char *args) static char *perl_cmd = NULL; perl_cmd = g_malloc(strlen(function) + strlen(args) + 4); sprintf(perl_cmd, "&%s(%s)", function, args); #ifndef HAVE_PERL_EVAL_PV i = (perl_eval_pv(perl_cmd, TRUE)); i = (Perl_eval_pv(perl_cmd, TRUE)); int perl_load_file(char *script_name) char *name = g_strdup_printf("'%s'", escape_quotes(script_name)); return_val = execute_perl("load_file", name); return SvNV (return_val); static int is_pl_file(char *filename) if (!filename[0]) return 0; return (!strncmp(filename + len, ".pl", 3)); struct dirent *dirent_buf; dirent_buf = g_malloc(sizeof(struct dirent) + NAME_MAX); while ((readdir_r(dir,dirent_buf,&ent),ent)) { if (strcmp(ent->d_name, ".") && strcmp(ent->d_name, "..")) { if (is_pl_file(ent->d_name)) { buf = g_malloc(strlen(path) + strlen(ent->d_name) + 2); sprintf(buf, "%s/%s", path, ent->d_name); char *perl_args[] = {"", "-e", "0", "-w"}; " (my $file_name) = @_;\n" " open FH, $file_name or return 2;\n" " $file = \"\\@ISA = qw(Exporter DynaLoader);\\n\" . $file;\n" perl_parse(my_perl, xs_init, 4, perl_args, NULL); #ifndef HAVE_PERL_EVAL_PV perl_eval_pv(load_file, TRUE); Perl_eval_pv(load_file, TRUE); newXS ("GAIM::register", XS_GAIM_register, "GAIM"); newXS ("GAIM::get_info", XS_GAIM_get_info, "GAIM"); newXS ("GAIM::print", XS_GAIM_print, "GAIM"); newXS ("GAIM::write_to_conv", XS_GAIM_write_to_conv, "GAIM"); newXS ("GAIM::buddy_list", XS_GAIM_buddy_list, "GAIM"); newXS ("GAIM::online_list", XS_GAIM_online_list, "GAIM"); newXS ("GAIM::command", XS_GAIM_command, "GAIM"); newXS ("GAIM::user_info", XS_GAIM_user_info, "GAIM"); newXS ("GAIM::print_to_conv", XS_GAIM_print_to_conv, "GAIM"); newXS ("GAIM::print_to_chat", XS_GAIM_print_to_chat, "GAIM"); newXS ("GAIM::serv_send_im", XS_GAIM_serv_send_im, "GAIM"); newXS ("GAIM::add_event_handler", XS_GAIM_add_event_handler, "GAIM"); newXS ("GAIM::add_timeout_handler", XS_GAIM_add_timeout_handler, "GAIM"); newXS ("GAIM::play_sound", XS_GAIM_play_sound, "GAIM"); struct _perl_timeout_handlers *thn; struct _perl_event_handlers *ehn; perl_list = g_list_remove(perl_list, scp); if (scp->shutdowncallback[0]) execute_perl(scp->shutdowncallback, ""); g_free(scp->shutdowncallback); while (perl_timeout_handlers) { thn = perl_timeout_handlers->data; perl_timeout_handlers = g_list_remove(perl_timeout_handlers, thn); g_source_remove(thn->iotag); g_free(thn->handler_args); g_free(thn->handler_name); while (perl_event_handlers) { ehn = perl_event_handlers->data; perl_event_handlers = g_list_remove(perl_event_handlers, ehn); g_free(ehn->handler_name); char *name, *ver, *callback, *unused; /* exactly like X-Chat, eh? :) */ name = SvPV (ST (0), junk); ver = SvPV (ST (1), junk); callback = SvPV (ST (2), junk); unused = SvPV (ST (3), junk); scp = g_new0(struct perlscript, 1); scp->name = g_strdup(name); scp->version = g_strdup(ver); scp->shutdowncallback = g_strdup(callback); perl_list = g_list_append(perl_list, scp); struct gaim_connection *gc; gc = (struct gaim_connection *)c->data; struct gaim_connection *gc = (struct gaim_connection *)SvIV(ST(1)); if (g_slist_find(connections, gc)) XST_mIV(i++, gc->protocol); struct gaim_connection *gc = (struct gaim_connection *)SvIV(ST(1)); if (g_slist_find(connections, gc)) XST_mPV(i++, gc->username); struct gaim_connection *gc = (struct gaim_connection *)SvIV(ST(1)); if (g_slist_find(connections, gc)) XST_mIV(i++, g_slist_index(aim_users, gc->user)); struct aim_user *u = a->data; XST_mPV(i++, u->username); struct aim_user *u = a->data; XST_mIV(i++, u->protocol); struct gaim_connection *gc = (struct gaim_connection *)SvIV(ST(1)); if (g_slist_find(connections, gc)) XST_mPV(i++, gc->prpl->name()); title = SvPV(ST(0), junk); message = SvPV(ST(1), junk); do_error_dialog(message, title); struct gaim_connection *gc; gc = (struct gaim_connection *)SvIV(ST(0)); if (g_slist_find(connections, gc)) g = (struct group *)list->data; buddy = (struct buddy *)mem->data; XST_mPV(i++, buddy->name); list = g_slist_next(list); struct gaim_connection *gc; gc = (struct gaim_connection *)SvIV(ST(0)); if (g_slist_find(connections, gc)) g = (struct group *)list->data; b = (struct buddy *)mem->data; if (b->present) XST_mPV(i++, b->name); list = g_slist_next(list); command = SvPV(ST(0), junk); if (!command) XSRETURN(0); if (!strncasecmp(command, "signon", 6)) { if (g_slist_nth_data(aim_users, index)) serv_login(g_slist_nth_data(aim_users, index)); } else if (!strncasecmp(command, "signoff", 7)) { struct gaim_connection *gc = (struct gaim_connection *)SvIV(ST(1)); if (g_slist_find(connections, gc)) signoff(gc); else signoff_all(NULL, NULL); } else if (!strncasecmp(command, "info", 4)) { struct gaim_connection *gc = (struct gaim_connection *)SvIV(ST(1)); if (g_slist_find(connections, gc)) serv_set_info(gc, SvPV(ST(2), junk)); } else if (!strncasecmp(command, "away", 4)) { char *message = SvPV(ST(1), junk); static struct away_message a; g_snprintf(a.message, sizeof(a.message), "%s", message); do_away_message(NULL, &a); } else if (!strncasecmp(command, "back", 4)) { } else if (!strncasecmp(command, "idle", 4)) { struct gaim_connection *gc; gc = (struct gaim_connection *)c->data; serv_set_idle(gc, SvIV(ST(1))); } else if (!strncasecmp(command, "warn", 4)) { struct gaim_connection *gc; gc = (struct gaim_connection *)c->data; serv_warn(gc, SvPV(ST(1), junk), SvIV(ST(2))); struct gaim_connection *gc; struct buddy *buddy = NULL; gc = (struct gaim_connection *)SvIV(ST(0)); if (g_slist_find(connections, gc)) buddy = find_buddy(gc, SvPV(ST(1), junk)); XST_mPV(2, buddy->present ? "Online" : "Offline"); XST_mIV(4, buddy->signon); XS (XS_GAIM_write_to_conv) nick = SvPV(ST(0), junk); what = SvPV(ST(2), junk); case 0: wflags=WFLAG_SEND; break; case 1: wflags=WFLAG_RECV; break; case 2: wflags=WFLAG_SYSTEM; break; default: wflags=WFLAG_RECV; c = find_conversation(nick); c = new_conversation(nick); write_to_conv(c, what, wflags, who, time(NULL), -1); XS (XS_GAIM_serv_send_im) struct gaim_connection *gc; gc = (struct gaim_connection *)SvIV(ST(0)); nick = SvPV(ST(1), junk); what = SvPV(ST(2), junk); if (!g_slist_find(connections, gc)) { serv_send_im(gc, nick, what, -1, isauto); XS (XS_GAIM_print_to_conv) struct gaim_connection *gc; gc = (struct gaim_connection *)SvIV(ST(0)); nick = SvPV(ST(1), junk); what = SvPV(ST(2), junk); if (!g_slist_find(connections, gc)) { c = find_conversation(nick); c = new_conversation(nick); write_to_conv(c, what, WFLAG_SEND | (isauto ? WFLAG_AUTO : 0), NULL, time(NULL), -1); serv_send_im(c->gc, nick, what, -1, isauto ? IM_FLAG_AWAY : 0); XS (XS_GAIM_print_to_chat) struct gaim_connection *gc; struct conversation *b = NULL; gc = (struct gaim_connection *)SvIV(ST(0)); what = SvPV(ST(2), junk); if (!g_slist_find(connections, gc)) { b = (struct conversation *)bcs->data; serv_chat_send(gc, id, what); int perl_event(enum gaim_event event, void *arg1, void *arg2, void *arg3, void *arg4) struct _perl_event_handlers *data; buf = g_strdup_printf("'%lu'", (unsigned long)arg1); buf = g_strdup_printf("'%lu','%s'", (unsigned long)arg1, ((struct gaim_connection *)arg1)->away ? escape_quotes(((struct gaim_connection *)arg1)->away) : ""); char *tmp = *(char **)arg2 ? g_strdup(escape_quotes(*(char **)arg2)) : g_malloc0(1); buf = g_strdup_printf("'%lu','%s','%s'", (unsigned long)arg1, tmp, *(char **)arg3 ? escape_quotes(*(char **)arg3) : ""); char *tmp = arg2 ? g_strdup(escape_quotes(arg2)) : g_malloc0(1); buf = g_strdup_printf("'%lu','%s','%s'", (unsigned long)arg1, tmp, *(char **)arg3 ? escape_quotes(*(char **)arg3) : ""); case event_buddy_signoff: buf = g_strdup_printf("'%lu','%s'", (unsigned long)arg1, escape_quotes(arg2)); char *tmp2, *tmp3, *tmp4; tmp2 = g_strdup(escape_quotes(arg2)); tmp3 = g_strdup(escape_quotes(arg3)); tmp4 = arg4 ? g_strdup(escape_quotes(arg4)) : g_malloc0(1); buf = g_strdup_printf("'%lu','%s','%s','%s'", (unsigned long)arg1, tmp2, tmp3, tmp4); case event_chat_buddy_join: case event_chat_buddy_leave: buf = g_strdup_printf("'%lu','%d','%s'", (unsigned long)arg1, (int)arg2, buf = g_strdup_printf("'%lu','%d'", (unsigned long)arg1, (int)arg2); t3 = g_strdup(escape_quotes(*(char **)arg3)); t4 = *(char **)arg4 ? g_strdup(escape_quotes(*(char **)arg4)) : g_malloc0(1); buf = g_strdup_printf("'%lu','%d','%s','%s'", (unsigned long)arg1, (int)arg2, t3, t4); case event_chat_send_invite: t3 = g_strdup(escape_quotes(arg3)); t4 = *(char **)arg4 ? g_strdup(escape_quotes(*(char **)arg4)) : g_malloc0(1); buf = g_strdup_printf("'%lu','%d','%s','%s'", (unsigned long)arg1, (int)arg2, t3, t4); buf = g_strdup_printf("'%lu','%d','%s'", (unsigned long)arg1, (int)arg2, *(char **)arg3 ? escape_quotes(*(char **)arg3) : ""); buf = g_strdup_printf("'%lu','%s','%d'", (unsigned long)arg1, arg2 ? escape_quotes(arg2) : "", (int)arg3); case event_new_conversation: buf = g_strdup_printf("'%s'", escape_quotes(arg1)); case event_im_displayed_sent: tmp2 = g_strdup(escape_quotes(arg2)); tmp3 = *(char **)arg3 ? g_strdup(escape_quotes(*(char **)arg3)) : g_malloc0(1); buf = g_strdup_printf("'%lu','%s','%s'", (unsigned long)arg1, tmp2, tmp3); case event_im_displayed_rcvd: tmp2 = g_strdup(escape_quotes(arg2)); tmp3 = arg3 ? g_strdup(escape_quotes(arg3)) : g_malloc0(1); buf = g_strdup_printf("'%lu','%s','%s'", (unsigned long)arg1, tmp2, tmp3); for (handler = perl_event_handlers; handler != NULL; handler = handler->next) { if (!strcmp(event_name(event), data->event_type)) { handler_return = execute_perl(data->handler_name, buf); if (SvIV(handler_return)) { return SvIV(handler_return); XS (XS_GAIM_add_event_handler) struct _perl_event_handlers *handler; handler = g_new0(struct _perl_event_handlers, 1); handler->event_type = g_strdup(SvPV(ST(0), junk)); handler->handler_name = g_strdup(SvPV(ST(1), junk)); perl_event_handlers = g_list_append(perl_event_handlers, handler); debug_printf("registered perl event handler for %s\n", handler->event_type); static int perl_timeout(gpointer data) struct _perl_timeout_handlers *handler = data; execute_perl(handler->handler_name, escape_quotes(handler->handler_args)); perl_timeout_handlers = g_list_remove(perl_timeout_handlers, handler); g_free(handler->handler_args); g_free(handler->handler_name); return 0; /* returning zero removes the timeout handler */ XS (XS_GAIM_add_timeout_handler) struct _perl_timeout_handlers *handler; handler = g_new0(struct _perl_timeout_handlers, 1); timeout = 1000 * SvIV(ST(0)); debug_printf("Adding timeout for %d seconds.\n", timeout/1000); handler->handler_name = g_strdup(SvPV(ST(1), junk)); handler->handler_args = g_strdup(SvPV(ST(2), junk)); perl_timeout_handlers = g_list_append(perl_timeout_handlers, handler); handler->iotag = g_timeout_add(timeout, perl_timeout, handler); extern void unload_perl_scripts() extern void list_perl_scripts() at += g_snprintf(buf + at, sizeof(buf) - at, "Loaded scripts:\n"); p = (struct perlscript *)s->data; at += g_snprintf(buf + at, sizeof(buf) - at, "%s\n", p->name); do_error_dialog(buf, _("Perl Scripts"));