home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 52
/
Amiga_Dream_52.iso
/
Linux
/
Divers
/
yagirc-0.51.tar.gz
/
yagirc-0.51.tar
/
yagirc-0.51
/
script.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-05-04
|
24KB
|
1,032 lines
/*
script.c : PERL script interface
Copyright (C) 1998 Jere Sanisalo <jeress@iname.com> and Timo Sirainen
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <string.h>
#include <sys/param.h>
#ifndef HAS_BOOL
#define HAS_BOOL
#define bool char
#endif
#include <EXTERN.h>
#include <XSUB.h>
#include <glib.h>
#include "os.h"
#include "txt.h"
#include "irc.h"
#include "script.h"
#include "events.h"
#include "commands.h"
#include "params.h"
#undef PACKAGE
#undef _
#include <perl.h>
enum
{
SCRIPT_EVENT_UNKNOWN,
SCRIPT_EVENT_COMMAND,
SCRIPT_EVENT_NUMERIC,
SCRIPT_EVENT_SERVERMSG,
SCRIPT_EVENT_JOIN,
SCRIPT_EVENT_PART,
SCRIPT_EVENT_PRIVMSG,
SCRIPT_EVENT_PUBMSG,
SCRIPT_EVENT_DCCMSG, /*!!*/
SCRIPT_EVENT_QUIT,
SCRIPT_EVENT_CONNECTED,
SCRIPT_EVENT_DISCONNECTED,
SCRIPT_EVENT_IRCJOIN, /*!!*/
SCRIPT_EVENT_IRCPART, /*!!*/
SCRIPT_EVENT_CTCP,
SCRIPT_EVENT_INVITE,
SCRIPT_EVENT_KICK,
SCRIPT_EVENT_MODE,
SCRIPT_EVENT_TOPIC,
SCRIPT_EVENT_ACTION,
};
typedef struct
{
int type;
char *name;
int sender_pos;
int sender_host_pos;
}
EVENT_LIST_REC;
static EVENT_LIST_REC events[] =
{
{ SCRIPT_EVENT_JOIN, "JOIN", 1, 2 },
{ SCRIPT_EVENT_PART, "PART", 1, 2 },
{ SCRIPT_EVENT_IRCJOIN, "IRCJOIN", 1, 2 },
{ SCRIPT_EVENT_IRCPART, "IRCPART", 1, 2 },
{ SCRIPT_EVENT_PRIVMSG, "PRIVMSG", 1, 0 },
{ SCRIPT_EVENT_PUBMSG, "PUBMSG", 1, 0 },
{ SCRIPT_EVENT_DCCMSG, "DCCMSG", 1, 0 },
{ SCRIPT_EVENT_ACTION, "ACTION", 1, 2 },
{ SCRIPT_EVENT_QUIT, "QUIT", 1, 2 },
{ SCRIPT_EVENT_SERVERMSG, "SERVERMSG", 0, 0 },
{ SCRIPT_EVENT_CONNECTED, "CONNECTED", 0, 0 },
{ SCRIPT_EVENT_DISCONNECTED, "DISCONNECTED", 0, 0 },
{ SCRIPT_EVENT_CTCP, "CTCP", 1, 2 },
{ SCRIPT_EVENT_INVITE, "INVITE", 1, 0 },
{ SCRIPT_EVENT_KICK, "KICK", 1, 0 },
{ SCRIPT_EVENT_MODE, "MODE", 1, 0 },
{ SCRIPT_EVENT_TOPIC, "TOPIC", 1, 0 },
{ 0, NULL }
};
static EVENT_LIST_REC event_numeric =
{ SCRIPT_EVENT_NUMERIC, NULL, 1, 2 };
static EVENT_LIST_REC event_command =
{ SCRIPT_EVENT_COMMAND, NULL, 0, 0 };
typedef struct
{
int id;
int type;
int num;
char *name;
char *spec;
char *func;
}
EVENT_REC;
typedef struct
{
int id;
int type;
char *name;
char *spec;
char *func;
}
MENU_REC;
static PerlInterpreter *perl_script;
static GList *event_list;
static int event_ids;
static GList *popup_menu;
static int popup_ids;
static int call_perl(char *name, char *args[]);
static void xs_init();
void script_init(void)
{
perl_script = NULL;
event_list = NULL; event_ids = 0;
popup_menu = NULL; popup_ids = 0;
}
void script_deinit(void)
{
GList *tmp;
script_event(eserver, NULL, NULL, "PRGQUIT", "");
if(perl_script!=NULL)
{
perl_destruct(perl_script);
perl_free(perl_script);
perl_script=NULL;
}
if (event_list == NULL)
{
for (tmp = g_list_first(event_list); tmp != NULL; tmp = tmp->next)
{
EVENT_REC *event;
event = (EVENT_REC *) tmp->data;
if (event->name != NULL) g_free(event->name);
g_free(event->spec);
g_free(event->func);
g_free(event);
}
g_list_free(event_list); event_list = NULL;
}
for (tmp = g_list_first(popup_menu); tmp != NULL; tmp = tmp->next)
{
MENU_REC *menu;
menu = (MENU_REC *) tmp->data;
g_free(menu->name);
g_free(menu->spec);
g_free(menu->func);
g_free(menu);
}
g_list_free(popup_menu); popup_menu = NULL;
}
int script_load(char *name)
{
char *arglist[] = { "perl", "-w", NULL, NULL };
g_return_val_if_fail(name != NULL, RET_ERR_PARAM);
script_deinit();
perl_script=perl_alloc();
if(perl_script==NULL)
{
g_warning("perl_alloc() failed\n");
return RET_ERROR;
}
perl_construct(perl_script);
arglist[2]=convhome(name);
if(perl_parse(perl_script,xs_init,2,arglist,(char **)NULL))
{
drawtext(curwin, TXT_TYPE_ERROR, IRCTXT_SCRIPT_NOT_FOUND, name);
script_deinit();
return RET_ERROR;
}
g_free(arglist[2]);
if(perl_run(perl_script))
{
g_warning("perl_run() failed\n");
script_deinit();
return RET_ERROR;
}
return RET_OK;
}
int script_event(SERVER_REC *sendserver, char *sendnick, char *sendaddr, char *event, char *data)
{
EVENT_LIST_REC *erec;
GList *tmp;
int num;
char *ptr;
g_return_val_if_fail(event != NULL, 1);
g_return_val_if_fail(data != NULL, 1);
if (perl_script == NULL) return 1;
if (event_list == NULL) return 1; /* there's no events grabbed.. */
if (sscanf(event, "%d", &num) == 1)
{
/* numeric event */
erec = &event_numeric;
}
else if (sendnick == NULL)
{
/* is is a grabbed /command */
erec = &event_command;
}
else
{
/* named event.. */
if (strcasecmp(event, "PRIVMSG") == 0 && (*data == '#' || *data == '&'))
{
/* this was public message */
event = "PUBMSG";
}
ptr = strchr(data, ' ');
if (ptr != NULL && *(ptr+1) == 1)
{
/* This is a CTCP */
if (strncmp(ptr+1, "ACTION ", 7) == 0)
event = "ACTION";
else
event = "CTCP";
}
erec = NULL;
for (num = 0; events[num].name != NULL; num++)
{
if (strcasecmp(event, events[num].name) == 0)
{
erec = &events[num];
break;
}
}
if (erec == NULL)
{
/* event wasn't recognized */
return 1;
}
}
/* now find every function that wants this event.. */
for (tmp = g_list_first(event_list); tmp != NULL; tmp = tmp->next)
{
EVENT_REC *ev;
ev = (EVENT_REC *) tmp->data;
if (ev->type == erec->type &&
(erec->type != SCRIPT_EVENT_NUMERIC || num == ev->num) &&
(erec->type != SCRIPT_EVENT_COMMAND || strcasecmp(ev->name, event) == 0))
{
/* found one! */
int ret, chancheck;
char *args[10], *datap, *startdata;
char *snick;
startdata = datap = g_strdup(data);
snick = NULL;
if (erec->sender_pos != 0)
{
if (sendnick == NULL)
args[erec->sender_pos-1] = "";
else
{
if (sendserver == NULL)
args[erec->sender_pos-1] = sendnick;
else
{
/* nick + server id */
snick = (char *) g_malloc(strlen(sendnick)+20);
sprintf(snick, "%s %d", sendnick, sendserver->handle);
args[erec->sender_pos-1] = snick;
}
}
}
if (erec->sender_host_pos != 0)
args[erec->sender_host_pos-1] = sendaddr == NULL ? "" : sendaddr;
ret = 1; /* default: call perl function */
chancheck = -1; /* default: don't check if channel name matches */
switch (ev->type)
{
case SCRIPT_EVENT_COMMAND:
args[0] = event_get_param(&datap); /* first parameter */
args[1] = datap;
args[2] = NULL;
chancheck = 0;
break;
case SCRIPT_EVENT_JOIN:
args[2] = event_get_param(&datap); /* channel */
args[3] = NULL;
chancheck = 2;
break;
case SCRIPT_EVENT_PART:
args[2] = event_get_param(&datap); /* channel */
args[3] = event_get_param(&datap); /* reason */
args[4] = NULL;
chancheck = 2;
break;
case SCRIPT_EVENT_QUIT:
args[2] = ""; /* channel names where (s)he was joined.. */
args[3] = event_get_param(&datap); /* reason */
break;
case SCRIPT_EVENT_PRIVMSG:
args[2] = event_get_param(&datap); /* text */
chancheck = 0;
break;
case SCRIPT_EVENT_PUBMSG:
args[2] = event_get_param(&datap); /* channel */
args[3] = event_get_param(&datap); /* text */
chancheck = 2;
break;
case SCRIPT_EVENT_ACTION:
args[2] = event_get_param(&datap); /* channel */
datap += 8; /* remove "\001ACTION "*/
ptr = strchr(datap, 1);
if (ptr != NULL) *ptr = '\0'; /* remove last \001 */
args[3] = event_get_param(&datap); /* data */
chancheck = 2;
break;
case SCRIPT_EVENT_CTCP:
args[2] = event_get_param(&datap); /* channel */
datap++; /* remove first \001 */
ptr = strchr(datap, 1);
if (ptr != NULL) *ptr = '\0'; /* remove last \001 */
args[3] = event_get_param(&datap); /* data */
chancheck = 2;
break;
case SCRIPT_EVENT_INVITE:
event_get_param(&datap); /* skip your name */
args[1] = event_get_param(&datap); /* channel */
args[2] = NULL;
chancheck = 1;
break;
case SCRIPT_EVENT_KICK:
args[1] = event_get_param(&datap); /* channel */
args[2] = event_get_param(&datap); /* kicked nick */
args[3] = event_get_param(&datap); /* reason */
args[4] = NULL;
chancheck = 1;
break;
case SCRIPT_EVENT_MODE:
args[1] = event_get_param(&datap); /* channel */
args[2] = event_get_param(&datap); /* mode */
args[3] = NULL;
chancheck = 1;
break;
case SCRIPT_EVENT_TOPIC:
args[1] = event_get_param(&datap); /* channel */
args[2] = event_get_param(&datap); /* topic */
args[3] = NULL;
chancheck = 1;
break;
default:
args[1] = datap;
args[2] = NULL;
break;
}
if (chancheck != -1 && *ev->spec != '\0' && strcasecmp(ev->spec, args[chancheck]) != 0)
{
/* this event isn't supposed to be sent in this channel.. */
ret = 0;
}
if (ret)
ret = !call_perl(ev->func, args);
else
ret = 1;
g_free(startdata);
if (snick != NULL) g_free(snick);
if (!ret) return 0;
}
}
return 1;
}
#ifdef USE_GUI
typedef struct
{
MENU_REC *menu;
char *data;
}
SCRIPT_PARAMS_REC;
static GList *script_params = NULL;
static void script_menu(SCRIPT_PARAMS_REC *sp)
{
char *args[2] = { NULL, NULL };
args[0] = sp->data;
call_perl(sp->menu->func, args);
}
void script_add_popups(GtkWidget *menu, int menutype, char *data)
{
GtkWidget *smenu;
GList *tmp;
g_return_if_fail(menu != NULL);
g_return_if_fail(data != NULL);
for (tmp = g_list_first(script_params); tmp != NULL; tmp = tmp->next)
g_free(script_params->data);
g_list_free(script_params);
smenu = NULL;
for (tmp = g_list_first(popup_menu); tmp != NULL; tmp = tmp->next)
{
MENU_REC *menu;
menu = (MENU_REC *) tmp->data;
if (menu->type == menutype &&
(*menu->spec == '\0' || strcasecmp(menu->spec, data) == 0))
{
SCRIPT_PARAMS_REC *sp;
if (smenu == NULL) smenu = gtk_menu_new();
sp = (SCRIPT_PARAMS_REC *) g_malloc(sizeof(SCRIPT_PARAMS_REC));
sp->menu = menu;
sp->data = data;
g_list_append(script_params, sp);
add_popup(smenu, menu->name, script_menu, sp);
}
}
if (smenu != NULL) add_popup_sub(menu, "Script", smenu);
}
#endif
/* C-commands used by perl */
/* NOTES ON PERL INTERFACE
---
Types:
. IV - Integer
. NV - Double
. PV - String
. SV - Scalar
Creates new values:
. SV* newSViv(IV);
. SV* newSVnv(double);
. SV* newSVpv(char*, int);
. SV* newSVpvf(const char*, ...);
. SV* newSVsv(SV*);
Sets the values: (length can be set to 0!)
. void sv_setiv(SV*, IV);
. void sv_setnv(SV*, double);
. void sv_setpv(SV*, char*);
. void sv_setpvn(SV*, char*, int)
. void sv_setpvf(SV*, const char*, ...);
. void sv_setsv(SV*, SV*);
Converts the values to C:
. SvIV(SV*)
. SvNV(SV*)
. SvPV(SV*,STRLEN len) (here the length is placed in len)
Checks if the value is TRUE:
. SvTRUE(SV*)
Checks if a value is ok:
. SvOK(SV*)
Checks if the value is of a type:
. SvIOK(SV*)
. SvNOK(SV*)
. SvPOK(SV*)
.If you know the name of a scalar variable, you can get a
.pointer to its SV by using the following:
. SV* perl_get_sv("package::varname", FALSE);
.This returns NULL if the variable does not exist.
Some predefined values:
. sv_no
. sv_undef
. sv_yes
---
NOTE ON STRINGS!
The strings may contains NUL-characters. The last char of the strings is not
necessarily a NUL, so be careful!
---
XS(xxx) predefined values:
. ax - unknown
. items - Number of items (use stack ST(x) to find 'em out (x=0..items))
The XS form goes like this (the dots at the start of the line are not
included):
XS(name)
{
. dXSARGS;
...CODE...
...Return method (eg. XS_RETURN_YES)...
}
Return methods:
. XSRETURN(v) - Returns with v args (must be mortal values in
. at the start of the stack)
. XSRETURN_IV(v)
. XSRETURN_NV(v)
. XSRETURN_PV(v)
. XSRETURN_NO
. XSRETURN_YES
. XSRETURN_UNDEF
. XSRETURN_EMPTY
*/
static char *dup0(char *str,int len)
{
char *tmp;
g_return_val_if_fail(str != NULL, NULL);
if(len<0) return NULL;
tmp=(char *)g_malloc(len+1);
memcpy(tmp,str,len);
tmp[len]='\0';
return tmp;
}
#define XS_GETSTR(num,name) { char *tmp; int len; tmp=(char *)SvPV(ST(num),len); name=dup0(tmp,len); }
#define XS_FREESTR(name) g_free(name);
static int call_perl(char *name, char *args[])
{
dSP;
int retcount,num,i,ret;
ENTER;
SAVETMPS;
g_return_val_if_fail(name != NULL, 0);
g_return_val_if_fail(args != NULL, 0);
PUSHMARK(sp);
while (*args != NULL)
{
XPUSHs(sv_2mortal(newSVpv(*args, strlen(*args))));
args++;
}
PUTBACK;
retcount=perl_call_pv(name,G_EVAL|G_SCALAR);
SPAGAIN;
ret = 0;
if(SvTRUE(GvSV(errgv)))
{
void *tmp;
g_warning("perl error: %s\n",SvPV(GvSV(errgv),na));
tmp = POPs;
}
else
{
if (retcount>0) ret = POPi;
for(num=2;num<=retcount;num++) i=POPi;
}
PUTBACK;
FREETMPS;
LEAVE;
return ret;
}
static SERVER_REC *get_server(char *chan)
{
int num;
chan = strchr(chan, ' ');
if (chan == NULL) return cserver;
*chan++ = '\0';
if (sscanf(chan, "%d", &num) != 1) return NULL;
return irc_get_server(num);
}
XS(ircBind)
{
char *event_name, *event_spec, *func_name;
EVENT_REC *event;
int tmp;
dXSARGS;
if(items!=3) XSRETURN_NO;
XS_GETSTR(0, event_name);
XS_GETSTR(1, event_spec);
XS_GETSTR(2, func_name);
event = g_malloc(sizeof(EVENT_REC));
event->id = ++event_ids;
event->type = SCRIPT_EVENT_UNKNOWN;
event->name = NULL;
event->spec = event_spec;
event->func = func_name;
if (sscanf(event_name, "%d", &event->num) == 1)
{
/* numeric event */
event->type = SCRIPT_EVENT_NUMERIC;
}
else
{
/* named event */
strupr(event_name);
for (tmp = 0; events[tmp].name != NULL; tmp++)
{
if (strcmp(event_name, events[tmp].name) == 0)
{
event->type = events[tmp].type;
break;
}
}
}
if (event->type == SCRIPT_EVENT_UNKNOWN)
{
/* unknown event */
event_ids--;
g_free(event);
XS_FREESTR(event_name);
XS_FREESTR(event_spec);
XS_FREESTR(func_name);
XSRETURN_NO;
}
XS_FREESTR(event_name);
event_list = g_list_append(event_list, event);
XSRETURN_IV(event->id);
}
XS(ircUnBind)
{
GList *tmp;
char *idstr;
int id;
dXSARGS;
if(items!=1) XSRETURN_NO;
XS_GETSTR(0, idstr);
if (sscanf(idstr, "%d", &id) != 1) XSRETURN_NO;
for (tmp = g_list_first(event_list); tmp != NULL; tmp = tmp->next)
{
EVENT_REC *event;
event = (EVENT_REC *) tmp->data;
if (event->id == id)
{
event_list = g_list_remove(event_list, event);
XSRETURN_YES;
}
}
XS_FREESTR(idstr);
XSRETURN_NO;
}
XS(ircBindCmd)
{
char *cmd_name, *cmd_spec, *func_name;
EVENT_REC *event;
dXSARGS;
if(items!=3) XSRETURN_NO;
XS_GETSTR(0, cmd_name);
XS_GETSTR(1, cmd_spec);
XS_GETSTR(2, func_name);
event = g_malloc(sizeof(EVENT_REC));
event->id = ++event_ids;
event->type = SCRIPT_EVENT_COMMAND;
event->name = cmd_name;
event->spec = cmd_spec;
event->func = func_name;
event_list = g_list_append(event_list, event);
XSRETURN_IV(event->id);
}
XS(ircMenuAdd)
{
char *menu_type, *menu_name, *menu_spec, *func_name;
MENU_REC *menu;
dXSARGS;
if(items!=4) XSRETURN_NO;
XS_GETSTR(0, menu_type);
XS_GETSTR(1, menu_name);
XS_GETSTR(2, menu_spec);
XS_GETSTR(3, func_name);
menu = (MENU_REC *) g_malloc(sizeof(MENU_REC));
menu->id = ++popup_ids;
menu->name = menu_name;
menu->spec = menu_spec;
menu->func = func_name;
if (strcasecmp(menu_type, "nick") == 0)
menu->type = POPUPMENU_NICK;
else if (strcasecmp(menu_type, "channel") == 0)
menu->type = POPUPMENU_CHAN;
else if (strcasecmp(menu_type, "global") == 0)
menu->type = POPUPMENU_MAIN;
else
{
/* unknown menu type */
popup_ids--;
g_free(menu);
XS_FREESTR(menu_type);
XS_FREESTR(menu_name);
XS_FREESTR(menu_spec);
XS_FREESTR(func_name);
XSRETURN_NO;
}
XS_FREESTR(menu_type);
popup_menu = g_list_append(popup_menu, menu);
XSRETURN_IV(menu->id);
}
XS(ircMenuRemove)
{
GList *tmp;
char *idstr;
int id;
dXSARGS;
if(items!=1) XSRETURN_NO;
XS_GETSTR(0, idstr);
if (sscanf(idstr, "%d", &id) != 1) XSRETURN_NO;
for (tmp = g_list_first(popup_menu); tmp != NULL; tmp = tmp->next)
{
MENU_REC *menu;
menu = (MENU_REC *) tmp->data;
if (menu->id == id)
{
popup_menu = g_list_remove(popup_menu, menu);
XSRETURN_YES;
}
}
XS_FREESTR(idstr);
XSRETURN_YES;
}
XS(ircMsg)
{
char *channel, *text, *tmp;
SERVER_REC *old;
dXSARGS;
if(items!=2) XSRETURN_NO;
XS_GETSTR(0, channel);
XS_GETSTR(1, text);
old = cserver; cserver = get_server(channel);
tmp = (char *) g_malloc(strlen(channel) + strlen(text)+2);
sprintf(tmp, "%s %s", channel, text);
irccmd_msg(tmp);
cserver = old;
XS_FREESTR(channel);
XS_FREESTR(text);
XSRETURN_YES;
}
XS(ircNotice)
{
char *channel, *text, *tmp;
SERVER_REC *old;
dXSARGS;
if(items!=2) XSRETURN_NO;
XS_GETSTR(0, channel);
XS_GETSTR(1, text);
old = cserver; cserver = get_server(channel);
tmp = (char *) g_malloc(strlen(channel) + strlen(text)+2);
sprintf(tmp, "%s %s", channel, text);
irccmd_notice(tmp);
cserver = old;
XS_FREESTR(channel);
XS_FREESTR(text);
XSRETURN_YES;
}
XS(ircCmd)
{
char *chan, *data;
CHAN_REC *ch;
dXSARGS;
if(items!=2) XSRETURN_NO;
XS_GETSTR(0, chan);
XS_GETSTR(1, data);
ch = channel_joined(NULL, chan);
if (ch == NULL) ch = curwin->curchan;
irc_parse_outgoing(ch, data);
XS_FREESTR(chan);
XS_FREESTR(data);
XSRETURN_YES;
}
XS(ircText)
{
char *chan, *data;
CHAN_REC *ch;
dXSARGS;
if(items!=2) XSRETURN_NO;
XS_GETSTR(0, chan);
XS_GETSTR(1, data);
ch = channel_joined(NULL, chan);
if (ch == NULL) ch = curwin->curchan;
drawtext(ch == NULL ? curwin : ch->window, TXT_TYPE_DEFAULT, data);
XS_FREESTR(chan);
XS_FREESTR(data);
XSRETURN_YES;
}
XS(ircCTCPSend)
{
char *chan, *data, *tmp;
SERVER_REC *old;
dXSARGS;
if(items!=2) XSRETURN_NO;
XS_GETSTR(0, chan);
XS_GETSTR(1, data);
old = cserver; cserver = get_server(chan);
tmp = (char *) g_malloc(strlen(chan)+strlen(data)+3);
sprintf(tmp, "%s %s\n", chan, data);
irccmd_ctcp(tmp);
g_free(tmp);
cserver = old;
XS_FREESTR(chan);
XS_FREESTR(data);
XSRETURN_YES;
}
XS(ircCTCPReply)
{
char *chan, *data, *tmp;
SERVER_REC *old;
dXSARGS;
if(items!=2) XSRETURN_NO;
XS_GETSTR(0, chan);
XS_GETSTR(1, data);
old = cserver; cserver = get_server(chan);
tmp = (char *) g_malloc(strlen(chan)+strlen(data)+3);
sprintf(tmp, "%s \001%s\001\n", chan, data);
irccmd_notice(tmp);
g_free(tmp);
cserver = old;
XS_FREESTR(chan);
XS_FREESTR(data);
XSRETURN_YES;
}
XS(ircServerCmd)
{
SERVER_REC *serv;
char *server, *data;
int tag, ok;
dXSARGS;
if(items!=2) XSRETURN_NO;
XS_GETSTR(0, server);
XS_GETSTR(1, data);
ok = 0;
if (sscanf(server, "%d", &tag) == 1)
{
serv = irc_get_server(tag);
if (serv != NULL)
ok = irc_send_cmd(serv, data);
}
XS_FREESTR(server);
XS_FREESTR(data);
if (ok) XSRETURN_YES; else XSRETURN_NO;
}
XS(ircTimerCallback)
{
/*char *func, *times;*/
dXSARGS;
if(items < 2) XSRETURN_NO;
/*XS_GETSTR(0, func);
XS_GETSTR(1, times);*/
XSRETURN_YES;
}
static void xs_init()
{
newXS("ircBind",ircBind,__FILE__);
newXS("ircUnBind",ircUnBind,__FILE__);
newXS("ircBindCmd",ircBindCmd,__FILE__);
newXS("ircUnBindCmd",ircUnBind,__FILE__);
newXS("ircMsg",ircMsg,__FILE__);
newXS("ircNotice",ircNotice,__FILE__);
newXS("ircCmd",ircCmd,__FILE__);
newXS("ircText",ircText,__FILE__);
newXS("ircMenuAdd",ircMenuAdd,__FILE__);
newXS("ircMenuRemove",ircMenuRemove,__FILE__);
newXS("ircCTCPSend",ircCTCPSend,__FILE__);
newXS("ircCTCPReply",ircCTCPReply,__FILE__);
newXS("ircServerCmd",ircServerCmd,__FILE__);
newXS("ircTimerCallback",ircTimerCallback,__FILE__);
}