/* Main processing code for Services.
*
* IRC Services is copyright (c) 1996-2007 Andrew Church.
* E-mail: <achurch@achurch.org>
* Parts written by Andrew Kempe and others.
* This program is free but copyrighted software; see the file COPYING for
* details.
*/
#include "services.h"
#include "modules.h"
#include "messages.h"
#include "ignore.h"
static int cb_recvmsg = -1;
/*************************************************************************/
/*************************************************************************/
/* split_buf: Split a buffer into arguments and store a pointer to the
* argument vector in argv_ptr; return the argument count.
* The argument vector will point to a static buffer;
* subsequent calls will overwrite this buffer.
* If colon_special is non-zero, then treat a parameter with a
* leading ':' as the last parameter of the line, per the IRC
* RFC. Destroys the buffer by side effect.
*/
static char **sbargv = NULL;
int split_buf(char *buf, char ***argv_ptr, int colon_special)
{
static int argvsize = 8;
int argc;
char *s;
if (!sbargv)
sbargv = smalloc(sizeof(char *) * argvsize);
argc = 0;
while (*buf) {
if (argc == argvsize) {
argvsize += 8;
sbargv = srealloc(sbargv, sizeof(char *) * argvsize);
}
if (*buf == ':' && colon_special) {
sbargv[argc++] = buf+1;
*buf = 0;
} else {
s = strpbrk(buf, " ");
if (s) {
*s++ = 0;
while (*s == ' ')
s++;
} else {
s = buf + strlen(buf);
}
sbargv[argc++] = buf;
buf = s;
}
}
*argv_ptr = sbargv;
return argc;
}
/*************************************************************************/
/*************************************************************************/
int process_init(int ac, char **av)
{
cb_recvmsg = register_callback(NULL, "receive message");
if (cb_recvmsg < 0) {
log("process_init: register_callback() failed\n");
return 0;
}
return 1;
}
/*************************************************************************/
void process_cleanup(void)
{
unregister_callback(NULL, cb_recvmsg);
free(sbargv);
sbargv = NULL;
}
/*************************************************************************/
/* process: Main processing routine. Takes the string in inbuf (global
* variable) and does something appropriate with it. */
void process()
{
char source[64];
char cmd[64];
char buf[512]; /* Longest legal IRC command line */
char *s;
int ac; /* Parameters for the command */
char **av;
/* If debugging, log the buffer. */
if (debug)
log("debug: Received: %s", inbuf);
/* First make a copy of the buffer so we have the original in case we
* crash - in that case, we want to know what we crashed on. */
strscpy(buf, inbuf, sizeof(buf));
/* Split the buffer into pieces. */
if (*buf == ':') {
s = strpbrk(buf, " ");
if (!s)
return;
*s = 0;
while (isspace(*++s))
;
strscpy(source, buf+1, sizeof(source));
strmove(buf, s);
} else {
*source = 0;
}
if (!*buf)
return;
s = strpbrk(buf, " ");
if (s) {
*s = 0;
while (isspace(*++s))
;
} else
s = buf + strlen(buf);
strscpy(cmd, buf, sizeof(cmd));
ac = split_buf(s, &av, 1);
/* Do something with the message. */
if (call_callback_4(NULL, cb_recvmsg, source, cmd, ac, av) <= 0) {
if (!source && stricmp(cmd, "NICK") != 0) {
log("Source missing for `%s' message from server (%s)",cmd,inbuf);
} else {
Message *m = find_message(cmd);
if (m) {
if (m->func)
m->func(source, ac, av);
} else {
log("unknown message from server (%s)", inbuf);
}
}
}
/* Finally, clear the first byte of `inbuf' to signal that we're
* finished processing. */
*inbuf = 0;
}
/*************************************************************************/
syntax highlighted by Code2HTML, v. 0.9.1