1
0
mirror of https://github.com/irssi/irssi.git synced 2024-09-29 04:45:57 -04:00

Changed option handling in /commands. Irssi will now complain about

unknown options and missing option arguments.

Renamed /SERVER -add, -remove and -list to /SERVER ADD, REMOVE and LIST.


git-svn-id: http://svn.irssi.org/repos/irssi/trunk@365 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
Timo Sirainen 2000-06-18 01:18:12 +00:00 committed by cras
parent ca4226cca6
commit a5d31a195d
34 changed files with 946 additions and 573 deletions

View File

@ -1,3 +1,6 @@
Irssi's colors that you can use in text formats etc. :
text text background text text background
--------------------------------------------------------------------- ---------------------------------------------------------------------
%k %K %0 black bold black black %k %K %0 black bold black black
@ -17,3 +20,7 @@
%| Marks the indentation position %| Marks the indentation position
%% A single % %% A single %
MIRC colors that you can use when writing text to channel and with
hilighting text:
FIXME: list them :)

View File

@ -394,7 +394,7 @@
network and Irssi will pick the server for you. network and Irssi will pick the server for you.
You don't need to specify the IRC network, password, nick, etc. if You don't need to specify the IRC network, password, nick, etc. if
you setup the server using /SERVER -add (see next section). If the you setup the server using /SERVER ADD (see next section). If the
settings can't be found there either, Irssi will use the defaults: settings can't be found there either, Irssi will use the defaults:
/SET default_nick = <nick>, defaults to user_name /SET default_nick = <nick>, defaults to user_name
@ -424,9 +424,9 @@
5.4 Server settings 5.4 Server settings
/SERVER -add [-auto | -noauto] [-ircnet <ircnet>] [-host <hostname>] /SERVER ADD [-auto | -noauto] [-ircnet <ircnet>] [-host <hostname>]
[-cmdspeed <ms>] [-cmdmax <count>] [-port <port>] [-cmdspeed <ms>] [-cmdmax <count>] [-port <port>]
<address> [<port> [<password>]] <address> [<port> [<password>]]
-auto: Automatically connect to server at startup (default) -auto: Automatically connect to server at startup (default)
-noauto: Don't connect to server at startup -noauto: Don't connect to server at startup
@ -437,9 +437,9 @@
-port: This is pretty much like the port argument later, except -port: This is pretty much like the port argument later, except
this can be used to modify existing server's port. this can be used to modify existing server's port.
/SERVER -remove <address> [<port>] /SERVER REMOVE <address> [<port>]
/SERVER -list /SERVER LIST
Servers are identified by their name and port. You can have multiple Servers are identified by their name and port. You can have multiple
entries for the same server name but in different ports. This is entries for the same server name but in different ports. This is
@ -450,7 +450,7 @@
-port command. For example if you had irc.server.org in port 6667 -port command. For example if you had irc.server.org in port 6667
and you wanted to change it to port 6668, use command: and you wanted to change it to port 6668, use command:
/SERVER -add -port 6668 irc.server.org 6667 /SERVER ADD -port 6668 irc.server.org 6667
If you want to remove some settings from existing server, for If you want to remove some settings from existing server, for
example hostname, just give -host "" parameters to it. example hostname, just give -host "" parameters to it.

View File

@ -66,6 +66,7 @@ void command_free(COMMAND_REC *rec)
signal_emit("commandlist remove", 1, rec); signal_emit("commandlist remove", 1, rec);
g_free_not_null(rec->category); g_free_not_null(rec->category);
g_strfreev(rec->options);
g_free(rec->cmd); g_free(rec->cmd);
g_free(rec); g_free(rec);
} }
@ -93,7 +94,7 @@ void command_unbind(const char *cmd, SIGNAL_FUNC func)
} }
} }
void command_runsub(const char *cmd, const char *data, void *p1, void *p2) void command_runsub(const char *cmd, const char *data, void *server, void *item)
{ {
char *subcmd, *defcmd, *args; char *subcmd, *defcmd, *args;
@ -106,30 +107,101 @@ void command_runsub(const char *cmd, const char *data, void *p1, void *p2)
while (*args == ' ') args++; while (*args == ' ') args++;
g_strdown(subcmd); g_strdown(subcmd);
if (!signal_emit(subcmd, 3, args, p1, p2)) { if (!signal_emit(subcmd, 3, args, server, item)) {
defcmd = g_strdup_printf("default command %s", cmd); defcmd = g_strdup_printf("default command %s", cmd);
if (!signal_emit(defcmd, 3, data, p1, p2)) if (!signal_emit(defcmd, 3, data, server, item))
signal_emit("unknown command", 3, strchr(subcmd, ' ')+1, p1, p2); signal_emit("unknown command", 3, strchr(subcmd, ' ')+1, server, item);
g_free(defcmd); g_free(defcmd);
} }
g_free(subcmd); g_free(subcmd);
} }
COMMAND_REC *command_find(const char *command) COMMAND_REC *command_find(const char *cmd)
{ {
GSList *tmp; GSList *tmp;
int len;
g_return_val_if_fail(cmd != NULL, NULL);
for (tmp = commands; tmp != NULL; tmp = tmp->next) { for (tmp = commands; tmp != NULL; tmp = tmp->next) {
COMMAND_REC *rec = tmp->data; COMMAND_REC *rec = tmp->data;
if (g_strcasecmp(rec->cmd, command) == 0) if (g_strcasecmp(rec->cmd, cmd) == 0)
return rec; return rec;
} }
return NULL; return NULL;
} }
#define iscmdtype(c) \
((c) == '-' || (c) == '+' || (c) == '@')
static GSList *optlist_find(GSList *optlist, const char *option)
{
while (optlist != NULL) {
char *name = optlist->data;
if (iscmdtype(*name)) name++;
if (g_strcasecmp(name, option) == 0)
return optlist;
optlist = optlist->next;
}
return NULL;
}
void command_set_options(const char *cmd, const char *options)
{
COMMAND_REC *rec;
char **optlist, **tmp, *name, *str;
GSList *list, *oldopt;
g_return_if_fail(cmd != NULL);
g_return_if_fail(options != NULL);
rec = command_find(cmd);
g_return_if_fail(rec != NULL);
optlist = g_strsplit(options, " ", -1);
if (rec->options == NULL) {
/* first call - use specified args directly */
rec->options = optlist;
return;
}
/* save old options to linked list */
list = NULL;
for (tmp = rec->options; *tmp != NULL; tmp++)
list = g_slist_append(list, g_strdup(*tmp));
g_strfreev(rec->options);
/* merge the options */
for (tmp = optlist; *tmp != NULL; tmp++) {
name = iscmdtype(**tmp) ? (*tmp)+1 : *tmp;
oldopt = optlist_find(list, name);
if (oldopt != NULL) {
/* already specified - overwrite old defination */
g_free(oldopt->data);
oldopt->data = g_strdup(*tmp);
} else {
/* new option, append to list */
list = g_slist_append(list, g_strdup(*tmp));
}
}
g_strfreev(optlist);
/* linked list -> string[] */
g_free(rec->options);
str = gslist_to_string(list, " ");
rec->options = g_strsplit(str, " ", -1);
g_free(str);
g_slist_foreach(list, (GFunc) g_free, NULL);
g_slist_free(list);
}
char *cmd_get_param(char **data) char *cmd_get_param(char **data)
{ {
char *pos; char *pos;
@ -146,7 +218,7 @@ char *cmd_get_param(char **data)
return pos; return pos;
} }
char *cmd_get_quoted_param(char **data) static char *cmd_get_quoted_param(char **data)
{ {
char *pos, quote; char *pos, quote;
@ -171,67 +243,7 @@ char *cmd_get_quoted_param(char **data)
return pos; return pos;
} }
static char *get_opt_args(char **data) static int option_find(char **array, const char *item)
{
/* -cmd1 -cmd2 -cmd3 ... */
char *p, *ret;
int stopnext;
g_return_val_if_fail(data != NULL, NULL);
g_return_val_if_fail(*data != NULL, NULL);
stopnext = FALSE;
ret = NULL;
for (p = *data;;) {
if (*p != '-' || stopnext) {
if (p == *data) return "";
ret = *data;
*data = p;
while (isspace(p[-1]) && p > ret) p--;
if (*p != '\0') *p = '\0';
return ret;
}
if (p[1] == '-') {
/* -- argument means end of arguments even if
next word starts with - */
stopnext = TRUE;
}
while (!isspace(*p) && *p != '\0') p++;
while (isspace(*p)) p++;
}
}
static void cmd_params_pack(char ***subargs, char *end, char *start, char *newstart)
{
char ***tmp;
char *data;
int bufsize, datalen, len;
bufsize = (int) (end-newstart)+1;
data = g_malloc(bufsize); datalen = 0;
for (tmp = subargs; *tmp != NULL; tmp++) {
if (**tmp < start || **tmp > end)
continue;
len = strlen(**tmp)+1;
if (datalen+len > bufsize)
g_error("cmd_params_pack() : buffer overflow!");
memcpy(data+datalen, **tmp, len);
**tmp = newstart+datalen;
datalen += len;
}
g_memmove(newstart, data, datalen);
g_free(data);
}
int arg_find(char **array, const char *item)
{ {
char **tmp; char **tmp;
int index; int index;
@ -241,101 +253,83 @@ int arg_find(char **array, const char *item)
index = 0; index = 0;
for (tmp = array; *tmp != NULL; tmp++, index++) { for (tmp = array; *tmp != NULL; tmp++, index++) {
if (g_strcasecmp(*tmp + (**tmp == '@'), item) == 0) if (g_strcasecmp(*tmp + iscmdtype(**tmp), item) == 0)
return index; return index;
} }
return -1; return -1;
} }
static int get_multi_args(char **data, int checkonly, va_list va) static int get_cmd_options(char **data, int ignore_unknown,
const char *cmd, GHashTable *options)
{ {
/* -cmd1 arg1 -cmd2 "argument two" -cmd3 */ COMMAND_REC *rec;
GString *returnargs; char *option, *arg, **optlist;
char **args, **arglist, *arg, *origdata; int pos;
char **nextarg, ***subargs;
int eat, pos;
eat = 0; /* get option definations */
args = (char **) va_arg(va, char **); rec = cmd == NULL ? NULL : command_find(cmd);
g_return_val_if_fail(args != NULL && *args != NULL && **args != '\0', 0); optlist = rec == NULL ? NULL : rec->options;
arglist = g_strsplit(*args, " ", -1); option = NULL; pos = -1;
eat = strarray_length(arglist);
subargs = g_new(char **, eat+1);
for (pos = 0; pos < eat; pos++) {
subargs[pos] = (char **) va_arg(va, char **);
if (subargs[pos] == NULL) {
g_free(subargs);
g_warning("get_multi_args() : subargument == NULL");
return eat;
}
*subargs[pos] = "";
}
subargs[eat] = NULL;
origdata = *data;
returnargs = g_string_new(NULL);
nextarg = NULL;
for (;;) { for (;;) {
if (**data == '-') { if (**data == '-') {
if (option != NULL && *optlist[pos] == '+') {
/* required argument missing! */
*data = optlist[pos] + 1;
return CMDERR_OPTION_ARG_MISSING;
}
(*data)++; (*data)++;
if (**data == '-') { if (**data == '-') {
/* -- argument means end of arguments even /* -- option means end of options even
if next word starts with - */ if next word starts with - */
(*data)++; (*data)++;
while (isspace(**data)) (*data)++; while (isspace(**data)) (*data)++;
break; break;
} }
arg = cmd_get_param(data); option = cmd_get_param(data);
g_string_sprintfa(returnargs, "-%s ", arg);
/* check if this argument can have parameter */ /* check if this option can have argument */
pos = arg_find(arglist, arg); pos = optlist == NULL ? -1 : option_find(optlist, option);
nextarg = pos == -1 ? NULL : subargs[pos]; if (pos == -1 && !ignore_unknown) {
/* unknown option! */
*data = option;
return CMDERR_OPTION_UNKNOWN;
}
if (pos != -1) {
/* if we used a shortcut of parameter, put
the whole parameter name in options table */
option = optlist[pos] + iscmdtype(*optlist[pos]);
}
if (options != NULL) g_hash_table_insert(options, option, "");
if (pos == -1 || !iscmdtype(*optlist[pos]))
option = NULL;
while (isspace(**data)) (*data)++; while (isspace(**data)) (*data)++;
continue; continue;
} }
if (nextarg == NULL) if (option == NULL)
break; break;
if (*arglist[pos] == '@' && !isdigit(**data)) if (*optlist[pos] == '@' && !isdigit(**data))
break; /* expected a numeric argument */ break; /* expected a numeric argument */
/* save the sub-argument to `nextarg' */ /* save the argument */
arg = cmd_get_quoted_param(data); arg = cmd_get_quoted_param(data);
*nextarg = arg; nextarg = NULL; if (options != NULL) {
g_hash_table_remove(options, option);
g_hash_table_insert(options, option, arg);
}
option = NULL;
while (isspace(**data)) (*data)++; while (isspace(**data)) (*data)++;
} }
if (!checkonly) { return 0;
/* ok, this is a bit stupid. this will pack the arguments in
`data' like "-arg1 subarg -arg2 sub2\0" ->
"-arg1 -arg2\0subarg\0sub2\0" this is because it's easier
to free only _one_ string instead of two (`args') when
using PARAM_FLAG_MULTIARGS. */
if (returnargs->len == 0)
*args = "";
else {
cmd_params_pack(subargs, **data == '\0' ? *data : (*data)-1,
origdata, origdata+returnargs->len);
g_string_truncate(returnargs, returnargs->len-1);
strcpy(origdata, returnargs->str);
*args = origdata;
}
}
g_string_free(returnargs, TRUE);
g_strfreev(arglist);
g_free(subargs);
return eat;
} }
char *cmd_get_callfuncs(const char *data, int *count, va_list *args) char *cmd_get_callfuncs(const char *data, int *count, va_list *args)
@ -356,34 +350,38 @@ char *cmd_get_callfuncs(const char *data, int *count, va_list *args)
return ret; return ret;
} }
char *cmd_get_params(const char *data, int count, ...) typedef struct {
char *data;
GHashTable *options;
} CMD_TEMP_REC;
int cmd_get_params(const char *data, gpointer *free_me, int count, ...)
{ {
CMD_TEMP_REC *rec;
GHashTable **opthash;
char **str, *arg, *datad, *old; char **str, *arg, *datad, *old;
va_list args; va_list args;
int cnt, eat, len; int cnt, error, len;
g_return_val_if_fail(data != NULL, NULL); g_return_val_if_fail(data != NULL, FALSE);
va_start(args, count); va_start(args, count);
/* get the length of the arguments in string */ /* get the length of the options in string */
if ((count & (PARAM_FLAG_MULTIARGS|PARAM_FLAG_OPTARGS)) == 0) if ((count & PARAM_FLAG_OPTIONS) == 0)
len = 0; len = 0;
else { else {
old = datad = g_strdup(data); old = datad = g_strdup(data);
if (count & PARAM_FLAG_MULTIARGS) get_cmd_options(&datad, TRUE, NULL, NULL);
get_multi_args(&datad, TRUE, args);
else
get_opt_args(&datad);
len = (int) (datad-old); len = (int) (datad-old);
g_free(old); g_free(old);
} }
/* send the text to custom functions to handle - skip arguments */ /* send the text to custom functions to handle - skip options */
old = datad = cmd_get_callfuncs(data+len, &count, &args); old = datad = cmd_get_callfuncs(data+len, &count, &args);
if (len > 0) { if (len > 0) {
/* put the arguments + the new data to one string */ /* put the options + the new data to one string */
datad = g_malloc(len+1 + strlen(old)+1); datad = g_malloc(len+1 + strlen(old)+1);
memcpy(datad, data, len); memcpy(datad, data, len);
datad[len] = ' '; datad[len] = ' ';
@ -393,20 +391,25 @@ char *cmd_get_params(const char *data, int count, ...)
old = datad; old = datad;
} }
rec = g_new0(CMD_TEMP_REC, 1);
rec->data = old;
*free_me = rec;
/* and now handle the string */ /* and now handle the string */
error = FALSE;
cnt = PARAM_WITHOUT_FLAGS(count); cnt = PARAM_WITHOUT_FLAGS(count);
while (cnt-- > 0) { while (cnt-- > 0) {
if (count & PARAM_FLAG_MULTIARGS) { if (count & PARAM_FLAG_OPTIONS) {
eat = get_multi_args(&datad, FALSE, args)+1; arg = (char *) va_arg(args, char *);
count &= ~PARAM_FLAG_MULTIARGS; opthash = (GHashTable **) va_arg(args, GHashTable **);
cnt -= eat-1; rec->options = *opthash = g_hash_table_new((GHashFunc) g_istr_hash, (GCompareFunc) g_istr_equal);
while (eat-- > 0) error = get_cmd_options(&datad, count & PARAM_FLAG_UNKNOWN_OPTIONS, arg, *opthash);
str = (char **) va_arg(args, char **); if (error) break;
count &= ~PARAM_FLAG_OPTIONS;
cnt++;
continue; continue;
} else if (count & PARAM_FLAG_OPTARGS) {
arg = get_opt_args(&datad);
count &= ~PARAM_FLAG_OPTARGS;
} else if (cnt == 0 && count & PARAM_FLAG_GETREST) { } else if (cnt == 0 && count & PARAM_FLAG_GETREST) {
/* get rest */ /* get rest */
arg = datad; arg = datad;
@ -421,7 +424,24 @@ char *cmd_get_params(const char *data, int count, ...)
} }
va_end(args); va_end(args);
return old; if (error) {
signal_emit("error command", 2, GINT_TO_POINTER(error), datad);
signal_stop();
cmd_params_free(rec);
*free_me = NULL;
}
return !error;
}
void cmd_params_free(void *free_me)
{
CMD_TEMP_REC *rec = free_me;
if (rec->options != NULL) g_hash_table_destroy(rec->options);
g_free(rec->data);
g_free(rec);
} }
void cmd_get_add_func(CMD_GET_FUNC func) void cmd_get_add_func(CMD_GET_FUNC func)

View File

@ -6,10 +6,13 @@
typedef struct { typedef struct {
char *category; char *category;
char *cmd; char *cmd;
} char **options;
COMMAND_REC; } COMMAND_REC;
enum { enum {
CMDERR_OPTION_UNKNOWN = -2, /* unknown -option */
CMDERR_OPTION_ARG_MISSING = -1, /* argument missing for -option */
CMDERR_ERRNO, /* get the error from errno */ CMDERR_ERRNO, /* get the error from errno */
CMDERR_NOT_ENOUGH_PARAMS, /* not enough parameters given */ CMDERR_NOT_ENOUGH_PARAMS, /* not enough parameters given */
CMDERR_NOT_CONNECTED, /* not connected to IRC server */ CMDERR_NOT_CONNECTED, /* not connected to IRC server */
@ -20,7 +23,7 @@ enum {
}; };
#define cmd_return_error(a) { signal_emit("error command", 1, GINT_TO_POINTER(a)); signal_stop(); return; } #define cmd_return_error(a) { signal_emit("error command", 1, GINT_TO_POINTER(a)); signal_stop(); return; }
#define cmd_param_error(a) { g_free(params); cmd_return_error(a); } #define cmd_param_error(a) { cmd_params_free(free_arg); cmd_return_error(a); }
extern GSList *commands; extern GSList *commands;
extern char *current_command; extern char *current_command;
@ -29,12 +32,29 @@ void command_bind_to(int pos, const char *cmd, const char *category, SIGNAL_FUNC
#define command_bind(a, b, c) command_bind_to(1, a, b, c) #define command_bind(a, b, c) command_bind_to(1, a, b, c)
#define command_bind_first(a, b, c) command_bind_to(0, a, b, c) #define command_bind_first(a, b, c) command_bind_to(0, a, b, c)
#define command_bind_last(a, b, c) command_bind_to(2, a, b, c) #define command_bind_last(a, b, c) command_bind_to(2, a, b, c)
void command_unbind(const char *cmd, SIGNAL_FUNC func); void command_unbind(const char *cmd, SIGNAL_FUNC func);
void command_runsub(const char *cmd, const char *data, void *p1, void *p2); /* Run subcommand, `cmd' contains the base command, first word in `data'
contains the subcommand */
void command_runsub(const char *cmd, const char *data, void *server, void *item);
COMMAND_REC *command_find(const char *command); COMMAND_REC *command_find(const char *cmd);
/* Specify options that command can accept. `options' contains list of
options separated with space, each option can contain a special
char in front of it:
'-': optional argument
'+': argument required
'@': optional numeric argument
for example if options = "save -file +nick", you can use
/command -save -file [<filename>] -nick <nickname>
You can call this command multiple times for same command, options
will be merged. If there's any conflicts with option types, the last
call will override the previous */
void command_set_options(const char *cmd, const char *options);
/* count can have these flags: */ /* count can have these flags: */
#define PARAM_WITHOUT_FLAGS(a) ((a) & 0x00ffffff) #define PARAM_WITHOUT_FLAGS(a) ((a) & 0x00ffffff)
@ -42,30 +62,40 @@ COMMAND_REC *command_find(const char *command);
#define PARAM_FLAG_NOQUOTES 0x01000000 #define PARAM_FLAG_NOQUOTES 0x01000000
/* final argument gets all the rest of the arguments */ /* final argument gets all the rest of the arguments */
#define PARAM_FLAG_GETREST 0x02000000 #define PARAM_FLAG_GETREST 0x02000000
/* optional arguments (-cmd -cmd2 -cmd3) */ /* command contains options - first you need to specify them with
#define PARAM_FLAG_OPTARGS 0x04000000 command_set_options() function. Example:
/* arguments can have arguments too. Example:
-cmd arg -noargcmd -cmd2 "another arg -optnumarg rest of the text -cmd requiredarg -noargcmd -cmd2 "another arg" -optnumarg rest of text
You would call this with: You would call this with:
args = "cmd cmd2 @optnumarg"; // only once in init
cmd_get_params(data, 5 | PARAM_FLAG_MULTIARGS | PARAM_FLAG_GETREST, command_set_options("mycmd", "+cmd noargcmd -cmd2 @optnumarg");
&args, &arg_cmd, &arg_cmd2, &arg_optnum, &rest);
The variables are filled as following: GHashTable *optlist;
args = "-cmd -noargcmd -cmd2 -optnumarg" cmd_get_params(data, &free_me, 1 | PARAM_FLAG_OPTIONS |
arg_cmd = "arg" PARAM_FLAG_GETREST, "mycmd", &optlist, &rest);
arg_cmd2 = "another arg"
rest = "rest of the text" The optlist hash table is filled:
arg_optnum = "" - this is because "rest" isn't a numeric value
"cmd" = "requiredarg"
"noargcmd" = ""
"cmd2" = "another arg"
"optnumarg" = "" - this is because "rest" isn't a numeric value
*/ */
#define PARAM_FLAG_MULTIARGS 0x08000000 #define PARAM_FLAG_OPTIONS 0x04000000
/* don't complain about unknown options */
#define PARAM_FLAG_UNKNOWN_OPTIONS 0x08000000
char *cmd_get_param(char **data); char *cmd_get_param(char **data);
char *cmd_get_params(const char *data, int count, ...); /* get parameters from command - you should point free_me somewhere and
cmd_params_free() it after you don't use any of the parameters anymore.
Returns TRUE if all ok, FALSE if error occured. */
int cmd_get_params(const char *data, gpointer *free_me, int count, ...);
void cmd_params_free(void *free_me);
typedef char* (*CMD_GET_FUNC) (const char *data, int *count, va_list *args); typedef char* (*CMD_GET_FUNC) (const char *data, int *count, va_list *args);
void cmd_get_add_func(CMD_GET_FUNC func); void cmd_get_add_func(CMD_GET_FUNC func);

View File

@ -247,7 +247,8 @@ void *gslist_foreach_find(GSList *list, FOREACH_FIND_FUNC func, void *data)
return NULL; return NULL;
} }
char *gslist_to_string(GSList *list, int offset, const char *delimiter) /* `list' contains pointer to structure with a char* to string. */
char *gslistptr_to_string(GSList *list, int offset, const char *delimiter)
{ {
GString *str; GString *str;
char **data, *ret; char **data, *ret;
@ -266,6 +267,41 @@ char *gslist_to_string(GSList *list, int offset, const char *delimiter)
return ret; return ret;
} }
/* `list' contains char* */
char *gslist_to_string(GSList *list, const char *delimiter)
{
GString *str;
char *ret;
str = g_string_new(NULL);
while (list != NULL) {
if (str->len != 0) g_string_append(str, delimiter);
g_string_append(str, list->data);
list = list->next;
}
ret = str->str;
g_string_free(str, FALSE);
return ret;
}
void hash_save_key(char *key, void *value, GSList **list)
{
*list = g_slist_append(*list, key);
}
/* save all keys in hash table to linked list - you shouldn't remove any
items while using this list, use g_slist_free() after you're done with it */
GSList *hashtable_get_keys(GHashTable *hash)
{
GSList *list;
list = NULL;
g_hash_table_foreach(hash, (GHFunc) hash_save_key, &list);
return list;
}
GList *glist_find_string(GList *list, const char *key) GList *glist_find_string(GList *list, const char *key)
{ {
for (list = list; list != NULL; list = list->next) for (list = list; list != NULL; list = list->next)

View File

@ -25,7 +25,15 @@ GList *glist_find_string(GList *list, const char *key);
GList *glist_find_icase_string(GList *list, const char *key); GList *glist_find_icase_string(GList *list, const char *key);
void *gslist_foreach_find(GSList *list, FOREACH_FIND_FUNC func, void *data); void *gslist_foreach_find(GSList *list, FOREACH_FIND_FUNC func, void *data);
char *gslist_to_string(GSList *list, int offset, const char *delimiter);
/* `list' contains pointer to structure with a char* to string. */
char *gslistptr_to_string(GSList *list, int offset, const char *delimiter);
/* `list' contains char* */
char *gslist_to_string(GSList *list, const char *delimiter);
/* save all keys in hash table to linked list - you shouldn't remove any
items while using this list, use g_slist_free() after you're done with it */
GSList *hashtable_get_keys(GHashTable *hash);
/* strstr() with case-ignoring */ /* strstr() with case-ignoring */
char *stristr(const char *data, const char *key); char *stristr(const char *data, const char *key);

View File

@ -31,7 +31,7 @@
#include "windows.h" #include "windows.h"
static const char *ret_texts[] = { static const char *ret_texts[] = {
NULL, NULL,
"Not enough parameters given", "Not enough parameters given",
"Not connected to IRC server yet", "Not connected to IRC server yet",
"Not joined to any channels yet", "Not joined to any channels yet",
@ -230,15 +230,18 @@ static void cmd_version(char *data)
static void cmd_cat(const char *data) static void cmd_cat(const char *data)
{ {
char *params, *fname, *fposstr;
char tmpbuf[1024], *str;
LINEBUF_REC *buffer = NULL; LINEBUF_REC *buffer = NULL;
char *fname, *fposstr;
char tmpbuf[1024], *str;
void *free_arg;
int f, ret, recvlen, fpos; int f, ret, recvlen, fpos;
params = cmd_get_params(data, 2, &fname, &fposstr); if (!cmd_get_params(data, &free_arg, 2, &fname, &fposstr))
return;
fname = convert_home(fname); fname = convert_home(fname);
fpos = atoi(fposstr); fpos = atoi(fposstr);
g_free(params); cmd_params_free(free_arg);
f = open(fname, O_RDONLY); f = open(fname, O_RDONLY);
g_free(fname); g_free(fname);
@ -301,15 +304,24 @@ static void event_default_command(const char *data, void *server, WI_ITEM_REC *i
cmd_unknown(data, server, item); cmd_unknown(data, server, item);
} }
static void event_cmderror(gpointer errorp) static void event_cmderror(gpointer errorp, const char *arg)
{ {
int error; int error;
error = GPOINTER_TO_INT(errorp); error = GPOINTER_TO_INT(errorp);
if (error == CMDERR_ERRNO) switch (error) {
case CMDERR_ERRNO:
printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, g_strerror(errno)); printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, g_strerror(errno));
else break;
case CMDERR_OPTION_UNKNOWN:
printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Unknown argument: %s", arg);
break;
case CMDERR_OPTION_ARG_MISSING:
printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Missing required argument for: %s", arg);
break;
default:
printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, ret_texts[error]); printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, ret_texts[error]);
}
} }
void fe_core_commands_init(void) void fe_core_commands_init(void)

View File

@ -45,18 +45,24 @@ static void cmd_log_open(const char *data)
{ {
/* /LOG OPEN [-noopen] [-autoopen] [-targets <targets>] [-window] /* /LOG OPEN [-noopen] [-autoopen] [-targets <targets>] [-window]
[-rotate hour|day|week|month] <fname> [<levels>] */ [-rotate hour|day|week|month] <fname> [<levels>] */
char *params, *args, *targetarg, *rotatearg, *fname, *levels; GHashTable *optlist;
char *targetarg, *rotatearg, *fname, *levels;
void *free_arg;
char window[MAX_INT_STRLEN]; char window[MAX_INT_STRLEN];
LOG_REC *log; LOG_REC *log;
int level, rotate; int level, rotate;
args = "targets rotate"; if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | PARAM_FLAG_GETREST,
params = cmd_get_params(data, 5 | PARAM_FLAG_MULTIARGS | PARAM_FLAG_GETREST, "log open", &optlist, &fname, &levels))
&args, &targetarg, &rotatearg, &fname, &levels); return;
targetarg = g_hash_table_lookup(optlist, "targets");
rotatearg = g_hash_table_lookup(optlist, "rotate");
if (*fname == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*fname == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
rotate = LOG_ROTATE_NEVER; rotate = LOG_ROTATE_NEVER;
if (stristr(args, "-rotate")) { if (rotatearg != NULL) {
rotate = log_str2rotate(rotatearg); rotate = log_str2rotate(rotatearg);
if (rotate < 0) rotate = LOG_ROTATE_NEVER; if (rotate < 0) rotate = LOG_ROTATE_NEVER;
} }
@ -64,7 +70,7 @@ static void cmd_log_open(const char *data)
level = level2bits(levels); level = level2bits(levels);
if (level == 0) level = MSGLEVEL_ALL; if (level == 0) level = MSGLEVEL_ALL;
if (stristr(args, "-window")) { if (g_hash_table_lookup(optlist, "window")) {
/* log by window ref# */ /* log by window ref# */
ltoa(window, active_win->refnum); ltoa(window, active_win->refnum);
targetarg = window; targetarg = window;
@ -72,12 +78,12 @@ static void cmd_log_open(const char *data)
log = log_create_rec(fname, level, targetarg); log = log_create_rec(fname, level, targetarg);
if (log != NULL) { if (log != NULL) {
if (stristr(args, "-autoopen")) if (g_hash_table_lookup(optlist, "autoopen"))
log->autoopen = TRUE; log->autoopen = TRUE;
log->rotate = rotate; log->rotate = rotate;
log_update(log); log_update(log);
if (log->handle == -1 && stristr(args, "-noopen") == NULL) { if (log->handle == -1 && g_hash_table_lookup(optlist, "noopen") == NULL) {
/* start logging */ /* start logging */
if (log_start_logging(log)) { if (log_start_logging(log)) {
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
@ -88,7 +94,7 @@ static void cmd_log_open(const char *data)
} }
} }
g_free(params); cmd_params_free(free_arg);
} }
static LOG_REC *log_find_from_data(const char *data) static LOG_REC *log_find_from_data(const char *data)
@ -191,10 +197,12 @@ static void cmd_window_log(const char *data)
{ {
/* /WINDOW LOG ON|OFF|TOGGLE [<filename>] */ /* /WINDOW LOG ON|OFF|TOGGLE [<filename>] */
LOG_REC *log; LOG_REC *log;
char *params, *set, *fname, window[MAX_INT_STRLEN]; char *set, *fname, window[MAX_INT_STRLEN];
void *free_arg;
int open_log, close_log; int open_log, close_log;
params = cmd_get_params(data, 2, &set, &fname); if (!cmd_get_params(data, &free_arg, 2, &set, &fname))
return;
ltoa(window, active_win->refnum); ltoa(window, active_win->refnum);
log = log_find_item(window); log = log_find_item(window);
@ -209,7 +217,7 @@ static void cmd_window_log(const char *data)
close_log = log != NULL; close_log = log != NULL;
} else { } else {
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_NOT_TOGGLE); printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_NOT_TOGGLE);
g_free(params); cmd_params_free(free_arg);
return; return;
} }
@ -232,7 +240,7 @@ static void cmd_window_log(const char *data)
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_LOG_CLOSED, log->fname); printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_LOG_CLOSED, log->fname);
} }
g_free(params); cmd_params_free(free_arg);
} }
/* Create log file entry to window, but don't start logging */ /* Create log file entry to window, but don't start logging */
@ -440,6 +448,8 @@ void fe_log_init(void)
signal_add("log create failed", (SIGNAL_FUNC) sig_log_create_failed); signal_add("log create failed", (SIGNAL_FUNC) sig_log_create_failed);
signal_add("awaylog show", (SIGNAL_FUNC) sig_awaylog_show); signal_add("awaylog show", (SIGNAL_FUNC) sig_awaylog_show);
signal_add("setup changed", (SIGNAL_FUNC) read_settings); signal_add("setup changed", (SIGNAL_FUNC) read_settings);
command_set_options("log open", "noopen autoopen -targets window -rotate");
} }
void fe_log_deinit(void) void fe_log_deinit(void)

View File

@ -66,10 +66,12 @@ static void set_boolean(const char *key, const char *value)
static void cmd_set(char *data) static void cmd_set(char *data)
{ {
GSList *sets, *tmp; GSList *sets, *tmp;
char *params, *key, *value, *last_section; char *key, *value, *last_section;
void *free_arg;
int found; int found;
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &key, &value); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &key, &value))
return;
last_section = ""; found = 0; last_section = ""; found = 0;
sets = settings_get_sorted(); sets = settings_get_sorted();
@ -110,15 +112,17 @@ static void cmd_set(char *data)
if (!found) if (!found)
printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Unknown setting %s", key); printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Unknown setting %s", key);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_toggle(const char *data) static void cmd_toggle(const char *data)
{ {
char *params, *key, *value; char *key, *value;
void *free_arg;
int type; int type;
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &key, &value); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &key, &value))
return;
type = settings_get_type(key); type = settings_get_type(key);
if (type == -1) if (type == -1)
@ -130,7 +134,7 @@ static void cmd_toggle(const char *data)
set_print(settings_get_record(key)); set_print(settings_get_record(key));
} }
g_free(params); cmd_params_free(free_arg);
} }
static void show_aliases(const char *alias) static void show_aliases(const char *alias)
@ -173,11 +177,14 @@ static void alias_remove(const char *alias)
static void cmd_alias(const char *data) static void cmd_alias(const char *data)
{ {
char *params, *alias, *value; char *alias, *value;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &alias, &value); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &alias, &value))
return;
if (*alias == '-') { if (*alias == '-') {
if (alias[1] != '\0') alias_remove(alias+1); if (alias[1] != '\0') alias_remove(alias+1);
} else if (*alias == '\0' || *value == '\0') } else if (*alias == '\0' || *value == '\0')
@ -186,7 +193,7 @@ static void cmd_alias(const char *data)
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_ALIAS_ADDED, alias); printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_ALIAS_ADDED, alias);
iconfig_set_str("aliases", alias, value); iconfig_set_str("aliases", alias, value);
} }
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_unalias(const char *data) static void cmd_unalias(const char *data)

View File

@ -268,9 +268,11 @@ static void cmd_hilight_show(void)
static void cmd_hilight(const char *data) static void cmd_hilight(const char *data)
{ {
/* /HILIGHT [-nick | -regexp | -word] [-color <color>] [-level <level>] [-channels <channels>] <text> */ /* /HILIGHT [-nick | -regexp | -word] [-color <color>] [-level <level>] [-channels <channels>] <text> */
char *params, *args, *colorarg, *levelarg, *chanarg, *text; GHashTable *optlist;
char **channels;
HILIGHT_REC *rec; HILIGHT_REC *rec;
char *colorarg, *levelarg, *chanarg, *text;
char **channels;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
@ -279,12 +281,17 @@ static void cmd_hilight(const char *data)
return; return;
} }
args = "color level channels"; if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS |
params = cmd_get_params(data, 5 | PARAM_FLAG_MULTIARGS | PARAM_FLAG_GETREST, PARAM_FLAG_GETREST, "hilight", &optlist, &text))
&args, &colorarg, &levelarg, &chanarg, &text); return;
chanarg = g_hash_table_lookup(optlist, "channels");
levelarg = g_hash_table_lookup(optlist, "level");
colorarg = g_hash_table_lookup(optlist, "color");
if (*text == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*text == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
channels = *chanarg == '\0' ? NULL : channels = (chanarg == NULL || *chanarg == '\0') ? NULL :
g_strsplit(replace_chars(chanarg, ',', ' '), " ", -1); g_strsplit(replace_chars(chanarg, ',', ' '), " ", -1);
rec = hilight_find(text, channels); rec = hilight_find(text, channels);
@ -302,17 +309,19 @@ static void cmd_hilight(const char *data)
} }
hilights = g_slist_append(hilights, rec); hilights = g_slist_append(hilights, rec);
rec->nickmask = stristr(args, "-nick") != NULL; rec->nickmask = g_hash_table_lookup(optlist, "nick") != NULL;
rec->fullword = stristr(args, "-word") != NULL; rec->fullword = g_hash_table_lookup(optlist, "word") != NULL;
rec->regexp = stristr(args, "-regexp") != NULL; rec->regexp = g_hash_table_lookup(optlist, "regexp") != NULL;
rec->level = level2bits(replace_chars(levelarg, ',', ' ')); rec->level = (levelarg == NULL || *levelarg == '\0') ? 0 :
if (*colorarg != '\0') rec->color = g_strdup(colorarg); level2bits(replace_chars(levelarg, ',', ' '));
if (colorarg != NULL && *colorarg != '\0')
rec->color = g_strdup(colorarg);
hilight_print(g_slist_index(hilights, rec)+1, rec); hilight_print(g_slist_index(hilights, rec)+1, rec);
hilight_add_config(rec); hilight_add_config(rec);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_dehilight(const char *data) static void cmd_dehilight(const char *data)
@ -349,6 +358,8 @@ void hilight_text_init(void)
signal_add("setup reread", (SIGNAL_FUNC) read_hilight_config); signal_add("setup reread", (SIGNAL_FUNC) read_hilight_config);
command_bind("hilight", NULL, (SIGNAL_FUNC) cmd_hilight); command_bind("hilight", NULL, (SIGNAL_FUNC) cmd_hilight);
command_bind("dehilight", NULL, (SIGNAL_FUNC) cmd_dehilight); command_bind("dehilight", NULL, (SIGNAL_FUNC) cmd_dehilight);
command_set_options("hilight", "-color -level -channels nick word regexp");
} }
void hilight_text_deinit(void) void hilight_text_deinit(void)

View File

@ -348,17 +348,21 @@ static void theme_show(THEME_SEARCH_REC *rec, const char *key, const char *value
static void cmd_format(const char *data) static void cmd_format(const char *data)
{ {
char *params, *module, *key, *value;
GSList *tmp, *modules; GSList *tmp, *modules;
char *module, *key, *value;
void *free_arg;
/* /FORMAT [<module>] [<key> [<value>]] */ /* /FORMAT [<module>] [<key> [<value>]] */
params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &module, &key, &value); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST,
&module, &key, &value))
return;
modules = get_sorted_modules(); modules = get_sorted_modules();
if (*module != '\0' && theme_search(modules, module) == NULL) { if (*module != '\0' && theme_search(modules, module) == NULL) {
/* first argument isn't module.. */ /* first argument isn't module.. */
g_free(params); cmd_params_free(free_arg);
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &key, &value); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &key, &value))
return;
module = ""; module = "";
} }
@ -374,7 +378,7 @@ static void cmd_format(const char *data)
g_slist_foreach(modules, (GFunc) g_free, NULL); g_slist_foreach(modules, (GFunc) g_free, NULL);
g_slist_free(modules); g_slist_free(modules);
g_free(params); cmd_params_free(free_arg);
} }
static void module_save(const char *module, MODULE_THEME_REC *rec, CONFIG_NODE *fnode) static void module_save(const char *module, MODULE_THEME_REC *rec, CONFIG_NODE *fnode)

View File

@ -231,24 +231,28 @@ static void dcc_error_close_not_found(const char *type, const char *nick, const
static void dcc_unknown_ctcp(const char *data, const char *sender) static void dcc_unknown_ctcp(const char *data, const char *sender)
{ {
char *params, *type, *args; char *type, *args;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &type, &args); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &type, &args))
return;
printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_UNKNOWN_CTCP, type, sender, args); printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_UNKNOWN_CTCP, type, sender, args);
g_free(params); cmd_params_free(free_arg);
} }
static void dcc_unknown_reply(const char *data, const char *sender) static void dcc_unknown_reply(const char *data, const char *sender)
{ {
char *params, *type, *args; char *type, *args;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &type, &args); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &type, &args))
return;
printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_UNKNOWN_REPLY, type, sender, args); printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_UNKNOWN_REPLY, type, sender, args);
g_free(params); cmd_params_free(free_arg);
} }
static void sig_dcc_destroyed(DCC_REC *dcc) static void sig_dcc_destroyed(DCC_REC *dcc)
@ -288,7 +292,8 @@ static void sig_query_destroyed(QUERY_REC *query)
static void cmd_msg(const char *data) static void cmd_msg(const char *data)
{ {
DCC_REC *dcc; DCC_REC *dcc;
char *params, *text, *target; char *text, *target;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
@ -297,7 +302,8 @@ static void cmd_msg(const char *data)
return; return;
} }
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &text); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &target, &text))
return;
dcc = dcc_find_item(DCC_TYPE_CHAT, target+1, NULL); dcc = dcc_find_item(DCC_TYPE_CHAT, target+1, NULL);
if (dcc == NULL) { if (dcc == NULL) {
@ -309,7 +315,7 @@ static void cmd_msg(const char *data)
IRCTXT_OWN_DCC, dcc->mynick, text); IRCTXT_OWN_DCC, dcc->mynick, text);
} }
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_me(const char *data, SERVER_REC *server, WI_IRC_REC *item) static void cmd_me(const char *data, SERVER_REC *server, WI_IRC_REC *item)
@ -327,8 +333,9 @@ static void cmd_me(const char *data, SERVER_REC *server, WI_IRC_REC *item)
static void cmd_action(const char *data, SERVER_REC *server, WI_IRC_REC *item) static void cmd_action(const char *data, SERVER_REC *server, WI_IRC_REC *item)
{ {
char *params, *target, *text;
DCC_REC *dcc; DCC_REC *dcc;
char *target, *text;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
@ -337,7 +344,8 @@ static void cmd_action(const char *data, SERVER_REC *server, WI_IRC_REC *item)
return; return;
} }
params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &target, &text); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, &target, &text))
return;
if (*target == '\0' || *text == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*target == '\0' || *text == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
dcc = dcc_find_item(DCC_TYPE_CHAT, target+1, NULL); dcc = dcc_find_item(DCC_TYPE_CHAT, target+1, NULL);
@ -348,23 +356,25 @@ static void cmd_action(const char *data, SERVER_REC *server, WI_IRC_REC *item)
printformat(NULL, target, MSGLEVEL_DCC, printformat(NULL, target, MSGLEVEL_DCC,
IRCTXT_OWN_DCC_ME, dcc->mynick, text); IRCTXT_OWN_DCC_ME, dcc->mynick, text);
} }
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_ctcp(const char *data, SERVER_REC *server) static void cmd_ctcp(const char *data, SERVER_REC *server)
{ {
char *params, *target, *ctcpcmd, *ctcpdata;
DCC_REC *dcc; DCC_REC *dcc;
char *target, *ctcpcmd, *ctcpdata;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED); if (server == NULL || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &target, &ctcpcmd, &ctcpdata); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, &target, &ctcpcmd, &ctcpdata))
return;
if (*target == '\0' || *ctcpcmd == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*target == '\0' || *ctcpcmd == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
if (*target != '=') { if (*target != '=') {
/* handle only DCC CTCPs */ /* handle only DCC CTCPs */
g_free(params); cmd_params_free(free_arg);
return; return;
} }
@ -378,7 +388,7 @@ static void cmd_ctcp(const char *data, SERVER_REC *server)
target, ctcpcmd, ctcpdata); target, ctcpcmd, ctcpdata);
} }
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_dcc_list(const char *data) static void cmd_dcc_list(const char *data)

View File

@ -192,12 +192,17 @@ static void cmd_channel(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *i
static void cmd_channel_add(const char *data) static void cmd_channel_add(const char *data)
{ {
char *params, *args, *botarg, *botcmdarg, *ircnet, *channel, *password; GHashTable *optlist;
SETUP_CHANNEL_REC *rec; SETUP_CHANNEL_REC *rec;
char *botarg, *botcmdarg, *ircnet, *channel, *password;
void *free_arg;
args = "bots botcmd"; if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_OPTIONS,
params = cmd_get_params(data, 6 | PARAM_FLAG_MULTIARGS, &args, "channel add", &optlist, &channel, &ircnet, &password))
&botarg, &botcmdarg, &channel, &ircnet, &password); return;
botarg = g_hash_table_lookup(optlist, "bots");
botcmdarg = g_hash_table_lookup(optlist, "botcmd");
if (*ircnet == '\0' || *channel == '\0') if (*ircnet == '\0' || *channel == '\0')
cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
@ -207,27 +212,29 @@ static void cmd_channel_add(const char *data)
rec->name = g_strdup(channel); rec->name = g_strdup(channel);
rec->ircnet = g_strdup(ircnet); rec->ircnet = g_strdup(ircnet);
} else { } else {
if (stristr(args, "-bots")) g_free_and_null(rec->botmasks); if (g_hash_table_lookup(optlist, "bots")) g_free_and_null(rec->botmasks);
if (stristr(args, "-botcmd")) g_free_and_null(rec->autosendcmd); if (g_hash_table_lookup(optlist, "botcmd")) g_free_and_null(rec->autosendcmd);
if (*password != '\0') g_free_and_null(rec->password); if (*password != '\0') g_free_and_null(rec->password);
} }
if (stristr(args, "-auto")) rec->autojoin = TRUE; if (g_hash_table_lookup(optlist, "auto")) rec->autojoin = TRUE;
if (stristr(args, "-noauto")) rec->autojoin = FALSE; if (g_hash_table_lookup(optlist, "noauto")) rec->autojoin = FALSE;
if (*botarg != '\0') rec->botmasks = g_strdup(botarg); if (botarg != NULL && *botarg != '\0') rec->botmasks = g_strdup(botarg);
if (*botcmdarg != '\0') rec->autosendcmd = g_strdup(botcmdarg); if (botcmdarg != NULL && *botcmdarg != '\0') rec->autosendcmd = g_strdup(botcmdarg);
if (*password != '\0' && strcmp(password, "-") != 0) rec->password = g_strdup(password); if (*password != '\0' && strcmp(password, "-") != 0) rec->password = g_strdup(password);
channels_setup_create(rec); channels_setup_create(rec);
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_CHANSETUP_ADDED, channel, ircnet); printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_CHANSETUP_ADDED, channel, ircnet);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_channel_remove(const char *data) static void cmd_channel_remove(const char *data)
{ {
char *params, *ircnet, *channel;
SETUP_CHANNEL_REC *rec; SETUP_CHANNEL_REC *rec;
char *ircnet, *channel;
void *free_arg;
params = cmd_get_params(data, 2, &channel, &ircnet); if (!cmd_get_params(data, &free_arg, 2, &channel, &ircnet))
return;
if (*ircnet == '\0' || *channel == '\0') if (*ircnet == '\0' || *channel == '\0')
cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
@ -238,7 +245,7 @@ static void cmd_channel_remove(const char *data)
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_CHANSETUP_REMOVED, channel, ircnet); printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_CHANSETUP_REMOVED, channel, ircnet);
channels_setup_destroy(rec); channels_setup_destroy(rec);
} }
g_free(params); cmd_params_free(free_arg);
} }
void fe_channels_init(void) void fe_channels_init(void)
@ -257,6 +264,8 @@ void fe_channels_init(void)
command_bind("channel add", NULL, (SIGNAL_FUNC) cmd_channel_add); command_bind("channel add", NULL, (SIGNAL_FUNC) cmd_channel_add);
command_bind("channel remove", NULL, (SIGNAL_FUNC) cmd_channel_remove); command_bind("channel remove", NULL, (SIGNAL_FUNC) cmd_channel_remove);
command_bind("channel list", NULL, (SIGNAL_FUNC) cmd_channel_list); command_bind("channel list", NULL, (SIGNAL_FUNC) cmd_channel_list);
command_set_options("channel add", "auto noauto -bots -botcmd");
} }
void fe_channels_deinit(void) void fe_channels_deinit(void)

View File

@ -137,14 +137,16 @@ static void cmd_ignore_show(void)
static void cmd_ignore(const char *data) static void cmd_ignore(const char *data)
{ {
/* /IGNORE [-regexp | -word] [-pattern <pattern>] [-except] /* /IGNORE [-regexp | -word] [-pattern <pattern>] [-except]
[-channels <channel>] <mask> <levels> [-replies] [-channels <channel>] <mask> <levels>
OR OR
/IGNORE [-regexp | -word] [-pattern <pattern>] [-except] /IGNORE [-regexp | -word] [-pattern <pattern>] [-except] [-replies]
<channels> <levels> */ <channels> <levels> */
char *params, *args, *patternarg, *chanarg, *mask, *levels, *key; GHashTable *optlist;
char **channels;
IGNORE_REC *rec; IGNORE_REC *rec;
char *patternarg, *chanarg, *mask, *levels, *key;
char **channels;
void *free_arg;
int new_ignore; int new_ignore;
if (*data == '\0') { if (*data == '\0') {
@ -152,16 +154,20 @@ static void cmd_ignore(const char *data)
return; return;
} }
args = "pattern channels"; if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | PARAM_FLAG_GETREST,
params = cmd_get_params(data, 5 | PARAM_FLAG_MULTIARGS | PARAM_FLAG_GETREST, "ignore", &optlist, &mask, &levels))
&args, &patternarg, &chanarg, &mask, &levels); return;
patternarg = g_hash_table_lookup(optlist, "pattern");
chanarg = g_hash_table_lookup(optlist, "channels");
if (*levels == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*levels == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
if (ischannel(*mask)) { if (ischannel(*mask)) {
chanarg = mask; chanarg = mask;
mask = ""; mask = "";
} }
channels = *chanarg == '\0' ? NULL : channels = (chanarg == NULL || *chanarg == '\0') ? NULL :
g_strsplit(replace_chars(chanarg, ',', ' '), " ", -1); g_strsplit(replace_chars(chanarg, ',', ' '), " ", -1);
rec = ignore_find(NULL, mask, channels); rec = ignore_find(NULL, mask, channels);
@ -177,16 +183,17 @@ static void cmd_ignore(const char *data)
g_strfreev(channels); g_strfreev(channels);
} }
if (stristr(args, "-except") != NULL) { if (g_hash_table_lookup(optlist, "except") != NULL) {
rec->except_level = combine_level(rec->except_level, levels); rec->except_level = combine_level(rec->except_level, levels);
} else { } else {
ignore_split_levels(levels, &rec->level, &rec->except_level); ignore_split_levels(levels, &rec->level, &rec->except_level);
} }
rec->pattern = *patternarg == '\0' ? NULL : g_strdup(patternarg); rec->pattern = (patternarg == NULL || *patternarg == '\0') ?
rec->regexp = stristr(args, "-regexp") != NULL; NULL : g_strdup(patternarg);
rec->fullword = stristr(args, "-word") != NULL; rec->regexp = g_hash_table_lookup(optlist, "regexp") != NULL;
rec->replies = stristr(args, "-replies") != NULL; rec->fullword = g_hash_table_lookup(optlist, "word") != NULL;
rec->replies = g_hash_table_lookup(optlist, "replies") != NULL;
if (rec->level == 0 && rec->except_level == 0) { if (rec->level == 0 && rec->except_level == 0) {
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_UNIGNORED, printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_UNIGNORED,
@ -204,7 +211,7 @@ static void cmd_ignore(const char *data)
else else
ignore_update_rec(rec); ignore_update_rec(rec);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_unignore(const char *data) static void cmd_unignore(const char *data)
@ -242,6 +249,8 @@ void fe_ignore_init(void)
{ {
command_bind("ignore", NULL, (SIGNAL_FUNC) cmd_ignore); command_bind("ignore", NULL, (SIGNAL_FUNC) cmd_ignore);
command_bind("unignore", NULL, (SIGNAL_FUNC) cmd_unignore); command_bind("unignore", NULL, (SIGNAL_FUNC) cmd_unignore);
command_set_options("ignore", "regexp word except replies -pattern -channels");
} }
void fe_ignore_deinit(void) void fe_ignore_deinit(void)

View File

@ -93,18 +93,20 @@ static void cmd_msg(gchar *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
WINDOW_REC *window; WINDOW_REC *window;
CHANNEL_REC *channel; CHANNEL_REC *channel;
NICK_REC *nickrec; NICK_REC *nickrec;
char *params, *target, *msg, *nickmode, *freestr, *newtarget; char *target, *msg, *nickmode, *freestr, *newtarget;
void *free_arg;
int free_ret; int free_ret;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &msg); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &target, &msg))
return;
if (*target == '\0' || *msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*target == '\0' || *msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
if (*target == '=') if (*target == '=')
{ {
/* dcc msg - handled in fe-dcc.c */ /* dcc msg - handled in fe-dcc.c */
g_free(params); cmd_params_free(free_arg);
return; return;
} }
@ -119,7 +121,7 @@ static void cmd_msg(gchar *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
if (newtarget == NULL) { if (newtarget == NULL) {
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, *target == ',' ? printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, *target == ',' ?
IRCTXT_NO_MSGS_GOT : IRCTXT_NO_MSGS_SENT); IRCTXT_NO_MSGS_GOT : IRCTXT_NO_MSGS_SENT);
g_free(params); cmd_params_free(free_arg);
signal_stop(); signal_stop();
return; return;
} }
@ -160,7 +162,7 @@ static void cmd_msg(gchar *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
} }
g_free_not_null(freestr); g_free_not_null(freestr);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_me(gchar *data, IRC_SERVER_REC *server, WI_IRC_REC *item) static void cmd_me(gchar *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
@ -180,27 +182,31 @@ static void cmd_me(gchar *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_action(const char *data, IRC_SERVER_REC *server) static void cmd_action(const char *data, IRC_SERVER_REC *server)
{ {
char *params, *target, *text; char *target, *text;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED); if (server == NULL || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &target, &text); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, &target, &text))
return;
if (*target == '\0' || *text == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*target == '\0' || *text == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
printformat(server, target, MSGLEVEL_ACTIONS, IRCTXT_OWN_ME, server->nick, text); printformat(server, target, MSGLEVEL_ACTIONS, IRCTXT_OWN_ME, server->nick, text);
irc_send_cmdv(server, "PRIVMSG %s :\001ACTION %s\001", target, text); irc_send_cmdv(server, "PRIVMSG %s :\001ACTION %s\001", target, text);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_notice(gchar *data, IRC_SERVER_REC *server) static void cmd_notice(gchar *data, IRC_SERVER_REC *server)
{ {
char *params, *target, *msg; char *target, *msg;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED); if (server == NULL || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &msg); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &target, &msg))
return;
if (*target == '\0' || *msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*target == '\0' || *msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
if (*target == '@' && ischannel(target[1])) if (*target == '@' && ischannel(target[1]))
@ -209,17 +215,19 @@ static void cmd_notice(gchar *data, IRC_SERVER_REC *server)
printformat(server, target, MSGLEVEL_NOTICES | MSGLEVEL_NOHILIGHT, printformat(server, target, MSGLEVEL_NOTICES | MSGLEVEL_NOHILIGHT,
IRCTXT_OWN_NOTICE, target, msg); IRCTXT_OWN_NOTICE, target, msg);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_ctcp(const char *data, IRC_SERVER_REC *server) static void cmd_ctcp(const char *data, IRC_SERVER_REC *server)
{ {
char *params, *target, *ctcpcmd, *ctcpdata; char *target, *ctcpcmd, *ctcpdata;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED); if (server == NULL || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &target, &ctcpcmd, &ctcpdata); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, &target, &ctcpcmd, &ctcpdata))
return;
if (*target == '\0' || *ctcpcmd == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*target == '\0' || *ctcpcmd == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
if (*target == '@' && ischannel(target[1])) if (*target == '@' && ischannel(target[1]))
@ -228,17 +236,19 @@ static void cmd_ctcp(const char *data, IRC_SERVER_REC *server)
g_strup(ctcpcmd); g_strup(ctcpcmd);
printformat(server, target, MSGLEVEL_CTCPS, IRCTXT_OWN_CTCP, target, ctcpcmd, ctcpdata); printformat(server, target, MSGLEVEL_CTCPS, IRCTXT_OWN_CTCP, target, ctcpcmd, ctcpdata);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_nctcp(const char *data, IRC_SERVER_REC *server) static void cmd_nctcp(const char *data, IRC_SERVER_REC *server)
{ {
gchar *params, *target, *ctcpcmd, *ctcpdata; char *target, *ctcpcmd, *ctcpdata;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED); if (server == NULL || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &target, &ctcpcmd, &ctcpdata); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, &target, &ctcpcmd, &ctcpdata))
return;
if (*target == '\0' || *ctcpcmd == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*target == '\0' || *ctcpcmd == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
if (*target == '@' && ischannel(target[1])) if (*target == '@' && ischannel(target[1]))
@ -247,19 +257,21 @@ static void cmd_nctcp(const char *data, IRC_SERVER_REC *server)
g_strup(ctcpcmd); g_strup(ctcpcmd);
printformat(server, target, MSGLEVEL_NOTICES, IRCTXT_OWN_NOTICE, target, ctcpcmd, ctcpdata); printformat(server, target, MSGLEVEL_NOTICES, IRCTXT_OWN_NOTICE, target, ctcpcmd, ctcpdata);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item) static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
{ {
char *params, *channame, *msg;
CHANNEL_REC *chanrec; CHANNEL_REC *chanrec;
char *channame, *msg;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server)) if (server == NULL || !server->connected || !irc_server_check(server))
cmd_return_error(CMDERR_NOT_CONNECTED); cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 2 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST, item, &channame, &msg); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST, item, &channame, &msg))
return;
if (*msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
chanrec = channel_find(server, channame); chanrec = channel_find(server, channame);
@ -267,7 +279,7 @@ static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
printformat(server, chanrec->name, MSGLEVEL_NOTICES, IRCTXT_OWN_WALL, chanrec->name, msg); printformat(server, chanrec->name, MSGLEVEL_NOTICES, IRCTXT_OWN_WALL, chanrec->name, msg);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_ban(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item) static void cmd_ban(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)

View File

@ -78,17 +78,18 @@ static void print_reconnects(void)
} }
} }
static void server_add(const char *data) static void cmd_server_add(const char *data)
{ {
GHashTable *optlist;
SETUP_SERVER_REC *rec; SETUP_SERVER_REC *rec;
char *params, *args, *ircnet, *host, *cmdspeed, *cmdmax, *portarg; char *addr, *portstr, *password, *value;
char *addr, *portstr, *password; void *free_arg;
int port; int port;
args = "ircnet host cmdspeed cmdmax port"; if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_OPTIONS,
params = cmd_get_params(data, 9 | PARAM_FLAG_MULTIARGS, "server add", &optlist, &addr, &portstr, &password))
&args, &ircnet, &host, &cmdspeed, &cmdmax, return;
&portarg, &addr, &portstr, &password);
if (*addr == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*addr == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
port = *portstr == '\0' ? 6667 : atoi(portstr); port = *portstr == '\0' ? 6667 : atoi(portstr);
@ -98,39 +99,48 @@ static void server_add(const char *data)
rec->address = g_strdup(addr); rec->address = g_strdup(addr);
rec->port = port; rec->port = port;
} else { } else {
if (*portarg != '\0') rec->port = atoi(portarg); value = g_hash_table_lookup(optlist, "port");
if (stristr(args, "-ircnet")) g_free_and_null(rec->ircnet); if (value != NULL && *value != '\0') rec->port = atoi(value);
if (g_hash_table_lookup(optlist, "ircnet")) g_free_and_null(rec->ircnet);
if (*password != '\0') g_free_and_null(rec->password); if (*password != '\0') g_free_and_null(rec->password);
if (stristr(args, "-host")) { if (g_hash_table_lookup(optlist, "host")) {
g_free_and_null(rec->own_host); g_free_and_null(rec->own_host);
rec->own_ip = NULL; rec->own_ip = NULL;
} }
} }
if (stristr(args, "-auto")) rec->autoconnect = TRUE; if (g_hash_table_lookup(optlist, "auto")) rec->autoconnect = TRUE;
if (stristr(args, "-noauto")) rec->autoconnect = FALSE; if (g_hash_table_lookup(optlist, "noauto")) rec->autoconnect = FALSE;
if (*ircnet != '\0') rec->ircnet = g_strdup(ircnet);
if (*password != '\0' && strcmp(password, "-") != 0) rec->password = g_strdup(password); if (*password != '\0' && strcmp(password, "-") != 0) rec->password = g_strdup(password);
if (*host != '\0') { value = g_hash_table_lookup(optlist, "ircnet");
rec->own_host = g_strdup(host); if (value != NULL && *value != '\0') rec->ircnet = g_strdup(value);
value = g_hash_table_lookup(optlist, "host");
if (value != NULL && *value != '\0') {
rec->own_host = g_strdup(value);
rec->own_ip = NULL; rec->own_ip = NULL;
} }
if (*cmdspeed != '\0') rec->cmd_queue_speed = atoi(cmdspeed); value = g_hash_table_lookup(optlist, "cmdspeed");
if (*cmdmax != '\0') rec->max_cmds_at_once = atoi(cmdmax); if (value != NULL && *value != '\0') rec->cmd_queue_speed = atoi(value);
value = g_hash_table_lookup(optlist, "cmdmax");
if (value != NULL && *value != '\0') rec->max_cmds_at_once = atoi(value);
server_setup_add(rec); server_setup_add(rec);
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_SETUPSERVER_ADDED, addr, port); printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_SETUPSERVER_ADDED, addr, port);
g_free(params); cmd_params_free(free_arg);
} }
static void server_remove(const char *data) static void cmd_server_remove(const char *data)
{ {
SETUP_SERVER_REC *rec; SETUP_SERVER_REC *rec;
char *params, *args, *addr, *portstr; char *addr, *portstr;
void *free_arg;
int port; int port;
params = cmd_get_params(data, 3 | PARAM_FLAG_OPTARGS, &args, &addr, &portstr); if (!cmd_get_params(data, &free_arg, 2, &addr, &portstr))
return;
if (*addr == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*addr == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
port = *portstr == '\0' ? 6667 : atoi(portstr); port = *portstr == '\0' ? 6667 : atoi(portstr);
@ -142,10 +152,10 @@ static void server_remove(const char *data)
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_SETUPSERVER_REMOVED, addr, port); printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_SETUPSERVER_REMOVED, addr, port);
} }
g_free(params); cmd_params_free(free_arg);
} }
static void server_list(const char *data) static void cmd_server_list(const char *data)
{ {
GString *str; GString *str;
GSList *tmp; GSList *tmp;
@ -177,9 +187,11 @@ static void server_list(const char *data)
g_string_free(str, TRUE); g_string_free(str, TRUE);
} }
static void cmd_server(const char *data) static void cmd_server(const char *data, IRC_SERVER_REC *server, void *item)
{ {
char *params, *args, *ircnetarg, *hostarg, *addr; GHashTable *optlist;
char *addr;
void *free_arg;
if (*data == '\0') { if (*data == '\0') {
print_servers(); print_servers();
@ -190,36 +202,40 @@ static void cmd_server(const char *data)
return; return;
} }
args = "ircnet host"; /* should be same as in connect_server() in src/irc/core/irc-commands.c */ if (g_strncasecmp(data, "add ", 4) == 0 ||
params = cmd_get_params(data, 4 | PARAM_FLAG_MULTIARGS, g_strncasecmp(data, "remove ", 7) == 0 ||
&args, &ircnetarg, &hostarg, &addr); g_strcasecmp(data, "list") == 0 ||
g_strncasecmp(data, "list ", 5) == 0) {
if (stristr(args, "-list") != NULL) { command_runsub("server", data, server, item);
server_list(data);
signal_stop(); signal_stop();
} else if (stristr(args, "-add") != NULL) { return;
if (*addr == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
server_add(data);
signal_stop();
} else if (stristr(args, "-remove") != NULL) {
if (*addr == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
server_remove(data);
signal_stop();
} else {
if (*addr == '\0' || strcmp(addr, "+") == 0)
cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
if (*addr == '+') window_create(NULL, FALSE);
} }
g_free(params); if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS,
"connect", &optlist, &addr))
return;
if (*addr == '\0' || strcmp(addr, "+") == 0)
cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
if (*addr == '+') window_create(NULL, FALSE);
cmd_params_free(free_arg);
} }
void fe_irc_server_init(void) void fe_irc_server_init(void)
{ {
command_bind("server", NULL, (SIGNAL_FUNC) cmd_server); command_bind("server", NULL, (SIGNAL_FUNC) cmd_server);
command_bind("server add", NULL, (SIGNAL_FUNC) cmd_server_add);
command_bind("server remove", NULL, (SIGNAL_FUNC) cmd_server_remove);
command_bind("server list", NULL, (SIGNAL_FUNC) cmd_server_list);
command_set_options("server add", "auto noauto -ircnet -host -cmdspeed -cmdmax -port");
} }
void fe_irc_server_deinit(void) void fe_irc_server_deinit(void)
{ {
command_unbind("server", (SIGNAL_FUNC) cmd_server); command_unbind("server", (SIGNAL_FUNC) cmd_server);
command_unbind("server add", (SIGNAL_FUNC) cmd_server_add);
command_unbind("server remove", (SIGNAL_FUNC) cmd_server_remove);
command_unbind("server list", (SIGNAL_FUNC) cmd_server_list);
} }

View File

@ -79,15 +79,14 @@ static void cmd_ircnet_list(void)
static void cmd_ircnet_add(const char *data) static void cmd_ircnet_add(const char *data)
{ {
char *params, *args, *kicks, *msgs, *modes, *whois; GHashTable *optlist;
char *cmdspeed, *cmdmax, *nick, *user, *realname, *host, *autosendcmd, *name; char *name, *value;
void *free_arg;
IRCNET_REC *rec; IRCNET_REC *rec;
args = "kicks msgs modes whois cmdspeed cmdmax nick user realname host autosendcmd"; if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS,
params = cmd_get_params(data, 13 | PARAM_FLAG_MULTIARGS, &args, "ircnet add", &optlist, &name))
&kicks, &msgs, &modes, &whois, &cmdspeed, return;
&cmdmax, &nick, &user, &realname, &host,
&autosendcmd, &name);
if (*name == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*name == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
rec = ircnet_find(name); rec = ircnet_find(name);
@ -95,37 +94,50 @@ static void cmd_ircnet_add(const char *data)
rec = g_new0(IRCNET_REC, 1); rec = g_new0(IRCNET_REC, 1);
rec->name = g_strdup(name); rec->name = g_strdup(name);
} else { } else {
if (stristr(args, "-nick")) g_free_and_null(rec->nick); if (g_hash_table_lookup(optlist, "nick")) g_free_and_null(rec->nick);
if (stristr(args, "-user")) g_free_and_null(rec->username); if (g_hash_table_lookup(optlist, "user")) g_free_and_null(rec->username);
if (stristr(args, "-realname")) g_free_and_null(rec->realname); if (g_hash_table_lookup(optlist, "realname")) g_free_and_null(rec->realname);
if (stristr(args, "-host")) { if (g_hash_table_lookup(optlist, "host")) {
g_free_and_null(rec->own_host); g_free_and_null(rec->own_host);
rec->own_ip = NULL; rec->own_ip = NULL;
} }
if (stristr(args, "-autosendcmd")) g_free_and_null(rec->autosendcmd); if (g_hash_table_lookup(optlist, "autosendcmd")) g_free_and_null(rec->autosendcmd);
} }
if (stristr(args, "-kicks")) rec->max_kicks = atoi(kicks); value = g_hash_table_lookup(optlist, "kicks");
if (stristr(args, "-msgs")) rec->max_msgs = atoi(msgs); if (value != NULL) rec->max_kicks = atoi(value);
if (stristr(args, "-modes")) rec->max_modes = atoi(modes); value = g_hash_table_lookup(optlist, "msgs");
if (stristr(args, "-whois")) rec->max_whois = atoi(whois); if (value != NULL) rec->max_msgs = atoi(value);
value = g_hash_table_lookup(optlist, "modes");
if (value != NULL) rec->max_modes = atoi(value);
value = g_hash_table_lookup(optlist, "whois");
if (value != NULL) rec->max_whois = atoi(value);
if (stristr(args, "-cmdspeed")) rec->cmd_queue_speed = atoi(cmdspeed); value = g_hash_table_lookup(optlist, "cmdspeed");
if (stristr(args, "-cmdmax")) rec->max_cmds_at_once = atoi(cmdmax); if (value != NULL) rec->cmd_queue_speed = atoi(value);
value = g_hash_table_lookup(optlist, "cmdmax");
if (value != NULL) rec->max_cmds_at_once = atoi(value);
if (*nick != '\0') rec->nick = g_strdup(nick); value = g_hash_table_lookup(optlist, "nick");
if (*user != '\0') rec->username = g_strdup(user); if (value != NULL && *value != '\0') rec->nick = g_strdup(value);
if (*realname != '\0') rec->realname = g_strdup(realname); value = g_hash_table_lookup(optlist, "user");
if (*host != '\0') { if (value != NULL && *value != '\0') rec->username = g_strdup(value);
rec->own_host = g_strdup(host); value = g_hash_table_lookup(optlist, "realname");
if (value != NULL && *value != '\0') rec->realname = g_strdup(value);
value = g_hash_table_lookup(optlist, "host");
if (value != NULL && *value != '\0') {
rec->own_host = g_strdup(value);
rec->own_ip = NULL; rec->own_ip = NULL;
} }
if (*autosendcmd != '\0') rec->autosendcmd = g_strdup(autosendcmd);
value = g_hash_table_lookup(optlist, "autosendcmd");
if (value != NULL && *value != '\0') rec->autosendcmd = g_strdup(value);
ircnet_create(rec); ircnet_create(rec);
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_IRCNET_ADDED, name); printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_IRCNET_ADDED, name);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_ircnet_remove(const char *data) static void cmd_ircnet_remove(const char *data)
@ -149,6 +161,8 @@ void fe_ircnet_init(void)
command_bind("ircnet ", NULL, (SIGNAL_FUNC) cmd_ircnet_list); command_bind("ircnet ", NULL, (SIGNAL_FUNC) cmd_ircnet_list);
command_bind("ircnet add", NULL, (SIGNAL_FUNC) cmd_ircnet_add); command_bind("ircnet add", NULL, (SIGNAL_FUNC) cmd_ircnet_add);
command_bind("ircnet remove", NULL, (SIGNAL_FUNC) cmd_ircnet_remove); command_bind("ircnet remove", NULL, (SIGNAL_FUNC) cmd_ircnet_remove);
command_set_options("ircnet add", "-kicks -msgs -modes -whois -cmdspeed -cmdmax -nick -user -realname -host -autosendcmd");
} }
void fe_ircnet_deinit(void) void fe_ircnet_deinit(void)

View File

@ -167,17 +167,19 @@ static void event_privmsg(const char *data, IRC_SERVER_REC *server, const char *
static void cmd_msg(const char *data, IRC_SERVER_REC *server) static void cmd_msg(const char *data, IRC_SERVER_REC *server)
{ {
char *params, *target, *msg; char *target, *msg;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &msg); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &target, &msg))
return;
if (*target != '\0' && *msg != '\0') { if (*target != '\0' && *msg != '\0') {
if (!ischannel(*target) && *target != '=' && server != NULL) if (!ischannel(*target) && *target != '=' && server != NULL)
add_private_msg(server, target); add_private_msg(server, target);
} }
g_free(params); cmd_params_free(free_arg);
} }
static void sig_nick_removed(CHANNEL_REC *channel, NICK_REC *nick) static void sig_nick_removed(CHANNEL_REC *channel, NICK_REC *nick)

View File

@ -91,31 +91,43 @@ static gchar *gui_window_line2text(LINE_REC *line)
#define LASTLOG_FLAG_WORD 0x08 #define LASTLOG_FLAG_WORD 0x08
#define LASTLOG_FLAG_REGEXP 0x10 #define LASTLOG_FLAG_REGEXP 0x10
static int lastlog_parse_args(char *args, int *flags) static int lastlog_parse_options(GHashTable *options, int *flags)
{ {
char **arglist, **tmp; GSList *list, *tmp;
int level; int level, optlevel;
/* move all keys from `options' to linked list */
list = hashtable_get_keys(options);
/* level can be specified in arguments.. */ /* level can be specified in arguments.. */
level = 0; *flags = 0; level = 0; *flags = 0;
arglist = g_strsplit(args, " ", -1); for (tmp = list; tmp != NULL; tmp = tmp->next) {
for (tmp = arglist; *tmp != NULL; tmp++) { char *opt = tmp->data;
if (strcmp(*tmp, "-") == 0)
if (strcmp(opt, "-") == 0)
*flags |= LASTLOG_FLAG_NOHEADERS; *flags |= LASTLOG_FLAG_NOHEADERS;
else if (g_strcasecmp(*tmp, "-new") == 0) else if (g_strcasecmp(opt, "new") == 0)
*flags |= LASTLOG_FLAG_NEW_LAST; *flags |= LASTLOG_FLAG_NEW_LAST;
else if (g_strcasecmp(*tmp, "-away") == 0) else if (g_strcasecmp(opt, "away") == 0)
*flags |= LASTLOG_FLAG_NEW_AWAY; *flags |= LASTLOG_FLAG_NEW_AWAY;
else if (g_strcasecmp(*tmp, "-word") == 0) else if (g_strcasecmp(opt, "word") == 0)
*flags |= LASTLOG_FLAG_WORD; *flags |= LASTLOG_FLAG_WORD;
else if (g_strcasecmp(*tmp, "-regexp") == 0) else if (g_strcasecmp(opt, "regexp") == 0)
*flags |= LASTLOG_FLAG_REGEXP; *flags |= LASTLOG_FLAG_REGEXP;
else else {
level |= level2bits(tmp[0]+1); optlevel = level2bits(opt);
if (optlevel != 0)
level |= optlevel;
else {
signal_emit("error command", 2, GINT_TO_POINTER(CMDERR_OPTION_UNKNOWN), opt);
level = -1;
break;
}
}
} }
if (level == 0) level = MSGLEVEL_ALL; if (level == 0) level = MSGLEVEL_ALL;
g_strfreev(arglist);
g_slist_free(list);
return level; return level;
} }
@ -148,14 +160,19 @@ static GList *lastlog_find_startline(GList *list, int count, int start, int leve
static void cmd_lastlog(const char *data) static void cmd_lastlog(const char *data)
{ {
GHashTable *optlist;
GList *startline, *list, *tmp; GList *startline, *list, *tmp;
char *params, *str, *args, *text, *countstr, *start; char *str, *text, *countstr, *start;
void *free_arg;
struct tm *tm; struct tm *tm;
int level, flags, count; int level, flags, count;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
params = cmd_get_params(data, 4 | PARAM_FLAG_OPTARGS, &args, &text, &countstr, &start); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_OPTIONS | PARAM_FLAG_UNKNOWN_OPTIONS,
"lastlog", &optlist, &text, &countstr, &start))
return;
if (*start == '\0' && is_numeric(text, 0)) { if (*start == '\0' && is_numeric(text, 0)) {
if (is_numeric(countstr, 0)) if (is_numeric(countstr, 0))
start = countstr; start = countstr;
@ -165,7 +182,12 @@ static void cmd_lastlog(const char *data)
count = atoi(countstr); count = atoi(countstr);
if (count == 0) count = -1; if (count == 0) count = -1;
level = lastlog_parse_args(args, &flags); level = lastlog_parse_options(optlist, &flags);
if (level == -1) {
/* error in options */
cmd_params_free(free_arg);
return;
}
if ((flags & LASTLOG_FLAG_NOHEADERS) == 0) if ((flags & LASTLOG_FLAG_NOHEADERS) == 0)
printformat(NULL, NULL, MSGLEVEL_LASTLOG, IRCTXT_LASTLOG_START); printformat(NULL, NULL, MSGLEVEL_LASTLOG, IRCTXT_LASTLOG_START);
@ -207,7 +229,7 @@ static void cmd_lastlog(const char *data)
g_list_last(WINDOW_GUI(active_win)->bottom_startline); g_list_last(WINDOW_GUI(active_win)->bottom_startline);
g_list_free(list); g_list_free(list);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_scrollback(gchar *data, SERVER_REC *server, WI_ITEM_REC *item) static void cmd_scrollback(gchar *data, SERVER_REC *server, WI_ITEM_REC *item)
@ -254,10 +276,12 @@ static void scrollback_goto_pos(WINDOW_REC *window, GList *pos)
static void cmd_scrollback_goto(gchar *data) static void cmd_scrollback_goto(gchar *data)
{ {
GList *pos; GList *pos;
gchar *params, *arg1, *arg2; gchar *arg1, *arg2;
void *free_arg;
gint lines; gint lines;
params = cmd_get_params(data, 2, &arg1, &arg2); if (!cmd_get_params(data, &free_arg, 2, &arg1, &arg2))
return;
if (*arg2 == '\0' && (*arg1 == '-' || *arg1 == '+')) if (*arg2 == '\0' && (*arg1 == '-' || *arg1 == '+'))
{ {
/* go forward/backward n lines */ /* go forward/backward n lines */
@ -322,7 +346,7 @@ static void cmd_scrollback_goto(gchar *data)
if (stamp > time(NULL)) { if (stamp > time(NULL)) {
/* we're still looking into future, don't bother checking */ /* we're still looking into future, don't bother checking */
g_free(params); cmd_params_free(free_arg);
return; return;
} }
@ -338,7 +362,7 @@ static void cmd_scrollback_goto(gchar *data)
} }
} }
} }
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_scrollback_home(gchar *data) static void cmd_scrollback_home(gchar *data)
@ -398,6 +422,7 @@ void gui_textwidget_init(void)
command_bind("scrollback goto", NULL, (SIGNAL_FUNC) cmd_scrollback_goto); command_bind("scrollback goto", NULL, (SIGNAL_FUNC) cmd_scrollback_goto);
command_bind("scrollback home", NULL, (SIGNAL_FUNC) cmd_scrollback_home); command_bind("scrollback home", NULL, (SIGNAL_FUNC) cmd_scrollback_home);
command_bind("scrollback end", NULL, (SIGNAL_FUNC) cmd_scrollback_end); command_bind("scrollback end", NULL, (SIGNAL_FUNC) cmd_scrollback_end);
command_set_options("lastlog", "new away word regexp");
signal_add("away mode changed", (SIGNAL_FUNC) sig_away_changed); signal_add("away mode changed", (SIGNAL_FUNC) sig_away_changed);
} }

View File

@ -480,14 +480,16 @@ static BOT_REC *bot_add(BOTNET_REC *botnet, const char *nick, const char *parent
static void botnet_event_botinfo(BOT_REC *bot, const char *data, const char *sender) static void botnet_event_botinfo(BOT_REC *bot, const char *data, const char *sender)
{ {
char *params, *nick, *parent, *priority; char *nick, *parent, *priority;
void *free_arg;
BOT_REC *rec; BOT_REC *rec;
/*str = g_strdup_printf("BOTINFO %s", data); /*str = g_strdup_printf("BOTINFO %s", data);
botnet_broadcast(bot->botnet, bot, sender, str); botnet_broadcast(bot->botnet, bot, sender, str);
g_free(str);*/ g_free(str);*/
params = cmd_get_params(data, 3, &nick, &parent, &priority); if (!cmd_get_params(data, &free_arg, 3, &nick, &parent, &priority))
return;
if (*parent == '-' && parent[1] == '\0') if (*parent == '-' && parent[1] == '\0')
parent = NULL; parent = NULL;
@ -503,7 +505,7 @@ static void botnet_event_botinfo(BOT_REC *bot, const char *data, const char *sen
if (rec != NULL) { if (rec != NULL) {
rec->priority = atoi(priority); rec->priority = atoi(priority);
} }
g_free(params); cmd_params_free(free_arg);
} }
static void botnet_event_botquit(BOT_REC *bot, const char *data) static void botnet_event_botquit(BOT_REC *bot, const char *data)

View File

@ -108,81 +108,94 @@ void botcmd_user_set_password(USER_REC *user, const char *password)
static void botnet_event_user_add(BOT_REC *bot, const char *data, const char *sender) static void botnet_event_user_add(BOT_REC *bot, const char *data, const char *sender)
{ {
char *params, *nick; char *nick;
void *free_arg;
if (!cmd_get_params(data, &free_arg, 1, &nick))
return;
params = cmd_get_params(data, 1, &nick);
botuser_add(nick); botuser_add(nick);
g_free(params); cmd_params_free(free_arg);
} }
static void botnet_event_user_flags(BOT_REC *bot, const char *data, const char *sender) static void botnet_event_user_flags(BOT_REC *bot, const char *data, const char *sender)
{ {
USER_REC *user; USER_REC *user;
char *params, *nick, *flags; char *nick, *flags;
void *free_arg;
params = cmd_get_params(data, 2, &nick, &flags); if (!cmd_get_params(data, &free_arg, 2, &nick, &flags))
return;
user = botuser_find(nick, NULL); user = botuser_find(nick, NULL);
if (user == NULL) user = botuser_add(nick); if (user == NULL) user = botuser_add(nick);
botuser_set_flags(user, botuser_flags2value(flags)); botuser_set_flags(user, botuser_flags2value(flags));
g_free(params); cmd_params_free(free_arg);
} }
static void botnet_event_user_chan_flags(BOT_REC *bot, const char *data, const char *sender) static void botnet_event_user_chan_flags(BOT_REC *bot, const char *data, const char *sender)
{ {
USER_REC *user; USER_REC *user;
char *params, *nick, *channel, *flags; char *nick, *channel, *flags;
void *free_arg;
params = cmd_get_params(data, 3, &nick, &channel, &flags); if (!cmd_get_params(data, &free_arg, 3, &nick, &channel, &flags))
return;
user = botuser_find(nick, NULL); user = botuser_find(nick, NULL);
if (user == NULL) user = botuser_add(nick); if (user == NULL) user = botuser_add(nick);
botuser_set_channel_flags(user, channel, botuser_flags2value(flags)); botuser_set_channel_flags(user, channel, botuser_flags2value(flags));
g_free(params); cmd_params_free(free_arg);
} }
static void botnet_event_user_add_mask(BOT_REC *bot, const char *data, const char *sender) static void botnet_event_user_add_mask(BOT_REC *bot, const char *data, const char *sender)
{ {
USER_REC *user; USER_REC *user;
char *params, *nick, *mask; char *nick, *mask;
void *free_arg;
params = cmd_get_params(data, 2, &nick, &mask); if (!cmd_get_params(data, &free_arg, 2, &nick, &mask))
return;
user = botuser_find(nick, NULL); user = botuser_find(nick, NULL);
if (user == NULL) user = botuser_add(nick); if (user == NULL) user = botuser_add(nick);
botuser_add_mask(user, mask); botuser_add_mask(user, mask);
g_free(params); cmd_params_free(free_arg);
} }
static void botnet_event_user_mask_notflags(BOT_REC *bot, const char *data, const char *sender) static void botnet_event_user_mask_notflags(BOT_REC *bot, const char *data, const char *sender)
{ {
USER_REC *user; USER_REC *user;
char *params, *nick, *mask, *not_flags; char *nick, *mask, *not_flags;
void *free_arg;
params = cmd_get_params(data, 3, &nick, &mask, &not_flags); if (!cmd_get_params(data, &free_arg, 3, &nick, &mask, &not_flags))
return;
user = botuser_find(nick, NULL); user = botuser_find(nick, NULL);
if (user == NULL) user = botuser_add(nick); if (user == NULL) user = botuser_add(nick);
botuser_set_mask_notflags(user, mask, botuser_flags2value(not_flags)); botuser_set_mask_notflags(user, mask, botuser_flags2value(not_flags));
g_free(params); cmd_params_free(free_arg);
} }
static void botnet_event_user_pass(BOT_REC *bot, const char *data, const char *sender) static void botnet_event_user_pass(BOT_REC *bot, const char *data, const char *sender)
{ {
USER_REC *user; USER_REC *user;
char *params, *nick, *pass; char *nick, *pass;
void *free_arg;
params = cmd_get_params(data, 2, &nick, &pass); if (!cmd_get_params(data, &free_arg, 2, &nick, &pass))
return;
user = botuser_find(nick, NULL); user = botuser_find(nick, NULL);
if (user == NULL) user = botuser_add(nick); if (user == NULL) user = botuser_add(nick);
botuser_set_password(user, pass); botuser_set_password(user, pass);
g_free(params); cmd_params_free(free_arg);
} }
void botnet_users_init(void) void botnet_users_init(void)

View File

@ -508,13 +508,15 @@ static void botnet_destroy(BOTNET_REC *botnet)
static void botnet_event(BOT_REC *bot, const char *data) static void botnet_event(BOT_REC *bot, const char *data)
{ {
char *params, *source, *target, *command, *args, *event; char *source, *target, *command, *args, *event;
void *free_arg;
if (!bot->connected) if (!bot->connected)
return; return;
params = cmd_get_params(data, 4 | PARAM_FLAG_GETREST, if (!cmd_get_params(data, &free_arg, 4 | PARAM_FLAG_GETREST,
&source, &target, &command, &args); &source, &target, &command, &args))
return;
if (*target == '-' && target[1] == '\0') if (*target == '-' && target[1] == '\0')
target = NULL; target = NULL;
@ -524,23 +526,25 @@ static void botnet_event(BOT_REC *bot, const char *data)
signal_emit(event, 4, bot, args, source, target); signal_emit(event, 4, bot, args, source, target);
g_free(event); g_free(event);
g_free(params); cmd_params_free(free_arg);
} }
/* broadcast the signal forward */ /* broadcast the signal forward */
static void botnet_event_broadcast(BOT_REC *bot, const char *data) static void botnet_event_broadcast(BOT_REC *bot, const char *data)
{ {
char *params, *source, *target, *command; char *source, *target, *command;
void *free_arg;
if (!bot->connected) if (!bot->connected)
return; return;
params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST,
&source, &target, &command); &source, &target, &command))
return;
if (g_strcasecmp(target, bot->botnet->nick) == 0) { if (g_strcasecmp(target, bot->botnet->nick) == 0) {
/* message was for us */ /* message was for us */
g_free(params); cmd_params_free(free_arg);
return; return;
} }
@ -552,7 +556,7 @@ static void botnet_event_broadcast(BOT_REC *bot, const char *data)
botnet_send_cmd(bot->botnet, source, target, command); botnet_send_cmd(bot->botnet, source, target, command);
} }
g_free(params); cmd_params_free(free_arg);
} }
static void botnet_event_master(BOT_REC *bot, const char *data, const char *sender) static void botnet_event_master(BOT_REC *bot, const char *data, const char *sender)

View File

@ -167,14 +167,15 @@ void ban_remove(CHANNEL_REC *channel, const char *bans)
static void command_set_ban(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item, int set) static void command_set_ban(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item, int set)
{ {
CHANNEL_REC *chanrec; CHANNEL_REC *chanrec;
char *params, *channel, *nicks; char *channel, *nicks;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server)) if (server == NULL || !server->connected || !irc_server_check(server))
cmd_return_error(CMDERR_NOT_CONNECTED); cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 2 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST, if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST,
item, &channel, &nicks); item, &channel, &nicks)) return;
if (!ischannel(*channel)) cmd_param_error(CMDERR_NOT_JOINED); if (!ischannel(*channel)) cmd_param_error(CMDERR_NOT_JOINED);
if (*nicks == '\0') { if (*nicks == '\0') {
if (strcmp(data, "*") != 0) if (strcmp(data, "*") != 0)
@ -192,7 +193,7 @@ static void command_set_ban(const char *data, IRC_SERVER_REC *server, WI_IRC_REC
else else
ban_remove(chanrec, nicks); ban_remove(chanrec, nicks);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_bantype(const char *data) static void cmd_bantype(const char *data)

View File

@ -181,8 +181,8 @@ static void channel_send_query(IRC_SERVER_REC *server, int query)
chans = rec->queries[query]; chans = rec->queries[query];
chanstr_commas = gslist_to_string(rec->queries[query], G_STRUCT_OFFSET(CHANNEL_REC, name), ","); chanstr_commas = gslistptr_to_string(rec->queries[query], G_STRUCT_OFFSET(CHANNEL_REC, name), ",");
chanstr_spaces = gslist_to_string(rec->queries[query], G_STRUCT_OFFSET(CHANNEL_REC, name), " "); chanstr_spaces = gslistptr_to_string(rec->queries[query], G_STRUCT_OFFSET(CHANNEL_REC, name), " ");
chanstr = g_strconcat(chanstr_commas, " ", chanstr_spaces, NULL); chanstr = g_strconcat(chanstr_commas, " ", chanstr_spaces, NULL);
g_free(chanstr_spaces); g_free(chanstr_spaces);

View File

@ -162,15 +162,17 @@ void channels_join(IRC_SERVER_REC *server, const char *data, int automatic)
SETUP_CHANNEL_REC *schannel; SETUP_CHANNEL_REC *schannel;
CHANNEL_REC *chanrec; CHANNEL_REC *chanrec;
GString *outchans, *outkeys; GString *outchans, *outkeys;
char *params, *channels, *keys, *key; char *channels, *keys, *key;
char **chanlist, **keylist, **tmp, **tmpkey, *channel; char **chanlist, **keylist, **tmp, **tmpkey, *channel;
void *free_arg;
int use_keys; int use_keys;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server)) if (server == NULL || !server->connected || !irc_server_check(server))
cmd_return_error(CMDERR_NOT_CONNECTED); cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &channels, &keys); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &channels, &keys))
return;
if (*channels == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*channels == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
chanlist = g_strsplit(channels, ",", -1); chanlist = g_strsplit(channels, ",", -1);
@ -221,7 +223,7 @@ void channels_join(IRC_SERVER_REC *server, const char *data, int automatic)
g_strfreev(chanlist); g_strfreev(chanlist);
g_strfreev(keylist); g_strfreev(keylist);
g_free(params); cmd_params_free(free_arg);
} }
void channels_init(void) void channels_init(void)

View File

@ -49,27 +49,34 @@ static IRC_SERVER_REC *connect_server(const char *data)
{ {
IRC_SERVER_CONNECT_REC *conn; IRC_SERVER_CONNECT_REC *conn;
IRC_SERVER_REC *server; IRC_SERVER_REC *server;
char *params, *args, *ircnet, *host, *addr, *portstr, *password, *nick; GHashTable *optlist;
char *addr, *portstr, *password, *nick, *ircnet, *host;
void *free_arg;
g_return_val_if_fail(data != NULL, NULL); g_return_val_if_fail(data != NULL, NULL);
args = "ircnet host"; if (!cmd_get_params(data, &free_arg, 4 | PARAM_FLAG_OPTIONS,
params = cmd_get_params(data, 7 | PARAM_FLAG_MULTIARGS, "connect", &optlist, &addr, &portstr, &password, &nick))
&args, &ircnet, &host, &addr, return NULL;
&portstr, &password, &nick);
if (*addr == '+') addr++; if (*addr == '+') addr++;
if (*addr == '\0') return NULL; if (*addr == '\0') {
signal_emit("error command", 1, GINT_TO_POINTER(CMDERR_NOT_ENOUGH_PARAMS));
cmd_params_free(free_arg);
return NULL;
}
if (strcmp(password, "-") == 0) if (strcmp(password, "-") == 0)
*password = '\0'; *password = '\0';
/* connect to server */ /* connect to server */
conn = irc_server_create_conn(addr, atoi(portstr), password, nick); conn = irc_server_create_conn(addr, atoi(portstr), password, nick);
if (*ircnet != '\0') { ircnet = g_hash_table_lookup(optlist, "ircnet");
if (ircnet != NULL && *ircnet != '\0') {
g_free_not_null(conn->ircnet); g_free_not_null(conn->ircnet);
conn->ircnet = g_strdup(ircnet); conn->ircnet = g_strdup(ircnet);
} }
if (*host != '\0') { host = g_hash_table_lookup(optlist, "host");
if (host != NULL && *host != '\0') {
IPADDR ip; IPADDR ip;
if (net_gethostbyname(host, &ip) == 0) { if (net_gethostbyname(host, &ip) == 0) {
@ -80,7 +87,7 @@ static IRC_SERVER_REC *connect_server(const char *data)
} }
server = irc_server_connect(conn); server = irc_server_connect(conn);
g_free(params); cmd_params_free(free_arg);
return server; return server;
} }
@ -93,14 +100,16 @@ static void cmd_connect(const char *data)
static void cmd_disconnect(const char *data, IRC_SERVER_REC *server) static void cmd_disconnect(const char *data, IRC_SERVER_REC *server)
{ {
IRC_SERVER_REC *ircserver; IRC_SERVER_REC *ircserver;
char *params, *tag, *msg; char *tag, *msg;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (g_strncasecmp(data, "RECON-", 6) == 0) if (g_strncasecmp(data, "RECON-", 6) == 0)
return; /* remove reconnection, handle in server-reconnect.c */ return; /* remove reconnection, handle in server-reconnect.c */
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &tag, &msg); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &tag, &msg))
return;
if (*tag != '\0' && strcmp(tag, "*") != 0) if (*tag != '\0' && strcmp(tag, "*") != 0)
server = (IRC_SERVER_REC *) server_find_tag(tag); server = (IRC_SERVER_REC *) server_find_tag(tag);
@ -120,22 +129,24 @@ static void cmd_disconnect(const char *data, IRC_SERVER_REC *server)
irc_send_cmdv(ircserver, "QUIT :%s", msg); irc_send_cmdv(ircserver, "QUIT :%s", msg);
} }
g_free(params); cmd_params_free(free_arg);
server_disconnect((SERVER_REC *) server); server_disconnect((SERVER_REC *) server);
} }
static void cmd_server(const char *data, IRC_SERVER_REC *server) static void cmd_server(const char *data, IRC_SERVER_REC *server)
{ {
char *params, *args, *ircnetarg, *hostarg, *addr; GHashTable *optlist;
char *channels, *away_reason, *usermode, *ircnet; char *addr, *channels, *away_reason, *usermode, *ircnet;
void *free_arg;
int no_old_server; int no_old_server;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
args = "ircnet host"; if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS,
params = cmd_get_params(data, 4 | PARAM_FLAG_MULTIARGS, "connect", &optlist, &addr))
&args, &ircnetarg, &hostarg, &addr); return;
if (*addr == '\0' || strcmp(addr, "+") == 0) if (*addr == '\0' || strcmp(addr, "+") == 0)
cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
@ -167,7 +178,7 @@ static void cmd_server(const char *data, IRC_SERVER_REC *server)
server->connrec->away_reason = away_reason; server->connrec->away_reason = away_reason;
} }
g_free_not_null(ircnet); g_free_not_null(ircnet);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_quit(const char *data) static void cmd_quit(const char *data)
@ -195,12 +206,14 @@ static void cmd_quit(const char *data)
static void cmd_msg(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item) static void cmd_msg(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
{ {
char *params, *target, *msg; char *target, *msg;
void *free_arg;
int free_ret; int free_ret;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &msg); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &target, &msg))
return;
if (*target == '\0' || *msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*target == '\0' || *msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
if (server == NULL || !server->connected || !irc_server_check(server)) if (server == NULL || !server->connected || !irc_server_check(server))
@ -219,35 +232,39 @@ static void cmd_msg(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
if (free_ret && target != NULL) g_free(target); if (free_ret && target != NULL) g_free(target);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_notice(const char *data, IRC_SERVER_REC *server) static void cmd_notice(const char *data, IRC_SERVER_REC *server)
{ {
char *params, *target, *msg; char *target, *msg;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server)) if (server == NULL || !server->connected || !irc_server_check(server))
cmd_return_error(CMDERR_NOT_CONNECTED); cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &msg); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &target, &msg))
return;
if (*target == '\0' || *msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*target == '\0' || *msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
g_string_sprintf(tmpstr, "NOTICE %s :%s", target, msg); g_string_sprintf(tmpstr, "NOTICE %s :%s", target, msg);
irc_send_cmd_split(server, tmpstr->str, 2, server->max_msgs_in_cmd); irc_send_cmd_split(server, tmpstr->str, 2, server->max_msgs_in_cmd);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_ctcp(const char *data, IRC_SERVER_REC *server) static void cmd_ctcp(const char *data, IRC_SERVER_REC *server)
{ {
char *params, *target, *ctcpcmd, *ctcpdata; char *target, *ctcpcmd, *ctcpdata;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server)) if (server == NULL || !server->connected || !irc_server_check(server))
cmd_return_error(CMDERR_NOT_CONNECTED); cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &target, &ctcpcmd, &ctcpdata); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, &target, &ctcpcmd, &ctcpdata))
return;
if (*target == '\0' || *ctcpcmd == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*target == '\0' || *ctcpcmd == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
g_strup(ctcpcmd); g_strup(ctcpcmd);
@ -257,61 +274,79 @@ static void cmd_ctcp(const char *data, IRC_SERVER_REC *server)
g_string_sprintf(tmpstr, "PRIVMSG %s :\001%s %s\001", target, ctcpcmd, ctcpdata); g_string_sprintf(tmpstr, "PRIVMSG %s :\001%s %s\001", target, ctcpcmd, ctcpdata);
irc_send_cmd_split(server, tmpstr->str, 2, server->max_msgs_in_cmd); irc_send_cmd_split(server, tmpstr->str, 2, server->max_msgs_in_cmd);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_nctcp(const char *data, IRC_SERVER_REC *server) static void cmd_nctcp(const char *data, IRC_SERVER_REC *server)
{ {
char *params, *target, *ctcpcmd, *ctcpdata; char *target, *ctcpcmd, *ctcpdata;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server)) if (server == NULL || !server->connected || !irc_server_check(server))
cmd_return_error(CMDERR_NOT_CONNECTED); cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &target, &ctcpcmd, &ctcpdata); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, &target, &ctcpcmd, &ctcpdata))
return;
if (*target == '\0' || *ctcpcmd == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*target == '\0' || *ctcpcmd == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
g_strup(ctcpcmd); g_strup(ctcpcmd);
g_string_sprintf(tmpstr, "NOTICE %s :\001%s %s\001", target, ctcpcmd, ctcpdata); g_string_sprintf(tmpstr, "NOTICE %s :\001%s %s\001", target, ctcpcmd, ctcpdata);
irc_send_cmd_split(server, tmpstr->str, 2, server->max_msgs_in_cmd); irc_send_cmd_split(server, tmpstr->str, 2, server->max_msgs_in_cmd);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_join(const char *data, IRC_SERVER_REC *server) static void cmd_join(const char *data, IRC_SERVER_REC *server)
{ {
char *params, *args, *channels; GHashTable *optlist;
GSList *list;
char *channels;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server)) if (server == NULL || !server->connected || !irc_server_check(server))
cmd_return_error(CMDERR_NOT_CONNECTED); cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 2 | PARAM_FLAG_OPTARGS | PARAM_FLAG_GETREST, &args, &channels); if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | PARAM_FLAG_UNKNOWN_OPTIONS |
PARAM_FLAG_GETREST, "join", &optlist, &channels))
return;
if (stristr(args, "-invite")) { if (g_hash_table_lookup(optlist, "-invite")) {
if (server->last_invite != NULL) if (server->last_invite != NULL)
channels_join(server, server->last_invite, FALSE); channels_join(server, server->last_invite, FALSE);
} else { } else {
if (*args != '\0') { /* -<server tag> */
server = (IRC_SERVER_REC *) server_find_tag(args+1); list = hashtable_get_keys(optlist);
if (server == NULL) cmd_param_error(CMDERR_NOT_CONNECTED); if (list != NULL) {
server = (IRC_SERVER_REC *) server_find_tag(list->data);
if (server == NULL) {
/* unknown option (not server tag) */
signal_emit("error command", 2, GINT_TO_POINTER(CMDERR_OPTION_UNKNOWN), list->data);
signal_stop();
}
g_slist_free(list);
} }
channels_join(server, channels, FALSE);
if (server != NULL) channels_join(server, channels, FALSE);
} }
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_part(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item) static void cmd_part(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
{ {
char *params, *channame, *msg;
CHANNEL_REC *chanrec; CHANNEL_REC *chanrec;
char *channame, *msg;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server)) if (server == NULL || !server->connected || !irc_server_check(server))
cmd_return_error(CMDERR_NOT_CONNECTED); cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 2 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST, item, &channame, &msg); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST, item, &channame, &msg))
return;
if (*channame == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*channame == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
chanrec = channel_find(server, channame); chanrec = channel_find(server, channame);
@ -320,19 +355,21 @@ static void cmd_part(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
irc_send_cmdv(server, *msg == '\0' ? "PART %s" : "PART %s :%s", irc_send_cmdv(server, *msg == '\0' ? "PART %s" : "PART %s :%s",
channame, msg); channame, msg);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_kick(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item) static void cmd_kick(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
{ {
char *params, *channame, *nicks, *reason; char *channame, *nicks, *reason;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server)) if (server == NULL || !server->connected || !irc_server_check(server))
cmd_return_error(CMDERR_NOT_CONNECTED); cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 3 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST, if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST,
item, &channame, &nicks, &reason); item, &channame, &nicks, &reason))
return;
if (*channame == '\0' || *nicks == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*channame == '\0' || *nicks == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
if (!ischannel(*channame)) cmd_param_error(CMDERR_NOT_JOINED); if (!ischannel(*channame)) cmd_param_error(CMDERR_NOT_JOINED);
@ -340,36 +377,42 @@ static void cmd_kick(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
g_string_sprintf(tmpstr, "KICK %s %s :%s", channame, nicks, reason); g_string_sprintf(tmpstr, "KICK %s %s :%s", channame, nicks, reason);
irc_send_cmd_split(server, tmpstr->str, 3, server->max_kicks_in_cmd); irc_send_cmd_split(server, tmpstr->str, 3, server->max_kicks_in_cmd);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_topic(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item) static void cmd_topic(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
{ {
char *params, *args, *channame, *topic; GHashTable *optlist;
char *channame, *topic;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server)) if (server == NULL || !server->connected || !irc_server_check(server))
cmd_return_error(CMDERR_NOT_CONNECTED); cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 3 | PARAM_FLAG_OPTCHAN | if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_OPTCHAN |
PARAM_FLAG_OPTARGS | PARAM_FLAG_GETREST, PARAM_FLAG_OPTIONS | PARAM_FLAG_GETREST,
item, &args, &channame, &topic); item, "topic", &optlist, &channame, &topic))
return;
irc_send_cmdv(server, *topic == '\0' && strstr(args, "-d") == NULL ? irc_send_cmdv(server, *topic == '\0' && g_hash_table_lookup(optlist, "-d") == NULL ?
"TOPIC %s" : "TOPIC %s :%s", channame, topic); "TOPIC %s" : "TOPIC %s :%s", channame, topic);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_invite(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item) static void cmd_invite(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
{ {
char *params, *nick, *channame; char *nick, *channame;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server)) if (server == NULL || !server->connected || !irc_server_check(server))
cmd_return_error(CMDERR_NOT_CONNECTED); cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 2, &nick, &channame); if (!cmd_get_params(data, &free_arg, 2, &nick, &channame))
return;
if (*nick == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*nick == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
if (*channame == '\0' || strcmp(channame, "*") == 0) { if (*channame == '\0' || strcmp(channame, "*") == 0) {
if (!irc_item_channel(item)) if (!irc_item_channel(item))
@ -379,24 +422,28 @@ static void cmd_invite(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *ite
} }
irc_send_cmdv(server, "INVITE %s %s", nick, channame); irc_send_cmdv(server, "INVITE %s %s", nick, channame);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_list(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item) static void cmd_list(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
{ {
char *params, *args, *str; GHashTable *optlist;
char *str;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server)) if (server == NULL || !server->connected || !irc_server_check(server))
cmd_return_error(CMDERR_NOT_CONNECTED); cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 2 | PARAM_FLAG_OPTARGS | PARAM_FLAG_GETREST, &args, &str); if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS |
PARAM_FLAG_GETREST, &optlist, &str))
return;
if (*str == '\0' && stristr(args, "-yes") == NULL) if (*str == '\0' && g_hash_table_lookup(optlist, "-yes") == NULL)
cmd_param_error(CMDERR_NOT_GOOD_IDEA); cmd_param_error(CMDERR_NOT_GOOD_IDEA);
irc_send_cmdv(server, "LIST %s", str); irc_send_cmdv(server, "LIST %s", str);
g_free(params); cmd_params_free(free_arg);
/* add default redirection */ /* add default redirection */
server_redirect_default((SERVER_REC *) server, "bogus command list"); server_redirect_default((SERVER_REC *) server, "bogus command list");
@ -404,13 +451,15 @@ static void cmd_list(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_who(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item) static void cmd_who(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
{ {
char *params, *channel, *args, *rest; char *channel, *rest;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server)) if (server == NULL || !server->connected || !irc_server_check(server))
cmd_return_error(CMDERR_NOT_CONNECTED); cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 3 | PARAM_FLAG_OPTARGS | PARAM_FLAG_GETREST, &args, &channel, &rest); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, &channel, &rest))
return;
if (strcmp(channel, "*") == 0 || *channel == '\0') { if (strcmp(channel, "*") == 0 || *channel == '\0') {
if (!irc_item_channel(item)) if (!irc_item_channel(item))
@ -425,7 +474,7 @@ static void cmd_who(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
irc_send_cmdv(server, *rest == '\0' ? "WHO %s" : "WHO %s %s", irc_send_cmdv(server, *rest == '\0' ? "WHO %s" : "WHO %s %s",
channel, rest); channel, rest);
g_free(params); cmd_params_free(free_arg);
/* add default redirection */ /* add default redirection */
server_redirect_default((SERVER_REC *) server, "bogus command who"); server_redirect_default((SERVER_REC *) server, "bogus command who");
@ -473,17 +522,20 @@ static char *get_redirect_nicklist(const char *nicks, int *free)
static void cmd_whois(const char *data, IRC_SERVER_REC *server) static void cmd_whois(const char *data, IRC_SERVER_REC *server)
{ {
char *params, *qserver, *query; char *qserver, *query;
void *free_arg;
int free_nick; int free_nick;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server)) if (server == NULL || !server->connected || !irc_server_check(server))
cmd_return_error(CMDERR_NOT_CONNECTED); cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 2, &qserver, &query); if (!cmd_get_params(data, &free_arg, 2, &qserver, &query))
return;
if (*query == '\0') { if (*query == '\0') {
g_free(params); cmd_params_free(free_arg);
params = cmd_get_params(data, 1, &query); if (!cmd_get_params(data, &free_arg, 1, &query)) return;
qserver = ""; qserver = "";
} }
if (*query == '\0') query = server->nick; if (*query == '\0') query = server->nick;
@ -505,7 +557,7 @@ static void cmd_whois(const char *data, IRC_SERVER_REC *server)
"event 311", "whois event", 1, "event 311", "whois event", 1,
"event 401", "whois not found", 1, NULL); "event 401", "whois not found", 1, NULL);
if (free_nick) g_free(query); if (free_nick) g_free(query);
g_free(params); cmd_params_free(free_arg);
} }
static void event_whois(const char *data, IRC_SERVER_REC *server, const char *nick, const char *addr) static void event_whois(const char *data, IRC_SERVER_REC *server, const char *nick, const char *addr)
@ -539,14 +591,16 @@ static void event_whowas(const char *data, IRC_SERVER_REC *server, const char *n
static void cmd_whowas(const char *data, IRC_SERVER_REC *server) static void cmd_whowas(const char *data, IRC_SERVER_REC *server)
{ {
char *params, *nicks, *count; char *nicks, *count;
void *free_arg;
int free_nick; int free_nick;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server)) if (server == NULL || !server->connected || !irc_server_check(server))
cmd_return_error(CMDERR_NOT_CONNECTED); cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 2, &nicks, &count); if (!cmd_get_params(data, &free_arg, 2, &nicks, &count))
return;
if (*nicks == '\0') nicks = server->nick; if (*nicks == '\0') nicks = server->nick;
server->whowas_found = FALSE; server->whowas_found = FALSE;
@ -558,7 +612,7 @@ static void cmd_whowas(const char *data, IRC_SERVER_REC *server)
"event 369", "event 369", 1, "event 369", "event 369", 1,
"event 314", "whowas event", 1, NULL); "event 314", "whowas event", 1, NULL);
if (free_nick) g_free(nicks); if (free_nick) g_free(nicks);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_ping(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item) static void cmd_ping(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
@ -594,20 +648,23 @@ static void server_send_away(IRC_SERVER_REC *server, const char *reason)
static void cmd_away(const char *data, IRC_SERVER_REC *server) static void cmd_away(const char *data, IRC_SERVER_REC *server)
{ {
char *params, *args, *reason; GHashTable *optlist;
char *reason;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server)) if (server == NULL || !server->connected || !irc_server_check(server))
cmd_return_error(CMDERR_NOT_CONNECTED); cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 2 | PARAM_FLAG_OPTARGS | PARAM_FLAG_GETREST, &args, &reason); if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS |
PARAM_FLAG_GETREST, "away", &optlist, &reason)) return;
if (stristr(args, "-one")) if (g_hash_table_lookup(optlist, "-one") != NULL)
server_send_away(server, reason); server_send_away(server, reason);
else else
g_slist_foreach(servers, (GFunc) server_send_away, reason); g_slist_foreach(servers, (GFunc) server_send_away, reason);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_deop(const char *data, IRC_SERVER_REC *server) static void cmd_deop(const char *data, IRC_SERVER_REC *server)
@ -646,7 +703,8 @@ static void cmd_wall_hash(gpointer key, NICK_REC *nick, GSList **nicks)
static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item) static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
{ {
char *params, *channame, *msg, *args; char *channame, *msg, *args;
void *free_arg;
CHANNEL_REC *chanrec; CHANNEL_REC *chanrec;
GSList *tmp, *nicks; GSList *tmp, *nicks;
@ -654,7 +712,9 @@ static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
if (server == NULL || !server->connected || !irc_server_check(server)) if (server == NULL || !server->connected || !irc_server_check(server))
cmd_return_error(CMDERR_NOT_CONNECTED); cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 2 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST, item, &channame, &msg); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN |
PARAM_FLAG_GETREST, item, &channame, &msg))
return;
if (*msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
chanrec = channel_find(server, channame); chanrec = channel_find(server, channame);
@ -677,19 +737,21 @@ static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
g_free(msg); g_free(msg);
g_slist_free(nicks); g_slist_free(nicks);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_cycle(gchar *data, IRC_SERVER_REC *server, WI_IRC_REC *item) static void cmd_cycle(gchar *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
{ {
char *params, *channame, *msg;
CHANNEL_REC *chanrec; CHANNEL_REC *chanrec;
char *channame, *msg;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server)) if (server == NULL || !server->connected || !irc_server_check(server))
cmd_return_error(CMDERR_NOT_CONNECTED); cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 2 | PARAM_FLAG_OPTCHAN, item, &channame, &msg); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN, item, &channame, &msg))
return;
if (*channame == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*channame == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
chanrec = channel_find(server, channame); chanrec = channel_find(server, channame);
@ -700,21 +762,23 @@ static void cmd_cycle(gchar *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
irc_send_cmdv(server, chanrec->key == NULL ? "JOIN %s" : "JOIN %s %s", irc_send_cmdv(server, chanrec->key == NULL ? "JOIN %s" : "JOIN %s %s",
channame, chanrec->key); channame, chanrec->key);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_kickban(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item) static void cmd_kickban(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
{ {
char *params, *nick; char *nick;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
params = cmd_get_params(data, 1, &nick); if (!cmd_get_params(data, &free_arg, 1, &nick))
return;
if (*nick == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*nick == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
signal_emit("command ban", 3, nick, server, item); signal_emit("command ban", 3, nick, server, item);
signal_emit("command kick", 3, data, server, item); signal_emit("command kick", 3, data, server, item);
g_free(params); cmd_params_free(free_arg);
} }
static void knockout_destroy(IRC_SERVER_REC *server, KNOCKOUT_REC *rec) static void knockout_destroy(IRC_SERVER_REC *server, KNOCKOUT_REC *rec)
@ -760,7 +824,8 @@ static void cmd_knockout(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *i
{ {
KNOCKOUT_REC *rec; KNOCKOUT_REC *rec;
CHANNEL_REC *channel; CHANNEL_REC *channel;
char *params, *nick, *reason, *timeoutstr, *str; char *nick, *reason, *timeoutstr, *str;
void *free_arg;
int timeleft; int timeleft;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
@ -771,11 +836,13 @@ static void cmd_knockout(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *i
if (is_numeric(data, ' ')) { if (is_numeric(data, ' ')) {
/* first argument is the timeout */ /* first argument is the timeout */
params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &timeoutstr, &nick, &reason); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, &timeoutstr, &nick, &reason))
return;
timeleft = atoi(timeoutstr); timeleft = atoi(timeoutstr);
} else { } else {
timeleft = 0; timeleft = 0;
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &nick, &reason); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &nick, &reason))
return;
} }
if (timeleft == 0) timeleft = settings_get_int("knockout_time"); if (timeleft == 0) timeleft = settings_get_int("knockout_time");
@ -795,7 +862,7 @@ static void cmd_knockout(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *i
server->knockoutlist = g_slist_append(server->knockoutlist, rec); server->knockoutlist = g_slist_append(server->knockoutlist, rec);
g_free(params); cmd_params_free(free_arg);
} }
/* destroy all knockouts in server */ /* destroy all knockouts in server */
@ -845,16 +912,18 @@ static void command_1self(const char *data, IRC_SERVER_REC *server)
static void command_2self(const char *data, IRC_SERVER_REC *server) static void command_2self(const char *data, IRC_SERVER_REC *server)
{ {
char *params, *target, *text; char *target, *text;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server)) if (server == NULL || !server->connected || !irc_server_check(server))
cmd_return_error(CMDERR_NOT_CONNECTED); cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &text); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &target, &text))
return;
if (*target == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*target == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
irc_send_cmdv(server, "%s %s :%s", current_command, target, text); irc_send_cmdv(server, "%s %s :%s", current_command, target, text);
g_free(params); cmd_params_free(free_arg);
} }
static void sig_connected(IRC_SERVER_REC *server) static void sig_connected(IRC_SERVER_REC *server)
@ -942,6 +1011,12 @@ void irc_commands_init(void)
signal_add("whois not found", (SIGNAL_FUNC) sig_whois_not_found); signal_add("whois not found", (SIGNAL_FUNC) sig_whois_not_found);
signal_add("whois event", (SIGNAL_FUNC) event_whois); signal_add("whois event", (SIGNAL_FUNC) event_whois);
signal_add("whowas event", (SIGNAL_FUNC) event_whowas); signal_add("whowas event", (SIGNAL_FUNC) event_whowas);
command_set_options("connect", "+ircnet +host");
command_set_options("topic", "d");
command_set_options("list", "yes");
command_set_options("away", "one all");
command_set_options("join", "invite");
} }
void irc_commands_deinit(void) void irc_commands_deinit(void)

View File

@ -236,11 +236,13 @@ static void event_privmsg(const char *data, IRC_SERVER_REC *server, const char *
static void cmd_msg(const char *data, IRC_SERVER_REC *server) static void cmd_msg(const char *data, IRC_SERVER_REC *server)
{ {
char *params, *target, *msg; char *target, *msg;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &msg); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &target, &msg))
return;
if (*target != '\0' && *msg != '\0' && !ischannel(*target) && isalpha(*target)) { if (*target != '\0' && *msg != '\0' && !ischannel(*target) && isalpha(*target)) {
g_free_not_null(last_sent_msg); g_free_not_null(last_sent_msg);
g_free_not_null(last_sent_msg_body); g_free_not_null(last_sent_msg_body);
@ -248,7 +250,7 @@ static void cmd_msg(const char *data, IRC_SERVER_REC *server)
last_sent_msg_body = g_strdup(msg); last_sent_msg_body = g_strdup(msg);
} }
g_free(params); cmd_params_free(free_arg);
} }
static void event_join(const char *data, IRC_SERVER_REC *server, const char *nick, const char *address) static void event_join(const char *data, IRC_SERVER_REC *server, const char *nick, const char *address)

View File

@ -158,7 +158,7 @@ static void sig_connected(IRC_SERVER_REC *server)
if (server->connrec->ircnet == NULL) return; if (server->connrec->ircnet == NULL) return;
ircnet = ircnet_find(server->connrec->ircnet); ircnet = ircnet_find(server->connrec->ircnet);
if (ircnet->autosendcmd) if (ircnet != NULL && ircnet->autosendcmd)
eval_special_string(ircnet->autosendcmd, "", server, NULL); eval_special_string(ircnet->autosendcmd, "", server, NULL);
} }

View File

@ -460,7 +460,8 @@ static void cmd_devoice(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *it
static void cmd_mode(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item) static void cmd_mode(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
{ {
char *params, *target, *mode; char *target, *mode;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server)) if (server == NULL || !server->connected || !irc_server_check(server))
@ -468,9 +469,11 @@ static void cmd_mode(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
if (*data == '+' || *data == '-') { if (*data == '+' || *data == '-') {
target = "*"; target = "*";
params = mode = g_strdup(data); /* cmd_param_error() wants to free params.. */ if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_GETREST, &mode))
return;
} else { } else {
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &mode); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &target, &mode))
return;
} }
if (strcmp(target, "*") == 0) { if (strcmp(target, "*") == 0) {
@ -488,7 +491,7 @@ static void cmd_mode(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
else else
irc_send_cmdv(server, "MODE %s %s", target, mode); irc_send_cmdv(server, "MODE %s %s", target, mode);
g_free(params); cmd_params_free(free_arg);
} }
void modes_init(void) void modes_init(void)

View File

@ -187,7 +187,8 @@ NICK_REC *netsplit_find_channel(IRC_SERVER_REC *server, const char *nick, const
int quitmsg_is_split(const char *msg) int quitmsg_is_split(const char *msg)
{ {
char *params, *host1, *host2, *p; char *host1, *host2, *p;
void *free_arg;
int ok; int ok;
g_return_val_if_fail(msg != NULL, FALSE); g_return_val_if_fail(msg != NULL, FALSE);
@ -202,8 +203,10 @@ int quitmsg_is_split(const char *msg)
return FALSE; return FALSE;
/* get the two hosts */ /* get the two hosts */
if (!cmd_get_params(msg, &free_arg, 2 | PARAM_FLAG_NOQUOTES, &host1, &host2))
return FALSE;
ok = FALSE; ok = FALSE;
params = cmd_get_params(msg, 2 | PARAM_FLAG_NOQUOTES, &host1, &host2);
if (g_strcasecmp(host1, host2) != 0) { /* hosts can't be same.. */ if (g_strcasecmp(host1, host2) != 0) { /* hosts can't be same.. */
/* check that domain length is 2 or 3 */ /* check that domain length is 2 or 3 */
p = strrchr(host1, '.'); p = strrchr(host1, '.');
@ -215,7 +218,7 @@ int quitmsg_is_split(const char *msg)
} }
} }
} }
g_free(params); cmd_params_free(free_arg);
return ok; return ok;
} }

View File

@ -59,7 +59,8 @@ DCC_REC *item_get_dcc(void *item)
static void cmd_msg(const char *data) static void cmd_msg(const char *data)
{ {
DCC_REC *dcc; DCC_REC *dcc;
char *params, *text, *target; char *text, *target;
void *free_arg;
g_return_if_fail(text != NULL); g_return_if_fail(text != NULL);
@ -68,12 +69,13 @@ static void cmd_msg(const char *data)
return; return;
} }
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &text); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &target, &text))
return;
dcc = dcc_find_item(DCC_TYPE_CHAT, ++target, NULL); dcc = dcc_find_item(DCC_TYPE_CHAT, ++target, NULL);
if (dcc != NULL) dcc_chat_send(dcc, text); if (dcc != NULL) dcc_chat_send(dcc, text);
g_free(params); cmd_params_free(free_arg);
signal_stop(); signal_stop();
} }
@ -96,9 +98,9 @@ static void cmd_me(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_action(const char *data, IRC_SERVER_REC *server) static void cmd_action(const char *data, IRC_SERVER_REC *server)
{ {
char *params, *target, *text;
DCC_REC *dcc; DCC_REC *dcc;
char *str; char *target, *text, *str;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
@ -107,7 +109,8 @@ static void cmd_action(const char *data, IRC_SERVER_REC *server)
return; return;
} }
params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &target, &text); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, &target, &text))
return;
if (*target == '\0' || *text == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*target == '\0' || *text == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
dcc = dcc_find_item(DCC_TYPE_CHAT, target+1, NULL); dcc = dcc_find_item(DCC_TYPE_CHAT, target+1, NULL);
@ -117,25 +120,26 @@ static void cmd_action(const char *data, IRC_SERVER_REC *server)
g_free(str); g_free(str);
} }
g_free(params); cmd_params_free(free_arg);
signal_stop(); signal_stop();
} }
static void cmd_ctcp(const char *data, IRC_SERVER_REC *server) static void cmd_ctcp(const char *data, IRC_SERVER_REC *server)
{ {
char *params, *target, *ctcpcmd, *ctcpdata;
DCC_REC *dcc; DCC_REC *dcc;
char *str; char *target, *ctcpcmd, *ctcpdata, *str;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
if (server == NULL || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED); if (server == NULL || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED);
params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &target, &ctcpcmd, &ctcpdata); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, &target, &ctcpcmd, &ctcpdata))
return;
if (*target == '\0' || *ctcpcmd == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*target == '\0' || *ctcpcmd == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
if (*target != '=') { if (*target != '=') {
/* handle only DCC CTCPs */ /* handle only DCC CTCPs */
g_free(params); cmd_params_free(free_arg);
return; return;
} }
@ -148,7 +152,7 @@ static void cmd_ctcp(const char *data, IRC_SERVER_REC *server)
g_free(str); g_free(str);
} }
g_free(params); cmd_params_free(free_arg);
signal_stop(); signal_stop();
} }

View File

@ -212,12 +212,14 @@ static void cmd_dcc_get(const char *data)
{ {
DCC_REC *dcc; DCC_REC *dcc;
GSList *tmp, *next; GSList *tmp, *next;
char *params, *nick, *fname; char *nick, *fname;
void *free_arg;
int found; int found;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &nick, &fname); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &nick, &fname))
return;
if (*nick == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*nick == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
dcc = NULL; found = FALSE; dcc = NULL; found = FALSE;
@ -235,7 +237,7 @@ static void cmd_dcc_get(const char *data)
if (!found) if (!found)
signal_emit("dcc error get not found", 1, nick); signal_emit("dcc error get not found", 1, nick);
g_free(params); cmd_params_free(free_arg);
} }
static void dcc_resume_send(DCC_REC *dcc, int port) static void dcc_resume_send(DCC_REC *dcc, int port)
@ -264,7 +266,8 @@ static void dcc_ctcp_msg(const char *data, IRC_SERVER_REC *server,
const char *sender, const char *sendaddr, const char *sender, const char *sendaddr,
const char *target, DCC_REC *chat) const char *target, DCC_REC *chat)
{ {
char *params, *type, *arg, *portstr, *sizestr; char *type, *arg, *portstr, *sizestr;
void *free_arg;
unsigned long size; unsigned long size;
int port; int port;
DCC_REC *dcc; DCC_REC *dcc;
@ -272,8 +275,9 @@ static void dcc_ctcp_msg(const char *data, IRC_SERVER_REC *server,
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
g_return_if_fail(sender != NULL); g_return_if_fail(sender != NULL);
params = cmd_get_params(data, 4 | PARAM_FLAG_NOQUOTES, if (!cmd_get_params(data, &free_arg, 4 | PARAM_FLAG_NOQUOTES,
&type, &arg, &portstr, &sizestr); &type, &arg, &portstr, &sizestr))
return;
port = atoi(portstr); port = atoi(portstr);
size = atol(sizestr); size = atol(sizestr);
@ -281,7 +285,7 @@ static void dcc_ctcp_msg(const char *data, IRC_SERVER_REC *server,
dcc = dcc_find_by_port(sender, port); dcc = dcc_find_by_port(sender, port);
if (dcc == NULL || !is_resume_type(type) || if (dcc == NULL || !is_resume_type(type) ||
!is_resume_ok(type, dcc) || !is_accept_ok(type, dcc)) { !is_resume_ok(type, dcc) || !is_accept_ok(type, dcc)) {
g_free(params); cmd_params_free(free_arg);
return; return;
} }
@ -298,7 +302,7 @@ static void dcc_ctcp_msg(const char *data, IRC_SERVER_REC *server,
dcc_get_connect(dcc); dcc_get_connect(dcc);
} }
g_free(params); cmd_params_free(free_arg);
} }
static void dcc_resume_rec(DCC_REC *dcc) static void dcc_resume_rec(DCC_REC *dcc)
@ -331,12 +335,14 @@ static void cmd_dcc_resume(const char *data)
{ {
DCC_REC *dcc; DCC_REC *dcc;
GSList *tmp; GSList *tmp;
char *params, *nick, *fname; char *nick, *fname;
void *free_arg;
int found; int found;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &nick, &fname); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &nick, &fname))
return;
if (*nick == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*nick == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
dcc = NULL; found = FALSE; dcc = NULL; found = FALSE;
@ -353,7 +359,7 @@ static void cmd_dcc_resume(const char *data)
if (!found) if (!found)
signal_emit("dcc error get not found", 1, nick); signal_emit("dcc error get not found", 1, nick);
g_free(params); cmd_params_free(free_arg);
} }
/* input function: DCC SEND - we're ready to send more data */ /* input function: DCC SEND - we're ready to send more data */
@ -483,7 +489,8 @@ static void dcc_send_init(DCC_REC *dcc)
/* command: DCC SEND */ /* command: DCC SEND */
static void cmd_dcc_send(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item) static void cmd_dcc_send(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
{ {
char *params, *target, *fname, *str, *ptr; char *target, *fname, *str, *ptr;
void *free_arg;
char host[MAX_IP_LEN]; char host[MAX_IP_LEN];
int hfile, hlisten, port; int hfile, hlisten, port;
long fsize; long fsize;
@ -492,7 +499,8 @@ static void cmd_dcc_send(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *i
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &fname); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &target, &fname))
return;
if (*target == '\0' || *fname == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*target == '\0' || *fname == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
/* if we're in dcc chat, send the request via it. */ /* if we're in dcc chat, send the request via it. */
@ -506,7 +514,7 @@ static void cmd_dcc_send(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *i
if (dcc_find_item(DCC_TYPE_SEND, target, fname)) { if (dcc_find_item(DCC_TYPE_SEND, target, fname)) {
signal_emit("dcc error send exists", 2, target, fname); signal_emit("dcc error send exists", 2, target, fname);
g_free(params); cmd_params_free(free_arg);
return; return;
} }
@ -525,7 +533,7 @@ static void cmd_dcc_send(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *i
if (hfile == -1) { if (hfile == -1) {
signal_emit("dcc error file not found", 2, target, fname); signal_emit("dcc error file not found", 2, target, fname);
g_free(params); cmd_params_free(free_arg);
return; return;
} }
fsize = lseek(hfile, 0, SEEK_END); fsize = lseek(hfile, 0, SEEK_END);
@ -565,7 +573,7 @@ static void cmd_dcc_send(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *i
g_free(str); g_free(str);
g_free(fname); g_free(fname);
g_free(params); cmd_params_free(free_arg);
} }
static void read_settings(void) static void read_settings(void)

View File

@ -278,7 +278,8 @@ static void dcc_get_address(const char *str, IPADDR *ip)
/* Handle incoming DCC CTCP messages */ /* Handle incoming DCC CTCP messages */
static void dcc_ctcp_msg(char *data, IRC_SERVER_REC *server, char *sender, char *sendaddr, char *target, DCC_REC *chat) static void dcc_ctcp_msg(char *data, IRC_SERVER_REC *server, char *sender, char *sendaddr, char *target, DCC_REC *chat)
{ {
char *params, *type, *arg, *addrstr, *portstr, *sizestr, *str; char *type, *arg, *addrstr, *portstr, *sizestr, *str;
void *free_arg;
const char *cstr; const char *cstr;
DCC_REC *dcc; DCC_REC *dcc;
gulong size; gulong size;
@ -287,8 +288,9 @@ static void dcc_ctcp_msg(char *data, IRC_SERVER_REC *server, char *sender, char
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
g_return_if_fail(sender != NULL); g_return_if_fail(sender != NULL);
params = cmd_get_params(data, 5 | PARAM_FLAG_NOQUOTES, if (!cmd_get_params(data, &free_arg, 5 | PARAM_FLAG_NOQUOTES,
&type, &arg, &addrstr, &portstr, &sizestr); &type, &arg, &addrstr, &portstr, &sizestr))
return;
if (sscanf(portstr, "%d", &port) != 1) port = 0; if (sscanf(portstr, "%d", &port) != 1) port = 0;
if (sscanf(sizestr, "%lu", &size) != 1) size = 0; if (sscanf(sizestr, "%lu", &size) != 1) size = 0;
@ -349,20 +351,22 @@ static void dcc_ctcp_msg(char *data, IRC_SERVER_REC *server, char *sender, char
break; break;
} }
g_free(params); cmd_params_free(free_arg);
} }
/* Handle incoming DCC CTCP replies */ /* Handle incoming DCC CTCP replies */
static void dcc_ctcp_reply(char *data, IRC_SERVER_REC *server, char *sender, char *sendaddr) static void dcc_ctcp_reply(char *data, IRC_SERVER_REC *server, char *sender, char *sendaddr)
{ {
char *params, *cmd, *subcmd, *args; char *cmd, *subcmd, *args;
void *free_arg;
int type; int type;
DCC_REC *dcc; DCC_REC *dcc;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
g_return_if_fail(sender != NULL); g_return_if_fail(sender != NULL);
params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &cmd, &subcmd, &args); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, &cmd, &subcmd, &args))
return;
if (g_strcasecmp(cmd, "REJECT") == 0) if (g_strcasecmp(cmd, "REJECT") == 0)
{ {
@ -380,7 +384,7 @@ static void dcc_ctcp_reply(char *data, IRC_SERVER_REC *server, char *sender, cha
signal_emit("dcc unknown reply", 3, data, sender, sendaddr); signal_emit("dcc unknown reply", 3, data, sender, sendaddr);
} }
g_free(params); cmd_params_free(free_arg);
} }
static void dcc_reject(DCC_REC *dcc, IRC_SERVER_REC *server) static void dcc_reject(DCC_REC *dcc, IRC_SERVER_REC *server)
@ -409,20 +413,22 @@ static void cmd_dcc_close(char *data, IRC_SERVER_REC *server)
{ {
DCC_REC *dcc; DCC_REC *dcc;
GSList *tmp, *next; GSList *tmp, *next;
char *params, *type, *nick, *arg; char *type, *nick, *arg;
void *free_arg;
gboolean found; gboolean found;
int itype; int itype;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
params = cmd_get_params(data, 3, &type, &nick, &arg); if (!cmd_get_params(data, &free_arg, 3, &type, &nick, &arg))
return;
g_strup(type); g_strup(type);
itype = dcc_str2type(type); itype = dcc_str2type(type);
if (itype == 0) if (itype == 0)
{ {
signal_emit("dcc error unknown type", 1, type); signal_emit("dcc error unknown type", 1, type);
g_free(params); cmd_params_free(free_arg);
return; return;
} }
@ -442,7 +448,7 @@ static void cmd_dcc_close(char *data, IRC_SERVER_REC *server)
if (!found) if (!found)
signal_emit("dcc error close not found", 3, type, nick, arg); signal_emit("dcc error close not found", 3, type, nick, arg);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_dcc(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item) static void cmd_dcc(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)

View File

@ -30,41 +30,47 @@
static void cmd_notify(gchar *data) static void cmd_notify(gchar *data)
{ {
char *params, *mask, *ircnets, *args, *idletime; GHashTable *optlist;
char *mask, *ircnets, *idletime;
void *free_arg;
int away_check, idle_check_time; int away_check, idle_check_time;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
args = "@idle"; if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | PARAM_FLAG_GETREST,
params = cmd_get_params(data, 4 | PARAM_FLAG_MULTIARGS | PARAM_FLAG_GETREST, &args, &idletime, &mask, &ircnets); "notify", &optlist, &mask, &ircnets))
return;
if (*mask == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*mask == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
if (stristr(args, "-idle") == NULL) idletime = g_hash_table_lookup(optlist, "idle");
if (idletime == NULL)
idle_check_time = 0; idle_check_time = 0;
else { else {
idle_check_time = is_numeric(idletime, 0) ? (atoi(idletime)*60) : idle_check_time = is_numeric(idletime, 0) ? (atoi(idletime)*60) :
(settings_get_int("notify_idle_time")*60); (settings_get_int("notify_idle_time")*60);
} }
away_check = stristr(args, "-away") != NULL; away_check = g_hash_table_lookup(optlist, "away") != NULL;
notifylist_remove(mask); notifylist_remove(mask);
notifylist_add(mask, ircnets, away_check, idle_check_time); notifylist_add(mask, ircnets, away_check, idle_check_time);
g_free(params); cmd_params_free(free_arg);
} }
static void cmd_unnotify(const char *data) static void cmd_unnotify(const char *data)
{ {
char *params, *mask; char *mask;
void *free_arg;
g_return_if_fail(data != NULL); g_return_if_fail(data != NULL);
params = cmd_get_params(data, 1, &mask); if (!cmd_get_params(data, &free_arg, 1, &mask))
return;
if (*mask == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*mask == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
notifylist_remove(mask); notifylist_remove(mask);
g_free(params); cmd_params_free(free_arg);
} }
void notifylist_commands_init(void) void notifylist_commands_init(void)
@ -72,6 +78,8 @@ void notifylist_commands_init(void)
settings_add_int("misc", "notify_idle_time", DEFAULT_NOTIFY_IDLE_TIME); settings_add_int("misc", "notify_idle_time", DEFAULT_NOTIFY_IDLE_TIME);
command_bind("notify", NULL, (SIGNAL_FUNC) cmd_notify); command_bind("notify", NULL, (SIGNAL_FUNC) cmd_notify);
command_bind("unnotify", NULL, (SIGNAL_FUNC) cmd_unnotify); command_bind("unnotify", NULL, (SIGNAL_FUNC) cmd_unnotify);
command_set_options("notify", "@idle away");
} }
void notifylist_commands_deinit(void) void notifylist_commands_deinit(void)